This is an automated email from the ASF dual-hosted git repository. victory pushed a commit to branch cloud-native in repository https://gitbox.apache.org/repos/asf/dubbo.git
The following commit(s) were added to refs/heads/cloud-native by this push: new 4baa0aa fix review issue 4baa0aa is described below commit 4baa0aad39ff313be9037c2b1aaf34cac49ab6aa Author: cvictory <shenglic...@gmail.com> AuthorDate: Wed Aug 14 15:37:29 2019 +0800 fix review issue --- .../bootstrap/DubboServiceConsumerBootstrap.java | 4 +- .../bootstrap/DubboServiceProviderBootstrap.java | 2 + .../DubboInterfaceConsumerBootstrap.java | 4 +- .../src/main/java/org/apache/dubbo/common/URL.java | 1 + .../dubbo/config/AbstractInterfaceConfig.java | 7 ++ .../apache/dubbo/config/MetadataReportConfig.java | 9 +- .../org/apache/dubbo/metadata/MetadataService.java | 2 + .../dubbo/metadata/WritableMetadataService.java | 2 +- .../dubbo/metadata/report/MetadataReport.java | 9 +- .../identifier/ServiceMetadataIdentifier.java | 21 ++++ .../report/support/AbstractMetadataReport.java | 45 ++++++--- .../store/BaseWritableMetadataService.java | 64 ++++++++++++ .../store/InMemoryWritableMetadataService.java | 66 +------------ .../store/RemoteWritableMetadataService.java | 108 ++++++++++++++++++--- .../support/AbstractMetadataReportFactoryTest.java | 8 +- .../report/support/AbstractMetadataReportTest.java | 12 +-- .../metadata/test/JTestMetadataReport4Test.java | 6 +- .../store/consul/ConsulMetadataReport.java | 6 +- .../metadata/store/etcd/EtcdMetadataReport.java | 6 +- .../metadata/store/nacos/NacosMetadataReport.java | 6 +- .../metadata/store/redis/RedisMetadataReport.java | 6 +- .../store/zookeeper/ZookeeperMetadataReport.java | 18 ++-- .../metadata/RefreshServiceMetadataCustomizer.java | 19 +++- .../metadata/ServiceInstanceMetadataUtils.java | 32 ++++++ ...bscribedServicesRevisionMetadataCustomizer.java | 73 ++++++++++++++ .../registry/service/ServiceOrientedRegistry.java | 11 ++- ...dubbo.registry.client.ServiceInstanceCustomizer | 1 + 27 files changed, 406 insertions(+), 142 deletions(-) diff --git a/dubbo-bootstrap/src/test/java/org/apache/dubbo/bootstrap/DubboServiceConsumerBootstrap.java b/dubbo-bootstrap/src/test/java/org/apache/dubbo/bootstrap/DubboServiceConsumerBootstrap.java index f082192..fe216ab 100644 --- a/dubbo-bootstrap/src/test/java/org/apache/dubbo/bootstrap/DubboServiceConsumerBootstrap.java +++ b/dubbo-bootstrap/src/test/java/org/apache/dubbo/bootstrap/DubboServiceConsumerBootstrap.java @@ -17,6 +17,7 @@ package org.apache.dubbo.bootstrap; import org.apache.dubbo.bootstrap.rest.UserService; +import org.apache.dubbo.config.MetadataReportConfig; import org.apache.dubbo.config.ReferenceConfig; import org.apache.dubbo.config.context.ConfigManager; @@ -33,6 +34,7 @@ public class DubboServiceConsumerBootstrap { .application("dubbo-consumer-demo") // Zookeeper .registry("zookeeper", builder -> builder.address("zookeeper://127.0.0.1:2181?registry.type=service&subscribed.services=dubbo-provider-demo")) + .metadataReport(new MetadataReportConfig("zookeeper://127.0.0.1:2181")) // Nacos // .registry("consul", builder -> builder.address("consul://127.0.0.1:8500?registry.type=service&subscribed.services=dubbo-provider-demo").group("namespace1")) .reference("echo", builder -> builder.interfaceClass(EchoService.class).protocol("dubbo")) @@ -43,7 +45,7 @@ public class DubboServiceConsumerBootstrap { ConfigManager configManager = ConfigManager.getInstance(); - ReferenceConfig<EchoService> referenceConfig = configManager.getReferenceConfig("echo"); + ReferenceConfig<EchoService> referenceConfig = configManager.getReference("echo"); EchoService echoService = referenceConfig.get(); diff --git a/dubbo-bootstrap/src/test/java/org/apache/dubbo/bootstrap/DubboServiceProviderBootstrap.java b/dubbo-bootstrap/src/test/java/org/apache/dubbo/bootstrap/DubboServiceProviderBootstrap.java index dd2060c..9bafe00 100644 --- a/dubbo-bootstrap/src/test/java/org/apache/dubbo/bootstrap/DubboServiceProviderBootstrap.java +++ b/dubbo-bootstrap/src/test/java/org/apache/dubbo/bootstrap/DubboServiceProviderBootstrap.java @@ -18,6 +18,7 @@ package org.apache.dubbo.bootstrap; import org.apache.dubbo.bootstrap.rest.UserService; import org.apache.dubbo.bootstrap.rest.UserServiceImpl; +import org.apache.dubbo.config.MetadataReportConfig; import org.apache.dubbo.config.ProtocolConfig; import org.apache.dubbo.config.RegistryConfig; import org.apache.dubbo.config.ServiceConfig; @@ -70,6 +71,7 @@ public class DubboServiceProviderBootstrap { .registries(Arrays.asList(interfaceRegistry, serviceRegistry)) // .registry(RegistryBuilder.newBuilder().address("consul://127.0.0.1:8500?registry.type=service").build()) .protocol(builder -> builder.port(-1).name("dubbo")) + .metadataReport(new MetadataReportConfig("zookeeper://127.0.0.1:2181")) .service(echoService) .service(userService) .start() diff --git a/dubbo-bootstrap/src/test/java/org/apache/dubbo/bootstrap/compatible/DubboInterfaceConsumerBootstrap.java b/dubbo-bootstrap/src/test/java/org/apache/dubbo/bootstrap/compatible/DubboInterfaceConsumerBootstrap.java index 59a8fb1..79a0030 100644 --- a/dubbo-bootstrap/src/test/java/org/apache/dubbo/bootstrap/compatible/DubboInterfaceConsumerBootstrap.java +++ b/dubbo-bootstrap/src/test/java/org/apache/dubbo/bootstrap/compatible/DubboInterfaceConsumerBootstrap.java @@ -49,10 +49,10 @@ public class DubboInterfaceConsumerBootstrap { ConfigManager configManager = ConfigManager.getInstance(); - ReferenceConfig<EchoService> referenceConfig = configManager.getReferenceConfig("echo"); + ReferenceConfig<EchoService> referenceConfig = configManager.getReference("echo"); EchoService echoService = referenceConfig.get(); - ReferenceConfig<UserService> referenceConfig1 = configManager.getReferenceConfig("user"); + ReferenceConfig<UserService> referenceConfig1 = configManager.getReference("user"); UserService userService = referenceConfig1.get(); for (int i = 0; i < 500; i++) { diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/URL.java b/dubbo-common/src/main/java/org/apache/dubbo/common/URL.java index 93cad0b..d986f66 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/URL.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/URL.java @@ -1259,6 +1259,7 @@ class URL implements Serializable { /** * The format is "{interface}:[version]:[group]" + * * @return */ public String getColonSeparatedKey() { diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java index f1ad3d9..257cf5d 100644 --- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java +++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java @@ -248,6 +248,13 @@ public abstract class AbstractInterfaceConfig extends AbstractMethodConfig { protected void checkMetadataReport() { // TODO get from ConfigManager first, only create if absent. if (metadataReportConfig == null) { + ConfigManager configManager = ConfigManager.getInstance(); + if (CollectionUtils.isNotEmpty(configManager.getMetadataConfigs())) { + setMetadataReportConfig(configManager.getMetadataConfigs() + .toArray(new MetadataReportConfig[configManager.getMetadataConfigs().size()])[0]); + } + } + if (metadataReportConfig == null) { setMetadataReportConfig(new MetadataReportConfig()); } metadataReportConfig.refresh(); diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/MetadataReportConfig.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/MetadataReportConfig.java index 30e5bcb..506ac46 100644 --- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/MetadataReportConfig.java +++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/MetadataReportConfig.java @@ -26,6 +26,7 @@ import java.util.Map; import static org.apache.dubbo.common.constants.CommonConstants.DUBBO; import static org.apache.dubbo.common.constants.CommonConstants.PROPERTIES_CHAR_SEPERATOR; +import static org.apache.dubbo.metadata.report.support.Constants.METADATA_REPORT_KEY; /** * MetadataReportConfig @@ -93,7 +94,13 @@ public class MetadataReportConfig extends AbstractConfig { } Map<String, String> map = new HashMap<String, String>(); appendParameters(map, this); - return UrlUtils.parseURL(address, map); + if (!StringUtils.isEmpty(address)) { + URL url = URL.valueOf(address); + map.put(METADATA_REPORT_KEY, url.getProtocol()); + return new URL(METADATA_REPORT_KEY, url.getUsername(), url.getPassword(), url.getHost(), + url.getPort(), url.getPath(), map); + } + throw new IllegalArgumentException("The address of metadata report is invalid."); } @Parameter(excluded = true) diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataService.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataService.java index 490abcb..c4cf250 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataService.java +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataService.java @@ -43,6 +43,8 @@ import static java.util.stream.StreamSupport.stream; */ public interface MetadataService { + //FIXME the value is default, it was used by testing temporarily + static final String DEFAULT_EXTENSION = "default"; /** * The value of all service names diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/WritableMetadataService.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/WritableMetadataService.java index 07cd5a5..7a8fd27 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/WritableMetadataService.java +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/WritableMetadataService.java @@ -64,7 +64,7 @@ public interface WritableMetadataService extends MetadataService { * * @return If success , return <code>true</code> */ - default boolean refreshMetadata(String revision){ + default boolean refreshMetadata(String exportedRevision, String subscribedRevision){ return true; } diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/MetadataReport.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/MetadataReport.java index 2a03ce1..90ca45a 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/MetadataReport.java +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/MetadataReport.java @@ -25,6 +25,7 @@ import org.apache.dubbo.metadata.report.identifier.SubscriberMetadataIdentifier; import java.util.List; import java.util.Map; +import java.util.Set; /** * @@ -35,15 +36,15 @@ public interface MetadataReport { void storeConsumerMetadata(MetadataIdentifier consumerMetadataIdentifier, Map<String, String> serviceParameterMap); - void saveServiceMetadata(URL url); + void saveServiceMetadata(ServiceMetadataIdentifier metadataIdentifier, URL url); - void removeServiceMetadata(URL url); + void removeServiceMetadata(ServiceMetadataIdentifier metadataIdentifier); List<String> getExportedURLs(ServiceMetadataIdentifier metadataIdentifier); - void saveSubscriberData(SubscriberMetadataIdentifier subscriberMetadataIdentifier, List<String> urls); + void saveSubscribedData(SubscriberMetadataIdentifier subscriberMetadataIdentifier, Set<String> urls); List<String> getSubscribedURLs(SubscriberMetadataIdentifier subscriberMetadataIdentifier); - String getServiceDefinition(MetadataIdentifier consumerMetadataIdentifier); + String getServiceDefinition(MetadataIdentifier metadataIdentifier); } diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/identifier/ServiceMetadataIdentifier.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/identifier/ServiceMetadataIdentifier.java index e7f394f..a04492a 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/identifier/ServiceMetadataIdentifier.java +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/identifier/ServiceMetadataIdentifier.java @@ -37,6 +37,7 @@ public class ServiceMetadataIdentifier extends BaseServiceMetadataIdentifier { this.group = url.getParameter(GROUP_KEY); this.side = url.getParameter(SIDE_KEY); this.revision = (url.getParameter(REVISION_KEY)); + this.protocol = url.getProtocol(); } public String getUniqueKey(MetadataIdentifier.KeyTypeEnum keyType) { @@ -46,4 +47,24 @@ public class ServiceMetadataIdentifier extends BaseServiceMetadataIdentifier { public String getIdentifierKey() { return super.getIdentifierKey(protocol, KEY_REVISON_PREFIX + revision); } + + public void setRevision(String revision) { + this.revision = revision; + } + + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + @Override + public String toString() { + return "ServiceMetadataIdentifier{" + + "revision='" + revision + '\'' + + ", protocol='" + protocol + '\'' + + ", serviceInterface='" + serviceInterface + '\'' + + ", version='" + version + '\'' + + ", group='" + group + '\'' + + ", side='" + side + '\'' + + "} " + super.toString(); + } } diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReport.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReport.java index 166fb90..f70e13e 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReport.java +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReport.java @@ -19,6 +19,7 @@ package org.apache.dubbo.metadata.report.support; import org.apache.dubbo.common.URL; import org.apache.dubbo.common.logger.Logger; import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.common.utils.CollectionUtils; import org.apache.dubbo.common.utils.ConfigUtils; import org.apache.dubbo.common.utils.NamedThreadFactory; import org.apache.dubbo.metadata.definition.model.FullServiceDefinition; @@ -29,6 +30,7 @@ import org.apache.dubbo.metadata.report.identifier.ServiceMetadataIdentifier; import org.apache.dubbo.metadata.report.identifier.SubscriberMetadataIdentifier; import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; import java.io.File; import java.io.FileInputStream; @@ -36,13 +38,17 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.RandomAccessFile; +import java.lang.reflect.Type; import java.nio.channels.FileChannel; import java.nio.channels.FileLock; +import java.util.ArrayList; import java.util.Calendar; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Properties; +import java.util.Set; +import java.util.SortedSet; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -286,20 +292,20 @@ public abstract class AbstractMetadataReport implements MetadataReport { } @Override - public void saveServiceMetadata(URL url) { + public void saveServiceMetadata(ServiceMetadataIdentifier metadataIdentifier, URL url) { if (syncReport) { - doSaveMetadata(new ServiceMetadataIdentifier(url), url); + doSaveMetadata(metadataIdentifier, url); } else { reportCacheExecutor.execute(() -> doSaveMetadata(new ServiceMetadataIdentifier(url), url)); } } @Override - public void removeServiceMetadata(URL url) { + public void removeServiceMetadata(ServiceMetadataIdentifier metadataIdentifier) { if (syncReport) { - doRemoveMetadata(new ServiceMetadataIdentifier(url), url); + doRemoveMetadata(metadataIdentifier); } else { - reportCacheExecutor.execute(() -> doRemoveMetadata(new ServiceMetadataIdentifier(url), url)); + reportCacheExecutor.execute(() -> doRemoveMetadata(metadataIdentifier)); } } @@ -310,19 +316,21 @@ public abstract class AbstractMetadataReport implements MetadataReport { } @Override - public void saveSubscriberData(SubscriberMetadataIdentifier subscriberMetadataIdentifier, List<String> urls) { + public void saveSubscribedData(SubscriberMetadataIdentifier subscriberMetadataIdentifier, Set<String> urls) { if (syncReport) { - doSaveSubscriberData(subscriberMetadataIdentifier, urls); + doSaveSubscriberData(subscriberMetadataIdentifier, new Gson().toJson(urls)); } else { - reportCacheExecutor.execute(() -> doSaveSubscriberData(subscriberMetadataIdentifier, urls)); + reportCacheExecutor.execute(() -> doSaveSubscriberData(subscriberMetadataIdentifier, new Gson().toJson(urls))); } } @Override public List<String> getSubscribedURLs(SubscriberMetadataIdentifier subscriberMetadataIdentifier) { - // TODO, fallback to local cache - return doGetSubscribedURLs(subscriberMetadataIdentifier); + String content = doGetSubscribedURLs(subscriberMetadataIdentifier); + Type setType = new TypeToken<SortedSet<String>>() { + }.getType(); + return new Gson().fromJson(content, setType); } String getProtocol(URL url) { @@ -430,18 +438,29 @@ public abstract class AbstractMetadataReport implements MetadataReport { } } + private void doSaveSubscriberData(SubscriberMetadataIdentifier subscriberMetadataIdentifier, List<String> urls) { + if (CollectionUtils.isEmpty(urls)) { + return; + } + List<String> encodedUrlList = new ArrayList<>(urls.size()); + for (String url : urls) { + encodedUrlList.add(URL.encode(url)); + } + doSaveSubscriberData(subscriberMetadataIdentifier, encodedUrlList); + } + protected abstract void doStoreProviderMetadata(MetadataIdentifier providerMetadataIdentifier, String serviceDefinitions); protected abstract void doStoreConsumerMetadata(MetadataIdentifier consumerMetadataIdentifier, String serviceParameterString); protected abstract void doSaveMetadata(ServiceMetadataIdentifier metadataIdentifier, URL url); - protected abstract void doRemoveMetadata(ServiceMetadataIdentifier metadataIdentifier, URL url); + protected abstract void doRemoveMetadata(ServiceMetadataIdentifier metadataIdentifier); protected abstract List<String> doGetExportedURLs(ServiceMetadataIdentifier metadataIdentifier); - protected abstract void doSaveSubscriberData(SubscriberMetadataIdentifier subscriberMetadataIdentifier, List<String> urls); + protected abstract void doSaveSubscriberData(SubscriberMetadataIdentifier subscriberMetadataIdentifier, String urlListStr); - protected abstract List<String> doGetSubscribedURLs(SubscriberMetadataIdentifier subscriberMetadataIdentifier); + protected abstract String doGetSubscribedURLs(SubscriberMetadataIdentifier subscriberMetadataIdentifier); } diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/BaseWritableMetadataService.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/BaseWritableMetadataService.java new file mode 100644 index 0000000..c751226 --- /dev/null +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/BaseWritableMetadataService.java @@ -0,0 +1,64 @@ +package org.apache.dubbo.metadata.store; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.logger.Logger; +import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.metadata.MetadataService; +import org.apache.dubbo.metadata.report.identifier.ServiceMetadataIdentifier; + +import java.util.Collection; +import java.util.Map; +import java.util.SortedSet; +import java.util.concurrent.ConcurrentNavigableMap; +import java.util.concurrent.ConcurrentSkipListMap; +import java.util.function.BiConsumer; +import java.util.function.Consumer; +import java.util.function.Function; +import java.util.function.Supplier; + +/** + * @author cvictory ON 2019-08-14 + */ +public class BaseWritableMetadataService { + final Logger logger = LoggerFactory.getLogger(getClass()); + + // =================================== Registration =================================== // + + /** + * All exported {@link URL urls} {@link Map} whose key is the return value of {@link URL#getServiceKey()} method + * and value is the {@link SortedSet sorted set} of the {@link URL URLs} + */ + static ConcurrentNavigableMap<String, SortedSet<URL>> exportedServiceURLs = new ConcurrentSkipListMap<>(); + + // ==================================================================================== // + + // =================================== Subscription =================================== // + + /** + * The subscribed {@link URL urls} {@link Map} of {@link MetadataService}, + * whose key is the return value of {@link URL#getServiceKey()} method and value is + * the {@link SortedSet sorted set} of the {@link URL URLs} + */ + final static ConcurrentNavigableMap<String, SortedSet<URL>> subscribedServiceURLs = new ConcurrentSkipListMap<>(); + + final static ConcurrentNavigableMap<String, String> serviceDefinitions = new ConcurrentSkipListMap<>(); + + + boolean throwableAction(Consumer<URL> consumer, URL url) { + try { + consumer.accept(url); + } catch (Exception e) { + logger.error("Failed to remove url metadata to remote center, url is: " + url); + return false; + } + return true; + } + + public SortedSet<String> getSubscribedURLs() { + return getAllUnmodifiableServiceURLs(subscribedServiceURLs); + } + + static SortedSet<String> getAllUnmodifiableServiceURLs(Map<String, SortedSet<URL>> serviceURLs) { + return MetadataService.toSortedStrings(serviceURLs.values().stream().flatMap(Collection::stream)); + } +} diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/InMemoryWritableMetadataService.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/InMemoryWritableMetadataService.java index 0f73ebe..ce8fea5 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/InMemoryWritableMetadataService.java +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/InMemoryWritableMetadataService.java @@ -17,8 +17,6 @@ package org.apache.dubbo.metadata.store; import org.apache.dubbo.common.URL; -import org.apache.dubbo.common.logger.Logger; -import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.common.utils.StringUtils; import org.apache.dubbo.metadata.MetadataService; import org.apache.dubbo.metadata.WritableMetadataService; @@ -27,18 +25,11 @@ import org.apache.dubbo.metadata.definition.model.ServiceDefinition; import com.google.gson.Gson; -import java.util.ArrayList; -import java.util.Collection; import java.util.Comparator; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; import java.util.Map; import java.util.SortedSet; import java.util.TreeSet; import java.util.concurrent.Callable; -import java.util.concurrent.ConcurrentNavigableMap; -import java.util.concurrent.ConcurrentSkipListMap; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; @@ -47,7 +38,6 @@ import static java.util.Collections.unmodifiableSortedSet; import static org.apache.dubbo.common.URL.buildKey; import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY; import static org.apache.dubbo.common.constants.CommonConstants.PROTOCOL_KEY; -import static org.apache.dubbo.common.constants.CommonConstants.REVISION_KEY; import static org.apache.dubbo.common.utils.CollectionUtils.isEmpty; /** @@ -58,32 +48,11 @@ import static org.apache.dubbo.common.utils.CollectionUtils.isEmpty; * @see WritableMetadataService * @since 2.7.4 */ -public class InMemoryWritableMetadataService implements WritableMetadataService { +public class InMemoryWritableMetadataService extends BaseWritableMetadataService implements WritableMetadataService { - private final Logger logger = LoggerFactory.getLogger(getClass()); - private final Lock lock = new ReentrantLock(); - - // =================================== Registration =================================== // - - /** - * All exported {@link URL urls} {@link Map} whose key is the return value of {@link URL#getServiceKey()} method - * and value is the {@link SortedSet sorted set} of the {@link URL URLs} - */ - ConcurrentNavigableMap<String, SortedSet<URL>> exportedServiceURLs = new ConcurrentSkipListMap<>(); - - // ==================================================================================== // - // =================================== Subscription =================================== // - - /** - * The subscribed {@link URL urls} {@link Map} of {@link MetadataService}, - * whose key is the return value of {@link URL#getServiceKey()} method and value is - * the {@link SortedSet sorted set} of the {@link URL URLs} - */ - final ConcurrentNavigableMap<String, SortedSet<URL>> subscribedServiceURLs = new ConcurrentSkipListMap<>(); - - final ConcurrentNavigableMap<String, String> serviceDefinitions = new ConcurrentSkipListMap<>(); + private final Lock lock = new ReentrantLock(); // ==================================================================================== // @@ -122,33 +91,6 @@ public class InMemoryWritableMetadataService implements WritableMetadataService } @Override - public boolean refreshMetadata(String revision) { - boolean result = true; - for (SortedSet<URL> urls : exportedServiceURLs.values()) { - Iterator<URL> iterator = urls.iterator(); - List<URL> newList = new ArrayList<>(urls.size()); - while (iterator.hasNext()) { - URL url = iterator.next(); - // refresh revision in urls - Map<String, String> parameters = new HashMap<>(url.getParameters()); - parameters.put(REVISION_KEY, revision); - URL newUrl = new URL(url.getProtocol(), url.getUsername(), url.getPassword(), url.getHost(), url.getPort(), url.getPath(), parameters); - newList.add(newUrl); - if (!finishRefreshExportedMetadata(newUrl)) { - result = false; - } - } - urls.clear(); - urls.addAll(newList); - } - return result; - } - - protected boolean finishRefreshExportedMetadata(URL url) { - return true; - } - - @Override public void publishServiceDefinition(URL providerUrl) { try { String interfaceName = providerUrl.getParameter(INTERFACE_KEY); @@ -231,10 +173,6 @@ public class InMemoryWritableMetadataService implements WritableMetadataService || protocol.equals(url.getProtocol()); } - private static SortedSet<String> getAllUnmodifiableServiceURLs(Map<String, SortedSet<URL>> serviceURLs) { - return MetadataService.toSortedStrings(serviceURLs.values().stream().flatMap(Collection::stream)); - } - static class URLComparator implements Comparator<URL> { diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/RemoteWritableMetadataService.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/RemoteWritableMetadataService.java index 79090b1..a2aa24f 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/RemoteWritableMetadataService.java +++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/RemoteWritableMetadataService.java @@ -27,10 +27,15 @@ import org.apache.dubbo.metadata.definition.model.ServiceDefinition; import org.apache.dubbo.metadata.report.MetadataReport; import org.apache.dubbo.metadata.report.MetadataReportInstance; import org.apache.dubbo.metadata.report.identifier.MetadataIdentifier; +import org.apache.dubbo.metadata.report.identifier.ServiceMetadataIdentifier; +import org.apache.dubbo.metadata.report.identifier.SubscriberMetadataIdentifier; import org.apache.dubbo.remoting.Constants; import org.apache.dubbo.rpc.RpcException; -import java.util.concurrent.atomic.AtomicBoolean; +import java.util.Iterator; +import java.util.Set; +import java.util.SortedSet; +import java.util.function.BiConsumer; import java.util.function.Consumer; import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY; @@ -47,11 +52,16 @@ import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY; * exported. * It is used by server (provider). * - * @since 2.7.0 + * @since 2.7.5 */ -public class RemoteWritableMetadataService extends InMemoryWritableMetadataService implements WritableMetadataService { +public class RemoteWritableMetadataService extends BaseWritableMetadataService implements WritableMetadataService { protected final Logger logger = LoggerFactory.getLogger(getClass()); + private volatile String exportedRevision; + private volatile String subscribedRevision; + + public RemoteWritableMetadataService() { + } public MetadataReport getMetadataReport() { return MetadataReportInstance.getMetadataReport(true); @@ -112,41 +122,109 @@ public class RemoteWritableMetadataService extends InMemoryWritableMetadataServi @Override public boolean exportURL(URL url) { - return super.exportURL(url); + return true; } @Override public boolean unexportURL(URL url) { - super.unexportURL(url); - return throwableAction(getMetadataReport()::removeServiceMetadata, url); + ServiceMetadataIdentifier metadataIdentifier = new ServiceMetadataIdentifier(url); + metadataIdentifier.setRevision(exportedRevision); + return throwableAction(getMetadataReport()::removeServiceMetadata, metadataIdentifier); } @Override public boolean subscribeURL(URL url) { - super.subscribeURL(url); - return throwableAction(getMetadataReport()::saveServiceMetadata, url); + return true; } @Override public boolean unsubscribeURL(URL url) { - super.unsubscribeURL(url); - return throwableAction(getMetadataReport()::removeServiceMetadata, url); + return true; } @Override - protected boolean finishRefreshExportedMetadata(URL url) { - return throwableAction(getMetadataReport()::saveServiceMetadata, url); + public boolean refreshMetadata(String exportedRevision, String subscribedRevision) { + boolean result = true; + if (!StringUtils.isEmpty(exportedRevision) && !exportedRevision.equals(this.exportedRevision)) { + this.exportedRevision = exportedRevision; + boolean executeResult = saveServiceMetadata(); + if (!executeResult) { + result = false; + } + } + if (!StringUtils.isEmpty(subscribedRevision) && !subscribedRevision.equals(this.subscribedRevision)) { + this.subscribedRevision = subscribedRevision; + SubscriberMetadataIdentifier metadataIdentifier = new SubscriberMetadataIdentifier(); + metadataIdentifier.setApplication(serviceName()); + metadataIdentifier.setRevision(subscribedRevision); + boolean executeResult = throwableAction(getMetadataReport()::saveSubscribedData, metadataIdentifier, super.getSubscribedURLs()); + if (!executeResult) { + result = false; + } + } + return result; } + private boolean saveServiceMetadata() { + boolean result = true; + for (SortedSet<URL> urls : exportedServiceURLs.values()) { + Iterator<URL> iterator = urls.iterator(); + while (iterator.hasNext()) { + URL url = iterator.next(); + // refresh revision in urls + ServiceMetadataIdentifier metadataIdentifier = new ServiceMetadataIdentifier(url); + metadataIdentifier.setRevision(exportedRevision); + + boolean tmpResult = throwableAction(getMetadataReport()::saveServiceMetadata, metadataIdentifier, url); + if (!tmpResult) result = tmpResult; + } + } + return result; + } - private boolean throwableAction(Consumer<URL> consumer, URL url) { + + @Override + public SortedSet<String> getExportedURLs(String serviceInterface, String group, String version, String protocol) { + return null; + } + + @Override + public String getServiceDefinition(String interfaceName, String version, String group) { + return null; + } + + @Override + public String getServiceDefinition(String serviceKey) { + return null; + } + + boolean throwableAction(BiConsumer<ServiceMetadataIdentifier, URL> consumer, ServiceMetadataIdentifier metadataIdentifier, URL url) { try { - consumer.accept(url); + consumer.accept(metadataIdentifier, url); } catch (Exception e) { - logger.error("Failed to remove url metadata to remote center, url is: " + url); + logger.error("Failed to execute consumer, url is: " + url); return false; } return true; } + boolean throwableAction(BiConsumer<SubscriberMetadataIdentifier, Set<String>> consumer, SubscriberMetadataIdentifier metadataIdentifier, Set<String> urls) { + try { + consumer.accept(metadataIdentifier, urls); + } catch (Exception e) { + logger.error("Failed to execute consumer, url is: " + urls); + return false; + } + return true; + } + + boolean throwableAction(Consumer<ServiceMetadataIdentifier> consumer, ServiceMetadataIdentifier metadataIdentifier) { + try { + consumer.accept(metadataIdentifier); + } catch (Exception e) { + logger.error("Failed to remove url metadata to remote center, metadataIdentifier is: " + metadataIdentifier); + return false; + } + return true; + } } diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReportFactoryTest.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReportFactoryTest.java index 31fb771..e96f4cd 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReportFactoryTest.java +++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReportFactoryTest.java @@ -30,6 +30,7 @@ import org.junit.jupiter.api.Test; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; /** @@ -48,12 +49,12 @@ public class AbstractMetadataReportFactoryTest { } @Override - public void saveServiceMetadata(URL url) { + public void saveServiceMetadata(ServiceMetadataIdentifier metadataIdentifier, URL url) { } @Override - public void removeServiceMetadata(URL url) { + public void removeServiceMetadata(ServiceMetadataIdentifier metadataIdentifier) { } @@ -63,7 +64,8 @@ public class AbstractMetadataReportFactoryTest { } @Override - public void saveSubscriberData(SubscriberMetadataIdentifier subscriberMetadataIdentifier, List<String> urls) { + public void saveSubscribedData(SubscriberMetadataIdentifier subscriberMetadataIdentifier, + Set<String> urls) { } diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReportTest.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReportTest.java index 60d8f3d..24239e5 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReportTest.java +++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReportTest.java @@ -297,7 +297,7 @@ public class AbstractMetadataReportTest { } @Override - protected void doRemoveMetadata(ServiceMetadataIdentifier metadataIdentifier, URL url) { + protected void doRemoveMetadata(ServiceMetadataIdentifier metadataIdentifier) { throw new UnsupportedOperationException("This extension does not support working as a remote metadata center."); } @@ -307,12 +307,12 @@ public class AbstractMetadataReportTest { } @Override - protected void doSaveSubscriberData(SubscriberMetadataIdentifier subscriberMetadataIdentifier, List<String> urls) { + protected void doSaveSubscriberData(SubscriberMetadataIdentifier subscriberMetadataIdentifier, String urls) { } @Override - protected List<String> doGetSubscribedURLs(SubscriberMetadataIdentifier metadataIdentifier) { + protected String doGetSubscribedURLs(SubscriberMetadataIdentifier metadataIdentifier) { throw new UnsupportedOperationException("This extension does not support working as a remote metadata center."); } @@ -358,7 +358,7 @@ public class AbstractMetadataReportTest { } @Override - protected void doRemoveMetadata(ServiceMetadataIdentifier metadataIdentifier, URL url) { + protected void doRemoveMetadata(ServiceMetadataIdentifier metadataIdentifier) { throw new UnsupportedOperationException("This extension does not support working as a remote metadata center."); } @@ -368,12 +368,12 @@ public class AbstractMetadataReportTest { } @Override - protected void doSaveSubscriberData(SubscriberMetadataIdentifier subscriberMetadataIdentifier, List<String> urls) { + protected void doSaveSubscriberData(SubscriberMetadataIdentifier subscriberMetadataIdentifier, String urls) { } @Override - protected List<String> doGetSubscribedURLs(SubscriberMetadataIdentifier metadataIdentifier) { + protected String doGetSubscribedURLs(SubscriberMetadataIdentifier metadataIdentifier) { throw new UnsupportedOperationException("This extension does not support working as a remote metadata center."); } diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/test/JTestMetadataReport4Test.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/test/JTestMetadataReport4Test.java index 48b77b7..57d41ee 100644 --- a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/test/JTestMetadataReport4Test.java +++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/test/JTestMetadataReport4Test.java @@ -67,7 +67,7 @@ public class JTestMetadataReport4Test extends AbstractMetadataReport { } @Override - protected void doRemoveMetadata(ServiceMetadataIdentifier metadataIdentifier, URL url) { + protected void doRemoveMetadata(ServiceMetadataIdentifier metadataIdentifier) { throw new UnsupportedOperationException("This extension does not support working as a remote metadata center."); } @@ -77,12 +77,12 @@ public class JTestMetadataReport4Test extends AbstractMetadataReport { } @Override - protected void doSaveSubscriberData(SubscriberMetadataIdentifier subscriberMetadataIdentifier, List<String> urls) { + protected void doSaveSubscriberData(SubscriberMetadataIdentifier subscriberMetadataIdentifier, String urls) { } @Override - protected List<String> doGetSubscribedURLs(SubscriberMetadataIdentifier metadataIdentifier) { + protected String doGetSubscribedURLs(SubscriberMetadataIdentifier metadataIdentifier) { throw new UnsupportedOperationException("This extension does not support working as a remote metadata center."); } diff --git a/dubbo-metadata/dubbo-metadata-report-consul/src/main/java/org/apache/dubbo/metadata/store/consul/ConsulMetadataReport.java b/dubbo-metadata/dubbo-metadata-report-consul/src/main/java/org/apache/dubbo/metadata/store/consul/ConsulMetadataReport.java index 1ad4516..ba96a08 100644 --- a/dubbo-metadata/dubbo-metadata-report-consul/src/main/java/org/apache/dubbo/metadata/store/consul/ConsulMetadataReport.java +++ b/dubbo-metadata/dubbo-metadata-report-consul/src/main/java/org/apache/dubbo/metadata/store/consul/ConsulMetadataReport.java @@ -63,7 +63,7 @@ public class ConsulMetadataReport extends AbstractMetadataReport { } @Override - protected void doRemoveMetadata(ServiceMetadataIdentifier serviceMetadataIdentifier, URL url) { + protected void doRemoveMetadata(ServiceMetadataIdentifier serviceMetadataIdentifier) { throw new UnsupportedOperationException("This extension does not support working as a remote metadata center."); } @@ -73,12 +73,12 @@ public class ConsulMetadataReport extends AbstractMetadataReport { } @Override - protected void doSaveSubscriberData(SubscriberMetadataIdentifier subscriberMetadataIdentifier, List<String> urls) { + protected void doSaveSubscriberData(SubscriberMetadataIdentifier subscriberMetadataIdentifier, String urlListStr) { } @Override - protected List<String> doGetSubscribedURLs(SubscriberMetadataIdentifier subscriberMetadataIdentifier) { + protected String doGetSubscribedURLs(SubscriberMetadataIdentifier subscriberMetadataIdentifier) { throw new UnsupportedOperationException("This extension does not support working as a remote metadata center."); } diff --git a/dubbo-metadata/dubbo-metadata-report-etcd/src/main/java/org/apache/dubbo/metadata/store/etcd/EtcdMetadataReport.java b/dubbo-metadata/dubbo-metadata-report-etcd/src/main/java/org/apache/dubbo/metadata/store/etcd/EtcdMetadataReport.java index 222eb19..507cd53 100644 --- a/dubbo-metadata/dubbo-metadata-report-etcd/src/main/java/org/apache/dubbo/metadata/store/etcd/EtcdMetadataReport.java +++ b/dubbo-metadata/dubbo-metadata-report-etcd/src/main/java/org/apache/dubbo/metadata/store/etcd/EtcdMetadataReport.java @@ -90,7 +90,7 @@ public class EtcdMetadataReport extends AbstractMetadataReport { } @Override - protected void doRemoveMetadata(ServiceMetadataIdentifier serviceMetadataIdentifier, URL url) { + protected void doRemoveMetadata(ServiceMetadataIdentifier serviceMetadataIdentifier) { throw new UnsupportedOperationException("This extension does not support working as a remote metadata center."); } @@ -100,12 +100,12 @@ public class EtcdMetadataReport extends AbstractMetadataReport { } @Override - protected void doSaveSubscriberData(SubscriberMetadataIdentifier subscriberMetadataIdentifier, List<String> urls) { + protected void doSaveSubscriberData(SubscriberMetadataIdentifier subscriberMetadataIdentifier, String urlListStr) { } @Override - protected List<String> doGetSubscribedURLs(SubscriberMetadataIdentifier subscriberMetadataIdentifier) { + protected String doGetSubscribedURLs(SubscriberMetadataIdentifier subscriberMetadataIdentifier) { throw new UnsupportedOperationException("This extension does not support working as a remote metadata center."); } diff --git a/dubbo-metadata/dubbo-metadata-report-nacos/src/main/java/org/apache/dubbo/metadata/store/nacos/NacosMetadataReport.java b/dubbo-metadata/dubbo-metadata-report-nacos/src/main/java/org/apache/dubbo/metadata/store/nacos/NacosMetadataReport.java index f1b5e90..bdbe759 100644 --- a/dubbo-metadata/dubbo-metadata-report-nacos/src/main/java/org/apache/dubbo/metadata/store/nacos/NacosMetadataReport.java +++ b/dubbo-metadata/dubbo-metadata-report-nacos/src/main/java/org/apache/dubbo/metadata/store/nacos/NacosMetadataReport.java @@ -131,7 +131,7 @@ public class NacosMetadataReport extends AbstractMetadataReport { } @Override - protected void doRemoveMetadata(ServiceMetadataIdentifier serviceMetadataIdentifier, URL url) { + protected void doRemoveMetadata(ServiceMetadataIdentifier serviceMetadataIdentifier) { throw new UnsupportedOperationException("This extension does not support working as a remote metadata center."); } @@ -141,12 +141,12 @@ public class NacosMetadataReport extends AbstractMetadataReport { } @Override - protected void doSaveSubscriberData(SubscriberMetadataIdentifier subscriberMetadataIdentifier, List<String> urls) { + protected void doSaveSubscriberData(SubscriberMetadataIdentifier subscriberMetadataIdentifier, String urlListStr) { throw new UnsupportedOperationException("This extension does not support working as a remote metadata center."); } @Override - protected List<String> doGetSubscribedURLs(SubscriberMetadataIdentifier subscriberMetadataIdentifier) { + protected String doGetSubscribedURLs(SubscriberMetadataIdentifier subscriberMetadataIdentifier) { throw new UnsupportedOperationException("This extension does not support working as a remote metadata center."); } diff --git a/dubbo-metadata/dubbo-metadata-report-redis/src/main/java/org/apache/dubbo/metadata/store/redis/RedisMetadataReport.java b/dubbo-metadata/dubbo-metadata-report-redis/src/main/java/org/apache/dubbo/metadata/store/redis/RedisMetadataReport.java index cebf14c..c9b3bb4 100644 --- a/dubbo-metadata/dubbo-metadata-report-redis/src/main/java/org/apache/dubbo/metadata/store/redis/RedisMetadataReport.java +++ b/dubbo-metadata/dubbo-metadata-report-redis/src/main/java/org/apache/dubbo/metadata/store/redis/RedisMetadataReport.java @@ -86,7 +86,7 @@ public class RedisMetadataReport extends AbstractMetadataReport { } @Override - protected void doRemoveMetadata(ServiceMetadataIdentifier serviceMetadataIdentifier, URL url) { + protected void doRemoveMetadata(ServiceMetadataIdentifier serviceMetadataIdentifier) { } @@ -96,12 +96,12 @@ public class RedisMetadataReport extends AbstractMetadataReport { } @Override - protected void doSaveSubscriberData(SubscriberMetadataIdentifier subscriberMetadataIdentifier, List<String> urls) { + protected void doSaveSubscriberData(SubscriberMetadataIdentifier subscriberMetadataIdentifier, String urlListStr) { throw new UnsupportedOperationException("This extension does not support working as a remote metadata center."); } @Override - protected List<String> doGetSubscribedURLs(SubscriberMetadataIdentifier subscriberMetadataIdentifier) { + protected String doGetSubscribedURLs(SubscriberMetadataIdentifier subscriberMetadataIdentifier) { throw new UnsupportedOperationException("This extension does not support working as a remote metadata center."); } diff --git a/dubbo-metadata/dubbo-metadata-report-zookeeper/src/main/java/org/apache/dubbo/metadata/store/zookeeper/ZookeeperMetadataReport.java b/dubbo-metadata/dubbo-metadata-report-zookeeper/src/main/java/org/apache/dubbo/metadata/store/zookeeper/ZookeeperMetadataReport.java index d1224cb..b370a62 100644 --- a/dubbo-metadata/dubbo-metadata-report-zookeeper/src/main/java/org/apache/dubbo/metadata/store/zookeeper/ZookeeperMetadataReport.java +++ b/dubbo-metadata/dubbo-metadata-report-zookeeper/src/main/java/org/apache/dubbo/metadata/store/zookeeper/ZookeeperMetadataReport.java @@ -80,7 +80,7 @@ public class ZookeeperMetadataReport extends AbstractMetadataReport { } @Override - protected void doRemoveMetadata(ServiceMetadataIdentifier metadataIdentifier, URL url) { + protected void doRemoveMetadata(ServiceMetadataIdentifier metadataIdentifier) { zkClient.delete(getNodePath(metadataIdentifier)); } @@ -90,18 +90,18 @@ public class ZookeeperMetadataReport extends AbstractMetadataReport { } @Override - protected void doSaveSubscriberData(SubscriberMetadataIdentifier subscriberMetadataIdentifier, List<String> urls) { - + protected void doSaveSubscriberData(SubscriberMetadataIdentifier subscriberMetadataIdentifier, String urls) { + zkClient.create(getNodePath(subscriberMetadataIdentifier), urls, false); } @Override - protected List<String> doGetSubscribedURLs(SubscriberMetadataIdentifier subscriberMetadataIdentifier) { - return null; + protected String doGetSubscribedURLs(SubscriberMetadataIdentifier subscriberMetadataIdentifier) { + return zkClient.getContent(getNodePath(subscriberMetadataIdentifier)); } @Override - public String getServiceDefinition(MetadataIdentifier consumerMetadataIdentifier) { - throw new UnsupportedOperationException("This extension does not support working as a remote metadata center."); + public String getServiceDefinition(MetadataIdentifier metadataIdentifier) { + return zkClient.getContent(getNodePath(metadataIdentifier)); } private void storeMetadata(MetadataIdentifier metadataIdentifier, String v) { @@ -116,5 +116,9 @@ public class ZookeeperMetadataReport extends AbstractMetadataReport { return toRootDir() + metadataIdentifier.getUniqueKey(MetadataIdentifier.KeyTypeEnum.PATH); } + String getNodePath(SubscriberMetadataIdentifier metadataIdentifier) { + return toRootDir() + metadataIdentifier.getUniqueKey(MetadataIdentifier.KeyTypeEnum.PATH); + } + } diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/RefreshServiceMetadataCustomizer.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/RefreshServiceMetadataCustomizer.java index 342681c..5681b98 100644 --- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/RefreshServiceMetadataCustomizer.java +++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/RefreshServiceMetadataCustomizer.java @@ -6,7 +6,11 @@ import org.apache.dubbo.registry.client.ServiceInstanceCustomizer; import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_KEY; import static org.apache.dubbo.common.constants.CommonConstants.REVISION_KEY; +import static org.apache.dubbo.metadata.WritableMetadataService.DEFAULT_EXTENSION; import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.EXPORTED_SERVICES_REVISION_KEY; +import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.getExportedServicesRevision; +import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.getMetadataStoredType; +import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.getSubscribedServicesRevision; /** * An {@link ServiceInstanceCustomizer} to refresh metadata. @@ -14,14 +18,19 @@ import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataU * 2019-08-08 */ public class RefreshServiceMetadataCustomizer implements ServiceInstanceCustomizer { + + public int getPriority() { + return MAX_PRIORITY; + } + @Override public void customize(ServiceInstance serviceInstance) { // FIXME to define the constant + String metadataStoredType = getMetadataStoredType(serviceInstance); WritableMetadataService remoteWritableMetadataService = - WritableMetadataService.getExtension(serviceInstance.getMetadata().getOrDefault(REVISION_KEY, DEFAULT_KEY)); - // FIXME TEST - remoteWritableMetadataService = - WritableMetadataService.getExtension("remote"); - remoteWritableMetadataService.refreshMetadata(serviceInstance.getMetadata().get(EXPORTED_SERVICES_REVISION_KEY)); + WritableMetadataService.getExtension(metadataStoredType == null ? DEFAULT_EXTENSION : metadataStoredType); + + remoteWritableMetadataService.refreshMetadata(getExportedServicesRevision(serviceInstance), + getSubscribedServicesRevision(serviceInstance)); } } diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataUtils.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataUtils.java index dcebcec..329dea8 100644 --- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataUtils.java +++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataUtils.java @@ -65,6 +65,16 @@ public class ServiceInstanceMetadataUtils { public static String EXPORTED_SERVICES_REVISION_KEY = "dubbo.exported-services.revision"; /** + * The key of The revision for all subscribed Dubbo services. + */ + public static String SUBSCRIBER_SERVICES_REVISION_KEY = "dubbo.subscribed-services.revision"; + + /** + * The key of metadata store type. + */ + public static String MEATADATA_STORED_TYPE_KEY = "dubbo.metadata.stored-type"; + + /** * The {@link URL url's} parameter name of Dubbo Provider host */ public static final String HOST_PARAM_NAME = "provider.host"; @@ -159,6 +169,28 @@ public class ServiceInstanceMetadataUtils { return metadata.get(EXPORTED_SERVICES_REVISION_KEY); } + /** + * The revision for all subscribed Dubbo services from the specified {@link ServiceInstance}. + * + * @param serviceInstance the specified {@link ServiceInstance} + * @return <code>null</code> if not exits + */ + public static String getSubscribedServicesRevision(ServiceInstance serviceInstance) { + Map<String, String> metadata = serviceInstance.getMetadata(); + return metadata.get(SUBSCRIBER_SERVICES_REVISION_KEY); + } + + /** + * The metadata is stored in the type used to which {@link org.apache.dubbo.metadata.WritableMetadataService} instance. + * + * @param serviceInstance the specified {@link ServiceInstance} + * @return <code>null</code> if not exits + */ + public static String getMetadataStoredType(ServiceInstance serviceInstance) { + Map<String, String> metadata = serviceInstance.getMetadata(); + return metadata.get(MEATADATA_STORED_TYPE_KEY); + } + private static void setProviderHostParam(Map<String, String> params, URL providerURL) { params.put(HOST_PARAM_NAME, providerURL.getHost()); } diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/SubscribedServicesRevisionMetadataCustomizer.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/SubscribedServicesRevisionMetadataCustomizer.java new file mode 100644 index 0000000..7197e10 --- /dev/null +++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/SubscribedServicesRevisionMetadataCustomizer.java @@ -0,0 +1,73 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.dubbo.registry.client.metadata; + +import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.compiler.support.ClassUtils; +import org.apache.dubbo.metadata.MetadataService; +import org.apache.dubbo.metadata.WritableMetadataService; +import org.apache.dubbo.registry.client.ServiceInstance; +import org.apache.dubbo.registry.client.ServiceInstanceMetadataCustomizer; + +import java.util.Arrays; +import java.util.Collection; +import java.util.SortedSet; + +import static java.lang.String.valueOf; +import static java.util.Objects.hash; +import static org.apache.dubbo.common.constants.CommonConstants.METADATA_KEY; +import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.EXPORTED_SERVICES_REVISION_KEY; +import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.SUBSCRIBER_SERVICES_REVISION_KEY; + +/** + * The customizer to a add the metadata that the reversion of Dubbo subscribed services calculates. + * <p> + * The reversion is calculated on the methods that all Dubbo subscribed interfaces declare + * + * @since 2.7.5 + */ +public class SubscribedServicesRevisionMetadataCustomizer extends ServiceInstanceMetadataCustomizer { + + @Override + protected String buildMetadataKey(ServiceInstance serviceInstance) { + return SUBSCRIBER_SERVICES_REVISION_KEY; + } + + @Override + protected String buildMetadataValue(ServiceInstance serviceInstance) { + WritableMetadataService writableMetadataService = WritableMetadataService.getExtension( + serviceInstance.getMetadata().get(METADATA_KEY) + ); + SortedSet<String> subscribedURLs = writableMetadataService.getSubscribedURLs(); + Object[] data = subscribedURLs.stream() + .map(URL::valueOf) // String to URL + .map(URL::getServiceInterface) // get the service interface + .filter(this::isNotMetadataService) // filter not MetadataService interface + .map(ClassUtils::forName) // load business interface class + .map(Class::getMethods) // get all public methods from business interface + .map(Arrays::asList) // Array to List + .flatMap(Collection::stream) // flat Stream<Stream> to be Stream + .map(Object::toString) // Method to String + .sorted() // sort methods marking sure the calculation of reversion is stable + .toArray(); // Stream to Array + return valueOf(hash(data)); // calculate the hash code as reversion + } + + private boolean isNotMetadataService(String serviceInterface) { + return !MetadataService.class.getName().equals(serviceInterface); + } +} diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/service/ServiceOrientedRegistry.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/service/ServiceOrientedRegistry.java index 13b4eed..5fdc35f 100644 --- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/service/ServiceOrientedRegistry.java +++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/service/ServiceOrientedRegistry.java @@ -66,9 +66,11 @@ import static org.apache.dubbo.common.extension.ExtensionLoader.getExtensionLoad import static org.apache.dubbo.common.utils.CollectionUtils.isEmpty; import static org.apache.dubbo.common.utils.CollectionUtils.isNotEmpty; import static org.apache.dubbo.common.utils.StringUtils.isBlank; +import static org.apache.dubbo.metadata.WritableMetadataService.DEFAULT_EXTENSION; import static org.apache.dubbo.metadata.report.support.Constants.METADATA_REPORT_KEY; import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.getExportedServicesRevision; import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.getMetadataServiceURLsParams; +import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.getMetadataStoredType; import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.getProviderHost; import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.getProviderPort; @@ -95,7 +97,6 @@ public class ServiceOrientedRegistry extends FailbackRegistry { private final WritableMetadataService writableMetadataService; - private final MetadataServiceProxyFactory metadataServiceProxyFactory; public ServiceOrientedRegistry(URL registryURL) { super(registryURL); @@ -105,9 +106,7 @@ public class ServiceOrientedRegistry extends FailbackRegistry { String metadata = registryURL.getParameter(METADATA_REPORT_KEY, METADATA_DEFAULT); // FIXME - metadata = "remote"; this.writableMetadataService = WritableMetadataService.getExtension(metadata); - this.metadataServiceProxyFactory = MetadataServiceProxyFactory.getExtension(metadata); } private Set<String> buildSubscribedServices(URL url) { @@ -430,9 +429,12 @@ public class ServiceOrientedRegistry extends FailbackRegistry { String version = subscribedURL.getParameter(VERSION_KEY); // The subscribed protocol may be null String protocol = subscribedURL.getParameter(PROTOCOL_KEY); + String metadataServiceType = getMetadataStoredType(providerInstance); try { - MetadataService metadataService = metadataServiceProxyFactory.getProxy(providerInstance); + MetadataService metadataService = MetadataServiceProxyFactory + .getExtension(metadataServiceType == null ? DEFAULT_EXTENSION : metadataServiceType) + .getProxy(providerInstance); SortedSet<String> urls = metadataService.getExportedURLs(serviceInterface, group, version, protocol); exportedURLs = urls.stream().map(URL::valueOf).collect(Collectors.toList()); } catch (Throwable e) { @@ -440,7 +442,6 @@ public class ServiceOrientedRegistry extends FailbackRegistry { logger.error(e.getMessage(), e); } } - return exportedURLs; } diff --git a/dubbo-registry/dubbo-registry-api/src/main/resources/META-INF/services/org.apache.dubbo.registry.client.ServiceInstanceCustomizer b/dubbo-registry/dubbo-registry-api/src/main/resources/META-INF/services/org.apache.dubbo.registry.client.ServiceInstanceCustomizer index 6c66ada..7b06893 100644 --- a/dubbo-registry/dubbo-registry-api/src/main/resources/META-INF/services/org.apache.dubbo.registry.client.ServiceInstanceCustomizer +++ b/dubbo-registry/dubbo-registry-api/src/main/resources/META-INF/services/org.apache.dubbo.registry.client.ServiceInstanceCustomizer @@ -1,3 +1,4 @@ org.apache.dubbo.registry.client.metadata.MetadataServiceURLParamsMetadataCustomizer org.apache.dubbo.registry.client.metadata.ExportedServicesRevisionMetadataCustomizer +org.apache.dubbo.registry.client.metadata.SubscribedServicesRevisionMetadataCustomizer org.apache.dubbo.registry.client.metadata.RefreshServiceMetadataCustomizer