dubboTranslatedAttributes = dubboTransportedMethodMetadata.getAttributes();
Method method = dubboTransportedMethodMetadata.getMethod();
- GenericService dubboGenericService = dubboGenericServiceFactory.create(dubboServiceMetadata, dubboTranslatedAttributes);
- RestMethodMetadata dubboRestMethodMetadata = dubboServiceMetadata.getRestMethodMetadata();
+ GenericService dubboGenericService = dubboGenericServiceFactory.create(metadata, dubboTranslatedAttributes);
+ RestMethodMetadata dubboRestMethodMetadata = metadata.getRestMethodMetadata();
MethodMetadata methodMetadata = dubboTransportedMethodMetadata.getMethodMetadata();
FeignMethodMetadata feignMethodMetadata = new FeignMethodMetadata(dubboGenericService,
dubboRestMethodMetadata, feignRestMethodMetadata);
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
deleted file mode 100644
index f17c3019..00000000
--- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/AbstractRegistrationFactory.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.springframework.cloud.alibaba.dubbo.registry;
-
-import org.apache.dubbo.common.Constants;
-import org.apache.dubbo.common.URL;
-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;
-
-/**
- * Abstract {@link RegistrationFactory} implementation
- *
- *
- * @param The subclass of {@link Registration}
- * @author Mercy
- */
-public abstract class AbstractRegistrationFactory implements RegistrationFactory {
-
- public final R create(URL url, ConfigurableApplicationContext applicationContext) {
- ServiceInstance serviceInstance = createServiceInstance(url, applicationContext);
- return create(serviceInstance, applicationContext);
- }
-
- /**
- * 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 = url.getIp();
- int port = newURL.getParameter(Constants.BIND_PORT_KEY, url.getPort());
- 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/AbstractSpringCloudRegistry.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/AbstractSpringCloudRegistry.java
new file mode 100644
index 00000000..c52cf231
--- /dev/null
+++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/AbstractSpringCloudRegistry.java
@@ -0,0 +1,293 @@
+/*
+ * 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;
+
+import org.apache.dubbo.common.Constants;
+import org.apache.dubbo.common.URL;
+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.client.ServiceInstance;
+import org.springframework.cloud.client.discovery.DiscoveryClient;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+
+import static java.util.Collections.singleton;
+import static org.apache.dubbo.common.Constants.PROVIDER_SIDE;
+import static org.apache.dubbo.common.Constants.SIDE_KEY;
+import static org.springframework.util.ObjectUtils.isEmpty;
+
+/**
+ * Abstract Dubbo {@link RegistryFactory} uses Spring Cloud Service Registration abstraction, whose protocol is "spring-cloud"
+ *
+ * @author Mercy
+ */
+public abstract class AbstractSpringCloudRegistry extends FailbackRegistry {
+
+ /**
+ * The parameter name of {@link #servicesLookupInterval}
+ */
+ public static final String SERVICES_LOOKUP_INTERVAL_PARAM_NAME = "dubbo.services.lookup.interval";
+
+ protected final Logger logger = LoggerFactory.getLogger(getClass());
+
+ /**
+ * The interval in second of lookup service names(only for Dubbo-OPS)
+ */
+ private final long servicesLookupInterval;
+
+ private final DiscoveryClient discoveryClient;
+
+ protected final ScheduledExecutorService servicesLookupScheduler;
+
+ public AbstractSpringCloudRegistry(URL url,
+ DiscoveryClient discoveryClient,
+ ScheduledExecutorService servicesLookupScheduler) {
+ super(url);
+ this.servicesLookupInterval = url.getParameter(SERVICES_LOOKUP_INTERVAL_PARAM_NAME, 60L);
+ this.discoveryClient = discoveryClient;
+ this.servicesLookupScheduler = servicesLookupScheduler;
+ }
+
+ protected boolean shouldRegister(URL url) {
+ String side = url.getParameter(SIDE_KEY);
+
+ boolean should = PROVIDER_SIDE.equals(side); // Only register the Provider.
+
+ if (!should) {
+ if (logger.isDebugEnabled()) {
+ logger.debug("The URL[{}] should not be registered.", url.toString());
+ }
+ }
+
+ return should;
+ }
+
+ @Override
+ public final void doRegister(URL url) {
+ if (!shouldRegister(url)) {
+ return;
+ }
+ doRegister0(url);
+ }
+
+ /**
+ * The sub-type should implement to register
+ *
+ * @param url {@link URL}
+ */
+ protected abstract void doRegister0(URL url);
+
+ @Override
+ public final void doUnregister(URL url) {
+ if (!shouldRegister(url)) {
+ return;
+ }
+ doUnregister0(url);
+ }
+
+ /**
+ * The sub-type should implement to unregister
+ *
+ * @param url {@link URL}
+ */
+ protected abstract void doUnregister0(URL url);
+
+ @Override
+ public final void doSubscribe(URL url, NotifyListener listener) {
+ Set serviceNames = getServiceNames(url);
+ doSubscribe(url, listener, serviceNames);
+ }
+
+ @Override
+ public final void doUnsubscribe(URL url, NotifyListener listener) {
+ if (isAdminProtocol(url)) {
+ shutdownServiceNamesLookup();
+ }
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return !discoveryClient.getServices().isEmpty();
+ }
+
+ protected void shutdownServiceNamesLookup() {
+ if (servicesLookupScheduler != null) {
+ servicesLookupScheduler.shutdown();
+ }
+ }
+
+ private void filterServiceNames(Collection serviceNames) {
+ filter(serviceNames, new Filter() {
+ @Override
+ public boolean accept(String serviceName) {
+ return supports(serviceName);
+ }
+ });
+ }
+
+ protected abstract boolean supports(String serviceName);
+
+ protected final Set getAllServiceNames() {
+ return new LinkedHashSet<>(discoveryClient.getServices());
+ }
+
+ /**
+ * Get the service names from the specified {@link URL url}
+ *
+ * @param url {@link URL}
+ * @return non-null
+ */
+ private Set getServiceNames(URL url) {
+ if (isAdminProtocol(url)) {
+ return getServiceNamesForOps(url);
+ } else {
+ return singleton(getServiceName(url));
+ }
+ }
+
+ protected boolean isAdminProtocol(URL url) {
+ return Constants.ADMIN_PROTOCOL.equals(url.getProtocol());
+ }
+
+ /**
+ * Get the service names for Dubbo OPS
+ *
+ * @param url {@link URL}
+ * @return non-null
+ */
+ protected Set getServiceNamesForOps(URL url) {
+ Set serviceNames = getAllServiceNames();
+ filterServiceNames(serviceNames);
+ return serviceNames;
+ }
+
+ protected abstract String getServiceName(URL url);
+
+ private void doSubscribe(final URL url, final NotifyListener listener, final Collection serviceNames) {
+
+ subscribe(url, listener, serviceNames);
+
+ schedule(() -> {
+ subscribe(url, listener, serviceNames);
+ });
+ }
+
+ protected ScheduledFuture> schedule(Runnable runnable) {
+ return this.servicesLookupScheduler.scheduleAtFixedRate(runnable, servicesLookupInterval,
+ servicesLookupInterval, TimeUnit.SECONDS);
+ }
+
+ protected List getServiceInstances(String serviceName) {
+ return discoveryClient.getInstances(serviceName);
+ }
+
+ private void subscribe(final URL url, final NotifyListener listener, final Collection serviceNames) {
+ for (String serviceName : serviceNames) {
+ List serviceInstances = getServiceInstances(serviceName);
+ if (!isEmpty(serviceInstances)) {
+ notifySubscriber(url, listener, serviceInstances);
+ }
+ }
+ }
+
+ /**
+ * Notify the Healthy {@link ServiceInstance service instance} to subscriber.
+ *
+ * @param url {@link URL}
+ * @param listener {@link NotifyListener}
+ * @param serviceInstances all {@link ServiceInstance instances}
+ */
+ protected abstract void notifySubscriber(URL url, NotifyListener listener, List serviceInstances);
+
+ protected void filterHealthyInstances(Collection instances) {
+ filter(instances, new Filter() {
+ @Override
+ public boolean accept(ServiceInstance data) {
+ // TODO check the details of status
+// return serviceRegistry.getStatus(new DubboRegistration(data)) != null;
+ return true;
+ }
+ });
+ }
+
+ protected List buildURLs(URL consumerURL, Collection serviceInstances) {
+ if (serviceInstances.isEmpty()) {
+ return Collections.emptyList();
+ }
+ List urls = new LinkedList();
+ for (ServiceInstance serviceInstance : serviceInstances) {
+ URL url = buildURL(serviceInstance);
+ if (UrlUtils.isMatch(consumerURL, url)) {
+ urls.add(url);
+ }
+ }
+ return urls;
+ }
+
+ private URL buildURL(ServiceInstance serviceInstance) {
+ URL url = new URL(serviceInstance.getMetadata().get(Constants.PROTOCOL_KEY),
+ serviceInstance.getHost(),
+ serviceInstance.getPort(),
+ serviceInstance.getMetadata());
+ return url;
+ }
+
+ private void filter(Collection collection, Filter filter) {
+ Iterator iterator = collection.iterator();
+ while (iterator.hasNext()) {
+ T data = iterator.next();
+ if (!filter.accept(data)) { // remove if not accept
+ iterator.remove();
+ }
+ }
+ }
+
+ private static T[] of(T... values) {
+ return values;
+ }
+
+ /**
+ * A filter
+ */
+ public interface Filter {
+
+ /**
+ * Tests whether or not the specified data should be accepted.
+ *
+ * @param data The data to be tested
+ * @return true
if and only if data
+ * should be accepted
+ */
+ boolean accept(T data);
+
+ }
+
+}
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
deleted file mode 100644
index d05eea94..00000000
--- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/RegistrationFactory.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.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.ConfigurableApplicationContext;
-
-
-/**
- * {@link Registration} Factory to createServiceInstance a instance of {@link Registration}
- *
- * @param The subclass of {@link Registration}
- * @author Mercy
- */
-public interface RegistrationFactory {
-
- /**
- * Create a instance of {@link R}
- *
- * @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.
- */
- R create(URL url, ConfigurableApplicationContext applicationContext);
-
- /**
- * Create a instance of {@link R}
- *
- * @param serviceInstance {@link ServiceInstance}
- * @param applicationContext {@link ConfigurableApplicationContext}
- * @return a instance of {@link R}, if null, it indicates the registration will not be executed.
- */
- R create(ServiceInstance serviceInstance, ConfigurableApplicationContext applicationContext);
-}
diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/RegistrationFactoryProvider.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/RegistrationFactoryProvider.java
deleted file mode 100644
index c5debc68..00000000
--- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/RegistrationFactoryProvider.java
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.springframework.cloud.alibaba.dubbo.registry;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.beans.BeansException;
-import org.springframework.beans.factory.FactoryBean;
-import org.springframework.cloud.client.serviceregistry.Registration;
-import org.springframework.cloud.client.serviceregistry.ServiceRegistry;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
-import org.springframework.core.ResolvableType;
-
-import java.util.List;
-
-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;
-
-/**
- * {@link RegistrationFactory} Provider
- *
- * @author Mercy
- */
-public class RegistrationFactoryProvider implements FactoryBean, ApplicationContextAware {
-
- private final Logger logger = LoggerFactory.getLogger(getClass());
-
- private RegistrationFactory registrationFactory;
-
- @Override
- public RegistrationFactory getObject() throws BeansException {
- return registrationFactory;
- }
-
- @Override
- public Class> getObjectType() {
- return RegistrationFactory.class;
- }
-
- public boolean isSingleton() {
- return true;
- }
-
- @Override
- public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
- ServiceRegistry serviceRegistry = applicationContext.getBean(ServiceRegistry.class);
- ClassLoader classLoader = applicationContext.getClassLoader();
- this.registrationFactory = buildRegistrationFactory(serviceRegistry, classLoader);
- }
-
- 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/ServiceRegistryAspect.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/ServiceRegistryAspect.java
new file mode 100644
index 00000000..72ac16b0
--- /dev/null
+++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/ServiceRegistryAspect.java
@@ -0,0 +1,59 @@
+/*
+ * 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;
+
+import org.aspectj.lang.annotation.After;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+import org.springframework.cloud.alibaba.dubbo.registry.event.ServiceInstancePreRegisteredEvent;
+import org.springframework.cloud.alibaba.dubbo.registry.event.ServiceInstanceRegisteredEvent;
+import org.springframework.cloud.client.serviceregistry.Registration;
+import org.springframework.cloud.client.serviceregistry.ServiceRegistry;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.context.ApplicationEventPublisherAware;
+
+/**
+ * {@link ServiceRegistry} Aspect
+ *
+ * @author Mercy
+ */
+@Aspect
+public class ServiceRegistryAspect implements ApplicationEventPublisherAware {
+
+ /**
+ * The pointcut expression for {@link ServiceRegistry#register(Registration)}
+ */
+ private static final String REGISTER_POINTCUT_EXPRESSION =
+ "execution(* org.springframework.cloud.client.serviceregistry.ServiceRegistry.register(*)) && args(registration)";
+
+ private ApplicationEventPublisher applicationEventPublisher;
+
+ @Before(REGISTER_POINTCUT_EXPRESSION)
+ public void beforeRegister(Registration registration) {
+ applicationEventPublisher.publishEvent(new ServiceInstancePreRegisteredEvent(registration));
+ }
+
+ @After(REGISTER_POINTCUT_EXPRESSION)
+ public void afterRegister(Registration registration) {
+ applicationEventPublisher.publishEvent(new ServiceInstanceRegisteredEvent(registration));
+ }
+
+ @Override
+ public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
+ this.applicationEventPublisher = applicationEventPublisher;
+ }
+}
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 d87e1f6c..d973e629 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
@@ -16,299 +16,138 @@
*/
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.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.alibaba.dubbo.metadata.repository.DubboServiceMetadataRepository;
+import org.springframework.cloud.alibaba.dubbo.util.JSONUtils;
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.ConfigurableApplicationContext;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.LinkedList;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
-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;
+import static java.util.Collections.emptyMap;
+import static org.apache.dubbo.common.Constants.APPLICATION_KEY;
+import static org.springframework.util.CollectionUtils.isEmpty;
/**
* Dubbo {@link RegistryFactory} uses Spring Cloud Service Registration abstraction, whose protocol is "spring-cloud"
*
* @author Mercy
*/
-public class SpringCloudRegistry extends FailbackRegistry {
+public class SpringCloudRegistry extends AbstractSpringCloudRegistry {
/**
- * The parameter name of {@link #allServicesLookupInterval}
+ * The property name of Dubbo {@link URL URLs} metadata
*/
- public static final String ALL_SERVICES_LOOKUP_INTERVAL_PARAM_NAME = "dubbo.all.services.lookup.interval";
+ public static final String DUBBO_URLS_METADATA_PROPERTY_NAME = "dubbo-urls";
/**
- * The parameter name of {@link #registeredServicesLookupInterval}
+ * The parameter name of the services of Dubbo Provider
*/
- public static final String REGISTERED_SERVICES_LOOKUP_INTERVAL_PARAM_NAME = "dubbo.registered.services.lookup.interval";
+ public static final String DUBBO_PROVIDER_SERVICES_PARAM_NAME = "dubbo-provider-services";
/**
- * All supported categories
+ * All services of Dubbo Provider
*/
- public static final String[] ALL_SUPPORTED_CATEGORIES = of(
- PROVIDERS_CATEGORY,
- CONSUMERS_CATEGORY,
- ROUTERS_CATEGORY,
- CONFIGURATORS_CATEGORY
- );
+ public static final String ALL_DUBBO_PROVIDER_SERVICES = "*";
- private final Logger logger = LoggerFactory.getLogger(getClass());
+ private final DubboServiceMetadataRepository dubboServiceMetadataRepository;
- /**
- * The interval in second of lookup service names(only for Dubbo-OPS)
- */
- private final long allServicesLookupInterval;
+ private final JSONUtils jsonUtils;
- private final long registeredServicesLookupInterval;
+ private final Set dubboProviderServices;
- private final ServiceRegistry serviceRegistry;
+ private final Map dubboServiceKeysCache;
- private final RegistrationFactory registrationFactory;
-
- 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,
+ public SpringCloudRegistry(URL url, DiscoveryClient discoveryClient,
ScheduledExecutorService servicesLookupScheduler,
+ DubboServiceMetadataRepository dubboServiceMetadataRepository,
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.servicesLookupScheduler = servicesLookupScheduler;
+ super(url, discoveryClient, servicesLookupScheduler);
+ this.dubboServiceMetadataRepository = dubboServiceMetadataRepository;
+ this.jsonUtils = applicationContext.getBean(JSONUtils.class);
+ this.dubboProviderServices = getDubboProviderServices();
+ this.dubboServiceKeysCache = this.initDubboServiceKeysCache();
}
- 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 Map initDubboServiceKeysCache() {
+
+ if (isEmpty(dubboProviderServices)) {
+ return emptyMap();
+ }
+
+ Map newCache = new HashMap<>();
+
+ dubboProviderServices.stream()
+ .map(this::getServiceInstances)
+ .filter(this::isNotEmpty)
+ .forEach(serviceInstances -> {
+ ServiceInstance serviceInstance = serviceInstances.get(0);
+ getURLs(serviceInstance).forEach(url -> {
+ String serviceKey = url.getServiceKey();
+ String serviceName = url.getParameter(APPLICATION_KEY);
+ newCache.put(serviceKey, serviceName);
+ });
+ });
+
+ return newCache;
+ }
+
+ private boolean isNotEmpty(Collection collection) {
+ return !CollectionUtils.isEmpty(collection);
+ }
+
+ private List getURLs(ServiceInstance serviceInstance) {
+ Map metadata = serviceInstance.getMetadata();
+ String dubboURLsJSON = metadata.get(DUBBO_URLS_METADATA_PROPERTY_NAME);
+ List urlValues = jsonUtils.toList(dubboURLsJSON);
+ return urlValues.stream().map(URL::valueOf).collect(Collectors.toList());
+ }
+
+ private Set getDubboProviderServices() {
+ URL registryURL = getUrl();
+ String services = registryURL.getParameter(DUBBO_PROVIDER_SERVICES_PARAM_NAME, ALL_DUBBO_PROVIDER_SERVICES);
+ return ALL_DUBBO_PROVIDER_SERVICES.equalsIgnoreCase(services) ?
+ getAllServiceNames() : StringUtils.commaDelimitedListToSet(services);
}
@Override
- public void doRegister(URL url) {
- final Registration registration = createRegistration(url);
- if (shouldRegister(registration)) {
- serviceRegistry.register(registration);
- }
+ protected void doRegister0(URL url) {
+ dubboServiceMetadataRepository.registerURL(url);
}
@Override
- public void doUnregister(URL url) {
- final Registration registration = createRegistration(url);
- if (shouldRegister(registration)) {
- this.serviceRegistry.deregister(registration);
- }
+ protected void doUnregister0(URL url) {
+ dubboServiceMetadataRepository.unregisterURL(url);
}
@Override
- public void doSubscribe(URL url, NotifyListener listener) {
- List serviceNames = getServiceNames(url, listener);
- doSubscribe(url, listener, serviceNames);
- this.servicesLookupScheduler.scheduleAtFixedRate(new Runnable() {
- @Override
- public void run() {
- doSubscribe(url, listener, serviceNames);
- }
- }, registeredServicesLookupInterval, registeredServicesLookupInterval, TimeUnit.SECONDS);
+ protected boolean supports(String serviceName) {
+ return dubboProviderServices.contains(serviceName);
}
@Override
- public void doUnsubscribe(URL url, NotifyListener listener) {
- if (isAdminProtocol(url)) {
- shutdownServiceNamesLookup();
- }
+ protected String getServiceName(URL url) {
+ String serviceKey = url.getServiceKey();
+ return dubboServiceKeysCache.get(serviceKey);
}
@Override
- public boolean isAvailable() {
- return !discoveryClient.getServices().isEmpty();
+ protected void notifySubscriber(URL url, NotifyListener listener, List serviceInstances) {
+ List urls = serviceInstances.stream().map(this::getURLs)
+ .flatMap(List::stream)
+ .collect(Collectors.toList());
+ notify(url, listener, urls);
}
-
- private void shutdownServiceNamesLookup() {
- if (servicesLookupScheduler != null) {
- servicesLookupScheduler.shutdown();
- }
- }
-
- private Registration createRegistration(URL url) {
- return registrationFactory.create(url, applicationContext);
- }
-
- private void filterServiceNames(List serviceNames) {
- filter(serviceNames, new Filter() {
- @Override
- public boolean accept(String serviceName) {
- return dubboRegistryServiceIdHandler.supports(serviceName);
- }
- });
- }
-
- private List getAllServiceNames() {
- return new LinkedList<>(discoveryClient.getServices());
- }
-
- /**
- * Get the service names from the specified {@link URL url}
- *
- * @param url {@link URL}
- * @param listener {@link NotifyListener}
- * @return non-null
- */
- private List getServiceNames(URL url, NotifyListener listener) {
- if (isAdminProtocol(url)) {
- initAllServicesLookupScheduler(url, listener);
- return getServiceNamesForOps(url);
- } else {
- return singletonList(dubboRegistryServiceIdHandler.createServiceId(url));
- }
- }
-
-
- private boolean isAdminProtocol(URL url) {
- return Constants.ADMIN_PROTOCOL.equals(url.getProtocol());
- }
-
- private void initAllServicesLookupScheduler(final URL url, final NotifyListener listener) {
- 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) {
- for (String serviceName : serviceNames) {
- List serviceInstances = discoveryClient.getInstances(serviceName);
- notifySubscriber(url, listener, serviceInstances);
- }
- }
-
- /**
- * Notify the Healthy {@link ServiceInstance service instance} to subscriber.
- *
- * @param url {@link URL}
- * @param listener {@link NotifyListener}
- * @param serviceInstances all {@link ServiceInstance instances}
- */
- private void notifySubscriber(URL url, NotifyListener listener, List serviceInstances) {
- List healthyInstances = new LinkedList(serviceInstances);
- // Healthy Instances
- filterHealthyInstances(healthyInstances);
- List urls = buildURLs(url, healthyInstances);
- this.notify(url, listener, urls);
- }
-
- private void filterHealthyInstances(Collection instances) {
- filter(instances, new Filter() {
- @Override
- public boolean accept(ServiceInstance data) {
- // TODO check the details of status
-// return serviceRegistry.getStatus(new DubboRegistration(data)) != null;
- return true;
- }
- });
- }
-
- private List buildURLs(URL consumerURL, Collection serviceInstances) {
- if (serviceInstances.isEmpty()) {
- return Collections.emptyList();
- }
- List urls = new LinkedList();
- for (ServiceInstance serviceInstance : serviceInstances) {
- URL url = buildURL(serviceInstance);
- if (UrlUtils.isMatch(consumerURL, url)) {
- urls.add(url);
- }
- }
- return urls;
- }
-
- private URL buildURL(ServiceInstance serviceInstance) {
- URL url = new URL(serviceInstance.getMetadata().get(Constants.PROTOCOL_KEY),
- serviceInstance.getHost(),
- serviceInstance.getPort(),
- serviceInstance.getMetadata());
- return url;
- }
-
- /**
- * Get the service names for Dubbo OPS
- *
- * @param url {@link URL}
- * @return non-null
- */
- private List getServiceNamesForOps(URL url) {
- List serviceNames = getAllServiceNames();
- filterServiceNames(serviceNames);
- return serviceNames;
- }
-
- private void filter(Collection collection, Filter filter) {
- Iterator iterator = collection.iterator();
- while (iterator.hasNext()) {
- T data = iterator.next();
- if (!filter.accept(data)) { // remove if not accept
- iterator.remove();
- }
- }
- }
-
- private static T[] of(T... values) {
- return values;
- }
-
- /**
- * A filter
- */
- public interface Filter {
-
- /**
- * Tests whether or not the specified data should be accepted.
- *
- * @param data The data to be tested
- * @return true
if and only if data
- * should be accepted
- */
- boolean accept(T data);
-
- }
-
}
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 234c65d4..15dd3e5d 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
@@ -20,11 +20,9 @@ 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.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+
+import org.springframework.cloud.alibaba.dubbo.metadata.repository.DubboServiceMetadataRepository;
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 java.util.concurrent.ScheduledExecutorService;
@@ -46,16 +44,12 @@ public class SpringCloudRegistryFactory implements RegistryFactory {
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 DubboServiceMetadataRepository dubboServiceMetadataRepository;
+
private volatile boolean initialized = false;
public SpringCloudRegistryFactory() {
@@ -67,17 +61,15 @@ public class SpringCloudRegistryFactory implements RegistryFactory {
if (initialized || applicationContext == null) {
return;
}
-
- this.serviceRegistry = applicationContext.getBean(ServiceRegistry.class);
- this.registrationFactory = applicationContext.getBean(RegistrationFactory.class);
this.discoveryClient = applicationContext.getBean(DiscoveryClient.class);
+ this.dubboServiceMetadataRepository = applicationContext.getBean(DubboServiceMetadataRepository.class);
}
@Override
public Registry getRegistry(URL url) {
init();
- return new SpringCloudRegistry(url, serviceRegistry, registrationFactory, discoveryClient,
- servicesLookupScheduler, applicationContext);
+ return new SpringCloudRegistry(url, discoveryClient, servicesLookupScheduler,
+ dubboServiceMetadataRepository, applicationContext);
}
public static void setApplicationContext(ConfigurableApplicationContext applicationContext) {
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
deleted file mode 100644
index 23638325..00000000
--- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/apache/zookeeper/ZookeeperRegistrationFactory.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.springframework.cloud.alibaba.dubbo.registry.apache.zookeeper;
-
-import org.springframework.cloud.alibaba.dubbo.registry.AbstractRegistrationFactory;
-import org.springframework.cloud.alibaba.dubbo.registry.RegistrationFactory;
-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.ConfigurableApplicationContext;
-
-/**
- * Zookeeper {@link RegistrationFactory}
- *
- * @author Mercy
- */
-public class ZookeeperRegistrationFactory extends AbstractRegistrationFactory {
-
- @Override
- public ZookeeperRegistration create(ServiceInstance serviceInstance, ConfigurableApplicationContext applicationContext) {
- ZookeeperInstance zookeeperInstance = new ZookeeperInstance(serviceInstance.getInstanceId(),
- serviceInstance.getServiceId(), serviceInstance.getMetadata());
-
- ZookeeperRegistration registration = ServiceInstanceRegistration
- .builder()
- .address(serviceInstance.getHost())
- .name(serviceInstance.getServiceId())
- .payload(zookeeperInstance)
- .port(serviceInstance.getPort())
- .build();
-
- // To trigger build() method
- registration.getServiceInstance();
-
- return registration;
- }
-}
diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/event/ServiceInstancePreRegisteredEvent.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/event/ServiceInstancePreRegisteredEvent.java
new file mode 100644
index 00000000..6233e9a5
--- /dev/null
+++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/event/ServiceInstancePreRegisteredEvent.java
@@ -0,0 +1,39 @@
+/*
+ * 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.event;
+
+import org.springframework.cloud.client.ServiceInstance;
+import org.springframework.cloud.client.serviceregistry.Registration;
+import org.springframework.cloud.client.serviceregistry.ServiceRegistry;
+import org.springframework.context.ApplicationEvent;
+
+/**
+ * The before-{@link ServiceRegistry#register(Registration) register} event for {@link ServiceInstance}
+ *
+ * @author Mercy
+ */
+public class ServiceInstancePreRegisteredEvent extends ApplicationEvent {
+
+ public ServiceInstancePreRegisteredEvent(Registration source) {
+ super(source);
+ }
+
+ @Override
+ public Registration getSource() {
+ return (Registration) super.getSource();
+ }
+}
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/event/ServiceInstanceRegisteredEvent.java
similarity index 65%
rename from spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/DefaultRegistrationFactory.java
rename to spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/event/ServiceInstanceRegisteredEvent.java
index 1bcfd534..8aab6aa7 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/event/ServiceInstanceRegisteredEvent.java
@@ -14,21 +14,26 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.springframework.cloud.alibaba.dubbo.registry;
+package org.springframework.cloud.alibaba.dubbo.registry.event;
-import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.serviceregistry.Registration;
-import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.cloud.client.serviceregistry.ServiceRegistry;
+
+import java.util.EventObject;
/**
- * Default {@link RegistrationFactory}
+ * The after-{@link ServiceRegistry#register(Registration) register} event for {@link Registration}
*
* @author Mercy
*/
-public class DefaultRegistrationFactory extends AbstractRegistrationFactory {
+public class ServiceInstanceRegisteredEvent extends EventObject {
+
+ public ServiceInstanceRegisteredEvent(Registration source) {
+ super(source);
+ }
@Override
- public Registration create(ServiceInstance serviceInstance, ConfigurableApplicationContext applicationContext) {
- return new DelegatingRegistration(serviceInstance);
+ public Registration getSource() {
+ return (Registration) super.getSource();
}
}
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
deleted file mode 100644
index a5861fb9..00000000
--- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/hashicorp/consul/ConsulRegistrationFactory.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.springframework.cloud.alibaba.dubbo.registry.hashicorp.consul;
-
-import com.ecwid.consul.v1.agent.model.NewService;
-import org.springframework.cloud.alibaba.dubbo.registry.AbstractRegistrationFactory;
-import org.springframework.cloud.alibaba.dubbo.registry.RegistrationFactory;
-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.ConfigurableApplicationContext;
-
-import java.util.LinkedHashSet;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * {@link ConsulRegistration} {@link RegistrationFactory} implementation
- *
- * @author Mercy
- */
-public class ConsulRegistrationFactory extends AbstractRegistrationFactory {
-
- @Override
- public ConsulRegistration create(ServiceInstance serviceInstance, ConfigurableApplicationContext applicationContext) {
- Map metadata = getMetadata(serviceInstance);
- List tags = createTags(metadata);
-
- NewService service = new NewService();
- service.setId(serviceInstance.getInstanceId());
- service.setName(serviceInstance.getServiceId());
- service.setAddress(serviceInstance.getHost());
- service.setPort(serviceInstance.getPort());
- service.setMeta(metadata);
- service.setTags(tags);
-
- ConsulDiscoveryProperties properties = applicationContext.getBean(ConsulDiscoveryProperties.class);
-
- ConsulRegistration registration = new ConsulRegistration(service, properties);
- return registration;
- }
-
- /**
- * @param metadata
- * @return
- * @see ConsulServerUtils#getMetadata(java.util.List)
- */
- private List createTags(Map metadata) {
- List tags = new LinkedList<>();
- for (Map.Entry entry : metadata.entrySet()) {
- String tag = entry.getKey() + "=" + entry.getValue();
- tags.add(tag);
-
- }
- return tags;
- }
-
- private Map getMetadata(ServiceInstance serviceInstance) {
- Map metadata = serviceInstance.getMetadata();
- Set removedKeys = new LinkedHashSet<>();
- for (String key : metadata.keySet()) {
- if (key.contains(".")) {
- removedKeys.add(key);
- }
- }
- for (String removedKey : removedKeys) {
- metadata.remove(removedKey);
- }
- return 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
deleted file mode 100644
index e72bf40f..00000000
--- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/netflix/eureka/EurekaRegistrationFactory.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.springframework.cloud.alibaba.dubbo.registry.netflix.eureka;
-
-import com.netflix.appinfo.HealthCheckHandler;
-import com.netflix.discovery.EurekaClientConfig;
-import org.springframework.beans.BeanUtils;
-import org.springframework.beans.factory.ObjectProvider;
-import org.springframework.cloud.alibaba.dubbo.registry.AbstractRegistrationFactory;
-import org.springframework.cloud.client.ServiceInstance;
-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.ConfigurableApplicationContext;
-
-/**
- * {@link EurekaRegistration} Factory
- *
- * @author Mercy
- */
-public class EurekaRegistrationFactory extends AbstractRegistrationFactory {
-
- @Override
- public EurekaRegistration create(ServiceInstance serviceInstance, ConfigurableApplicationContext applicationContext) {
- CloudEurekaInstanceConfig cloudEurekaInstanceConfig = applicationContext.getBean(CloudEurekaInstanceConfig.class);
- ObjectProvider healthCheckHandler = applicationContext.getBeanProvider(HealthCheckHandler.class);
- EurekaClientConfig eurekaClientConfig = applicationContext.getBean(EurekaClientConfig.class);
- InetUtils inetUtils = applicationContext.getBean(InetUtils.class);
- EurekaInstanceConfigBean eurekaInstanceConfigBean = new EurekaInstanceConfigBean(inetUtils);
- BeanUtils.copyProperties(cloudEurekaInstanceConfig, eurekaInstanceConfigBean);
- String serviceId = serviceInstance.getServiceId();
- eurekaInstanceConfigBean.setInstanceId(serviceInstance.getInstanceId());
- eurekaInstanceConfigBean.setVirtualHostName(serviceId);
- eurekaInstanceConfigBean.setSecureVirtualHostName(serviceId);
- eurekaInstanceConfigBean.setAppname(serviceId);
- eurekaInstanceConfigBean.setHostname(serviceInstance.getHost());
- eurekaInstanceConfigBean.setNonSecurePort(serviceInstance.getPort());
- eurekaInstanceConfigBean.setMetadataMap(serviceInstance.getMetadata());
-
- return EurekaRegistration.builder(eurekaInstanceConfigBean)
- .with(healthCheckHandler)
- .with(eurekaClientConfig, applicationContext)
- .build();
- }
-}
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 10cd08c9..d1648641 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
@@ -25,7 +25,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
-import org.springframework.cloud.alibaba.dubbo.metadata.DubboServiceMetadata;
+import org.springframework.cloud.alibaba.dubbo.metadata.DubboRestServiceMetadata;
import org.springframework.cloud.alibaba.dubbo.metadata.ServiceRestMetadata;
import org.springframework.util.StringUtils;
import org.springframework.validation.DataBinder;
@@ -54,7 +54,7 @@ public class DubboGenericServiceFactory {
private final ConcurrentMap> cache = new ConcurrentHashMap<>();
- public GenericService create(DubboServiceMetadata dubboServiceMetadata,
+ public GenericService create(DubboRestServiceMetadata dubboServiceMetadata,
Map dubboTranslatedAttributes) {
ReferenceBean referenceBean = build(dubboServiceMetadata.getServiceRestMetadata(), dubboTranslatedAttributes);
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 fa49e94b..76fe660f 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
@@ -16,13 +16,11 @@
*/
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.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.alibaba.dubbo.metadata.ServiceRestMetadata;
+import org.springframework.cloud.alibaba.dubbo.util.JSONUtils;
import org.springframework.util.CollectionUtils;
-import javax.annotation.PostConstruct;
import java.util.LinkedHashSet;
import java.util.Set;
@@ -41,12 +39,8 @@ public class PublishingDubboMetadataConfigService implements DubboMetadataConfig
*/
private final Set serviceRestMetadata = new LinkedHashSet<>();
- private final ObjectMapper objectMapper = new ObjectMapper();
-
- @PostConstruct
- public void init() {
- this.objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
- }
+ @Autowired
+ private JSONUtils jsonUtils;
/**
* Publish the {@link Set} of {@link ServiceRestMetadata}
@@ -64,12 +58,8 @@ public class PublishingDubboMetadataConfigService implements DubboMetadataConfig
@Override
public String getServiceRestMetadata() {
String serviceRestMetadataJsonConfig = null;
- try {
- if (!isEmpty(serviceRestMetadata)) {
- serviceRestMetadataJsonConfig = objectMapper.writeValueAsString(serviceRestMetadata);
- }
- } catch (JsonProcessingException e) {
- throw new RuntimeException(e);
+ if (!isEmpty(serviceRestMetadata)) {
+ serviceRestMetadataJsonConfig = jsonUtils.toJSON(serviceRestMetadata);
}
return serviceRestMetadataJsonConfig;
}
diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/util/JSONUtils.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/util/JSONUtils.java
new file mode 100644
index 00000000..1dd1f6da
--- /dev/null
+++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/util/JSONUtils.java
@@ -0,0 +1,72 @@
+/*
+ * 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.util;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.util.StringUtils;
+
+import javax.annotation.PostConstruct;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * JSON Utilities class
+ *
+ * @author Mercy
+ */
+public class JSONUtils {
+
+ private final Logger logger = LoggerFactory.getLogger(getClass());
+
+ private final ObjectMapper objectMapper = new ObjectMapper();
+
+ @PostConstruct
+ public void init() {
+ this.objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
+ }
+
+ public String toJSON(Object object) {
+ String jsonContent = null;
+ try {
+ jsonContent = objectMapper.writeValueAsString(object);
+ } catch (JsonProcessingException e) {
+ if (logger.isErrorEnabled()) {
+ logger.error(e.getMessage(), e);
+ }
+ }
+ return jsonContent;
+ }
+
+ public List toList(String json) {
+ List list = Collections.emptyList();
+ try {
+ if (StringUtils.hasText(json)) {
+ list = objectMapper.readValue(json, List.class);
+ }
+ } catch (IOException e) {
+ if (logger.isErrorEnabled()) {
+ logger.error(e.getMessage(), e);
+ }
+ }
+ return list;
+ }
+}
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 ed1c9c3f..951a6362 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
@@ -6,9 +6,4 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboServiceAutoConfiguration
org.springframework.context.ApplicationContextInitializer=\
- org.springframework.cloud.alibaba.dubbo.context.DubboServiceRegistrationApplicationContextInitializer
-
-org.springframework.cloud.alibaba.dubbo.registry.RegistrationFactory=\
- 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
+ org.springframework.cloud.alibaba.dubbo.context.DubboServiceRegistrationApplicationContextInitializer
\ No newline at end of file
diff --git a/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-provider-web-sample/src/main/resources/application.yaml b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-provider-web-sample/src/main/resources/application.yaml
index a890294c..786da0f2 100644
--- a/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-provider-web-sample/src/main/resources/application.yaml
+++ b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-provider-web-sample/src/main/resources/application.yaml
@@ -16,4 +16,4 @@ feign:
enabled: true
server:
- port: 8080
\ No newline at end of file
+ port: 0
\ No newline at end of file