dubboTranslatedAttributes = dubboTransportedMethodMetadata.getAttributes();
Method method = dubboTransportedMethodMetadata.getMethod();
- GenericService dubboGenericService = dubboGenericServiceFactory.create(dubboServiceMetadata, dubboTransportedMetadata);
- 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/DubboServiceRegistrationEventPublishingAspect.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/DubboServiceRegistrationEventPublishingAspect.java
new file mode 100644
index 00000000..17826624
--- /dev/null
+++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/DubboServiceRegistrationEventPublishingAspect.java
@@ -0,0 +1,61 @@
+/*
+ * 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;
+
+/**
+ * Dubbo Service Registration Event-Publishing Aspect
+ *
+ * @author Mercy
+ * @see ServiceInstancePreRegisteredEvent
+ * @see ServiceInstanceRegisteredEvent
+ */
+@Aspect
+public class DubboServiceRegistrationEventPublishingAspect implements ApplicationEventPublisherAware {
+
+ /**
+ * The pointcut expression for {@link ServiceRegistry#register(Registration)}
+ */
+ public 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/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/SpringCloudRegistry.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/SpringCloudRegistry.java
index d87e1f6c..24db7366 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,60 @@
*/
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.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 java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.LinkedList;
import java.util.List;
-import java.util.Map;
import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
-
-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 java.util.stream.Collectors;
/**
* 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}
- */
- public static final String ALL_SERVICES_LOOKUP_INTERVAL_PARAM_NAME = "dubbo.all.services.lookup.interval";
+ private final DubboServiceMetadataRepository dubboServiceMetadataRepository;
- /**
- * The parameter name of {@link #registeredServicesLookupInterval}
- */
- public static final String REGISTERED_SERVICES_LOOKUP_INTERVAL_PARAM_NAME = "dubbo.registered.services.lookup.interval";
-
- /**
- * All supported categories
- */
- public static final String[] ALL_SUPPORTED_CATEGORIES = of(
- PROVIDERS_CATEGORY,
- CONSUMERS_CATEGORY,
- ROUTERS_CATEGORY,
- CONFIGURATORS_CATEGORY
- );
-
- private final Logger logger = LoggerFactory.getLogger(getClass());
-
- /**
- * The interval in second of lookup service names(only for Dubbo-OPS)
- */
- private final long allServicesLookupInterval;
-
- private final long registeredServicesLookupInterval;
-
- private final ServiceRegistry serviceRegistry;
-
- 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,
- 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;
- }
-
- protected boolean shouldRegister(Registration registration) {
- Map metadata = registration.getMetadata();
- String side = metadata.get(SIDE_KEY);
- return PROVIDER_SIDE.equals(side); // Only register the Provider.
+ DubboServiceMetadataRepository dubboServiceMetadataRepository) {
+ super(url, discoveryClient, servicesLookupScheduler);
+ this.dubboServiceMetadataRepository = dubboServiceMetadataRepository;
}
@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 dubboServiceMetadataRepository.isSubscribedService(serviceName);
}
@Override
- public void doUnsubscribe(URL url, NotifyListener listener) {
- if (isAdminProtocol(url)) {
- shutdownServiceNamesLookup();
- }
+ protected String getServiceName(URL url) {
+ return dubboServiceMetadataRepository.getServiceName(url);
}
@Override
- public boolean isAvailable() {
- return !discoveryClient.getServices().isEmpty();
+ protected void notifySubscriber(URL url, NotifyListener listener, List serviceInstances) {
+ List urls = serviceInstances.stream()
+ .map(dubboServiceMetadataRepository::buildURLs)
+ .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..4a046801 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,14 @@ 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);
}
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 6657343f..00000000
--- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/apache/zookeeper/ZookeeperRegistrationFactory.java
+++ /dev/null
@@ -1,49 +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();
-
- 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/handler/DubboRegistryServiceIdHandler.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/handler/DubboRegistryServiceIdHandler.java
deleted file mode 100644
index 15a35029..00000000
--- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/handler/DubboRegistryServiceIdHandler.java
+++ /dev/null
@@ -1,53 +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.handler;
-
-import org.apache.dubbo.common.URL;
-import org.apache.dubbo.registry.Registry;
-import org.springframework.context.ConfigurableApplicationContext;
-
-/**
- * Dubbo {@link Registry} Spring Cloud Service Id Builder
- *
- * @author Mercy
- */
-public interface DubboRegistryServiceIdHandler {
-
- /**
- * Supports the specified id of Spring Cloud Service or not
- *
- * @param serviceId the specified id of Spring Cloud Service
- * @return if supports, return true
, or false
- */
- boolean supports(String serviceId);
-
- /**
- * Creates the id of Spring Cloud Service
- *
- * @param url The Dubbo's {@link URL}
- * @return non-null
- */
- String createServiceId(URL url);
-
- /**
- * The instance if {@link ConfigurableApplicationContext} .
- *
- * @return non-null
- */
- ConfigurableApplicationContext getContext();
-
-}
diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/handler/StandardDubboRegistryServiceIdHandler.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/handler/StandardDubboRegistryServiceIdHandler.java
deleted file mode 100644
index caaa0706..00000000
--- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/handler/StandardDubboRegistryServiceIdHandler.java
+++ /dev/null
@@ -1,96 +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.handler;
-
-import org.apache.dubbo.common.Constants;
-import org.apache.dubbo.common.URL;
-import org.springframework.context.ConfigurableApplicationContext;
-import org.springframework.util.StringUtils;
-
-import java.util.Objects;
-
-import static java.lang.System.getProperty;
-import static org.apache.dubbo.common.Constants.CONSUMERS_CATEGORY;
-import static org.apache.dubbo.common.Constants.PROVIDERS_CATEGORY;
-import static org.springframework.util.StringUtils.startsWithIgnoreCase;
-
-/**
- * The Standard {@link DubboRegistryServiceIdHandler}
- *
- * The service ID pattern is "${category}:${interface}:${version}:${group}"
- *
- * @author Mercy
- */
-public class StandardDubboRegistryServiceIdHandler implements DubboRegistryServiceIdHandler {
-
- /**
- * The separator for service name that could be changed by the Java Property "dubbo.service.name.separator".
- */
- protected static final String SERVICE_NAME_SEPARATOR = getProperty("dubbo.service.name.separator", ":");
-
- private final ConfigurableApplicationContext context;
-
- public StandardDubboRegistryServiceIdHandler(ConfigurableApplicationContext context) {
- this.context = context;
- }
-
- @Override
- public boolean supports(String serviceId) {
- return startsWithIgnoreCase(serviceId, PROVIDERS_CATEGORY) ||
- startsWithIgnoreCase(serviceId, CONSUMERS_CATEGORY);
- }
-
- @Override
- public String createServiceId(URL url) {
- String category = url.getParameter(Constants.CATEGORY_KEY, Constants.DEFAULT_CATEGORY);
- if (!Objects.equals(category, PROVIDERS_CATEGORY) && !Objects.equals(category, CONSUMERS_CATEGORY)) {
- category = PROVIDERS_CATEGORY;
- }
- return createServiceId(url, category);
- }
-
- @Override
- public ConfigurableApplicationContext getContext() {
- return context;
- }
-
- /**
- * This method maybe override by sub-class.
- *
- * @param url The Dubbo's {@link URL}
- * @param category The category
- * @return
- */
- protected String createServiceId(URL url, String category) {
- StringBuilder serviceNameBuilder = new StringBuilder(category);
- appendIfPresent(serviceNameBuilder, url, Constants.INTERFACE_KEY);
- appendIfPresent(serviceNameBuilder, url, Constants.VERSION_KEY);
- appendIfPresent(serviceNameBuilder, url, Constants.GROUP_KEY);
- return serviceNameBuilder.toString();
- }
-
- private static void appendIfPresent(StringBuilder target, URL url, String parameterName) {
- String parameterValue = url.getParameter(parameterName);
- appendIfPresent(target, parameterValue);
- }
-
- private static void appendIfPresent(StringBuilder target, String parameterValue) {
- if (StringUtils.hasText(parameterValue)) {
- target.append(SERVICE_NAME_SEPARATOR).append(parameterValue);
- }
- }
-}
diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/hashicorp/consul/ConsulRegistrationFactory.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/hashicorp/consul/ConsulRegistrationFactory.java
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 84fafa62..00000000
--- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/netflix/eureka/EurekaRegistrationFactory.java
+++ /dev/null
@@ -1,59 +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.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 e15bbb69..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
@@ -17,24 +17,31 @@
package org.springframework.cloud.alibaba.dubbo.service;
import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.config.spring.ReferenceBean;
import org.apache.dubbo.rpc.service.GenericService;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.cloud.alibaba.dubbo.metadata.DubboServiceMetadata;
-import org.springframework.cloud.alibaba.dubbo.metadata.DubboTransportedMetadata;
+import org.springframework.beans.MutablePropertyValues;
+import org.springframework.beans.propertyeditors.StringTrimmerEditor;
+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;
import javax.annotation.PreDestroy;
+import java.beans.PropertyEditorSupport;
import java.util.Collection;
+import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
-import static org.apache.dubbo.common.Constants.DEFAULT_CLUSTER;
-import static org.apache.dubbo.common.Constants.DEFAULT_PROTOCOL;
+import static java.util.Collections.emptyMap;
import static org.apache.dubbo.common.Constants.GROUP_KEY;
import static org.apache.dubbo.common.Constants.VERSION_KEY;
+import static org.springframework.util.StringUtils.commaDelimitedListToStringArray;
/**
* Dubbo {@link GenericService} Factory
@@ -47,39 +54,36 @@ public class DubboGenericServiceFactory {
private final ConcurrentMap> cache = new ConcurrentHashMap<>();
- public GenericService create(DubboServiceMetadata dubboServiceMetadata,
- DubboTransportedMetadata dubboTransportedMetadata) {
+ public GenericService create(DubboRestServiceMetadata dubboServiceMetadata,
+ Map dubboTranslatedAttributes) {
- ReferenceBean referenceBean = build(dubboServiceMetadata.getServiceRestMetadata(), dubboTransportedMetadata);
+ ReferenceBean referenceBean = build(dubboServiceMetadata.getServiceRestMetadata(), dubboTranslatedAttributes);
return referenceBean == null ? null : referenceBean.get();
}
public GenericService create(String serviceName, Class> serviceClass) {
String interfaceName = serviceClass.getName();
- ReferenceBean referenceBean = build(interfaceName, serviceName, null,
- DEFAULT_PROTOCOL, DEFAULT_CLUSTER);
+ ReferenceBean referenceBean = build(interfaceName, serviceName, null, emptyMap());
return referenceBean.get();
}
private ReferenceBean build(ServiceRestMetadata serviceRestMetadata,
- DubboTransportedMetadata dubboTransportedMetadata) {
+ Map dubboTranslatedAttributes) {
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();
+ String group = url.getParameter(GROUP_KEY);
- return build(interfaceName, version, group, protocol, cluster);
+ return build(interfaceName, version, group, dubboTranslatedAttributes);
}
- private ReferenceBean build(String interfaceName, String version, String group, String protocol,
- String cluster) {
+ private ReferenceBean build(String interfaceName, String version, String group,
+ Map dubboTranslatedAttributes) {
- Integer key = Objects.hash(interfaceName, version, group, protocol, cluster);
+ Integer key = Objects.hash(interfaceName, version, group, dubboTranslatedAttributes);
ReferenceBean referenceBean = cache.get(key);
@@ -89,13 +93,38 @@ public class DubboGenericServiceFactory {
referenceBean.setInterface(interfaceName);
referenceBean.setVersion(version);
referenceBean.setGroup(group);
- referenceBean.setProtocol(protocol);
- referenceBean.setCluster(cluster);
+ bindReferenceBean(referenceBean, dubboTranslatedAttributes);
}
return referenceBean;
}
+ private void bindReferenceBean(ReferenceBean referenceBean, Map dubboTranslatedAttributes) {
+ DataBinder dataBinder = new DataBinder(referenceBean);
+ // Register CustomEditors for special fields
+ dataBinder.registerCustomEditor(String.class, "filter", new StringTrimmerEditor(true));
+ dataBinder.registerCustomEditor(String.class, "listener", new StringTrimmerEditor(true));
+ dataBinder.registerCustomEditor(Map.class, "parameters", new PropertyEditorSupport() {
+
+ public void setAsText(String text) throws java.lang.IllegalArgumentException {
+ // Trim all whitespace
+ String content = StringUtils.trimAllWhitespace(text);
+ if (!StringUtils.hasText(content)) { // No content , ignore directly
+ return;
+ }
+ // replace "=" to ","
+ content = StringUtils.replace(content, "=", ",");
+ // replace ":" to ","
+ content = StringUtils.replace(content, ":", ",");
+ // String[] to Map
+ Map parameters = CollectionUtils.toStringMap(commaDelimitedListToStringArray(content));
+ setValue(parameters);
+ }
+ });
+
+ dataBinder.bind(new MutablePropertyValues(dubboTranslatedAttributes));
+ }
+
@PreDestroy
public void destroy() {
destroyReferenceBeans();
diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/service/DubboMetadataConfigServiceExporter.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/service/DubboMetadataConfigServiceExporter.java
new file mode 100644
index 00000000..a47d1895
--- /dev/null
+++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/service/DubboMetadataConfigServiceExporter.java
@@ -0,0 +1,109 @@
+/*
+ * 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.service;
+
+import org.apache.dubbo.config.ApplicationConfig;
+import org.apache.dubbo.config.ProtocolConfig;
+import org.apache.dubbo.config.ServiceConfig;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+import org.springframework.util.StringUtils;
+
+import java.util.function.Supplier;
+
+/**
+ * {@link DubboMetadataConfigService} exporter
+ *
+ * @author Mercy
+ */
+@Component
+public class DubboMetadataConfigServiceExporter {
+
+ private final Logger logger = LoggerFactory.getLogger(getClass());
+
+ @Autowired
+ private ApplicationConfig applicationConfig;
+
+ @Autowired
+ private PublishingDubboMetadataConfigService dubboMetadataConfigService;
+
+ @Autowired
+ private Supplier protocolConfigSupplier;
+
+ @Value("${spring.application.name:application}")
+ private String currentApplicationName;
+
+ /**
+ * The ServiceConfig of DubboMetadataConfigService to be exported, can be nullable.
+ */
+ private ServiceConfig serviceConfig;
+
+ /**
+ * export {@link DubboMetadataConfigService} as Dubbo service
+ */
+ public void export() {
+
+ if (serviceConfig != null && serviceConfig.isExported()) {
+ return;
+ }
+
+ if (StringUtils.isEmpty(dubboMetadataConfigService.getServiceRestMetadata())) {
+ // If there is no REST metadata, DubboMetadataConfigService will not be exported.
+ if (logger.isInfoEnabled()) {
+ logger.info("There is no REST metadata, the Dubbo service[{}] will not be exported.",
+ dubboMetadataConfigService.getClass().getName());
+ }
+ return;
+ }
+
+ serviceConfig = new ServiceConfig<>();
+
+ serviceConfig.setInterface(DubboMetadataConfigService.class);
+ // Use current Spring application name as the Dubbo Service version
+ serviceConfig.setVersion(currentApplicationName);
+ serviceConfig.setRef(dubboMetadataConfigService);
+ serviceConfig.setApplication(applicationConfig);
+ serviceConfig.setProtocol(protocolConfigSupplier.get());
+
+ serviceConfig.export();
+
+ if (logger.isInfoEnabled()) {
+ logger.info("The Dubbo service[{}] has been exported.", serviceConfig.toString());
+ }
+ }
+
+
+ /**
+ * unexport {@link DubboMetadataConfigService}
+ */
+ public void unexport() {
+
+ if (serviceConfig == null || serviceConfig.isUnexported()) {
+ return;
+ }
+
+ serviceConfig.unexport();
+
+ if (logger.isInfoEnabled()) {
+ logger.info("The Dubbo service[{}] has been unexported.", serviceConfig.toString());
+ }
+ }
+}
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..46ad6959 100644
--- a/spring-cloud-alibaba-dubbo/src/main/resources/META-INF/spring.factories
+++ b/spring-cloud-alibaba-dubbo/src/main/resources/META-INF/spring.factories
@@ -1,14 +1,15 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
- org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboMetadataAutoConfiguration,\
- org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboOpenFeignAutoConfiguration,\
- org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboMetadataEventHandlingAutoConfiguration,\
- org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboLoadBalancedRestTemplateAutoConfiguration,\
- org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboServiceAutoConfiguration
+org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboMetadataAutoConfiguration,\
+org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboOpenFeignAutoConfiguration,\
+org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboServiceRegistrationAutoConfiguration,\
+org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboServiceRegistrationNonWebApplicationAutoConfiguration,\
+org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboLoadBalancedRestTemplateAutoConfiguration,\
+org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboServiceAutoConfiguration
+
org.springframework.context.ApplicationContextInitializer=\
- org.springframework.cloud.alibaba.dubbo.context.DubboServiceRegistrationApplicationContextInitializer
+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.boot.env.EnvironmentPostProcessor=\
+org.springframework.cloud.alibaba.dubbo.env.DubboNonWebApplicationEnvironmentPostProcessor
\ No newline at end of file
diff --git a/spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/NacosDiscoveryAutoConfiguration.java b/spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/NacosDiscoveryAutoConfiguration.java
index 97e04060..c092f62a 100644
--- a/spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/NacosDiscoveryAutoConfiguration.java
+++ b/spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/NacosDiscoveryAutoConfiguration.java
@@ -16,12 +16,10 @@
package org.springframework.cloud.alibaba.nacos;
-import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnNotWebApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.alibaba.nacos.discovery.NacosDiscoveryClientAutoConfiguration;
@@ -43,17 +41,10 @@ import org.springframework.context.annotation.Configuration;
@EnableConfigurationProperties
@ConditionalOnNacosDiscoveryEnabled
@ConditionalOnProperty(value = "spring.cloud.service-registry.auto-registration.enabled", matchIfMissing = true)
-@AutoConfigureBefore(NacosDiscoveryClientAutoConfiguration.class)
@AutoConfigureAfter({ AutoServiceRegistrationConfiguration.class,
AutoServiceRegistrationAutoConfiguration.class })
public class NacosDiscoveryAutoConfiguration {
- @Bean
- @ConditionalOnMissingBean
- public NacosDiscoveryProperties nacosProperties() {
- return new NacosDiscoveryProperties();
- }
-
@Bean
public NacosServiceRegistry nacosServiceRegistry(
NacosDiscoveryProperties nacosDiscoveryProperties) {
@@ -77,26 +68,4 @@ public class NacosDiscoveryAutoConfiguration {
return new NacosAutoServiceRegistration(registry,
autoServiceRegistrationProperties, registration);
}
-
- @Bean
- @ConditionalOnBean(NacosAutoServiceRegistration.class) // NacosAutoServiceRegistration
- // should be present
- @ConditionalOnNotWebApplication // Not Web Application
- public ApplicationRunner applicationRunner(
- NacosAutoServiceRegistration nacosAutoServiceRegistration) {
- return args -> {
- // WebServerInitializedEvent should not be multicast in Non-Web environment.
- // Whatever, NacosAutoServiceRegistration must be checked it's running or not.
- if (!nacosAutoServiceRegistration.isRunning()) { // If it's not running, let
- // it start.
- // FIXME: Please make sure "spring.cloud.nacos.discovery.port" must be
- // configured on an available port,
- // or the startup or Nacos health check will be failed.
- nacosAutoServiceRegistration.start();
- // NacosAutoServiceRegistration will be stopped after its destroy() method
- // is invoked.
- // @PreDestroy destroy() -> stop()
- }
- };
- }
}
\ No newline at end of file
diff --git a/spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/discovery/NacosDiscoveryClientAutoConfiguration.java b/spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/discovery/NacosDiscoveryClientAutoConfiguration.java
index 2ddb4c34..2c1433ae 100644
--- a/spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/discovery/NacosDiscoveryClientAutoConfiguration.java
+++ b/spring-cloud-alibaba-nacos-discovery/src/main/java/org/springframework/cloud/alibaba/nacos/discovery/NacosDiscoveryClientAutoConfiguration.java
@@ -33,11 +33,16 @@ import org.springframework.context.annotation.Configuration;
*/
@Configuration
@ConditionalOnNacosDiscoveryEnabled
-@EnableConfigurationProperties
@AutoConfigureBefore({ SimpleDiscoveryClientAutoConfiguration.class,
CommonsClientAutoConfiguration.class })
public class NacosDiscoveryClientAutoConfiguration {
+ @Bean
+ @ConditionalOnMissingBean
+ public NacosDiscoveryProperties nacosProperties() {
+ return new NacosDiscoveryProperties();
+ }
+
@Bean
public DiscoveryClient nacosDiscoveryClient(
NacosDiscoveryProperties discoveryProperties) {