urls = serviceBean.getExportedUrls();
urls.stream()
- .map(SpringCloudRegistry::getServiceName)
- .forEach(serviceName -> {
+ .map(URL::toString)
+ .forEach(url -> {
ServiceRestMetadata metadata = new ServiceRestMetadata();
- metadata.setName(serviceName);
+ metadata.setUrl(url);
metadata.setMeta(methodRestMetadata);
serviceRestMetadata.add(metadata);
});
diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/openfeign/TargeterBeanPostProcessor.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/openfeign/TargeterBeanPostProcessor.java
index a4a3c77f..331e7a00 100644
--- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/openfeign/TargeterBeanPostProcessor.java
+++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/openfeign/TargeterBeanPostProcessor.java
@@ -25,6 +25,7 @@ import org.springframework.cloud.alibaba.dubbo.service.DubboGenericServiceFactor
import org.springframework.core.env.Environment;
import static java.lang.reflect.Proxy.newProxyInstance;
+import static org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboOpenFeignAutoConfiguration.TARGETER_CLASS_NAME;
import static org.springframework.util.ClassUtils.getUserClass;
import static org.springframework.util.ClassUtils.isPresent;
import static org.springframework.util.ClassUtils.resolveClassName;
@@ -36,8 +37,6 @@ import static org.springframework.util.ClassUtils.resolveClassName;
*/
public class TargeterBeanPostProcessor implements BeanPostProcessor, BeanClassLoaderAware {
- private static final String TARGETER_CLASS_NAME = "org.springframework.cloud.openfeign.Targeter";
-
private final Environment environment;
private final DubboServiceMetadataRepository dubboServiceMetadataRepository;
diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/AbstractRegistrationFactory.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/AbstractRegistrationFactory.java
index d0465342..8cd29998 100644
--- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/AbstractRegistrationFactory.java
+++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/AbstractRegistrationFactory.java
@@ -18,10 +18,11 @@ package org.springframework.cloud.alibaba.dubbo.registry;
import org.apache.dubbo.common.Constants;
import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.utils.NetUtils;
+import org.springframework.cloud.alibaba.dubbo.registry.handler.DubboRegistryServiceIdHandler;
import org.springframework.cloud.client.DefaultServiceInstance;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.serviceregistry.Registration;
+import org.springframework.context.ConfigurableApplicationContext;
import java.util.LinkedHashMap;
@@ -29,20 +30,49 @@ import java.util.LinkedHashMap;
* Abstract {@link RegistrationFactory} implementation
*
*
- * @param The subclass of {@link Registration}
+ * @param The subclass of {@link Registration}
* @author Mercy
*/
-public abstract class AbstractRegistrationFactory implements RegistrationFactory {
+public abstract class AbstractRegistrationFactory implements RegistrationFactory {
- protected ServiceInstance createServiceInstance(String serviceName, URL url) {
+ public final R create(URL url, ConfigurableApplicationContext applicationContext) {
+ ServiceInstance serviceInstance = createServiceInstance(url, applicationContext);
+ return create(url, applicationContext, serviceInstance);
+ }
+
+ /**
+ * Sub-class should override this method to create an instance of {@link R}
+ *
+ * @param url The Dubbo's {@link URL}
+ * @param applicationContext {@link ConfigurableApplicationContext}
+ * @param serviceInstance {@link ServiceInstance}
+ * @return nullable
+ */
+ protected abstract R create(URL url, ConfigurableApplicationContext applicationContext, ServiceInstance serviceInstance);
+
+ /**
+ * Create an instance {@link ServiceInstance}. This method maybe override by sub-class.
+ *
+ * @param url The Dubbo's {@link URL}
+ * @param applicationContext {@link ConfigurableApplicationContext}
+ * @return an instance {@link ServiceInstance}
+ */
+ protected ServiceInstance createServiceInstance(URL url, ConfigurableApplicationContext applicationContext) {
+ String serviceId = createServiceId(url, applicationContext);
// Append default category if absent
String category = url.getParameter(Constants.CATEGORY_KEY, Constants.DEFAULT_CATEGORY);
URL newURL = url.addParameter(Constants.CATEGORY_KEY, category);
newURL = newURL.addParameter(Constants.PROTOCOL_KEY, url.getProtocol());
- String ip = NetUtils.getLocalHost();
+ String ip = url.getIp();
int port = newURL.getParameter(Constants.BIND_PORT_KEY, url.getPort());
- DefaultServiceInstance serviceInstance = new DefaultServiceInstance(url.toIdentityString(), serviceName, ip, port, false);
+ DefaultServiceInstance serviceInstance = new DefaultServiceInstance(url.toIdentityString(), serviceId, ip, port, false);
serviceInstance.getMetadata().putAll(new LinkedHashMap<>(newURL.getParameters()));
return serviceInstance;
}
+
+ protected String createServiceId(URL url, ConfigurableApplicationContext applicationContext) {
+ DubboRegistryServiceIdHandler handler = applicationContext.getBean(DubboRegistryServiceIdHandler.class);
+ return handler.createServiceId(url);
+ }
}
+
diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/DefaultRegistrationFactory.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/DefaultRegistrationFactory.java
index d9960574..30865768 100644
--- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/DefaultRegistrationFactory.java
+++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/DefaultRegistrationFactory.java
@@ -17,8 +17,9 @@
package org.springframework.cloud.alibaba.dubbo.registry;
import org.apache.dubbo.common.URL;
+import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.serviceregistry.Registration;
-import org.springframework.context.ApplicationContext;
+import org.springframework.context.ConfigurableApplicationContext;
/**
* Default {@link RegistrationFactory}
@@ -28,7 +29,7 @@ import org.springframework.context.ApplicationContext;
public class DefaultRegistrationFactory extends AbstractRegistrationFactory {
@Override
- public Registration create(String serviceName, URL url, ApplicationContext applicationContext) {
- return new DelegatingRegistration(createServiceInstance(serviceName, url));
+ protected Registration create(URL url, ConfigurableApplicationContext applicationContext, ServiceInstance serviceInstance) {
+ return new DelegatingRegistration(serviceInstance);
}
}
diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/RegistrationFactory.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/RegistrationFactory.java
index d7c34712..d7d97737 100644
--- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/RegistrationFactory.java
+++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/RegistrationFactory.java
@@ -18,24 +18,23 @@ package org.springframework.cloud.alibaba.dubbo.registry;
import org.apache.dubbo.common.URL;
import org.springframework.cloud.client.serviceregistry.Registration;
-import org.springframework.context.ApplicationContext;
+import org.springframework.context.ConfigurableApplicationContext;
/**
* {@link Registration} Factory to createServiceInstance a instance of {@link Registration}
*
- * @param The subclass of {@link Registration}
+ * @param The subclass of {@link Registration}
* @author Mercy
*/
-public interface RegistrationFactory {
+public interface RegistrationFactory {
/**
- * Create a instance of {@link T}
+ * Create a instance of {@link R}
*
- * @param serviceName The service name of Dubbo service interface
- * @param url The Dubbo's URL
- * @param applicationContext {@link ApplicationContext}
- * @return a instance of {@link T}
+ * @param url The Dubbo's {@link URL}
+ * @param applicationContext {@link ConfigurableApplicationContext}
+ * @return a instance of {@link R}, if null, it indicates the registration will not be executed.
*/
- T create(String serviceName, URL url, ApplicationContext applicationContext);
+ R create(URL url, ConfigurableApplicationContext applicationContext);
}
diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/SpringCloudRegistry.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/SpringCloudRegistry.java
index 99222a4d..d87e1f6c 100644
--- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/SpringCloudRegistry.java
+++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/SpringCloudRegistry.java
@@ -18,44 +18,35 @@ package org.springframework.cloud.alibaba.dubbo.registry;
import org.apache.dubbo.common.Constants;
import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.utils.NamedThreadFactory;
import org.apache.dubbo.common.utils.UrlUtils;
import org.apache.dubbo.registry.NotifyListener;
import org.apache.dubbo.registry.RegistryFactory;
import org.apache.dubbo.registry.support.FailbackRegistry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.cloud.alibaba.dubbo.registry.handler.DubboRegistryServiceIdHandler;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.serviceregistry.Registration;
import org.springframework.cloud.client.serviceregistry.ServiceRegistry;
-import org.springframework.context.ApplicationContext;
-import org.springframework.core.ResolvableType;
-import org.springframework.util.StringUtils;
+import org.springframework.context.ConfigurableApplicationContext;
-import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
-import java.util.Objects;
+import java.util.Map;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
-import static com.alibaba.dubbo.common.Constants.CONFIGURATORS_CATEGORY;
-import static com.alibaba.dubbo.common.Constants.CONSUMERS_CATEGORY;
-import static com.alibaba.dubbo.common.Constants.PROVIDERS_CATEGORY;
-import static com.alibaba.dubbo.common.Constants.ROUTERS_CATEGORY;
-import static java.lang.Long.getLong;
-import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
-import static org.springframework.beans.BeanUtils.instantiateClass;
-import static org.springframework.core.ResolvableType.forInstance;
-import static org.springframework.core.ResolvableType.forType;
-import static org.springframework.core.io.support.SpringFactoriesLoader.loadFactoryNames;
-import static org.springframework.util.ClassUtils.isPresent;
-import static org.springframework.util.ClassUtils.resolveClassName;
+import static java.util.Collections.singletonList;
+import static org.apache.dubbo.common.Constants.CONFIGURATORS_CATEGORY;
+import static org.apache.dubbo.common.Constants.CONSUMERS_CATEGORY;
+import static org.apache.dubbo.common.Constants.PROVIDERS_CATEGORY;
+import static org.apache.dubbo.common.Constants.PROVIDER_SIDE;
+import static org.apache.dubbo.common.Constants.ROUTERS_CATEGORY;
+import static org.apache.dubbo.common.Constants.SIDE_KEY;
/**
* Dubbo {@link RegistryFactory} uses Spring Cloud Service Registration abstraction, whose protocol is "spring-cloud"
@@ -64,169 +55,96 @@ import static org.springframework.util.ClassUtils.resolveClassName;
*/
public class SpringCloudRegistry extends FailbackRegistry {
+ /**
+ * The parameter name of {@link #allServicesLookupInterval}
+ */
+ public static final String ALL_SERVICES_LOOKUP_INTERVAL_PARAM_NAME = "dubbo.all.services.lookup.interval";
+
+ /**
+ * The parameter name of {@link #registeredServicesLookupInterval}
+ */
+ public static final String REGISTERED_SERVICES_LOOKUP_INTERVAL_PARAM_NAME = "dubbo.registered.services.lookup.interval";
+
/**
* All supported categories
*/
- private static final String[] ALL_SUPPORTED_CATEGORIES = of(
+ public static final String[] ALL_SUPPORTED_CATEGORIES = of(
PROVIDERS_CATEGORY,
CONSUMERS_CATEGORY,
ROUTERS_CATEGORY,
CONFIGURATORS_CATEGORY
);
- private static final int CATEGORY_INDEX = 0;
-
- private static final int SERVICE_INTERFACE_INDEX = CATEGORY_INDEX + 1;
-
- private static final int SERVICE_VERSION_INDEX = SERVICE_INTERFACE_INDEX + 1;
-
- private static final int SERVICE_GROUP_INDEX = SERVICE_VERSION_INDEX + 1;
-
- private static final String WILDCARD = "*";
+ private final Logger logger = LoggerFactory.getLogger(getClass());
/**
* The interval in second of lookup service names(only for Dubbo-OPS)
*/
- private static final long ALL_SERVICES_LOOKUP_INTERVAL = getLong("dubbo.all.services.lookup.interval", 30);
+ private final long allServicesLookupInterval;
- /**
- * The interval in second of lookup regigered service instances
- */
- private static final long REGISTERED_SERVICES_LOOKUP_INTERVAL = getLong("dubbo.registered.services.lookup.interval", 300);
-
- /**
- * The {@link ScheduledExecutorService Scheduler} to lookup the registered services
- */
- private static final ScheduledExecutorService registeredServicesLookupScheduler = newSingleThreadScheduledExecutor(new NamedThreadFactory("dubbo-registered-services-lookup-"));
-
- /**
- * The {@link ScheduledExecutorService Scheduler} to lookup all services (only for Dubbo-OPS)
- */
- private static volatile ScheduledExecutorService allServicesLookupScheduler;
-
- private final Logger logger = LoggerFactory.getLogger(getClass());
-
- /**
- * The separator for service name
- */
- private static final String SERVICE_NAME_SEPARATOR = ":";
-
- private final ApplicationContext applicationContext;
+ private final long registeredServicesLookupInterval;
private final ServiceRegistry serviceRegistry;
- private final DiscoveryClient discoveryClient;
-
private final RegistrationFactory registrationFactory;
- public SpringCloudRegistry(URL url, ApplicationContext applicationContext) {
+ private final DiscoveryClient discoveryClient;
+
+ private final DubboRegistryServiceIdHandler dubboRegistryServiceIdHandler;
+
+ private final ScheduledExecutorService servicesLookupScheduler;
+
+ private final ConfigurableApplicationContext applicationContext;
+
+ public SpringCloudRegistry(URL url,
+ ServiceRegistry serviceRegistry,
+ RegistrationFactory registrationFactory,
+ DiscoveryClient discoveryClient,
+ ScheduledExecutorService servicesLookupScheduler,
+ ConfigurableApplicationContext applicationContext) {
super(url);
+ this.allServicesLookupInterval = url.getParameter(ALL_SERVICES_LOOKUP_INTERVAL_PARAM_NAME, 30L);
+ this.registeredServicesLookupInterval = url.getParameter(REGISTERED_SERVICES_LOOKUP_INTERVAL_PARAM_NAME, 300L);
+ this.serviceRegistry = serviceRegistry;
+ this.registrationFactory = registrationFactory;
+ this.discoveryClient = discoveryClient;
+ this.dubboRegistryServiceIdHandler = applicationContext.getBean(DubboRegistryServiceIdHandler.class);
this.applicationContext = applicationContext;
- this.serviceRegistry = applicationContext.getBean(ServiceRegistry.class);
- this.registrationFactory = buildRegistrationFactory(serviceRegistry, applicationContext.getClassLoader());
- this.discoveryClient = applicationContext.getBean(DiscoveryClient.class);
- applicationContext.getClassLoader();
+ this.servicesLookupScheduler = servicesLookupScheduler;
}
- private RegistrationFactory buildRegistrationFactory(ServiceRegistry serviceRegistry,
- ClassLoader classLoader) {
- RegistrationFactory registrationFactory = null;
- List factoryClassNames = loadFactoryNames(RegistrationFactory.class, classLoader);
-
- ResolvableType serviceRegistryType = forInstance(serviceRegistry);
- // Get first generic Class
- Class> registrationClass = resolveGenericClass(serviceRegistryType, ServiceRegistry.class, 0);
-
- for (String factoryClassName : factoryClassNames) {
- if (isPresent(factoryClassName, classLoader)) { // ignore compilation issue
- Class> factoryClass = resolveClassName(factoryClassName, classLoader);
- ResolvableType registrationFactoryType = forType(factoryClass);
- Class> actualRegistrationClass = resolveGenericClass(registrationFactoryType, RegistrationFactory.class, 0);
- if (registrationClass.equals(actualRegistrationClass)) {
- registrationFactory = (RegistrationFactory) instantiateClass(registrationFactoryType.getRawClass());
- break;
- }
- }
- }
-
- if (registrationFactory == null) {
-
- if (logger.isWarnEnabled()) {
- logger.warn("{} implementation can't be resolved by ServiceRegistry[{}]",
- registrationClass.getSimpleName(), serviceRegistry.getClass().getName());
- }
-
- registrationFactory = new DefaultRegistrationFactory();
- } else {
- if (logger.isInfoEnabled()) {
- logger.info("{} has been resolved by ServiceRegistry[{}]",
- registrationFactory.getClass().getName(), serviceRegistry.getClass().getName());
- }
- }
-
- return registrationFactory;
+ protected boolean shouldRegister(Registration registration) {
+ Map metadata = registration.getMetadata();
+ String side = metadata.get(SIDE_KEY);
+ return PROVIDER_SIDE.equals(side); // Only register the Provider.
}
- private Class> resolveGenericClass(ResolvableType implementedType, Class> interfaceClass, int index) {
-
- ResolvableType resolvableType = implementedType;
-
- try {
- OUTER:
- while (true) {
-
- ResolvableType[] interfaceTypes = resolvableType.getInterfaces();
-
- for (ResolvableType interfaceType : interfaceTypes) {
- if (interfaceType.resolve().equals(interfaceClass)) {
- resolvableType = interfaceType;
- break OUTER;
- }
- }
-
- ResolvableType superType = resolvableType.getSuperType();
-
- Class> superClass = superType.resolve();
-
- if (Object.class.equals(superClass)) {
- break;
- }
-
- resolvableType = superType;
- }
-
- } catch (Throwable e) {
- resolvableType = ResolvableType.forType(void.class);
- }
-
- return resolvableType.resolveGeneric(index);
- }
-
-
@Override
public void doRegister(URL url) {
- final String serviceName = getServiceName(url);
- final Registration registration = createRegistration(serviceName, url);
- serviceRegistry.register(registration);
+ final Registration registration = createRegistration(url);
+ if (shouldRegister(registration)) {
+ serviceRegistry.register(registration);
+ }
}
@Override
public void doUnregister(URL url) {
- final String serviceName = getServiceName(url);
- final Registration registration = createRegistration(serviceName, url);
- this.serviceRegistry.deregister(registration);
+ final Registration registration = createRegistration(url);
+ if (shouldRegister(registration)) {
+ this.serviceRegistry.deregister(registration);
+ }
}
@Override
public void doSubscribe(URL url, NotifyListener listener) {
List serviceNames = getServiceNames(url, listener);
doSubscribe(url, listener, serviceNames);
- this.registeredServicesLookupScheduler.scheduleAtFixedRate(new Runnable() {
+ this.servicesLookupScheduler.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
doSubscribe(url, listener, serviceNames);
}
- }, REGISTERED_SERVICES_LOOKUP_INTERVAL, REGISTERED_SERVICES_LOOKUP_INTERVAL, TimeUnit.SECONDS);
+ }, registeredServicesLookupInterval, registeredServicesLookupInterval, TimeUnit.SECONDS);
}
@Override
@@ -234,136 +152,34 @@ public class SpringCloudRegistry extends FailbackRegistry {
if (isAdminProtocol(url)) {
shutdownServiceNamesLookup();
}
-
-// if (registeredServicesLookupScheduler != null) {
-// registeredServicesLookupScheduler.shutdown();
-// }
}
@Override
public boolean isAvailable() {
- return false;
+ return !discoveryClient.getServices().isEmpty();
}
private void shutdownServiceNamesLookup() {
- if (allServicesLookupScheduler != null) {
- allServicesLookupScheduler.shutdown();
+ if (servicesLookupScheduler != null) {
+ servicesLookupScheduler.shutdown();
}
}
- private Registration createRegistration(String serviceName, URL url) {
- return registrationFactory.create(serviceName, url, applicationContext);
+ private Registration createRegistration(URL url) {
+ return registrationFactory.create(url, applicationContext);
}
- public static String getServiceName(URL url) {
- String category = url.getParameter(Constants.CATEGORY_KEY, Constants.DEFAULT_CATEGORY);
- return getServiceName(url, category);
- }
-
- private static String getServiceName(URL url, String category) {
- StringBuilder serviceNameBuilder = new StringBuilder(category);
- appendIfPresent(serviceNameBuilder, url, Constants.INTERFACE_KEY);
- appendIfPresent(serviceNameBuilder, url, Constants.VERSION_KEY);
- appendIfPresent(serviceNameBuilder, url, Constants.GROUP_KEY);
- return serviceNameBuilder.toString();
- }
-
- private static void appendIfPresent(StringBuilder target, URL url, String parameterName) {
- String parameterValue = url.getParameter(parameterName);
- appendIfPresent(target, parameterValue);
- }
-
- private static void appendIfPresent(StringBuilder target, String parameterValue) {
- if (StringUtils.hasText(parameterValue)) {
- target.append(SERVICE_NAME_SEPARATOR).append(parameterValue);
- }
- }
-
- private void filterServiceNames(List serviceNames, URL url) {
-
- final String[] categories = getCategories(url);
-
- final String targetServiceInterface = url.getServiceInterface();
-
- final String targetVersion = url.getParameter(Constants.VERSION_KEY);
-
- final String targetGroup = url.getParameter(Constants.GROUP_KEY);
-
+ private void filterServiceNames(List serviceNames) {
filter(serviceNames, new Filter() {
@Override
public boolean accept(String serviceName) {
- // split service name to segments
- // (required) segments[0] = category
- // (required) segments[1] = serviceInterface
- // (required) segments[2] = version
- // (optional) segments[3] = group
- String[] segments = getServiceSegments(serviceName);
- int length = segments.length;
- if (length < SERVICE_GROUP_INDEX) { // must present 4 segments or more
- return false;
- }
-
- String category = getCategory(segments);
- if (Arrays.binarySearch(categories, category) > -1) { // no match category
- return false;
- }
-
- String serviceInterface = getServiceInterface(segments);
- if (!WILDCARD.equals(targetServiceInterface) &&
- !Objects.equals(targetServiceInterface, serviceInterface)) { // no match service interface
- return false;
- }
-
- String version = getServiceVersion(segments);
- if (!WILDCARD.equals(targetVersion) &&
- !Objects.equals(targetVersion, version)) { // no match service version
- return false;
- }
-
- String group = getServiceGroup(segments);
- if (group != null && !WILDCARD.equals(targetGroup)
- && !Objects.equals(targetGroup, group)) { // no match service group
- return false;
- }
-
- return true;
+ return dubboRegistryServiceIdHandler.supports(serviceName);
}
});
}
- public static String[] getServiceSegments(String serviceName) {
- return StringUtils.delimitedListToStringArray(serviceName, SERVICE_NAME_SEPARATOR);
- }
-
- public static String getCategory(String[] segments) {
- return segments[CATEGORY_INDEX];
- }
-
- public static String getServiceInterface(String[] segments) {
- return segments[SERVICE_INTERFACE_INDEX];
- }
-
- public static String getServiceVersion(String[] segments) {
- return segments[SERVICE_VERSION_INDEX];
- }
-
- public static String getServiceGroup(String[] segments) {
- return segments.length > SERVICE_GROUP_INDEX ? segments[SERVICE_GROUP_INDEX] : null;
- }
-
- /**
- * Get the categories from {@link URL}
- *
- * @param url {@link URL}
- * @return non-null array
- */
- private String[] getCategories(URL url) {
- return Constants.ANY_VALUE.equals(url.getServiceInterface()) ?
- ALL_SUPPORTED_CATEGORIES : of(Constants.DEFAULT_CATEGORY);
- }
-
private List getAllServiceNames() {
- return discoveryClient.getServices();
+ return new LinkedList<>(discoveryClient.getServices());
}
/**
@@ -378,7 +194,7 @@ public class SpringCloudRegistry extends FailbackRegistry {
initAllServicesLookupScheduler(url, listener);
return getServiceNamesForOps(url);
} else {
- return doGetServiceNames(url);
+ return singletonList(dubboRegistryServiceIdHandler.createServiceId(url));
}
}
@@ -388,30 +204,14 @@ public class SpringCloudRegistry extends FailbackRegistry {
}
private void initAllServicesLookupScheduler(final URL url, final NotifyListener listener) {
- if (allServicesLookupScheduler == null) {
- allServicesLookupScheduler = newSingleThreadScheduledExecutor(new NamedThreadFactory("dubbo-all-services-lookup-"));
- allServicesLookupScheduler.scheduleAtFixedRate(new Runnable() {
- @Override
- public void run() {
- List serviceNames = getAllServiceNames();
- filter(serviceNames, new Filter() {
- @Override
- public boolean accept(String serviceName) {
- boolean accepted = false;
- for (String category : ALL_SUPPORTED_CATEGORIES) {
- String prefix = category + SERVICE_NAME_SEPARATOR;
- if (StringUtils.startsWithIgnoreCase(serviceName, prefix)) {
- accepted = true;
- break;
- }
- }
- return accepted;
- }
- });
- doSubscribe(url, listener, serviceNames);
- }
- }, ALL_SERVICES_LOOKUP_INTERVAL, ALL_SERVICES_LOOKUP_INTERVAL, TimeUnit.SECONDS);
- }
+ servicesLookupScheduler.scheduleAtFixedRate(new Runnable() {
+ @Override
+ public void run() {
+ List serviceNames = getAllServiceNames();
+ filterServiceNames(serviceNames);
+ doSubscribe(url, listener, serviceNames);
+ }
+ }, allServicesLookupInterval, allServicesLookupInterval, TimeUnit.SECONDS);
}
private void doSubscribe(final URL url, final NotifyListener listener, final List serviceNames) {
@@ -421,16 +221,6 @@ public class SpringCloudRegistry extends FailbackRegistry {
}
}
- private List doGetServiceNames(URL url) {
- String[] categories = getCategories(url);
- List serviceNames = new ArrayList(categories.length);
- for (String category : categories) {
- final String serviceName = getServiceName(url, category);
- serviceNames.add(serviceName);
- }
- return serviceNames;
- }
-
/**
* Notify the Healthy {@link ServiceInstance service instance} to subscriber.
*
@@ -487,7 +277,7 @@ public class SpringCloudRegistry extends FailbackRegistry {
*/
private List getServiceNamesForOps(URL url) {
List serviceNames = getAllServiceNames();
- filterServiceNames(serviceNames, url);
+ filterServiceNames(serviceNames);
return serviceNames;
}
@@ -508,7 +298,7 @@ public class SpringCloudRegistry extends FailbackRegistry {
/**
* A filter
*/
- private interface Filter {
+ public interface Filter {
/**
* Tests whether or not the specified data should be accepted.
diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/SpringCloudRegistryFactory.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/SpringCloudRegistryFactory.java
index 80329853..3ff199c9 100644
--- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/SpringCloudRegistryFactory.java
+++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/SpringCloudRegistryFactory.java
@@ -17,9 +17,28 @@
package org.springframework.cloud.alibaba.dubbo.registry;
import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.utils.NamedThreadFactory;
import org.apache.dubbo.registry.Registry;
import org.apache.dubbo.registry.RegistryFactory;
-import org.springframework.context.ApplicationContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.cloud.client.discovery.DiscoveryClient;
+import org.springframework.cloud.client.serviceregistry.Registration;
+import org.springframework.cloud.client.serviceregistry.ServiceRegistry;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.core.ResolvableType;
+
+import java.util.List;
+import java.util.concurrent.ScheduledExecutorService;
+
+import static java.lang.System.getProperty;
+import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
+import static org.springframework.beans.BeanUtils.instantiateClass;
+import static org.springframework.core.ResolvableType.forInstance;
+import static org.springframework.core.ResolvableType.forType;
+import static org.springframework.core.io.support.SpringFactoriesLoader.loadFactoryNames;
+import static org.springframework.util.ClassUtils.isPresent;
+import static org.springframework.util.ClassUtils.resolveClassName;
/**
* Dubbo {@link RegistryFactory} uses Spring Cloud Service Registration abstraction, whose protocol is "spring-cloud"
@@ -30,14 +49,122 @@ import org.springframework.context.ApplicationContext;
*/
public class SpringCloudRegistryFactory implements RegistryFactory {
- private static ApplicationContext applicationContext;
+ private static String SERVICES_LOOKUP_SCHEDULER_THREAD_NAME_PREFIX =
+ getProperty("dubbo.services.lookup.scheduler.thread.name.prefix ", "dubbo-services-lookup-");
+
+ private static ConfigurableApplicationContext applicationContext;
+
+ private final Logger logger = LoggerFactory.getLogger(getClass());
+
+ private final ScheduledExecutorService servicesLookupScheduler;
+
+ private ServiceRegistry serviceRegistry;
+
+ private RegistrationFactory registrationFactory;
+
+ private DiscoveryClient discoveryClient;
+
+ private volatile boolean initialized = false;
+
+ public SpringCloudRegistryFactory() {
+ servicesLookupScheduler = newSingleThreadScheduledExecutor(
+ new NamedThreadFactory(SERVICES_LOOKUP_SCHEDULER_THREAD_NAME_PREFIX));
+ }
+
+ protected void init() {
+ if (initialized || applicationContext == null) {
+ return;
+ }
+
+ this.serviceRegistry = applicationContext.getBean(ServiceRegistry.class);
+ this.registrationFactory = buildRegistrationFactory(serviceRegistry, applicationContext.getClassLoader());
+ this.discoveryClient = applicationContext.getBean(DiscoveryClient.class);
+ }
@Override
public Registry getRegistry(URL url) {
- return new SpringCloudRegistry(url, applicationContext);
+ init();
+ return new SpringCloudRegistry(url, serviceRegistry, registrationFactory, discoveryClient,
+ servicesLookupScheduler, applicationContext);
}
- public static void setApplicationContext(ApplicationContext applicationContext) {
+ public static void setApplicationContext(ConfigurableApplicationContext applicationContext) {
SpringCloudRegistryFactory.applicationContext = applicationContext;
}
+
+
+ private RegistrationFactory buildRegistrationFactory(ServiceRegistry serviceRegistry,
+ ClassLoader classLoader) {
+ RegistrationFactory registrationFactory = null;
+ List factoryClassNames = loadFactoryNames(RegistrationFactory.class, classLoader);
+
+ ResolvableType serviceRegistryType = forInstance(serviceRegistry);
+ // Get first generic Class
+ Class> registrationClass = resolveGenericClass(serviceRegistryType, ServiceRegistry.class, 0);
+
+ for (String factoryClassName : factoryClassNames) {
+ if (isPresent(factoryClassName, classLoader)) { // ignore compilation issue
+ Class> factoryClass = resolveClassName(factoryClassName, classLoader);
+ ResolvableType registrationFactoryType = forType(factoryClass);
+ Class> actualRegistrationClass = resolveGenericClass(registrationFactoryType, RegistrationFactory.class, 0);
+ if (registrationClass.equals(actualRegistrationClass)) {
+ registrationFactory = (RegistrationFactory) instantiateClass(registrationFactoryType.getRawClass());
+ break;
+ }
+ }
+ }
+
+ if (registrationFactory == null) {
+
+ if (logger.isWarnEnabled()) {
+ logger.warn("{} implementation can't be resolved by ServiceRegistry[{}]",
+ registrationClass.getSimpleName(), serviceRegistry.getClass().getName());
+ }
+
+ registrationFactory = new DefaultRegistrationFactory();
+ } else {
+ if (logger.isInfoEnabled()) {
+ logger.info("{} has been resolved by ServiceRegistry[{}]",
+ registrationFactory.getClass().getName(), serviceRegistry.getClass().getName());
+ }
+ }
+
+ return registrationFactory;
+ }
+
+ private Class> resolveGenericClass(ResolvableType implementedType, Class> interfaceClass, int index) {
+
+ ResolvableType resolvableType = implementedType;
+
+ try {
+ OUTER:
+ while (true) {
+
+ ResolvableType[] interfaceTypes = resolvableType.getInterfaces();
+
+ for (ResolvableType interfaceType : interfaceTypes) {
+ if (interfaceType.resolve().equals(interfaceClass)) {
+ resolvableType = interfaceType;
+ break OUTER;
+ }
+ }
+
+ ResolvableType superType = resolvableType.getSuperType();
+
+ Class> superClass = superType.resolve();
+
+ if (Object.class.equals(superClass)) {
+ break;
+ }
+
+ resolvableType = superType;
+ }
+
+ } catch (Throwable e) {
+ resolvableType = ResolvableType.forType(void.class);
+ }
+
+ return resolvableType.resolveGeneric(index);
+ }
+
}
diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/apache/zookeeper/ZookeeperRegistrationFactory.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/apache/zookeeper/ZookeeperRegistrationFactory.java
index e065a6e7..d24e9e71 100644
--- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/apache/zookeeper/ZookeeperRegistrationFactory.java
+++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/apache/zookeeper/ZookeeperRegistrationFactory.java
@@ -23,7 +23,7 @@ import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.zookeeper.discovery.ZookeeperInstance;
import org.springframework.cloud.zookeeper.serviceregistry.ServiceInstanceRegistration;
import org.springframework.cloud.zookeeper.serviceregistry.ZookeeperRegistration;
-import org.springframework.context.ApplicationContext;
+import org.springframework.context.ConfigurableApplicationContext;
/**
* Zookeeper {@link RegistrationFactory}
@@ -33,10 +33,7 @@ import org.springframework.context.ApplicationContext;
public class ZookeeperRegistrationFactory extends AbstractRegistrationFactory {
@Override
- public ZookeeperRegistration create(String serviceName, URL url, ApplicationContext applicationContext) {
-
- ServiceInstance serviceInstance = createServiceInstance(serviceName, url);
-
+ protected ZookeeperRegistration create(URL url, ConfigurableApplicationContext applicationContext, ServiceInstance serviceInstance) {
ZookeeperInstance zookeeperInstance = new ZookeeperInstance(serviceInstance.getInstanceId(),
serviceInstance.getServiceId(), serviceInstance.getMetadata());
diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/handler/DubboRegistryServiceIdHandler.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/handler/DubboRegistryServiceIdHandler.java
new file mode 100644
index 00000000..15a35029
--- /dev/null
+++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/handler/DubboRegistryServiceIdHandler.java
@@ -0,0 +1,53 @@
+/*
+ * 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.springframework.cloud.alibaba.dubbo.registry.handler;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.registry.Registry;
+import org.springframework.context.ConfigurableApplicationContext;
+
+/**
+ * Dubbo {@link Registry} Spring Cloud Service Id Builder
+ *
+ * @author Mercy
+ */
+public interface DubboRegistryServiceIdHandler {
+
+ /**
+ * Supports the specified id of Spring Cloud Service or not
+ *
+ * @param serviceId the specified id of Spring Cloud Service
+ * @return if supports, return true
, or false
+ */
+ boolean supports(String serviceId);
+
+ /**
+ * Creates the id of Spring Cloud Service
+ *
+ * @param url The Dubbo's {@link URL}
+ * @return non-null
+ */
+ String createServiceId(URL url);
+
+ /**
+ * The instance if {@link ConfigurableApplicationContext} .
+ *
+ * @return non-null
+ */
+ ConfigurableApplicationContext getContext();
+
+}
diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/handler/StandardDubboRegistryServiceIdHandler.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/handler/StandardDubboRegistryServiceIdHandler.java
new file mode 100644
index 00000000..caaa0706
--- /dev/null
+++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/handler/StandardDubboRegistryServiceIdHandler.java
@@ -0,0 +1,96 @@
+/*
+ * 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.springframework.cloud.alibaba.dubbo.registry.handler;
+
+import org.apache.dubbo.common.Constants;
+import org.apache.dubbo.common.URL;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.util.StringUtils;
+
+import java.util.Objects;
+
+import static java.lang.System.getProperty;
+import static org.apache.dubbo.common.Constants.CONSUMERS_CATEGORY;
+import static org.apache.dubbo.common.Constants.PROVIDERS_CATEGORY;
+import static org.springframework.util.StringUtils.startsWithIgnoreCase;
+
+/**
+ * The Standard {@link DubboRegistryServiceIdHandler}
+ *
+ * The service ID pattern is "${category}:${interface}:${version}:${group}"
+ *
+ * @author Mercy
+ */
+public class StandardDubboRegistryServiceIdHandler implements DubboRegistryServiceIdHandler {
+
+ /**
+ * The separator for service name that could be changed by the Java Property "dubbo.service.name.separator".
+ */
+ protected static final String SERVICE_NAME_SEPARATOR = getProperty("dubbo.service.name.separator", ":");
+
+ private final ConfigurableApplicationContext context;
+
+ public StandardDubboRegistryServiceIdHandler(ConfigurableApplicationContext context) {
+ this.context = context;
+ }
+
+ @Override
+ public boolean supports(String serviceId) {
+ return startsWithIgnoreCase(serviceId, PROVIDERS_CATEGORY) ||
+ startsWithIgnoreCase(serviceId, CONSUMERS_CATEGORY);
+ }
+
+ @Override
+ public String createServiceId(URL url) {
+ String category = url.getParameter(Constants.CATEGORY_KEY, Constants.DEFAULT_CATEGORY);
+ if (!Objects.equals(category, PROVIDERS_CATEGORY) && !Objects.equals(category, CONSUMERS_CATEGORY)) {
+ category = PROVIDERS_CATEGORY;
+ }
+ return createServiceId(url, category);
+ }
+
+ @Override
+ public ConfigurableApplicationContext getContext() {
+ return context;
+ }
+
+ /**
+ * This method maybe override by sub-class.
+ *
+ * @param url The Dubbo's {@link URL}
+ * @param category The category
+ * @return
+ */
+ protected String createServiceId(URL url, String category) {
+ StringBuilder serviceNameBuilder = new StringBuilder(category);
+ appendIfPresent(serviceNameBuilder, url, Constants.INTERFACE_KEY);
+ appendIfPresent(serviceNameBuilder, url, Constants.VERSION_KEY);
+ appendIfPresent(serviceNameBuilder, url, Constants.GROUP_KEY);
+ return serviceNameBuilder.toString();
+ }
+
+ private static void appendIfPresent(StringBuilder target, URL url, String parameterName) {
+ String parameterValue = url.getParameter(parameterName);
+ appendIfPresent(target, parameterValue);
+ }
+
+ private static void appendIfPresent(StringBuilder target, String parameterValue) {
+ if (StringUtils.hasText(parameterValue)) {
+ target.append(SERVICE_NAME_SEPARATOR).append(parameterValue);
+ }
+ }
+}
diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/hashicorp/consul/ConsulRegistrationFactory.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/hashicorp/consul/ConsulRegistrationFactory.java
index c287570c..8fd93a65 100644
--- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/hashicorp/consul/ConsulRegistrationFactory.java
+++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/hashicorp/consul/ConsulRegistrationFactory.java
@@ -24,7 +24,7 @@ import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.consul.discovery.ConsulDiscoveryProperties;
import org.springframework.cloud.consul.discovery.ConsulServerUtils;
import org.springframework.cloud.consul.serviceregistry.ConsulRegistration;
-import org.springframework.context.ApplicationContext;
+import org.springframework.context.ConfigurableApplicationContext;
import java.util.LinkedHashSet;
import java.util.LinkedList;
@@ -40,9 +40,7 @@ import java.util.Set;
public class ConsulRegistrationFactory extends AbstractRegistrationFactory {
@Override
- public ConsulRegistration create(String serviceName, URL url, ApplicationContext applicationContext) {
- ServiceInstance serviceInstance = createServiceInstance(serviceName, url);
-
+ protected ConsulRegistration create(URL url, ConfigurableApplicationContext applicationContext, ServiceInstance serviceInstance) {
Map metadata = getMetadata(serviceInstance);
List tags = createTags(metadata);
diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/netflix/eureka/EurekaRegistrationFactory.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/netflix/eureka/EurekaRegistrationFactory.java
index 8b918e27..486154f5 100644
--- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/netflix/eureka/EurekaRegistrationFactory.java
+++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/netflix/eureka/EurekaRegistrationFactory.java
@@ -27,7 +27,7 @@ import org.springframework.cloud.commons.util.InetUtils;
import org.springframework.cloud.netflix.eureka.CloudEurekaInstanceConfig;
import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean;
import org.springframework.cloud.netflix.eureka.serviceregistry.EurekaRegistration;
-import org.springframework.context.ApplicationContext;
+import org.springframework.context.ConfigurableApplicationContext;
/**
* {@link EurekaRegistration} Factory
@@ -37,8 +37,7 @@ import org.springframework.context.ApplicationContext;
public class EurekaRegistrationFactory extends AbstractRegistrationFactory {
@Override
- public EurekaRegistration create(String serviceName, URL url, ApplicationContext applicationContext) {
- ServiceInstance serviceInstance = createServiceInstance(serviceName, url);
+ protected EurekaRegistration create(URL url, ConfigurableApplicationContext applicationContext, ServiceInstance serviceInstance) {
CloudEurekaInstanceConfig cloudEurekaInstanceConfig = applicationContext.getBean(CloudEurekaInstanceConfig.class);
ObjectProvider healthCheckHandler = applicationContext.getBeanProvider(HealthCheckHandler.class);
EurekaClientConfig eurekaClientConfig = applicationContext.getBean(EurekaClientConfig.class);
diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/service/DubboGenericServiceFactory.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/service/DubboGenericServiceFactory.java
index 2cfe2029..e15bbb69 100644
--- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/service/DubboGenericServiceFactory.java
+++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/service/DubboGenericServiceFactory.java
@@ -16,6 +16,7 @@
*/
package org.springframework.cloud.alibaba.dubbo.service;
+import org.apache.dubbo.common.URL;
import org.apache.dubbo.config.spring.ReferenceBean;
import org.apache.dubbo.rpc.service.GenericService;
import org.slf4j.Logger;
@@ -30,12 +31,10 @@ import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
-import static com.alibaba.dubbo.common.Constants.DEFAULT_CLUSTER;
-import static com.alibaba.dubbo.common.Constants.DEFAULT_PROTOCOL;
-import static org.springframework.cloud.alibaba.dubbo.registry.SpringCloudRegistry.getServiceGroup;
-import static org.springframework.cloud.alibaba.dubbo.registry.SpringCloudRegistry.getServiceInterface;
-import static org.springframework.cloud.alibaba.dubbo.registry.SpringCloudRegistry.getServiceSegments;
-import static org.springframework.cloud.alibaba.dubbo.registry.SpringCloudRegistry.getServiceVersion;
+import static org.apache.dubbo.common.Constants.DEFAULT_CLUSTER;
+import static org.apache.dubbo.common.Constants.DEFAULT_PROTOCOL;
+import static org.apache.dubbo.common.Constants.GROUP_KEY;
+import static org.apache.dubbo.common.Constants.VERSION_KEY;
/**
* Dubbo {@link GenericService} Factory
@@ -66,11 +65,11 @@ public class DubboGenericServiceFactory {
private ReferenceBean build(ServiceRestMetadata serviceRestMetadata,
DubboTransportedMetadata dubboTransportedMetadata) {
- String dubboServiceName = serviceRestMetadata.getName();
- String[] segments = getServiceSegments(dubboServiceName);
- String interfaceName = getServiceInterface(segments);
- String version = getServiceVersion(segments);
- String group = getServiceGroup(segments);
+ String urlValue = serviceRestMetadata.getUrl();
+ URL url = URL.valueOf(urlValue);
+ String interfaceName = url.getServiceInterface();
+ String version = url.getParameter(VERSION_KEY);
+ String group = url.getParameter(GROUP_KEY);
String protocol = dubboTransportedMetadata.getProtocol();
String cluster = dubboTransportedMetadata.getCluster();
diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/service/PublishingDubboMetadataConfigService.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/service/PublishingDubboMetadataConfigService.java
index 97074e3f..fa49e94b 100644
--- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/service/PublishingDubboMetadataConfigService.java
+++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/service/PublishingDubboMetadataConfigService.java
@@ -19,7 +19,6 @@ package org.springframework.cloud.alibaba.dubbo.service;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
-import org.apache.dubbo.config.annotation.Service;
import org.springframework.cloud.alibaba.dubbo.metadata.ServiceRestMetadata;
import org.springframework.util.CollectionUtils;
@@ -27,15 +26,13 @@ import javax.annotation.PostConstruct;
import java.util.LinkedHashSet;
import java.util.Set;
-import static org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboMetadataAutoConfiguration.METADATA_PROTOCOL_BEAN_NAME;
+import static org.springframework.util.ObjectUtils.isEmpty;
/**
* Publishing {@link DubboMetadataConfigService} implementation
*
* @author Mercy
*/
-@Service(version = "${spring.application.name}", protocol = METADATA_PROTOCOL_BEAN_NAME)
-// Use current Spring application name as the Dubbo Service version
public class PublishingDubboMetadataConfigService implements DubboMetadataConfigService {
/**
@@ -68,7 +65,9 @@ public class PublishingDubboMetadataConfigService implements DubboMetadataConfig
public String getServiceRestMetadata() {
String serviceRestMetadataJsonConfig = null;
try {
- serviceRestMetadataJsonConfig = objectMapper.writeValueAsString(serviceRestMetadata);
+ if (!isEmpty(serviceRestMetadata)) {
+ serviceRestMetadataJsonConfig = objectMapper.writeValueAsString(serviceRestMetadata);
+ }
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
diff --git a/spring-cloud-alibaba-dubbo/src/main/resources/META-INF/spring.factories b/spring-cloud-alibaba-dubbo/src/main/resources/META-INF/spring.factories
index f90bb175..ed1c9c3f 100644
--- a/spring-cloud-alibaba-dubbo/src/main/resources/META-INF/spring.factories
+++ b/spring-cloud-alibaba-dubbo/src/main/resources/META-INF/spring.factories
@@ -1,7 +1,7 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboMetadataAutoConfiguration,\
org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboOpenFeignAutoConfiguration,\
- org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboRestMetadataRegistrationAutoConfiguration,\
+ org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboMetadataEventHandlingAutoConfiguration,\
org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboLoadBalancedRestTemplateAutoConfiguration,\
org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboServiceAutoConfiguration
@@ -9,7 +9,6 @@ org.springframework.context.ApplicationContextInitializer=\
org.springframework.cloud.alibaba.dubbo.context.DubboServiceRegistrationApplicationContextInitializer
org.springframework.cloud.alibaba.dubbo.registry.RegistrationFactory=\
- org.springframework.cloud.alibaba.dubbo.registry.DefaultRegistrationFactory,\
org.springframework.cloud.alibaba.dubbo.registry.netflix.eureka.EurekaRegistrationFactory,\
org.springframework.cloud.alibaba.dubbo.registry.apache.zookeeper.ZookeeperRegistrationFactory,\
org.springframework.cloud.alibaba.dubbo.registry.hashicorp.consul.ConsulRegistrationFactory
\ No newline at end of file
diff --git a/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-consumer-sample/src/main/resources/application.yaml b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-consumer-sample/src/main/resources/application.yaml
index 83d0d835..d2b72d47 100644
--- a/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-consumer-sample/src/main/resources/application.yaml
+++ b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-consumer-sample/src/main/resources/application.yaml
@@ -1,5 +1,8 @@
dubbo:
registry:
- address: spring-cloud://nacos
+# The Spring Cloud Dubbo's registry extension
+ address: spring-cloud://localhost
+# The traditional Dubbo's registry
+# address: zookeeper://127.0.0.1:2181
server:
port: 7070
\ No newline at end of file
diff --git a/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-provider-sample/src/main/resources/application.yaml b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-provider-sample/src/main/resources/application.yaml
index 2b3eb54e..0f6094ac 100644
--- a/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-provider-sample/src/main/resources/application.yaml
+++ b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-provider-sample/src/main/resources/application.yaml
@@ -10,7 +10,10 @@ dubbo:
port: 8081
server: netty
registry:
- address: spring-cloud://nacos
+# The Spring Cloud Dubbo's registry extension
+ address: spring-cloud://localhost
+# The traditional Dubbo's registry
+# address: zookeeper://127.0.0.1:2181
feign:
hystrix:
diff --git a/spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/discovery/NacosDiscoveryClient.java b/spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/discovery/NacosDiscoveryClient.java
index 4bedab5c..ccf2e838 100644
--- a/spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/discovery/NacosDiscoveryClient.java
+++ b/spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/discovery/NacosDiscoveryClient.java
@@ -18,6 +18,7 @@ package org.springframework.cloud.alibaba.nacos.discovery;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.api.naming.pojo.ListView;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.alibaba.nacos.NacosDiscoveryProperties;
@@ -25,7 +26,11 @@ import org.springframework.cloud.alibaba.nacos.NacosServiceInstance;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
/**
* @author xiaojing
@@ -33,75 +38,74 @@ import java.util.*;
*/
public class NacosDiscoveryClient implements DiscoveryClient {
- private static final Logger log = LoggerFactory
- .getLogger(NacosDiscoveryClient.class);
- public static final String DESCRIPTION = "Spring Cloud Nacos Discovery Client";
+ private static final Logger log = LoggerFactory
+ .getLogger(NacosDiscoveryClient.class);
+ public static final String DESCRIPTION = "Spring Cloud Nacos Discovery Client";
- private NacosDiscoveryProperties discoveryProperties;
+ private NacosDiscoveryProperties discoveryProperties;
- public NacosDiscoveryClient(NacosDiscoveryProperties discoveryProperties) {
- this.discoveryProperties = discoveryProperties;
- }
+ public NacosDiscoveryClient(NacosDiscoveryProperties discoveryProperties) {
+ this.discoveryProperties = discoveryProperties;
+ }
- @Override
- public String description() {
- return DESCRIPTION;
- }
+ @Override
+ public String description() {
+ return DESCRIPTION;
+ }
- @Override
- public List getInstances(String serviceId) {
- try {
- List instances = discoveryProperties.namingServiceInstance()
- .selectInstances(serviceId, true);
- return hostToServiceInstanceList(instances, serviceId);
- }
- catch (Exception e) {
- throw new RuntimeException(
- "Can not get hosts from nacos server. serviceId: " + serviceId, e);
- }
- }
+ @Override
+ public List getInstances(String serviceId) {
+ try {
+ List instances = discoveryProperties.namingServiceInstance()
+ .selectInstances(serviceId, true);
+ return hostToServiceInstanceList(instances, serviceId);
+ } catch (Exception e) {
+ throw new RuntimeException(
+ "Can not get hosts from nacos server. serviceId: " + serviceId, e);
+ }
+ }
- private static ServiceInstance hostToServiceInstance(Instance instance,
- String serviceId) {
- NacosServiceInstance nacosServiceInstance = new NacosServiceInstance();
- nacosServiceInstance.setHost(instance.getIp());
- nacosServiceInstance.setPort(instance.getPort());
- nacosServiceInstance.setServiceId(serviceId);
- Map metadata = new HashMap<>();
- metadata.put("instanceId", instance.getInstanceId());
- metadata.put("weight", instance.getWeight() + "");
- metadata.put("healthy", instance.isHealthy() + "");
- metadata.put("cluster", instance.getClusterName() + "");
- metadata.putAll(instance.getMetadata());
- nacosServiceInstance.setMetadata(metadata);
+ private static ServiceInstance hostToServiceInstance(Instance instance,
+ String serviceId) {
+ NacosServiceInstance nacosServiceInstance = new NacosServiceInstance();
+ nacosServiceInstance.setHost(instance.getIp());
+ nacosServiceInstance.setPort(instance.getPort());
+ nacosServiceInstance.setServiceId(serviceId);
- if (metadata.containsKey("secure")) {
- boolean secure = Boolean.parseBoolean(metadata.get("secure"));
- nacosServiceInstance.setSecure(secure);
- }
- return nacosServiceInstance;
- }
+ Map metadata = new HashMap<>();
+ metadata.put("nacos.instanceId", instance.getInstanceId());
+ metadata.put("nacos.weight", instance.getWeight() + "");
+ metadata.put("nacos.healthy", instance.isHealthy() + "");
+ metadata.put("nacos.cluster", instance.getClusterName() + "");
+ metadata.putAll(instance.getMetadata());
+ nacosServiceInstance.setMetadata(metadata);
- private static List hostToServiceInstanceList(
- List instances, String serviceId) {
- List result = new ArrayList<>(instances.size());
- for (Instance instance : instances) {
- result.add(hostToServiceInstance(instance, serviceId));
- }
- return result;
- }
+ if (metadata.containsKey("secure")) {
+ boolean secure = Boolean.parseBoolean(metadata.get("secure"));
+ nacosServiceInstance.setSecure(secure);
+ }
+ return nacosServiceInstance;
+ }
- @Override
- public List getServices() {
+ private static List hostToServiceInstanceList(
+ List instances, String serviceId) {
+ List result = new ArrayList<>(instances.size());
+ for (Instance instance : instances) {
+ result.add(hostToServiceInstance(instance, serviceId));
+ }
+ return result;
+ }
- try {
- ListView services = discoveryProperties.namingServiceInstance()
- .getServicesOfServer(1, Integer.MAX_VALUE);
- return services.getData();
- }
- catch (Exception e) {
- log.error("get service name from nacos server fail,", e);
- return Collections.emptyList();
- }
- }
+ @Override
+ public List getServices() {
+
+ try {
+ ListView services = discoveryProperties.namingServiceInstance()
+ .getServicesOfServer(1, Integer.MAX_VALUE);
+ return services.getData();
+ } catch (Exception e) {
+ log.error("get service name from nacos server fail,", e);
+ return Collections.emptyList();
+ }
+ }
}