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/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..5fb3d2e4 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/env/DubboNonWebApplicationEnvironmentPostProcessor.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/env/DubboNonWebApplicationEnvironmentPostProcessor.java
new file mode 100644
index 00000000..60faa7c3
--- /dev/null
+++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/registry/env/DubboNonWebApplicationEnvironmentPostProcessor.java
@@ -0,0 +1,199 @@
+/*
+ * 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.env;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.WebApplicationType;
+import org.springframework.boot.env.EnvironmentPostProcessor;
+import org.springframework.core.Ordered;
+import org.springframework.core.env.ConfigurableEnvironment;
+import org.springframework.core.env.MapPropertySource;
+import org.springframework.core.env.MutablePropertySources;
+import org.springframework.core.env.PropertySource;
+import org.springframework.util.StringUtils;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+import static org.apache.dubbo.common.Constants.DEFAULT_PROTOCOL;
+import static org.apache.dubbo.config.spring.util.PropertySourcesUtils.getSubProperties;
+
+/**
+ * Dubbo {@link WebApplicationType#NONE Non-Web Application} {@link EnvironmentPostProcessor}
+ *
+ * @author Mercy
+ */
+public class DubboNonWebApplicationEnvironmentPostProcessor implements EnvironmentPostProcessor, Ordered {
+
+ private static final String DOT = ".";
+
+ /**
+ * The name of default {@link PropertySource} defined in SpringApplication#configurePropertySources method.
+ */
+ private static final String PROPERTY_SOURCE_NAME = "defaultProperties";
+
+ private static final String SERVER_PORT_PROPERTY_NAME = "server.port";
+
+ private static final String PORT_PROPERTY_NAME = "port";
+
+ private static final String PROTOCOL_PROPERTY_NAME_PREFIX = "dubbo.protocol";
+
+ private static final String PROTOCOL_NAME_PROPERTY_NAME_SUFFIX = DOT + "name";
+
+ private static final String PROTOCOL_PORT_PROPERTY_NAME_SUFFIX = DOT + PORT_PROPERTY_NAME;
+
+ private static final String PROTOCOL_PORT_PROPERTY_NAME = PROTOCOL_PROPERTY_NAME_PREFIX + PROTOCOL_PORT_PROPERTY_NAME_SUFFIX;
+
+ private static final String PROTOCOL_NAME_PROPERTY_NAME = PROTOCOL_PROPERTY_NAME_PREFIX + PROTOCOL_NAME_PROPERTY_NAME_SUFFIX;
+
+ private static final String PROTOCOLS_PROPERTY_NAME_PREFIX = "dubbo.protocols";
+
+ private static final String REST_PROTOCOL = "rest";
+
+ private final Logger logger = LoggerFactory.getLogger(DubboNonWebApplicationEnvironmentPostProcessor.class);
+
+ @Override
+ public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
+ WebApplicationType webApplicationType = application.getWebApplicationType();
+
+ if (!WebApplicationType.NONE.equals(webApplicationType)) { // Just works in Non-Web Application
+ if (logger.isDebugEnabled()) {
+ logger.debug("Current application is a Web Application, the process will be ignored.");
+ }
+ return;
+ }
+
+ resetServerPort(environment);
+ }
+
+ /**
+ * Reset server port property if it's absent, whose value is configured by "dubbbo.protocol.port"
+ * or "dubbo.protcols.rest.port"
+ *
+ * @param environment
+ */
+ private void resetServerPort(ConfigurableEnvironment environment) {
+
+ String serverPort = environment.getProperty(SERVER_PORT_PROPERTY_NAME, environment.getProperty(PORT_PROPERTY_NAME));
+
+ if (serverPort != null) {
+ return;
+ }
+
+ serverPort = getRestPortFromProtocolProperty(environment);
+
+ if (serverPort == null) {
+ serverPort = getRestPortFromProtocolsProperties(environment);
+ }
+
+ setServerPort(environment, serverPort);
+
+ }
+
+ private String getRestPortFromProtocolProperty(ConfigurableEnvironment environment) {
+
+ String protocol = environment.getProperty(PROTOCOL_NAME_PROPERTY_NAME, DEFAULT_PROTOCOL);
+
+ return isRestProtocol(protocol) ?
+ environment.getProperty(PROTOCOL_PORT_PROPERTY_NAME) :
+ null;
+ }
+
+ private String getRestPortFromProtocolsProperties(ConfigurableEnvironment environment) {
+
+ String restPort = null;
+
+ Map subProperties = getSubProperties(environment, PROTOCOLS_PROPERTY_NAME_PREFIX);
+
+ Properties properties = new Properties();
+
+ properties.putAll(subProperties);
+
+ for (String propertyName : properties.stringPropertyNames()) {
+ if (propertyName.endsWith(PROTOCOL_NAME_PROPERTY_NAME_SUFFIX)) { // protocol name property
+ String protocol = properties.getProperty(propertyName);
+ if (isRestProtocol(protocol)) {
+ String beanName = resolveBeanName(propertyName);
+ if (StringUtils.hasText(beanName)) {
+ restPort = properties.getProperty(beanName + PROTOCOL_PORT_PROPERTY_NAME_SUFFIX);
+ break;
+ }
+ }
+ }
+ }
+
+ return restPort;
+ }
+
+ private String resolveBeanName(String propertyName) {
+ int index = propertyName.indexOf(DOT);
+ return index > -1 ? propertyName.substring(0, index) : null;
+ }
+
+ private void setServerPort(ConfigurableEnvironment environment, String serverPort) {
+ if (serverPort == null) {
+ return;
+ }
+
+ MutablePropertySources propertySources = environment.getPropertySources();
+
+ Map properties = new HashMap<>();
+ properties.put(SERVER_PORT_PROPERTY_NAME, String.valueOf(serverPort));
+
+ addOrReplace(propertySources, properties);
+ }
+
+ /**
+ * Copy from BusEnvironmentPostProcessor#addOrReplace(MutablePropertySources, Map)
+ *
+ * @param propertySources {@link MutablePropertySources}
+ * @param map Default Dubbo Properties
+ */
+ private void addOrReplace(MutablePropertySources propertySources,
+ Map map) {
+ MapPropertySource target = null;
+ if (propertySources.contains(PROPERTY_SOURCE_NAME)) {
+ PropertySource> source = propertySources.get(PROPERTY_SOURCE_NAME);
+ if (source instanceof MapPropertySource) {
+ target = (MapPropertySource) source;
+ for (String key : map.keySet()) {
+ if (!target.containsProperty(key)) {
+ target.getSource().put(key, map.get(key));
+ }
+ }
+ }
+ }
+ if (target == null) {
+ target = new MapPropertySource(PROPERTY_SOURCE_NAME, map);
+ }
+ if (!propertySources.contains(PROPERTY_SOURCE_NAME)) {
+ propertySources.addLast(target);
+ }
+ }
+
+ @Override
+ public int getOrder() { // Keep LOWEST_PRECEDENCE
+ return LOWEST_PRECEDENCE;
+ }
+
+ private static boolean isRestProtocol(String protocol) {
+ return REST_PROTOCOL.equalsIgnoreCase(protocol);
+ }
+}
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 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/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..515af6f5 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.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.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.registry.env.DubboNonWebApplicationEnvironmentPostProcessor
\ No newline at end of file
diff --git a/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/pom.xml b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/pom.xml
index 6d548b81..424a48c8 100644
--- a/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/pom.xml
+++ b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/pom.xml
@@ -20,6 +20,7 @@
spring-cloud-dubbo-provider-sample
spring-cloud-dubbo-consumer-sample
spring-cloud-dubbo-provider-web-sample
+ spring-cloud-dubbo-servlet-gateway-sample
diff --git a/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-consumer-sample/src/main/java/org/springframework/cloud/alibaba/dubbo/bootstrap/DubboSpringCloudConsumerBootstrap.java b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-consumer-sample/src/main/java/org/springframework/cloud/alibaba/dubbo/bootstrap/DubboSpringCloudConsumerBootstrap.java
index 8c2a0c9e..2e389ce2 100644
--- a/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-consumer-sample/src/main/java/org/springframework/cloud/alibaba/dubbo/bootstrap/DubboSpringCloudConsumerBootstrap.java
+++ b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-consumer-sample/src/main/java/org/springframework/cloud/alibaba/dubbo/bootstrap/DubboSpringCloudConsumerBootstrap.java
@@ -17,6 +17,7 @@
package org.springframework.cloud.alibaba.dubbo.bootstrap;
import org.apache.dubbo.config.annotation.Reference;
+
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationRunner;
@@ -52,7 +53,7 @@ import static org.springframework.http.MediaType.APPLICATION_JSON_UTF8_VALUE;
@EnableFeignClients
public class DubboSpringCloudConsumerBootstrap {
- @Reference(version = "1.0.0")
+ @Reference(version = "1.0.0", protocol = "dubbo")
private RestService restService;
@Autowired
@@ -94,7 +95,7 @@ public class DubboSpringCloudConsumerBootstrap {
}
@FeignClient("${provider.application.name}")
- @DubboTransported()
+ @DubboTransported(protocol = "dubbo")
public interface DubboFeignRestService {
@GetMapping(value = "/param")
diff --git a/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-consumer-sample/src/main/resources/application.yaml b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-consumer-sample/src/main/resources/application.yaml
index 263a5699..41c67146 100644
--- a/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-consumer-sample/src/main/resources/application.yaml
+++ b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-consumer-sample/src/main/resources/application.yaml
@@ -9,4 +9,4 @@ server:
provider:
application:
- name: spring-cloud-alibaba-dubbo-web-provider
\ No newline at end of file
+ name: spring-cloud-alibaba-dubbo-provider
\ No newline at end of file
diff --git a/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-provider-sample/pom.xml b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-provider-sample/pom.xml
index 3f5c35cb..14424d8a 100644
--- a/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-provider-sample/pom.xml
+++ b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-provider-sample/pom.xml
@@ -17,6 +17,13 @@
+
+
+ javax.servlet
+ javax.servlet-api
+ 3.1.0
+
+
org.springframework
diff --git a/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-provider-sample/src/main/java/org/springframework/cloud/alibaba/dubbo/bootstrap/DubboSpringCloudProviderBootstrap.java b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-provider-sample/src/main/java/org/springframework/cloud/alibaba/dubbo/bootstrap/DubboSpringCloudProviderBootstrap.java
index 4606a190..8e6ed4e9 100644
--- a/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-provider-sample/src/main/java/org/springframework/cloud/alibaba/dubbo/bootstrap/DubboSpringCloudProviderBootstrap.java
+++ b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-provider-sample/src/main/java/org/springframework/cloud/alibaba/dubbo/bootstrap/DubboSpringCloudProviderBootstrap.java
@@ -16,6 +16,7 @@
*/
package org.springframework.cloud.alibaba.dubbo.bootstrap;
+import org.springframework.boot.WebApplicationType;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@@ -30,6 +31,7 @@ public class DubboSpringCloudProviderBootstrap {
public static void main(String[] args) {
new SpringApplicationBuilder(DubboSpringCloudProviderBootstrap.class)
.properties("spring.profiles.active=nacos")
+ .web(WebApplicationType.NONE)
.run(args);
}
}
diff --git a/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-provider-web-sample/src/main/resources/bootstrap.yaml b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-provider-web-sample/src/main/resources/bootstrap.yaml
index fd82247b..0d8dfca9 100644
--- a/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-provider-web-sample/src/main/resources/bootstrap.yaml
+++ b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-provider-web-sample/src/main/resources/bootstrap.yaml
@@ -1,6 +1,6 @@
spring:
application:
- name: spring-cloud-alibaba-dubbo-web-provider
+ name: spring-cloud-alibaba-dubbo-provider
main:
allow-bean-definition-overriding: true
diff --git a/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-servlet-gateway-sample/pom.xml b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-servlet-gateway-sample/pom.xml
new file mode 100644
index 00000000..75b6d18e
--- /dev/null
+++ b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-servlet-gateway-sample/pom.xml
@@ -0,0 +1,39 @@
+
+
+
+ spring-cloud-alibaba-dubbo-examples
+ org.springframework.cloud
+ 0.2.2.BUILD-SNAPSHOT
+ ../pom.xml
+
+ 4.0.0
+
+ org.springframework.cloud
+ spring-cloud-dubbo-servlet-gateway-sample
+ Spring Cloud Dubbo Servlet Gateway Sample
+
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+
+
+ org.springframework.cloud
+ spring-cloud-dubbo-sample-api
+ ${project.version}
+
+
+
+
+ org.springframework.cloud
+ spring-cloud-starter-openfeign
+
+
+
+
+
\ No newline at end of file
diff --git a/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-servlet-gateway-sample/src/main/java/org/springframework/cloud/alibaba/dubbo/bootstrap/DubboSpringCloudServletGatewayBootstrap.java b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-servlet-gateway-sample/src/main/java/org/springframework/cloud/alibaba/dubbo/bootstrap/DubboSpringCloudServletGatewayBootstrap.java
new file mode 100644
index 00000000..0ad4d68e
--- /dev/null
+++ b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-servlet-gateway-sample/src/main/java/org/springframework/cloud/alibaba/dubbo/bootstrap/DubboSpringCloudServletGatewayBootstrap.java
@@ -0,0 +1,23 @@
+package org.springframework.cloud.alibaba.dubbo.bootstrap;
+
+import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
+import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.boot.web.servlet.ServletComponentScan;
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+
+/**
+ * Dubbo Spring Cloud Servlet Gateway Bootstrap
+ */
+@EnableDiscoveryClient
+@EnableAutoConfiguration
+@EnableFeignClients
+@ServletComponentScan(basePackages = "org.springframework.cloud.alibaba.dubbo.gateway")
+public class DubboSpringCloudServletGatewayBootstrap {
+
+ public static void main(String[] args) {
+ new SpringApplicationBuilder(DubboSpringCloudServletGatewayBootstrap.class)
+ .properties("spring.profiles.active=nacos")
+ .run(args);
+ }
+}
diff --git a/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-servlet-gateway-sample/src/main/java/org/springframework/cloud/alibaba/dubbo/gateway/DubboGatewayServlet.java b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-servlet-gateway-sample/src/main/java/org/springframework/cloud/alibaba/dubbo/gateway/DubboGatewayServlet.java
new file mode 100644
index 00000000..0bff5e0c
--- /dev/null
+++ b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-servlet-gateway-sample/src/main/java/org/springframework/cloud/alibaba/dubbo/gateway/DubboGatewayServlet.java
@@ -0,0 +1,188 @@
+//package org.springframework.cloud.alibaba.dubbo.gateway;
+//
+//import org.apache.commons.lang.StringUtils;
+//import org.apache.dubbo.rpc.service.GenericException;
+//import org.apache.dubbo.rpc.service.GenericService;
+//import org.springframework.cloud.alibaba.dubbo.http.MutableHttpServerRequest;
+//import org.springframework.cloud.alibaba.dubbo.metadata.DubboServiceMetadata;
+//import org.springframework.cloud.alibaba.dubbo.metadata.DubboTransportedMetadata;
+//import org.springframework.cloud.alibaba.dubbo.metadata.RequestMetadata;
+//import org.springframework.cloud.alibaba.dubbo.metadata.RestMethodMetadata;
+//import org.springframework.cloud.alibaba.dubbo.metadata.repository.DubboServiceMetadataRepository;
+//import org.springframework.cloud.alibaba.dubbo.service.DubboGenericServiceExecutionContext;
+//import org.springframework.cloud.alibaba.dubbo.service.DubboGenericServiceExecutionContextFactory;
+//import org.springframework.cloud.alibaba.dubbo.service.DubboGenericServiceFactory;
+//import org.springframework.http.HttpHeaders;
+//import org.springframework.http.HttpRequest;
+//import org.springframework.util.AntPathMatcher;
+//import org.springframework.util.CollectionUtils;
+//import org.springframework.util.PathMatcher;
+//import org.springframework.util.StreamUtils;
+//import org.springframework.web.util.UriComponents;
+//
+//import javax.servlet.ServletException;
+//import javax.servlet.ServletInputStream;
+//import javax.servlet.annotation.WebServlet;
+//import javax.servlet.http.HttpServlet;
+//import javax.servlet.http.HttpServletRequest;
+//import javax.servlet.http.HttpServletResponse;
+//import java.io.IOException;
+//import java.net.URI;
+//import java.net.URISyntaxException;
+//import java.util.*;
+//
+//import static org.springframework.web.util.UriComponentsBuilder.fromUriString;
+//
+//@WebServlet(urlPatterns = "/dsc/*")
+//public class DubboGatewayServlet extends HttpServlet {
+//
+// private final DubboServiceMetadataRepository repository;
+//
+// private final DubboTransportedMetadata dubboTransportedMetadata;
+//
+// private final DubboGenericServiceFactory serviceFactory;
+//
+// private final DubboGenericServiceExecutionContextFactory contextFactory;
+//
+// private final PathMatcher pathMatcher = new AntPathMatcher();
+//
+// public DubboGatewayServlet(DubboServiceMetadataRepository repository,
+// DubboGenericServiceFactory serviceFactory,
+// DubboGenericServiceExecutionContextFactory contextFactory) {
+// this.repository = repository;
+// this.dubboTransportedMetadata = new DubboTransportedMetadata();
+// dubboTransportedMetadata.setProtocol("dubbo");
+// dubboTransportedMetadata.setCluster("failover");
+// this.serviceFactory = serviceFactory;
+// this.contextFactory = contextFactory;
+// }
+//
+// public void service(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
+//
+// // /g/{app-name}/{rest-path}
+// String requestURI = request.getRequestURI();
+// // /g/
+// String servletPath = request.getServletPath();
+//
+// String part = StringUtils.substringAfter(requestURI, servletPath);
+//
+// String serviceName = StringUtils.substringBetween(part, "/", "/");
+//
+// // App name= spring-cloud-alibaba-dubbo-web-provider (127.0.0.1:8080)
+//
+// String restPath = StringUtils.substringAfter(part, serviceName);
+//
+// // 初始化 serviceName 的 REST 请求元数据
+// repository.initialize(serviceName);
+// // 将 HttpServletRequest 转化为 RequestMetadata
+// RequestMetadata clientMetadata = buildRequestMetadata(request, restPath);
+//
+// DubboServiceMetadata dubboServiceMetadata = repository.get(serviceName, clientMetadata);
+//
+// if (dubboServiceMetadata == null) {
+// // if DubboServiceMetadata is not found, executes next
+// throw new ServletException("DubboServiceMetadata can't be found!");
+// }
+//
+// RestMethodMetadata dubboRestMethodMetadata = dubboServiceMetadata.getRestMethodMetadata();
+//
+// GenericService genericService = serviceFactory.create(dubboServiceMetadata, dubboTransportedMetadata);
+//
+// // TODO: Get the Request Body from HttpServletRequest
+// byte[] body = getRequestBody(request);
+//
+// MutableHttpServerRequest httpServerRequest = new MutableHttpServerRequest(new HttpRequestAdapter(request), body);
+//
+//// customizeRequest(httpServerRequest, dubboRestMethodMetadata, clientMetadata);
+//
+// DubboGenericServiceExecutionContext context = contextFactory.create(dubboRestMethodMetadata, httpServerRequest);
+//
+// Object result = null;
+// GenericException exception = null;
+//
+// try {
+// result = genericService.$invoke(context.getMethodName(), context.getParameterTypes(), context.getParameters());
+// } catch (GenericException e) {
+// exception = e;
+// }
+// response.getWriter().println(result);
+// }
+//
+// private byte[] getRequestBody(HttpServletRequest request) throws IOException {
+// ServletInputStream inputStream = request.getInputStream();
+// return StreamUtils.copyToByteArray(inputStream);
+// }
+//
+// private static class HttpRequestAdapter implements HttpRequest {
+//
+// private final HttpServletRequest request;
+//
+// private HttpRequestAdapter(HttpServletRequest request) {
+// this.request = request;
+// }
+//
+// @Override
+// public String getMethodValue() {
+// return request.getMethod();
+// }
+//
+// @Override
+// public URI getURI() {
+// try {
+// return new URI(request.getRequestURL().toString() + "?" + request.getQueryString());
+// } catch (URISyntaxException e) {
+// e.printStackTrace();
+// }
+// throw new RuntimeException();
+// }
+//
+// @Override
+// public HttpHeaders getHeaders() {
+// return new HttpHeaders();
+// }
+// }
+//
+//// protected void customizeRequest(MutableHttpServerRequest httpServerRequest,
+//// RestMethodMetadata dubboRestMethodMetadata, RequestMetadata clientMetadata) {
+////
+//// RequestMetadata dubboRequestMetadata = dubboRestMethodMetadata.getRequest();
+//// String pathPattern = dubboRequestMetadata.getPath();
+////
+//// Map pathVariables = pathMatcher.extractUriTemplateVariables(pathPattern, httpServerRequest.getPath());
+////
+//// if (!CollectionUtils.isEmpty(pathVariables)) {
+//// // Put path variables Map into query parameters Map
+//// httpServerRequest.params(pathVariables);
+//// }
+////
+//// }
+//
+// private RequestMetadata buildRequestMetadata(HttpServletRequest request, String restPath) {
+// UriComponents uriComponents = fromUriString(request.getRequestURI()).build(true);
+// RequestMetadata requestMetadata = new RequestMetadata();
+// requestMetadata.setPath(restPath);
+// requestMetadata.setMethod(request.getMethod());
+// requestMetadata.setParams(getParams(request));
+// requestMetadata.setHeaders(getHeaders(request));
+// return requestMetadata;
+// }
+//
+// private Map> getHeaders(HttpServletRequest request) {
+// Map> map = new LinkedHashMap<>();
+// Enumeration headerNames = request.getHeaderNames();
+// while (headerNames.hasMoreElements()) {
+// String headerName = headerNames.nextElement();
+// Enumeration headerValues = request.getHeaders(headerName);
+// map.put(headerName, Collections.list(headerValues));
+// }
+// return map;
+// }
+//
+// private Map> getParams(HttpServletRequest request) {
+// Map> map = new LinkedHashMap<>();
+// for (Map.Entry entry : request.getParameterMap().entrySet()) {
+// map.put(entry.getKey(), Arrays.asList(entry.getValue()));
+// }
+// return map;
+// }
+//}
diff --git a/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-servlet-gateway-sample/src/main/resources/application.yaml b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-servlet-gateway-sample/src/main/resources/application.yaml
new file mode 100644
index 00000000..263a5699
--- /dev/null
+++ b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-servlet-gateway-sample/src/main/resources/application.yaml
@@ -0,0 +1,12 @@
+dubbo:
+ registry:
+ # The Spring Cloud Dubbo's registry extension
+ address: spring-cloud://localhost
+# The traditional Dubbo's registry
+# address: zookeeper://127.0.0.1:2181
+server:
+ port: 0
+
+provider:
+ application:
+ name: spring-cloud-alibaba-dubbo-web-provider
\ No newline at end of file
diff --git a/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-servlet-gateway-sample/src/main/resources/bootstrap.yaml b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-servlet-gateway-sample/src/main/resources/bootstrap.yaml
new file mode 100644
index 00000000..a86acd15
--- /dev/null
+++ b/spring-cloud-alibaba-examples/spring-cloud-alibaba-dubbo-examples/spring-cloud-dubbo-servlet-gateway-sample/src/main/resources/bootstrap.yaml
@@ -0,0 +1,70 @@
+spring:
+ application:
+ name: spring-cloud-alibaba-dubbo-servlet-gateway
+ main:
+ allow-bean-definition-overriding: true
+
+
+ # default disable all
+ cloud:
+ nacos:
+ discovery:
+ enabled: false
+ register-enabled: false
+ zookeeper:
+ enabled: false
+ consul:
+ enabled: false
+
+eureka:
+ client:
+ enabled: false
+
+ribbon:
+ nacos:
+ enabled: false
+
+---
+spring:
+ profiles: nacos
+
+ cloud:
+ nacos:
+ discovery:
+ enabled: true
+ register-enabled: true
+ server-addr: 127.0.0.1:8848
+
+ribbon:
+ nacos:
+ enabled: true
+
+---
+spring:
+ profiles: eureka
+
+eureka:
+ client:
+ enabled: true
+ service-url:
+ defaultZone: http://127.0.0.1:8761/eureka/
+
+
+---
+spring:
+ profiles: zookeeper
+ cloud:
+ zookeeper:
+ enabled: true
+ connect-string: 127.0.0.1:2181
+
+
+---
+spring:
+ profiles: consul
+
+ cloud:
+ consul:
+ enabled: true
+ host: 127.0.0.1
+ port: 8500
\ 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..6e6c2008 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;
@@ -77,26 +75,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