You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by li...@apache.org on 2021/11/04 14:28:20 UTC
[dubbo] 01/02: try to refactor metadata
This is an automated email from the ASF dual-hosted git repository.
liujun pushed a commit to branch 3.0-metadata-refactor
in repository https://gitbox.apache.org/repos/asf/dubbo.git
commit b10e5bfc28d2e23376b4c6492d0c8c4ed37d995b
Author: ken.lj <ke...@gmail.com>
AuthorDate: Thu Nov 4 19:20:57 2021 +0800
try to refactor metadata
---
.../dubbo/rpc/model/ModuleServiceRepository.java | 9 +
.../apache/dubbo/rpc/model/ServiceDescriptor.java | 20 +
.../dubbo/metadata/definition/MetadataTest.java | 0
.../dubbo/metadata/definition/MetadataUtils.java | 0
.../definition/ServiceDefinitionBuilderTest.java | 1 +
.../metadata/definition/Test3TypeBuilder.java | 0
.../dubbo/metadata/definition/TestTypeBuilder.java | 0
.../definition/TypeDefinitionBuilderTest.java | 0
.../definition/common/ClassExtendsMap.java | 0
.../metadata/definition/common/ColorEnum.java | 0
.../metadata/definition/common/OuterClass.java | 0
.../common/ResultWithRawCollections.java | 0
.../metadata/definition/common/TestService.java | 0
.../metadata/definition/service/ComplexObject.java | 4 +-
.../metadata/definition/service/DemoService.java | 0
.../service/annotation/MockMethodAnnotation.java | 0
.../service/annotation/MockMethodAnnotation2.java | 0
.../service/annotation/MockTypeAnnotation.java | 0
.../org/apache/dubbo/config/ReferenceConfig.java | 12 +-
.../org/apache/dubbo/config/ServiceConfig.java | 14 +-
.../config/deploy/DefaultApplicationDeployer.java | 88 +-
.../config/metadata}/MetadataReportInstance.java | 4 +-
.../ServiceInstanceHostPortCustomizer.java | 83 --
.../dubbo/config/mock/MockServiceDiscovery.java | 8 +-
...terServiceDiscoveryRegistryIntegrationTest.java | 4 +-
...ceDiscoveryRegistryRegistryServiceListener.java | 4 +-
.../ServiceDiscoveryRegistryInfoWrapper.java | 10 +-
...RegistryCenterDubboProtocolIntegrationTest.java | 19 +-
dubbo-metadata/dubbo-metadata-api/pom.xml | 4 +-
.../dubbo/metadata/AbstractServiceNameMapping.java | 80 +-
.../org/apache/dubbo/metadata/MappingListener.java | 2 +
.../org/apache/dubbo/metadata/MetadataInfo.java | 118 ++-
.../org/apache/dubbo/metadata/MetadataService.java | 5 +-
.../apache/dubbo/metadata/ServiceNameMapping.java | 30 +-
.../dubbo/metadata/WritableMetadataService.java | 64 +-
.../definition/MethodDefinitionBuilder.java | 78 --
.../definition/ServiceDefinitionBuilder.java | 126 ---
.../metadata/definition/TypeDefinitionBuilder.java | 87 --
.../definition/builder/ArrayTypeBuilder.java | 56 --
.../definition/builder/CollectionTypeBuilder.java | 83 --
.../definition/builder/DefaultTypeBuilder.java | 65 --
.../definition/builder/EnumTypeBuilder.java | 69 --
.../definition/builder/MapTypeBuilder.java | 87 --
.../metadata/definition/builder/TypeBuilder.java | 42 -
.../definition/model/FullServiceDefinition.java | 43 -
.../definition/model/MethodDefinition.java | 117 ---
.../definition/model/ServiceDefinition.java | 136 ---
.../metadata/definition/model/TypeDefinition.java | 183 ----
.../dubbo/metadata/definition/util/ClassUtils.java | 164 ----
.../definition/util/JaketConfigurationUtils.java | 102 --
.../dubbo/metadata/report/MetadataReport.java | 4 +
.../AbstractAbstractWritableMetadataService.java | 98 --
.../metadata/AbstractServiceNameMappingTest.java | 117 +--
.../apache/dubbo/metadata/MetadataInfoTest.java | 30 +-
.../support/AbstractMetadataReportFactoryTest.java | 6 +
.../report/support/AbstractMetadataReportTest.java | 14 +-
.../metadata/test/JTestMetadataReport4Test.java | 6 +
.../store/nacos/NacosConfigServiceWrapper.java | 4 +
.../metadata/store/nacos/NacosMetadataReport.java | 54 +-
.../store/zookeeper/ZookeeperMetadataReport.java | 28 +-
.../dubbo/qos/command/impl/PublishMetadata.java | 32 +-
.../registry/RegistryScopeModelInitializer.java | 2 -
.../registry/client/AbstractServiceDiscovery.java | 157 ++-
.../client/AbstractServiceDiscoveryFactory.java | 10 +-
.../client/FileSystemServiceDiscovery.java | 429 ++++----
.../client/SelfHostMetaServiceDiscovery.java | 308 ------
.../dubbo/registry/client/ServiceDiscovery.java | 82 +-
.../registry/client/ServiceDiscoveryFactory.java | 4 +-
.../registry/client/ServiceDiscoveryRegistry.java | 67 +-
.../listener/ServiceInstancesChangedListener.java | 148 +--
.../metadata/MetadataServiceNameMapping.java | 72 +-
...MetadataServiceURLParamsMetadataCustomizer.java | 23 +-
.../registry/client/metadata/MetadataUtils.java | 145 ++-
.../ServiceInstanceMetadataCustomizer.java | 13 +-
.../metadata/ServiceInstanceMetadataUtils.java | 84 +-
.../store/InMemoryWritableMetadataService.java | 467 ---------
.../metadata/store/MetadataServiceDelegation.java | 228 +++++
.../metadata/store/RemoteMetadataServiceImpl.java | 170 ----
.../client/migration/model/MigrationRule.java | 14 +-
...g.apache.dubbo.metadata.WritableMetadataService | 2 +-
.../ServiceInstancesChangedListenerTest.java | 1030 ++++++++++----------
...dataServiceURLParamsMetadataCustomizerTest.java | 11 +-
.../ProtocolPortsMetadataCustomizerTest.java | 11 +-
.../ServiceInstanceMetadataCustomizerTest.java | 6 +-
.../metadata/ServiceInstanceMetadataUtilsTest.java | 49 +-
.../store/InMemoryMetadataServiceTest.java | 11 +-
.../store/RemoteMetadataServiceImplTest.java | 134 ---
.../client/migration/model/MigrationRuleTest.java | 8 +-
.../dubbo/registry/consul/ConsulParameter.java | 87 --
.../consul/ConsulServiceDiscoveryFactory.java | 30 -
...e.dubbo.registry.client.ServiceDiscoveryFactory | 1 -
dubbo-registry/dubbo-registry-dns/pom.xml | 90 --
.../org/apache/dubbo/registry/dns/DNSRegistry.java | 58 --
.../dubbo/registry/dns/DNSRegistryFactory.java | 34 -
.../dubbo/registry/dns/DNSServiceDiscovery.java | 153 ---
.../registry/dns/DNSServiceDiscoveryFactory.java | 28 -
.../dubbo/registry/dns/util/DNSClientConst.java | 47 -
.../dubbo/registry/dns/util/DNSResolver.java | 120 ---
.../dubbo/registry/dns/util/ResolveResult.java | 66 --
.../org.apache.dubbo.registry.RegistryFactory | 1 -
...g.apache.dubbo.registry.client.ServiceDiscovery | 1 -
...e.dubbo.registry.client.ServiceDiscoveryFactory | 1 -
.../registry/dns/DNSServiceDiscoveryTest.java | 198 ----
.../dubbo/registry/dns/util/DNSResolverTest.java | 30 -
.../src/test/resources/dubbo.properties | 2 -
dubbo-registry/dubbo-registry-kubernetes/pom.xml | 73 --
.../kubernetes/KubernetesMeshEnvListener.java | 197 ----
.../KubernetesMeshEnvListenerFactory.java | 42 -
.../registry/kubernetes/KubernetesRegistry.java | 58 --
.../kubernetes/KubernetesRegistryFactory.java | 34 -
.../kubernetes/KubernetesServiceDiscovery.java | 399 --------
.../KubernetesServiceDiscoveryFactory.java | 28 -
.../dubbo/registry/kubernetes/MeshConstant.java | 43 -
.../kubernetes/util/KubernetesClientConst.java | 76 --
.../kubernetes/util/KubernetesConfigUtils.java | 113 ---
.../org.apache.dubbo.registry.RegistryFactory | 1 -
...g.apache.dubbo.registry.client.ServiceDiscovery | 1 -
...e.dubbo.registry.client.ServiceDiscoveryFactory | 1 -
...luster.router.mesh.route.MeshEnvListenerFactory | 1 -
.../kubernetes/KubernetesServiceDiscoveryTest.java | 198 ----
.../org.mockito.plugins.MockMaker | 1 -
.../multicast/MulticastServiceDiscovery.java | 8 +-
.../MulticastServiceDiscoveryFactory.java | 8 +-
.../multiple/MultipleServiceDiscovery.java | 45 +-
.../registry/nacos/NacosServiceDiscovery.java | 17 +-
.../nacos/NacosServiceDiscoveryFactory.java | 2 +-
.../nacos/util/NacosNamingServiceUtils.java | 21 +-
dubbo-registry/dubbo-registry-xds/pom.xml | 115 ---
.../dubbo/registry/xds/XdsCertificateSigner.java | 52 -
.../java/org/apache/dubbo/registry/xds/XdsEnv.java | 21 -
.../org/apache/dubbo/registry/xds/XdsRegistry.java | 58 --
.../dubbo/registry/xds/XdsRegistryFactory.java | 34 -
.../dubbo/registry/xds/XdsServiceDiscovery.java | 89 --
.../registry/xds/XdsServiceDiscoveryFactory.java | 38 -
.../xds/istio/IstioCitadelCertificateSigner.java | 249 -----
.../dubbo/registry/xds/istio/IstioConstant.java | 53 -
.../apache/dubbo/registry/xds/istio/IstioEnv.java | 121 ---
.../dubbo/registry/xds/util/NodeBuilder.java | 29 -
.../dubbo/registry/xds/util/PilotExchanger.java | 163 ----
.../apache/dubbo/registry/xds/util/XdsChannel.java | 80 --
.../xds/util/protocol/AbstractProtocol.java | 242 -----
.../registry/xds/util/protocol/DeltaResource.java | 32 -
.../registry/xds/util/protocol/XdsProtocol.java | 48 -
.../xds/util/protocol/delta/DeltaEndpoint.java | 51 -
.../xds/util/protocol/delta/DeltaListener.java | 49 -
.../xds/util/protocol/delta/DeltaRoute.java | 47 -
.../xds/util/protocol/impl/EdsProtocol.java | 93 --
.../xds/util/protocol/impl/LdsProtocol.java | 106 --
.../xds/util/protocol/impl/RdsProtocol.java | 94 --
.../xds/util/protocol/message/Endpoint.java | 88 --
.../xds/util/protocol/message/EndpointResult.java | 62 --
.../xds/util/protocol/message/ListenerResult.java | 70 --
.../xds/util/protocol/message/RouteResult.java | 73 --
.../dubbo-registry-xds/src/main/proto/ca.proto | 57 --
.../org.apache.dubbo.registry.RegistryFactory | 1 -
...g.apache.dubbo.registry.client.ServiceDiscovery | 1 -
...e.dubbo.registry.client.ServiceDiscoveryFactory | 1 -
....apache.dubbo.registry.xds.XdsCertificateSigner | 1 -
.../zookeeper/ZookeeperServiceDiscovery.java | 27 +-
.../ZookeeperServiceDiscoveryFactory.java | 2 +-
.../zookeeper/util/CuratorFrameworkUtils.java | 12 +-
dubbo-registry/pom.xml | 3 -
162 files changed, 1888 insertions(+), 8787 deletions(-)
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ModuleServiceRepository.java b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ModuleServiceRepository.java
index 9710eb55..5b8a58b 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ModuleServiceRepository.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ModuleServiceRepository.java
@@ -186,6 +186,15 @@ public class ModuleServiceRepository {
return Collections.unmodifiableList(serviceDescriptors);
}
+ public ServiceDescriptor getService(String serviceName) {
+ // TODO, may need to distinguish service by class loader.
+ List<ServiceDescriptor> serviceDescriptors = services.get(serviceName);
+ if (CollectionUtils.isEmpty(serviceDescriptors)) {
+ return null;
+ }
+ return serviceDescriptors.get(0);
+ }
+
public ServiceDescriptor lookupService(String interfaceName) {
if (services.containsKey(interfaceName)) {
List<ServiceDescriptor> serviceDescriptors = services.get(interfaceName);
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ServiceDescriptor.java b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ServiceDescriptor.java
index c063ec5..b3ac2f4 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ServiceDescriptor.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/rpc/model/ServiceDescriptor.java
@@ -17,16 +17,21 @@
package org.apache.dubbo.rpc.model;
import org.apache.dubbo.common.utils.CollectionUtils;
+import org.apache.dubbo.metadata.definition.ServiceDefinitionBuilder;
+import org.apache.dubbo.metadata.definition.model.FullServiceDefinition;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
+import java.util.concurrent.ConcurrentNavigableMap;
+import java.util.concurrent.ConcurrentSkipListMap;
/**
* ServiceModel and ServiceMetadata are to some extend duplicated with each other. We should merge them in the future.
@@ -37,11 +42,18 @@ public class ServiceDescriptor {
// to accelerate search
private final Map<String, List<MethodDescriptor>> methods = new HashMap<>();
private final Map<String, Map<String, MethodDescriptor>> descToMethods = new HashMap<>();
+ private ConcurrentNavigableMap<String, FullServiceDefinition> serviceDefinitions = new ConcurrentSkipListMap<>();
public ServiceDescriptor(Class<?> interfaceClass) {
this.serviceInterfaceClass = interfaceClass;
this.serviceName = interfaceClass.getName();
initMethods();
+ initServiceDefinition(interfaceClass);
+ }
+
+ private void initServiceDefinition(Class<?> interfaceClass) {
+ FullServiceDefinition fullServiceDefinition = ServiceDefinitionBuilder.buildFullDefinition(interfaceClass, Collections.emptyMap());
+ serviceDefinitions.put(serviceName, fullServiceDefinition);
}
private void initMethods() {
@@ -116,6 +128,14 @@ public class ServiceDescriptor {
return methods.get(methodName);
}
+ public ConcurrentNavigableMap<String, FullServiceDefinition> getServiceDefinitions() {
+ return serviceDefinitions;
+ }
+
+ public FullServiceDefinition getServiceDefinition(String serviceName) {
+ return serviceDefinitions.get(serviceName);
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) {
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/MetadataTest.java b/dubbo-common/src/test/java/org/apache/dubbo/metadata/definition/MetadataTest.java
similarity index 100%
rename from dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/MetadataTest.java
rename to dubbo-common/src/test/java/org/apache/dubbo/metadata/definition/MetadataTest.java
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/MetadataUtils.java b/dubbo-common/src/test/java/org/apache/dubbo/metadata/definition/MetadataUtils.java
similarity index 100%
rename from dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/MetadataUtils.java
rename to dubbo-common/src/test/java/org/apache/dubbo/metadata/definition/MetadataUtils.java
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/ServiceDefinitionBuilderTest.java b/dubbo-common/src/test/java/org/apache/dubbo/metadata/definition/ServiceDefinitionBuilderTest.java
similarity index 99%
rename from dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/ServiceDefinitionBuilderTest.java
rename to dubbo-common/src/test/java/org/apache/dubbo/metadata/definition/ServiceDefinitionBuilderTest.java
index 91d65bf..a6bb55b 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/ServiceDefinitionBuilderTest.java
+++ b/dubbo-common/src/test/java/org/apache/dubbo/metadata/definition/ServiceDefinitionBuilderTest.java
@@ -21,6 +21,7 @@ import org.apache.dubbo.metadata.definition.model.MethodDefinition;
import org.apache.dubbo.metadata.definition.model.TypeDefinition;
import org.apache.dubbo.metadata.definition.service.ComplexObject;
import org.apache.dubbo.metadata.definition.service.DemoService;
+
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/Test3TypeBuilder.java b/dubbo-common/src/test/java/org/apache/dubbo/metadata/definition/Test3TypeBuilder.java
similarity index 100%
rename from dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/Test3TypeBuilder.java
rename to dubbo-common/src/test/java/org/apache/dubbo/metadata/definition/Test3TypeBuilder.java
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/TestTypeBuilder.java b/dubbo-common/src/test/java/org/apache/dubbo/metadata/definition/TestTypeBuilder.java
similarity index 100%
rename from dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/TestTypeBuilder.java
rename to dubbo-common/src/test/java/org/apache/dubbo/metadata/definition/TestTypeBuilder.java
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/TypeDefinitionBuilderTest.java b/dubbo-common/src/test/java/org/apache/dubbo/metadata/definition/TypeDefinitionBuilderTest.java
similarity index 100%
rename from dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/TypeDefinitionBuilderTest.java
rename to dubbo-common/src/test/java/org/apache/dubbo/metadata/definition/TypeDefinitionBuilderTest.java
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/common/ClassExtendsMap.java b/dubbo-common/src/test/java/org/apache/dubbo/metadata/definition/common/ClassExtendsMap.java
similarity index 100%
rename from dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/common/ClassExtendsMap.java
rename to dubbo-common/src/test/java/org/apache/dubbo/metadata/definition/common/ClassExtendsMap.java
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/common/ColorEnum.java b/dubbo-common/src/test/java/org/apache/dubbo/metadata/definition/common/ColorEnum.java
similarity index 100%
rename from dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/common/ColorEnum.java
rename to dubbo-common/src/test/java/org/apache/dubbo/metadata/definition/common/ColorEnum.java
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/common/OuterClass.java b/dubbo-common/src/test/java/org/apache/dubbo/metadata/definition/common/OuterClass.java
similarity index 100%
rename from dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/common/OuterClass.java
rename to dubbo-common/src/test/java/org/apache/dubbo/metadata/definition/common/OuterClass.java
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/common/ResultWithRawCollections.java b/dubbo-common/src/test/java/org/apache/dubbo/metadata/definition/common/ResultWithRawCollections.java
similarity index 100%
rename from dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/common/ResultWithRawCollections.java
rename to dubbo-common/src/test/java/org/apache/dubbo/metadata/definition/common/ResultWithRawCollections.java
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/common/TestService.java b/dubbo-common/src/test/java/org/apache/dubbo/metadata/definition/common/TestService.java
similarity index 100%
rename from dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/common/TestService.java
rename to dubbo-common/src/test/java/org/apache/dubbo/metadata/definition/common/TestService.java
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/service/ComplexObject.java b/dubbo-common/src/test/java/org/apache/dubbo/metadata/definition/service/ComplexObject.java
similarity index 98%
rename from dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/service/ComplexObject.java
rename to dubbo-common/src/test/java/org/apache/dubbo/metadata/definition/service/ComplexObject.java
index 9371e8a..b984dee 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/service/ComplexObject.java
+++ b/dubbo-common/src/test/java/org/apache/dubbo/metadata/definition/service/ComplexObject.java
@@ -32,8 +32,8 @@ public class ComplexObject {
public ComplexObject() {
}
- public ComplexObject(String var1, int var2, long l, String[] var3, List<Integer> var4, ComplexObject.TestEnum testEnum) {
- this.setInnerObject(new ComplexObject.InnerObject());
+ public ComplexObject(String var1, int var2, long l, String[] var3, List<Integer> var4, TestEnum testEnum) {
+ this.setInnerObject(new InnerObject());
this.getInnerObject().setInnerA(var1);
this.getInnerObject().setInnerB(var2);
this.setIntList(var4);
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/service/DemoService.java b/dubbo-common/src/test/java/org/apache/dubbo/metadata/definition/service/DemoService.java
similarity index 100%
rename from dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/service/DemoService.java
rename to dubbo-common/src/test/java/org/apache/dubbo/metadata/definition/service/DemoService.java
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/service/annotation/MockMethodAnnotation.java b/dubbo-common/src/test/java/org/apache/dubbo/metadata/definition/service/annotation/MockMethodAnnotation.java
similarity index 100%
rename from dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/service/annotation/MockMethodAnnotation.java
rename to dubbo-common/src/test/java/org/apache/dubbo/metadata/definition/service/annotation/MockMethodAnnotation.java
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/service/annotation/MockMethodAnnotation2.java b/dubbo-common/src/test/java/org/apache/dubbo/metadata/definition/service/annotation/MockMethodAnnotation2.java
similarity index 100%
rename from dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/service/annotation/MockMethodAnnotation2.java
rename to dubbo-common/src/test/java/org/apache/dubbo/metadata/definition/service/annotation/MockMethodAnnotation2.java
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/service/annotation/MockTypeAnnotation.java b/dubbo-common/src/test/java/org/apache/dubbo/metadata/definition/service/annotation/MockTypeAnnotation.java
similarity index 100%
rename from dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/definition/service/annotation/MockTypeAnnotation.java
rename to dubbo-common/src/test/java/org/apache/dubbo/metadata/definition/service/annotation/MockTypeAnnotation.java
diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
index 51079e4..11d38e1 100644
--- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ReferenceConfig.java
@@ -31,7 +31,7 @@ import org.apache.dubbo.common.utils.UrlUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.dubbo.config.support.Parameter;
import org.apache.dubbo.config.utils.ConfigValidationUtils;
-import org.apache.dubbo.registry.client.metadata.MetadataUtils;
+import org.apache.dubbo.metadata.ServiceNameMapping;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.Protocol;
import org.apache.dubbo.rpc.ProxyFactory;
@@ -247,12 +247,14 @@ public class ReferenceConfig<T> extends ReferenceConfigBase<T> {
//init serviceMetadata
initServiceMetadata(consumer);
+
serviceMetadata.setServiceType(getServiceInterfaceClass());
// TODO, uncomment this line once service key is unified
serviceMetadata.setServiceKey(URL.buildKey(interfaceName, group, version));
Map<String, String> referenceParameters = appendConfig();
-
+ // init service-application mapping
+ initServiceAppsMapping(referenceParameters);
ModuleServiceRepository repository = getScopeModel().getServiceRepository();
ServiceDescriptor serviceDescriptor = repository.registerService(interfaceClass);
@@ -274,6 +276,11 @@ public class ReferenceConfig<T> extends ReferenceConfigBase<T> {
checkInvokerAvailable();
}
+ private void initServiceAppsMapping(Map<String, String> referenceParameters) {
+ ServiceNameMapping serviceNameMapping = ServiceNameMapping.getDefaultExtension(getScopeModel());
+ serviceNameMapping.getServices(new ServiceConfigURL(LOCAL_PROTOCOL, LOCALHOST_VALUE, 0, interfaceName, referenceParameters));
+ }
+
/**
* convert and aggregate async method info
*
@@ -385,7 +392,6 @@ public class ReferenceConfig<T> extends ReferenceConfigBase<T> {
referenceParameters.get(INTERFACE_KEY), referenceParameters);
consumerUrl = consumerUrl.setScopeModel(getScopeModel());
consumerUrl = consumerUrl.setServiceModel(consumerModel);
- MetadataUtils.publishServiceDefinition(consumerUrl);
// create service proxy
return (T) proxyFactory.getProxy(invoker, ProtocolUtils.isGeneric(generic));
diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
index 60b7fc8..25da572 100644
--- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/ServiceConfig.java
@@ -32,9 +32,7 @@ import org.apache.dubbo.config.annotation.Service;
import org.apache.dubbo.config.invoker.DelegateProviderMetaDataInvoker;
import org.apache.dubbo.config.support.Parameter;
import org.apache.dubbo.config.utils.ConfigValidationUtils;
-import org.apache.dubbo.metadata.MetadataService;
import org.apache.dubbo.metadata.ServiceNameMapping;
-import org.apache.dubbo.metadata.WritableMetadataService;
import org.apache.dubbo.registry.client.metadata.MetadataUtils;
import org.apache.dubbo.rpc.Exporter;
import org.apache.dubbo.rpc.Invoker;
@@ -133,7 +131,7 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
private final List<Exporter<?>> exporters = new ArrayList<Exporter<?>>();
private final List<ServiceListener> serviceListeners = new ArrayList<>();
- private WritableMetadataService localMetadataService;
+ ModuleServiceRepository repository = getScopeModel().getServiceRepository();
public ServiceConfig() {
}
@@ -147,7 +145,6 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
super.postProcessAfterScopeModelChanged(oldScopeModel, newScopeModel);
protocolSPI = this.getExtensionLoader(Protocol.class).getAdaptiveExtension();
proxyFactory = this.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
- localMetadataService = this.getScopeModel().getDefaultExtension(WritableMetadataService.class);
}
@Override
@@ -252,6 +249,8 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
boolean succeeded = serviceNameMapping.map(url);
if (succeeded) {
logger.info("Successfully registered interface application mapping for service " + url.getServiceKey());
+ } else {
+ logger.error("Failed register interface application mapping for service " + url.getServiceKey());
}
} catch (Exception e) {
logger.error("Failed register interface application mapping for service " + url.getServiceKey(), e);
@@ -357,7 +356,6 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
@SuppressWarnings({"unchecked", "rawtypes"})
private void doExportUrls() {
- ModuleServiceRepository repository = getScopeModel().getServiceRepository();
ServiceDescriptor serviceDescriptor = repository.registerService(getInterfaceClass());
providerModel = new ProviderModel(getUniqueServiceName(),
ref,
@@ -561,7 +559,7 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
// export to remote if the config is not local (export to local only when config is local)
if (!SCOPE_LOCAL.equalsIgnoreCase(scope)) {
url = exportRemote(url, registryURLs);
- MetadataUtils.publishServiceDefinition(url);
+ MetadataUtils.publishServiceDefinition(repository.getService(interfaceName), getApplicationModel());
}
}
@@ -605,10 +603,6 @@ public class ServiceConfig<T> extends ServiceConfigBase<T> {
} else {
- if (MetadataService.class.getName().equals(url.getServiceInterface())) {
- localMetadataService.setMetadataServiceURL(url);
- }
-
if (logger.isInfoEnabled()) {
logger.info("Export dubbo service " + interfaceClass.getName() + " to url " + url);
}
diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java
index fd95e3b..a9f3603 100644
--- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/deploy/DefaultApplicationDeployer.java
@@ -49,11 +49,7 @@ import org.apache.dubbo.metadata.MetadataServiceExporter;
import org.apache.dubbo.metadata.WritableMetadataService;
import org.apache.dubbo.metadata.report.MetadataReportFactory;
import org.apache.dubbo.metadata.report.MetadataReportInstance;
-import org.apache.dubbo.registry.client.DefaultServiceInstance;
-import org.apache.dubbo.registry.client.ServiceInstance;
import org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils;
-import org.apache.dubbo.registry.client.metadata.store.InMemoryWritableMetadataService;
-import org.apache.dubbo.registry.client.metadata.store.RemoteMetadataServiceImpl;
import org.apache.dubbo.registry.support.RegistryManager;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.ModuleModel;
@@ -83,8 +79,6 @@ import static org.apache.dubbo.common.utils.StringUtils.isEmpty;
import static org.apache.dubbo.common.utils.StringUtils.isNotEmpty;
import static org.apache.dubbo.metadata.MetadataConstants.DEFAULT_METADATA_PUBLISH_DELAY;
import static org.apache.dubbo.metadata.MetadataConstants.METADATA_PUBLISH_DELAY_KEY;
-import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.calInstanceRevision;
-import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.setMetadataStorageType;
import static org.apache.dubbo.remoting.Constants.CLIENT_KEY;
/**
@@ -104,8 +98,6 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
private final ExecutorRepository executorRepository;
- private volatile ServiceInstance serviceInstance;
-
private AtomicBoolean hasPreparedApplicationInstance = new AtomicBoolean(false);
private AtomicBoolean hasPreparedInternalModule = new AtomicBoolean(false);
@@ -739,19 +731,13 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
}
}
- private void registerServiceInstance() {
- if (isRegisteredServiceInstance()) {
- return;
- }
+ private volatile boolean registered;
- ApplicationConfig application = getApplication();
- String serviceName = application.getName();
- ServiceInstance serviceInstance = createServiceInstance(serviceName);
- boolean registered = true;
+ private void registerServiceInstance() {
try {
- ServiceInstanceMetadataUtils.registerMetadataAndInstance(serviceInstance);
+ registered = true;
+ ServiceInstanceMetadataUtils.registerMetadataAndInstance(applicationModel);
} catch (Exception e) {
- registered = false;
logger.error("Register instance error", e);
}
if (registered) {
@@ -762,79 +748,25 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
if (applicationModel.isDestroyed()) {
return;
}
-
- InMemoryWritableMetadataService localMetadataService = (InMemoryWritableMetadataService) WritableMetadataService.getDefaultExtension(applicationModel);
- localMetadataService.blockUntilUpdated();
try {
if (!applicationModel.isDestroyed()) {
- ServiceInstanceMetadataUtils.refreshMetadataAndInstance(serviceInstance);
+ ServiceInstanceMetadataUtils.refreshMetadataAndInstance(applicationModel);
}
} catch (Exception e) {
if (!applicationModel.isDestroyed()) {
logger.error("Refresh instance and metadata error", e);
}
- } finally {
- localMetadataService.releaseBlock();
}
}, 0, ConfigurationUtils.get(applicationModel, METADATA_PUBLISH_DELAY_KEY, DEFAULT_METADATA_PUBLISH_DELAY), TimeUnit.MILLISECONDS);
}
}
- private boolean isRegisteredServiceInstance() {
- return this.serviceInstance != null;
- }
-
- private void doRegisterServiceInstance(ServiceInstance serviceInstance) {
- // register instance only when at least one service is exported.
- if (serviceInstance.getPort() > 0) {
- publishMetadataToRemote(serviceInstance);
- logger.info("Start registering instance address to registry.");
- RegistryManager.getInstance(applicationModel).getServiceDiscoveries().forEach(serviceDiscovery ->
- {
- ServiceInstance serviceInstanceForRegistry = new DefaultServiceInstance((DefaultServiceInstance) serviceInstance);
- calInstanceRevision(serviceDiscovery, serviceInstanceForRegistry);
- if (logger.isDebugEnabled()) {
- logger.info("Start registering instance address to registry" + serviceDiscovery.getUrl() + ", instance " + serviceInstanceForRegistry);
- }
- // register metadata
- serviceDiscovery.register(serviceInstanceForRegistry);
- });
- }
- }
-
- private void publishMetadataToRemote(ServiceInstance serviceInstance) {
-// InMemoryWritableMetadataService localMetadataService = (InMemoryWritableMetadataService)WritableMetadataService.getDefaultExtension();
-// localMetadataService.blockUntilUpdated();
- if (logger.isInfoEnabled()) {
- logger.info("Start publishing metadata to remote center, this only makes sense for applications enabled remote metadata center.");
- }
- RemoteMetadataServiceImpl remoteMetadataService = applicationModel.getBeanFactory().getBean(RemoteMetadataServiceImpl.class);
- remoteMetadataService.publishMetadata(serviceInstance.getServiceName());
- }
-
private void unregisterServiceInstance() {
- if (isRegisteredServiceInstance()) {
- RegistryManager.getInstance(applicationModel).getServiceDiscoveries().forEach(serviceDiscovery -> {
- try {
- serviceDiscovery.unregister(serviceInstance);
- } catch (Exception ignored) {
- // ignored
- }
- });
+ if (registered) {
+ ServiceInstanceMetadataUtils.unregisterMetadataAndInstance(applicationModel);
}
}
- private ServiceInstance createServiceInstance(String serviceName) {
- this.serviceInstance = new DefaultServiceInstance(serviceName, applicationModel);
- setMetadataStorageType(serviceInstance, getMetadataType());
- ServiceInstanceMetadataUtils.customizeInstance(this.serviceInstance);
- return this.serviceInstance;
- }
-
- public ServiceInstance getServiceInstance() {
- return serviceInstance;
- }
-
@Override
public void stop() {
applicationModel.destroy();
@@ -1001,11 +933,11 @@ public class DefaultApplicationDeployer extends AbstractDeployer<ApplicationMode
}
// refresh metadata
try {
- if (serviceInstance != null) {
- ServiceInstanceMetadataUtils.refreshMetadataAndInstance(serviceInstance);
+ if (registered) {
+ ServiceInstanceMetadataUtils.refreshMetadataAndInstance(applicationModel);
}
} catch (Exception e) {
- logger.error("refresh metadata failed: " + e.getMessage(), e);
+ logger.error("refresh meta and instance failed: " + e.getMessage(), e);
}
// shutdown export/refer executor after started
executorRepository.shutdownServiceExportExecutor();
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/MetadataReportInstance.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/metadata/MetadataReportInstance.java
similarity index 95%
rename from dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/MetadataReportInstance.java
rename to dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/metadata/MetadataReportInstance.java
index ee40342..75be9cc 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/MetadataReportInstance.java
+++ b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/metadata/MetadataReportInstance.java
@@ -14,11 +14,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.dubbo.metadata.report;
+package org.apache.dubbo.config.metadata;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.URLBuilder;
import org.apache.dubbo.config.MetadataReportConfig;
+import org.apache.dubbo.metadata.report.MetadataReport;
+import org.apache.dubbo.metadata.report.MetadataReportFactory;
import org.apache.dubbo.rpc.model.ApplicationModel;
import java.util.HashMap;
diff --git a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/metadata/ServiceInstanceHostPortCustomizer.java b/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/metadata/ServiceInstanceHostPortCustomizer.java
deleted file mode 100644
index edccd63..0000000
--- a/dubbo-config/dubbo-config-api/src/main/java/org/apache/dubbo/config/metadata/ServiceInstanceHostPortCustomizer.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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.config.metadata;
-
-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.metadata.WritableMetadataService;
-import org.apache.dubbo.registry.client.DefaultServiceInstance;
-import org.apache.dubbo.registry.client.ServiceInstance;
-import org.apache.dubbo.registry.client.ServiceInstanceCustomizer;
-import org.apache.dubbo.rpc.model.ApplicationModel;
-
-import java.util.Set;
-
-/**
- * The {@link ServiceInstanceCustomizer} to customize the {@link ServiceInstance#getPort() port} of service instance.
- *
- * @since 2.7.5
- */
-public class ServiceInstanceHostPortCustomizer implements ServiceInstanceCustomizer {
- private static final Logger logger = LoggerFactory.getLogger(ServiceInstanceHostPortCustomizer.class);
-
-
- @Override
- public void customize(ServiceInstance serviceInstance) {
-
- if (serviceInstance.getPort() > 0) {
- return;
- }
-
- WritableMetadataService writableMetadataService = WritableMetadataService.getDefaultExtension(serviceInstance.getApplicationModel());
-
- String host = null;
- int port = -1;
- Set<URL> urls = writableMetadataService.getExportedServiceURLs();
- if (CollectionUtils.isNotEmpty(urls)) {
- ApplicationModel applicationModel = serviceInstance.getApplicationModel();
- String preferredProtocol = applicationModel.getCurrentConfig().getProtocol();
- if (preferredProtocol != null) {
- for (URL exportedURL : urls) {
- if (preferredProtocol.equals(exportedURL.getProtocol())) {
- host = exportedURL.getHost();
- port = exportedURL.getPort();
- break;
- }
- }
-
- if (host == null || port == -1) {
- logger.warn("The default preferredProtocol \"" + preferredProtocol + "\" is not found, fall back to the strategy that pick the first found protocol. Please try to modify the config of dubbo.application.protocol");
- URL url = urls.iterator().next();
- host = url.getHost();
- port = url.getPort();
- }
- } else {
- URL url = urls.iterator().next();
- host = url.getHost();
- port = url.getPort();
- }
-
- if (serviceInstance instanceof DefaultServiceInstance) {
- DefaultServiceInstance instance = (DefaultServiceInstance) serviceInstance;
- instance.setHost(host);
- instance.setPort(port);
- }
- }
- }
-}
diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/mock/MockServiceDiscovery.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/mock/MockServiceDiscovery.java
index 3044dcb..fcf827b 100644
--- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/mock/MockServiceDiscovery.java
+++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/mock/MockServiceDiscovery.java
@@ -26,6 +26,10 @@ import java.util.Set;
public class MockServiceDiscovery extends AbstractServiceDiscovery {
private URL registryURL;
+ public MockServiceDiscovery(String serviceName) {
+ super(serviceName);
+ }
+
@Override
public void doInitialize(URL registryURL) throws Exception {
this.registryURL = registryURL;
@@ -42,12 +46,12 @@ public class MockServiceDiscovery extends AbstractServiceDiscovery {
}
@Override
- public void doUpdate(ServiceInstance serviceInstance) throws RuntimeException {
+ public void doUpdate() throws RuntimeException {
this.serviceInstance = serviceInstance;
}
@Override
- public void doUnregister(ServiceInstance serviceInstance) throws RuntimeException {
+ public void doUnregister() throws RuntimeException {
this.serviceInstance = null;
}
diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/servicediscoveryregistry/MultipleRegistryCenterServiceDiscoveryRegistryIntegrationTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/servicediscoveryregistry/MultipleRegistryCenterServiceDiscoveryRegistryIntegrationTest.java
index 2be4305..8d2159f 100644
--- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/servicediscoveryregistry/MultipleRegistryCenterServiceDiscoveryRegistryIntegrationTest.java
+++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/servicediscoveryregistry/MultipleRegistryCenterServiceDiscoveryRegistryIntegrationTest.java
@@ -26,7 +26,7 @@ import org.apache.dubbo.config.ServiceConfig;
import org.apache.dubbo.config.bootstrap.DubboBootstrap;
import org.apache.dubbo.integration.IntegrationTest;
import org.apache.dubbo.registry.RegistryServiceListener;
-import org.apache.dubbo.registry.client.metadata.store.InMemoryWritableMetadataService;
+import org.apache.dubbo.registry.client.metadata.store.MetadataServiceDelegation;
import org.apache.dubbo.registrycenter.RegistryCenter;
import org.apache.dubbo.registrycenter.ZookeeperMultipleRegistryCenter;
@@ -179,7 +179,7 @@ public class MultipleRegistryCenterServiceDiscoveryRegistryIntegrationTest imple
Assertions.assertTrue(serviceDiscoveryRegistryInfoWrapper.isRegistered());
// check if it's subscribed
Assertions.assertFalse(serviceDiscoveryRegistryInfoWrapper.isSubscribed());
- InMemoryWritableMetadataService inMemoryWritableMetadataService = serviceDiscoveryRegistryInfoWrapper.getInMemoryWritableMetadataService();
+ MetadataServiceDelegation inMemoryWritableMetadataService = serviceDiscoveryRegistryInfoWrapper.getInMemoryWritableMetadataService();
// check if the count of exported urls is right or not
Assertions.assertEquals(inMemoryWritableMetadataService.getExportedURLs().size(), 1);
// check the exported url is right or not.
diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/servicediscoveryregistry/MultipleRegistryCenterServiceDiscoveryRegistryRegistryServiceListener.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/servicediscoveryregistry/MultipleRegistryCenterServiceDiscoveryRegistryRegistryServiceListener.java
index 00d45f4..4b5676d 100644
--- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/servicediscoveryregistry/MultipleRegistryCenterServiceDiscoveryRegistryRegistryServiceListener.java
+++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/servicediscoveryregistry/MultipleRegistryCenterServiceDiscoveryRegistryRegistryServiceListener.java
@@ -22,7 +22,7 @@ import org.apache.dubbo.metadata.WritableMetadataService;
import org.apache.dubbo.registry.Registry;
import org.apache.dubbo.registry.RegistryServiceListener;
import org.apache.dubbo.registry.client.ServiceDiscoveryRegistry;
-import org.apache.dubbo.registry.client.metadata.store.InMemoryWritableMetadataService;
+import org.apache.dubbo.registry.client.metadata.store.MetadataServiceDelegation;
import static org.apache.dubbo.integration.Constants.MULTIPLE_CONFIG_CENTER_SERVICE_DISCOVERY_REGISTRY;
@@ -43,7 +43,7 @@ public class MultipleRegistryCenterServiceDiscoveryRegistryRegistryServiceListen
serviceDiscoveryRegistryInfoWrapper.setHost(host);
serviceDiscoveryRegistryInfoWrapper.setPort(port);
serviceDiscoveryRegistryInfoWrapper.setServiceDiscoveryRegistry(serviceDiscoveryRegistry);
- serviceDiscoveryRegistryInfoWrapper.setInMemoryWritableMetadataService((InMemoryWritableMetadataService) WritableMetadataService.getDefaultExtension(url.getScopeModel()));
+ serviceDiscoveryRegistryInfoWrapper.setInMemoryWritableMetadataService((MetadataServiceDelegation) WritableMetadataService.getDefaultExtension(url.getScopeModel()));
serviceDiscoveryRegistryInfoWrapper.setRegistered(true);
return serviceDiscoveryRegistryInfoWrapper;
}
diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/servicediscoveryregistry/ServiceDiscoveryRegistryInfoWrapper.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/servicediscoveryregistry/ServiceDiscoveryRegistryInfoWrapper.java
index 583eec9..4df35d3 100644
--- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/servicediscoveryregistry/ServiceDiscoveryRegistryInfoWrapper.java
+++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/multiple/servicediscoveryregistry/ServiceDiscoveryRegistryInfoWrapper.java
@@ -17,16 +17,16 @@
package org.apache.dubbo.integration.multiple.servicediscoveryregistry;
import org.apache.dubbo.registry.client.ServiceDiscoveryRegistry;
-import org.apache.dubbo.registry.client.metadata.store.InMemoryWritableMetadataService;
+import org.apache.dubbo.registry.client.metadata.store.MetadataServiceDelegation;
/**
* The instance to wrap {@link org.apache.dubbo.registry.client.ServiceDiscoveryRegistry}
- * and {@link org.apache.dubbo.registry.client.metadata.store.InMemoryWritableMetadataService}
+ * and {@link MetadataServiceDelegation}
*/
public class ServiceDiscoveryRegistryInfoWrapper {
private ServiceDiscoveryRegistry serviceDiscoveryRegistry;
- private InMemoryWritableMetadataService inMemoryWritableMetadataService;
+ private MetadataServiceDelegation inMemoryWritableMetadataService;
private boolean registered;
private boolean subscribed;
private String host;
@@ -40,11 +40,11 @@ public class ServiceDiscoveryRegistryInfoWrapper {
this.serviceDiscoveryRegistry = serviceDiscoveryRegistry;
}
- public InMemoryWritableMetadataService getInMemoryWritableMetadataService() {
+ public MetadataServiceDelegation getInMemoryWritableMetadataService() {
return inMemoryWritableMetadataService;
}
- public void setInMemoryWritableMetadataService(InMemoryWritableMetadataService inMemoryWritableMetadataService) {
+ public void setInMemoryWritableMetadataService(MetadataServiceDelegation inMemoryWritableMetadataService) {
this.inMemoryWritableMetadataService = inMemoryWritableMetadataService;
}
diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/SingleRegistryCenterDubboProtocolIntegrationTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/SingleRegistryCenterDubboProtocolIntegrationTest.java
index 862a553..e4e8e5a 100644
--- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/SingleRegistryCenterDubboProtocolIntegrationTest.java
+++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/integration/single/SingleRegistryCenterDubboProtocolIntegrationTest.java
@@ -34,7 +34,7 @@ import org.apache.dubbo.registry.ListenerRegistryWrapper;
import org.apache.dubbo.registry.Registry;
import org.apache.dubbo.registry.client.ServiceDiscoveryRegistry;
import org.apache.dubbo.registry.client.ServiceDiscoveryRegistryDirectory;
-import org.apache.dubbo.registry.client.metadata.store.InMemoryWritableMetadataService;
+import org.apache.dubbo.registry.client.metadata.store.MetadataServiceDelegation;
import org.apache.dubbo.registry.client.migration.MigrationInvoker;
import org.apache.dubbo.registry.support.RegistryManager;
import org.apache.dubbo.registry.zookeeper.ZookeeperServiceDiscovery;
@@ -42,6 +42,7 @@ import org.apache.dubbo.registrycenter.RegistryCenter;
import org.apache.dubbo.registrycenter.ZookeeperSingleRegistryCenter;
import org.apache.dubbo.rpc.cluster.Directory;
import org.apache.dubbo.rpc.model.ApplicationModel;
+
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
@@ -237,24 +238,18 @@ public class SingleRegistryCenterDubboProtocolIntegrationTest implements Integra
Assertions.assertTrue(services.contains(PROVIDER_APPLICATION_NAME));
// obtain InMemoryWritableMetadataService instance
- InMemoryWritableMetadataService inMemoryWritableMetadataService = (InMemoryWritableMetadataService) WritableMetadataService.getDefaultExtension(serviceConfig.getScopeModel());
+ MetadataServiceDelegation inMemoryWritableMetadataService = (MetadataServiceDelegation) WritableMetadataService.getDefaultExtension(serviceConfig.getScopeModel());
// Exported url is right or not in InMemoryWritableMetadataService
Assertions.assertEquals(inMemoryWritableMetadataService.getExportedURLs().size(), 1);
// MetadataInfo exists or not in InMemoryWritableMetadataService
- Assertions.assertFalse(inMemoryWritableMetadataService.getMetadataInfos().values().isEmpty());
- // get MetadataInfo
- MetadataInfo metadataInfo = inMemoryWritableMetadataService.getMetadataInfos().get("default");
- // MetadataInfo exists or not in InMemoryWritableMetadataService
- Assertions.assertNotNull(metadataInfo);
- // MetadataInfo has reported or not
- Assertions.assertFalse(metadataInfo.hasReported());
+ Assertions.assertFalse(inMemoryWritableMetadataService.getMetadataInfos().isEmpty());
// MetadataInfo has reported or not has service or not
- Assertions.assertFalse(metadataInfo.getServices().isEmpty());
+ Assertions.assertFalse(inMemoryWritableMetadataService.getMetadataInfos().get(0).getServices().isEmpty());
// MetadataInfo has reported or not has service or not
- Assertions.assertEquals(metadataInfo.getServices().size(), 1);
+ Assertions.assertEquals(inMemoryWritableMetadataService.getMetadataInfos().get(0).getServices().size(), 1);
// obtain the service's key
String key = SingleRegistryCenterIntegrationService.class.getName() + ":" + PROTOCOL_NAME;
- MetadataInfo.ServiceInfo serviceInfo = metadataInfo.getServices().get(key);
+ MetadataInfo.ServiceInfo serviceInfo = inMemoryWritableMetadataService.getMetadataInfos().get(0).getServices().get(key);
// MetadataInfo's service exists or not
Assertions.assertNotNull(serviceInfo);
// The name of MetadataInfo's service is right or not
diff --git a/dubbo-metadata/dubbo-metadata-api/pom.xml b/dubbo-metadata/dubbo-metadata-api/pom.xml
index 9caf31e..03579d5 100644
--- a/dubbo-metadata/dubbo-metadata-api/pom.xml
+++ b/dubbo-metadata/dubbo-metadata-api/pom.xml
@@ -44,7 +44,7 @@
<artifactId>dubbo-cluster</artifactId>
<version>${project.parent.version}</version>
</dependency>
-
+
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
@@ -87,4 +87,4 @@
</dependencies>
-</project>
\ No newline at end of file
+</project>
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/AbstractServiceNameMapping.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/AbstractServiceNameMapping.java
index 72a7985..7ad3fa5 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/AbstractServiceNameMapping.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/AbstractServiceNameMapping.java
@@ -23,27 +23,29 @@ import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.ScopeModelAware;
+import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
import static java.util.Collections.emptySet;
import static java.util.Collections.unmodifiableSet;
import static java.util.stream.Collectors.toSet;
import static java.util.stream.Stream.of;
import static org.apache.dubbo.common.constants.RegistryConstants.PROVIDED_BY;
-import static org.apache.dubbo.common.constants.RegistryConstants.SUBSCRIBED_SERVICE_NAMES_KEY;
import static org.apache.dubbo.common.utils.CollectionUtils.isEmpty;
import static org.apache.dubbo.common.utils.StringUtils.isBlank;
public abstract class AbstractServiceNameMapping implements ServiceNameMapping, ScopeModelAware {
protected final Logger logger = LoggerFactory.getLogger(getClass());
protected ApplicationModel applicationModel;
- private WritableMetadataService metadataService;
+ private final Map<String, Set<String>> serviceToAppsMapping = new ConcurrentHashMap<>();
+ private final Map<String, MappingListener> mappingListeners = new ConcurrentHashMap<>();
@Override
public void setApplicationModel(ApplicationModel applicationModel) {
this.applicationModel = applicationModel;
- metadataService = WritableMetadataService.getDefaultExtension(applicationModel);
}
/**
@@ -60,6 +62,8 @@ public abstract class AbstractServiceNameMapping implements ServiceNameMapping,
*/
abstract public Set<String> getAndListen(URL url, MappingListener mappingListener);
+ abstract protected void removeListener(URL url, MappingListener mappingListener);
+
@Override
public Set<String> getServices(URL subscribedURL) {
Set<String> subscribedServices = new TreeSet<>();
@@ -71,7 +75,7 @@ public abstract class AbstractServiceNameMapping implements ServiceNameMapping,
}
if (isEmpty(subscribedServices)) {
- Set<String> cachedServices = metadataService.getCachedMapping(ServiceNameMapping.buildMappingKey(subscribedURL));
+ Set<String> cachedServices = this.getCachedMapping(ServiceNameMapping.buildMappingKey(subscribedURL));
if(!isEmpty(cachedServices)) {
subscribedServices.addAll(cachedServices);
}
@@ -81,35 +85,43 @@ public abstract class AbstractServiceNameMapping implements ServiceNameMapping,
Set<String> mappedServices = get(subscribedURL);
logger.info(subscribedURL.getServiceInterface() + " mapping to " + mappedServices + " instructed by remote metadata center.");
subscribedServices.addAll(mappedServices);
- metadataService.putCachedMapping(ServiceNameMapping.buildMappingKey(subscribedURL), subscribedServices);
}
+
+ this.putCachedMapping(ServiceNameMapping.buildMappingKey(subscribedURL), subscribedServices);
+
return subscribedServices;
}
@Override
- public Set<String> getAndListenServices(URL registryURL, URL subscribedURL, MappingListener listener) {
- Set<String> subscribedServices = new TreeSet<>();
- Set<String> globalConfiguredSubscribingServices = parseServices(registryURL.getParameter(SUBSCRIBED_SERVICE_NAMES_KEY));
+ public Set<String> getAndListen(URL registryURL, URL subscribedURL, MappingListener listener) {
+ // use previously cached services.
+ Set<String> cachedServices = this.getCachedMapping(ServiceNameMapping.buildMappingKey(subscribedURL));
+
+ // Asynchronously register listener in case previous cache does not exist or cache updating in the future.
+ ExecutorService executorService = applicationModel.getApplicationExecutorRepository().nextExecutorExecutor();
+ executorService.submit(() -> {
+ synchronized (mappingListeners) {
+ Set<String> mappedServices = getAndListen(subscribedURL, listener);
+ this.putCachedMapping(ServiceNameMapping.buildMappingKey(subscribedURL), mappedServices);
+ mappingListeners.put(subscribedURL.getProtocolServiceKey(), listener);
+ }
+ });
- String serviceNames = subscribedURL.getParameter(PROVIDED_BY);
- if (StringUtils.isNotEmpty(serviceNames)) {
- logger.info(subscribedURL.getServiceInterface() + " mapping to " + serviceNames + " instructed by provided-by set by user.");
- subscribedServices.addAll(parseServices(serviceNames));
- }
+ return cachedServices;
+ }
- if (isEmpty(subscribedServices)) {
- Set<String> mappedServices = getAndListen(subscribedURL, listener);
- logger.info(subscribedURL.getServiceInterface() + " mapping to " + mappedServices + " instructed by remote metadata center.");
- subscribedServices.addAll(mappedServices);
- if (isEmpty(subscribedServices)) {
- logger.info(subscribedURL.getServiceInterface() + " mapping to " + globalConfiguredSubscribingServices + " by default.");
- subscribedServices.addAll(globalConfiguredSubscribingServices);
+ @Override
+ public MappingListener stopListen(URL subscribeURL) {
+ synchronized (mappingListeners) {
+ MappingListener listener = mappingListeners.remove(subscribeURL.getProtocolServiceKey());
+ //todo, remove listener from remote metadata center
+ listener.stop();
+ removeListener(subscribeURL, listener);
+ if (mappingListeners.size() == 0) {
+ removeCachedMapping(ServiceNameMapping.buildMappingKey(subscribeURL));
}
+ return listener;
}
-
- metadataService.putCachedMapping(ServiceNameMapping.buildMappingKey(subscribedURL), subscribedServices);
-
- return subscribedServices;
}
static Set<String> parseServices(String literalServices) {
@@ -120,4 +132,24 @@ public abstract class AbstractServiceNameMapping implements ServiceNameMapping,
.collect(toSet()));
}
+ @Override
+ public void putCachedMapping(String serviceKey, Set<String> apps) {
+ serviceToAppsMapping.put(serviceKey, new TreeSet<>(apps));
+ }
+
+ @Override
+ public Set<String> getCachedMapping(String mappingKey) {
+ return serviceToAppsMapping.get(mappingKey);
+ }
+
+ @Override
+ public Set<String> getCachedMapping(URL consumerURL) {
+ return serviceToAppsMapping.get(ServiceNameMapping.buildMappingKey(consumerURL));
+ }
+
+ @Override
+ public Set<String> removeCachedMapping(String serviceKey) {
+ return serviceToAppsMapping.remove(serviceKey);
+ }
+
}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MappingListener.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MappingListener.java
index f709d75..c9e7922 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MappingListener.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MappingListener.java
@@ -18,4 +18,6 @@ package org.apache.dubbo.metadata;
public interface MappingListener {
void onEvent(MappingChangedEvent event);
+
+ void stop();
}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataInfo.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataInfo.java
index 4f0cecb..0985e3a 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataInfo.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataInfo.java
@@ -27,12 +27,17 @@ import org.apache.dubbo.common.utils.StringUtils;
import java.io.Serializable;
import java.util.Collections;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.SortedSet;
import java.util.TreeMap;
+import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentNavigableMap;
+import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.atomic.AtomicBoolean;
import static org.apache.dubbo.common.constants.CommonConstants.DOT_SEPARATOR;
@@ -61,7 +66,10 @@ public class MetadataInfo implements Serializable {
// used at runtime
private transient Map<String, String> extendParams;
- private transient AtomicBoolean reported = new AtomicBoolean(false);
+ protected transient AtomicBoolean updated = new AtomicBoolean(false);
+ private transient ConcurrentNavigableMap<String, SortedSet<URL>> subscribedServiceURLs = new ConcurrentSkipListMap<>();
+ private transient ConcurrentNavigableMap<String, SortedSet<URL>> exportedServiceURLs;
+ private transient ConcurrentNavigableMap<String, String> serviceDefinitions = new ConcurrentSkipListMap<>();
public MetadataInfo() {
this(null);
@@ -78,38 +86,41 @@ public class MetadataInfo implements Serializable {
this.extendParams = new ConcurrentHashMap<>();
}
- public void addService(ServiceInfo serviceInfo) {
- if (serviceInfo == null) {
- return;
- }
+ public synchronized void addService(URL url) {
+ ServiceInfo serviceInfo = new ServiceInfo(url);
this.services.put(serviceInfo.getMatchKey(), serviceInfo);
- markChanged();
- }
- public void removeService(ServiceInfo serviceInfo) {
- if (serviceInfo == null) {
- return;
+ if (exportedServiceURLs == null) {
+ exportedServiceURLs = new ConcurrentSkipListMap<>();
}
- this.services.remove(serviceInfo.getMatchKey());
- markChanged();
+ addURL(exportedServiceURLs, url);
+ updated.compareAndSet(false, true);
}
- public void removeService(String key) {
- if (key == null) {
+ public synchronized void removeService(URL url) {
+ if (url == null) {
return;
}
- this.services.remove(key);
- markChanged();
+ this.services.remove(url.getProtocolServiceKey());
+ this.exportedServiceURLs.remove(url);
+
+ updated.compareAndSet(false, true);
+ }
+
+ public String getRevision() {
+ return revision;
}
/**
* Reported status and metadata modification must be synchronized if used in multiple threads.
*/
- public String calAndGetRevision() {
- if (revision != null && hasReported()) {
+ public synchronized String calAndGetRevision() {
+ if (revision != null && updated.get()) {
return revision;
}
+ updated.compareAndSet(true, false);
+
if (CollectionUtils.isEmptyMap(services)) {
this.revision = EMPTY_REVISION;
} else {
@@ -133,27 +144,6 @@ public class MetadataInfo implements Serializable {
this.revision = revision;
}
- /**
- * Reported status and metadata modification must be synchronized if used in multiple threads.
- */
- public boolean hasReported() {
- return reported.get();
- }
-
- /**
- * Reported status and metadata modification must be synchronized if used in multiple threads.
- */
- public void markReported() {
- reported.compareAndSet(false, true);
- }
-
- /**
- * Reported status and metadata modification must be synchronized if used in multiple threads.
- */
- public void markChanged() {
- reported.compareAndSet(true, false);
- }
-
public String getApp() {
return app;
}
@@ -206,6 +196,46 @@ public class MetadataInfo implements Serializable {
return serviceInfo.toFullString();
}
+ public void addSubscribedURL(URL url) {
+ addURL(subscribedServiceURLs, url);
+ }
+
+ public boolean removeSubscribedURL(URL url) {
+ return removeURL(subscribedServiceURLs, url);
+ }
+
+ public ConcurrentNavigableMap<String, SortedSet<URL>> getSubscribedServiceURLs() {
+ return subscribedServiceURLs;
+ }
+
+ public ConcurrentNavigableMap<String, SortedSet<URL>> getExportedServiceURLs() {
+ return exportedServiceURLs;
+ }
+
+ private boolean addURL(Map<String, SortedSet<URL>> serviceURLs, URL url) {
+ SortedSet<URL> urls = serviceURLs.computeIfAbsent(url.getServiceKey(), this::newSortedURLs);
+ // make sure the parameters of tmpUrl is variable
+ return urls.add(url);
+ }
+
+ boolean removeURL(Map<String, SortedSet<URL>> serviceURLs, URL url) {
+ String key = url.getServiceKey();
+ SortedSet<URL> urls = serviceURLs.getOrDefault(key, null);
+ if (urls == null) {
+ return true;
+ }
+ boolean r = urls.remove(url);
+ // if it is empty
+ if (urls.isEmpty()) {
+ serviceURLs.remove(key);
+ }
+ return r;
+ }
+
+ private SortedSet<URL> newSortedURLs(String serviceKey) {
+ return new TreeSet<>(URLComparator.INSTANCE);
+ }
+
@Override
public int hashCode() {
return Objects.hash(app, services);
@@ -548,4 +578,14 @@ public class MetadataInfo implements Serializable {
"}";
}
}
+
+ static class URLComparator implements Comparator<URL> {
+
+ public static final URLComparator INSTANCE = new URLComparator();
+
+ @Override
+ public int compare(URL o1, URL o2) {
+ return o1.toFullString().compareTo(o2.toFullString());
+ }
+ }
}
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 5ccb0b0..946322b 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
@@ -185,8 +185,6 @@ public interface MetadataService {
MetadataInfo getMetadataInfo(String revision);
- Map<String, MetadataInfo> getMetadataInfos();
-
/**
* Is the {@link URL} for the {@link MetadataService} or not?
*
@@ -275,4 +273,7 @@ public interface MetadataService {
default String getAndListenInstanceMetadata(String consumerId, InstanceMetadataChangedListener listener) {
throw new UnsupportedOperationException("This operation is not supported for consumer.");
}
+
+ List<MetadataInfo> getMetadataInfos();
+
}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/ServiceNameMapping.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/ServiceNameMapping.java
index ac71b5c..459d299 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/ServiceNameMapping.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/ServiceNameMapping.java
@@ -18,13 +18,14 @@ package org.apache.dubbo.metadata;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.SPI;
+import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.rpc.model.ScopeModel;
import org.apache.dubbo.rpc.model.ScopeModelUtil;
import java.util.Arrays;
-import java.util.HashSet;
import java.util.Set;
+import java.util.TreeSet;
import static java.util.Collections.emptySet;
import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SEPARATOR;
@@ -65,14 +66,25 @@ public interface ServiceNameMapping {
}
static String toStringKeys(Set<String> serviceNames) {
- return serviceNames.toString();
+ if (CollectionUtils.isEmpty(serviceNames)) {
+ return "";
+ }
+
+ StringBuilder builder = new StringBuilder();
+ for (String n : serviceNames) {
+ builder.append(n);
+ builder.append(COMMA_SEPARATOR);
+ }
+
+ builder.deleteCharAt(builder.length() - 1);
+ return builder.toString();
}
static Set<String> getAppNames(String content) {
if (StringUtils.isBlank(content)) {
return emptySet();
}
- return new HashSet<>(Arrays.asList(content.split(COMMA_SEPARATOR)));
+ return new TreeSet<>(Arrays.asList(content.split(COMMA_SEPARATOR)));
}
/**
@@ -86,5 +98,15 @@ public interface ServiceNameMapping {
* 2.check Interface-App mapping
* 3.use the services specified in registry url.
*/
- Set<String> getAndListenServices(URL registryURL, URL subscribedURL, MappingListener listener);
+ Set<String> getAndListen(URL registryURL, URL subscribedURL, MappingListener listener);
+
+ MappingListener stopListen(URL subscribeURL);
+
+ void putCachedMapping(String serviceKey, Set<String> apps);
+
+ Set<String> getCachedMapping(String mappingKey);
+
+ Set<String> getCachedMapping(URL consumerURL);
+
+ Set<String> removeCachedMapping(String serviceKey);
}
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 bd77ec5..9c331f7 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
@@ -17,83 +17,21 @@
package org.apache.dubbo.metadata;
import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.extension.ExtensionScope;
import org.apache.dubbo.common.extension.SPI;
import org.apache.dubbo.rpc.model.ScopeModel;
import org.apache.dubbo.rpc.model.ScopeModelUtil;
-import java.util.Map;
-import java.util.Set;
-
/**
- * Local {@link MetadataService} that extends {@link MetadataService} and provides the modification, which is used for
- * Dubbo's consumers and providers.
- *
- * @since 2.7.5
+ * FIXME, this class is not needed anymore.
*/
@SPI(value = "default", scope = ExtensionScope.APPLICATION)
public interface WritableMetadataService extends MetadataService {
- /**
- * Exports a {@link URL}
- *
- * @param url a {@link URL}
- * @return If success , return <code>true</code>
- */
- boolean exportURL(URL url);
-
- /**
- * Unexports a {@link URL}
- *
- * @param url a {@link URL}
- * @return If success , return <code>true</code>
- */
- boolean unexportURL(URL url);
-
- /**
- * Subscribes a {@link URL}
- *
- * @param url a {@link URL}
- * @return If success , return <code>true</code>
- */
- boolean subscribeURL(URL url);
-
- /**
- * Unsubscribes a {@link URL}
- *
- * @param url a {@link URL}
- * @return If success , return <code>true</code>
- */
- boolean unsubscribeURL(URL url);
-
- void publishServiceDefinition(URL url);
-
- default void setMetadataServiceURL(URL url) {
-
- }
-
default URL getMetadataServiceURL() {
return null;
}
- void putCachedMapping(String serviceKey, Set<String> apps);
-
- Set<String> getCachedMapping(String mappingKey);
-
- Set<String> getCachedMapping(URL consumerURL);
-
- Set<String> removeCachedMapping(String serviceKey);
-
- Map<String, Set<String>> getCachedMapping();
-
- MetadataInfo getDefaultMetadataInfo();
-
- /**
- * Get {@link ExtensionLoader#getDefaultExtension() the defautl extension} of {@link WritableMetadataService}
- *
- * @return non-null
- */
static WritableMetadataService getDefaultExtension(ScopeModel scopeModel) {
return ScopeModelUtil.getExtensionLoader(WritableMetadataService.class, scopeModel).getDefaultExtension();
}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/MethodDefinitionBuilder.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/MethodDefinitionBuilder.java
deleted file mode 100644
index e7c18e6..0000000
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/MethodDefinitionBuilder.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * 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.metadata.definition;
-
-import org.apache.dubbo.metadata.definition.model.MethodDefinition;
-import org.apache.dubbo.metadata.definition.model.TypeDefinition;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * {@link MethodDefinition} Builder based on Java Reflection
- *
- * @since 2.7.6
- */
-public class MethodDefinitionBuilder {
-
- private final TypeDefinitionBuilder builder;
-
- public MethodDefinitionBuilder(TypeDefinitionBuilder builder) {
- this.builder = builder;
- }
-
- public MethodDefinitionBuilder() {
- this.builder = new TypeDefinitionBuilder();
- }
-
- /**
- * Build the instance of {@link MethodDefinition}
- *
- * @param method {@link Method}
- * @return non-null
- */
- public MethodDefinition build(Method method) {
-
- MethodDefinition md = new MethodDefinition();
- md.setName(method.getName());
-
- // Process the parameters
- Class<?>[] paramTypes = method.getParameterTypes();
- Type[] genericParamTypes = method.getGenericParameterTypes();
-
- int paramSize = paramTypes.length;
- String[] parameterTypes = new String[paramSize];
- List<TypeDefinition> parameters = new ArrayList<>(paramSize);
- for (int i = 0; i < paramSize; i++) {
- TypeDefinition parameter = builder.build(genericParamTypes[i], paramTypes[i]);
- parameterTypes[i] = parameter.getType();
- parameters.add(parameter);
- }
-
- md.setParameterTypes(parameterTypes);
- md.setParameters(parameters);
-
- // Process return type.
- TypeDefinition td = builder.build(method.getGenericReturnType(), method.getReturnType());
- md.setReturnType(td.getType());
-
- return md;
- }
-
-}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/ServiceDefinitionBuilder.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/ServiceDefinitionBuilder.java
deleted file mode 100755
index db09b76..0000000
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/ServiceDefinitionBuilder.java
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * 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.metadata.definition;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Method;
-import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.dubbo.metadata.definition.model.FullServiceDefinition;
-import org.apache.dubbo.metadata.definition.model.MethodDefinition;
-import org.apache.dubbo.metadata.definition.model.ServiceDefinition;
-import org.apache.dubbo.metadata.definition.model.TypeDefinition;
-import org.apache.dubbo.metadata.definition.util.ClassUtils;
-
-import com.google.gson.Gson;
-
-/**
- * 2015/1/27.
- */
-public final class ServiceDefinitionBuilder {
-
- /**
- * Describe a Java interface in {@link ServiceDefinition}.
- *
- * @return Service description
- */
- public static ServiceDefinition build(final Class<?> interfaceClass) {
- ServiceDefinition sd = new ServiceDefinition();
- build(sd, interfaceClass);
- return sd;
- }
-
- public static FullServiceDefinition buildFullDefinition(final Class<?> interfaceClass) {
- FullServiceDefinition sd = new FullServiceDefinition();
- build(sd, interfaceClass);
- return sd;
- }
-
- public static FullServiceDefinition buildFullDefinition(final Class<?> interfaceClass, Map<String, String> params) {
- FullServiceDefinition sd = new FullServiceDefinition();
- build(sd, interfaceClass);
- sd.setParameters(params);
- return sd;
- }
-
- public static <T extends ServiceDefinition> void build(T sd, final Class<?> interfaceClass) {
- sd.setCanonicalName(interfaceClass.getCanonicalName());
- sd.setCodeSource(ClassUtils.getCodeSource(interfaceClass));
- Annotation[] classAnnotations = interfaceClass.getAnnotations();
- sd.setAnnotations(annotationToStringList(classAnnotations));
-
- TypeDefinitionBuilder builder = new TypeDefinitionBuilder();
- List<Method> methods = ClassUtils.getPublicNonStaticMethods(interfaceClass);
- for (Method method : methods) {
- MethodDefinition md = new MethodDefinition();
- md.setName(method.getName());
-
- Annotation[] methodAnnotations = method.getAnnotations();
- md.setAnnotations(annotationToStringList(methodAnnotations));
-
- // Process parameter types.
- Class<?>[] paramTypes = method.getParameterTypes();
- Type[] genericParamTypes = method.getGenericParameterTypes();
-
- String[] parameterTypes = new String[paramTypes.length];
- for (int i = 0; i < paramTypes.length; i++) {
- TypeDefinition td = builder.build(genericParamTypes[i], paramTypes[i]);
- parameterTypes[i] = td.getType();
- }
- md.setParameterTypes(parameterTypes);
-
- // Process return type.
- TypeDefinition td = builder.build(method.getGenericReturnType(), method.getReturnType());
- md.setReturnType(td.getType());
-
- sd.getMethods().add(md);
- }
-
- sd.setTypes(builder.getTypeDefinitions());
- }
-
- private static List<String> annotationToStringList(Annotation[] annotations) {
- if (annotations == null) {
- return Collections.emptyList();
- }
- List<String> list = new ArrayList<>();
- for (Annotation annotation : annotations) {
- list.add(annotation.toString());
- }
- return list;
- }
-
- /**
- * Describe a Java interface in Json schema.
- *
- * @return Service description
- */
- public static String schema(final Class<?> clazz) {
- ServiceDefinition sd = build(clazz);
- Gson gson = new Gson();
- return gson.toJson(sd);
- }
-
- private ServiceDefinitionBuilder() {
- }
-}
-
-
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/TypeDefinitionBuilder.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/TypeDefinitionBuilder.java
deleted file mode 100755
index b2758e3..0000000
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/TypeDefinitionBuilder.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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.metadata.definition;
-
-import org.apache.dubbo.common.extension.ExtensionLoader;
-import org.apache.dubbo.common.logger.Logger;
-import org.apache.dubbo.common.logger.LoggerFactory;
-import org.apache.dubbo.common.utils.ClassUtils;
-import org.apache.dubbo.metadata.definition.builder.DefaultTypeBuilder;
-import org.apache.dubbo.metadata.definition.builder.TypeBuilder;
-import org.apache.dubbo.metadata.definition.model.TypeDefinition;
-
-import java.lang.reflect.Type;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-
-/**
- * 2015/1/27.
- */
-public class TypeDefinitionBuilder {
- private static final Logger logger = LoggerFactory.getLogger(TypeDefinitionBuilder.class);
- static final List<TypeBuilder> BUILDERS;
-
- static {
- ExtensionLoader<TypeBuilder> extensionLoader = ExtensionLoader.getExtensionLoader(TypeBuilder.class);
- Set<TypeBuilder> tbs = extensionLoader.getSupportedExtensionInstances();
- BUILDERS = new ArrayList<>(tbs);
- }
-
- public static TypeDefinition build(Type type, Class<?> clazz, Map<String, TypeDefinition> typeCache) {
- TypeBuilder builder = getGenericTypeBuilder(clazz);
- TypeDefinition td;
-
- if (clazz.isPrimitive() || ClassUtils.isSimpleType(clazz)) { // changed since 2.7.6
- td = new TypeDefinition(clazz.getCanonicalName());
- typeCache.put(clazz.getCanonicalName(), td);
- } else if (builder != null) {
- td = builder.build(type, clazz, typeCache);
- } else {
- td = DefaultTypeBuilder.build(clazz, typeCache);
- }
- return td;
- }
-
- private static TypeBuilder getGenericTypeBuilder(Class<?> clazz) {
- for (TypeBuilder builder : BUILDERS) {
- try {
- if (builder.accept(clazz)) {
- return builder;
- }
- } catch (NoClassDefFoundError cnfe) {
- //ignore
- logger.info("Throw classNotFound (" + cnfe.getMessage() + ") in " + builder.getClass());
- }
- }
- return null;
- }
-
- private Map<String, TypeDefinition> typeCache = new HashMap<>();
-
- public TypeDefinition build(Type type, Class<?> clazz) {
- return build(type, clazz, typeCache);
- }
-
- public List<TypeDefinition> getTypeDefinitions() {
- return new ArrayList<>(typeCache.values());
- }
-
-}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/builder/ArrayTypeBuilder.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/builder/ArrayTypeBuilder.java
deleted file mode 100755
index 78cc7a5..0000000
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/builder/ArrayTypeBuilder.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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.metadata.definition.builder;
-
-import org.apache.dubbo.metadata.definition.TypeDefinitionBuilder;
-import org.apache.dubbo.metadata.definition.model.TypeDefinition;
-
-import java.lang.reflect.Type;
-import java.util.Map;
-
-/**
- * 2015/1/27.
- */
-public class ArrayTypeBuilder implements TypeBuilder {
-
- @Override
- public boolean accept(Class<?> clazz) {
- if (clazz == null) {
- return false;
- }
- return clazz.isArray();
- }
-
- @Override
- public TypeDefinition build(Type type, Class<?> clazz, Map<String, TypeDefinition> typeCache) {
- final String canonicalName = clazz.getCanonicalName();
- TypeDefinition td = typeCache.get(canonicalName);
- if (td != null) {
- return td;
- }
- td = new TypeDefinition(canonicalName);
- typeCache.put(canonicalName, td);
- // Process the component type of array.
- Class<?> componentType = clazz.getComponentType();
- TypeDefinition itemTd = TypeDefinitionBuilder.build(componentType, componentType, typeCache);
- if (itemTd != null) {
- td.getItems().add(itemTd.getType());
- }
- return td;
- }
-
-}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/builder/CollectionTypeBuilder.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/builder/CollectionTypeBuilder.java
deleted file mode 100755
index 6c6ee11..0000000
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/builder/CollectionTypeBuilder.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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.metadata.definition.builder;
-
-import org.apache.dubbo.metadata.definition.TypeDefinitionBuilder;
-import org.apache.dubbo.metadata.definition.model.TypeDefinition;
-import org.apache.dubbo.metadata.definition.util.ClassUtils;
-
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.text.MessageFormat;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Map;
-
-/**
- * 2015/1/27.
- */
-public class CollectionTypeBuilder implements TypeBuilder {
-
- @Override
- public boolean accept(Class<?> clazz) {
- if (clazz == null) {
- return false;
- }
- return Collection.class.isAssignableFrom(clazz);
- }
-
- @Override
- public TypeDefinition build(Type type, Class<?> clazz, Map<String, TypeDefinition> typeCache) {
- if (!(type instanceof ParameterizedType)) {
- return new TypeDefinition(clazz.getCanonicalName());
- }
-
- ParameterizedType parameterizedType = (ParameterizedType) type;
- Type[] actualTypeArgs = parameterizedType.getActualTypeArguments();
- if (actualTypeArgs == null || actualTypeArgs.length != 1) {
- throw new IllegalArgumentException(MessageFormat.format(
- "[ServiceDefinitionBuilder] Collection type [{0}] with unexpected amount of arguments [{1}]."
- + Arrays.toString(actualTypeArgs),
- type, actualTypeArgs));
- }
-
- String colType = ClassUtils.getCanonicalNameForParameterizedType(parameterizedType);
- TypeDefinition td = typeCache.get(colType);
- if (td != null) {
- return td;
- }
- td = new TypeDefinition(colType);
- typeCache.put(colType, td);
-
- Type actualType = actualTypeArgs[0];
- TypeDefinition itemTd = null;
- if (actualType instanceof ParameterizedType) {
- // Nested collection or map.
- Class<?> rawType = (Class<?>) ((ParameterizedType) actualType).getRawType();
- itemTd = TypeDefinitionBuilder.build(actualType, rawType, typeCache);
- } else if (actualType instanceof Class<?>) {
- Class<?> actualClass = (Class<?>) actualType;
- itemTd = TypeDefinitionBuilder.build(null, actualClass, typeCache);
- }
- if (itemTd != null) {
- td.getItems().add(itemTd.getType());
- }
-
- return td;
- }
-
-}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/builder/DefaultTypeBuilder.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/builder/DefaultTypeBuilder.java
deleted file mode 100755
index 4ac52a4..0000000
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/builder/DefaultTypeBuilder.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * 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.metadata.definition.builder;
-
-import org.apache.dubbo.metadata.definition.TypeDefinitionBuilder;
-import org.apache.dubbo.metadata.definition.model.TypeDefinition;
-import org.apache.dubbo.metadata.definition.util.ClassUtils;
-import org.apache.dubbo.metadata.definition.util.JaketConfigurationUtils;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Type;
-import java.util.List;
-import java.util.Map;
-
-/**
- * 2015/1/27.
- */
-public final class DefaultTypeBuilder {
-
- public static TypeDefinition build(Class<?> clazz, Map<String, TypeDefinition> typeCache) {
- final String canonicalName = clazz.getCanonicalName();
-
- // Try to get a cached definition
- TypeDefinition td = typeCache.get(canonicalName);
- if (td != null) {
- return td;
- }
- td = new TypeDefinition(canonicalName);
- typeCache.put(canonicalName, td);
-
- // Primitive type
- if (!JaketConfigurationUtils.needAnalyzing(clazz)) {
- return td;
- }
-
- // Custom type
- List<Field> fields = ClassUtils.getNonStaticFields(clazz);
- for (Field field : fields) {
- String fieldName = field.getName();
- Class<?> fieldClass = field.getType();
- Type fieldType = field.getGenericType();
- TypeDefinition fieldTd = TypeDefinitionBuilder.build(fieldType, fieldClass, typeCache);
- td.getProperties().put(fieldName, fieldTd.getType());
- }
-
- return td;
- }
-
- private DefaultTypeBuilder() {
- }
-}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/builder/EnumTypeBuilder.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/builder/EnumTypeBuilder.java
deleted file mode 100755
index 1f5d52a..0000000
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/builder/EnumTypeBuilder.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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.metadata.definition.builder;
-
-import org.apache.dubbo.common.logger.Logger;
-import org.apache.dubbo.common.logger.LoggerFactory;
-import org.apache.dubbo.metadata.definition.TypeDefinitionBuilder;
-import org.apache.dubbo.metadata.definition.model.TypeDefinition;
-
-import java.lang.reflect.Method;
-import java.lang.reflect.Type;
-import java.util.Map;
-
-/**
- * 2015/1/27.
- */
-public class EnumTypeBuilder implements TypeBuilder {
- private static final Logger logger = LoggerFactory.getLogger(TypeDefinitionBuilder.class);
-
- @Override
- public boolean accept(Class<?> clazz) {
- if (clazz == null) {
- return false;
- }
- return clazz.isEnum();
- }
-
- @Override
- public TypeDefinition build(Type type, Class<?> clazz, Map<String, TypeDefinition> typeCache) {
- String canonicalName = clazz.getCanonicalName();
-
- TypeDefinition td = typeCache.get(canonicalName);
- if (td != null) {
- return td;
- }
- td = new TypeDefinition(canonicalName);
- typeCache.put(canonicalName, td);
-
- try {
- Method methodValues = clazz.getDeclaredMethod("values");
- methodValues.setAccessible(true);
- Object[] values = (Object[]) methodValues.invoke(clazz, new Object[0]);
- int length = values.length;
- for (int i = 0; i < length; i++) {
- Object value = values[i];
- td.getEnums().add(value.toString());
- }
- return td;
- } catch (Throwable t) {
- logger.error("There is an error while process class " + clazz, t);
- }
- return td;
- }
-
-}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/builder/MapTypeBuilder.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/builder/MapTypeBuilder.java
deleted file mode 100755
index 121198c..0000000
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/builder/MapTypeBuilder.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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.metadata.definition.builder;
-
-import org.apache.dubbo.metadata.definition.TypeDefinitionBuilder;
-import org.apache.dubbo.metadata.definition.model.TypeDefinition;
-import org.apache.dubbo.metadata.definition.util.ClassUtils;
-
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.text.MessageFormat;
-import java.util.Arrays;
-import java.util.Map;
-
-import static org.apache.dubbo.common.utils.TypeUtils.getRawClass;
-import static org.apache.dubbo.common.utils.TypeUtils.isClass;
-import static org.apache.dubbo.common.utils.TypeUtils.isParameterizedType;
-
-/**
- * 2015/1/27.
- */
-public class MapTypeBuilder implements TypeBuilder {
-
- @Override
- public boolean accept(Class<?> clazz) {
- if (clazz == null) {
- return false;
- }
- return Map.class.isAssignableFrom(clazz);
- }
-
- @Override
- public TypeDefinition build(Type type, Class<?> clazz, Map<String, TypeDefinition> typeCache) {
- if (!(type instanceof ParameterizedType)) {
- return new TypeDefinition(clazz.getCanonicalName());
- }
-
- ParameterizedType parameterizedType = (ParameterizedType) type;
- Type[] actualTypeArgs = parameterizedType.getActualTypeArguments();
- int actualTypeArgsLength = actualTypeArgs == null ? 0 : actualTypeArgs.length;
-
- if (actualTypeArgsLength != 2) {
- throw new IllegalArgumentException(MessageFormat.format(
- "[ServiceDefinitionBuilder] Map type [{0}] with unexpected amount of arguments [{1}]."
- + Arrays.toString(actualTypeArgs), type, actualTypeArgs));
- }
-
- String mapType = ClassUtils.getCanonicalNameForParameterizedType(parameterizedType);
-
- TypeDefinition td = typeCache.get(mapType);
- if (td != null) {
- return td;
- }
- td = new TypeDefinition(mapType);
- typeCache.put(mapType, td);
-
- for (int i = 0; i < actualTypeArgsLength; i++) {
- Type actualType = actualTypeArgs[i];
- TypeDefinition item = null;
- Class<?> rawType = getRawClass(actualType);
- if (isParameterizedType(actualType)) {
- // Nested collection or map.
- item = TypeDefinitionBuilder.build(actualType, rawType, typeCache);
- } else if (isClass(actualType)) {
- item = TypeDefinitionBuilder.build(null, rawType, typeCache);
- }
- if (item != null) {
- td.getItems().add(item.getType());
- }
- }
- return td;
- }
-}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/builder/TypeBuilder.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/builder/TypeBuilder.java
deleted file mode 100755
index 050de3c..0000000
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/builder/TypeBuilder.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.metadata.definition.builder;
-
-import org.apache.dubbo.common.extension.SPI;
-import org.apache.dubbo.common.lang.Prioritized;
-import org.apache.dubbo.metadata.definition.model.TypeDefinition;
-
-import java.lang.reflect.Type;
-import java.util.Map;
-
-/**
- * 2015/1/27.
- */
-@SPI
-public interface TypeBuilder extends Prioritized {
-
- /**
- * Whether the build accept the class passed in.
- */
- boolean accept(Class<?> clazz);
-
- /**
- * Build type definition with the type or class.
- */
- TypeDefinition build(Type type, Class<?> clazz, Map<String, TypeDefinition> typeCache);
-
-}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/model/FullServiceDefinition.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/model/FullServiceDefinition.java
deleted file mode 100644
index fbebcf1..0000000
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/model/FullServiceDefinition.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.metadata.definition.model;
-
-import java.util.Map;
-
-/**
- * 2018/10/25
- */
-public class FullServiceDefinition extends ServiceDefinition {
-
- private Map<String, String> parameters;
-
- public Map<String, String> getParameters() {
- return parameters;
- }
-
- public void setParameters(Map<String, String> parameters) {
- this.parameters = parameters;
- }
-
- @Override
- public String toString() {
- return "FullServiceDefinition{" +
- "parameters=" + parameters +
- "} " + super.toString();
- }
-
-}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/model/MethodDefinition.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/model/MethodDefinition.java
deleted file mode 100755
index 305bfc3..0000000
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/model/MethodDefinition.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * 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.metadata.definition.model;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Objects;
-
-import static org.apache.dubbo.metadata.definition.model.TypeDefinition.formatType;
-import static org.apache.dubbo.metadata.definition.model.TypeDefinition.formatTypes;
-
-/**
- * 2015/1/27.
- */
-public class MethodDefinition implements Serializable {
-
- private String name;
- private String[] parameterTypes;
- private String returnType;
-
- /**
- * @deprecated please use parameterTypes,
- * and find TypeDefinition in org.apache.dubbo.metadata.definition.model.ServiceDefinition#types
- */
- @Deprecated
- private List<TypeDefinition> parameters;
-
- private List<String> annotations;
-
- public String getName() {
- return name;
- }
-
- public List<TypeDefinition> getParameters() {
- if (parameters == null) {
- parameters = new ArrayList<>();
- }
- return parameters;
- }
-
- public String[] getParameterTypes() {
- return parameterTypes;
- }
-
- public String getReturnType() {
- return returnType;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public void setParameters(List<TypeDefinition> parameters) {
- this.parameters = parameters;
- }
-
- public void setParameterTypes(String[] parameterTypes) {
- this.parameterTypes = formatTypes(parameterTypes);
- }
-
- public void setReturnType(String returnType) {
- this.returnType = formatType(returnType);
- }
-
- public List<String> getAnnotations() {
- if (annotations == null) {
- annotations = Collections.emptyList();
- }
- return annotations;
- }
-
- public void setAnnotations(List<String> annotations) {
- this.annotations = annotations;
- }
-
- @Override
- public String toString() {
- return "MethodDefinition [name=" + name + ", parameterTypes=" + Arrays.toString(parameterTypes)
- + ", returnType=" + returnType + "]";
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (!(o instanceof MethodDefinition)) {
- return false;
- }
- MethodDefinition that = (MethodDefinition) o;
- return Objects.equals(getName(), that.getName()) &&
- Arrays.equals(getParameterTypes(), that.getParameterTypes()) &&
- Objects.equals(getReturnType(), that.getReturnType());
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(getName(), getReturnType(), Arrays.toString(getParameterTypes()));
- }
-}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/model/ServiceDefinition.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/model/ServiceDefinition.java
deleted file mode 100755
index 40ced04..0000000
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/model/ServiceDefinition.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * 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.metadata.definition.model;
-
-import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Objects;
-
-import org.apache.dubbo.metadata.definition.util.ClassUtils;
-
-/**
- * 2015/1/27.
- */
-public class ServiceDefinition implements Serializable {
-
- /**
- * the canonical name of interface
- *
- * @see Class#getCanonicalName()
- */
- private String canonicalName;
-
- /**
- * the location of class file
- *
- * @see ClassUtils#getCodeSource(Class)
- */
- private String codeSource;
-
- private List<MethodDefinition> methods;
-
- /**
- * the definitions of type
- */
- private List<TypeDefinition> types;
-
- /**
- * the definitions of annotations
- */
- private List<String> annotations;
-
- public String getCanonicalName() {
- return canonicalName;
- }
-
- public String getCodeSource() {
- return codeSource;
- }
-
- public List<MethodDefinition> getMethods() {
- if (methods == null) {
- methods = new ArrayList<>();
- }
- return methods;
- }
-
- public List<TypeDefinition> getTypes() {
- if (types == null) {
- types = new ArrayList<>();
- }
- return types;
- }
-
- public String getUniqueId() {
- return canonicalName + "@" + codeSource;
- }
-
- public void setCanonicalName(String canonicalName) {
- this.canonicalName = canonicalName;
- }
-
- public void setCodeSource(String codeSource) {
- this.codeSource = codeSource;
- }
-
- public void setMethods(List<MethodDefinition> methods) {
- this.methods = methods;
- }
-
- public void setTypes(List<TypeDefinition> types) {
- this.types = types;
- }
-
- public List<String> getAnnotations() {
- if (annotations == null) {
- annotations = Collections.emptyList();
- }
- return annotations;
- }
-
- public void setAnnotations(List<String> annotations) {
- this.annotations = annotations;
- }
-
- @Override
- public String toString() {
- return "ServiceDefinition [canonicalName=" + canonicalName + ", codeSource=" + codeSource + ", methods="
- + methods + "]";
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (!(o instanceof ServiceDefinition)) {
- return false;
- }
- ServiceDefinition that = (ServiceDefinition) o;
- return Objects.equals(getCanonicalName(), that.getCanonicalName()) &&
- Objects.equals(getCodeSource(), that.getCodeSource()) &&
- Objects.equals(getMethods(), that.getMethods()) &&
- Objects.equals(getTypes(), that.getTypes());
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(getCanonicalName(), getCodeSource(), getMethods(), getTypes());
- }
-}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/model/TypeDefinition.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/model/TypeDefinition.java
deleted file mode 100755
index 6dd0f06..0000000
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/model/TypeDefinition.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * 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.metadata.definition.model;
-
-import com.google.gson.annotations.SerializedName;
-
-import java.io.Serializable;
-import java.lang.reflect.ParameterizedType;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-
-import static org.apache.dubbo.common.utils.StringUtils.replace;
-
-/**
- * 2015/1/27.
- */
-public class TypeDefinition implements Serializable {
-
- /**
- * the name of type
- *
- * @see Class#getCanonicalName()
- * @see org.apache.dubbo.metadata.definition.util.ClassUtils#getCanonicalNameForParameterizedType(ParameterizedType)
- */
- private String type;
-
- /**
- * the items(generic parameter) of Map/List(ParameterizedType)
- * <p>
- * if this type is not ParameterizedType, the items is null or empty
- */
- @SerializedName("items")
- private List<String> items;
-
- /**
- * the enum's value
- * <p>
- * If this type is not enum, enums is null or empty
- */
- @SerializedName("enum")
- private List<String> enums;
-
- /**
- * the key is property name,
- * the value is property's type name
- */
- private Map<String, String> properties;
-
- public TypeDefinition() {
- }
-
- public TypeDefinition(String type) {
- this.setType(type);
- }
-
- /**
- * Format the {@link String} array presenting Java types
- *
- * @param types the strings presenting Java types
- * @return new String array of Java types after be formatted
- * @since 2.7.9
- */
- public static String[] formatTypes(String[] types) {
- String[] newTypes = new String[types.length];
- for (int i = 0; i < types.length; i++) {
- newTypes[i] = formatType(types[i]);
- }
- return newTypes;
- }
-
- /**
- * Format the {@link String} presenting Java type
- *
- * @param type the String presenting type
- * @return new String presenting Java type after be formatted
- * @since 2.7.9
- */
- public static String formatType(String type) {
- if (isGenericType(type)) {
- return formatGenericType(type);
- }
- return type;
- }
-
- /**
- * Replacing <code>", "</code> to <code>","</code> will not change the semantic of
- * {@link ParameterizedType#toString()}
- *
- * @param type
- * @return formatted type
- * @see sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
- */
- private static String formatGenericType(String type) {
- return replace(type, ", ", ",");
- }
-
- private static boolean isGenericType(String type) {
- return type.contains("<") && type.contains(">");
- }
-
- public List<String> getEnums() {
- if (enums == null) {
- enums = new ArrayList<>();
- }
- return enums;
- }
-
- public List<String> getItems() {
- if (items == null) {
- items = new ArrayList<>();
- }
- return items;
- }
-
- public Map<String, String> getProperties() {
- if (properties == null) {
- properties = new HashMap<>();
- }
- return properties;
- }
-
- public String getType() {
- return type;
- }
-
- public void setEnums(List<String> enums) {
- this.enums = enums;
- }
-
- public void setItems(List<String> items) {
- this.items = items;
- }
-
- public void setProperties(Map<String, String> properties) {
- this.properties = properties;
- }
-
- public void setType(String type) {
- this.type = formatType(type);
- }
-
- @Override
- public String toString() {
- return "TypeDefinition [type=" + type + ", properties=" + properties + "]";
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) {
- return true;
- }
- if (!(o instanceof TypeDefinition)) {
- return false;
- }
- TypeDefinition that = (TypeDefinition) o;
- return Objects.equals(getType(), that.getType()) &&
- Objects.equals(getItems(), that.getItems()) &&
- Objects.equals(getEnums(), that.getEnums()) &&
- Objects.equals(getProperties(), that.getProperties());
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(getType(), getItems(), getEnums(), getProperties());
- }
-}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/util/ClassUtils.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/util/ClassUtils.java
deleted file mode 100755
index c6f13d5..0000000
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/util/ClassUtils.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * 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.metadata.definition.util;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.net.URL;
-import java.security.CodeSource;
-import java.security.ProtectionDomain;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * 2015/1/27.
- */
-public final class ClassUtils {
-
- /**
- * Get the code source file or class path of the Class passed in.
- *
- * @param clazz
- * @return Jar file name or class path.
- */
- public static String getCodeSource(Class<?> clazz) {
- ProtectionDomain protectionDomain = clazz.getProtectionDomain();
- if (protectionDomain == null || protectionDomain.getCodeSource() == null) {
- return null;
- }
-
- CodeSource codeSource = clazz.getProtectionDomain().getCodeSource();
- URL location = codeSource.getLocation();
- if (location == null) {
- return null;
- }
-
- String path = location.toExternalForm();
-
- if (path.endsWith(".jar") && path.contains("/")) {
- return path.substring(path.lastIndexOf('/') + 1);
- }
- return path;
- }
-
- /**
- * Get all non-static fields of the Class passed in or its super classes.
- * <p>
- *
- * @param clazz Class to parse.
- * @return field list
- */
- public static List<Field> getNonStaticFields(final Class<?> clazz) {
- List<Field> result = new ArrayList<>();
- Class<?> target = clazz;
- while (target != null) {
- if (JaketConfigurationUtils.isExcludedType(target)) {
- break;
- }
-
- Field[] fields = target.getDeclaredFields();
- for (Field field : fields) {
- int modifiers = field.getModifiers();
- if (Modifier.isStatic(modifiers) || Modifier.isTransient(modifiers)) {
- continue;
- }
-
- result.add(field);
- }
- target = target.getSuperclass();
- }
-
- return result;
- }
-
- /**
- * Get all public, non-static methods of the Class passed in.
- * <p>
- *
- * @param clazz Class to parse.
- * @return methods list
- */
- public static List<Method> getPublicNonStaticMethods(final Class<?> clazz) {
- List<Method> result = new ArrayList<Method>();
-
- Method[] methods = clazz.getMethods();
- for (Method method : methods) {
- int mod = method.getModifiers();
- if (Modifier.isPublic(mod) && !Modifier.isStatic(mod)) {
- result.add(method);
- }
- }
- return result;
- }
-
- public static String getCanonicalNameForParameterizedType(ParameterizedType parameterizedType) {
- StringBuilder sb = new StringBuilder();
- Type ownerType = parameterizedType.getOwnerType();
- Class<?> rawType = (Class) parameterizedType.getRawType();
- Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
-
- if (ownerType != null) {
- if (ownerType instanceof Class) {
- sb.append(((Class) ownerType).getName());
- } else {
- sb.append(ownerType);
- }
-
- sb.append('.');
-
- if (ownerType instanceof ParameterizedType) {
- // Find simple name of nested type by removing the
- // shared prefix with owner.
- sb.append(rawType.getName().replace(((Class) ((ParameterizedType) ownerType).getRawType()).getName() + "$",
- ""));
- } else {
- sb.append(rawType.getSimpleName());
- }
- } else {
- sb.append(rawType.getCanonicalName());
- }
-
- if (actualTypeArguments != null &&
- actualTypeArguments.length > 0) {
- sb.append('<');
- boolean first = true;
- for (Type t : actualTypeArguments) {
- if (!first) {
- sb.append(", ");
- }
- if (t instanceof Class) {
- Class c = (Class) t;
- sb.append(c.getCanonicalName());
- } else if (t instanceof ParameterizedType) {
- sb.append(getCanonicalNameForParameterizedType((ParameterizedType) t));
- } else {
- sb.append(t.toString());
- }
- first = false;
- }
- sb.append('>');
- }
-
- return sb.toString();
- }
-
- private ClassUtils() {
- }
-}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/util/JaketConfigurationUtils.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/util/JaketConfigurationUtils.java
deleted file mode 100755
index a21de3f..0000000
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/definition/util/JaketConfigurationUtils.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * 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.metadata.definition.util;
-
-import org.apache.dubbo.common.utils.StringUtils;
-
-import java.io.InputStream;
-import java.util.Properties;
-
-/**
- * 2015/1/27.
- */
-public class JaketConfigurationUtils {
-
- private static final String CONFIGURATION_FILE = "jaket.properties";
-
- private static String[] includedInterfacePackages;
- private static String[] includedTypePackages;
- private static String[] closedTypes;
-
- static {
- Properties props = new Properties();
- InputStream inStream = JaketConfigurationUtils.class.getClassLoader().getResourceAsStream(CONFIGURATION_FILE);
- try {
- props.load(inStream);
- String value = (String) props.get("included_interface_packages");
- if (StringUtils.isNotEmpty(value)) {
- includedInterfacePackages = value.split(",");
- }
-
- value = props.getProperty("included_type_packages");
- if (StringUtils.isNotEmpty(value)) {
- includedTypePackages = value.split(",");
- }
-
- value = props.getProperty("closed_types");
- if (StringUtils.isNotEmpty(value)) {
- closedTypes = value.split(",");
- }
-
- } catch (Throwable e) {
- // Ignore it.
- }
- }
-
- public static boolean isExcludedInterface(Class<?> clazz) {
- if (includedInterfacePackages == null || includedInterfacePackages.length == 0) {
- return false;
- }
-
- for (String packagePrefix : includedInterfacePackages) {
- if (clazz.getCanonicalName().startsWith(packagePrefix)) {
- return false;
- }
- }
-
- return true;
- }
-
- public static boolean isExcludedType(Class<?> clazz) {
- if (includedTypePackages == null || includedTypePackages.length == 0) {
- return false;
- }
-
- for (String packagePrefix : includedTypePackages) {
- if (clazz.getCanonicalName().startsWith(packagePrefix)) {
- return false;
- }
- }
-
- return true;
- }
-
- public static boolean needAnalyzing(Class<?> clazz) {
- String canonicalName = clazz.getCanonicalName();
-
- if (closedTypes != null && closedTypes.length > 0) {
- for (String type : closedTypes) {
- if (canonicalName.startsWith(type)) {
- return false;
- }
- }
- }
-
- return !isExcludedType(clazz);
- }
-
-}
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 3dc659e..0208650 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
@@ -78,6 +78,10 @@ public interface MetadataReport {
return false;
}
+ default void removeServiceAppMappingListener(String serviceKey, MappingListener listener) {
+
+ }
+
/**
* Service<-->Application Mapping -- START
**/
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/AbstractAbstractWritableMetadataService.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/AbstractAbstractWritableMetadataService.java
deleted file mode 100644
index d084477..0000000
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/store/AbstractAbstractWritableMetadataService.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * 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.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.WritableMetadataService;
-import org.apache.dubbo.metadata.definition.model.ServiceDefinition;
-
-import com.google.gson.Gson;
-
-import static org.apache.dubbo.common.constants.CommonConstants.PID_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER_SIDE;
-import static org.apache.dubbo.common.constants.CommonConstants.TIMESTAMP_KEY;
-import static org.apache.dubbo.common.utils.ClassUtils.forName;
-import static org.apache.dubbo.metadata.definition.ServiceDefinitionBuilder.buildFullDefinition;
-import static org.apache.dubbo.remoting.Constants.BIND_IP_KEY;
-import static org.apache.dubbo.remoting.Constants.BIND_PORT_KEY;
-import static org.apache.dubbo.rpc.Constants.GENERIC_KEY;
-import static org.apache.dubbo.rpc.support.ProtocolUtils.isGeneric;
-
-/**
- * The abstract implementation of {@link WritableMetadataService}
- *
- * @see WritableMetadataService
- * @since 2.7.8
- */
-public abstract class AbstractAbstractWritableMetadataService implements WritableMetadataService {
-
- protected final Logger logger = LoggerFactory.getLogger(getClass());
-
- @Override
- public void publishServiceDefinition(URL url) {
- if (SERVICE_INTERFACE_NAME.equals(url.getServiceInterface())) { // Ignore the interface "MetadataService"
- return;
- }
-
- // Remove the useless parameters
- url = url.removeParameters(PID_KEY, TIMESTAMP_KEY, BIND_IP_KEY, BIND_PORT_KEY, TIMESTAMP_KEY);
-
- String side = url.getSide();
- if (PROVIDER_SIDE.equalsIgnoreCase(side)) {
- publishProviderServiceDefinition(url);
- } else {
- publishConsumerParameters(url);
- }
- }
-
- protected void publishProviderServiceDefinition(URL url) {
- String serviceDefinition = getServiceDefinition(url);
- if (!StringUtils.isBlank(serviceDefinition)) {
- publishServiceDefinition(url.getServiceKey(), serviceDefinition);
- }
- }
-
- protected String getServiceDefinition(URL exportedURL) {
- String interfaceName = exportedURL.getServiceInterface();
- String json = null;
- try {
- if (StringUtils.isNotEmpty(interfaceName) && !isGeneric(exportedURL.getParameter(GENERIC_KEY))) {
- Class interfaceClass = forName(interfaceName);
- ServiceDefinition serviceDefinition = buildFullDefinition(interfaceClass, exportedURL.getParameters());
- Gson gson = new Gson();
- json = gson.toJson(serviceDefinition);
- }
- } catch (ClassNotFoundException e) {
- //ignore error
- if (logger.isErrorEnabled()) {
- logger.error("The interface class[name : " + interfaceName + "] can't be found , providerUrl: "
- + exportedURL.toFullString());
- }
- }
- return json;
- }
-
- protected void publishConsumerParameters(URL url) {
- }
-
- protected void publishServiceDefinition(String key, String json) {
- }
-
-}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/AbstractServiceNameMappingTest.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/AbstractServiceNameMappingTest.java
index 2c974c8..3134c9e 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/AbstractServiceNameMappingTest.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/AbstractServiceNameMappingTest.java
@@ -17,19 +17,15 @@
package org.apache.dubbo.metadata;
import org.apache.dubbo.common.URL;
+
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Collections;
-import java.util.HashMap;
import java.util.HashSet;
-import java.util.Map;
import java.util.Set;
-import java.util.SortedSet;
-import java.util.TreeSet;
import static org.apache.dubbo.common.constants.RegistryConstants.PROVIDED_BY;
import static org.apache.dubbo.common.constants.RegistryConstants.SUBSCRIBED_SERVICE_NAMES_KEY;
@@ -40,14 +36,9 @@ import static org.apache.dubbo.common.constants.RegistryConstants.SUBSCRIBED_SER
class AbstractServiceNameMappingTest {
private MockServiceNameMapping mapping = new MockServiceNameMapping();
- private MockWritableMetadataService writableMetadataService = new MockWritableMetadataService();
@BeforeEach
- public void setUp() throws Exception {
- Field metadataService = mapping.getClass().getSuperclass().getDeclaredField("metadataService");
- metadataService.setAccessible(true);
- metadataService.set(mapping, writableMetadataService);
- }
+ public void setUp() throws Exception {}
@Test
void testGetServices() {
@@ -63,10 +54,8 @@ class AbstractServiceNameMappingTest {
Assertions.assertTrue(services.contains("remote-app2"));
- Map<String, Set<String>> cachedMapping = writableMetadataService.getCachedMapping();
- Assertions.assertNotNull(cachedMapping);
- Assertions.assertTrue(cachedMapping.containsKey(ServiceNameMapping.buildMappingKey(url)));
- Assertions.assertIterableEquals(cachedMapping.get(ServiceNameMapping.buildMappingKey(url)), services);
+ Assertions.assertNotNull(mapping.getCachedMapping(url));
+ Assertions.assertIterableEquals(mapping.getCachedMapping(url), services);
}
@@ -76,17 +65,25 @@ class AbstractServiceNameMappingTest {
URL registryURL = URL.valueOf("registry://127.0.0.1:7777/test");
registryURL = registryURL.addParameter(SUBSCRIBED_SERVICE_NAMES_KEY, "registry-app1");
- Set<String> services = mapping.getAndListenServices(registryURL, url, null);
+ Set<String> services = mapping.getAndListen(registryURL, url, null);
Assertions.assertTrue(services.contains("registry-app1"));
mapping.enabled = true;
- services = mapping.getAndListenServices(registryURL, url, event -> {
+ services = mapping.getAndListen(registryURL, url, new MappingListener() {
+ @Override
+ public void onEvent(MappingChangedEvent event) {
+
+ }
+
+ @Override
+ public void stop() {
+
+ }
});
Assertions.assertTrue(services.contains("remote-app3"));
}
-
private class MockServiceNameMapping extends AbstractServiceNameMapping {
public boolean enabled = false;
@@ -105,94 +102,14 @@ class AbstractServiceNameMappingTest {
}
@Override
- public boolean map(URL url) {
- return false;
- }
- }
+ protected void removeListener(URL url, MappingListener mappingListener) {
- private class MockWritableMetadataService implements WritableMetadataService {
- private final Map<String, Set<String>> serviceToAppsMapping = new HashMap<>();
-
- @Override
- public String serviceName() {
- return null;
}
@Override
- public SortedSet<String> getExportedURLs(String serviceInterface, String group, String version, String protocol) {
- return null;
- }
-
- @Override
- public String getServiceDefinition(String serviceKey) {
- return null;
- }
-
- @Override
- public MetadataInfo getMetadataInfo(String revision) {
- return null;
- }
-
- @Override
- public Map<String, MetadataInfo> getMetadataInfos() {
- return null;
- }
-
- @Override
- public boolean exportURL(URL url) {
- return false;
- }
-
- @Override
- public boolean unexportURL(URL url) {
- return false;
- }
-
- @Override
- public boolean subscribeURL(URL url) {
- return false;
- }
-
- @Override
- public boolean unsubscribeURL(URL url) {
+ public boolean map(URL url) {
return false;
}
-
- @Override
- public void publishServiceDefinition(URL url) {
-
- }
-
- @Override
- public Set<String> getCachedMapping(String mappingKey) {
- return serviceToAppsMapping.get(mappingKey);
- }
-
- @Override
- public Set<String> getCachedMapping(URL consumerURL) {
- String serviceKey = ServiceNameMapping.buildMappingKey(consumerURL);
- return serviceToAppsMapping.get(serviceKey);
- }
-
- @Override
- public Set<String> removeCachedMapping(String serviceKey) {
- return serviceToAppsMapping.remove(serviceKey);
- }
-
- @Override
- public void putCachedMapping(String serviceKey, Set<String> apps) {
- serviceToAppsMapping.put(serviceKey, new TreeSet<>(apps));
- }
-
- @Override
- public Map<String, Set<String>> getCachedMapping() {
- return serviceToAppsMapping;
- }
-
- @Override
- public MetadataInfo getDefaultMetadataInfo() {
- return null;
- }
}
}
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/MetadataInfoTest.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/MetadataInfoTest.java
index ca25300..8b05868 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/MetadataInfoTest.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/MetadataInfoTest.java
@@ -63,7 +63,7 @@ public class MetadataInfoTest {
MetadataInfo metadataInfo = new MetadataInfo("demo");
// export normal url again
- metadataInfo.addService(new MetadataInfo.ServiceInfo(url));
+ metadataInfo.addService(url);
MetadataInfo.ServiceInfo serviceInfo2 = metadataInfo.getServiceInfo(url.getProtocolServiceKey());
assertNotNull(serviceInfo2);
assertEquals(5, serviceInfo2.getParams().size());
@@ -80,31 +80,31 @@ public class MetadataInfoTest {
public void testEqualsAndRevision() {
// same metadata
MetadataInfo metadataInfo = new MetadataInfo("demo");
- metadataInfo.addService(new MetadataInfo.ServiceInfo(url));
+ metadataInfo.addService(url);
MetadataInfo sameMetadataInfo = new MetadataInfo("demo");
- sameMetadataInfo.addService(new MetadataInfo.ServiceInfo(url));
+ sameMetadataInfo.addService(url);
assertEquals(metadataInfo, sameMetadataInfo);
assertEquals(metadataInfo.calAndGetRevision(), sameMetadataInfo.calAndGetRevision());
// url with different params that are not counted in ServiceInfo
MetadataInfo metadataInfoWithDifferentParam1 = new MetadataInfo("demo");
- metadataInfoWithDifferentParam1.addService(new MetadataInfo.ServiceInfo(url.addParameter("delay", 6000)));
+ metadataInfoWithDifferentParam1.addService(url.addParameter("delay", 6000));
assertEquals(metadataInfo, metadataInfoWithDifferentParam1);
assertEquals(metadataInfo.calAndGetRevision(), metadataInfoWithDifferentParam1.calAndGetRevision());
// url with different params that are counted in ServiceInfo
MetadataInfo metadataInfoWithDifferentParam2 = new MetadataInfo("demo");
- metadataInfoWithDifferentParam2.addService(new MetadataInfo.ServiceInfo(url.addParameter(TIMEOUT_KEY, 6000)));
+ metadataInfoWithDifferentParam2.addService(url.addParameter(TIMEOUT_KEY, 6000));
assertNotEquals(metadataInfo, metadataInfoWithDifferentParam2);
assertNotEquals(metadataInfo.calAndGetRevision(), metadataInfoWithDifferentParam2.calAndGetRevision());
MetadataInfo metadataInfoWithDifferentGroup = new MetadataInfo("demo");
- metadataInfoWithDifferentGroup.addService(new MetadataInfo.ServiceInfo(url.addParameter(GROUP_KEY, "newGroup")));
+ metadataInfoWithDifferentGroup.addService(url.addParameter(GROUP_KEY, "newGroup"));
assertNotEquals(metadataInfo, metadataInfoWithDifferentGroup);
assertNotEquals(metadataInfo.calAndGetRevision(), metadataInfoWithDifferentGroup.calAndGetRevision());
MetadataInfo metadataInfoWithDifferentServices = new MetadataInfo("demo");
- metadataInfoWithDifferentServices.addService(new MetadataInfo.ServiceInfo(url));
- metadataInfoWithDifferentServices.addService(new MetadataInfo.ServiceInfo(url2));
+ metadataInfoWithDifferentServices.addService(url);
+ metadataInfoWithDifferentServices.addService(url2);
assertNotEquals(metadataInfo, metadataInfoWithDifferentServices);
assertNotEquals(metadataInfo.calAndGetRevision(), metadataInfoWithDifferentServices.calAndGetRevision());
}
@@ -112,12 +112,12 @@ public class MetadataInfoTest {
@Test
public void testChanged() {
MetadataInfo metadataInfo = new MetadataInfo("demo");
- metadataInfo.addService(new MetadataInfo.ServiceInfo(url));
- metadataInfo.addService(new MetadataInfo.ServiceInfo(url2));
- assertFalse(metadataInfo.hasReported());
- metadataInfo.markReported();
- assertTrue(metadataInfo.hasReported());
- metadataInfo.removeService(new MetadataInfo.ServiceInfo(url2));
- assertFalse(metadataInfo.hasReported());
+ metadataInfo.addService(url);
+ metadataInfo.addService(url2);
+ assertTrue(metadataInfo.updated.get());
+ metadataInfo.calAndGetRevision();
+ assertFalse(metadataInfo.updated.get());
+ metadataInfo.removeService(url2);
+ assertTrue(metadataInfo.updated.get());
}
}
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 4a9acc9..eb68abf 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
@@ -18,6 +18,7 @@ package org.apache.dubbo.metadata.report.support;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.utils.NetUtils;
+import org.apache.dubbo.metadata.MappingListener;
import org.apache.dubbo.metadata.definition.model.ServiceDefinition;
import org.apache.dubbo.metadata.report.MetadataReport;
import org.apache.dubbo.metadata.report.identifier.MetadataIdentifier;
@@ -79,6 +80,11 @@ public class AbstractMetadataReportFactoryTest {
}
@Override
+ public void removeServiceAppMappingListener(String serviceKey, MappingListener listener) {
+
+ }
+
+ @Override
public String getServiceDefinition(MetadataIdentifier consumerMetadataIdentifier) {
return null;
}
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 9d20e91..624a97f 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
@@ -17,10 +17,10 @@
package org.apache.dubbo.metadata.report.support;
-import com.google.gson.Gson;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.utils.NetUtils;
import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.metadata.MappingListener;
import org.apache.dubbo.metadata.definition.ServiceDefinitionBuilder;
import org.apache.dubbo.metadata.definition.model.FullServiceDefinition;
import org.apache.dubbo.metadata.report.identifier.KeyTypeEnum;
@@ -28,6 +28,8 @@ 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.rpc.model.ApplicationModel;
+
+import com.google.gson.Gson;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
@@ -314,6 +316,11 @@ public class AbstractMetadataReportTest {
public String getServiceDefinition(MetadataIdentifier consumerMetadataIdentifier) {
throw new UnsupportedOperationException("This extension does not support working as a remote metadata center.");
}
+
+ @Override
+ public void removeServiceAppMappingListener(String serviceKey, MappingListener listener) {
+ throw new UnsupportedOperationException("This extension does not support working as a remote metadata center.");
+ }
}
private static class RetryMetadataReport extends AbstractMetadataReport {
@@ -376,6 +383,11 @@ public class AbstractMetadataReportTest {
throw new UnsupportedOperationException("This extension does not support working as a remote metadata center.");
}
+ @Override
+ public void removeServiceAppMappingListener(String serviceKey, MappingListener listener) {
+ 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 c52aff9..8e94495 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
@@ -19,6 +19,7 @@ package org.apache.dubbo.metadata.test;
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.MappingListener;
import org.apache.dubbo.metadata.report.identifier.KeyTypeEnum;
import org.apache.dubbo.metadata.report.identifier.MetadataIdentifier;
import org.apache.dubbo.metadata.report.identifier.ServiceMetadataIdentifier;
@@ -98,4 +99,9 @@ public class JTestMetadataReport4Test extends AbstractMetadataReport {
public String getServiceDefinition(MetadataIdentifier consumerMetadataIdentifier) {
return store.get(consumerMetadataIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY));
}
+
+ @Override
+ public void removeServiceAppMappingListener(String serviceKey, MappingListener listener) {
+
+ }
}
diff --git a/dubbo-metadata/dubbo-metadata-report-nacos/src/main/java/org/apache/dubbo/metadata/store/nacos/NacosConfigServiceWrapper.java b/dubbo-metadata/dubbo-metadata-report-nacos/src/main/java/org/apache/dubbo/metadata/store/nacos/NacosConfigServiceWrapper.java
index 54bfa60..3fb52fb 100644
--- a/dubbo-metadata/dubbo-metadata-report-nacos/src/main/java/org/apache/dubbo/metadata/store/nacos/NacosConfigServiceWrapper.java
+++ b/dubbo-metadata/dubbo-metadata-report-nacos/src/main/java/org/apache/dubbo/metadata/store/nacos/NacosConfigServiceWrapper.java
@@ -45,6 +45,10 @@ public class NacosConfigServiceWrapper {
configService.addListener(handleInnerSymbol(dataId), handleInnerSymbol(group), listener);
}
+ public void removeListener(String dataId, String group, Listener listener) throws NacosException {
+ configService.removeListener(handleInnerSymbol(dataId), handleInnerSymbol(group), listener);
+ }
+
public String getConfig(String dataId, String group) throws NacosException {
return configService.getConfig(handleInnerSymbol(dataId), handleInnerSymbol(group), DEFAULT_TIMEOUT);
}
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 30b26b7..bfe982f 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
@@ -34,7 +34,6 @@ 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.metadata.report.support.AbstractMetadataReport;
-import org.apache.dubbo.rpc.RpcException;
import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.PropertyKeyConst;
@@ -243,6 +242,14 @@ public class NacosMetadataReport extends AbstractMetadataReport {
}
@Override
+ public void removeServiceAppMappingListener(String serviceKey, MappingListener listener) {
+ MappingDataListener mappingDataListener = casListenerMap.get(buildListenerKey(serviceKey, group));
+ if (null != mappingDataListener) {
+ removeCasServiceMappingListener(serviceKey, group, listener);
+ }
+ }
+
+ @Override
public Set<String> getServiceAppMapping(String serviceKey, URL url) {
String content = getConfig(serviceKey, DEFAULT_MAPPING_GROUP);
return ServiceNameMapping.getAppNames(content);
@@ -263,6 +270,17 @@ public class NacosMetadataReport extends AbstractMetadataReport {
addListener(serviceKey, DEFAULT_MAPPING_GROUP, mappingDataListener);
}
+ private void removeCasServiceMappingListener(String serviceKey, String group, MappingListener listener) {
+ MappingDataListener mappingDataListener = casListenerMap.get(buildListenerKey(serviceKey, group));
+ if (mappingDataListener != null) {
+ mappingDataListener.removeListeners(listener);
+ if (mappingDataListener.isEmpty()) {
+ removeListener(serviceKey, DEFAULT_MAPPING_GROUP, mappingDataListener);
+ casListenerMap.remove(buildListenerKey(serviceKey, group), mappingDataListener);
+ }
+ }
+ }
+
public void addListener(String key, String group, ConfigurationListener listener) {
String listenerKey = buildListenerKey(key, group);
NacosConfigListener nacosConfigListener =
@@ -275,6 +293,22 @@ public class NacosMetadataReport extends AbstractMetadataReport {
}
}
+ public void removeListener(String key, String group, ConfigurationListener listener) {
+ String listenerKey = buildListenerKey(key, group);
+ NacosConfigListener nacosConfigListener = watchListenerMap.get(listenerKey);
+ try {
+ if (nacosConfigListener != null) {
+ nacosConfigListener.removeListener(listener);
+ if (nacosConfigListener.isEmpty()) {
+ configService.removeListener(key, group, nacosConfigListener);
+ watchListenerMap.remove(listenerKey);
+ }
+ }
+ } catch (NacosException e) {
+ logger.error(e.getMessage());
+ }
+ }
+
private NacosConfigListener createTargetListener(String key, String group) {
NacosConfigListener configListener = new NacosConfigListener();
configListener.fillContext(key, group);
@@ -294,7 +328,7 @@ public class NacosMetadataReport extends AbstractMetadataReport {
}
} catch (Throwable t) {
logger.error("Failed to put " + identifier + " to nacos " + value + ", cause: " + t.getMessage(), t);
- throw new RpcException("Failed to put " + identifier + " to nacos " + value + ", cause: " + t.getMessage(), t);
+ throw new RuntimeException("Failed to put " + identifier + " to nacos " + value + ", cause: " + t.getMessage(), t);
}
}
@@ -306,7 +340,7 @@ public class NacosMetadataReport extends AbstractMetadataReport {
}
} catch (Throwable t) {
logger.error("Failed to remove " + identifier + " from nacos , cause: " + t.getMessage(), t);
- throw new RpcException("Failed to remove " + identifier + " from nacos , cause: " + t.getMessage(), t);
+ throw new RuntimeException("Failed to remove " + identifier + " from nacos , cause: " + t.getMessage(), t);
}
}
@@ -315,7 +349,7 @@ public class NacosMetadataReport extends AbstractMetadataReport {
return configService.getConfig(identifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY), group, 3000L);
} catch (Throwable t) {
logger.error("Failed to get " + identifier + " from nacos , cause: " + t.getMessage(), t);
- throw new RpcException("Failed to get " + identifier + " from nacos , cause: " + t.getMessage(), t);
+ throw new RuntimeException("Failed to get " + identifier + " from nacos , cause: " + t.getMessage(), t);
}
}
@@ -360,6 +394,10 @@ public class NacosMetadataReport extends AbstractMetadataReport {
this.listeners.remove(configurationListener);
}
+ boolean isEmpty() {
+ return this.listeners.isEmpty();
+ }
+
private ConfigChangeType getChangeType(String configInfo, String oldValue) {
if (StringUtils.isBlank(configInfo)) {
return ConfigChangeType.DELETED;
@@ -392,6 +430,14 @@ public class NacosMetadataReport extends AbstractMetadataReport {
listeners.add(mappingListener);
}
+ public void removeListeners(MappingListener mappingListener) {
+ listeners.remove(mappingListener);
+ }
+
+ public boolean isEmpty() {
+ return listeners.isEmpty();
+ }
+
@Override
public void process(ConfigChangedEvent event) {
if (ConfigChangeType.DELETED == event.getChangeType()) {
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 78a1909..3909227 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
@@ -16,7 +16,6 @@
*/
package org.apache.dubbo.metadata.store.zookeeper;
-import com.google.gson.Gson;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.config.configcenter.ConfigItem;
import org.apache.dubbo.common.logger.Logger;
@@ -35,6 +34,8 @@ import org.apache.dubbo.remoting.zookeeper.DataListener;
import org.apache.dubbo.remoting.zookeeper.EventType;
import org.apache.dubbo.remoting.zookeeper.ZookeeperClient;
import org.apache.dubbo.remoting.zookeeper.ZookeeperTransporter;
+
+import com.google.gson.Gson;
import org.apache.zookeeper.data.Stat;
import java.util.ArrayList;
@@ -161,6 +162,14 @@ public class ZookeeperMetadataReport extends AbstractMetadataReport {
}
@Override
+ public void removeServiceAppMappingListener(String serviceKey, MappingListener listener) {
+ String path = buildPathKey(DEFAULT_MAPPING_GROUP, serviceKey);
+ if (null != casListenerMap.get(path)) {
+ removeCasServiceMappingListener(path, listener);
+ }
+ }
+
+ @Override
public Set<String> getServiceAppMapping(String serviceKey, URL url) {
String path = buildPathKey(DEFAULT_MAPPING_GROUP, serviceKey);
return getAppNames(zkClient.getContent(path));
@@ -204,6 +213,15 @@ public class ZookeeperMetadataReport extends AbstractMetadataReport {
zkClient.addDataListener(path, mappingDataListener);
}
+ private void removeCasServiceMappingListener(String path, MappingListener listener) {
+ MappingDataListener mappingDataListener = casListenerMap.get(path);
+ mappingDataListener.removeListener(listener);
+ if (mappingDataListener.isEmpty()) {
+ zkClient.removeDataListener(path, mappingDataListener);
+ casListenerMap.remove(path, mappingDataListener);
+ }
+ }
+
private static class MappingDataListener implements DataListener {
private String serviceKey;
@@ -220,6 +238,14 @@ public class ZookeeperMetadataReport extends AbstractMetadataReport {
this.listeners.add(listener);
}
+ public void removeListener(MappingListener listener) {
+ this.listeners.remove(listener);
+ }
+
+ public boolean isEmpty() {
+ return listeners.isEmpty();
+ }
+
@Override
public void dataChanged(String path, Object value, EventType eventType) {
if (!this.path.equals(path)) {
diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/PublishMetadata.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/PublishMetadata.java
index 97767b1..8cf435a 100644
--- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/PublishMetadata.java
+++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/PublishMetadata.java
@@ -20,11 +20,9 @@ import org.apache.dubbo.common.logger.Logger;
import org.apache.dubbo.common.logger.LoggerFactory;
import org.apache.dubbo.common.threadpool.manager.ExecutorRepository;
import org.apache.dubbo.common.utils.ArrayUtils;
-import org.apache.dubbo.config.deploy.DefaultApplicationDeployer;
import org.apache.dubbo.qos.command.BaseCommand;
import org.apache.dubbo.qos.command.CommandContext;
import org.apache.dubbo.qos.command.annotation.Cmd;
-import org.apache.dubbo.registry.client.ServiceInstance;
import org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.FrameworkModel;
@@ -52,24 +50,20 @@ public class PublishMetadata implements BaseCommand {
List<ApplicationModel> applicationModels = frameworkModel.getApplicationModels();
for (ApplicationModel applicationModel : applicationModels) {
- DefaultApplicationDeployer deployer = applicationModel.getBeanFactory().getBean(DefaultApplicationDeployer.class);
- ServiceInstance serviceInstance = deployer.getServiceInstance();
- if (serviceInstance != null) {
- if (ArrayUtils.isEmpty(args)) {
- ServiceInstanceMetadataUtils.refreshMetadataAndInstance(serviceInstance);
- stringBuilder.append("publish metadata succeeded. App:").append(serviceInstance.getServiceName()).append("\n");
- } else {
- try {
- int delay = Integer.parseInt(args[0]);
- ExecutorRepository executorRepository = applicationModel.getExtensionLoader(ExecutorRepository.class).getDefaultExtension();
- executorRepository.nextScheduledExecutor()
- .schedule(() -> ServiceInstanceMetadataUtils.refreshMetadataAndInstance(serviceInstance), delay, TimeUnit.SECONDS);
- } catch (NumberFormatException e) {
- logger.error("Wrong delay param", e);
- return "publishMetadata failed! Wrong delay param!";
- }
- stringBuilder.append("publish task submitted, will publish in ").append(args[0]).append(" seconds. App:").append(serviceInstance.getServiceName()).append("\n");
+ if (ArrayUtils.isEmpty(args)) {
+ ServiceInstanceMetadataUtils.refreshMetadataAndInstance(applicationModel);
+ stringBuilder.append("publish metadata succeeded. App:").append(applicationModel.getApplicationName()).append("\n");
+ } else {
+ try {
+ int delay = Integer.parseInt(args[0]);
+ ExecutorRepository executorRepository = applicationModel.getExtensionLoader(ExecutorRepository.class).getDefaultExtension();
+ executorRepository.nextScheduledExecutor()
+ .schedule(() -> ServiceInstanceMetadataUtils.refreshMetadataAndInstance(applicationModel), delay, TimeUnit.SECONDS);
+ } catch (NumberFormatException e) {
+ logger.error("Wrong delay param", e);
+ return "publishMetadata failed! Wrong delay param!";
}
+ stringBuilder.append("publish task submitted, will publish in ").append(args[0]).append(" seconds. App:").append(applicationModel.getApplicationName()).append("\n");
}
}
return stringBuilder.toString();
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/RegistryScopeModelInitializer.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/RegistryScopeModelInitializer.java
index f780d0a..6be4e29 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/RegistryScopeModelInitializer.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/RegistryScopeModelInitializer.java
@@ -17,7 +17,6 @@
package org.apache.dubbo.registry;
import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
-import org.apache.dubbo.registry.client.metadata.store.RemoteMetadataServiceImpl;
import org.apache.dubbo.registry.support.RegistryManager;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.FrameworkModel;
@@ -33,7 +32,6 @@ public class RegistryScopeModelInitializer implements ScopeModelInitializer {
@Override
public void initializeApplicationModel(ApplicationModel applicationModel) {
ScopeBeanFactory beanFactory = applicationModel.getBeanFactory();
- beanFactory.registerBean(RemoteMetadataServiceImpl.class);
beanFactory.registerBean(RegistryManager.class);
}
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscovery.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscovery.java
index 0c606be..c2744e0 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscovery.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscovery.java
@@ -17,63 +17,94 @@
package org.apache.dubbo.registry.client;
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.MetadataInfo;
+import org.apache.dubbo.metadata.report.MetadataReport;
+import org.apache.dubbo.metadata.report.MetadataReportInstance;
+import org.apache.dubbo.metadata.report.identifier.SubscriberMetadataIdentifier;
+import org.apache.dubbo.registry.NotifyListener;
import org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils;
+import org.apache.dubbo.rpc.model.ApplicationModel;
+import org.apache.dubbo.rpc.model.ScopeModelAware;
-import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.isInstanceUpdated;
-import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.resetInstanceUpdateKey;
+import java.util.List;
+import java.util.Map;
-public abstract class AbstractServiceDiscovery implements ServiceDiscovery {
+import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_CLUSTER_KEY;
+import static org.apache.dubbo.metadata.RevisionResolver.EMPTY_REVISION;
+import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.EXPORTED_SERVICES_REVISION_PROPERTY_NAME;
+import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.customizeInstance;
+import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.setMetadataStorageType;
+/**
+ * Each service discovery is bond to one application.
+ */
+public abstract class AbstractServiceDiscovery implements ServiceDiscovery, ScopeModelAware {
+ private Logger logger = LoggerFactory.getLogger(AbstractServiceDiscovery.class);
private volatile boolean isDestroy;
+ private final String serviceName;
protected volatile ServiceInstance serviceInstance;
+ protected volatile MetadataInfo metadataInfo;
+ protected MetadataReport metadataReport;
+
+ private ApplicationModel applicationModel;
+
+ protected Map<String, MetadataInfo> revisionToMetadata;
+
+ public AbstractServiceDiscovery(String serviceName) {
+ this.serviceName = serviceName;
+ this.metadataInfo = new MetadataInfo(serviceName);
+ }
@Override
- public final ServiceInstance getLocalInstance() {
- return serviceInstance;
+ public void setApplicationModel(ApplicationModel applicationModel) {
+ this.applicationModel = applicationModel;
}
@Override
public final void initialize(URL registryURL) throws Exception {
doInitialize(registryURL);
+ String registryCluster = registryURL.getParameter(REGISTRY_CLUSTER_KEY);
+ metadataReport = applicationModel.getBeanFactory().getBean(MetadataReportInstance.class).getMetadataReport(registryCluster);
}
- public abstract void doInitialize(URL registryURL) throws Exception;
-
- @Override
- public final void register(ServiceInstance serviceInstance) throws RuntimeException {
- if (ServiceInstanceMetadataUtils.getExportedServicesRevision(serviceInstance) == null) {
- ServiceInstanceMetadataUtils.calInstanceRevision(this, serviceInstance);
+ public final void register() throws RuntimeException {
+ this.serviceInstance = createServiceInstance();
+ customizeInstance(this.serviceInstance);
+ boolean revisionUpdated = calOrUpdateInstanceRevision();
+ if (revisionUpdated) {
+ reportMetadata();
+ doRegister(serviceInstance);
}
- doRegister(serviceInstance);
- this.serviceInstance = serviceInstance;
}
- public abstract void doRegister(ServiceInstance serviceInstance) throws RuntimeException;
-
-
@Override
- public final void update(ServiceInstance serviceInstance) throws RuntimeException {
+ public final void update() throws RuntimeException {
if (this.serviceInstance == null) {
- this.register(serviceInstance);
- return;
+ this.serviceInstance = createServiceInstance();
}
- if (!isInstanceUpdated(serviceInstance)) {
- return;
+ boolean revisionUpdated = calOrUpdateInstanceRevision();
+ if (revisionUpdated) {
+ doUpdate();
}
- doUpdate(serviceInstance);
- resetInstanceUpdateKey(serviceInstance);
- this.serviceInstance = serviceInstance;
}
- public abstract void doUpdate(ServiceInstance serviceInstance) throws RuntimeException;
+ @Override
+ public final void unregister() throws RuntimeException {
+ doUnregister();
+ }
@Override
- public final void unregister(ServiceInstance serviceInstance) throws RuntimeException {
- doUnregister(serviceInstance);
+ public final ServiceInstance getLocalInstance() {
+ return serviceInstance;
}
- public abstract void doUnregister(ServiceInstance serviceInstance);
+ @Override
+ public MetadataInfo getMetadata() {
+ return metadataInfo;
+ }
@Override
public final void destroy() throws Exception {
@@ -81,10 +112,76 @@ public abstract class AbstractServiceDiscovery implements ServiceDiscovery {
doDestroy();
}
- public abstract void doDestroy() throws Exception;
-
@Override
public final boolean isDestroy() {
return isDestroy;
}
+
+ @Override
+ public void register(URL url) {
+ metadataInfo.addService(url);
+ }
+
+ @Override
+ public void unregister(URL url) {
+ metadataInfo.removeService(url);
+ }
+
+ @Override
+ public void subscribe(URL url, NotifyListener listener) {
+ metadataInfo.addSubscribedURL(url);
+ }
+
+ @Override
+ public void unsubscribe(URL url, NotifyListener listener) {
+ metadataInfo.removeSubscribedURL(url);
+ }
+
+ @Override
+ public List<URL> lookup(URL url) {
+ throw new UnsupportedOperationException("Service discovery implementation does not support lookup of url list.");
+ }
+
+ public void doUpdate() throws RuntimeException {
+ this.unregister();
+
+ reportMetadata();
+ this.register();
+ }
+
+ public abstract void doRegister(ServiceInstance serviceInstance) throws RuntimeException;
+
+ public abstract void doUnregister();
+
+ public abstract void doInitialize(URL registryURL) throws Exception;
+
+ public abstract void doDestroy() throws Exception;
+
+ private ServiceInstance createServiceInstance() {
+ DefaultServiceInstance instance = new DefaultServiceInstance(serviceName, applicationModel);
+ instance.setServiceMetadata(metadataInfo);
+ String metadataType = applicationModel.getApplicationConfigManager().getApplicationOrElseThrow().getMetadataType();
+ setMetadataStorageType(instance, metadataType);
+ ServiceInstanceMetadataUtils.customizeInstance(instance);
+ return instance;
+ }
+
+ protected boolean calOrUpdateInstanceRevision() {
+ String existingInstanceRevision = serviceInstance.getMetadata().get(EXPORTED_SERVICES_REVISION_PROPERTY_NAME);
+ String newRevision = metadataInfo.calAndGetRevision();
+ if (!newRevision.equals(existingInstanceRevision)) {
+ if (EMPTY_REVISION.equals(newRevision)) {
+ return false;
+ }
+ serviceInstance.getMetadata().put(EXPORTED_SERVICES_REVISION_PROPERTY_NAME, metadataInfo.calAndGetRevision());
+ return true;
+ }
+ return false;
+ }
+
+ protected void reportMetadata() {
+ SubscriberMetadataIdentifier identifier = new SubscriberMetadataIdentifier(serviceName, metadataInfo.calAndGetRevision());
+ metadataReport.publishAppMetadata(identifier, metadataInfo);
+ }
+
}
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscoveryFactory.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscoveryFactory.java
index 07e1d60..a2d74d6 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscoveryFactory.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/AbstractServiceDiscoveryFactory.java
@@ -17,6 +17,8 @@
package org.apache.dubbo.registry.client;
import org.apache.dubbo.common.URL;
+import org.apache.dubbo.rpc.model.ApplicationModel;
+import org.apache.dubbo.rpc.model.ScopeModelAware;
import java.util.Collections;
import java.util.LinkedList;
@@ -31,10 +33,16 @@ import java.util.concurrent.ConcurrentMap;
* @see ServiceDiscoveryFactory
* @since 2.7.5
*/
-public abstract class AbstractServiceDiscoveryFactory implements ServiceDiscoveryFactory {
+public abstract class AbstractServiceDiscoveryFactory implements ServiceDiscoveryFactory, ScopeModelAware {
+ protected ApplicationModel applicationModel;
private final ConcurrentMap<String, ServiceDiscovery> discoveries = new ConcurrentHashMap<>();
+ @Override
+ public void setApplicationModel(ApplicationModel applicationModel) {
+ this.applicationModel = applicationModel;
+ }
+
public List<ServiceDiscovery> getAllServiceDiscoveries() {
return Collections.unmodifiableList(new LinkedList<>(discoveries.values()));
}
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/FileSystemServiceDiscovery.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/FileSystemServiceDiscovery.java
index 1590b21..fae8f22 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/FileSystemServiceDiscovery.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/FileSystemServiceDiscovery.java
@@ -1,215 +1,214 @@
-/*
- * 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;
-
-import com.alibaba.fastjson.JSON;
-import org.apache.commons.io.FileUtils;
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.config.configcenter.ConfigChangedEvent;
-import org.apache.dubbo.common.config.configcenter.file.FileSystemDynamicConfiguration;
-import org.apache.dubbo.common.lang.ShutdownHookCallbacks;
-import org.apache.dubbo.common.logger.Logger;
-import org.apache.dubbo.common.logger.LoggerFactory;
-import org.apache.dubbo.common.utils.StringUtils;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.channels.FileChannel;
-import java.nio.channels.FileLock;
-import java.nio.file.LinkOption;
-import java.nio.file.Path;
-import java.nio.file.StandardOpenOption;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.stream.Collectors;
-
-import static com.alibaba.fastjson.JSON.toJSONString;
-import static java.lang.String.format;
-import static java.nio.channels.FileChannel.open;
-import static org.apache.dubbo.common.config.configcenter.DynamicConfiguration.DEFAULT_GROUP;
-import static org.apache.dubbo.common.config.configcenter.file.FileSystemDynamicConfiguration.CONFIG_CENTER_DIR_PARAM_NAME;
-
-/**
- * File System {@link ServiceDiscovery} implementation
- *
- * @see FileSystemDynamicConfiguration
- * @since 2.7.5
- */
-public class FileSystemServiceDiscovery extends AbstractServiceDiscovery {
-
- private final Logger logger = LoggerFactory.getLogger(getClass());
-
- private final Map<File, FileLock> fileLocksCache = new ConcurrentHashMap<>();
-
- private FileSystemDynamicConfiguration dynamicConfiguration;
-
- @Override
- public void doInitialize(URL registryURL) throws Exception {
- dynamicConfiguration = createDynamicConfiguration(registryURL);
- registerDubboShutdownHook();
- registerListener();
- }
-
- private void registerDubboShutdownHook() {
- serviceInstance.getApplicationModel().getBeanFactory().getBean(ShutdownHookCallbacks.class)
- .addCallback(this::destroy);
- }
-
- private void registerListener() {
- getServices().forEach(serviceName -> {
- dynamicConfiguration.getConfigKeys(DEFAULT_GROUP).forEach(serviceInstanceId -> {
- dynamicConfiguration.addListener(serviceInstanceId, serviceName, this::onConfigChanged);
- });
- });
- }
-
- public void onConfigChanged(ConfigChangedEvent event) {
-
- }
-
- @Override
- public void doDestroy() throws Exception {
- dynamicConfiguration.close();
- releaseAndRemoveRegistrationFiles();
- }
-
- private void releaseAndRemoveRegistrationFiles() {
- fileLocksCache.keySet().forEach(file -> {
- releaseFileLock(file);
- removeFile(file);
- });
- }
-
- private void removeFile(File file) {
- FileUtils.deleteQuietly(file);
- }
-
- private String getServiceInstanceId(ServiceInstance serviceInstance) {
- String id = serviceInstance.getAddress();
- if (StringUtils.isBlank(id)) {
- return serviceInstance.getHost() + "." + serviceInstance.getPort();
- }
- return id;
- }
-
- private String getServiceName(ServiceInstance serviceInstance) {
- return serviceInstance.getServiceName();
- }
-
- @Override
- public List<ServiceInstance> getInstances(String serviceName) {
- return dynamicConfiguration.getConfigKeys(DEFAULT_GROUP)
- .stream()
- .map(serviceInstanceId -> dynamicConfiguration.getConfig(serviceInstanceId, serviceName))
- .map(content -> JSON.parseObject(content, DefaultServiceInstance.class))
- .collect(Collectors.toList());
- }
-
- @Override
- public URL getUrl() {
- return null;
- }
-
-
- @Override
- public void doRegister(ServiceInstance serviceInstance) throws RuntimeException {
- this.serviceInstance = serviceInstance;
- String serviceInstanceId = getServiceInstanceId(serviceInstance);
- String serviceName = getServiceName(serviceInstance);
- String content = toJSONString(serviceInstance);
- if (dynamicConfiguration.publishConfig(serviceInstanceId, serviceName, content)) {
- lockFile(serviceInstanceId, serviceName);
- }
- }
-
- private void lockFile(String serviceInstanceId, String serviceName) {
- File serviceInstanceFile = serviceInstanceFile(serviceInstanceId, serviceName);
- Path serviceInstanceFilePath = serviceInstanceFile.toPath();
-
- fileLocksCache.computeIfAbsent(serviceInstanceFile, file -> {
- FileLock fileLock = null;
- try {
- FileChannel fileChannel = open(serviceInstanceFilePath, StandardOpenOption.READ, StandardOpenOption.WRITE, LinkOption.NOFOLLOW_LINKS);
- fileLock = fileChannel.tryLock();
- } catch (IOException e) {
- if (logger.isErrorEnabled()) {
- logger.error(e.getMessage(), e);
- }
- }
- if (fileLock != null) {
- if (logger.isInfoEnabled()) {
- logger.info(format("%s has been locked", serviceInstanceFilePath.toAbsolutePath()));
- }
- }
- return fileLock;
- });
- }
-
- @Override
- public void doUpdate(ServiceInstance serviceInstance) throws RuntimeException {
- register(serviceInstance);
- }
-
- @Override
- public void doUnregister(ServiceInstance serviceInstance) throws RuntimeException {
- String key = getServiceInstanceId(serviceInstance);
- String group = getServiceName(serviceInstance);
- releaseFileLock(key, group);
- dynamicConfiguration.removeConfig(key, group);
- }
-
- private void releaseFileLock(String serviceInstanceId, String serviceName) {
- File serviceInstanceFile = serviceInstanceFile(serviceInstanceId, serviceName);
- releaseFileLock(serviceInstanceFile);
- }
-
- private void releaseFileLock(File serviceInstanceFile) {
- fileLocksCache.computeIfPresent(serviceInstanceFile, (f, fileLock) -> {
- releaseFileLock(fileLock);
- if (logger.isInfoEnabled()) {
- logger.info(format("The file[%s] has been released", serviceInstanceFile.getAbsolutePath()));
- }
- return null;
- });
- }
-
- private void releaseFileLock(FileLock fileLock) {
- try (FileChannel fileChannel = fileLock.channel()) {
- fileLock.release();
- } catch (IOException e) {
- if (logger.isErrorEnabled()) {
- logger.error(e.getMessage(), e);
- }
- }
- }
-
- private File serviceInstanceFile(String serviceInstanceId, String serviceName) {
- return dynamicConfiguration.configFile(serviceInstanceId, serviceName);
- }
-
- @Override
- public Set<String> getServices() {
- return dynamicConfiguration.getConfigGroups();
- }
-
- private static FileSystemDynamicConfiguration createDynamicConfiguration(URL connectionURL) {
- String path = System.getProperty("user.home") + File.separator + ".dubbo" + File.separator + "registry";
- return new FileSystemDynamicConfiguration(connectionURL.addParameter(CONFIG_CENTER_DIR_PARAM_NAME, path));
- }
-}
+///*
+// * 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;
+//
+//import com.alibaba.fastjson.JSON;
+//import org.apache.commons.io.FileUtils;
+//import org.apache.dubbo.common.URL;
+//import org.apache.dubbo.common.config.configcenter.ConfigChangedEvent;
+//import org.apache.dubbo.common.config.configcenter.file.FileSystemDynamicConfiguration;
+//import org.apache.dubbo.common.lang.ShutdownHookCallbacks;
+//import org.apache.dubbo.common.logger.Logger;
+//import org.apache.dubbo.common.logger.LoggerFactory;
+//import org.apache.dubbo.common.utils.StringUtils;
+//
+//import java.io.File;
+//import java.io.IOException;
+//import java.nio.channels.FileChannel;
+//import java.nio.channels.FileLock;
+//import java.nio.file.LinkOption;
+//import java.nio.file.Path;
+//import java.nio.file.StandardOpenOption;
+//import java.util.List;
+//import java.util.Map;
+//import java.util.Set;
+//import java.util.concurrent.ConcurrentHashMap;
+//import java.util.stream.Collectors;
+//
+//import static com.alibaba.fastjson.JSON.toJSONString;
+//import static java.lang.String.format;
+//import static java.nio.channels.FileChannel.open;
+//import static org.apache.dubbo.common.config.configcenter.DynamicConfiguration.DEFAULT_GROUP;
+//import static org.apache.dubbo.common.config.configcenter.file.FileSystemDynamicConfiguration.CONFIG_CENTER_DIR_PARAM_NAME;
+//
+///**
+// * File System {@link ServiceDiscovery} implementation
+// *
+// * @see FileSystemDynamicConfiguration
+// * @since 2.7.5
+// */
+//public class FileSystemServiceDiscovery extends AbstractServiceDiscovery {
+//
+// private final Logger logger = LoggerFactory.getLogger(getClass());
+//
+// private final Map<File, FileLock> fileLocksCache = new ConcurrentHashMap<>();
+//
+// private FileSystemDynamicConfiguration dynamicConfiguration;
+//
+// public FileSystemServiceDiscovery(String serviceName) {
+// super(serviceName);
+// }
+//
+// @Override
+// public void doInitialize(URL registryURL) throws Exception {
+// dynamicConfiguration = createDynamicConfiguration(registryURL);
+// registerDubboShutdownHook();
+// registerListener();
+// }
+//
+// private void registerDubboShutdownHook() {
+// serviceInstance.getApplicationModel().getBeanFactory().getBean(ShutdownHookCallbacks.class)
+// .addCallback(this::destroy);
+// }
+//
+// private void registerListener() {
+// getServices().forEach(serviceName -> {
+// dynamicConfiguration.getConfigKeys(DEFAULT_GROUP).forEach(serviceInstanceId -> {
+// dynamicConfiguration.addListener(serviceInstanceId, serviceName, this::onConfigChanged);
+// });
+// });
+// }
+//
+// public void onConfigChanged(ConfigChangedEvent event) {
+//
+// }
+//
+// @Override
+// public void doDestroy() throws Exception {
+// dynamicConfiguration.close();
+// releaseAndRemoveRegistrationFiles();
+// }
+//
+// private void releaseAndRemoveRegistrationFiles() {
+// fileLocksCache.keySet().forEach(file -> {
+// releaseFileLock(file);
+// removeFile(file);
+// });
+// }
+//
+// private void removeFile(File file) {
+// FileUtils.deleteQuietly(file);
+// }
+//
+// private String getServiceInstanceId(ServiceInstance serviceInstance) {
+// String id = serviceInstance.getAddress();
+// if (StringUtils.isBlank(id)) {
+// return serviceInstance.getHost() + "." + serviceInstance.getPort();
+// }
+// return id;
+// }
+//
+// private String getServiceName(ServiceInstance serviceInstance) {
+// return serviceInstance.getServiceName();
+// }
+//
+// @Override
+// public List<ServiceInstance> getInstances(String serviceName) {
+// return dynamicConfiguration.getConfigKeys(DEFAULT_GROUP)
+// .stream()
+// .map(serviceInstanceId -> dynamicConfiguration.getConfig(serviceInstanceId, serviceName))
+// .map(content -> JSON.parseObject(content, DefaultServiceInstance.class))
+// .collect(Collectors.toList());
+// }
+//
+// @Override
+// public URL getUrl() {
+// return null;
+// }
+//
+//
+// @Override
+// public void doRegister(ServiceInstance serviceInstance) throws RuntimeException {
+// this.serviceInstance = serviceInstance;
+// String serviceInstanceId = getServiceInstanceId(serviceInstance);
+// String serviceName = getServiceName(serviceInstance);
+// String content = toJSONString(serviceInstance);
+// if (dynamicConfiguration.publishConfig(serviceInstanceId, serviceName, content)) {
+// lockFile(serviceInstanceId, serviceName);
+// }
+// }
+//
+// private void lockFile(String serviceInstanceId, String serviceName) {
+// File serviceInstanceFile = serviceInstanceFile(serviceInstanceId, serviceName);
+// Path serviceInstanceFilePath = serviceInstanceFile.toPath();
+//
+// fileLocksCache.computeIfAbsent(serviceInstanceFile, file -> {
+// FileLock fileLock = null;
+// try {
+// FileChannel fileChannel = open(serviceInstanceFilePath, StandardOpenOption.READ, StandardOpenOption.WRITE, LinkOption.NOFOLLOW_LINKS);
+// fileLock = fileChannel.tryLock();
+// } catch (IOException e) {
+// if (logger.isErrorEnabled()) {
+// logger.error(e.getMessage(), e);
+// }
+// }
+// if (fileLock != null) {
+// if (logger.isInfoEnabled()) {
+// logger.info(format("%s has been locked", serviceInstanceFilePath.toAbsolutePath()));
+// }
+// }
+// return fileLock;
+// });
+// }
+//
+// @Override
+// public void doUnregister() throws RuntimeException {
+// String key = getServiceInstanceId(serviceInstance);
+// String group = getServiceName(serviceInstance);
+// releaseFileLock(key, group);
+// dynamicConfiguration.removeConfig(key, group);
+// }
+//
+// private void releaseFileLock(String serviceInstanceId, String serviceName) {
+// File serviceInstanceFile = serviceInstanceFile(serviceInstanceId, serviceName);
+// releaseFileLock(serviceInstanceFile);
+// }
+//
+// private void releaseFileLock(File serviceInstanceFile) {
+// fileLocksCache.computeIfPresent(serviceInstanceFile, (f, fileLock) -> {
+// releaseFileLock(fileLock);
+// if (logger.isInfoEnabled()) {
+// logger.info(format("The file[%s] has been released", serviceInstanceFile.getAbsolutePath()));
+// }
+// return null;
+// });
+// }
+//
+// private void releaseFileLock(FileLock fileLock) {
+// try (FileChannel fileChannel = fileLock.channel()) {
+// fileLock.release();
+// } catch (IOException e) {
+// if (logger.isErrorEnabled()) {
+// logger.error(e.getMessage(), e);
+// }
+// }
+// }
+//
+// private File serviceInstanceFile(String serviceInstanceId, String serviceName) {
+// return dynamicConfiguration.configFile(serviceInstanceId, serviceName);
+// }
+//
+// @Override
+// public Set<String> getServices() {
+// return dynamicConfiguration.getConfigGroups();
+// }
+//
+// private static FileSystemDynamicConfiguration createDynamicConfiguration(URL connectionURL) {
+// String path = System.getProperty("user.home") + File.separator + ".dubbo" + File.separator + "registry";
+// return new FileSystemDynamicConfiguration(connectionURL.addParameter(CONFIG_CENTER_DIR_PARAM_NAME, path));
+// }
+//}
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/SelfHostMetaServiceDiscovery.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/SelfHostMetaServiceDiscovery.java
deleted file mode 100644
index 30fc1d8..0000000
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/SelfHostMetaServiceDiscovery.java
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * 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;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.constants.CommonConstants;
-import org.apache.dubbo.common.logger.Logger;
-import org.apache.dubbo.common.logger.LoggerFactory;
-import org.apache.dubbo.common.utils.NamedThreadFactory;
-import org.apache.dubbo.common.utils.NetUtils;
-import org.apache.dubbo.common.utils.StringUtils;
-import org.apache.dubbo.metadata.InstanceMetadataChangedListener;
-import org.apache.dubbo.metadata.MetadataService;
-import org.apache.dubbo.metadata.RevisionResolver;
-import org.apache.dubbo.metadata.WritableMetadataService;
-import org.apache.dubbo.registry.Constants;
-import org.apache.dubbo.registry.client.event.ServiceInstancesChangedEvent;
-import org.apache.dubbo.registry.client.event.listener.ServiceInstancesChangedListener;
-import org.apache.dubbo.registry.client.metadata.MetadataUtils;
-import org.apache.dubbo.rpc.RpcException;
-import org.apache.dubbo.rpc.model.ApplicationModel;
-import org.apache.dubbo.rpc.model.ScopeModelAware;
-import org.apache.dubbo.rpc.model.ScopeModelUtil;
-
-import com.alibaba.fastjson.JSONObject;
-
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-public abstract class SelfHostMetaServiceDiscovery implements ServiceDiscovery, ScopeModelAware {
-
- private volatile boolean isDestroy;
-
- private final Logger logger = LoggerFactory.getLogger(getClass());
-
- private URL registryURL;
-
- /**
- * Echo check if consumer is still work
- * echo task may take a lot of time when consumer offline, create a new ScheduledThreadPool
- */
- private final ScheduledExecutorService echoCheckExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("Dubbo-Registry-EchoCheck-Consumer"));
-
- // =================================== Provider side =================================== //
-
- private ServiceInstance serviceInstance;
-
- /**
- * Local {@link ServiceInstance} Metadata's revision
- */
- private String lastMetadataRevision;
-
- // =================================== Consumer side =================================== //
-
- /**
- * Local Cache of {@link ServiceInstance} Metadata
- * <p>
- * Key - {@link ServiceInstance} ID ( usually ip + port )
- * Value - Json processed metadata string
- */
- private final ConcurrentHashMap<String, String> metadataMap = new ConcurrentHashMap<>();
-
- /**
- * Local Cache of {@link ServiceInstance}
- * <p>
- * Key - Service Name
- * Value - List {@link ServiceInstance}
- */
- private final ConcurrentHashMap<String, List<ServiceInstance>> cachedServiceInstances = new ConcurrentHashMap<>();
-
- /**
- * Local Cache of Service's {@link ServiceInstance} list revision,
- * used to check if {@link ServiceInstance} list has been updated
- * <p>
- * Key - ServiceName
- * Value - a revision calculate from {@link List} of {@link ServiceInstance}
- */
- private final ConcurrentHashMap<String, String> serviceInstanceRevisionMap = new ConcurrentHashMap<>();
- private ApplicationModel applicationModel;
- private WritableMetadataService metadataService;
-
- @Override
- public void setApplicationModel(ApplicationModel applicationModel) {
- this.applicationModel = applicationModel;
- metadataService = WritableMetadataService.getDefaultExtension(applicationModel);
-
- }
-
- @Override
- public void initialize(URL registryURL) throws Exception {
- this.registryURL = registryURL;
- doInitialize(registryURL);
- long echoPollingCycle = registryURL.getParameter(Constants.ECHO_POLLING_CYCLE_KEY, Constants.DEFAULT_ECHO_POLLING_CYCLE);
-
- // Echo check: test if consumer is offline, remove MetadataChangeListener,
- // reduce the probability of failure when metadata update
- echoCheckExecutor.scheduleAtFixedRate(() -> {
- Map<String, InstanceMetadataChangedListener> listenerMap = metadataService.getInstanceMetadataChangedListenerMap();
- Iterator<Map.Entry<String, InstanceMetadataChangedListener>> iterator = listenerMap.entrySet().iterator();
-
- while (iterator.hasNext()) {
- Map.Entry<String, InstanceMetadataChangedListener> entry = iterator.next();
- try {
- entry.getValue().echo(CommonConstants.DUBBO);
- } catch (RpcException e) {
- if (logger.isInfoEnabled()) {
- logger.info("Send echo message to consumer error. Possible cause: consumer is offline.");
- }
- iterator.remove();
- }
- }
- }, echoPollingCycle, echoPollingCycle, TimeUnit.MILLISECONDS);
- }
-
- @Override
- public void destroy() throws Exception {
- isDestroy = true;
- doDestroy();
- metadataMap.clear();
- serviceInstanceRevisionMap.clear();
- echoCheckExecutor.shutdown();
- }
-
- @Override
- public boolean isDestroy() {
- return isDestroy;
- }
-
- private void updateMetadata(ServiceInstance serviceInstance) {
- String metadataString = JSONObject.toJSONString(serviceInstance.getMetadata());
- String metadataRevision = RevisionResolver.calRevision(metadataString);
-
- // check if metadata updated
- if (!metadataRevision.equalsIgnoreCase(lastMetadataRevision)) {
- if (logger.isDebugEnabled()) {
- logger.debug("Update Service Instance Metadata of DNS registry. Newer metadata: " + metadataString);
- }
-
- lastMetadataRevision = metadataRevision;
-
- // save newest metadata to local
- metadataService.exportInstanceMetadata(metadataString);
-
- // notify to consumer
- Map<String, InstanceMetadataChangedListener> listenerMap = metadataService.getInstanceMetadataChangedListenerMap();
- Iterator<Map.Entry<String, InstanceMetadataChangedListener>> iterator = listenerMap.entrySet().iterator();
-
- while (iterator.hasNext()) {
- Map.Entry<String, InstanceMetadataChangedListener> entry = iterator.next();
- try {
- entry.getValue().onEvent(metadataString);
- } catch (RpcException e) {
- logger.warn("Notify to consumer error. Possible cause: consumer is offline.");
- // remove listener if consumer is offline
- iterator.remove();
- }
- }
- }
- }
-
- @Override
- public void register(ServiceInstance serviceInstance) throws RuntimeException {
- this.serviceInstance = serviceInstance;
-
- updateMetadata(serviceInstance);
-
- doRegister(serviceInstance);
- }
-
- @Override
- public void update(ServiceInstance serviceInstance) throws RuntimeException {
- this.serviceInstance = serviceInstance;
-
- updateMetadata(serviceInstance);
-
- doUpdate(serviceInstance);
- }
-
- @Override
- public void unregister(ServiceInstance serviceInstance) throws RuntimeException {
- doUnregister(serviceInstance);
-
- this.serviceInstance = null;
-
- // notify empty message to consumer
- metadataService.exportInstanceMetadata("");
- metadataService.getInstanceMetadataChangedListenerMap().forEach((consumerId, listener) -> listener.onEvent(""));
- metadataService.getInstanceMetadataChangedListenerMap().clear();
- }
-
- @Override
- public ServiceInstance getLocalInstance() {
- return serviceInstance;
- }
-
- @Override
- public URL getUrl() {
- return registryURL;
- }
-
- @SuppressWarnings("unchecked")
- public final void fillServiceInstance(DefaultServiceInstance serviceInstance) {
- String hostId = serviceInstance.getAddress();
- if (metadataMap.containsKey(hostId)) {
- // Use cached metadata.
- // Metadata will be updated by provider callback
-
- String metadataString = metadataMap.get(hostId);
- serviceInstance.setMetadata(JSONObject.parseObject(metadataString, Map.class));
- } else {
- // refer from MetadataUtils, this proxy is different from the one used to refer exportedURL
- MetadataService metadataService = MetadataUtils.getMetadataServiceProxy(serviceInstance);
-
- String consumerId = ScopeModelUtil.getApplicationModel(registryURL.getScopeModel()).getApplicationName() + NetUtils.getLocalHost();
- String metadata = metadataService.getAndListenInstanceMetadata(
- consumerId, metadataString -> {
- if(logger.isDebugEnabled()) {
- logger.debug("Receive callback: " + metadataString + serviceInstance);
- }
- if (StringUtils.isEmpty(metadataString)) {
- // provider is shutdown
- metadataMap.remove(hostId);
- } else {
- metadataMap.put(hostId, metadataString);
- }
- });
- metadataMap.put(hostId, metadata);
- serviceInstance.setMetadata(JSONObject.parseObject(metadata, Map.class));
- }
- }
-
- public final void notifyListener(String serviceName, ServiceInstancesChangedListener listener, List<ServiceInstance> instances) {
- String serviceInstanceRevision = RevisionResolver.calRevision(JSONObject.toJSONString(instances));
- boolean changed = !serviceInstanceRevision.equalsIgnoreCase(
- serviceInstanceRevisionMap.put(serviceName, serviceInstanceRevision));
-
- if (logger.isDebugEnabled()) {
- logger.debug("Service changed event received (possibly because of DNS polling). " +
- "Service Instance changed: " + changed + " Service Name: " + serviceName);
- }
-
- if (changed) {
- List<ServiceInstance> oldServiceInstances = cachedServiceInstances.getOrDefault(serviceName, new LinkedList<>());
-
- // remove expired invoker
- Set<ServiceInstance> allServiceInstances = new HashSet<>(oldServiceInstances.size() + instances.size());
- allServiceInstances.addAll(oldServiceInstances);
- allServiceInstances.addAll(instances);
-
- allServiceInstances.removeAll(oldServiceInstances);
-
- allServiceInstances.forEach(removedServiceInstance -> {
- MetadataUtils.destroyMetadataServiceProxy(removedServiceInstance);
- });
-
- cachedServiceInstances.put(serviceName, instances);
- listener.onEvent(new ServiceInstancesChangedEvent(serviceName, instances));
- }
- }
-
- public void doInitialize(URL registryURL) throws Exception {
- }
-
- public void doDestroy() throws Exception {
- }
-
- public void doRegister(ServiceInstance serviceInstance) throws RuntimeException {
-
- }
-
- public void doUpdate(ServiceInstance serviceInstance) throws RuntimeException {
-
- }
-
- public void doUnregister(ServiceInstance serviceInstance) throws RuntimeException {
-
- }
-
- /**
- * UT used only
- */
- @Deprecated
- public final ConcurrentHashMap<String, List<ServiceInstance>> getCachedServiceInstances() {
- return cachedServiceInstances;
- }
-}
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscovery.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscovery.java
index 5f2533d..5652e19 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscovery.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscovery.java
@@ -20,9 +20,8 @@ import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.SPI;
import org.apache.dubbo.common.lang.Prioritized;
import org.apache.dubbo.common.utils.Page;
-import org.apache.dubbo.common.utils.StringUtils;
-import org.apache.dubbo.registry.NotifyListener;
-import org.apache.dubbo.registry.client.event.ServiceInstancesChangedEvent;
+import org.apache.dubbo.metadata.MetadataInfo;
+import org.apache.dubbo.registry.RegistryService;
import org.apache.dubbo.registry.client.event.listener.ServiceInstancesChangedListener;
import java.util.LinkedHashMap;
@@ -30,7 +29,6 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.stream.Stream;
import static java.util.Collections.unmodifiableList;
import static java.util.Collections.unmodifiableMap;
@@ -43,10 +41,7 @@ import static org.apache.dubbo.common.extension.ExtensionScope.APPLICATION;
* @since 2.7.5
*/
@SPI(value = "zookeeper", scope = APPLICATION)
-public interface ServiceDiscovery extends Prioritized {
-
- // ==================================== Lifecycle ==================================== //
-
+public interface ServiceDiscovery extends RegistryService, Prioritized {
/**
* Initializes the {@link ServiceDiscovery}
*
@@ -64,37 +59,12 @@ public interface ServiceDiscovery extends Prioritized {
boolean isDestroy();
- // ==================================================================================== //
- // =================================== Registration =================================== //
+ void register() throws RuntimeException;
- /**
- * Registers an instance of {@link ServiceInstance}.
- *
- * @param serviceInstance an instance of {@link ServiceInstance} to be registered
- * @throws RuntimeException if failed
- */
- void register(ServiceInstance serviceInstance) throws RuntimeException;
+ void update() throws RuntimeException;
- /**
- * Updates the registered {@link ServiceInstance}.
- *
- * @param serviceInstance the registered {@link ServiceInstance}
- * @throws RuntimeException if failed
- */
- void update(ServiceInstance serviceInstance) throws RuntimeException;
-
- /**
- * Unregisters an instance of {@link ServiceInstance}.
- *
- * @param serviceInstance an instance of {@link ServiceInstance} to be unregistered
- * @throws RuntimeException if failed
- */
- void unregister(ServiceInstance serviceInstance) throws RuntimeException;
-
- // ==================================================================================== //
-
- // ==================================== Discovery ===================================== //
+ void unregister() throws RuntimeException;
/**
* Get the default size of pagination query
@@ -196,44 +166,12 @@ public interface ServiceDiscovery extends Prioritized {
return unmodifiableMap(instances);
}
- default void dispatchServiceInstancesChangedEvent(String serviceName) {
- dispatchServiceInstancesChangedEvent(serviceName, getInstances(serviceName));
- }
-
- default void dispatchServiceInstancesChangedEvent(String serviceName, String... otherServiceNames) {
- dispatchServiceInstancesChangedEvent(serviceName, getInstances(serviceName));
- if (otherServiceNames != null) {
- Stream.of(otherServiceNames)
- .filter(StringUtils::isNotEmpty)
- .forEach(this::dispatchServiceInstancesChangedEvent);
- }
- }
-
- default void dispatchServiceInstancesChangedEvent(String serviceName, List<ServiceInstance> serviceInstances) {
- dispatchServiceInstancesChangedEvent(new ServiceInstancesChangedEvent(serviceName, serviceInstances));
- }
-
- default void dispatchServiceInstancesChangedEvent(ServiceInstancesChangedEvent event) {}
-
- /**
- * Add an instance of {@link ServiceInstancesChangedListener} for specified service
- * <p>
- * Default, Current method will be invoked by {@link ServiceDiscoveryRegistry#subscribe(URL, NotifyListener)
- * the ServiceDiscoveryRegistry on the subscription}, this method is used to
- * trigger or adapt the vendor's change notification mechanism typically, like Zookeeper Watcher,
- * Nacos EventListener. If the registry observes the change, It's suggested that the implementation could invoke
- * {@link #dispatchServiceInstancesChangedEvent(String)} method or variants
- *
- * @param listener an instance of {@link ServiceInstancesChangedListener}
- * @throws NullPointerException
- * @throws IllegalArgumentException
- */
default void addServiceInstancesChangedListener(ServiceInstancesChangedListener listener)
throws NullPointerException, IllegalArgumentException {
}
/**
- * unsubscribe to instances change event.
+ * unsubscribe to instance change event.
*
* @param listener
* @throws IllegalArgumentException
@@ -246,16 +184,14 @@ public interface ServiceDiscovery extends Prioritized {
return new ServiceInstancesChangedListener(serviceNames, this);
}
- // ==================================================================================== //
+ ServiceInstance getLocalInstance();
-// String getKey(URL exportedURL);
+ MetadataInfo getMetadata();
default URL getUrl() {
return null;
}
- ServiceInstance getLocalInstance();
-
default long getDelay() {
return getUrl().getParameter(REGISTRY_DELAY_NOTIFICATION_KEY, 5000);
}
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryFactory.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryFactory.java
index f94cce2..2168095 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryFactory.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryFactory.java
@@ -20,13 +20,15 @@ import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.ExtensionLoader;
import org.apache.dubbo.common.extension.SPI;
+import static org.apache.dubbo.common.extension.ExtensionScope.APPLICATION;
+
/**
* The factory to create {@link ServiceDiscovery}
*
* @see ServiceDiscovery
* @since 2.7.5
*/
-@SPI("default")
+@SPI(value = "default", scope = APPLICATION)
public interface ServiceDiscoveryFactory {
/**
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistry.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistry.java
index 079653c..320577b 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistry.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/ServiceDiscoveryRegistry.java
@@ -18,13 +18,13 @@ package org.apache.dubbo.registry.client;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.ExtensionLoader;
+import org.apache.dubbo.common.function.ThrowableAction;
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.metadata.MappingChangedEvent;
import org.apache.dubbo.metadata.MappingListener;
import org.apache.dubbo.metadata.ServiceNameMapping;
-import org.apache.dubbo.metadata.WritableMetadataService;
import org.apache.dubbo.registry.NotifyListener;
import org.apache.dubbo.registry.client.event.ServiceInstancesChangedEvent;
import org.apache.dubbo.registry.client.event.listener.ServiceInstancesChangedListener;
@@ -41,7 +41,6 @@ import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.ConcurrentHashMap;
-import static java.lang.String.format;
import static org.apache.dubbo.common.constants.CommonConstants.CHECK_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.DUBBO;
import static org.apache.dubbo.common.constants.CommonConstants.GROUP_CHAR_SEPARATOR;
@@ -56,6 +55,8 @@ import static org.apache.dubbo.metadata.ServiceNameMapping.toStringKeys;
import static org.apache.dubbo.registry.client.ServiceDiscoveryFactory.getExtension;
/**
+ * TODO, this bridge implementation is not necessary now, protocol can interact with service discovery directly.
+ *
* ServiceDiscoveryRegistry is a very special Registry implementation, which is used to bridge the old interface-level service discovery model
* with the new service discovery model introduced in 3.0 in a compatible manner.
* <p>
@@ -74,7 +75,7 @@ public class ServiceDiscoveryRegistry extends FailbackRegistry {
private final ServiceDiscovery serviceDiscovery;
- private final WritableMetadataService writableMetadataService;
+ private final ServiceNameMapping serviceNameMapping;
/* apps - listener */
private final Map<String, ServiceInstancesChangedListener> serviceListeners = new ConcurrentHashMap<>();
@@ -84,15 +85,15 @@ public class ServiceDiscoveryRegistry extends FailbackRegistry {
public ServiceDiscoveryRegistry(URL registryURL) {
super(registryURL);
this.serviceDiscovery = createServiceDiscovery(registryURL);
- this.writableMetadataService = WritableMetadataService.getDefaultExtension(registryURL.getScopeModel());
+ this.serviceNameMapping = ServiceNameMapping.getDefaultExtension(registryURL.getScopeModel());
this.registryManager = registryURL.getOrDefaultApplicationModel().getBeanFactory().getBean(RegistryManager.class);
}
// Currently, for test purpose
- protected ServiceDiscoveryRegistry(URL registryURL, ServiceDiscovery serviceDiscovery, WritableMetadataService writableMetadataService) {
+ protected ServiceDiscoveryRegistry(URL registryURL, ServiceDiscovery serviceDiscovery, ServiceNameMapping serviceNameMapping) {
super(registryURL);
this.serviceDiscovery = serviceDiscovery;
- this.writableMetadataService = writableMetadataService;
+ this.serviceNameMapping = serviceNameMapping;
}
public ServiceDiscovery getServiceDiscovery() {
@@ -107,8 +108,9 @@ public class ServiceDiscoveryRegistry extends FailbackRegistry {
*/
protected ServiceDiscovery createServiceDiscovery(URL registryURL) {
ServiceDiscovery serviceDiscovery = getServiceDiscovery(registryURL);
- execute(() -> serviceDiscovery.initialize(registryURL.addParameter(INTERFACE_KEY, ServiceDiscovery.class.getName())
- .removeParameter(REGISTRY_TYPE_KEY)));
+ final ThrowableAction throwableAction = () -> serviceDiscovery.initialize(registryURL.addParameter(INTERFACE_KEY, ServiceDiscovery.class.getName())
+ .removeParameter(REGISTRY_TYPE_KEY));
+ execute(throwableAction);
return serviceDiscovery;
}
@@ -163,16 +165,9 @@ public class ServiceDiscoveryRegistry extends FailbackRegistry {
@Override
public void doRegister(URL url) {
+ // fixme, add registry-cluster is not necessary anymore
url = addRegistryClusterKey(url);
- if (writableMetadataService.exportURL(url)) {
- if (logger.isInfoEnabled()) {
- logger.info(format("The URL[%s] registered successfully.", url.toString()));
- }
- } else {
- if (logger.isWarnEnabled()) {
- logger.warn(format("The URL[%s] has been registered.", url.toString()));
- }
- }
+ serviceDiscovery.register(url);
}
@Override
@@ -185,16 +180,9 @@ public class ServiceDiscoveryRegistry extends FailbackRegistry {
@Override
public void doUnregister(URL url) {
+ // fixme, add registry-cluster is not necessary anymore
url = addRegistryClusterKey(url);
- if (writableMetadataService.unexportURL(url)) {
- if (logger.isInfoEnabled()) {
- logger.info(format("The URL[%s] deregistered successfully.", url.toString()));
- }
- } else {
- if (logger.isWarnEnabled()) {
- logger.warn(format("The URL[%s] has been deregistered.", url.toString()));
- }
- }
+ serviceDiscovery.unregister(url);
}
@Override
@@ -202,20 +190,21 @@ public class ServiceDiscoveryRegistry extends FailbackRegistry {
if (!shouldSubscribe(url)) { // Should Not Subscribe
return;
}
- url = addRegistryClusterKey(url);
doSubscribe(url, listener);
}
@Override
public void doSubscribe(URL url, NotifyListener listener) {
- writableMetadataService.subscribeURL(url);
+ url = addRegistryClusterKey(url);
+
+ serviceDiscovery.subscribe(url, listener);
boolean check = url.getParameter(CHECK_KEY, false);
Set<String> subscribedServices = Collections.emptySet();
try {
ServiceNameMapping serviceNameMapping = ServiceNameMapping.getDefaultExtension(this.getUrl().getScopeModel());
- subscribedServices = serviceNameMapping.getAndListenServices(this.getUrl(), url, new DefaultMappingListener(url, subscribedServices, listener));
+ subscribedServices = serviceNameMapping.getAndListen(this.getUrl(), url, new DefaultMappingListener(url, subscribedServices, listener));
} catch (Exception e) {
logger.warn("Cannot find app mapping for service " + url.getServiceInterface() + ", will not migrate.", e);
}
@@ -250,9 +239,10 @@ public class ServiceDiscoveryRegistry extends FailbackRegistry {
@Override
public void doUnsubscribe(URL url, NotifyListener listener) {
// TODO: remove service name mapping listener
- writableMetadataService.unsubscribeURL(url);
+ serviceDiscovery.unsubscribe(url, listener);
String protocolServiceKey = url.getServiceKey() + GROUP_CHAR_SEPARATOR + url.getParameter(PROTOCOL_KEY, DUBBO);
- Set<String> serviceNames = writableMetadataService.getCachedMapping(url);
+ Set<String> serviceNames = serviceNameMapping.getCachedMapping(url);
+ serviceNameMapping.stopListen(url);
if (CollectionUtils.isNotEmpty(serviceNames)) {
String serviceNamesKey = toStringKeys(serviceNames);
ServiceInstancesChangedListener instancesChangedListener = serviceListeners.get(serviceNamesKey);
@@ -359,6 +349,7 @@ public class ServiceDiscoveryRegistry extends FailbackRegistry {
private URL url;
private Set<String> oldApps;
private NotifyListener listener;
+ private boolean stopped;
public DefaultMappingListener(URL subscribedURL, Set<String> serviceNames, NotifyListener listener) {
this.url = subscribedURL;
@@ -371,6 +362,10 @@ public class ServiceDiscoveryRegistry extends FailbackRegistry {
if (logger.isDebugEnabled()) {
logger.debug("Received mapping notification from meta server, " + event);
}
+ if (stopped) {
+ logger.warn("Listener has been stopped, ignore mapping notification, check why listener is not removed.");
+ return;
+ }
Set<String> newApps = event.getApps();
Set<String> tempOldApps = oldApps;
oldApps = newApps;
@@ -380,18 +375,24 @@ public class ServiceDiscoveryRegistry extends FailbackRegistry {
}
if (CollectionUtils.isEmpty(tempOldApps) && newApps.size() > 0) {
- writableMetadataService.putCachedMapping(ServiceNameMapping.buildMappingKey(url), newApps);
+ serviceNameMapping.putCachedMapping(ServiceNameMapping.buildMappingKey(url), newApps);
subscribeURLs(url, listener, newApps);
return;
}
for (String newAppName : newApps) {
if (!tempOldApps.contains(newAppName)) {
- writableMetadataService.putCachedMapping(ServiceNameMapping.buildMappingKey(url), newApps);
+ serviceNameMapping.removeCachedMapping(ServiceNameMapping.buildMappingKey(url));
+ serviceNameMapping.putCachedMapping(ServiceNameMapping.buildMappingKey(url), newApps);
subscribeURLs(url, listener, newApps);
return;
}
}
}
+
+ @Override
+ public void stop() {
+ stopped = true;
+ }
}
}
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/event/listener/ServiceInstancesChangedListener.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/event/listener/ServiceInstancesChangedListener.java
index faf8578..0b28109 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/event/listener/ServiceInstancesChangedListener.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/event/listener/ServiceInstancesChangedListener.java
@@ -24,17 +24,13 @@ import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.common.utils.ConcurrentHashSet;
import org.apache.dubbo.metadata.MetadataInfo;
import org.apache.dubbo.metadata.MetadataInfo.ServiceInfo;
-import org.apache.dubbo.metadata.MetadataService;
import org.apache.dubbo.registry.NotifyListener;
import org.apache.dubbo.registry.client.DefaultServiceInstance;
-import org.apache.dubbo.registry.client.RegistryClusterIdentifier;
import org.apache.dubbo.registry.client.ServiceDiscovery;
import org.apache.dubbo.registry.client.ServiceInstance;
import org.apache.dubbo.registry.client.event.RetryServiceInstancesChangedEvent;
import org.apache.dubbo.registry.client.event.ServiceInstancesChangedEvent;
-import org.apache.dubbo.registry.client.metadata.MetadataUtils;
import org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils;
-import org.apache.dubbo.registry.client.metadata.store.RemoteMetadataServiceImpl;
import org.apache.dubbo.rpc.model.ScopeModelUtil;
import java.util.ArrayList;
@@ -52,18 +48,13 @@ import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.Semaphore;
import java.util.concurrent.ThreadLocalRandom;
-import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
-import static org.apache.dubbo.common.constants.CommonConstants.REMOTE_METADATA_STORAGE_TYPE;
import static org.apache.dubbo.metadata.RevisionResolver.EMPTY_REVISION;
import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.getExportedServicesRevision;
/**
- * The Service Discovery Changed Listener
- *
- * @see ServiceInstancesChangedEvent
- * @since 2.7.5
+ * TODO, refactor to move revision-metadata mapping to ServiceDiscovery. Instances should already being mapped with metadata when reached here.
*/
public class ServiceInstancesChangedListener {
@@ -79,7 +70,6 @@ public class ServiceInstancesChangedListener {
protected Map<String, List<ServiceInstance>> allInstances;
protected Map<String, Object> serviceUrls;
- protected Map<String, MetadataInfo> revisionToMetadata;
private volatile long lastRefreshTime;
private Semaphore retryPermission;
@@ -93,7 +83,6 @@ public class ServiceInstancesChangedListener {
this.listenerQueue = new ConcurrentLinkedQueue<>();
this.allInstances = new HashMap<>();
this.serviceUrls = new HashMap<>();
- this.revisionToMetadata = new HashMap<>();
retryPermission = new Semaphore(1);
this.scheduler = ScopeModelUtil.getApplicationModel(serviceDiscovery == null || serviceDiscovery.getUrl() == null ? null : serviceDiscovery.getUrl().getScopeModel())
.getExtensionLoader(ExecutorRepository.class).getDefaultExtension().getMetadataRetryExecutor();
@@ -105,7 +94,7 @@ public class ServiceInstancesChangedListener {
* @param event {@link ServiceInstancesChangedEvent}
*/
public synchronized void onEvent(ServiceInstancesChangedEvent event) {
- if (destroyed.get() || !accept(event) || isRetryAndExpired(event)) {
+ if (destroyed.get() || !accept(event)) {
return;
}
@@ -138,32 +127,12 @@ public class ServiceInstancesChangedListener {
// get MetadataInfo with revision
for (Map.Entry<String, List<ServiceInstance>> entry : revisionToInstances.entrySet()) {
String revision = entry.getKey();
- List<ServiceInstance> subInstances = entry.getValue();
- ServiceInstance instance = selectInstance(subInstances);
- MetadataInfo metadata = getRemoteMetadata(revision, localServiceToRevisions, instance);
- // update metadata into each instance, in case new instance created.
- for (ServiceInstance tmpInstance : subInstances) {
- ((DefaultServiceInstance) tmpInstance).setServiceMetadata(metadata);
- }
-// ((DefaultServiceInstance) instance).setServiceMetadata(metadata);
- newRevisionToMetadata.putIfAbsent(revision, metadata);
- }
-
- if (logger.isDebugEnabled()) {
- logger.debug(newRevisionToMetadata.size() + " unique revisions: " + newRevisionToMetadata.keySet());
- }
-
- if (hasEmptyMetadata(newRevisionToMetadata)) {// retry every 10 seconds
- if (retryPermission.tryAcquire()) {
- retryFuture = scheduler.schedule(new AddressRefreshRetryTask(retryPermission, event.getServiceName()), 10_000L, TimeUnit.MILLISECONDS);
- logger.warn("Address refresh try task submitted.");
- }
- logger.error("Address refresh failed because of Metadata Server failure, wait for retry or new address refresh event.");
- return;
+ List<ServiceInstance> instances = entry.getValue();
+ // instances should never be empty.
+ DefaultServiceInstance instance = (DefaultServiceInstance)instances.iterator().next();
+ parseMetadata(revision, instance.getServiceMetadata(), localServiceToRevisions);
}
- this.revisionToMetadata = newRevisionToMetadata;
-
Map<String, Map<Set<String>, Object>> protocolRevisionsToUrls = new HashMap<>();
Map<String, Object> newServiceUrls = new HashMap<>();
for (Map.Entry<String, Map<String, Set<String>>> entry : localServiceToRevisions.entrySet()) {
@@ -259,14 +228,6 @@ public class ServiceInstancesChangedListener {
return allInstances.get(appName);
}
- public Map<String, MetadataInfo> getRevisionToMetadata() {
- return revisionToMetadata;
- }
-
- public MetadataInfo getMetadata(String revision) {
- return revisionToMetadata.get(revision);
- }
-
/**
* @param event {@link ServiceInstancesChangedEvent event}
* @return If service name matches, return <code>true</code>, or <code>false</code>
@@ -275,19 +236,6 @@ public class ServiceInstancesChangedListener {
return serviceNames.contains(event.getServiceName());
}
- protected boolean isRetryAndExpired(ServiceInstancesChangedEvent event) {
- if (event instanceof RetryServiceInstancesChangedEvent) {
- RetryServiceInstancesChangedEvent retryEvent = (RetryServiceInstancesChangedEvent) event;
- logger.warn("Received address refresh retry event, " + retryEvent.getFailureRecordTime());
- if (retryEvent.getFailureRecordTime() < lastRefreshTime && !hasEmptyMetadata(revisionToMetadata)) {
- logger.warn("Ignore retry event, event time: " + retryEvent.getFailureRecordTime() + ", last refresh time: " + lastRefreshTime);
- return true;
- }
- logger.warn("Retrying address notification...");
- }
- return false;
- }
-
private void refreshInstance(ServiceInstancesChangedEvent event) {
if (event instanceof RetryServiceInstancesChangedEvent) {
return;
@@ -311,42 +259,6 @@ public class ServiceInstancesChangedListener {
return false;
}
- protected MetadataInfo getRemoteMetadata(String revision, Map<String, Map<String, Set<String>>> localServiceToRevisions, ServiceInstance instance) {
- MetadataInfo metadata = revisionToMetadata.get(revision);
-
- if (metadata != null && metadata != MetadataInfo.EMPTY) {
- // metadata loaded from cache
- if (logger.isDebugEnabled()) {
- logger.debug("MetadataInfo for instance " + instance.getAddress() + "?revision=" + revision
- + "&cluster=" + instance.getRegistryCluster() + ", " + metadata);
- }
- parseMetadata(revision, metadata, localServiceToRevisions);
- return metadata;
- }
-
- // try to load metadata from remote.
- int triedTimes = 0;
- while (triedTimes < 3) {
- metadata = doGetMetadataInfo(instance);
-
- if (metadata != MetadataInfo.EMPTY) {// succeeded
- parseMetadata(revision, metadata, localServiceToRevisions);
- break;
- } else {// failed
- logger.error("Failed to get MetadataInfo for instance " + instance.getAddress() + "?revision=" + revision
- + "&cluster=" + instance.getRegistryCluster() + ", wait for retry.");
- triedTimes++;
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- }
- }
- }
-
- revisionToMetadata.putIfAbsent(revision, metadata);
- return metadata;
- }
-
protected Map<String, Map<String, Set<String>>> parseMetadata(String revision, MetadataInfo metadata, Map<String, Map<String, Set<String>>> localServiceToRevisions) {
Map<String, ServiceInfo> serviceInfos = metadata.getServices();
for (Map.Entry<String, ServiceInfo> entry : serviceInfos.entrySet()) {
@@ -360,37 +272,6 @@ public class ServiceInstancesChangedListener {
return localServiceToRevisions;
}
- protected MetadataInfo doGetMetadataInfo(ServiceInstance instance) {
- String metadataType = ServiceInstanceMetadataUtils.getMetadataStorageType(instance);
- // FIXME, check "REGISTRY_CLUSTER_KEY" must be set by every registry implementation.
- if (instance.getRegistryCluster() == null) {
- instance.setRegistryCluster(RegistryClusterIdentifier.getExtension(url).consumerKey(url));
- }
- MetadataInfo metadataInfo;
- try {
- if (logger.isDebugEnabled()) {
- logger.debug("Instance " + instance.getAddress() + " is using metadata type " + metadataType);
- }
- if (REMOTE_METADATA_STORAGE_TYPE.equals(metadataType)) {
- RemoteMetadataServiceImpl remoteMetadataService = MetadataUtils.getRemoteMetadataService(instance.getApplicationModel());
- metadataInfo = remoteMetadataService.getMetadata(instance);
- } else {
- // change the instance used to communicate to avoid all requests route to the same instance
- MetadataService metadataServiceProxy = MetadataUtils.getMetadataServiceProxy(instance);
- metadataInfo = metadataServiceProxy.getMetadataInfo(ServiceInstanceMetadataUtils.getExportedServicesRevision(instance));
- MetadataUtils.destroyMetadataServiceProxy(instance);
- }
- } catch (Exception e) {
- logger.error("Failed to load service metadata, meta type is " + metadataType, e);
- metadataInfo = null;
- }
-
- if (metadataInfo == null) {
- metadataInfo = MetadataInfo.EMPTY;
- }
- return metadataInfo;
- }
-
private ServiceInstance selectInstance(List<ServiceInstance> instances) {
if (instances.size() == 1) {
return instances.get(0);
@@ -448,7 +329,6 @@ public class ServiceInstancesChangedListener {
if (destroyed.compareAndSet(false, true)) {
allInstances.clear();
serviceUrls.clear();
- revisionToMetadata.clear();
if (retryFuture != null && !retryFuture.isDone()) {
retryFuture.cancel(true);
}
@@ -478,22 +358,6 @@ public class ServiceInstancesChangedListener {
return Objects.hash(getClass(), getServiceNames());
}
- protected class AddressRefreshRetryTask implements Runnable {
- private final RetryServiceInstancesChangedEvent retryEvent;
- private final Semaphore retryPermission;
-
- public AddressRefreshRetryTask(Semaphore semaphore, String serviceName) {
- this.retryEvent = new RetryServiceInstancesChangedEvent(serviceName);
- this.retryPermission = semaphore;
- }
-
- @Override
- public void run() {
- retryPermission.release();
- ServiceInstancesChangedListener.this.onEvent(retryEvent);
- }
- }
-
protected static class NotifyListenerWithKey {
private String serviceKey;
private NotifyListener notifyListener;
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataServiceNameMapping.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataServiceNameMapping.java
index 6c126db..fe8e9a9 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataServiceNameMapping.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataServiceNameMapping.java
@@ -32,6 +32,7 @@ import org.apache.dubbo.rpc.model.ApplicationModel;
import java.util.Collections;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SEPARATOR;
@@ -50,6 +51,9 @@ public class MetadataServiceNameMapping extends AbstractServiceNameMapping {
metadataReportInstance = applicationModel.getBeanFactory().getBean(MetadataReportInstance.class);
}
+ /**
+ * Simply register to all metadata center
+ */
@Override
public boolean map(URL url) {
if (CollectionUtils.isEmpty(applicationModel.getApplicationConfigManager().getMetadataConfigs())) {
@@ -59,37 +63,45 @@ public class MetadataServiceNameMapping extends AbstractServiceNameMapping {
if (IGNORED_SERVICE_INTERFACES.contains(serviceInterface)) {
return false;
}
- String registryCluster = getRegistryCluster(url);
- MetadataReport metadataReport = metadataReportInstance.getMetadataReport(registryCluster);
- String appName = applicationModel.getApplicationName();
- if (metadataReport.registerServiceAppMapping(serviceInterface, appName, url)) {
- // MetadataReport support directly register service-app mapping
- return true;
- }
+ boolean result = true;
+ for (Map.Entry<String, MetadataReport> entry : metadataReportInstance.getMetadataReports(true).entrySet()) {
+ MetadataReport metadataReport = entry.getValue();
+ String appName = applicationModel.getApplicationName();
+ try {
+ if (metadataReport.registerServiceAppMapping(serviceInterface, appName, url)) {
+ // MetadataReport support directly register service-app mapping
+ continue;
+ }
+
+ boolean succeeded;
+ int currentRetryTimes = 1;
+ String newConfigContent = appName;
+ do {
+ ConfigItem configItem = metadataReport.getConfigItem(serviceInterface, DEFAULT_MAPPING_GROUP);
+ String oldConfigContent = configItem.getContent();
+ if (StringUtils.isNotEmpty(oldConfigContent)) {
+ boolean contains = StringUtils.isContains(oldConfigContent, appName);
+ if (contains) {
+ // From the user's perspective, it means successful when the oldConfigContent has contained the current appName. So we should not throw an Exception to user, it will confuse the user.
+ succeeded = true;
+ break;
+ }
+ newConfigContent = oldConfigContent + COMMA_SEPARATOR + appName;
+ }
+ succeeded = metadataReport.registerServiceAppMapping(serviceInterface, DEFAULT_MAPPING_GROUP, newConfigContent, configItem.getTicket());
+ } while (!succeeded && currentRetryTimes++ <= CAS_RETRY_TIMES);
- int currentRetryTimes = 1;
- boolean succeeded = false;
- String newConfigContent = appName;
- do {
- ConfigItem configItem = metadataReport.getConfigItem(serviceInterface, DEFAULT_MAPPING_GROUP);
- String oldConfigContent = configItem.getContent();
- if (StringUtils.isNotEmpty(oldConfigContent)) {
- boolean contains = StringUtils.isContains(oldConfigContent, appName);
- if (contains) {
- // From the user's perspective, it means successful when the oldConfigContent has contained the current appName. So we should not throw an Exception to user, it will confuse the user.
- succeeded = true;
- break;
+ if (!succeeded) {
+ result = false;
}
- newConfigContent = oldConfigContent + COMMA_SEPARATOR + appName;
+ } catch (Exception e) {
+ result = false;
+ logger.warn("Failed registering mapping to remote." + metadataReport, e);
}
- succeeded = metadataReport.registerServiceAppMapping(serviceInterface, DEFAULT_MAPPING_GROUP, newConfigContent, configItem.getTicket());
- } while (!succeeded && currentRetryTimes++ <= CAS_RETRY_TIMES);
- if (!succeeded) {
- throw new RuntimeException();
}
- return true;
+ return result;
}
@Override
@@ -103,11 +115,21 @@ public class MetadataServiceNameMapping extends AbstractServiceNameMapping {
@Override
public Set<String> getAndListen(URL url, MappingListener mappingListener) {
String serviceInterface = url.getServiceInterface();
+ // randomly pick one metadata report is ok for it's guaranteed each metadata report will have the same mapping content.
String registryCluster = getRegistryCluster(url);
MetadataReport metadataReport = metadataReportInstance.getMetadataReport(registryCluster);
return metadataReport.getServiceAppMapping(serviceInterface, mappingListener, url);
}
+ @Override
+ protected void removeListener(URL url, MappingListener mappingListener) {
+ String serviceInterface = url.getServiceInterface();
+ // randomly pick one metadata report is ok for it's guaranteed each metadata report will have the same mapping content.
+ String registryCluster = getRegistryCluster(url);
+ MetadataReport metadataReport = metadataReportInstance.getMetadataReport(registryCluster);
+ metadataReport.removeServiceAppMappingListener(serviceInterface, mappingListener);
+ }
+
protected String getRegistryCluster(URL url) {
String registryCluster = RegistryClusterIdentifier.getExtension(url).providerKey(url);
if (registryCluster == null) {
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataServiceURLParamsMetadataCustomizer.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataServiceURLParamsMetadataCustomizer.java
index d584c74..71b8d8d 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataServiceURLParamsMetadataCustomizer.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataServiceURLParamsMetadataCustomizer.java
@@ -16,10 +16,14 @@
*/
package org.apache.dubbo.registry.client.metadata;
-import org.apache.dubbo.metadata.WritableMetadataService;
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.metadata.MetadataServiceExporter;
import org.apache.dubbo.registry.client.ServiceInstance;
import org.apache.dubbo.registry.client.ServiceInstanceCustomizer;
+import org.apache.dubbo.rpc.model.ApplicationModel;
+import org.apache.dubbo.rpc.model.ScopeModelAware;
+import java.util.List;
import java.util.Map;
import static org.apache.dubbo.common.utils.StringUtils.isBlank;
@@ -29,7 +33,14 @@ import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataU
/**
* Used to interact with non-dubbo systems, also see {@link SpringCloudMetadataServiceURLBuilder}
*/
-public class MetadataServiceURLParamsMetadataCustomizer implements ServiceInstanceCustomizer {
+public class MetadataServiceURLParamsMetadataCustomizer implements ServiceInstanceCustomizer, ScopeModelAware {
+
+ private ApplicationModel applicationModel;
+
+ @Override
+ public void setApplicationModel(ApplicationModel applicationModel) {
+ this.applicationModel = applicationModel;
+ }
@Override
public void customize(ServiceInstance serviceInstance) {
@@ -49,7 +60,11 @@ public class MetadataServiceURLParamsMetadataCustomizer implements ServiceInstan
}
private String resolveMetadataPropertyValue(ServiceInstance serviceInstance) {
- WritableMetadataService writableMetadataService = WritableMetadataService.getDefaultExtension(serviceInstance.getApplicationModel());
- return getMetadataServiceParameter(writableMetadataService.getMetadataServiceURL());
+ MetadataServiceExporter metadataServiceExporter = applicationModel.getExtensionLoader(MetadataServiceExporter.class).getDefaultExtension();
+ if (metadataServiceExporter.isExported()) {
+ List<URL> metadataURLs = metadataServiceExporter.getExportedURLs();
+ return getMetadataServiceParameter(metadataURLs.get(0));
+ }
+ return "";
}
}
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataUtils.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataUtils.java
index 4fe171b..3fbedb2 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataUtils.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/MetadataUtils.java
@@ -18,43 +18,72 @@ package org.apache.dubbo.registry.client.metadata;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.extension.ExtensionLoader;
+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.StringUtils;
+import org.apache.dubbo.metadata.MetadataInfo;
import org.apache.dubbo.metadata.MetadataService;
-import org.apache.dubbo.metadata.WritableMetadataService;
+import org.apache.dubbo.metadata.definition.model.FullServiceDefinition;
+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.SubscriberMetadataIdentifier;
import org.apache.dubbo.registry.client.ServiceInstance;
-import org.apache.dubbo.registry.client.metadata.store.RemoteMetadataServiceImpl;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.Protocol;
import org.apache.dubbo.rpc.ProxyFactory;
+import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.ScopeModel;
import org.apache.dubbo.rpc.model.ScopeModelUtil;
+import org.apache.dubbo.rpc.model.ServiceDescriptor;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
-import static org.apache.dubbo.common.constants.CommonConstants.METADATA_KEY;
+import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER_SIDE;
import static org.apache.dubbo.common.constants.CommonConstants.REMOTE_METADATA_STORAGE_TYPE;
+import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_CLUSTER_KEY;
import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.METADATA_SERVICE_URLS_PROPERTY_NAME;
public class MetadataUtils {
+ public static final Logger logger = LoggerFactory.getLogger(MetadataUtils.class);
public static ConcurrentMap<String, MetadataService> metadataServiceProxies = new ConcurrentHashMap<>();
public static ConcurrentMap<String, Invoker<?>> metadataServiceInvokers = new ConcurrentHashMap<>();
- public static RemoteMetadataServiceImpl getRemoteMetadataService(ScopeModel scopeModel) {
- return scopeModel.getBeanFactory().getBean(RemoteMetadataServiceImpl.class);
+ public static ConcurrentMap<String, Invoker<?>> getMetadataServiceInvokers() {
+ return metadataServiceInvokers;
}
- public static void publishServiceDefinition(URL url) {
- // store in local
- WritableMetadataService.getDefaultExtension(url.getScopeModel()).publishServiceDefinition(url);
- // send to remote
- if (REMOTE_METADATA_STORAGE_TYPE.equalsIgnoreCase(url.getParameter(METADATA_KEY))) {
- getRemoteMetadataService(url.getOrDefaultApplicationModel()).publishServiceDefinition(url);
+ public static synchronized MetadataService getMetadataServiceProxy(ServiceInstance instance) {
+ return metadataServiceProxies.computeIfAbsent(computeKey(instance), k -> referProxy(k, instance));
+ }
+
+ public static void publishServiceDefinition(ServiceDescriptor serviceDescriptor, ApplicationModel applicationModel) {
+ checkRemoteConfigured(applicationModel);
+
+ String serviceName = serviceDescriptor.getServiceName();
+ FullServiceDefinition serviceDefinition = serviceDescriptor.getServiceDefinition(serviceName);
+
+ try {
+ if (StringUtils.isNotEmpty(serviceName)) {
+ for (Map.Entry<String, MetadataReport> entry : getMetadataReports(applicationModel).entrySet()) {
+ MetadataReport metadataReport = entry.getValue();
+ metadataReport.storeProviderMetadata(new MetadataIdentifier(serviceName,
+ "", "",
+ PROVIDER_SIDE, applicationModel.getApplicationName()), serviceDefinition);
+ }
+ return;
+ }
+ logger.error("publishProvider interfaceName is empty.");
+ } catch (Exception e) {
+ //ignore error
+ logger.error("publishProvider getServiceDescriptor error.", e);
}
}
@@ -63,10 +92,6 @@ public class MetadataUtils {
ServiceInstanceMetadataUtils.getExportedServicesRevision(serviceInstance);
}
- public static synchronized MetadataService getMetadataServiceProxy(ServiceInstance instance) {
- return metadataServiceProxies.computeIfAbsent(computeKey(instance), k -> referProxy(k, instance));
- }
-
public static synchronized void destroyMetadataServiceProxy(ServiceInstance instance) {
String key = computeKey(instance);
if (metadataServiceProxies.containsKey(key)) {
@@ -110,7 +135,93 @@ public class MetadataUtils {
return metadataServiceProxies;
}
- public static ConcurrentMap<String, Invoker<?>> getMetadataServiceInvokers() {
- return metadataServiceInvokers;
+ public static MetadataInfo getRemoteMetadata(String revision, ServiceInstance instance, Map<String, MetadataInfo> revisionToMetadata, MetadataReport metadataReport) {
+ MetadataInfo metadata = revisionToMetadata.get(revision);
+
+ if (metadata != null && metadata != MetadataInfo.EMPTY) {
+ // metadata loaded from cache
+ if (logger.isDebugEnabled()) {
+ logger.debug("MetadataInfo for instance " + instance.getAddress() + "?revision=" + revision
+ + "&cluster=" + instance.getRegistryCluster() + ", " + metadata);
+ }
+ return metadata;
+ }
+
+ // try to load metadata from remote.
+ int triedTimes = 0;
+ while (triedTimes < 3) {
+ metadata = doGetMetadataInfo(instance, metadataReport);
+
+ if (metadata != MetadataInfo.EMPTY) {// succeeded
+ break;
+ } else {// failed
+ logger.error("Failed to get MetadataInfo for instance " + instance.getAddress() + "?revision=" + revision
+ + "&cluster=" + instance.getRegistryCluster() + ", wait for retry.");
+ triedTimes++;
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ }
+ }
+ }
+
+ revisionToMetadata.putIfAbsent(revision, metadata);
+ return metadata;
}
+
+ protected static MetadataInfo doGetMetadataInfo(ServiceInstance instance, MetadataReport metadataReport) {
+ String metadataType = ServiceInstanceMetadataUtils.getMetadataStorageType(instance);
+ MetadataInfo metadataInfo = null;
+ try {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Instance " + instance.getAddress() + " is using metadata type " + metadataType);
+ }
+ if (REMOTE_METADATA_STORAGE_TYPE.equals(metadataType)) {
+ getMetadata(instance, metadataReport);
+ } else {
+ // change the instance used to communicate to avoid all requests route to the same instance
+ MetadataService metadataServiceProxy = MetadataUtils.getMetadataServiceProxy(instance);
+ metadataInfo = metadataServiceProxy.getMetadataInfo(ServiceInstanceMetadataUtils.getExportedServicesRevision(instance));
+ MetadataUtils.destroyMetadataServiceProxy(instance);
+ }
+ } catch (Exception e) {
+ logger.error("Failed to load service metadata, meta type is " + metadataType, e);
+ metadataInfo = null;
+ }
+
+ if (metadataInfo == null) {
+ metadataInfo = MetadataInfo.EMPTY;
+ }
+ return metadataInfo;
+ }
+
+ public static MetadataInfo getMetadata(ServiceInstance instance, MetadataReport metadataReport) {
+ SubscriberMetadataIdentifier identifier = new SubscriberMetadataIdentifier(instance.getServiceName(),
+ ServiceInstanceMetadataUtils.getExportedServicesRevision(instance));
+
+ if (metadataReport == null) {
+ throw new IllegalStateException("No valid remote metadata report specified.");
+ }
+
+ String registryCluster = instance.getRegistryCluster();
+ Map<String, String> params = new HashMap<>(instance.getExtendParams());
+ if (registryCluster != null && !registryCluster.equalsIgnoreCase(params.get(REGISTRY_CLUSTER_KEY))) {
+ params.put(REGISTRY_CLUSTER_KEY, registryCluster);
+ }
+
+ return metadataReport.getAppMetadata(identifier, params);
+ }
+
+ private static void checkRemoteConfigured(ApplicationModel applicationModel) {
+ if (getMetadataReports(applicationModel).size() == 0) {
+ String msg = "Remote Metadata Report Server not hasn't been configured or unavailable . Unable to get Metadata from remote!";
+ logger.error(msg);
+ throw new IllegalStateException(msg);
+ }
+ }
+
+ private static Map<String, MetadataReport> getMetadataReports(ApplicationModel applicationModel) {
+ return applicationModel.getBeanFactory().getBean(MetadataReportInstance.class).getMetadataReports(false);
+ }
+
}
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataCustomizer.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataCustomizer.java
index 1c70842..cfdc530 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataCustomizer.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataCustomizer.java
@@ -23,10 +23,9 @@ import org.apache.dubbo.common.utils.ArrayUtils;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.metadata.MetadataInfo;
import org.apache.dubbo.metadata.MetadataParamsFilter;
-import org.apache.dubbo.metadata.WritableMetadataService;
+import org.apache.dubbo.registry.client.DefaultServiceInstance;
import org.apache.dubbo.registry.client.ServiceInstance;
import org.apache.dubbo.registry.client.ServiceInstanceCustomizer;
-import org.apache.dubbo.registry.client.metadata.store.InMemoryWritableMetadataService;
import org.apache.dubbo.rpc.model.ApplicationModel;
import java.util.Collections;
@@ -61,15 +60,7 @@ public class ServiceInstanceMetadataCustomizer implements ServiceInstanceCustomi
ApplicationModel applicationModel = serviceInstance.getApplicationModel();
ExtensionLoader<MetadataParamsFilter> loader = applicationModel.getExtensionLoader(MetadataParamsFilter.class);
- InMemoryWritableMetadataService localMetadataService
- = (InMemoryWritableMetadataService) WritableMetadataService.getDefaultExtension(applicationModel);
- // pick the first interface metadata available.
- // FIXME, check the same key in different urls have the same value
- Map<String, MetadataInfo> metadataInfos = localMetadataService.getMetadataInfos();
- if (CollectionUtils.isEmptyMap(metadataInfos)) {
- return;
- }
- MetadataInfo metadataInfo = metadataInfos.values().iterator().next();
+ MetadataInfo metadataInfo = ((DefaultServiceInstance)serviceInstance).getServiceMetadata();
if (metadataInfo == null || CollectionUtils.isEmptyMap(metadataInfo.getServices())) {
return;
}
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 e6e19ba..6cfc2df 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
@@ -21,7 +21,6 @@ import org.apache.dubbo.common.extension.ExtensionLoader;
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.MetadataInfo;
import org.apache.dubbo.metadata.MetadataService;
import org.apache.dubbo.metadata.WritableMetadataService;
import org.apache.dubbo.registry.client.DefaultServiceInstance;
@@ -29,8 +28,8 @@ import org.apache.dubbo.registry.client.DefaultServiceInstance.Endpoint;
import org.apache.dubbo.registry.client.ServiceDiscovery;
import org.apache.dubbo.registry.client.ServiceInstance;
import org.apache.dubbo.registry.client.ServiceInstanceCustomizer;
-import org.apache.dubbo.registry.client.metadata.store.RemoteMetadataServiceImpl;
import org.apache.dubbo.registry.support.RegistryManager;
+import org.apache.dubbo.rpc.model.ApplicationModel;
import com.google.gson.Gson;
@@ -41,14 +40,11 @@ import java.util.Map;
import static java.util.Collections.emptyMap;
import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_METADATA_STORAGE_TYPE;
import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.PORT_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.PROTOCOL_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.REMOTE_METADATA_STORAGE_TYPE;
import static org.apache.dubbo.common.constants.CommonConstants.TIMESTAMP_KEY;
-import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_CLUSTER_KEY;
import static org.apache.dubbo.common.utils.StringUtils.isBlank;
import static org.apache.dubbo.registry.integration.InterfaceCompatibleRegistryProtocol.DEFAULT_REGISTER_PROVIDER_KEYS;
import static org.apache.dubbo.rpc.Constants.DEPRECATED_KEY;
@@ -217,71 +213,30 @@ public class ServiceInstanceMetadataUtils {
return null;
}
- public static void calInstanceRevision(ServiceDiscovery serviceDiscovery, ServiceInstance instance) {
- String registryCluster = serviceDiscovery.getUrl() == null ? DEFAULT_KEY : serviceDiscovery.getUrl().getParameter(REGISTRY_CLUSTER_KEY);
- if (registryCluster == null) {
- registryCluster = DEFAULT_KEY;
- }
- WritableMetadataService writableMetadataService = WritableMetadataService.getDefaultExtension(instance.getApplicationModel());
- MetadataInfo metadataInfo = writableMetadataService.getMetadataInfos().get(registryCluster);
- if (metadataInfo == null) {
- metadataInfo = writableMetadataService.getDefaultMetadataInfo();
- }
- if (metadataInfo != null) {
- String existingInstanceRevision = instance.getMetadata().get(EXPORTED_SERVICES_REVISION_PROPERTY_NAME);
- if (!metadataInfo.calAndGetRevision().equals(existingInstanceRevision)) {
- instance.getMetadata().put(EXPORTED_SERVICES_REVISION_PROPERTY_NAME, metadataInfo.calAndGetRevision());
- if (existingInstanceRevision != null) {// skip the first registration.
- instance.getExtendParams().put(INSTANCE_REVISION_UPDATED_KEY, "true");
- }
- }
- }
- }
-
public static boolean isInstanceUpdated(ServiceInstance instance) {
return "true".equals(instance.getExtendParams().get(INSTANCE_REVISION_UPDATED_KEY));
}
- public static void resetInstanceUpdateKey(ServiceInstance instance) {
- instance.getExtendParams().remove(INSTANCE_REVISION_UPDATED_KEY);
+ public static void registerMetadataAndInstance(ApplicationModel applicationModel) {
+ LOGGER.info("Start registering instance address to registry.");
+ RegistryManager registryManager = applicationModel.getBeanFactory().getBean(RegistryManager.class);
+ // register service instance
+ registryManager.getServiceDiscoveries().forEach(ServiceDiscovery::register);
}
- public static void registerMetadataAndInstance(ServiceInstance serviceInstance) {
- // register instance only when at least one service is exported.
- if (serviceInstance.getPort() > 0) {
- reportMetadataToRemote(serviceInstance);
- LOGGER.info("Start registering instance address to registry.");
- RegistryManager registryManager = serviceInstance.getOrDefaultApplicationModel().getBeanFactory().getBean(RegistryManager.class);
- registryManager.getServiceDiscoveries().forEach(serviceDiscovery ->
- {
- // copy instance for each registry to make sure instance in each registry can evolve independently
- ServiceInstance serviceInstanceForRegistry = new DefaultServiceInstance((DefaultServiceInstance) serviceInstance);
- calInstanceRevision(serviceDiscovery, serviceInstanceForRegistry);
- if (LOGGER.isDebugEnabled()) {
- LOGGER.debug("Start registering instance address to registry" + serviceDiscovery.getUrl() + ", instance " + serviceInstanceForRegistry);
- }
- // register service instance
- serviceDiscovery.register(serviceInstanceForRegistry);
- });
- }
+ public static void refreshMetadataAndInstance(ApplicationModel applicationModel) {
+ RegistryManager registryManager = applicationModel.getBeanFactory().getBean(RegistryManager.class);
+ // update service instance revision
+ registryManager.getServiceDiscoveries().forEach(ServiceDiscovery::update);
}
- public static void refreshMetadataAndInstance(ServiceInstance serviceInstance) {
- reportMetadataToRemote(serviceInstance);
- RegistryManager registryManager = serviceInstance.getOrDefaultApplicationModel().getBeanFactory().getBean(RegistryManager.class);
+ public static void unregisterMetadataAndInstance(ApplicationModel applicationModel) {
+ RegistryManager registryManager = applicationModel.getBeanFactory().getBean(RegistryManager.class);
registryManager.getServiceDiscoveries().forEach(serviceDiscovery -> {
- ServiceInstance instance = serviceDiscovery.getLocalInstance();
- if (instance == null) {
- LOGGER.warn("Refreshing of service instance started, but instance hasn't been registered yet.");
- instance = serviceInstance;
- }
- // copy instance again, in case the same instance accidently shared among registries
- instance = new DefaultServiceInstance((DefaultServiceInstance) instance);
- calInstanceRevision(serviceDiscovery, instance);
- customizeInstance(instance);
- if (instance.getPort() > 0) {
- // update service instance revision
- serviceDiscovery.update(instance);
+ try {
+ serviceDiscovery.unregister();
+ } catch (Exception ignored) {
+ // ignored
}
});
}
@@ -296,13 +251,6 @@ public class ServiceInstanceMetadataUtils {
});
}
- private static void reportMetadataToRemote(ServiceInstance serviceInstance) {
- if (REMOTE_METADATA_STORAGE_TYPE.equalsIgnoreCase(getMetadataStorageType(serviceInstance))) {
- RemoteMetadataServiceImpl remoteMetadataService = MetadataUtils.getRemoteMetadataService(serviceInstance.getApplicationModel());
- remoteMetadataService.publishMetadata(serviceInstance.getApplicationModel().getApplicationName());
- }
- }
-
/**
* Set the default parameters via the specified {@link URL providerURL}
*
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/store/InMemoryWritableMetadataService.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/store/InMemoryWritableMetadataService.java
deleted file mode 100644
index d563972..0000000
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/store/InMemoryWritableMetadataService.java
+++ /dev/null
@@ -1,467 +0,0 @@
-/*
- * 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.store;
-
-import com.google.gson.Gson;
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.config.ConfigurationUtils;
-import org.apache.dubbo.common.logger.Logger;
-import org.apache.dubbo.common.logger.LoggerFactory;
-import org.apache.dubbo.common.utils.ClassUtils;
-import org.apache.dubbo.common.utils.CollectionUtils;
-import org.apache.dubbo.common.utils.StringUtils;
-import org.apache.dubbo.metadata.InstanceMetadataChangedListener;
-import org.apache.dubbo.metadata.MetadataInfo;
-import org.apache.dubbo.metadata.MetadataInfo.ServiceInfo;
-import org.apache.dubbo.metadata.MetadataService;
-import org.apache.dubbo.metadata.ServiceNameMapping;
-import org.apache.dubbo.metadata.WritableMetadataService;
-import org.apache.dubbo.metadata.definition.ServiceDefinitionBuilder;
-import org.apache.dubbo.metadata.definition.model.ServiceDefinition;
-import org.apache.dubbo.registry.client.RegistryClusterIdentifier;
-import org.apache.dubbo.rpc.model.ApplicationModel;
-import org.apache.dubbo.rpc.model.ScopeModelAware;
-import org.apache.dubbo.rpc.support.ProtocolUtils;
-
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.SortedSet;
-import java.util.TreeSet;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.ConcurrentNavigableMap;
-import java.util.concurrent.ConcurrentSkipListMap;
-import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
-import static java.util.Collections.emptySortedSet;
-import static java.util.Collections.unmodifiableSortedSet;
-import static org.apache.dubbo.common.URL.buildKey;
-import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER_SIDE;
-import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.PROTOCOL_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.SIDE_KEY;
-import static org.apache.dubbo.common.utils.CollectionUtils.isEmpty;
-import static org.apache.dubbo.metadata.MetadataConstants.DEFAULT_METADATA_PUBLISH_DELAY;
-import static org.apache.dubbo.metadata.MetadataConstants.METADATA_PUBLISH_DELAY_KEY;
-import static org.apache.dubbo.rpc.Constants.GENERIC_KEY;
-
-/**
- * The {@link WritableMetadataService} implementation stores the metadata of Dubbo services in memory locally when they
- * exported. It is used by server (provider).
- *
- * @see MetadataService
- * @see WritableMetadataService
- * @since 2.7.5
- */
-public class InMemoryWritableMetadataService implements WritableMetadataService, ScopeModelAware {
-
- 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}
- */
- private ConcurrentNavigableMap<String, SortedSet<URL>> exportedServiceURLs = new ConcurrentSkipListMap<>();
- private URL metadataServiceURL;
- private ConcurrentMap<String, MetadataInfo> metadataInfos;
-
- // used to mark whether current metadata info is being updated to registry,
- // readLock for export or unExport which are support concurrency update,
- // writeLock for ServiceInstance update which should not work during exporting services
- private final ReentrantReadWriteLock updateLock = new ReentrantReadWriteLock();
- private final Semaphore metadataSemaphore = new Semaphore(0);
- private final Map<String, Set<String>> serviceToAppsMapping = new HashMap<>();
-
- private String instanceMetadata;
- private ConcurrentMap<String, InstanceMetadataChangedListener> instanceMetadataChangedListenerMap = new ConcurrentHashMap<>();
-
-
- // ==================================================================================== //
-
- // =================================== 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}
- */
- private ConcurrentNavigableMap<String, SortedSet<URL>> subscribedServiceURLs = new ConcurrentSkipListMap<>();
-
- private ConcurrentNavigableMap<String, String> serviceDefinitions = new ConcurrentSkipListMap<>();
- private ApplicationModel applicationModel;
- private long metadataPublishDelayTime ;
-
- public InMemoryWritableMetadataService() {
- this.metadataInfos = new ConcurrentHashMap<>();
- }
-
- /**
- * Gets the current Dubbo Service name
- *
- * @return non-null
- */
- @Override
- public String serviceName() {
- return ApplicationModel.ofNullable(applicationModel).getApplicationName();
- }
-
- @Override
- public void setApplicationModel(ApplicationModel applicationModel) {
- this.applicationModel = applicationModel;
- this.metadataPublishDelayTime = ConfigurationUtils.get(applicationModel, METADATA_PUBLISH_DELAY_KEY, DEFAULT_METADATA_PUBLISH_DELAY);
- }
-
- @Override
- public SortedSet<String> getSubscribedURLs() {
- return getAllUnmodifiableServiceURLs(subscribedServiceURLs);
- }
-
- private SortedSet<String> getAllUnmodifiableServiceURLs(Map<String, SortedSet<URL>> serviceURLs) {
- SortedSet<URL> bizURLs = new TreeSet<>(InMemoryWritableMetadataService.URLComparator.INSTANCE);
- for (Map.Entry<String, SortedSet<URL>> entry : serviceURLs.entrySet()) {
- SortedSet<URL> urls = entry.getValue();
- if (urls != null) {
- for (URL url : urls) {
- if (!MetadataService.class.getName().equals(url.getServiceInterface())) {
- bizURLs.add(url);
- }
- }
- }
- }
- return MetadataService.toSortedStrings(bizURLs);
- }
-
- @Override
- public SortedSet<String> getExportedURLs(String serviceInterface, String group, String version, String protocol) {
- if (ALL_SERVICE_INTERFACES.equals(serviceInterface)) {
- return getAllUnmodifiableServiceURLs(exportedServiceURLs);
- }
- String serviceKey = buildKey(serviceInterface, group, version);
- return unmodifiableSortedSet(getServiceURLs(exportedServiceURLs, serviceKey, protocol));
- }
-
- @Override
- public Set<URL> getExportedServiceURLs() {
- Set<URL> set = new HashSet<>();
- for (Map.Entry<String, SortedSet<URL>> entry : exportedServiceURLs.entrySet()) {
- set.addAll(entry.getValue());
- }
- return set;
- }
-
- @Override
- public boolean exportURL(URL url) {
- if (MetadataService.class.getName().equals(url.getServiceInterface())) {
- this.metadataServiceURL = url;
- return true;
- }
-
- updateLock.readLock().lock();
- try {
- String[] clusters = getRegistryCluster(url).split(",");
- for (String cluster : clusters) {
- MetadataInfo metadataInfo = metadataInfos.computeIfAbsent(cluster, k -> new MetadataInfo(applicationModel.getApplicationName()));
- metadataInfo.addService(new ServiceInfo(url));
- }
- metadataSemaphore.release();
- return addURL(exportedServiceURLs, url);
- } finally {
- updateLock.readLock().unlock();
- }
- }
-
- public void addMetadataInfo(String key, MetadataInfo metadataInfo) {
- updateLock.readLock().lock();
- try {
- metadataInfos.put(key, metadataInfo);
- } finally {
- updateLock.readLock().unlock();
- }
- }
-
- @Override
- public boolean unexportURL(URL url) {
- if (MetadataService.class.getName().equals(url.getServiceInterface())) {
- // TODO, metadata service need to be unexported.
- this.metadataServiceURL = null;
- return true;
- }
-
- updateLock.readLock().lock();
- try {
- String[] clusters = getRegistryCluster(url).split(",");
- for (String cluster : clusters) {
- MetadataInfo metadataInfo = metadataInfos.get(cluster);
- metadataInfo.removeService(url.getProtocolServiceKey());
-// if (metadataInfo.getServices().isEmpty()) {
-// metadataInfos.remove(cluster);
-// }
- }
- metadataSemaphore.release();
- return removeURL(exportedServiceURLs, url);
- } finally {
- updateLock.readLock().unlock();
- }
- }
-
- private String getRegistryCluster(URL url) {
- String registryCluster = RegistryClusterIdentifier.getExtension(url).providerKey(url);
- if (StringUtils.isEmpty(registryCluster)) {
- registryCluster = DEFAULT_KEY;
- }
- return registryCluster;
- }
-
- @Override
- public boolean subscribeURL(URL url) {
- return addURL(subscribedServiceURLs, url);
- }
-
- @Override
- public boolean unsubscribeURL(URL url) {
- return removeURL(subscribedServiceURLs, url);
- }
-
- @Override
- public void publishServiceDefinition(URL url) {
- try {
- String interfaceName = url.getServiceInterface();
- if (StringUtils.isNotEmpty(interfaceName)
- && !ProtocolUtils.isGeneric(url.getParameter(GENERIC_KEY))) {
- ClassLoader classLoader = url.getServiceModel() != null ?
- url.getServiceModel().getClassLoader() :
- ClassUtils.getClassLoader();
- Class interfaceClass = Class.forName(interfaceName, false, classLoader);
- ServiceDefinition serviceDefinition = ServiceDefinitionBuilder.build(interfaceClass);
- Gson gson = new Gson();
- String data = gson.toJson(serviceDefinition);
- serviceDefinitions.put(url.getServiceKey(), data);
- return;
- } else if (CONSUMER_SIDE.equalsIgnoreCase(url.getParameter(SIDE_KEY))) {
- //to avoid consumer generic invoke style error
- return;
- }
- logger.error("publish service definition interfaceName is empty. url: " + url.toFullString());
- } catch (Throwable e) {
- //ignore error
- logger.error("publish service definition getServiceDescriptor error. url: " + url.toFullString(), e);
- }
- }
-
- @Override
- public String getServiceDefinition(String interfaceName, String version, String group) {
- return serviceDefinitions.get(URL.buildKey(interfaceName, group, version));
- }
-
- @Override
- public String getServiceDefinition(String serviceKey) {
- return serviceDefinitions.get(serviceKey);
- }
-
- @Override
- public MetadataInfo getMetadataInfo(String revision) {
- if (StringUtils.isEmpty(revision)) {
- return null;
- }
- for (Map.Entry<String, MetadataInfo> entry : metadataInfos.entrySet()) {
- MetadataInfo metadataInfo = entry.getValue();
- if (revision.equals(metadataInfo.calAndGetRevision())) {
- return metadataInfo;
- }
- }
- if (logger.isInfoEnabled()) {
- logger.info("metadata not found for revision: " + revision);
- }
- return null;
- }
-
- @Override
- public void exportInstanceMetadata(String metadata) {
- this.instanceMetadata = metadata;
- }
-
- @Override
- public Map<String, InstanceMetadataChangedListener> getInstanceMetadataChangedListenerMap() {
- return instanceMetadataChangedListenerMap;
- }
-
- @Override
- public String getAndListenInstanceMetadata(String consumerId, InstanceMetadataChangedListener listener) {
- instanceMetadataChangedListenerMap.put(consumerId, listener);
- return instanceMetadata;
- }
-
- @Override
- public MetadataInfo getDefaultMetadataInfo() {
- if (CollectionUtils.isEmptyMap(metadataInfos)) {
- return null;
- }
- for (Map.Entry<String, MetadataInfo> entry : metadataInfos.entrySet()) {
- if (entry.getKey().equalsIgnoreCase(DEFAULT_KEY)) {
- return entry.getValue();
- }
- }
- return metadataInfos.entrySet().iterator().next().getValue();
- }
-
- public void blockUntilUpdated() {
- try {
- metadataSemaphore.tryAcquire(metadataPublishDelayTime, TimeUnit.MILLISECONDS);
- metadataSemaphore.drainPermits();
- updateLock.writeLock().lock();
- } catch (InterruptedException e) {
- if (!applicationModel.isDestroyed()) {
- logger.warn("metadata refresh thread has been interrupted unexpectedly while waiting for update.", e);
- }
- }
- }
-
- public void releaseBlock() {
- updateLock.writeLock().unlock();
- }
-
- public Map<String, MetadataInfo> getMetadataInfos() {
- return Collections.unmodifiableMap(metadataInfos);
- }
-
- void addMetaServiceURL(URL url) {
- this.metadataServiceURL = url;
- }
-
- @Override
- public URL getMetadataServiceURL() {
- return this.metadataServiceURL;
- }
-
- @Override
- public void putCachedMapping(String serviceKey, Set<String> apps) {
- serviceToAppsMapping.put(serviceKey, new TreeSet<>(apps));
- }
-
- @Override
- public Set<String> getCachedMapping(String mappingKey) {
- return serviceToAppsMapping.get(mappingKey);
- }
-
- @Override
- public Set<String> getCachedMapping(URL consumerURL) {
- String serviceKey = ServiceNameMapping.buildMappingKey(consumerURL);
- return serviceToAppsMapping.get(serviceKey);
- }
-
- @Override
- public Set<String> removeCachedMapping(String serviceKey) {
- return serviceToAppsMapping.remove(serviceKey);
- }
-
- @Override
- public Map<String, Set<String>> getCachedMapping() {
- return serviceToAppsMapping;
- }
-
- @Override
- public void setMetadataServiceURL(URL url) {
- this.metadataServiceURL = url;
- }
-
- boolean addURL(Map<String, SortedSet<URL>> serviceURLs, URL url) {
- return executeMutually(() -> {
- SortedSet<URL> urls = serviceURLs.computeIfAbsent(url.getServiceKey(), this::newSortedURLs);
- // make sure the parameters of tmpUrl is variable
- return urls.add(url);
- });
- }
-
- boolean removeURL(Map<String, SortedSet<URL>> serviceURLs, URL url) {
- return executeMutually(() -> {
- String key = url.getServiceKey();
- SortedSet<URL> urls = serviceURLs.getOrDefault(key, null);
- if (urls == null) {
- return true;
- }
- boolean r = urls.remove(url);
- // if it is empty
- if (urls.isEmpty()) {
- serviceURLs.remove(key);
- }
- return r;
- });
- }
-
- private SortedSet<URL> newSortedURLs(String serviceKey) {
- return new TreeSet<>(InMemoryWritableMetadataService.URLComparator.INSTANCE);
- }
-
- boolean executeMutually(Callable<Boolean> callable) {
- boolean success = false;
- try {
- lock.lock();
- try {
- success = callable.call();
- } catch (Exception e) {
- if (logger.isErrorEnabled()) {
- logger.error(e);
- }
- }
- } finally {
- lock.unlock();
- }
- return success;
- }
-
- private SortedSet<String> getServiceURLs(Map<String, SortedSet<URL>> exportedServiceURLs, String serviceKey,
- String protocol) {
-
- SortedSet<URL> serviceURLs = exportedServiceURLs.get(serviceKey);
-
- if (isEmpty(serviceURLs)) {
- return emptySortedSet();
- }
-
- return MetadataService.toSortedStrings(serviceURLs.stream().filter(url -> isAcceptableProtocol(protocol, url)));
- }
-
- private boolean isAcceptableProtocol(String protocol, URL url) {
- return protocol == null
- || protocol.equals(url.getParameter(PROTOCOL_KEY))
- || protocol.equals(url.getProtocol());
- }
-
-
- static class URLComparator implements Comparator<URL> {
-
- public static final URLComparator INSTANCE = new URLComparator();
-
- @Override
- public int compare(URL o1, URL o2) {
- return o1.toFullString().compareTo(o2.toFullString());
- }
- }
-}
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/store/MetadataServiceDelegation.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/store/MetadataServiceDelegation.java
new file mode 100644
index 0000000..a298f17
--- /dev/null
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/store/MetadataServiceDelegation.java
@@ -0,0 +1,228 @@
+/*
+ * 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.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.MetadataInfo;
+import org.apache.dubbo.metadata.MetadataService;
+import org.apache.dubbo.metadata.MetadataServiceExporter;
+import org.apache.dubbo.metadata.WritableMetadataService;
+import org.apache.dubbo.registry.client.ServiceDiscovery;
+import org.apache.dubbo.registry.support.RegistryManager;
+import org.apache.dubbo.rpc.model.ApplicationModel;
+import org.apache.dubbo.rpc.model.ScopeModelAware;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import java.util.concurrent.ConcurrentNavigableMap;
+import java.util.concurrent.ConcurrentSkipListMap;
+
+import static java.util.Collections.emptySortedSet;
+import static java.util.Collections.unmodifiableSortedSet;
+import static org.apache.dubbo.common.URL.buildKey;
+import static org.apache.dubbo.common.constants.CommonConstants.PROTOCOL_KEY;
+import static org.apache.dubbo.common.utils.CollectionUtils.isEmpty;
+
+/**
+ * Implementation providing remote RPC service to facilitate the query of metadata information.
+ */
+public class MetadataServiceDelegation implements WritableMetadataService, ScopeModelAware {
+ Logger logger = LoggerFactory.getLogger(getClass());
+ private ApplicationModel applicationModel;
+ private RegistryManager registryManager;
+ private ConcurrentNavigableMap<String, String> serviceDefinitions = new ConcurrentSkipListMap<>();
+
+ public MetadataServiceDelegation() {}
+
+ /**
+ * Gets the current Dubbo Service name
+ *
+ * @return non-null
+ */
+ @Override
+ public String serviceName() {
+ return ApplicationModel.ofNullable(applicationModel).getApplicationName();
+ }
+
+ @Override
+ public void setApplicationModel(ApplicationModel applicationModel) {
+ this.applicationModel = applicationModel;
+ registryManager = RegistryManager.getInstance(applicationModel);
+ }
+
+ @Override
+ public SortedSet<String> getSubscribedURLs() {
+ return getAllUnmodifiableSubscribedURLs();
+ }
+
+ private SortedSet<String> getAllUnmodifiableServiceURLs() {
+ SortedSet<URL> bizURLs = new TreeSet<>(MetadataServiceDelegation.URLComparator.INSTANCE);
+ List<ServiceDiscovery> serviceDiscoveries = registryManager.getServiceDiscoveries();
+ for (ServiceDiscovery sd : serviceDiscoveries) {
+ MetadataInfo metadataInfo = sd.getMetadata();
+ Map<String, SortedSet<URL>> serviceURLs = metadataInfo.getExportedServiceURLs();
+ for (Map.Entry<String, SortedSet<URL>> entry : serviceURLs.entrySet()) {
+ SortedSet<URL> urls = entry.getValue();
+ if (urls != null) {
+ for (URL url : urls) {
+ if (!MetadataService.class.getName().equals(url.getServiceInterface())) {
+ bizURLs.add(url);
+ }
+ }
+ }
+ }
+ }
+ return MetadataService.toSortedStrings(bizURLs);
+ }
+
+ private SortedSet<String> getAllUnmodifiableSubscribedURLs() {
+ SortedSet<URL> bizURLs = new TreeSet<>(MetadataServiceDelegation.URLComparator.INSTANCE);
+ List<ServiceDiscovery> serviceDiscoveries = registryManager.getServiceDiscoveries();
+ for (ServiceDiscovery sd : serviceDiscoveries) {
+ MetadataInfo metadataInfo = sd.getMetadata();
+ Map<String, SortedSet<URL>> serviceURLs = metadataInfo.getSubscribedServiceURLs();
+ for (Map.Entry<String, SortedSet<URL>> entry : serviceURLs.entrySet()) {
+ SortedSet<URL> urls = entry.getValue();
+ if (urls != null) {
+ for (URL url : urls) {
+ if (!MetadataService.class.getName().equals(url.getServiceInterface())) {
+ bizURLs.add(url);
+ }
+ }
+ }
+ }
+ }
+ return MetadataService.toSortedStrings(bizURLs);
+ }
+
+ @Override
+ public SortedSet<String> getExportedURLs(String serviceInterface, String group, String version, String protocol) {
+ if (ALL_SERVICE_INTERFACES.equals(serviceInterface)) {
+ return getAllUnmodifiableServiceURLs();
+ }
+ String serviceKey = buildKey(serviceInterface, group, version);
+ return unmodifiableSortedSet(getServiceURLs(getAllServiceURLs(), serviceKey, protocol));
+ }
+
+ private Map<String, SortedSet<URL>> getAllServiceURLs () {
+ List<ServiceDiscovery> serviceDiscoveries = registryManager.getServiceDiscoveries();
+ Map<String, SortedSet<URL>> allServiceURLs = new HashMap<>();
+ for (ServiceDiscovery sd : serviceDiscoveries) {
+ MetadataInfo metadataInfo = sd.getMetadata();
+ Map<String, SortedSet<URL>> serviceURLs = metadataInfo.getExportedServiceURLs();
+ allServiceURLs.putAll(serviceURLs);
+ }
+ return allServiceURLs;
+ }
+
+ @Override
+ public Set<URL> getExportedServiceURLs() {
+ Set<URL> set = new HashSet<>();
+ registryManager.getRegistries();
+ for (Map.Entry<String, SortedSet<URL>> entry : getAllServiceURLs().entrySet()) {
+ set.addAll(entry.getValue());
+ }
+ return set;
+ }
+
+ @Override
+ public String getServiceDefinition(String interfaceName, String version, String group) {
+ return serviceDefinitions.get(URL.buildKey(interfaceName, group, version));
+ }
+
+ @Override
+ public String getServiceDefinition(String serviceKey) {
+ return serviceDefinitions.get(serviceKey);
+ }
+
+ @Override
+ public MetadataInfo getMetadataInfo(String revision) {
+ if (StringUtils.isEmpty(revision)) {
+ return null;
+ }
+
+ for (ServiceDiscovery sd : registryManager.getServiceDiscoveries()) {
+ MetadataInfo metadataInfo = sd.getMetadata();
+ if (revision.equals(metadataInfo.calAndGetRevision())) {
+ return metadataInfo;
+ }
+ }
+
+ if (logger.isWarnEnabled()) {
+ logger.warn("metadata not found for revision: " + revision);
+ }
+ return null;
+ }
+
+ @Override
+ public List<MetadataInfo> getMetadataInfos() {
+ List<MetadataInfo> metadataInfos = new ArrayList<>();
+ for (ServiceDiscovery sd : registryManager.getServiceDiscoveries()) {
+ metadataInfos.add(sd.getMetadata());
+ }
+ return metadataInfos;
+ }
+
+ @Override
+ public URL getMetadataServiceURL() {
+ MetadataServiceExporter metadataServiceExporter = applicationModel.getExtensionLoader(MetadataServiceExporter.class).getDefaultExtension();
+ if (metadataServiceExporter.isExported()) {
+ List<URL> metadataURLs = metadataServiceExporter.getExportedURLs();
+ return metadataURLs.get(0);
+ }
+ return null;
+ }
+
+ private SortedSet<String> getServiceURLs(Map<String, SortedSet<URL>> exportedServiceURLs, String serviceKey,
+ String protocol) {
+
+ SortedSet<URL> serviceURLs = exportedServiceURLs.get(serviceKey);
+
+ if (isEmpty(serviceURLs)) {
+ return emptySortedSet();
+ }
+
+ return MetadataService.toSortedStrings(serviceURLs.stream().filter(url -> isAcceptableProtocol(protocol, url)));
+ }
+
+ private boolean isAcceptableProtocol(String protocol, URL url) {
+ return protocol == null
+ || protocol.equals(url.getParameter(PROTOCOL_KEY))
+ || protocol.equals(url.getProtocol());
+ }
+
+
+ static class URLComparator implements Comparator<URL> {
+
+ public static final URLComparator INSTANCE = new URLComparator();
+
+ @Override
+ public int compare(URL o1, URL o2) {
+ return o1.toFullString().compareTo(o2.toFullString());
+ }
+ }
+}
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/store/RemoteMetadataServiceImpl.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/store/RemoteMetadataServiceImpl.java
deleted file mode 100644
index 7b68e4c..0000000
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/store/RemoteMetadataServiceImpl.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * 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.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.ClassUtils;
-import org.apache.dubbo.common.utils.StringUtils;
-import org.apache.dubbo.metadata.MetadataInfo;
-import org.apache.dubbo.metadata.WritableMetadataService;
-import org.apache.dubbo.metadata.definition.ServiceDefinitionBuilder;
-import org.apache.dubbo.metadata.definition.model.FullServiceDefinition;
-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.SubscriberMetadataIdentifier;
-import org.apache.dubbo.registry.client.ServiceInstance;
-import org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils;
-import org.apache.dubbo.rpc.RpcException;
-import org.apache.dubbo.rpc.model.ScopeModel;
-import org.apache.dubbo.rpc.model.ScopeModelAware;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER_SIDE;
-import static org.apache.dubbo.common.constants.CommonConstants.PID_KEY;
-import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER_SIDE;
-import static org.apache.dubbo.common.constants.CommonConstants.TIMESTAMP_KEY;
-import static org.apache.dubbo.common.constants.RegistryConstants.REGISTRY_CLUSTER_KEY;
-import static org.apache.dubbo.registry.Constants.REGISTER_IP_KEY;
-import static org.apache.dubbo.remoting.Constants.BIND_IP_KEY;
-import static org.apache.dubbo.remoting.Constants.BIND_PORT_KEY;
-
-public class RemoteMetadataServiceImpl implements ScopeModelAware {
- protected final Logger logger = LoggerFactory.getLogger(getClass());
- private WritableMetadataService localMetadataService;
- private MetadataReportInstance metadataReportInstance;
-
- @Override
- public void setScopeModel(ScopeModel scopeModel) {
- metadataReportInstance = scopeModel.getBeanFactory().getBean(MetadataReportInstance.class);
- localMetadataService = scopeModel.getDefaultExtension(WritableMetadataService.class);
- }
-
- public Map<String, MetadataReport> getMetadataReports() {
- return metadataReportInstance.getMetadataReports(false);
- }
-
- public void publishMetadata(String serviceName) {
- Map<String, MetadataInfo> metadataInfos = localMetadataService.getMetadataInfos();
- metadataInfos.forEach((registryCluster, metadataInfo) -> {
- if (!metadataInfo.hasReported()) {
- SubscriberMetadataIdentifier identifier = new SubscriberMetadataIdentifier(serviceName, metadataInfo.calAndGetRevision());
- metadataInfo.getExtendParams().put(REGISTRY_CLUSTER_KEY, registryCluster);
- if (getMetadataReports().size() > 0) {
- MetadataReport metadataReport = getMetadataReports().get(registryCluster);
- if (metadataReport == null) {
- metadataReport = getMetadataReports().entrySet().iterator().next().getValue();
- }
- logger.info("Publishing metadata to " + metadataReport.getClass().getSimpleName());
- if (logger.isDebugEnabled()) {
- logger.debug(metadataInfo.toString());
- }
- metadataReport.publishAppMetadata(identifier, metadataInfo);
- } else {
- if (logger.isInfoEnabled()) {
- logger.info("Remote Metadata Report Server not hasn't been configured. Only publish Metadata to local.");
- }
- }
- metadataInfo.markReported();
- }
- });
- }
-
- public MetadataInfo getMetadata(ServiceInstance instance) {
- SubscriberMetadataIdentifier identifier = new SubscriberMetadataIdentifier(instance.getServiceName(),
- ServiceInstanceMetadataUtils.getExportedServicesRevision(instance));
-
- String registryCluster = instance.getRegistryCluster();
-
- checkRemoteConfigured();
-
- MetadataReport metadataReport = getMetadataReports().get(registryCluster);
- if (metadataReport == null) {
- metadataReport = getMetadataReports().entrySet().iterator().next().getValue();
- }
- Map<String, String> params = new HashMap<>(instance.getExtendParams());
- if (registryCluster != null && !registryCluster.equalsIgnoreCase(params.get(REGISTRY_CLUSTER_KEY))) {
- params.put(REGISTRY_CLUSTER_KEY, registryCluster);
- }
- return metadataReport.getAppMetadata(identifier, params);
- }
-
- private void checkRemoteConfigured() {
- if (getMetadataReports().size() == 0) {
- String msg = "Remote Metadata Report Server not hasn't been configured or unavailable . Unable to get Metadata from remote!";
- logger.error(msg);
- throw new IllegalStateException(msg);
- }
- }
-
- public void publishServiceDefinition(URL url) {
- checkRemoteConfigured();
-
- String side = url.getSide();
-
- if (PROVIDER_SIDE.equalsIgnoreCase(side)) {
- //TODO, the params part is duplicate with that stored by exportURL(url), can be further optimized in the future.
- publishProvider(url);
- } else {
- //TODO, only useful for ops showing the url parameters, this is duplicate with subscribeURL(url), can be removed in the future.
- publishConsumer(url);
- }
- }
-
- private void publishProvider(URL providerUrl) throws RpcException {
- //first add into the list
- // remove the individual param
- providerUrl = providerUrl.removeParameters(PID_KEY, TIMESTAMP_KEY, BIND_IP_KEY, BIND_PORT_KEY);
-
- try {
- String interfaceName = providerUrl.getServiceInterface();
- if (StringUtils.isNotEmpty(interfaceName)) {
- ClassLoader classLoader = providerUrl.getServiceModel() != null ?
- providerUrl.getServiceModel().getClassLoader() :
- ClassUtils.getClassLoader();
- Class interfaceClass = Class.forName(interfaceName, false, classLoader);
- FullServiceDefinition fullServiceDefinition = ServiceDefinitionBuilder.buildFullDefinition(interfaceClass,
- providerUrl.getParameters());
- for (Map.Entry<String, MetadataReport> entry : getMetadataReports().entrySet()) {
- MetadataReport metadataReport = entry.getValue();
- metadataReport.storeProviderMetadata(new MetadataIdentifier(providerUrl.getServiceInterface(),
- providerUrl.getVersion(), providerUrl.getGroup(),
- PROVIDER_SIDE, providerUrl.getApplication()), fullServiceDefinition);
- }
- return;
- }
- logger.error("publishProvider interfaceName is empty. providerUrl: " + providerUrl.toFullString());
- } catch (ClassNotFoundException e) {
- //ignore error
- logger.error("publishProvider getServiceDescriptor error. providerUrl: " + providerUrl.toFullString(), e);
- }
- }
-
- private void publishConsumer(URL consumerURL) throws RpcException {
- final URL url = consumerURL.removeParameters(PID_KEY, TIMESTAMP_KEY, BIND_IP_KEY, BIND_PORT_KEY, REGISTER_IP_KEY);
- getMetadataReports().forEach((registryKey, config) -> {
- config.storeConsumerMetadata(new MetadataIdentifier(url.getServiceInterface(),
- url.getVersion(), url.getGroup(), CONSUMER_SIDE,
- url.getApplication()), url.getParameters());
- });
- }
-
-}
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/model/MigrationRule.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/model/MigrationRule.java
index e2f10e4..de42362 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/model/MigrationRule.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/migration/model/MigrationRule.java
@@ -20,6 +20,7 @@ import org.apache.dubbo.common.URL;
import org.apache.dubbo.common.config.ConfigurationUtils;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.metadata.ServiceNameMapping;
+
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.Constructor;
import org.yaml.snakeyaml.constructor.SafeConstructor;
@@ -87,8 +88,6 @@ public class MigrationRule {
private transient Map<String, SubMigrationRule> interfaceRules;
private transient Map<String, SubMigrationRule> applicationRules;
-
-
@SuppressWarnings("unchecked")
private static MigrationRule parseFromMap(Map<String, Object> map) {
MigrationRule migrationRule = new MigrationRule();
@@ -161,7 +160,7 @@ public class MigrationRule {
if (applications != null) {
ServiceNameMapping serviceNameMapping = ServiceNameMapping.getDefaultExtension(consumerURL.getScopeModel());
- Set<String> services = serviceNameMapping.getServices(consumerURL);
+ Set<String> services = serviceNameMapping.getCachedMapping(consumerURL);
if (CollectionUtils.isNotEmpty(services)) {
for (String service : services) {
SubMigrationRule rule = applicationRules.get(service);
@@ -202,7 +201,7 @@ public class MigrationRule {
if (applications != null) {
ServiceNameMapping serviceNameMapping = ServiceNameMapping.getDefaultExtension(consumerURL.getScopeModel());
- Set<String> services = serviceNameMapping.getServices(consumerURL);
+ Set<String> services = serviceNameMapping.getCachedMapping(consumerURL);
if (CollectionUtils.isNotEmpty(services)) {
for (String service : services) {
SubMigrationRule rule = applicationRules.get(service);
@@ -242,7 +241,7 @@ public class MigrationRule {
if (applications != null) {
ServiceNameMapping serviceNameMapping = ServiceNameMapping.getDefaultExtension(consumerURL.getScopeModel());
- Set<String> services = serviceNameMapping.getServices(consumerURL);
+ Set<String> services = serviceNameMapping.getCachedMapping(consumerURL);
if (CollectionUtils.isNotEmpty(services)) {
for (String service : services) {
SubMigrationRule rule = applicationRules.get(service);
@@ -278,7 +277,7 @@ public class MigrationRule {
if (applications != null) {
ServiceNameMapping serviceNameMapping = ServiceNameMapping.getDefaultExtension(consumerURL.getScopeModel());
- Set<String> services = serviceNameMapping.getServices(consumerURL);
+ Set<String> services = serviceNameMapping.getCachedMapping(consumerURL);
if (CollectionUtils.isNotEmpty(services)) {
for (String service : services) {
SubMigrationRule rule = applicationRules.get(service);
@@ -318,7 +317,7 @@ public class MigrationRule {
if (applications != null) {
ServiceNameMapping serviceNameMapping = ServiceNameMapping.getDefaultExtension(consumerURL.getScopeModel());
- Set<String> services = serviceNameMapping.getServices(consumerURL);
+ Set<String> services = serviceNameMapping.getCachedMapping(consumerURL);
if (CollectionUtils.isNotEmpty(services)) {
for (String service : services) {
SubMigrationRule rule = applicationRules.get(service);
@@ -364,7 +363,6 @@ public class MigrationRule {
applicationRules.put(rule.getServiceKey(), rule);
});
}
-
}
public static MigrationRule parse(String rawRule) {
diff --git a/dubbo-registry/dubbo-registry-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.WritableMetadataService b/dubbo-registry/dubbo-registry-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.WritableMetadataService
index 0030270..13b0fd7 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.WritableMetadataService
+++ b/dubbo-registry/dubbo-registry-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.WritableMetadataService
@@ -1 +1 @@
-default=org.apache.dubbo.registry.client.metadata.store.InMemoryWritableMetadataService
\ No newline at end of file
+default=org.apache.dubbo.registry.client.metadata.store.WritableMetadataServiceDelegation
diff --git a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/event/listener/ServiceInstancesChangedListenerTest.java b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/event/listener/ServiceInstancesChangedListenerTest.java
index 042a071..0093a50 100644
--- a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/event/listener/ServiceInstancesChangedListenerTest.java
+++ b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/event/listener/ServiceInstancesChangedListenerTest.java
@@ -1,522 +1,522 @@
-/*
- * 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.event.listener;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.utils.StringUtils;
-import org.apache.dubbo.metadata.MetadataInfo;
-import org.apache.dubbo.metadata.MetadataService;
-import org.apache.dubbo.registry.NotifyListener;
-import org.apache.dubbo.registry.client.DefaultServiceInstance;
-import org.apache.dubbo.registry.client.InstanceAddressURL;
-import org.apache.dubbo.registry.client.ServiceDiscovery;
-import org.apache.dubbo.registry.client.ServiceInstance;
-import org.apache.dubbo.registry.client.event.ServiceInstancesChangedEvent;
-import org.apache.dubbo.registry.client.metadata.MetadataUtils;
-
-import com.google.gson.Gson;
-import org.hamcrest.Matchers;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.MethodOrderer;
-import org.junit.jupiter.api.Order;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.TestMethodOrder;
-import org.mockito.ArgumentCaptor;
-import org.mockito.MockedStatic;
-import org.mockito.Mockito;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.ThreadLocalRandom;
-
-import static org.apache.dubbo.common.constants.CommonConstants.REVISION_KEY;
-import static org.apache.dubbo.common.utils.CollectionUtils.isEmpty;
-import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.EXPORTED_SERVICES_REVISION_PROPERTY_NAME;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.mockito.ArgumentMatchers.eq;
-
-/**
- * {@link ServiceInstancesChangedListener} Test
- *
- * @since 2.7.5
- */
-@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
-public class ServiceInstancesChangedListenerTest {
- private static Gson gson = new Gson();
-
- static List<ServiceInstance> app1Instances;
- static List<ServiceInstance> app2Instances;
- static List<ServiceInstance> app1FailedInstances;
- static List<ServiceInstance> app1FailedInstances2;
- static List<ServiceInstance> app1InstancesWithNoRevision;
-
- static String metadata_111 = "{\"app\":\"app1\",\"revision\":\"111\",\"services\":{"
- + "\"org.apache.dubbo.demo.DemoService:dubbo\":{\"name\":\"org.apache.dubbo.demo.DemoService\",\"protocol\":\"dubbo\",\"path\":\"org.apache.dubbo.demo.DemoService\",\"params\":{\"side\":\"provider\",\"release\":\"\",\"methods\":\"sayHello,sayHelloAsync\",\"deprecated\":\"false\",\"dubbo\":\"2.0.2\",\"pid\":\"72723\",\"interface\":\"org.apache.dubbo.demo.DemoService\",\"service-name-mapping\":\"true\",\"timeout\":\"3000\",\"generic\":\"false\",\"metadata-type\":\"remote\",\"delay\ [...]
- + "}}";
- static String metadata_222 = "{\"app\":\"app2\",\"revision\":\"333\",\"services\":{"
- + "\"org.apache.dubbo.demo.DemoService:dubbo\":{\"name\":\"org.apache.dubbo.demo.DemoService\",\"protocol\":\"dubbo\",\"path\":\"org.apache.dubbo.demo.DemoService\",\"params\":{\"side\":\"provider\",\"release\":\"\",\"methods\":\"sayHello,sayHelloAsync\",\"deprecated\":\"false\",\"dubbo\":\"2.0.2\",\"pid\":\"72723\",\"interface\":\"org.apache.dubbo.demo.DemoService\",\"service-name-mapping\":\"true\",\"timeout\":\"3000\",\"generic\":\"false\",\"metadata-type\":\"remote\",\"delay\ [...]
- + "\"org.apache.dubbo.demo.DemoService2:dubbo\":{\"name\":\"org.apache.dubbo.demo.DemoService2\",\"protocol\":\"dubbo\",\"path\":\"org.apache.dubbo.demo.DemoService2\",\"params\":{\"side\":\"provider\",\"release\":\"\",\"methods\":\"sayHello,sayHelloAsync\",\"deprecated\":\"false\",\"dubbo\":\"2.0.2\",\"pid\":\"72723\",\"interface\":\"org.apache.dubbo.demo.DemoService2\",\"service-name-mapping\":\"true\",\"timeout\":\"3000\",\"generic\":\"false\",\"metadata-type\":\"remote\",\"de [...]
- + "}}";
- static String metadata_333 = "{\"app\":\"app2\",\"revision\":\"333\",\"services\":{"
- + "\"org.apache.dubbo.demo.DemoService:dubbo\":{\"name\":\"org.apache.dubbo.demo.DemoService\",\"protocol\":\"dubbo\",\"path\":\"org.apache.dubbo.demo.DemoService\",\"params\":{\"side\":\"provider\",\"release\":\"\",\"methods\":\"sayHello,sayHelloAsync\",\"deprecated\":\"false\",\"dubbo\":\"2.0.2\",\"pid\":\"72723\",\"interface\":\"org.apache.dubbo.demo.DemoService\",\"service-name-mapping\":\"true\",\"timeout\":\"3000\",\"generic\":\"false\",\"metadata-type\":\"remote\",\"delay\ [...]
- + "\"org.apache.dubbo.demo.DemoService2:dubbo\":{\"name\":\"org.apache.dubbo.demo.DemoService2\",\"protocol\":\"dubbo\",\"path\":\"org.apache.dubbo.demo.DemoService2\",\"params\":{\"side\":\"provider\",\"release\":\"\",\"methods\":\"sayHello,sayHelloAsync\",\"deprecated\":\"false\",\"dubbo\":\"2.0.2\",\"pid\":\"72723\",\"interface\":\"org.apache.dubbo.demo.DemoService2\",\"service-name-mapping\":\"true\",\"timeout\":\"3000\",\"generic\":\"false\",\"metadata-type\":\"remote\",\"de [...]
- + "\"org.apache.dubbo.demo.DemoService3:dubbo\":{\"name\":\"org.apache.dubbo.demo.DemoService3\",\"protocol\":\"dubbo\",\"path\":\"org.apache.dubbo.demo.DemoService3\",\"params\":{\"side\":\"provider\",\"release\":\"\",\"methods\":\"sayHello,sayHelloAsync\",\"deprecated\":\"false\",\"dubbo\":\"2.0.2\",\"pid\":\"72723\",\"interface\":\"org.apache.dubbo.demo.DemoService3\",\"service-name-mapping\":\"true\",\"timeout\":\"3000\",\"generic\":\"false\",\"metadata-type\":\"remote\",\"de [...]
- + "}}";
- // failed
- static String metadata_444 = "{\"app\":\"app1\",\"revision\":\"444\",\"services\":{"
- + "\"org.apache.dubbo.demo.DemoService:dubbo\":{\"name\":\"org.apache.dubbo.demo.DemoService\",\"protocol\":\"dubbo\",\"path\":\"org.apache.dubbo.demo.DemoService\",\"params\":{\"side\":\"provider\",\"release\":\"\",\"methods\":\"sayHello,sayHelloAsync\",\"deprecated\":\"false\",\"dubbo\":\"2.0.2\",\"pid\":\"72723\",\"interface\":\"org.apache.dubbo.demo.DemoService\",\"service-name-mapping\":\"true\",\"timeout\":\"3000\",\"generic\":\"false\",\"metadata-type\":\"remote\",\"delay\ [...]
- + "}}";
-
- static String bad_metadatainfo = "{\"xxx\":\"yyy\"}";
-
- static String service1 = "org.apache.dubbo.demo.DemoService";
- static String service2 = "org.apache.dubbo.demo.DemoService2";
- static String service3 = "org.apache.dubbo.demo.DemoService3";
-
- static URL consumerURL = URL.valueOf("dubbo://127.0.0.1/org.apache.dubbo.demo.DemoService?registry_cluster=default");
-
- static MetadataInfo metadataInfo_111;
- static MetadataInfo metadataInfo_222;
- static MetadataInfo metadataInfo_333;
- static MetadataInfo metadataInfo_444;
-
- static MetadataService metadataService;
-
- static ServiceDiscovery serviceDiscovery;
-
- @BeforeAll
- public static void setUp() {
- List<Object> urlsSameRevision = new ArrayList<>();
- urlsSameRevision.add("127.0.0.1:20880?revision=111");
- urlsSameRevision.add("127.0.0.2:20880?revision=111");
- urlsSameRevision.add("127.0.0.3:20880?revision=111");
-
- List<Object> urlsDifferentRevision = new ArrayList<>();
- urlsDifferentRevision.add("30.10.0.1:20880?revision=222");
- urlsDifferentRevision.add("30.10.0.2:20880?revision=222");
- urlsDifferentRevision.add("30.10.0.3:20880?revision=333");
- urlsDifferentRevision.add("30.10.0.4:20880?revision=333");
-
- List<Object> urlsFailedRevision = new ArrayList<>();
- urlsFailedRevision.add("30.10.0.5:20880?revision=222");
- urlsFailedRevision.add("30.10.0.6:20880?revision=222");
- urlsFailedRevision.add("30.10.0.7:20880?revision=444");// revision will fail
- urlsFailedRevision.add("30.10.0.8:20880?revision=444");// revision will fail
-
- List<Object> urlsFailedRevision2 = new ArrayList<>();
- urlsFailedRevision2.add("30.10.0.1:20880?revision=222");
- urlsFailedRevision2.add("30.10.0.2:20880?revision=222");
-
- List<Object> urlsWithoutRevision = new ArrayList<>();
- urlsWithoutRevision.add("30.10.0.1:20880");
-
- app1Instances = buildInstances(urlsSameRevision);
- app2Instances = buildInstances(urlsDifferentRevision);
- app1FailedInstances = buildInstances(urlsFailedRevision);
- app1FailedInstances2 = buildInstances(urlsFailedRevision2);
- app1InstancesWithNoRevision = buildInstances(urlsWithoutRevision);
-
- metadataInfo_111 = gson.fromJson(metadata_111, MetadataInfo.class);
- metadataInfo_222 = gson.fromJson(metadata_222, MetadataInfo.class);
- metadataInfo_333 = gson.fromJson(metadata_333, MetadataInfo.class);
- metadataInfo_444 = gson.fromJson(metadata_444, MetadataInfo.class);
-
- metadataService = Mockito.mock(MetadataService.class);
- Mockito.doReturn(metadataInfo_111).when(metadataService).getMetadataInfo("111");
- Mockito.doReturn(metadataInfo_222).when(metadataService).getMetadataInfo("222");
- Mockito.doReturn(metadataInfo_333).when(metadataService).getMetadataInfo("333");
- Mockito.doThrow(IllegalStateException.class).when(metadataService).getMetadataInfo("444");
-
- serviceDiscovery = Mockito.mock(ServiceDiscovery.class);
- }
-
- // 正常场景。单应用app1 通知地址基本流程,只做instance-metadata关联,没有metadata内容的解析
- @Test
- @Order(1)
- public void testInstanceNotification() {
- Set<String> serviceNames = new HashSet<>();
- serviceNames.add("app1");
- ServiceDiscovery serviceDiscovery = Mockito.mock(ServiceDiscovery.class);
- ServiceInstancesChangedListener spyListener = Mockito.spy(new ServiceInstancesChangedListener(serviceNames, serviceDiscovery));
- Mockito.doReturn(metadataInfo_111).when(spyListener).getRemoteMetadata(eq("111"), Mockito.anyMap(), Mockito.any());
- ServiceInstancesChangedEvent event = new ServiceInstancesChangedEvent("app1", app1Instances);
- spyListener.onEvent(event);
-
- Map<String, List<ServiceInstance>> allInstances = spyListener.getAllInstances();
- Assertions.assertEquals(1, allInstances.size());
- Assertions.assertEquals(3, allInstances.get("app1").size());
-
- Map<String, MetadataInfo> revisionToMetadata = spyListener.getRevisionToMetadata();
- Assertions.assertEquals(1, revisionToMetadata.size());
- Assertions.assertEquals(metadataInfo_111, revisionToMetadata.get("111"));
-
-// // test app2 notification
-// Mockito.doReturn(metadataInfo_222).when(spyListener).getRemoteMetadata(eq("222"), Mockito.anyMap(), Mockito.anyList());
-// Mockito.doReturn(metadataInfo_333).when(spyListener).getRemoteMetadata(eq("333"), Mockito.anyMap(), Mockito.anyList());
-//
-// ServiceInstancesChangedEvent event_app2 = new ServiceInstancesChangedEvent("app2", app2Instances);
-// spyListener.onEvent(event_app2);
-
- }
-
- // 正常场景。单应用app1,进一步检查 metadata service 是否正确映射
- @Test
- @Order(2)
- public void testInstanceNotificationAndMetadataParse() {
- Set<String> serviceNames = new HashSet<>();
- serviceNames.add("app1");
- ServiceInstancesChangedListener listener = new ServiceInstancesChangedListener(serviceNames, serviceDiscovery);
-
- try (MockedStatic<MetadataUtils> mockedMetadataUtils = Mockito.mockStatic(MetadataUtils.class)) {
- mockedMetadataUtils.when(() -> MetadataUtils.getMetadataServiceProxy(Mockito.any())).thenReturn(metadataService);
- // notify instance change
- ServiceInstancesChangedEvent event = new ServiceInstancesChangedEvent("app1", app1Instances);
- listener.onEvent(event);
-
- Map<String, List<ServiceInstance>> allInstances = listener.getAllInstances();
- Assertions.assertEquals(1, allInstances.size());
- Assertions.assertEquals(3, allInstances.get("app1").size());
-
- Map<String, MetadataInfo> revisionToMetadata = listener.getRevisionToMetadata();
- Assertions.assertEquals(1, revisionToMetadata.size());
- Assertions.assertEquals(metadataInfo_111, revisionToMetadata.get("111"));
-
- List<URL> serviceUrls = listener.getAddresses(service1 + ":dubbo", consumerURL);
- Assertions.assertEquals(3, serviceUrls.size());
- assertTrue(serviceUrls.get(0) instanceof InstanceAddressURL);
-
- assertThat(serviceUrls, Matchers.hasItem(Matchers.hasProperty("instance", Matchers.notNullValue())));
- assertThat(serviceUrls, Matchers.hasItem(Matchers.hasProperty("metadataInfo", Matchers.notNullValue())));
-
- }
- }
-
- // 正常场景。多应用,app1 app2 分别通知地址
- @Test
- @Order(3)
- public void testMultipleAppNotification() {
- Set<String> serviceNames = new HashSet<>();
- serviceNames.add("app1");
- serviceNames.add("app2");
- ServiceInstancesChangedListener listener = new ServiceInstancesChangedListener(serviceNames, serviceDiscovery);
-
- try (MockedStatic<MetadataUtils> mockedMetadataUtils = Mockito.mockStatic(MetadataUtils.class)) {
- mockedMetadataUtils.when(() -> MetadataUtils.getMetadataServiceProxy(Mockito.any())).thenReturn(metadataService);
- // notify app1 instance change
- ServiceInstancesChangedEvent app1_event = new ServiceInstancesChangedEvent("app1", app1Instances);
- listener.onEvent(app1_event);
-
- // notify app2 instance change
- ServiceInstancesChangedEvent app2_event = new ServiceInstancesChangedEvent("app2", app2Instances);
- listener.onEvent(app2_event);
-
- // check
- Map<String, List<ServiceInstance>> allInstances = listener.getAllInstances();
- Assertions.assertEquals(2, allInstances.size());
- Assertions.assertEquals(3, allInstances.get("app1").size());
- Assertions.assertEquals(4, allInstances.get("app2").size());
-
- Map<String, MetadataInfo> revisionToMetadata = listener.getRevisionToMetadata();
- Assertions.assertEquals(3, revisionToMetadata.size());
- Assertions.assertEquals(metadataInfo_111, revisionToMetadata.get("111"));
- Assertions.assertEquals(metadataInfo_222, revisionToMetadata.get("222"));
- Assertions.assertEquals(metadataInfo_333, revisionToMetadata.get("333"));
-
- List<URL> serviceUrls = listener.getAddresses(service1 + ":dubbo", consumerURL);
- Assertions.assertEquals(7, serviceUrls.size());
- List<URL> serviceUrls2 = listener.getAddresses(service2 + ":dubbo", consumerURL);
- Assertions.assertEquals(4, serviceUrls2.size());
- assertTrue(serviceUrls2.get(0).getIp().contains("30.10."));
- List<URL> serviceUrls3 = listener.getAddresses(service3 + ":dubbo", consumerURL);
- Assertions.assertEquals(2, serviceUrls3.size());
- assertTrue(serviceUrls3.get(0).getIp().contains("30.10."));
- }
- }
-
- // 正常场景。多应用,app1 app2,空地址通知(边界条件)能否解析出正确的空地址列表
- @Test
- @Order(4)
- public void testMultipleAppEmptyNotification() {
- Set<String> serviceNames = new HashSet<>();
- serviceNames.add("app1");
- serviceNames.add("app2");
- ServiceInstancesChangedListener listener = new ServiceInstancesChangedListener(serviceNames, serviceDiscovery);
-
- try (MockedStatic<MetadataUtils> mockedMetadataUtils = Mockito.mockStatic(MetadataUtils.class)) {
- mockedMetadataUtils.when(() -> MetadataUtils.getMetadataServiceProxy(Mockito.any())).thenReturn(metadataService);
- // notify app1 instance change
- ServiceInstancesChangedEvent app1_event = new ServiceInstancesChangedEvent("app1", app1Instances);
- listener.onEvent(app1_event);
-
- // notify app2 instance change
- ServiceInstancesChangedEvent app2_event = new ServiceInstancesChangedEvent("app2", app2Instances);
- listener.onEvent(app2_event);
-
- // empty notification
- ServiceInstancesChangedEvent app1_event_again = new ServiceInstancesChangedEvent("app1", Collections.EMPTY_LIST);
- listener.onEvent(app1_event_again);
-
- // check app1 cleared
- Map<String, List<ServiceInstance>> allInstances = listener.getAllInstances();
- Assertions.assertEquals(2, allInstances.size());
- Assertions.assertEquals(0, allInstances.get("app1").size());
- Assertions.assertEquals(4, allInstances.get("app2").size());
-
- Map<String, MetadataInfo> revisionToMetadata = listener.getRevisionToMetadata();
- Assertions.assertEquals(2, revisionToMetadata.size());
- Assertions.assertNull(revisionToMetadata.get("111"));
- Assertions.assertEquals(metadataInfo_222, revisionToMetadata.get("222"));
- Assertions.assertEquals(metadataInfo_333, revisionToMetadata.get("333"));
-
- List<URL> serviceUrls = listener.getAddresses(service1 + ":dubbo", consumerURL);
- Assertions.assertEquals(4, serviceUrls.size());
- assertTrue(serviceUrls.get(0).getIp().contains("30.10."));
- List<URL> serviceUrls2 = listener.getAddresses(service2 + ":dubbo", consumerURL);
- Assertions.assertEquals(4, serviceUrls2.size());
- assertTrue(serviceUrls2.get(0).getIp().contains("30.10."));
- List<URL> serviceUrls3 = listener.getAddresses(service3 + ":dubbo", consumerURL);
- Assertions.assertEquals(2, serviceUrls3.size());
- assertTrue(serviceUrls3.get(0).getIp().contains("30.10."));
-
- // app2 empty notification
- ServiceInstancesChangedEvent app2_event_again = new ServiceInstancesChangedEvent("app2", Collections.EMPTY_LIST);
- listener.onEvent(app2_event_again);
-
- // check app2 cleared
- Map<String, List<ServiceInstance>> allInstances_app2 = listener.getAllInstances();
- Assertions.assertEquals(2, allInstances_app2.size());
- Assertions.assertEquals(0, allInstances_app2.get("app1").size());
- Assertions.assertEquals(0, allInstances_app2.get("app2").size());
-
- Map<String, MetadataInfo> revisionToMetadata_app2 = listener.getRevisionToMetadata();
- Assertions.assertEquals(0, revisionToMetadata_app2.size());
-
- assertTrue(isEmpty(listener.getAddresses(service1 + ":dubbo", consumerURL)));
- assertTrue(isEmpty(listener.getAddresses(service2+ ":dubbo", consumerURL)));
- assertTrue(isEmpty(listener.getAddresses(service3 + ":dubbo", consumerURL)));
- }
- }
-
- // 正常场景。检查instance listener -> service listener(Directory)地址推送流程
- @Test
- @Order(5)
- public void testServiceListenerNotification() {
- Set<String> serviceNames = new HashSet<>();
- serviceNames.add("app1");
- serviceNames.add("app2");
- ServiceInstancesChangedListener listener = new ServiceInstancesChangedListener(serviceNames, serviceDiscovery);
- NotifyListener demoServiceListener = Mockito.mock(NotifyListener.class);
- NotifyListener demoService2Listener = Mockito.mock(NotifyListener.class);
- listener.addListenerAndNotify(service1 + ":dubbo", demoServiceListener);
- listener.addListenerAndNotify(service2 + ":dubbo", demoService2Listener);
-
- try (MockedStatic<MetadataUtils> mockedMetadataUtils = Mockito.mockStatic(MetadataUtils.class)) {
- mockedMetadataUtils.when(() -> MetadataUtils.getMetadataServiceProxy(Mockito.any())).thenReturn(metadataService);
- // notify app1 instance change
- ServiceInstancesChangedEvent app1_event = new ServiceInstancesChangedEvent("app1", app1Instances);
- listener.onEvent(app1_event);
-
- // check
- ArgumentCaptor<List<URL>> captor = ArgumentCaptor.forClass(List.class);
- Mockito.verify(demoServiceListener, Mockito.times(1)).notify(captor.capture());
- List<URL> notifiedUrls = captor.getValue();
- Assertions.assertEquals(3, notifiedUrls.size());
- ArgumentCaptor<List<URL>> captor2 = ArgumentCaptor.forClass(List.class);
- Mockito.verify(demoService2Listener, Mockito.times(1)).notify(captor2.capture());
- List<URL> notifiedUrls2 = captor2.getValue();
- Assertions.assertEquals(0, notifiedUrls2.size());
-
- // notify app2 instance change
- ServiceInstancesChangedEvent app2_event = new ServiceInstancesChangedEvent("app2", app2Instances);
- listener.onEvent(app2_event);
-
- // check
- ArgumentCaptor<List<URL>> app2_captor = ArgumentCaptor.forClass(List.class);
- Mockito.verify(demoServiceListener, Mockito.times(2)).notify(app2_captor.capture());
- List<URL> app2_notifiedUrls = app2_captor.getValue();
- Assertions.assertEquals(7, app2_notifiedUrls.size());
- ArgumentCaptor<List<URL>> app2_captor2 = ArgumentCaptor.forClass(List.class);
- Mockito.verify(demoService2Listener, Mockito.times(2)).notify(app2_captor2.capture());
- List<URL> app2_notifiedUrls2 = app2_captor2.getValue();
- Assertions.assertEquals(4, app2_notifiedUrls2.size());
- }
-
- // test service listener still get notified when added after instance notification.
- NotifyListener demoService3Listener = Mockito.mock(NotifyListener.class);
- listener.addListenerAndNotify(service3 + ":dubbo", demoService3Listener);
- Mockito.verify(demoService3Listener, Mockito.times(1)).notify(Mockito.anyList());
- }
-
- // revision 异常场景。第一次启动,完全拿不到metadata,只能通知部分地址
- @Test
- @Order(6)
- public void testRevisionFailureOnStartup() {
- Set<String> serviceNames = new HashSet<>();
- serviceNames.add("app1");
- ServiceInstancesChangedListener listener = new ServiceInstancesChangedListener(serviceNames, serviceDiscovery);
- try (MockedStatic<MetadataUtils> mockedMetadataUtils = Mockito.mockStatic(MetadataUtils.class)) {
- mockedMetadataUtils.when(() -> MetadataUtils.getMetadataServiceProxy(Mockito.any())).thenReturn(metadataService);
- // notify app1 instance change
- ServiceInstancesChangedEvent failed_revision_event = new ServiceInstancesChangedEvent("app1", app1FailedInstances);
- listener.onEvent(failed_revision_event);
-
- List<URL> serviceUrls = listener.getAddresses(service1 + ":dubbo", consumerURL);
- List<URL> serviceUrls2 = listener.getAddresses(service2 + ":dubbo", consumerURL);
-
- assertTrue(isEmpty(serviceUrls));
- assertTrue(isEmpty(serviceUrls2));
-
- Map<String, MetadataInfo> revisionToMetadata = listener.getRevisionToMetadata();
- Assertions.assertEquals(2, revisionToMetadata.size());
- Assertions.assertEquals(metadataInfo_222, revisionToMetadata.get("222"));
- Assertions.assertEquals(MetadataInfo.EMPTY, revisionToMetadata.get("444"));
- }
- }
-
- // revision 异常场景。运行中地址通知,拿不到revision就用老版本revision
- @Test
- public void testRevisionFailureOnNotification() {
- Set<String> serviceNames = new HashSet<>();
- serviceNames.add("app1");
- serviceNames.add("app2");
- ServiceInstancesChangedListener listener = new ServiceInstancesChangedListener(serviceNames, serviceDiscovery);
-
- ConcurrentMap tmpProxyMap = MetadataUtils.metadataServiceProxies;
-
- try (MockedStatic<MetadataUtils> mockedMetadataUtils = Mockito.mockStatic(MetadataUtils.class)) {
- mockedMetadataUtils.when(() -> MetadataUtils.getMetadataServiceProxy(Mockito.any())).thenReturn(metadataService);
-
- // notify app1 instance change
- ServiceInstancesChangedEvent event = new ServiceInstancesChangedEvent("app1", app1Instances);
- listener.onEvent(event);
-
- Mockito.when(metadataService.getMetadataInfo("222")).thenAnswer(new Answer<MetadataInfo>() {
- @Override
- public MetadataInfo answer(InvocationOnMock invocationOnMock) throws Throwable {
- if (Thread.currentThread().getName().contains("Dubbo-metadata-retry")) {
- return metadataInfo_222;
- }
- return null;
- }
- });
-// Mockito.when(metadataService.getMetadataInfo("444")).thenAnswer(new Answer<MetadataInfo>() {
+///*
+// * 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.event.listener;
+//
+//import org.apache.dubbo.common.URL;
+//import org.apache.dubbo.common.utils.StringUtils;
+//import org.apache.dubbo.metadata.MetadataInfo;
+//import org.apache.dubbo.metadata.MetadataService;
+//import org.apache.dubbo.registry.NotifyListener;
+//import org.apache.dubbo.registry.client.DefaultServiceInstance;
+//import org.apache.dubbo.registry.client.InstanceAddressURL;
+//import org.apache.dubbo.registry.client.ServiceDiscovery;
+//import org.apache.dubbo.registry.client.ServiceInstance;
+//import org.apache.dubbo.registry.client.event.ServiceInstancesChangedEvent;
+//import org.apache.dubbo.registry.client.metadata.MetadataUtils;
+//
+//import com.google.gson.Gson;
+//import org.hamcrest.Matchers;
+//import org.junit.jupiter.api.Assertions;
+//import org.junit.jupiter.api.BeforeAll;
+//import org.junit.jupiter.api.MethodOrderer;
+//import org.junit.jupiter.api.Order;
+//import org.junit.jupiter.api.Test;
+//import org.junit.jupiter.api.TestMethodOrder;
+//import org.mockito.ArgumentCaptor;
+//import org.mockito.MockedStatic;
+//import org.mockito.Mockito;
+//import org.mockito.invocation.InvocationOnMock;
+//import org.mockito.stubbing.Answer;
+//
+//import java.util.ArrayList;
+//import java.util.Collections;
+//import java.util.HashMap;
+//import java.util.HashSet;
+//import java.util.List;
+//import java.util.Map;
+//import java.util.Set;
+//import java.util.concurrent.ConcurrentMap;
+//import java.util.concurrent.ThreadLocalRandom;
+//
+//import static org.apache.dubbo.common.constants.CommonConstants.REVISION_KEY;
+//import static org.apache.dubbo.common.utils.CollectionUtils.isEmpty;
+//import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.EXPORTED_SERVICES_REVISION_PROPERTY_NAME;
+//import static org.hamcrest.MatcherAssert.assertThat;
+//import static org.junit.jupiter.api.Assertions.assertTrue;
+//import static org.mockito.ArgumentMatchers.eq;
+//
+///**
+// * {@link ServiceInstancesChangedListener} Test
+// *
+// * @since 2.7.5
+// */
+//@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
+//public class ServiceInstancesChangedListenerTest {
+// private static Gson gson = new Gson();
+//
+// static List<ServiceInstance> app1Instances;
+// static List<ServiceInstance> app2Instances;
+// static List<ServiceInstance> app1FailedInstances;
+// static List<ServiceInstance> app1FailedInstances2;
+// static List<ServiceInstance> app1InstancesWithNoRevision;
+//
+// static String metadata_111 = "{\"app\":\"app1\",\"revision\":\"111\",\"services\":{"
+// + "\"org.apache.dubbo.demo.DemoService:dubbo\":{\"name\":\"org.apache.dubbo.demo.DemoService\",\"protocol\":\"dubbo\",\"path\":\"org.apache.dubbo.demo.DemoService\",\"params\":{\"side\":\"provider\",\"release\":\"\",\"methods\":\"sayHello,sayHelloAsync\",\"deprecated\":\"false\",\"dubbo\":\"2.0.2\",\"pid\":\"72723\",\"interface\":\"org.apache.dubbo.demo.DemoService\",\"service-name-mapping\":\"true\",\"timeout\":\"3000\",\"generic\":\"false\",\"metadata-type\":\"remote\",\"dela [...]
+// + "}}";
+// static String metadata_222 = "{\"app\":\"app2\",\"revision\":\"333\",\"services\":{"
+// + "\"org.apache.dubbo.demo.DemoService:dubbo\":{\"name\":\"org.apache.dubbo.demo.DemoService\",\"protocol\":\"dubbo\",\"path\":\"org.apache.dubbo.demo.DemoService\",\"params\":{\"side\":\"provider\",\"release\":\"\",\"methods\":\"sayHello,sayHelloAsync\",\"deprecated\":\"false\",\"dubbo\":\"2.0.2\",\"pid\":\"72723\",\"interface\":\"org.apache.dubbo.demo.DemoService\",\"service-name-mapping\":\"true\",\"timeout\":\"3000\",\"generic\":\"false\",\"metadata-type\":\"remote\",\"dela [...]
+// + "\"org.apache.dubbo.demo.DemoService2:dubbo\":{\"name\":\"org.apache.dubbo.demo.DemoService2\",\"protocol\":\"dubbo\",\"path\":\"org.apache.dubbo.demo.DemoService2\",\"params\":{\"side\":\"provider\",\"release\":\"\",\"methods\":\"sayHello,sayHelloAsync\",\"deprecated\":\"false\",\"dubbo\":\"2.0.2\",\"pid\":\"72723\",\"interface\":\"org.apache.dubbo.demo.DemoService2\",\"service-name-mapping\":\"true\",\"timeout\":\"3000\",\"generic\":\"false\",\"metadata-type\":\"remote\",\" [...]
+// + "}}";
+// static String metadata_333 = "{\"app\":\"app2\",\"revision\":\"333\",\"services\":{"
+// + "\"org.apache.dubbo.demo.DemoService:dubbo\":{\"name\":\"org.apache.dubbo.demo.DemoService\",\"protocol\":\"dubbo\",\"path\":\"org.apache.dubbo.demo.DemoService\",\"params\":{\"side\":\"provider\",\"release\":\"\",\"methods\":\"sayHello,sayHelloAsync\",\"deprecated\":\"false\",\"dubbo\":\"2.0.2\",\"pid\":\"72723\",\"interface\":\"org.apache.dubbo.demo.DemoService\",\"service-name-mapping\":\"true\",\"timeout\":\"3000\",\"generic\":\"false\",\"metadata-type\":\"remote\",\"dela [...]
+// + "\"org.apache.dubbo.demo.DemoService2:dubbo\":{\"name\":\"org.apache.dubbo.demo.DemoService2\",\"protocol\":\"dubbo\",\"path\":\"org.apache.dubbo.demo.DemoService2\",\"params\":{\"side\":\"provider\",\"release\":\"\",\"methods\":\"sayHello,sayHelloAsync\",\"deprecated\":\"false\",\"dubbo\":\"2.0.2\",\"pid\":\"72723\",\"interface\":\"org.apache.dubbo.demo.DemoService2\",\"service-name-mapping\":\"true\",\"timeout\":\"3000\",\"generic\":\"false\",\"metadata-type\":\"remote\",\" [...]
+// + "\"org.apache.dubbo.demo.DemoService3:dubbo\":{\"name\":\"org.apache.dubbo.demo.DemoService3\",\"protocol\":\"dubbo\",\"path\":\"org.apache.dubbo.demo.DemoService3\",\"params\":{\"side\":\"provider\",\"release\":\"\",\"methods\":\"sayHello,sayHelloAsync\",\"deprecated\":\"false\",\"dubbo\":\"2.0.2\",\"pid\":\"72723\",\"interface\":\"org.apache.dubbo.demo.DemoService3\",\"service-name-mapping\":\"true\",\"timeout\":\"3000\",\"generic\":\"false\",\"metadata-type\":\"remote\",\" [...]
+// + "}}";
+// // failed
+// static String metadata_444 = "{\"app\":\"app1\",\"revision\":\"444\",\"services\":{"
+// + "\"org.apache.dubbo.demo.DemoService:dubbo\":{\"name\":\"org.apache.dubbo.demo.DemoService\",\"protocol\":\"dubbo\",\"path\":\"org.apache.dubbo.demo.DemoService\",\"params\":{\"side\":\"provider\",\"release\":\"\",\"methods\":\"sayHello,sayHelloAsync\",\"deprecated\":\"false\",\"dubbo\":\"2.0.2\",\"pid\":\"72723\",\"interface\":\"org.apache.dubbo.demo.DemoService\",\"service-name-mapping\":\"true\",\"timeout\":\"3000\",\"generic\":\"false\",\"metadata-type\":\"remote\",\"dela [...]
+// + "}}";
+//
+// static String bad_metadatainfo = "{\"xxx\":\"yyy\"}";
+//
+// static String service1 = "org.apache.dubbo.demo.DemoService";
+// static String service2 = "org.apache.dubbo.demo.DemoService2";
+// static String service3 = "org.apache.dubbo.demo.DemoService3";
+//
+// static URL consumerURL = URL.valueOf("dubbo://127.0.0.1/org.apache.dubbo.demo.DemoService?registry_cluster=default");
+//
+// static MetadataInfo metadataInfo_111;
+// static MetadataInfo metadataInfo_222;
+// static MetadataInfo metadataInfo_333;
+// static MetadataInfo metadataInfo_444;
+//
+// static MetadataService metadataService;
+//
+// static ServiceDiscovery serviceDiscovery;
+//
+// @BeforeAll
+// public static void setUp() {
+// List<Object> urlsSameRevision = new ArrayList<>();
+// urlsSameRevision.add("127.0.0.1:20880?revision=111");
+// urlsSameRevision.add("127.0.0.2:20880?revision=111");
+// urlsSameRevision.add("127.0.0.3:20880?revision=111");
+//
+// List<Object> urlsDifferentRevision = new ArrayList<>();
+// urlsDifferentRevision.add("30.10.0.1:20880?revision=222");
+// urlsDifferentRevision.add("30.10.0.2:20880?revision=222");
+// urlsDifferentRevision.add("30.10.0.3:20880?revision=333");
+// urlsDifferentRevision.add("30.10.0.4:20880?revision=333");
+//
+// List<Object> urlsFailedRevision = new ArrayList<>();
+// urlsFailedRevision.add("30.10.0.5:20880?revision=222");
+// urlsFailedRevision.add("30.10.0.6:20880?revision=222");
+// urlsFailedRevision.add("30.10.0.7:20880?revision=444");// revision will fail
+// urlsFailedRevision.add("30.10.0.8:20880?revision=444");// revision will fail
+//
+// List<Object> urlsFailedRevision2 = new ArrayList<>();
+// urlsFailedRevision2.add("30.10.0.1:20880?revision=222");
+// urlsFailedRevision2.add("30.10.0.2:20880?revision=222");
+//
+// List<Object> urlsWithoutRevision = new ArrayList<>();
+// urlsWithoutRevision.add("30.10.0.1:20880");
+//
+// app1Instances = buildInstances(urlsSameRevision);
+// app2Instances = buildInstances(urlsDifferentRevision);
+// app1FailedInstances = buildInstances(urlsFailedRevision);
+// app1FailedInstances2 = buildInstances(urlsFailedRevision2);
+// app1InstancesWithNoRevision = buildInstances(urlsWithoutRevision);
+//
+// metadataInfo_111 = gson.fromJson(metadata_111, MetadataInfo.class);
+// metadataInfo_222 = gson.fromJson(metadata_222, MetadataInfo.class);
+// metadataInfo_333 = gson.fromJson(metadata_333, MetadataInfo.class);
+// metadataInfo_444 = gson.fromJson(metadata_444, MetadataInfo.class);
+//
+// metadataService = Mockito.mock(MetadataService.class);
+// Mockito.doReturn(metadataInfo_111).when(metadataService).getMetadataInfo("111");
+// Mockito.doReturn(metadataInfo_222).when(metadataService).getMetadataInfo("222");
+// Mockito.doReturn(metadataInfo_333).when(metadataService).getMetadataInfo("333");
+// Mockito.doThrow(IllegalStateException.class).when(metadataService).getMetadataInfo("444");
+//
+// serviceDiscovery = Mockito.mock(ServiceDiscovery.class);
+// }
+//
+// // 正常场景。单应用app1 通知地址基本流程,只做instance-metadata关联,没有metadata内容的解析
+// @Test
+// @Order(1)
+// public void testInstanceNotification() {
+// Set<String> serviceNames = new HashSet<>();
+// serviceNames.add("app1");
+// ServiceDiscovery serviceDiscovery = Mockito.mock(ServiceDiscovery.class);
+// ServiceInstancesChangedListener spyListener = Mockito.spy(new ServiceInstancesChangedListener(serviceNames, serviceDiscovery));
+// Mockito.doReturn(metadataInfo_111).when(spyListener).getRemoteMetadata(eq("111"), Mockito.anyMap(), Mockito.any());
+// ServiceInstancesChangedEvent event = new ServiceInstancesChangedEvent("app1", app1Instances);
+// spyListener.onEvent(event);
+//
+// Map<String, List<ServiceInstance>> allInstances = spyListener.getAllInstances();
+// Assertions.assertEquals(1, allInstances.size());
+// Assertions.assertEquals(3, allInstances.get("app1").size());
+//
+// Map<String, MetadataInfo> revisionToMetadata = spyListener.getRevisionToMetadata();
+// Assertions.assertEquals(1, revisionToMetadata.size());
+// Assertions.assertEquals(metadataInfo_111, revisionToMetadata.get("111"));
+//
+//// // test app2 notification
+//// Mockito.doReturn(metadataInfo_222).when(spyListener).getRemoteMetadata(eq("222"), Mockito.anyMap(), Mockito.anyList());
+//// Mockito.doReturn(metadataInfo_333).when(spyListener).getRemoteMetadata(eq("333"), Mockito.anyMap(), Mockito.anyList());
+////
+//// ServiceInstancesChangedEvent event_app2 = new ServiceInstancesChangedEvent("app2", app2Instances);
+//// spyListener.onEvent(event_app2);
+//
+// }
+//
+// // 正常场景。单应用app1,进一步检查 metadata service 是否正确映射
+// @Test
+// @Order(2)
+// public void testInstanceNotificationAndMetadataParse() {
+// Set<String> serviceNames = new HashSet<>();
+// serviceNames.add("app1");
+// ServiceInstancesChangedListener listener = new ServiceInstancesChangedListener(serviceNames, serviceDiscovery);
+//
+// try (MockedStatic<MetadataUtils> mockedMetadataUtils = Mockito.mockStatic(MetadataUtils.class)) {
+// mockedMetadataUtils.when(() -> MetadataUtils.getMetadataServiceProxy(Mockito.any())).thenReturn(metadataService);
+// // notify instance change
+// ServiceInstancesChangedEvent event = new ServiceInstancesChangedEvent("app1", app1Instances);
+// listener.onEvent(event);
+//
+// Map<String, List<ServiceInstance>> allInstances = listener.getAllInstances();
+// Assertions.assertEquals(1, allInstances.size());
+// Assertions.assertEquals(3, allInstances.get("app1").size());
+//
+// Map<String, MetadataInfo> revisionToMetadata = listener.getRevisionToMetadata();
+// Assertions.assertEquals(1, revisionToMetadata.size());
+// Assertions.assertEquals(metadataInfo_111, revisionToMetadata.get("111"));
+//
+// List<URL> serviceUrls = listener.getAddresses(service1 + ":dubbo", consumerURL);
+// Assertions.assertEquals(3, serviceUrls.size());
+// assertTrue(serviceUrls.get(0) instanceof InstanceAddressURL);
+//
+// assertThat(serviceUrls, Matchers.hasItem(Matchers.hasProperty("instance", Matchers.notNullValue())));
+// assertThat(serviceUrls, Matchers.hasItem(Matchers.hasProperty("metadataInfo", Matchers.notNullValue())));
+//
+// }
+// }
+//
+// // 正常场景。多应用,app1 app2 分别通知地址
+// @Test
+// @Order(3)
+// public void testMultipleAppNotification() {
+// Set<String> serviceNames = new HashSet<>();
+// serviceNames.add("app1");
+// serviceNames.add("app2");
+// ServiceInstancesChangedListener listener = new ServiceInstancesChangedListener(serviceNames, serviceDiscovery);
+//
+// try (MockedStatic<MetadataUtils> mockedMetadataUtils = Mockito.mockStatic(MetadataUtils.class)) {
+// mockedMetadataUtils.when(() -> MetadataUtils.getMetadataServiceProxy(Mockito.any())).thenReturn(metadataService);
+// // notify app1 instance change
+// ServiceInstancesChangedEvent app1_event = new ServiceInstancesChangedEvent("app1", app1Instances);
+// listener.onEvent(app1_event);
+//
+// // notify app2 instance change
+// ServiceInstancesChangedEvent app2_event = new ServiceInstancesChangedEvent("app2", app2Instances);
+// listener.onEvent(app2_event);
+//
+// // check
+// Map<String, List<ServiceInstance>> allInstances = listener.getAllInstances();
+// Assertions.assertEquals(2, allInstances.size());
+// Assertions.assertEquals(3, allInstances.get("app1").size());
+// Assertions.assertEquals(4, allInstances.get("app2").size());
+//
+// Map<String, MetadataInfo> revisionToMetadata = listener.getRevisionToMetadata();
+// Assertions.assertEquals(3, revisionToMetadata.size());
+// Assertions.assertEquals(metadataInfo_111, revisionToMetadata.get("111"));
+// Assertions.assertEquals(metadataInfo_222, revisionToMetadata.get("222"));
+// Assertions.assertEquals(metadataInfo_333, revisionToMetadata.get("333"));
+//
+// List<URL> serviceUrls = listener.getAddresses(service1 + ":dubbo", consumerURL);
+// Assertions.assertEquals(7, serviceUrls.size());
+// List<URL> serviceUrls2 = listener.getAddresses(service2 + ":dubbo", consumerURL);
+// Assertions.assertEquals(4, serviceUrls2.size());
+// assertTrue(serviceUrls2.get(0).getIp().contains("30.10."));
+// List<URL> serviceUrls3 = listener.getAddresses(service3 + ":dubbo", consumerURL);
+// Assertions.assertEquals(2, serviceUrls3.size());
+// assertTrue(serviceUrls3.get(0).getIp().contains("30.10."));
+// }
+// }
+//
+// // 正常场景。多应用,app1 app2,空地址通知(边界条件)能否解析出正确的空地址列表
+// @Test
+// @Order(4)
+// public void testMultipleAppEmptyNotification() {
+// Set<String> serviceNames = new HashSet<>();
+// serviceNames.add("app1");
+// serviceNames.add("app2");
+// ServiceInstancesChangedListener listener = new ServiceInstancesChangedListener(serviceNames, serviceDiscovery);
+//
+// try (MockedStatic<MetadataUtils> mockedMetadataUtils = Mockito.mockStatic(MetadataUtils.class)) {
+// mockedMetadataUtils.when(() -> MetadataUtils.getMetadataServiceProxy(Mockito.any())).thenReturn(metadataService);
+// // notify app1 instance change
+// ServiceInstancesChangedEvent app1_event = new ServiceInstancesChangedEvent("app1", app1Instances);
+// listener.onEvent(app1_event);
+//
+// // notify app2 instance change
+// ServiceInstancesChangedEvent app2_event = new ServiceInstancesChangedEvent("app2", app2Instances);
+// listener.onEvent(app2_event);
+//
+// // empty notification
+// ServiceInstancesChangedEvent app1_event_again = new ServiceInstancesChangedEvent("app1", Collections.EMPTY_LIST);
+// listener.onEvent(app1_event_again);
+//
+// // check app1 cleared
+// Map<String, List<ServiceInstance>> allInstances = listener.getAllInstances();
+// Assertions.assertEquals(2, allInstances.size());
+// Assertions.assertEquals(0, allInstances.get("app1").size());
+// Assertions.assertEquals(4, allInstances.get("app2").size());
+//
+// Map<String, MetadataInfo> revisionToMetadata = listener.getRevisionToMetadata();
+// Assertions.assertEquals(2, revisionToMetadata.size());
+// Assertions.assertNull(revisionToMetadata.get("111"));
+// Assertions.assertEquals(metadataInfo_222, revisionToMetadata.get("222"));
+// Assertions.assertEquals(metadataInfo_333, revisionToMetadata.get("333"));
+//
+// List<URL> serviceUrls = listener.getAddresses(service1 + ":dubbo", consumerURL);
+// Assertions.assertEquals(4, serviceUrls.size());
+// assertTrue(serviceUrls.get(0).getIp().contains("30.10."));
+// List<URL> serviceUrls2 = listener.getAddresses(service2 + ":dubbo", consumerURL);
+// Assertions.assertEquals(4, serviceUrls2.size());
+// assertTrue(serviceUrls2.get(0).getIp().contains("30.10."));
+// List<URL> serviceUrls3 = listener.getAddresses(service3 + ":dubbo", consumerURL);
+// Assertions.assertEquals(2, serviceUrls3.size());
+// assertTrue(serviceUrls3.get(0).getIp().contains("30.10."));
+//
+// // app2 empty notification
+// ServiceInstancesChangedEvent app2_event_again = new ServiceInstancesChangedEvent("app2", Collections.EMPTY_LIST);
+// listener.onEvent(app2_event_again);
+//
+// // check app2 cleared
+// Map<String, List<ServiceInstance>> allInstances_app2 = listener.getAllInstances();
+// Assertions.assertEquals(2, allInstances_app2.size());
+// Assertions.assertEquals(0, allInstances_app2.get("app1").size());
+// Assertions.assertEquals(0, allInstances_app2.get("app2").size());
+//
+// Map<String, MetadataInfo> revisionToMetadata_app2 = listener.getRevisionToMetadata();
+// Assertions.assertEquals(0, revisionToMetadata_app2.size());
+//
+// assertTrue(isEmpty(listener.getAddresses(service1 + ":dubbo", consumerURL)));
+// assertTrue(isEmpty(listener.getAddresses(service2+ ":dubbo", consumerURL)));
+// assertTrue(isEmpty(listener.getAddresses(service3 + ":dubbo", consumerURL)));
+// }
+// }
+//
+// // 正常场景。检查instance listener -> service listener(Directory)地址推送流程
+// @Test
+// @Order(5)
+// public void testServiceListenerNotification() {
+// Set<String> serviceNames = new HashSet<>();
+// serviceNames.add("app1");
+// serviceNames.add("app2");
+// ServiceInstancesChangedListener listener = new ServiceInstancesChangedListener(serviceNames, serviceDiscovery);
+// NotifyListener demoServiceListener = Mockito.mock(NotifyListener.class);
+// NotifyListener demoService2Listener = Mockito.mock(NotifyListener.class);
+// listener.addListenerAndNotify(service1 + ":dubbo", demoServiceListener);
+// listener.addListenerAndNotify(service2 + ":dubbo", demoService2Listener);
+//
+// try (MockedStatic<MetadataUtils> mockedMetadataUtils = Mockito.mockStatic(MetadataUtils.class)) {
+// mockedMetadataUtils.when(() -> MetadataUtils.getMetadataServiceProxy(Mockito.any())).thenReturn(metadataService);
+// // notify app1 instance change
+// ServiceInstancesChangedEvent app1_event = new ServiceInstancesChangedEvent("app1", app1Instances);
+// listener.onEvent(app1_event);
+//
+// // check
+// ArgumentCaptor<List<URL>> captor = ArgumentCaptor.forClass(List.class);
+// Mockito.verify(demoServiceListener, Mockito.times(1)).notify(captor.capture());
+// List<URL> notifiedUrls = captor.getValue();
+// Assertions.assertEquals(3, notifiedUrls.size());
+// ArgumentCaptor<List<URL>> captor2 = ArgumentCaptor.forClass(List.class);
+// Mockito.verify(demoService2Listener, Mockito.times(1)).notify(captor2.capture());
+// List<URL> notifiedUrls2 = captor2.getValue();
+// Assertions.assertEquals(0, notifiedUrls2.size());
+//
+// // notify app2 instance change
+// ServiceInstancesChangedEvent app2_event = new ServiceInstancesChangedEvent("app2", app2Instances);
+// listener.onEvent(app2_event);
+//
+// // check
+// ArgumentCaptor<List<URL>> app2_captor = ArgumentCaptor.forClass(List.class);
+// Mockito.verify(demoServiceListener, Mockito.times(2)).notify(app2_captor.capture());
+// List<URL> app2_notifiedUrls = app2_captor.getValue();
+// Assertions.assertEquals(7, app2_notifiedUrls.size());
+// ArgumentCaptor<List<URL>> app2_captor2 = ArgumentCaptor.forClass(List.class);
+// Mockito.verify(demoService2Listener, Mockito.times(2)).notify(app2_captor2.capture());
+// List<URL> app2_notifiedUrls2 = app2_captor2.getValue();
+// Assertions.assertEquals(4, app2_notifiedUrls2.size());
+// }
+//
+// // test service listener still get notified when added after instance notification.
+// NotifyListener demoService3Listener = Mockito.mock(NotifyListener.class);
+// listener.addListenerAndNotify(service3 + ":dubbo", demoService3Listener);
+// Mockito.verify(demoService3Listener, Mockito.times(1)).notify(Mockito.anyList());
+// }
+//
+// // revision 异常场景。第一次启动,完全拿不到metadata,只能通知部分地址
+// @Test
+// @Order(6)
+// public void testRevisionFailureOnStartup() {
+// Set<String> serviceNames = new HashSet<>();
+// serviceNames.add("app1");
+// ServiceInstancesChangedListener listener = new ServiceInstancesChangedListener(serviceNames, serviceDiscovery);
+// try (MockedStatic<MetadataUtils> mockedMetadataUtils = Mockito.mockStatic(MetadataUtils.class)) {
+// mockedMetadataUtils.when(() -> MetadataUtils.getMetadataServiceProxy(Mockito.any())).thenReturn(metadataService);
+// // notify app1 instance change
+// ServiceInstancesChangedEvent failed_revision_event = new ServiceInstancesChangedEvent("app1", app1FailedInstances);
+// listener.onEvent(failed_revision_event);
+//
+// List<URL> serviceUrls = listener.getAddresses(service1 + ":dubbo", consumerURL);
+// List<URL> serviceUrls2 = listener.getAddresses(service2 + ":dubbo", consumerURL);
+//
+// assertTrue(isEmpty(serviceUrls));
+// assertTrue(isEmpty(serviceUrls2));
+//
+// Map<String, MetadataInfo> revisionToMetadata = listener.getRevisionToMetadata();
+// Assertions.assertEquals(2, revisionToMetadata.size());
+// Assertions.assertEquals(metadataInfo_222, revisionToMetadata.get("222"));
+// Assertions.assertEquals(MetadataInfo.EMPTY, revisionToMetadata.get("444"));
+// }
+// }
+//
+// // revision 异常场景。运行中地址通知,拿不到revision就用老版本revision
+// @Test
+// public void testRevisionFailureOnNotification() {
+// Set<String> serviceNames = new HashSet<>();
+// serviceNames.add("app1");
+// serviceNames.add("app2");
+// ServiceInstancesChangedListener listener = new ServiceInstancesChangedListener(serviceNames, serviceDiscovery);
+//
+// ConcurrentMap tmpProxyMap = MetadataUtils.metadataServiceProxies;
+//
+// try (MockedStatic<MetadataUtils> mockedMetadataUtils = Mockito.mockStatic(MetadataUtils.class)) {
+// mockedMetadataUtils.when(() -> MetadataUtils.getMetadataServiceProxy(Mockito.any())).thenReturn(metadataService);
+//
+// // notify app1 instance change
+// ServiceInstancesChangedEvent event = new ServiceInstancesChangedEvent("app1", app1Instances);
+// listener.onEvent(event);
+//
+// Mockito.when(metadataService.getMetadataInfo("222")).thenAnswer(new Answer<MetadataInfo>() {
// @Override
// public MetadataInfo answer(InvocationOnMock invocationOnMock) throws Throwable {
// if (Thread.currentThread().getName().contains("Dubbo-metadata-retry")) {
-// return metadataInfo_444;
+// return metadataInfo_222;
// }
// return null;
// }
// });
-
- ServiceInstancesChangedEvent event2 = new ServiceInstancesChangedEvent("app2", app1FailedInstances2);
- listener.onEvent(event2);
-
- // FIXME, manually mock proxy util, for retry task will work on another thread which makes MockStatic useless.
- ConcurrentMap map = Mockito.mock(ConcurrentMap.class);
- Mockito.doReturn(metadataService).when(map).get(Mockito.any());
- Mockito.doReturn(metadataService).when(map).computeIfAbsent(Mockito.any(), Mockito.any());
- MetadataUtils.metadataServiceProxies = map;
-
- // event2 did not really take effect
- Map<String, MetadataInfo> revisionToMetadata = listener.getRevisionToMetadata();
- Assertions.assertEquals(2, revisionToMetadata.size());
- Assertions.assertEquals(metadataInfo_111, revisionToMetadata.get("111"));
- Assertions.assertEquals(MetadataInfo.EMPTY, revisionToMetadata.get("222"));
-
- Assertions.assertEquals(3, listener.getAddresses(service1 + ":dubbo", consumerURL).size());
- assertTrue(isEmpty(listener.getAddresses(service2 + ":dubbo", consumerURL)));
-
- try {
- Thread.sleep(15000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- // check recovered after retry.
- Map<String, MetadataInfo> revisionToMetadata_after_retry = listener.getRevisionToMetadata();
- Assertions.assertEquals(2, revisionToMetadata_after_retry.size());
- Assertions.assertEquals(metadataInfo_111, revisionToMetadata_after_retry.get("111"));
- Assertions.assertEquals(metadataInfo_222, revisionToMetadata_after_retry.get("222"));
-
- List<URL> serviceUrls_after_retry = listener.getAddresses(service1 + ":dubbo", consumerURL);
- Assertions.assertEquals(5, serviceUrls_after_retry.size());
- List<URL> serviceUrls2_after_retry = listener.getAddresses(service2 + ":dubbo", consumerURL);
- Assertions.assertEquals(2, serviceUrls2_after_retry.size());
- } finally {
- MetadataUtils.metadataServiceProxies = tmpProxyMap;
- }
- }
-
- // Abnormal case. Instance does not has revision
- @Test
- public void testInstanceWithoutRevision() {
- Set<String> serviceNames = new HashSet<>();
- serviceNames.add("app1");
- ServiceDiscovery serviceDiscovery = Mockito.mock(ServiceDiscovery.class);
- ServiceInstancesChangedListener spyListener = Mockito.spy(new ServiceInstancesChangedListener(serviceNames, serviceDiscovery));
- Mockito.doReturn(null).when(spyListener).getRemoteMetadata(eq(null), Mockito.anyMap(), Mockito.any());
- ServiceInstancesChangedEvent event = new ServiceInstancesChangedEvent("app1", app1InstancesWithNoRevision);
- spyListener.onEvent(event);
- // notification succeeded
- assertTrue(true);
- }
-
- @Test
- public void testSelectInstance() {
- System.out.println(ThreadLocalRandom.current().nextInt(0, 100));
- System.out.println(ThreadLocalRandom.current().nextInt(0, 100));
- System.out.println(ThreadLocalRandom.current().nextInt(0, 100));
- System.out.println(ThreadLocalRandom.current().nextInt(0, 100));
- System.out.println(ThreadLocalRandom.current().nextInt(0, 100));
- }
-
- static List<ServiceInstance> buildInstances(List<Object> rawURls) {
- List<ServiceInstance> instances = new ArrayList<>();
-
- for (Object obj : rawURls) {
- String rawURL = (String)obj;
- DefaultServiceInstance instance = new DefaultServiceInstance();
- final URL dubboUrl = URL.valueOf(rawURL);
- instance.setRawAddress(rawURL);
- instance.setHost(dubboUrl.getHost());
- instance.setEnabled(true);
- instance.setHealthy(true);
- instance.setPort(dubboUrl.getPort());
- instance.setRegistryCluster("default");
-
- Map<String, String> metadata = new HashMap<>();
- if (StringUtils.isNotEmpty(dubboUrl.getParameter(REVISION_KEY))) {
- metadata.put(EXPORTED_SERVICES_REVISION_PROPERTY_NAME, dubboUrl.getParameter(REVISION_KEY));
- }
- instance.setMetadata(metadata);
-
- instances.add(instance);
- }
-
- return instances;
- }
-}
+//// Mockito.when(metadataService.getMetadataInfo("444")).thenAnswer(new Answer<MetadataInfo>() {
+//// @Override
+//// public MetadataInfo answer(InvocationOnMock invocationOnMock) throws Throwable {
+//// if (Thread.currentThread().getName().contains("Dubbo-metadata-retry")) {
+//// return metadataInfo_444;
+//// }
+//// return null;
+//// }
+//// });
+//
+// ServiceInstancesChangedEvent event2 = new ServiceInstancesChangedEvent("app2", app1FailedInstances2);
+// listener.onEvent(event2);
+//
+// // FIXME, manually mock proxy util, for retry task will work on another thread which makes MockStatic useless.
+// ConcurrentMap map = Mockito.mock(ConcurrentMap.class);
+// Mockito.doReturn(metadataService).when(map).get(Mockito.any());
+// Mockito.doReturn(metadataService).when(map).computeIfAbsent(Mockito.any(), Mockito.any());
+// MetadataUtils.metadataServiceProxies = map;
+//
+// // event2 did not really take effect
+// Map<String, MetadataInfo> revisionToMetadata = listener.getRevisionToMetadata();
+// Assertions.assertEquals(2, revisionToMetadata.size());
+// Assertions.assertEquals(metadataInfo_111, revisionToMetadata.get("111"));
+// Assertions.assertEquals(MetadataInfo.EMPTY, revisionToMetadata.get("222"));
+//
+// Assertions.assertEquals(3, listener.getAddresses(service1 + ":dubbo", consumerURL).size());
+// assertTrue(isEmpty(listener.getAddresses(service2 + ":dubbo", consumerURL)));
+//
+// try {
+// Thread.sleep(15000);
+// } catch (InterruptedException e) {
+// e.printStackTrace();
+// }
+// // check recovered after retry.
+// Map<String, MetadataInfo> revisionToMetadata_after_retry = listener.getRevisionToMetadata();
+// Assertions.assertEquals(2, revisionToMetadata_after_retry.size());
+// Assertions.assertEquals(metadataInfo_111, revisionToMetadata_after_retry.get("111"));
+// Assertions.assertEquals(metadataInfo_222, revisionToMetadata_after_retry.get("222"));
+//
+// List<URL> serviceUrls_after_retry = listener.getAddresses(service1 + ":dubbo", consumerURL);
+// Assertions.assertEquals(5, serviceUrls_after_retry.size());
+// List<URL> serviceUrls2_after_retry = listener.getAddresses(service2 + ":dubbo", consumerURL);
+// Assertions.assertEquals(2, serviceUrls2_after_retry.size());
+// } finally {
+// MetadataUtils.metadataServiceProxies = tmpProxyMap;
+// }
+// }
+//
+// // Abnormal case. Instance does not has revision
+// @Test
+// public void testInstanceWithoutRevision() {
+// Set<String> serviceNames = new HashSet<>();
+// serviceNames.add("app1");
+// ServiceDiscovery serviceDiscovery = Mockito.mock(ServiceDiscovery.class);
+// ServiceInstancesChangedListener spyListener = Mockito.spy(new ServiceInstancesChangedListener(serviceNames, serviceDiscovery));
+// Mockito.doReturn(null).when(spyListener).getRemoteMetadata(eq(null), Mockito.anyMap(), Mockito.any());
+// ServiceInstancesChangedEvent event = new ServiceInstancesChangedEvent("app1", app1InstancesWithNoRevision);
+// spyListener.onEvent(event);
+// // notification succeeded
+// assertTrue(true);
+// }
+//
+// @Test
+// public void testSelectInstance() {
+// System.out.println(ThreadLocalRandom.current().nextInt(0, 100));
+// System.out.println(ThreadLocalRandom.current().nextInt(0, 100));
+// System.out.println(ThreadLocalRandom.current().nextInt(0, 100));
+// System.out.println(ThreadLocalRandom.current().nextInt(0, 100));
+// System.out.println(ThreadLocalRandom.current().nextInt(0, 100));
+// }
+//
+// static List<ServiceInstance> buildInstances(List<Object> rawURls) {
+// List<ServiceInstance> instances = new ArrayList<>();
+//
+// for (Object obj : rawURls) {
+// String rawURL = (String)obj;
+// DefaultServiceInstance instance = new DefaultServiceInstance();
+// final URL dubboUrl = URL.valueOf(rawURL);
+// instance.setRawAddress(rawURL);
+// instance.setHost(dubboUrl.getHost());
+// instance.setEnabled(true);
+// instance.setHealthy(true);
+// instance.setPort(dubboUrl.getPort());
+// instance.setRegistryCluster("default");
+//
+// Map<String, String> metadata = new HashMap<>();
+// if (StringUtils.isNotEmpty(dubboUrl.getParameter(REVISION_KEY))) {
+// metadata.put(EXPORTED_SERVICES_REVISION_PROPERTY_NAME, dubboUrl.getParameter(REVISION_KEY));
+// }
+// instance.setMetadata(metadata);
+//
+// instances.add(instance);
+// }
+//
+// return instances;
+// }
+//}
diff --git a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/MetadataServiceURLParamsMetadataCustomizerTest.java b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/MetadataServiceURLParamsMetadataCustomizerTest.java
index f3ea39d..eb38149 100644
--- a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/MetadataServiceURLParamsMetadataCustomizerTest.java
+++ b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/MetadataServiceURLParamsMetadataCustomizerTest.java
@@ -16,14 +16,15 @@
*/
package org.apache.dubbo.registry.client.metadata;
-import com.google.gson.Gson;
-import com.google.gson.reflect.TypeToken;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.metadata.MetadataService;
import org.apache.dubbo.metadata.WritableMetadataService;
import org.apache.dubbo.registry.client.DefaultServiceInstance;
-import org.apache.dubbo.registry.client.metadata.store.InMemoryWritableMetadataService;
+import org.apache.dubbo.registry.client.metadata.store.MetadataServiceDelegation;
import org.apache.dubbo.rpc.model.ApplicationModel;
+
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
@@ -48,7 +49,7 @@ public class MetadataServiceURLParamsMetadataCustomizerTest {
private static final Gson gson = new Gson();
public DefaultServiceInstance instance;
- private InMemoryWritableMetadataService metadataService;
+ private MetadataServiceDelegation metadataService;
private URL metadataServiceURL = URL.valueOf("metadata://127.0.0.1:21881/" + MetadataService.class.getName() +
"?application=demo&group=g1&version=1.0.0×tamp=1632662388960");
@@ -60,7 +61,7 @@ public class MetadataServiceURLParamsMetadataCustomizerTest {
@BeforeEach
public void init() {
instance = createInstance();
- metadataService = mock(InMemoryWritableMetadataService.class);
+ metadataService = mock(MetadataServiceDelegation.class);
when(metadataService.getMetadataServiceURL()).thenReturn(metadataServiceURL);
}
diff --git a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/ProtocolPortsMetadataCustomizerTest.java b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/ProtocolPortsMetadataCustomizerTest.java
index 3f946c6..fa058f8 100644
--- a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/ProtocolPortsMetadataCustomizerTest.java
+++ b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/ProtocolPortsMetadataCustomizerTest.java
@@ -16,14 +16,15 @@
*/
package org.apache.dubbo.registry.client.metadata;
-import com.google.gson.Gson;
-import com.google.gson.reflect.TypeToken;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.metadata.WritableMetadataService;
import org.apache.dubbo.registry.client.DefaultServiceInstance;
-import org.apache.dubbo.registry.client.metadata.store.InMemoryWritableMetadataService;
+import org.apache.dubbo.registry.client.metadata.store.MetadataServiceDelegation;
import org.apache.dubbo.rpc.model.ApplicationModel;
+
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
import org.hamcrest.MatcherAssert;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
@@ -51,7 +52,7 @@ public class ProtocolPortsMetadataCustomizerTest {
private static final Gson gson = new Gson();
public DefaultServiceInstance instance;
- private InMemoryWritableMetadataService metadataService;
+ private MetadataServiceDelegation metadataService;
public static DefaultServiceInstance createInstance() {
return new DefaultServiceInstance("A", "127.0.0.1", 20880, ApplicationModel.defaultModel());
@@ -71,7 +72,7 @@ public class ProtocolPortsMetadataCustomizerTest {
@BeforeEach
public void init() {
instance = createInstance();
- metadataService = mock(InMemoryWritableMetadataService.class);
+ metadataService = mock(MetadataServiceDelegation.class);
URL dubboUrl = URL.valueOf("dubbo://30.10.104.63:20880/org.apache.dubbo.demo.GreetingService?" +
"REGISTRY_CLUSTER=registry1&anyhost=true&application=demo-provider2&delay=5000&deprecated=false&dubbo=2.0.2&dynamic=true&generic=false&group=greeting&interface=org.apache.dubbo.demo.GreetingService&metadata-type=remote&methods=hello&pid=55805&release=&revision=1.0.0&service-name-mapping=true&side=provider&timeout=5000×tamp=1630229110058&version=1.0.0");
diff --git a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataCustomizerTest.java b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataCustomizerTest.java
index fcc81d7..8140c96 100644
--- a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataCustomizerTest.java
+++ b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataCustomizerTest.java
@@ -22,7 +22,7 @@ import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.metadata.MetadataInfo;
import org.apache.dubbo.metadata.WritableMetadataService;
import org.apache.dubbo.registry.client.DefaultServiceInstance;
-import org.apache.dubbo.registry.client.metadata.store.InMemoryWritableMetadataService;
+import org.apache.dubbo.registry.client.metadata.store.MetadataServiceDelegation;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.junit.jupiter.api.AfterAll;
@@ -45,7 +45,7 @@ import static org.mockito.Mockito.when;
public class ServiceInstanceMetadataCustomizerTest {
public DefaultServiceInstance instance;
- private InMemoryWritableMetadataService metadataService;
+ private MetadataServiceDelegation metadataService;
public static DefaultServiceInstance createInstance() {
return new DefaultServiceInstance("A", "127.0.0.1", 20880, ApplicationModel.defaultModel());
@@ -65,7 +65,7 @@ public class ServiceInstanceMetadataCustomizerTest {
@BeforeEach
public void init() {
instance = createInstance();
- metadataService = mock(InMemoryWritableMetadataService.class);
+ metadataService = mock(MetadataServiceDelegation.class);
URL url = URL.valueOf("dubbo://30.10.104.63:20880/org.apache.dubbo.demo.GreetingService?" + "params-filter=-default&" +
"REGISTRY_CLUSTER=registry1&anyhost=true&application=demo-provider2&delay=5000&deprecated=false&dubbo=2.0.2&dynamic=true&generic=false&group=greeting&interface=org.apache.dubbo.demo.GreetingService&metadata-type=remote&methods=hello&pid=55805&release=&revision=1.0.0&service-name-mapping=true&side=provider&timeout=5000×tamp=1630229110058&version=1.0.0");
diff --git a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataUtilsTest.java b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataUtilsTest.java
index 7a83c1d..73ed92b 100644
--- a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataUtilsTest.java
+++ b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataUtilsTest.java
@@ -18,15 +18,12 @@ package org.apache.dubbo.registry.client.metadata;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.config.ApplicationConfig;
-import org.apache.dubbo.metadata.MetadataInfo;
-import org.apache.dubbo.metadata.MetadataService;
import org.apache.dubbo.metadata.WritableMetadataService;
import org.apache.dubbo.registry.Registry;
import org.apache.dubbo.registry.client.DefaultServiceInstance;
import org.apache.dubbo.registry.client.InMemoryServiceDiscovery;
import org.apache.dubbo.registry.client.ServiceDiscovery;
import org.apache.dubbo.registry.client.ServiceDiscoveryRegistry;
-import org.apache.dubbo.registry.client.metadata.store.InMemoryWritableMetadataService;
import org.apache.dubbo.registry.support.RegistryManager;
import org.apache.dubbo.rpc.model.ApplicationModel;
@@ -38,7 +35,6 @@ import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-import org.mockito.Mockito;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
@@ -48,11 +44,8 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
-import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_METADATA_STORAGE_TYPE;
import static org.apache.dubbo.common.constants.CommonConstants.REMOTE_METADATA_STORAGE_TYPE;
-import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.EXPORTED_SERVICES_REVISION_PROPERTY_NAME;
-import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.INSTANCE_REVISION_UPDATED_KEY;
import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.METADATA_CLUSTER_PROPERTY_NAME;
import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.METADATA_SERVICE_URL_PARAMS_PROPERTY_NAME;
import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.METADATA_STORAGE_TYPE_PROPERTY_NAME;
@@ -140,15 +133,6 @@ public class ServiceInstanceMetadataUtilsTest {
}
@Test
- public void testInstanceUpdateKey() {
- serviceInstance.getExtendParams().put(INSTANCE_REVISION_UPDATED_KEY, "true");
- Assertions.assertTrue(ServiceInstanceMetadataUtils.isInstanceUpdated(serviceInstance));
-
- ServiceInstanceMetadataUtils.resetInstanceUpdateKey(serviceInstance);
- Assertions.assertFalse(ServiceInstanceMetadataUtils.isInstanceUpdated(serviceInstance));
- }
-
- @Test
public void testEndpoints() {
Assertions.assertFalse(ServiceInstanceMetadataUtils.hasEndpoints(serviceInstance));
@@ -167,31 +151,9 @@ public class ServiceInstanceMetadataUtilsTest {
}
@Test
- public void testCalInstanceRevision() {
- URL url1 = URL.valueOf("test://127.0.0.1:8080/" + ServiceInstanceMetadataUtils.class.getName() + "?version=1.0.0");
- URL url2 = URL.valueOf("test://127.0.0.1:8080/" + ServiceInstanceMetadataUtils.class.getName() + "?version=2.0.0");
-
- ServiceDiscovery serviceDiscovery = Mockito.mock(ServiceDiscovery.class);
-
- InMemoryWritableMetadataService writableMetadataService = (InMemoryWritableMetadataService) WritableMetadataService.getDefaultExtension(serviceInstance.getApplicationModel());
- MetadataInfo metadataInfo = new MetadataInfo("demo");
- metadataInfo.addService(new MetadataInfo.ServiceInfo(url1));
- writableMetadataService.addMetadataInfo(DEFAULT_KEY, metadataInfo);
-
- ServiceInstanceMetadataUtils.calInstanceRevision(serviceDiscovery, serviceInstance);
- Assertions.assertEquals(metadataInfo.calAndGetRevision(), serviceInstance.getMetadata().get(EXPORTED_SERVICES_REVISION_PROPERTY_NAME));
- Assertions.assertNull(serviceInstance.getExtendParams().get(INSTANCE_REVISION_UPDATED_KEY));
-
- writableMetadataService.getMetadataInfos().get(DEFAULT_KEY).addService(new MetadataInfo.ServiceInfo(url2));
- ServiceInstanceMetadataUtils.calInstanceRevision(serviceDiscovery, serviceInstance);
- Assertions.assertEquals(metadataInfo.calAndGetRevision(), serviceInstance.getMetadata().get(EXPORTED_SERVICES_REVISION_PROPERTY_NAME));
- Assertions.assertEquals(serviceInstance.getExtendParams().get(INSTANCE_REVISION_UPDATED_KEY), "true");
- }
-
- @Test
public void testRegisterMetadataAndInstance() throws Exception {
InMemoryServiceDiscovery inMemoryServiceDiscovery = prepare();
- ServiceInstanceMetadataUtils.registerMetadataAndInstance(serviceInstance);
+ ServiceInstanceMetadataUtils.registerMetadataAndInstance(ApplicationModel.defaultModel());
Assertions.assertTrue(inMemoryServiceDiscovery.getServices().contains(serviceInstance.getServiceName()));
}
@@ -202,7 +164,7 @@ public class ServiceInstanceMetadataUtilsTest {
Assertions.assertNull(inMemoryServiceDiscovery.getLocalInstance());
- ServiceInstanceMetadataUtils.refreshMetadataAndInstance(serviceInstance);
+ ServiceInstanceMetadataUtils.refreshMetadataAndInstance(ApplicationModel.defaultModel());
Assertions.assertEquals(inMemoryServiceDiscovery.getLocalInstance().getServiceName(), serviceInstance.getServiceName());
Assertions.assertEquals(inMemoryServiceDiscovery.getLocalInstance().getHost(), serviceInstance.getHost());
@@ -211,14 +173,7 @@ public class ServiceInstanceMetadataUtilsTest {
}
private InMemoryServiceDiscovery prepare() throws NoSuchMethodException, InstantiationException, IllegalAccessException, java.lang.reflect.InvocationTargetException, NoSuchFieldException {
-
-
-
WritableMetadataService writableMetadataService = WritableMetadataService.getDefaultExtension(ApplicationModel.defaultModel());
- // Prevent NPE when calling the refreshMetadataAndInstance method (customizeInstance -> MetadataServiceURLParamsMetadataCustomizer.customize)
- URL metadataURL = URL.valueOf("dubbo://127.0.0.1:8080/" + MetadataService.class);
- writableMetadataService.setMetadataServiceURL(metadataURL);
-
// Construct serviceDiscoveryRegistry
InMemoryServiceDiscovery inMemoryServiceDiscovery = new InMemoryServiceDiscovery();
diff --git a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/store/InMemoryMetadataServiceTest.java b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/store/InMemoryMetadataServiceTest.java
index 7f770e7..1cd9c76 100644
--- a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/store/InMemoryMetadataServiceTest.java
+++ b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/store/InMemoryMetadataServiceTest.java
@@ -16,7 +16,6 @@
*/
package org.apache.dubbo.registry.client.metadata.store;
-import com.google.gson.Gson;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.metadata.MetadataInfo;
@@ -25,6 +24,8 @@ import org.apache.dubbo.metadata.definition.model.ServiceDefinition;
import org.apache.dubbo.registry.MockLogger;
import org.apache.dubbo.rpc.model.ApplicationModel;
import org.apache.dubbo.rpc.model.FrameworkModel;
+
+import com.google.gson.Gson;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
@@ -73,7 +74,7 @@ public class InMemoryMetadataServiceTest {
*/
@Test
public void testExport() {
- InMemoryWritableMetadataService metadataService = new InMemoryWritableMetadataService();
+ MetadataServiceDelegation metadataService = new MetadataServiceDelegation();
metadataService.setApplicationModel(ApplicationModel.defaultModel());
// export normal url
URL url = URL.valueOf("dubbo://30.225.21.30:20880/org.apache.dubbo.registry.service.DemoService?" +
@@ -160,7 +161,7 @@ public class InMemoryMetadataServiceTest {
*/
@Test
public void testUnExport() {
- InMemoryWritableMetadataService metadataService = new InMemoryWritableMetadataService();
+ MetadataServiceDelegation metadataService = new MetadataServiceDelegation();
metadataService.setApplicationModel(ApplicationModel.defaultModel());
// export normal url
URL url = URL.valueOf("dubbo://30.225.21.30:20880/org.apache.dubbo.registry.service.DemoService?" +
@@ -183,7 +184,7 @@ public class InMemoryMetadataServiceTest {
@Test
public void testServiceDefinition() {
URL url = URL.valueOf("dubbo://30.225.21.30:20880/org.apache.dubbo.registry.service.DemoService");
- InMemoryWritableMetadataService metadataService = new InMemoryWritableMetadataService();
+ MetadataServiceDelegation metadataService = new MetadataServiceDelegation();
metadataService.setApplicationModel(ApplicationModel.defaultModel());
metadataService.publishServiceDefinition(url);
@@ -195,7 +196,7 @@ public class InMemoryMetadataServiceTest {
@Test
public void testSubscribe() {
- InMemoryWritableMetadataService metadataService = new InMemoryWritableMetadataService();
+ MetadataServiceDelegation metadataService = new MetadataServiceDelegation();
metadataService.setApplicationModel(ApplicationModel.defaultModel());
URL url = URL.valueOf("dubbo://30.225.21.30:20880/org.apache.dubbo.registry.service.DemoService");
diff --git a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/store/RemoteMetadataServiceImplTest.java b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/store/RemoteMetadataServiceImplTest.java
deleted file mode 100644
index a7e7f85..0000000
--- a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/store/RemoteMetadataServiceImplTest.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * 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.store;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
-import org.apache.dubbo.metadata.MetadataInfo;
-import org.apache.dubbo.metadata.WritableMetadataService;
-import org.apache.dubbo.metadata.report.MetadataReport;
-import org.apache.dubbo.metadata.report.MetadataReportInstance;
-import org.apache.dubbo.metadata.report.identifier.SubscriberMetadataIdentifier;
-import org.apache.dubbo.registry.client.DefaultServiceInstance;
-import org.apache.dubbo.rpc.model.ApplicationModel;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.stubbing.Answer;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.EXPORTED_SERVICES_REVISION_PROPERTY_NAME;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.anyBoolean;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-public class RemoteMetadataServiceImplTest {
-
- private static final String REGISTRY_CLUSTER = "registry9103";
- private static final String SERVICE_NAME = "A";
- private RemoteMetadataServiceImpl remoteMetadataService;
- private MetadataReport metadataReport;
- private MetadataInfo metadataInfo;
- private String reversion;
-
- @BeforeEach
- public void setUp() {
- ApplicationModel applicationModel = spy(ApplicationModel.defaultModel());
- ScopeBeanFactory beanFactory = mock(ScopeBeanFactory.class);
- MetadataReportInstance metadataReportInstance = mock(MetadataReportInstance.class);
- metadataReport = mock(MetadataReport.class);
-
- Map<String, MetadataReport> clusterToMetadataReport = new HashMap<>();
- clusterToMetadataReport.put(REGISTRY_CLUSTER, metadataReport);
- when(metadataReportInstance.getMetadataReports(anyBoolean())).thenReturn(clusterToMetadataReport);
- when(applicationModel.getBeanFactory()).thenReturn(beanFactory);
- when(beanFactory.getBean(MetadataReportInstance.class)).thenReturn(metadataReportInstance);
-
- metadataInfo = new MetadataInfo();
- URL url = URL.valueOf("dubbo://30.225.21.30:20880/org.apache.dubbo.registry.service.DemoService");
- metadataInfo.addService(new MetadataInfo.ServiceInfo(url));
- reversion = metadataInfo.calAndGetRevision();
- Map<String, MetadataInfo> clusterToMetadataInfo = new HashMap<>();
- clusterToMetadataInfo.put(REGISTRY_CLUSTER, metadataInfo);
-
- WritableMetadataService writableMetadataService = mock(WritableMetadataService.class);
- when(applicationModel.getDefaultExtension(WritableMetadataService.class)).thenReturn(writableMetadataService);
- when(writableMetadataService.getMetadataInfos()).thenReturn(clusterToMetadataInfo);
- when(metadataReport.getAppMetadata(any(),any())).thenAnswer((Answer<MetadataInfo>) invocationOnMock -> {
- SubscriberMetadataIdentifier identifier = invocationOnMock.getArgument(0, SubscriberMetadataIdentifier.class);
- if (SERVICE_NAME.equals(identifier.getApplication()) && reversion.equals(identifier.getRevision())) {
- return metadataInfo;
- }
- return null;
- });
-
-
- remoteMetadataService = new RemoteMetadataServiceImpl();
- remoteMetadataService.setScopeModel(applicationModel);
- }
-
- @Test
- public void testPublishAndGetMetadata() {
-
- // test getMetadataReports
- Map<String, MetadataReport> metadataReports = remoteMetadataService.getMetadataReports();
- Assertions.assertTrue(metadataReports.containsKey(REGISTRY_CLUSTER));
-
- // test publishMetadata
- remoteMetadataService.publishMetadata(SERVICE_NAME);
-
- ArgumentCaptor<SubscriberMetadataIdentifier> identifierArgumentCaptor = ArgumentCaptor.forClass(SubscriberMetadataIdentifier.class);
- ArgumentCaptor<MetadataInfo> metadataInfoArgumentCaptor = ArgumentCaptor.forClass(MetadataInfo.class);
- verify(metadataReport, times(1)).publishAppMetadata(identifierArgumentCaptor.capture(), metadataInfoArgumentCaptor.capture());
- SubscriberMetadataIdentifier identifier = identifierArgumentCaptor.getValue();
- Assertions.assertEquals(identifier.getRevision(), reversion);
- Assertions.assertEquals(identifier.getApplication(), SERVICE_NAME);
-
- // test getMetadata
- DefaultServiceInstance serviceInstance = new DefaultServiceInstance(SERVICE_NAME, "127.0.0.1", 20880, ApplicationModel.defaultModel());
- serviceInstance.setRegistryCluster(REGISTRY_CLUSTER);
- serviceInstance.getMetadata().put(EXPORTED_SERVICES_REVISION_PROPERTY_NAME, reversion);
-
- MetadataInfo remoteMetadataInfo = remoteMetadataService.getMetadata(serviceInstance);
- Assertions.assertEquals(remoteMetadataInfo, metadataInfo);
-
- serviceInstance.setServiceName("FAIL_SERVICE_NAME");
- remoteMetadataInfo = remoteMetadataService.getMetadata(serviceInstance);
- Assertions.assertNull(remoteMetadataInfo);
- }
-
- @Test
- public void testPublishServiceDefinition() {
- // test provider publishServiceDefinition
- URL providerURL = URL.valueOf("dubbo://127.0.0.1:8888/org.apache.dubbo.registry.service.DemoService?side=provider");
- remoteMetadataService.publishServiceDefinition(providerURL);
- verify(metadataReport, times(1)).storeProviderMetadata(any(),any());
-
- // test consumer publishServiceDefinition
- URL consumerURL = URL.valueOf("dubbo://127.0.0.1:8888/org.apache.dubbo.registry.service.DemoService?side=consumer");
- remoteMetadataService.publishServiceDefinition(consumerURL);
- verify(metadataReport, times(1)).storeConsumerMetadata(any(),any());
-
- }
-}
diff --git a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/migration/model/MigrationRuleTest.java b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/migration/model/MigrationRuleTest.java
index 53b9899..f2668bf 100644
--- a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/migration/model/MigrationRuleTest.java
+++ b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/migration/model/MigrationRuleTest.java
@@ -18,8 +18,8 @@ package org.apache.dubbo.registry.client.migration.model;
import org.apache.dubbo.common.URL;
import org.apache.dubbo.metadata.ServiceNameMapping;
-import org.apache.dubbo.metadata.WritableMetadataService;
import org.apache.dubbo.rpc.model.ApplicationModel;
+
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentMatchers;
import org.mockito.Mockito;
@@ -99,8 +99,7 @@ public class MigrationRuleTest {
Mockito.when(url.getDisplayServiceKey()).thenReturn("GreetingService:1.0.1");
Mockito.when(url.getServiceInterface()).thenReturn("GreetingService");
- WritableMetadataService metadataService = WritableMetadataService.getDefaultExtension(defaultModel);
- metadataService.putCachedMapping(ServiceNameMapping.buildMappingKey(url), Collections.singleton("TestApplication"));
+ when(mapping.getCachedMapping(any(URL.class))).thenReturn(Collections.singleton("TestApplication"));
Set<String> services = new HashSet<>();
services.add("TestApplication");
@@ -110,7 +109,8 @@ public class MigrationRuleTest {
assertEquals(10, migrationRule.getDelay(url));
assertEquals(false, migrationRule.getForce(url));
assertEquals(MigrationStep.FORCE_INTERFACE, migrationRule.getStep(url));
- metadataService.removeCachedMapping("GreetingService");
+ when(mapping.getCachedMapping(any(URL.class))).thenReturn(Collections.emptySet());
+
ApplicationModel.defaultModel().destroy();
}
}
diff --git a/dubbo-registry/dubbo-registry-consul/src/main/java/org/apache/dubbo/registry/consul/ConsulParameter.java b/dubbo-registry/dubbo-registry-consul/src/main/java/org/apache/dubbo/registry/consul/ConsulParameter.java
deleted file mode 100644
index f3fb024..0000000
--- a/dubbo-registry/dubbo-registry-consul/src/main/java/org/apache/dubbo/registry/consul/ConsulParameter.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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.consul;
-
-import org.apache.dubbo.common.URL;
-
-import static org.apache.dubbo.common.utils.StringUtils.isBlank;
-
-/**
- * The enumeration for the Consul's parameters on the {@link URL}
- *
- * @see URL#getParameters()
- * @since 2.7.8
- */
-public enum ConsulParameter {
-
- ACL_TOKEN,
-
- TAGS,
-
- INSTANCE_ZONE,
-
- DEFAULT_ZONE_METADATA_NAME("zone"),
-
- INSTANCE_GROUP,
-
- CONSISTENCY_MODE,
-
- ;
-
- private final String name;
-
- private final String defaultValue;
-
- ConsulParameter() {
- this(null);
- }
-
- ConsulParameter(String defaultValue) {
- this(null, defaultValue);
- }
-
- ConsulParameter(String name, String defaultValue) {
- this.name = isBlank(name) ? defaultName() : name;
- this.defaultValue = defaultValue;
- }
-
- private String defaultName() {
- return name().toLowerCase().replace('_', '-');
- }
-
- /**
- * The parameter value from the specified registry {@link URL}
- *
- * @param registryURL the specified registry {@link URL}
- * @return <code>defaultValue</code> if not found
- */
- public String getValue(URL registryURL) {
- return registryURL.getParameter(name, defaultValue);
- }
-
- /**
- * The parameter value from the specified registry {@link URL}
- *
- * @param registryURL the specified registry {@link URL}
- * @param valueType the type of parameter value
- * @param defaultValue the default value if parameter is absent
- * @return <code>defaultValue</code> if not found
- */
- public <T> T getValue(URL registryURL, Class<T> valueType, T defaultValue) {
- return registryURL.getParameter(name, valueType, defaultValue);
- }
-}
diff --git a/dubbo-registry/dubbo-registry-consul/src/main/java/org/apache/dubbo/registry/consul/ConsulServiceDiscoveryFactory.java b/dubbo-registry/dubbo-registry-consul/src/main/java/org/apache/dubbo/registry/consul/ConsulServiceDiscoveryFactory.java
deleted file mode 100644
index bd77db8..0000000
--- a/dubbo-registry/dubbo-registry-consul/src/main/java/org/apache/dubbo/registry/consul/ConsulServiceDiscoveryFactory.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.consul;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.registry.client.AbstractServiceDiscoveryFactory;
-import org.apache.dubbo.registry.client.ServiceDiscovery;
-
-public class ConsulServiceDiscoveryFactory extends AbstractServiceDiscoveryFactory {
-
- @Override
- protected ServiceDiscovery createDiscovery(URL registryURL) {
- return new ConsulServiceDiscovery();
- }
-
-}
diff --git a/dubbo-registry/dubbo-registry-consul/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.client.ServiceDiscoveryFactory b/dubbo-registry/dubbo-registry-consul/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.client.ServiceDiscoveryFactory
deleted file mode 100644
index a0f1252..0000000
--- a/dubbo-registry/dubbo-registry-consul/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.client.ServiceDiscoveryFactory
+++ /dev/null
@@ -1 +0,0 @@
-consul=org.apache.dubbo.registry.consul.ConsulServiceDiscoveryFactory
\ No newline at end of file
diff --git a/dubbo-registry/dubbo-registry-dns/pom.xml b/dubbo-registry/dubbo-registry-dns/pom.xml
deleted file mode 100644
index 54e526c..0000000
--- a/dubbo-registry/dubbo-registry-dns/pom.xml
+++ /dev/null
@@ -1,90 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- 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.
- -->
-<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns="http://maven.apache.org/POM/4.0.0"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.apache.dubbo</groupId>
- <artifactId>dubbo-registry</artifactId>
- <version>${revision}</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>dubbo-registry-dns</artifactId>
- <packaging>jar</packaging>
- <name>${project.artifactId}</name>
- <description>The DNS registry module of Dubbo project</description>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.dubbo</groupId>
- <artifactId>dubbo-registry-api</artifactId>
- <version>${project.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.apache.dubbo</groupId>
- <artifactId>dubbo-common</artifactId>
- <version>${project.version}</version>
- </dependency>
-
- <dependency>
- <groupId>io.netty</groupId>
- <artifactId>netty-all</artifactId>
- </dependency>
-
- <dependency>
- <groupId>org.apache.dubbo</groupId>
- <artifactId>dubbo-config-api</artifactId>
- <version>${project.version}</version>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>org.apache.dubbo</groupId>
- <artifactId>dubbo-rpc-dubbo</artifactId>
- <version>${project.version}</version>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>org.apache.dubbo</groupId>
- <artifactId>dubbo-serialization-hessian2</artifactId>
- <version>${project.version}</version>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>org.apache.dubbo</groupId>
- <artifactId>dubbo-remoting-netty4</artifactId>
- <version>${project.version}</version>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>org.apache.dubbo</groupId>
- <artifactId>dubbo-registry-multicast</artifactId>
- <version>${project.version}</version>
- <scope>test</scope>
- </dependency>
-
- </dependencies>
-
-</project>
\ No newline at end of file
diff --git a/dubbo-registry/dubbo-registry-dns/src/main/java/org/apache/dubbo/registry/dns/DNSRegistry.java b/dubbo-registry/dubbo-registry-dns/src/main/java/org/apache/dubbo/registry/dns/DNSRegistry.java
deleted file mode 100644
index 79fa0cd..0000000
--- a/dubbo-registry/dubbo-registry-dns/src/main/java/org/apache/dubbo/registry/dns/DNSRegistry.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * 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.dns;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.registry.NotifyListener;
-import org.apache.dubbo.registry.support.FailbackRegistry;
-
-/**
- * Empty implements for DNS <br/>
- * DNS only support `Service Discovery` mode register <br/>
- * Used to compat past version like 2.6.x, 2.7.x with interface level register <br/>
- * {@link DNSServiceDiscovery} is the real implementation of DNS
- */
-public class DNSRegistry extends FailbackRegistry {
- public DNSRegistry(URL url) {
- super(url);
- }
-
- @Override
- public boolean isAvailable() {
- return true;
- }
-
- @Override
- public void doRegister(URL url) {
-
- }
-
- @Override
- public void doUnregister(URL url) {
-
- }
-
- @Override
- public void doSubscribe(URL url, NotifyListener listener) {
-
- }
-
- @Override
- public void doUnsubscribe(URL url, NotifyListener listener) {
-
- }
-}
diff --git a/dubbo-registry/dubbo-registry-dns/src/main/java/org/apache/dubbo/registry/dns/DNSRegistryFactory.java b/dubbo-registry/dubbo-registry-dns/src/main/java/org/apache/dubbo/registry/dns/DNSRegistryFactory.java
deleted file mode 100644
index 870485e..0000000
--- a/dubbo-registry/dubbo-registry-dns/src/main/java/org/apache/dubbo/registry/dns/DNSRegistryFactory.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.dns;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.registry.Registry;
-import org.apache.dubbo.registry.support.AbstractRegistryFactory;
-
-public class DNSRegistryFactory extends AbstractRegistryFactory {
-
- @Override
- protected String createRegistryCacheKey(URL url) {
- return url.toFullString();
- }
-
- @Override
- protected Registry createRegistry(URL url) {
- return new DNSRegistry(url);
- }
-}
diff --git a/dubbo-registry/dubbo-registry-dns/src/main/java/org/apache/dubbo/registry/dns/DNSServiceDiscovery.java b/dubbo-registry/dubbo-registry-dns/src/main/java/org/apache/dubbo/registry/dns/DNSServiceDiscovery.java
deleted file mode 100644
index 8f302fb..0000000
--- a/dubbo-registry/dubbo-registry-dns/src/main/java/org/apache/dubbo/registry/dns/DNSServiceDiscovery.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * 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.dns;
-
-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.NamedThreadFactory;
-import org.apache.dubbo.registry.client.DefaultServiceInstance;
-import org.apache.dubbo.registry.client.SelfHostMetaServiceDiscovery;
-import org.apache.dubbo.registry.client.ServiceInstance;
-import org.apache.dubbo.registry.client.event.listener.ServiceInstancesChangedListener;
-import org.apache.dubbo.registry.dns.util.DNSClientConst;
-import org.apache.dubbo.registry.dns.util.DNSResolver;
-import org.apache.dubbo.registry.dns.util.ResolveResult;
-import org.apache.dubbo.rpc.model.ScopeModelUtil;
-
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.TimeUnit;
-
-public class DNSServiceDiscovery extends SelfHostMetaServiceDiscovery {
-
- private final Logger logger = LoggerFactory.getLogger(getClass());
-
- /**
- * DNS properties
- */
-
- private String addressPrefix;
- private String addressSuffix;
- private long pollingCycle;
- private DNSResolver dnsResolver;
-
- /**
- * Polling task ScheduledFuture, used to stop task when destroy
- */
- private final ConcurrentHashMap<String, ScheduledFuture<?>> pollingExecutorMap = new ConcurrentHashMap<>();
-
- /**
- * Polling check provider ExecutorService
- */
- private ScheduledExecutorService pollingExecutorService;
-
- @Override
- public void doInitialize(URL registryURL) throws Exception {
- this.addressPrefix = registryURL.getParameter(DNSClientConst.ADDRESS_PREFIX, "");
- this.addressSuffix = registryURL.getParameter(DNSClientConst.ADDRESS_SUFFIX, "");
- this.pollingCycle = registryURL.getParameter(DNSClientConst.DNS_POLLING_CYCLE, DNSClientConst.DEFAULT_DNS_POLLING_CYCLE);
-
- String nameserver = registryURL.getHost();
- int port = registryURL.getPort();
- int maxQueriesPerResolve = registryURL.getParameter(DNSClientConst.MAX_QUERIES_PER_RESOLVE, 10);
- this.dnsResolver = new DNSResolver(nameserver, port, maxQueriesPerResolve);
-
-
- int scheduledThreadPoolSize = registryURL.getParameter(DNSClientConst.DNS_POLLING_POOL_SIZE_KEY, DNSClientConst.DEFAULT_DNS_POLLING_POOL_SIZE);
-
- // polling task may take a lot of time, create a new ScheduledThreadPool
- pollingExecutorService = Executors.newScheduledThreadPool(scheduledThreadPoolSize, new NamedThreadFactory("Dubbo-DNS-Poll"));
-
- }
-
- @Override
- public void doDestroy() throws Exception {
- dnsResolver.destroy();
- pollingExecutorMap.forEach((serviceName, scheduledFuture) -> scheduledFuture.cancel(true));
- pollingExecutorMap.clear();
- pollingExecutorService.shutdown();
- }
-
- @Override
- public Set<String> getServices() {
- // it is impossible for dns to discover service names
- return Collections.singleton("Unsupported Method");
- }
-
- @Override
- public List<ServiceInstance> getInstances(String serviceName) throws NullPointerException {
-
- String serviceAddress = addressPrefix + serviceName + addressSuffix;
-
- ResolveResult resolveResult = dnsResolver.resolve(serviceAddress);
-
- return toServiceInstance(serviceName, resolveResult);
- }
-
- @Override
- public void addServiceInstancesChangedListener(ServiceInstancesChangedListener listener) throws NullPointerException, IllegalArgumentException {
- listener.getServiceNames().forEach(serviceName -> {
- ScheduledFuture<?> scheduledFuture = pollingExecutorService.scheduleAtFixedRate(() -> {
- List<ServiceInstance> instances = getInstances(serviceName);
- instances.sort(Comparator.comparingInt(ServiceInstance::hashCode));
- notifyListener(serviceName, listener, instances);
- },
- pollingCycle, pollingCycle, TimeUnit.MILLISECONDS);
-
- pollingExecutorMap.put(serviceName, scheduledFuture);
- });
- }
-
- /**
- * UT used only
- */
- @Deprecated
- public void setDnsResolver(DNSResolver dnsResolver) {
- this.dnsResolver = dnsResolver;
- }
-
- private List<ServiceInstance> toServiceInstance(String serviceName, ResolveResult resolveResult) {
-
- int port;
-
- if (resolveResult.getPort().size() > 0) {
- // use first as default
- port = resolveResult.getPort().get(0);
- } else {
- // not support SRV record
- port = 20880;
- }
-
- List<ServiceInstance> instanceList = new LinkedList<>();
-
- for (String host : resolveResult.getHostnameList()) {
- DefaultServiceInstance serviceInstance = new DefaultServiceInstance(serviceName, host, port, ScopeModelUtil.getApplicationModel(getUrl().getScopeModel()));
- fillServiceInstance(serviceInstance);
- instanceList.add(serviceInstance);
- }
-
- return instanceList;
- }
-}
diff --git a/dubbo-registry/dubbo-registry-dns/src/main/java/org/apache/dubbo/registry/dns/DNSServiceDiscoveryFactory.java b/dubbo-registry/dubbo-registry-dns/src/main/java/org/apache/dubbo/registry/dns/DNSServiceDiscoveryFactory.java
deleted file mode 100644
index 57eba84..0000000
--- a/dubbo-registry/dubbo-registry-dns/src/main/java/org/apache/dubbo/registry/dns/DNSServiceDiscoveryFactory.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * 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.dns;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.registry.client.AbstractServiceDiscoveryFactory;
-import org.apache.dubbo.registry.client.ServiceDiscovery;
-
-public class DNSServiceDiscoveryFactory extends AbstractServiceDiscoveryFactory {
- @Override
- protected ServiceDiscovery createDiscovery(URL registryURL) {
- return new DNSServiceDiscovery();
- }
-}
diff --git a/dubbo-registry/dubbo-registry-dns/src/main/java/org/apache/dubbo/registry/dns/util/DNSClientConst.java b/dubbo-registry/dubbo-registry-dns/src/main/java/org/apache/dubbo/registry/dns/util/DNSClientConst.java
deleted file mode 100644
index 0fc8ada..0000000
--- a/dubbo-registry/dubbo-registry-dns/src/main/java/org/apache/dubbo/registry/dns/util/DNSClientConst.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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.dns.util;
-
-public class DNSClientConst {
-
- public final static String ADDRESS_PREFIX = "addressPrefix";
-
- public final static String ADDRESS_SUFFIX = "addressSuffix";
-
- public final static String MAX_QUERIES_PER_RESOLVE = "maxQueriesPerResolve";
-
- /**
- * To decide the frequency of execute DNS poll (in ms)
- */
- public final static String DNS_POLLING_CYCLE = "dnsPollingCycle";
-
- /**
- * Default value for check frequency: 60000 (ms)
- */
- public final static int DEFAULT_DNS_POLLING_CYCLE = 60000;
-
- /**
- * To decide how many threads used to execute DNS poll
- */
- public final static String DNS_POLLING_POOL_SIZE_KEY = "dnsPollingPoolSize";
-
- /**
- * Default value for DNS pool thread: 1
- */
- public final static int DEFAULT_DNS_POLLING_POOL_SIZE = 1;
-
-}
diff --git a/dubbo-registry/dubbo-registry-dns/src/main/java/org/apache/dubbo/registry/dns/util/DNSResolver.java b/dubbo-registry/dubbo-registry-dns/src/main/java/org/apache/dubbo/registry/dns/util/DNSResolver.java
deleted file mode 100644
index 7745873..0000000
--- a/dubbo-registry/dubbo-registry-dns/src/main/java/org/apache/dubbo/registry/dns/util/DNSResolver.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * 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.dns.util;
-
-import org.apache.dubbo.common.logger.Logger;
-import org.apache.dubbo.common.logger.LoggerFactory;
-
-import io.netty.buffer.ByteBuf;
-import io.netty.channel.AddressedEnvelope;
-import io.netty.channel.EventLoopGroup;
-import io.netty.channel.nio.NioEventLoopGroup;
-import io.netty.channel.socket.nio.NioDatagramChannel;
-import io.netty.handler.codec.dns.DefaultDnsQuestion;
-import io.netty.handler.codec.dns.DnsRawRecord;
-import io.netty.handler.codec.dns.DnsRecordType;
-import io.netty.handler.codec.dns.DnsResponse;
-import io.netty.handler.codec.dns.DnsSection;
-import io.netty.resolver.ResolvedAddressTypes;
-import io.netty.resolver.dns.DnsNameResolver;
-import io.netty.resolver.dns.DnsNameResolverBuilder;
-import io.netty.util.concurrent.Future;
-
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.UnknownHostException;
-import java.util.List;
-import java.util.stream.Collectors;
-
-import static io.netty.resolver.dns.DnsServerAddresses.sequential;
-
-public class DNSResolver {
-
- private final Logger logger = LoggerFactory.getLogger(getClass());
-
- private final DnsNameResolver resolver;
-
- private static final EventLoopGroup GROUP = new NioEventLoopGroup(1);
-
- public DNSResolver(String nameserver, int port, int maxQueriesPerResolve) {
- this.resolver = newResolver(nameserver, port, maxQueriesPerResolve);
- }
-
- public ResolveResult resolve(String path) {
- ResolveResult recordList = new ResolveResult();
-
- try {
- Future<List<InetAddress>> hostFuture = resolver.resolveAll(path);
- Future<AddressedEnvelope<DnsResponse, InetSocketAddress>> srvFuture =
- resolver.query(new DefaultDnsQuestion(path, DnsRecordType.SRV));
-
- try {
- recordList.getHostnameList()
- .addAll(hostFuture
- .sync().getNow()
- .stream()
- .map(InetAddress::getHostAddress)
- .collect(Collectors.toList()));
-
- DnsResponse srvResponse = srvFuture.sync().getNow().content();
- for (int i = 0; i < srvResponse.count(DnsSection.ANSWER); i++) {
- DnsRawRecord record = srvResponse.recordAt(DnsSection.ANSWER, i);
- ByteBuf buf = record.content();
- // Priority
- buf.readUnsignedShort();
- // Weight
- buf.readUnsignedShort();
- // Port
- int port = buf.readUnsignedShort();
- recordList.getPort().add(port);
- }
-
- } catch (InterruptedException e) {
- logger.warn("Waiting DNS resolve interrupted. " + e.getLocalizedMessage());
- }
- } catch (Throwable t) {
- if (t instanceof UnknownHostException) {
- if (logger.isInfoEnabled()) {
- logger.info(t.getLocalizedMessage());
- }
- } else {
- logger.error(t.getLocalizedMessage());
- }
- }
-
-
- return recordList;
- }
-
- public void destroy() {
- resolver.close();
- }
-
- private static DnsNameResolver newResolver(String nameserver, int port, int maxQueriesPerResolve) {
- return new DnsNameResolverBuilder(GROUP.next())
- .channelType(NioDatagramChannel.class)
- .maxQueriesPerResolve(maxQueriesPerResolve)
- .decodeIdn(true)
- .optResourceEnabled(false)
- .ndots(1)
- .resolvedAddressTypes(ResolvedAddressTypes.IPV4_PREFERRED)
- // ignore cache
- .ttl(0, 1)
- .nameServerProvider((hostname) -> sequential(new InetSocketAddress(nameserver, port)).stream())
- .build();
- }
-}
diff --git a/dubbo-registry/dubbo-registry-dns/src/main/java/org/apache/dubbo/registry/dns/util/ResolveResult.java b/dubbo-registry/dubbo-registry-dns/src/main/java/org/apache/dubbo/registry/dns/util/ResolveResult.java
deleted file mode 100644
index a02b122..0000000
--- a/dubbo-registry/dubbo-registry-dns/src/main/java/org/apache/dubbo/registry/dns/util/ResolveResult.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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.dns.util;
-
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Objects;
-
-public class ResolveResult {
-
- private List<String> hostnameList = new LinkedList<>();
-
- private List<Integer> port = new LinkedList<>();
-
- public List<String> getHostnameList() {
- return hostnameList;
- }
-
- public void setHostnameList(List<String> hostnameList) {
- this.hostnameList = hostnameList;
- }
-
- public List<Integer> getPort() {
- return port;
- }
-
- public void setPort(List<Integer> port) {
- this.port = port;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- ResolveResult that = (ResolveResult) o;
- return Objects.equals(hostnameList, that.hostnameList) &&
- Objects.equals(port, that.port);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(hostnameList, port);
- }
-
- @Override
- public String toString() {
- return "ResolveResult{" +
- "hostnameList=" + hostnameList +
- ", port=" + port +
- '}';
- }
-}
diff --git a/dubbo-registry/dubbo-registry-dns/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.RegistryFactory b/dubbo-registry/dubbo-registry-dns/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.RegistryFactory
deleted file mode 100644
index 69ca007..0000000
--- a/dubbo-registry/dubbo-registry-dns/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.RegistryFactory
+++ /dev/null
@@ -1 +0,0 @@
-dns=org.apache.dubbo.registry.dns.DNSRegistryFactory
\ No newline at end of file
diff --git a/dubbo-registry/dubbo-registry-dns/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.client.ServiceDiscovery b/dubbo-registry/dubbo-registry-dns/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.client.ServiceDiscovery
deleted file mode 100644
index 3adb9f4..0000000
--- a/dubbo-registry/dubbo-registry-dns/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.client.ServiceDiscovery
+++ /dev/null
@@ -1 +0,0 @@
-dns=org.apache.dubbo.registry.dns.DNSServiceDiscovery
\ No newline at end of file
diff --git a/dubbo-registry/dubbo-registry-dns/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.client.ServiceDiscoveryFactory b/dubbo-registry/dubbo-registry-dns/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.client.ServiceDiscoveryFactory
deleted file mode 100644
index 900e78c..0000000
--- a/dubbo-registry/dubbo-registry-dns/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.registry.client.ServiceDiscoveryFactory
+++ /dev/null
@@ -1 +0,0 @@
-dns=org.apache.dubbo.registry.dns.DNSServiceDiscoveryFactory
\ No newline at end of file
diff --git a/dubbo-registry/dubbo-registry-dns/src/test/java/org/apache/dubbo/registry/dns/DNSServiceDiscoveryTest.java b/dubbo-registry/dubbo-registry-dns/src/test/java/org/apache/dubbo/registry/dns/DNSServiceDiscoveryTest.java
deleted file mode 100644
index 37c215a..0000000
--- a/dubbo-registry/dubbo-registry-dns/src/test/java/org/apache/dubbo/registry/dns/DNSServiceDiscoveryTest.java
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * 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.dns;
-
-import com.alibaba.fastjson.JSONObject;
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.utils.NetUtils;
-import org.apache.dubbo.config.ApplicationConfig;
-import org.apache.dubbo.config.ArgumentConfig;
-import org.apache.dubbo.config.MethodConfig;
-import org.apache.dubbo.config.ProtocolConfig;
-import org.apache.dubbo.config.RegistryConfig;
-import org.apache.dubbo.config.ServiceConfig;
-import org.apache.dubbo.config.bootstrap.DubboBootstrap;
-import org.apache.dubbo.metadata.InstanceMetadataChangedListener;
-import org.apache.dubbo.metadata.MetadataService;
-import org.apache.dubbo.metadata.WritableMetadataService;
-import org.apache.dubbo.registry.Constants;
-import org.apache.dubbo.registry.client.DefaultServiceInstance;
-import org.apache.dubbo.registry.client.ServiceInstance;
-import org.apache.dubbo.registry.client.event.ServiceInstancesChangedEvent;
-import org.apache.dubbo.registry.client.event.listener.ServiceInstancesChangedListener;
-import org.apache.dubbo.registry.dns.util.DNSClientConst;
-import org.apache.dubbo.registry.dns.util.DNSResolver;
-import org.apache.dubbo.registry.dns.util.ResolveResult;
-import org.apache.dubbo.rpc.model.ApplicationModel;
-import org.apache.dubbo.rpc.model.ScopeModelUtil;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mockito;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import static org.apache.dubbo.common.constants.CommonConstants.DUBBO_PROTOCOL;
-import static org.apache.dubbo.metadata.MetadataConstants.METADATA_PROXY_TIMEOUT_KEY;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-public class DNSServiceDiscoveryTest {
-
- @BeforeEach
- public void setup() {
- DubboBootstrap.reset();
- ApplicationConfig applicationConfig = new ApplicationConfig("Test");
- ApplicationModel.defaultModel().getApplicationConfigManager().setApplication(applicationConfig);
- }
-
- @AfterEach
- public void destroy() {
- DubboBootstrap.reset();
- }
-
- @Test
- public void testProvider() throws Exception {
- ApplicationModel applicationModel = ApplicationModel.defaultModel();
- DNSServiceDiscovery dnsServiceDiscovery = new DNSServiceDiscovery();
- dnsServiceDiscovery.setApplicationModel(applicationModel);
-
- URL registryURL = URL.valueOf("dns://");
- registryURL.setScopeModel(ApplicationModel.defaultModel());
- dnsServiceDiscovery.initialize(registryURL);
-
- assertEquals(registryURL, dnsServiceDiscovery.getUrl());
-
- ServiceInstance serviceInstance = new DefaultServiceInstance("TestService", "localhost", 12345, ScopeModelUtil.getApplicationModel(dnsServiceDiscovery.getUrl().getScopeModel()));
- serviceInstance.getMetadata().put("a", "b");
-
- dnsServiceDiscovery.register(serviceInstance);
-
- WritableMetadataService metadataService = WritableMetadataService.getDefaultExtension(applicationModel);
- InstanceMetadataChangedListener changeListener = Mockito.mock(InstanceMetadataChangedListener.class);
-
- String metadataString = metadataService
- .getAndListenInstanceMetadata("test", changeListener);
-
- assertEquals(JSONObject.toJSONString(serviceInstance.getMetadata()), metadataString);
- assertEquals(serviceInstance, dnsServiceDiscovery.getLocalInstance());
-
- dnsServiceDiscovery.unregister(serviceInstance);
-
- Mockito.verify(changeListener, Mockito.times(1)).onEvent(Mockito.any());
-
- metadataService.getInstanceMetadataChangedListenerMap().clear();
- metadataService.exportInstanceMetadata(null);
-
- dnsServiceDiscovery.destroy();
-
- }
-
- @Test
- public void testConsumer() throws Exception {
- ApplicationModel applicationModel = ApplicationModel.defaultModel();
- DNSServiceDiscovery dnsServiceDiscovery = new DNSServiceDiscovery();
- dnsServiceDiscovery.setApplicationModel(applicationModel);
-
- URL registryURL = URL.valueOf("dns://")
- .addParameter(DNSClientConst.DNS_POLLING_CYCLE, 100)
- .addParameter(Constants.ECHO_POLLING_CYCLE_KEY, 100);
- registryURL.setScopeModel(ApplicationModel.defaultModel());
- applicationModel.getModelEnvironment().getAppExternalConfigMap()
- .put(METADATA_PROXY_TIMEOUT_KEY, String.valueOf(500));
- dnsServiceDiscovery.initialize(registryURL);
-
- WritableMetadataService metadataService = WritableMetadataService.getDefaultExtension(applicationModel);
- ServiceInstance serviceInstance = new DefaultServiceInstance("TestService", "localhost", 12345, ScopeModelUtil.getApplicationModel(dnsServiceDiscovery.getUrl().getScopeModel()));
- serviceInstance.getMetadata().put("a", "b");
-
- dnsServiceDiscovery.register(serviceInstance);
-
- int port = NetUtils.getAvailablePort();
- applicationModel.getCurrentConfig().setMetadataServicePort(port);
-
- WritableMetadataService spiedMetadataService = Mockito.spy(metadataService);
-
- ServiceConfig<MetadataService> serviceConfig = exportMockMetadataService(spiedMetadataService, port);
-
- DNSResolver dnsResolver = Mockito.mock(DNSResolver.class);
- ResolveResult resolveResult = new ResolveResult();
- resolveResult.getHostnameList().add("127.0.0.1");
- Mockito.when(dnsResolver.resolve("Test.Service.")).thenReturn(resolveResult);
- dnsServiceDiscovery.setDnsResolver(dnsResolver);
-
- List<ServiceInstance> serviceInstances = dnsServiceDiscovery.getInstances("Test.Service.");
- assertEquals("b", serviceInstances.get(0).getMetadata("a"));
-
- Set<String> serviceNames = new HashSet<>();
- serviceNames.add("Test.Service.");
- ServiceInstancesChangedListener changedListener = Mockito.spy(new ServiceInstancesChangedListener(serviceNames, null));
- Mockito.doNothing().when(changedListener).onEvent(Mockito.any());
-
- serviceInstance.getMetadata().put("a", "c");
- dnsServiceDiscovery.update(serviceInstance);
-
- serviceInstances = dnsServiceDiscovery.getInstances("Test.Service.");
- assertEquals("c", serviceInstances.get(0).getMetadata("a"));
-
- ArgumentCaptor<ServiceInstancesChangedEvent> argument = ArgumentCaptor.forClass(ServiceInstancesChangedEvent.class);
- dnsServiceDiscovery.addServiceInstancesChangedListener(changedListener);
- Thread.sleep(1000);
- Mockito.verify(changedListener, Mockito.timeout(1000)).onEvent(argument.capture());
- assertEquals("c", argument.getValue().getServiceInstances().get(0).getMetadata("a"));
-
- Mockito.when(dnsResolver.resolve("Test.Service.")).thenReturn(new ResolveResult());
-
- Thread.sleep(1000);
- assertTrue(dnsServiceDiscovery.getCachedServiceInstances().get("Test.Service.").isEmpty());
-
- metadataService.exportInstanceMetadata(null);
- metadataService.getInstanceMetadataChangedListenerMap().clear();
- serviceConfig.unexport();
-
- dnsServiceDiscovery.destroy();
- applicationModel.getModelEnvironment().getAppExternalConfigMap()
- .remove(METADATA_PROXY_TIMEOUT_KEY);
- }
-
- private ServiceConfig<MetadataService> exportMockMetadataService(MetadataService metadataService, int port) {
- ServiceConfig<MetadataService> serviceConfig = new ServiceConfig<>();
- serviceConfig.setProtocol(new ProtocolConfig(DUBBO_PROTOCOL, port));
- serviceConfig.setRegistry(new RegistryConfig("239.255.255.255", "multicast"));
- serviceConfig.setInterface(MetadataService.class);
- serviceConfig.setRef(metadataService);
- serviceConfig.setGroup("Test.Service.");
- serviceConfig.setVersion(MetadataService.VERSION);
- MethodConfig methodConfig = new MethodConfig();
- methodConfig.setName("getAndListenInstanceMetadata");
-
- ArgumentConfig argumentConfig = new ArgumentConfig();
- argumentConfig.setIndex(1);
- argumentConfig.setCallback(true);
-
- methodConfig.setArguments(Collections.singletonList(argumentConfig));
- serviceConfig.setMethods(Collections.singletonList(methodConfig));
-
- serviceConfig.export();
-
- return serviceConfig;
- }
-}
diff --git a/dubbo-registry/dubbo-registry-dns/src/test/java/org/apache/dubbo/registry/dns/util/DNSResolverTest.java b/dubbo-registry/dubbo-registry-dns/src/test/java/org/apache/dubbo/registry/dns/util/DNSResolverTest.java
deleted file mode 100644
index 17088ac..0000000
--- a/dubbo-registry/dubbo-registry-dns/src/test/java/org/apache/dubbo/registry/dns/util/DNSResolverTest.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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.dns.util;
-
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.Test;
-
-public class DNSResolverTest {
-
- @Test
- public void testResolve() {
- DNSResolver dnsResolver = new DNSResolver("8.8.8.8", 53, 1);
- ResolveResult resolve = dnsResolver.resolve("aliyun.com");
- Assertions.assertTrue(resolve.getHostnameList().size() > 0);
- }
-}
diff --git a/dubbo-registry/dubbo-registry-dns/src/test/resources/dubbo.properties b/dubbo-registry/dubbo-registry-dns/src/test/resources/dubbo.properties
deleted file mode 100644
index 1aade88..0000000
--- a/dubbo-registry/dubbo-registry-dns/src/test/resources/dubbo.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-dubbo.application.enable-file-cache=false
-dubbo.service.shutdown.wait=200
diff --git a/dubbo-registry/dubbo-registry-kubernetes/pom.xml b/dubbo-registry/dubbo-registry-kubernetes/pom.xml
deleted file mode 100644
index 799e45e..0000000
--- a/dubbo-registry/dubbo-registry-kubernetes/pom.xml
+++ /dev/null
@@ -1,73 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ 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.
- -->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.dubbo</groupId>
- <artifactId>dubbo-registry</artifactId>
- <version>${revision}</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>dubbo-registry-kubernetes</artifactId>
- <packaging>jar</packaging>
- <name>${project.artifactId}</name>
- <description>The Kubernetes registry module of Dubbo project</description>
-
- <dependencies>
- <dependency>
- <groupId>org.apache.dubbo</groupId>
- <artifactId>dubbo-registry-api</artifactId>
- <version>${project.version}</version>
- </dependency>
-
- <dependency>
- <groupId>org.apache.dubbo</groupId>
- <artifactId>dubbo-common</artifactId>
- <version>${project.version}</version>
- </dependency>
-
- <dependency>
- <groupId>io.fabric8</groupId>
- <artifactId>kubernetes-client</artifactId>
- </dependency>
-
- <dependency>
- <groupId>io.fabric8</groupId>
- <artifactId>kubernetes-server-mock</artifactId>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-core</artifactId>
- <version>3.4.6</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-junit-jupiter</artifactId>
- <version>3.4.6</version>
- <scope>test</scope>
- </dependency>
-
- </dependencies>
-
-</project>
\ No newline at end of file
diff --git a/dubbo-registry/dubbo-registry-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/KubernetesMeshEnvListener.java b/dubbo-registry/dubbo-registry-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/KubernetesMeshEnvListener.java
deleted file mode 100644
index 1a0c1fa..0000000
--- a/dubbo-registry/dubbo-registry-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/KubernetesMeshEnvListener.java
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * 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.kubernetes;
-
-import org.apache.dubbo.common.logger.Logger;
-import org.apache.dubbo.common.logger.LoggerFactory;
-import org.apache.dubbo.rpc.cluster.router.mesh.route.MeshAppRuleListener;
-import org.apache.dubbo.rpc.cluster.router.mesh.route.MeshEnvListener;
-
-import com.google.gson.Gson;
-import io.fabric8.kubernetes.api.model.ListOptionsBuilder;
-import io.fabric8.kubernetes.client.KubernetesClient;
-import io.fabric8.kubernetes.client.Watch;
-import io.fabric8.kubernetes.client.Watcher;
-import io.fabric8.kubernetes.client.WatcherException;
-import org.yaml.snakeyaml.Yaml;
-import org.yaml.snakeyaml.constructor.SafeConstructor;
-
-import java.io.IOException;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-public class KubernetesMeshEnvListener implements MeshEnvListener {
- public static final Logger logger = LoggerFactory.getLogger(KubernetesMeshEnvListener.class);
- private volatile static boolean usingApiServer = false;
- private volatile static KubernetesClient kubernetesClient;
- private volatile static String namespace;
-
- private final Map<String, MeshAppRuleListener> appRuleListenerMap = new ConcurrentHashMap<>();
-
- private final Map<String, Watch> vsAppWatch = new ConcurrentHashMap<>();
- private final Map<String, Watch> drAppWatch = new ConcurrentHashMap<>();
-
- private final Map<String, String> vsAppCache = new ConcurrentHashMap<>();
- private final Map<String, String> drAppCache = new ConcurrentHashMap<>();
-
- public static void injectKubernetesEnv(KubernetesClient client, String configuredNamespace) {
- usingApiServer = true;
- kubernetesClient = client;
- namespace = configuredNamespace;
- }
-
- @Override
- public boolean isEnable() {
- return usingApiServer;
- }
-
- @Override
- public void onSubscribe(String appName, MeshAppRuleListener listener) {
- appRuleListenerMap.put(appName, listener);
- logger.info("Subscribe Mesh Rule in Kubernetes. AppName: " + appName);
-
- // subscribe VisualService
- subscribeVs(appName);
-
- // subscribe DestinationRule
- subscribeDr(appName);
-
- // notify for start
- notifyOnce(appName);
- }
-
- private void subscribeVs(String appName) {
- if (vsAppWatch.containsKey(appName)) {
- return;
- }
-
- try {
- Watch watch = kubernetesClient
- .customResource(
- MeshConstant.getVsDefinition())
- .watch(namespace, appName, null, new ListOptionsBuilder().build(), new Watcher<String>() {
- @Override
- public void eventReceived(Action action, String resource) {
- logger.info("Received VS Rule notification. AppName: " + appName + " Action:" + action + " Resource:" + resource);
-
- if (action == Action.ADDED || action == Action.MODIFIED) {
- Map drRuleMap = new Gson().fromJson(resource, Map.class);
- String vsRule = new Yaml(new SafeConstructor()).dump(drRuleMap);
- vsAppCache.put(appName, vsRule);
- if (drAppCache.containsKey(appName)) {
- notifyListener(vsRule, appName, drAppCache.get(appName));
- }
- } else {
- appRuleListenerMap.get(appName).receiveConfigInfo("");
- }
- }
-
- @Override
- public void onClose(WatcherException cause) {
- // ignore
- }
- });
- vsAppWatch.put(appName, watch);
- try {
- Map<String, Object> vsRule = kubernetesClient
- .customResource(
- MeshConstant.getVsDefinition())
- .get(namespace, appName);
- vsAppCache.put(appName, new Yaml(new SafeConstructor()).dump(vsRule));
- } catch (Throwable ignore) {
-
- }
- } catch (IOException e) {
- logger.error("Error occurred when listen kubernetes crd.", e);
- }
- }
-
- private void notifyListener(String vsRule, String appName, String drRule) {
- String rule = vsRule + "\n---\n" + drRule;
- logger.info("Notify App Rule Listener. AppName: " + appName + " Rule:" + rule);
-
- appRuleListenerMap.get(appName).receiveConfigInfo(rule);
- }
-
- private void subscribeDr(String appName) {
- if (drAppWatch.containsKey(appName)) {
- return;
- }
-
- try {
- Watch watch = kubernetesClient
- .customResource(
- MeshConstant.getDrDefinition())
- .watch(namespace, appName, null, new ListOptionsBuilder().build(), new Watcher<String>() {
- @Override
- public void eventReceived(Action action, String resource) {
- logger.info("Received VS Rule notification. AppName: " + appName + " Action:" + action + " Resource:" + resource);
-
- if (action == Action.ADDED || action == Action.MODIFIED) {
- Map drRuleMap = new Gson().fromJson(resource, Map.class);
- String drRule = new Yaml(new SafeConstructor()).dump(drRuleMap);
-
- drAppCache.put(appName, drRule);
- if (vsAppCache.containsKey(appName)) {
- notifyListener(vsAppCache.get(appName), appName, drRule);
- }
- } else {
- appRuleListenerMap.get(appName).receiveConfigInfo("");
- }
- }
-
- @Override
- public void onClose(WatcherException cause) {
- // ignore
- }
- });
- drAppWatch.put(appName, watch);
- try {
- Map<String, Object> drRule = kubernetesClient
- .customResource(
- MeshConstant.getDrDefinition())
- .get(namespace, appName);
- drAppCache.put(appName, new Yaml(new SafeConstructor()).dump(drRule));
- } catch (Throwable ignore) {
-
- }
- } catch (IOException e) {
- logger.error("Error occurred when listen kubernetes crd.", e);
- }
- }
-
- private void notifyOnce(String appName) {
- if (vsAppCache.containsKey(appName) && drAppCache.containsKey(appName)) {
- notifyListener(vsAppCache.get(appName), appName, drAppCache.get(appName));
- }
- }
-
- @Override
- public void onUnSubscribe(String appName) {
- appRuleListenerMap.remove(appName);
-
- if (vsAppWatch.containsKey(appName)) {
- vsAppWatch.remove(appName).close();
- }
- vsAppCache.remove(appName);
-
- if (drAppWatch.containsKey(appName)) {
- drAppWatch.remove(appName).close();
- }
- drAppCache.remove(appName);
- }
-}
diff --git a/dubbo-registry/dubbo-registry-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/KubernetesMeshEnvListenerFactory.java b/dubbo-registry/dubbo-registry-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/KubernetesMeshEnvListenerFactory.java
deleted file mode 100644
index 67b1b4c..0000000
--- a/dubbo-registry/dubbo-registry-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/KubernetesMeshEnvListenerFactory.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.kubernetes;
-
-import org.apache.dubbo.common.logger.Logger;
-import org.apache.dubbo.common.logger.LoggerFactory;
-import org.apache.dubbo.rpc.cluster.router.mesh.route.MeshEnvListener;
-import org.apache.dubbo.rpc.cluster.router.mesh.route.MeshEnvListenerFactory;
-
-import java.util.concurrent.atomic.AtomicBoolean;
-
-public class KubernetesMeshEnvListenerFactory implements MeshEnvListenerFactory {
- public static final Logger logger = LoggerFactory.getLogger(KubernetesMeshEnvListenerFactory.class);
- private final AtomicBoolean initialized = new AtomicBoolean(false);
- private MeshEnvListener listener = null;
-
- @Override
- public MeshEnvListener getListener() {
- try {
- if (initialized.compareAndSet(false, true)) {
- listener = new KubernetesMeshEnvListener();
- }
- } catch (Throwable t) {
- logger.info("Current Env not support Kubernetes.");
- }
- return listener;
- }
-}
diff --git a/dubbo-registry/dubbo-registry-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/KubernetesRegistry.java b/dubbo-registry/dubbo-registry-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/KubernetesRegistry.java
deleted file mode 100644
index b221c89..0000000
--- a/dubbo-registry/dubbo-registry-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/KubernetesRegistry.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * 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.kubernetes;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.registry.NotifyListener;
-import org.apache.dubbo.registry.support.FailbackRegistry;
-
-/**
- * Empty implements for Kubernetes <br/>
- * Kubernetes only support `Service Discovery` mode register <br/>
- * Used to compat past version like 2.6.x, 2.7.x with interface level register <br/>
- * {@link KubernetesServiceDiscovery} is the real implementation of Kubernetes
- */
-public class KubernetesRegistry extends FailbackRegistry {
- public KubernetesRegistry(URL url) {
- super(url);
- }
-
- @Override
- public boolean isAvailable() {
- return true;
- }
-
- @Override
- public void doRegister(URL url) {
-
- }
-
- @Override
- public void doUnregister(URL url) {
-
- }
-
- @Override
- public void doSubscribe(URL url, NotifyListener listener) {
-
- }
-
- @Override
- public void doUnsubscribe(URL url, NotifyListener listener) {
-
- }
-}
diff --git a/dubbo-registry/dubbo-registry-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/KubernetesRegistryFactory.java b/dubbo-registry/dubbo-registry-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/KubernetesRegistryFactory.java
deleted file mode 100644
index ab9af54..0000000
--- a/dubbo-registry/dubbo-registry-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/KubernetesRegistryFactory.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.kubernetes;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.registry.Registry;
-import org.apache.dubbo.registry.support.AbstractRegistryFactory;
-
-public class KubernetesRegistryFactory extends AbstractRegistryFactory {
-
- @Override
- protected String createRegistryCacheKey(URL url) {
- return url.toFullString();
- }
-
- @Override
- protected Registry createRegistry(URL url) {
- return new KubernetesRegistry(url);
- }
-}
diff --git a/dubbo-registry/dubbo-registry-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/KubernetesServiceDiscovery.java b/dubbo-registry/dubbo-registry-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/KubernetesServiceDiscovery.java
deleted file mode 100644
index f9d58f6..0000000
--- a/dubbo-registry/dubbo-registry-kubernetes/src/main/java/org/apache/dubbo/registry/kubernetes/KubernetesServiceDiscovery.java
+++ /dev/null
@@ -1,399 +0,0 @@
-/*
- * 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.kubernetes;
-
-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.registry.client.AbstractServiceDiscovery;
-import org.apache.dubbo.registry.client.DefaultServiceInstance;
-import org.apache.dubbo.registry.client.ServiceInstance;
-import org.apache.dubbo.registry.client.event.ServiceInstancesChangedEvent;
-import org.apache.dubbo.registry.client.event.listener.ServiceInstancesChangedListener;
-import org.apache.dubbo.registry.kubernetes.util.KubernetesClientConst;
-import org.apache.dubbo.registry.kubernetes.util.KubernetesConfigUtils;
-import org.apache.dubbo.rpc.model.ScopeModelUtil;
-
-import com.alibaba.fastjson.JSONObject;
-import io.fabric8.kubernetes.api.model.EndpointAddress;
-import io.fabric8.kubernetes.api.model.EndpointPort;
-import io.fabric8.kubernetes.api.model.EndpointSubset;
-import io.fabric8.kubernetes.api.model.Endpoints;
-import io.fabric8.kubernetes.api.model.Pod;
-import io.fabric8.kubernetes.api.model.PodBuilder;
-import io.fabric8.kubernetes.api.model.Service;
-import io.fabric8.kubernetes.client.Config;
-import io.fabric8.kubernetes.client.DefaultKubernetesClient;
-import io.fabric8.kubernetes.client.KubernetesClient;
-import io.fabric8.kubernetes.client.Watch;
-import io.fabric8.kubernetes.client.Watcher;
-import io.fabric8.kubernetes.client.WatcherException;
-
-import java.util.HashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.stream.Collectors;
-
-public class KubernetesServiceDiscovery extends AbstractServiceDiscovery {
- private final Logger logger = LoggerFactory.getLogger(getClass());
-
- private KubernetesClient kubernetesClient;
-
- private String currentHostname;
-
- private URL registryURL;
-
- private String namespace;
-
- private boolean enableRegister;
-
- public final static String KUBERNETES_PROPERTIES_KEY = "io.dubbo/metadata";
-
- private final static ConcurrentHashMap<String, Watch> SERVICE_WATCHER = new ConcurrentHashMap<>(64);
-
- private final static ConcurrentHashMap<String, Watch> PODS_WATCHER = new ConcurrentHashMap<>(64);
-
- private final static ConcurrentHashMap<String, Watch> ENDPOINTS_WATCHER = new ConcurrentHashMap<>(64);
-
- private final static ConcurrentHashMap<String, AtomicLong> SERVICE_UPDATE_TIME = new ConcurrentHashMap<>(64);
-
- @Override
- public void doInitialize(URL registryURL) throws Exception {
- Config config = KubernetesConfigUtils.createKubernetesConfig(registryURL);
- this.kubernetesClient = new DefaultKubernetesClient(config);
- this.currentHostname = System.getenv("HOSTNAME");
- this.registryURL = registryURL;
- this.namespace = config.getNamespace();
- this.enableRegister = registryURL.getParameter(KubernetesClientConst.ENABLE_REGISTER, true);
-
- boolean availableAccess;
- try {
- availableAccess = kubernetesClient.pods().withName(currentHostname).get() != null;
- } catch (Throwable e) {
- availableAccess = false;
- }
- if (!availableAccess) {
- String message = "Unable to access api server. " +
- "Please check your url config." +
- " Master URL: " + config.getMasterUrl() +
- " Hostname: " + currentHostname;
- logger.error(message);
- } else {
- KubernetesMeshEnvListener.injectKubernetesEnv(kubernetesClient, namespace);
- }
- }
-
- @Override
- public void doDestroy() throws Exception {
- SERVICE_WATCHER.forEach((k, v) -> v.close());
- SERVICE_WATCHER.clear();
-
- PODS_WATCHER.forEach((k, v) -> v.close());
- PODS_WATCHER.clear();
-
- ENDPOINTS_WATCHER.forEach((k, v) -> v.close());
- ENDPOINTS_WATCHER.clear();
-
- kubernetesClient.close();
- }
-
- @Override
- public void doRegister(ServiceInstance serviceInstance) throws RuntimeException {
- if (enableRegister) {
- kubernetesClient
- .pods()
- .inNamespace(namespace)
- .withName(currentHostname)
- .edit(pod ->
- new PodBuilder(pod)
- .editOrNewMetadata()
- .addToAnnotations(KUBERNETES_PROPERTIES_KEY, JSONObject.toJSONString(serviceInstance.getMetadata()))
- .endMetadata()
- .build());
- if (logger.isInfoEnabled()) {
- logger.info("Write Current Service Instance Metadata to Kubernetes pod. " +
- "Current pod name: " + currentHostname);
- }
- }
- }
-
- @Override
- public void doUpdate(ServiceInstance serviceInstance) throws RuntimeException {
- register(serviceInstance);
- }
-
- @Override
- public void doUnregister(ServiceInstance serviceInstance) throws RuntimeException {
- if (enableRegister) {
- kubernetesClient
- .pods()
- .inNamespace(namespace)
- .withName(currentHostname)
- .edit(pod ->
- new PodBuilder(pod)
- .editOrNewMetadata()
- .removeFromAnnotations(KUBERNETES_PROPERTIES_KEY)
- .endMetadata()
- .build());
- if (logger.isInfoEnabled()) {
- logger.info("Remove Current Service Instance from Kubernetes pod. Current pod name: " + currentHostname);
- }
- }
- }
-
- @Override
- public Set<String> getServices() {
- return kubernetesClient
- .services()
- .inNamespace(namespace)
- .list()
- .getItems()
- .stream()
- .map(service -> service.getMetadata().getName())
- .collect(Collectors.toSet());
- }
-
- @Override
- public List<ServiceInstance> getInstances(String serviceName) throws NullPointerException {
- Endpoints endpoints =
- kubernetesClient
- .endpoints()
- .inNamespace(namespace)
- .withName(serviceName)
- .get();
-
- return toServiceInstance(endpoints, serviceName);
- }
-
- @Override
- public void addServiceInstancesChangedListener(ServiceInstancesChangedListener listener) throws NullPointerException, IllegalArgumentException {
- listener.getServiceNames().forEach(serviceName -> {
- SERVICE_UPDATE_TIME.put(serviceName, new AtomicLong(0L));
-
- // Watch Service Endpoint Modification
- watchEndpoints(listener, serviceName);
-
- // Watch Pods Modification, happens when ServiceInstance updated
- watchPods(listener, serviceName);
-
- // Watch Service Modification, happens when Service Selector updated, used to update pods watcher
- watchService(listener, serviceName);
- });
- }
-
- private void watchEndpoints(ServiceInstancesChangedListener listener, String serviceName) {
- Watch watch = kubernetesClient
- .endpoints()
- .inNamespace(namespace)
- .withName(serviceName)
- .watch(new Watcher<Endpoints>() {
- @Override
- public void eventReceived(Action action, Endpoints resource) {
- if (logger.isDebugEnabled()) {
- logger.debug("Received Endpoint Event. Event type: " + action.name() +
- ". Current pod name: " + currentHostname);
- }
-
- notifyServiceChanged(serviceName, listener);
- }
-
- @Override
- public void onClose(WatcherException cause) {
- // ignore
- }
- });
... 3495 lines suppressed ...