mirror of
https://gitee.com/mirrors/Spring-Cloud-Alibaba.git
synced 2021-06-26 13:25:11 +08:00
Polish : spring-cloud-incubator/spring-cloud-alibaba#377 : Refactor
This commit is contained in:
parent
514fef53f5
commit
e48863640a
@ -20,12 +20,15 @@ import org.apache.dubbo.common.utils.Assert;
|
||||
import org.apache.dubbo.config.spring.util.PropertySourcesUtils;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.context.properties.source.ConfigurationPropertySources;
|
||||
import org.springframework.cloud.alibaba.dubbo.registry.handler.DubboRegistryServiceIdHandler;
|
||||
import org.springframework.cloud.alibaba.dubbo.registry.handler.StandardDubboRegistryServiceIdHandler;
|
||||
import org.springframework.cloud.alibaba.dubbo.service.DubboGenericServiceExecutionContextFactory;
|
||||
import org.springframework.cloud.alibaba.dubbo.service.DubboGenericServiceFactory;
|
||||
import org.springframework.cloud.alibaba.dubbo.service.parameter.PathVariableServiceParameterResolver;
|
||||
import org.springframework.cloud.alibaba.dubbo.service.parameter.RequestBodyServiceParameterResolver;
|
||||
import org.springframework.cloud.alibaba.dubbo.service.parameter.RequestHeaderServiceParameterResolver;
|
||||
import org.springframework.cloud.alibaba.dubbo.service.parameter.RequestParamServiceParameterResolver;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
@ -67,6 +70,11 @@ public class DubboServiceAutoConfiguration {
|
||||
static class ParameterResolversConfiguration {
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public DubboRegistryServiceIdHandler dubboRegistryServiceIdHandler(ConfigurableApplicationContext context) {
|
||||
return new StandardDubboRegistryServiceIdHandler(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Bugfix code for an issue : https://github.com/apache/incubator-dubbo-spring-boot-project/issues/459
|
||||
|
@ -30,16 +30,16 @@ import java.util.Set;
|
||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||
public class ServiceRestMetadata {
|
||||
|
||||
private String name;
|
||||
private String url;
|
||||
|
||||
private Set<RestMethodMetadata> meta;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public Set<RestMethodMetadata> getMeta() {
|
||||
@ -55,12 +55,12 @@ public class ServiceRestMetadata {
|
||||
if (this == o) return true;
|
||||
if (!(o instanceof ServiceRestMetadata)) return false;
|
||||
ServiceRestMetadata that = (ServiceRestMetadata) o;
|
||||
return Objects.equals(name, that.name) &&
|
||||
return Objects.equals(url, that.url) &&
|
||||
Objects.equals(meta, that.meta);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(name, meta);
|
||||
return Objects.hash(url, meta);
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,6 @@ import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.beans.factory.SmartInitializingSingleton;
|
||||
import org.springframework.cloud.alibaba.dubbo.metadata.RestMethodMetadata;
|
||||
import org.springframework.cloud.alibaba.dubbo.metadata.ServiceRestMetadata;
|
||||
import org.springframework.cloud.alibaba.dubbo.registry.SpringCloudRegistry;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
@ -115,10 +114,10 @@ public class DubboServiceBeanMetadataResolver implements BeanClassLoaderAware, S
|
||||
List<URL> 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);
|
||||
});
|
||||
|
@ -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
|
||||
* <p>
|
||||
*
|
||||
* @param <T> The subclass of {@link Registration}
|
||||
* @param <R> The subclass of {@link Registration}
|
||||
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||
*/
|
||||
public abstract class AbstractRegistrationFactory<T extends Registration> implements RegistrationFactory<T> {
|
||||
public abstract class AbstractRegistrationFactory<R extends Registration> implements RegistrationFactory<R> {
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<Registration> {
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
||||
|
@ -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 <T> The subclass of {@link Registration}
|
||||
* @param <R> The subclass of {@link Registration}
|
||||
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||
*/
|
||||
public interface RegistrationFactory<T extends Registration> {
|
||||
public interface RegistrationFactory<R extends Registration> {
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
@ -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<Registration> 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<Registration> 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<Registration> serviceRegistry,
|
||||
ClassLoader classLoader) {
|
||||
RegistrationFactory registrationFactory = null;
|
||||
List<String> 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<String, String> 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<String> 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<String> 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<String> serviceNames) {
|
||||
filter(serviceNames, new Filter<String>() {
|
||||
@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<String> 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<String> serviceNames = getAllServiceNames();
|
||||
filter(serviceNames, new Filter<String>() {
|
||||
@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<String> serviceNames = getAllServiceNames();
|
||||
filterServiceNames(serviceNames);
|
||||
doSubscribe(url, listener, serviceNames);
|
||||
}
|
||||
}, allServicesLookupInterval, allServicesLookupInterval, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
private void doSubscribe(final URL url, final NotifyListener listener, final List<String> serviceNames) {
|
||||
@ -421,16 +221,6 @@ public class SpringCloudRegistry extends FailbackRegistry {
|
||||
}
|
||||
}
|
||||
|
||||
private List<String> doGetServiceNames(URL url) {
|
||||
String[] categories = getCategories(url);
|
||||
List<String> serviceNames = new ArrayList<String>(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<String> getServiceNamesForOps(URL url) {
|
||||
List<String> serviceNames = getAllServiceNames();
|
||||
filterServiceNames(serviceNames, url);
|
||||
filterServiceNames(serviceNames);
|
||||
return serviceNames;
|
||||
}
|
||||
|
||||
@ -508,7 +298,7 @@ public class SpringCloudRegistry extends FailbackRegistry {
|
||||
/**
|
||||
* A filter
|
||||
*/
|
||||
private interface Filter<T> {
|
||||
public interface Filter<T> {
|
||||
|
||||
/**
|
||||
* Tests whether or not the specified data should be accepted.
|
||||
|
@ -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<Registration> 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<Registration> serviceRegistry,
|
||||
ClassLoader classLoader) {
|
||||
RegistrationFactory registrationFactory = null;
|
||||
List<String> 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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<ZookeeperRegistration> {
|
||||
|
||||
@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());
|
||||
|
||||
|
@ -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 <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||
*/
|
||||
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 <code>true</code>, or <code>false</code>
|
||||
*/
|
||||
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();
|
||||
|
||||
}
|
@ -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}
|
||||
* <p>
|
||||
* The service ID pattern is "${category}:${interface}:${version}:${group}"
|
||||
*
|
||||
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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<ConsulRegistration> {
|
||||
|
||||
@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<String, String> metadata = getMetadata(serviceInstance);
|
||||
List<String> tags = createTags(metadata);
|
||||
|
||||
|
@ -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<EurekaRegistration> {
|
||||
|
||||
@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> healthCheckHandler = applicationContext.getBeanProvider(HealthCheckHandler.class);
|
||||
EurekaClientConfig eurekaClientConfig = applicationContext.getBean(EurekaClientConfig.class);
|
||||
|
@ -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<GenericService> 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();
|
||||
|
||||
|
@ -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
|
@ -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
|
@ -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:
|
||||
|
Loading…
x
Reference in New Issue
Block a user