diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboMetadataAutoConfiguration.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboMetadataAutoConfiguration.java index 7eff2f818..94184b4b8 100644 --- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboMetadataAutoConfiguration.java +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboMetadataAutoConfiguration.java @@ -25,12 +25,10 @@ import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.event.ApplicationFailedEvent; -import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.cloud.alibaba.dubbo.metadata.DubboProtocolConfigSupplier; import org.springframework.cloud.alibaba.dubbo.metadata.repository.DubboServiceMetadataRepository; import org.springframework.cloud.alibaba.dubbo.metadata.resolver.DubboServiceBeanMetadataResolver; import org.springframework.cloud.alibaba.dubbo.metadata.resolver.MetadataResolver; -import org.springframework.cloud.alibaba.dubbo.registry.event.ServiceInstancePreRegisteredEvent; import org.springframework.cloud.alibaba.dubbo.service.DubboGenericServiceFactory; import org.springframework.cloud.alibaba.dubbo.service.DubboMetadataConfigServiceExporter; import org.springframework.cloud.alibaba.dubbo.service.DubboMetadataConfigServiceProxy; @@ -89,26 +87,12 @@ public class DubboMetadataAutoConfiguration { public void onServiceBeanExported(ServiceBeanExportedEvent event) { ServiceBean serviceBean = event.getServiceBean(); publishServiceRestMetadata(serviceBean); - } - - /** - * On Dubbo Service registering in Spring Cloud Registry - */ - @EventListener(ServiceInstancePreRegisteredEvent.class) - public void onServiceInstancePreRegistered() { - dubboMetadataConfigServiceExporter.export(); - } - - @EventListener(ApplicationReadyEvent.class) - public void onApplicationReady() { - // Maybe invoke again if used Spring Cloud Registry, - // but don't worry. - dubboMetadataConfigServiceExporter.export(); + exportDubboMetadataConfigService(); } @EventListener(ApplicationFailedEvent.class) public void onApplicationFailed() { - dubboMetadataConfigServiceExporter.unexport(); + unExportDubboMetadataConfigService(); } @EventListener(ContextClosedEvent.class) @@ -119,4 +103,12 @@ public class DubboMetadataAutoConfiguration { private void publishServiceRestMetadata(ServiceBean serviceBean) { dubboMetadataConfigService.publishServiceRestMetadata(metadataResolver.resolveServiceRestMetadata(serviceBean)); } + + private void exportDubboMetadataConfigService() { + dubboMetadataConfigServiceExporter.export(); + } + + private void unExportDubboMetadataConfigService() { + dubboMetadataConfigServiceExporter.unexport(); + } } \ No newline at end of file diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboServiceRegistrationAutoConfiguration.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboServiceRegistrationAutoConfiguration.java index c926fd6b4..081e5b6e8 100644 --- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboServiceRegistrationAutoConfiguration.java +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboServiceRegistrationAutoConfiguration.java @@ -17,28 +17,32 @@ package org.springframework.cloud.alibaba.dubbo.autoconfigure; import org.apache.dubbo.common.URL; +import org.apache.dubbo.config.spring.ServiceBean; import com.ecwid.consul.v1.agent.model.NewService; -import org.aspectj.lang.ProceedingJoinPoint; -import org.aspectj.lang.annotation.Around; +import com.netflix.appinfo.InstanceInfo; import org.aspectj.lang.annotation.Aspect; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.aop.support.AopUtils; +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.beans.factory.SmartInitializingSingleton; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.AutoConfigureOrder; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.event.ApplicationStartedEvent; import org.springframework.cloud.alibaba.dubbo.metadata.repository.DubboServiceMetadataRepository; import org.springframework.cloud.alibaba.dubbo.registry.DubboServiceRegistrationEventPublishingAspect; import org.springframework.cloud.alibaba.dubbo.registry.event.ServiceInstancePreRegisteredEvent; import org.springframework.cloud.alibaba.dubbo.util.JSONUtils; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.serviceregistry.Registration; -import org.springframework.cloud.client.serviceregistry.ServiceRegistry; import org.springframework.cloud.consul.serviceregistry.ConsulRegistration; +import org.springframework.cloud.netflix.eureka.serviceregistry.EurekaAutoServiceRegistration; +import org.springframework.cloud.netflix.eureka.serviceregistry.EurekaRegistration; +import org.springframework.cloud.netflix.eureka.serviceregistry.EurekaServiceRegistry; +import org.springframework.context.SmartLifecycle; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.context.event.EventListener; @@ -52,8 +56,8 @@ import java.util.stream.Collectors; import static org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboServiceRegistrationAutoConfiguration.CONSUL_AUTO_CONFIGURATION_CLASS_NAME; import static org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboServiceRegistrationAutoConfiguration.EUREKA_AUTO_CONFIGURATION_CLASS_NAME; -import static org.springframework.cloud.alibaba.dubbo.registry.DubboServiceRegistrationEventPublishingAspect.REGISTER_POINTCUT_EXPRESSION; import static org.springframework.cloud.alibaba.dubbo.registry.SpringCloudRegistry.DUBBO_URLS_METADATA_PROPERTY_NAME; +import static org.springframework.util.ObjectUtils.isEmpty; /** * Dubbo Service Registration Auto-{@link Configuration} @@ -81,6 +85,9 @@ public class DubboServiceRegistrationAutoConfiguration { public static final String CONSUL_AUTO_REGISTRATION_CLASS_NAME = "org.springframework.cloud.consul.serviceregistry.ConsulAutoRegistration"; + public static final String ZOOKEEPER_AUTO_CONFIGURATION_CLASS_NAME = + "org.springframework.cloud.zookeeper.serviceregistry.ZookeeperAutoServiceRegistrationAutoConfiguration"; + private static final Logger logger = LoggerFactory.getLogger(DubboServiceRegistrationAutoConfiguration.class); @Autowired @@ -89,7 +96,6 @@ public class DubboServiceRegistrationAutoConfiguration { @Autowired private JSONUtils jsonUtils; - @EventListener(ServiceInstancePreRegisteredEvent.class) public void onServiceInstancePreRegistered(ServiceInstancePreRegisteredEvent event) { Registration registration = event.getSource(); @@ -98,32 +104,32 @@ public class DubboServiceRegistrationAutoConfiguration { @Configuration @ConditionalOnBean(name = EUREKA_AUTO_CONFIGURATION_CLASS_NAME) - @AutoConfigureOrder @Aspect - class EurekaConfiguration { + class EurekaConfiguration implements SmartInitializingSingleton { @Autowired - private ServiceRegistry serviceRegistry; - - private Registration registration; - - private boolean deferredRegistration = true; + private ObjectProvider> serviceBeans; - @Around(REGISTER_POINTCUT_EXPRESSION) - public Object doRegister(ProceedingJoinPoint pjp, Registration registration) throws Throwable { - this.registration = registration; - if (deferredRegistration) { - return null; - } - return pjp.proceed(pjp.getArgs()); + @EventListener(ServiceInstancePreRegisteredEvent.class) + public void onServiceInstancePreRegistered(ServiceInstancePreRegisteredEvent event) { + Registration registration = event.getSource(); + EurekaRegistration eurekaRegistration = EurekaRegistration.class.cast(registration); + InstanceInfo instanceInfo = eurekaRegistration.getApplicationInfoManager().getInfo(); + attachURLsIntoMetadata(instanceInfo.getMetadata()); } - @EventListener(ApplicationStartedEvent.class) - public void onApplicationStarted() { - deferredRegistration = false; - serviceRegistry.register(registration); + /** + * {@link EurekaServiceRegistry} will register current {@link ServiceInstance service instance} on + * {@link EurekaAutoServiceRegistration#start()} execution(in {@link SmartLifecycle#start() start phase}), + * thus this method must {@link ServiceBean#export() export} all {@link ServiceBean ServiceBeans} in advance. + */ + @Override + public void afterSingletonsInstantiated() { + Collection serviceBeans = this.serviceBeans.getIfAvailable(); + if (!isEmpty(serviceBeans)) { + serviceBeans.forEach(ServiceBean::export); + } } - } @Configuration @@ -161,7 +167,13 @@ public class DubboServiceRegistrationAutoConfiguration { if (registration == null) { return; } - Map metadata = registration.getMetadata(); + synchronized (registration) { + Map metadata = registration.getMetadata(); + attachURLsIntoMetadata(metadata); + } + } + + private void attachURLsIntoMetadata(Map metadata) { String dubboURLsJson = getDubboURLsJSON(); if (StringUtils.hasText(dubboURLsJson)) { metadata.put(DUBBO_URLS_METADATA_PROPERTY_NAME, dubboURLsJson); @@ -178,6 +190,4 @@ public class DubboServiceRegistrationAutoConfiguration { } return jsonUtils.toJSON(urls.stream().map(URL::toFullString).collect(Collectors.toList())); } - - -} +} \ No newline at end of file diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboServiceRegistrationNonWebApplicationAutoConfiguration.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboServiceRegistrationNonWebApplicationAutoConfiguration.java index 3f69e7ad8..15a5190b9 100644 --- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboServiceRegistrationNonWebApplicationAutoConfiguration.java +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboServiceRegistrationNonWebApplicationAutoConfiguration.java @@ -24,9 +24,9 @@ import com.ecwid.consul.v1.agent.model.NewService; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; +import org.springframework.beans.factory.SmartInitializingSingleton; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.AutoConfigureOrder; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnNotWebApplication; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -36,15 +36,14 @@ import org.springframework.cloud.client.serviceregistry.Registration; import org.springframework.cloud.client.serviceregistry.ServiceRegistry; import org.springframework.cloud.consul.serviceregistry.ConsulAutoRegistration; import org.springframework.cloud.consul.serviceregistry.ConsulRegistration; -import org.springframework.cloud.netflix.eureka.CloudEurekaInstanceConfig; -import org.springframework.cloud.netflix.eureka.serviceregistry.EurekaRegistration; +import org.springframework.cloud.zookeeper.serviceregistry.ServiceInstanceRegistration; import org.springframework.context.annotation.Configuration; import org.springframework.context.event.EventListener; import java.util.List; import static org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboServiceRegistrationAutoConfiguration.CONSUL_AUTO_CONFIGURATION_CLASS_NAME; -import static org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboServiceRegistrationAutoConfiguration.EUREKA_AUTO_CONFIGURATION_CLASS_NAME; +import static org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboServiceRegistrationAutoConfiguration.ZOOKEEPER_AUTO_CONFIGURATION_CLASS_NAME; /** * Dubbo Service Registration Auto-{@link Configuration} for Non-Web application @@ -58,6 +57,8 @@ import static org.springframework.cloud.alibaba.dubbo.autoconfigure.DubboService @Aspect public class DubboServiceRegistrationNonWebApplicationAutoConfiguration { + private static final String REST_PROTOCOL = "rest"; + @Autowired private ServiceRegistry serviceRegistry; @@ -96,7 +97,7 @@ public class DubboServiceRegistrationNonWebApplicationAutoConfiguration { if (webPort == null) { List urls = serviceBean.getExportedUrls(); urls.stream() - .filter(url -> "rest".equalsIgnoreCase(url.getProtocol())) + .filter(url -> REST_PROTOCOL.equalsIgnoreCase(url.getProtocol())) .findFirst() .ifPresent(url -> { webPort = url.getPort(); @@ -105,26 +106,26 @@ public class DubboServiceRegistrationNonWebApplicationAutoConfiguration { } @Configuration - @ConditionalOnBean(name = EUREKA_AUTO_CONFIGURATION_CLASS_NAME) - @AutoConfigureOrder - static class EurekaConfiguration { + @ConditionalOnBean(name = ZOOKEEPER_AUTO_CONFIGURATION_CLASS_NAME) + class ZookeeperConfiguration implements SmartInitializingSingleton { + + @Autowired + private ServiceInstanceRegistration registration; @EventListener(ServiceInstancePreRegisteredEvent.class) public void onServiceInstancePreRegistered(ServiceInstancePreRegisteredEvent event) { - setPort(event.getSource()); + registration.setPort(webPort); } - private void setPort(Registration registration) { - EurekaRegistration eurekaRegistration = (EurekaRegistration) registration; - CloudEurekaInstanceConfig cloudEurekaInstanceConfig = eurekaRegistration.getInstanceConfig(); - cloudEurekaInstanceConfig.setNonSecurePort(registration.getPort()); + @Override + public void afterSingletonsInstantiated() { + // invoke getServiceInstance() method to trigger the ServiceInstance building before register + registration.getServiceInstance(); } - } @Configuration @ConditionalOnBean(name = CONSUL_AUTO_CONFIGURATION_CLASS_NAME) - @AutoConfigureOrder class ConsulConfiguration { /** @@ -153,4 +154,4 @@ public class DubboServiceRegistrationNonWebApplicationAutoConfiguration { } } -} +} \ No newline at end of file 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 d973e6293..5fb3d2e4b 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 @@ -50,12 +50,12 @@ public class SpringCloudRegistry extends AbstractSpringCloudRegistry { /** * The property name of Dubbo {@link URL URLs} metadata */ - public static final String DUBBO_URLS_METADATA_PROPERTY_NAME = "dubbo-urls"; + public static final String DUBBO_URLS_METADATA_PROPERTY_NAME = "dubbo.urls"; /** * The parameter name of the services of Dubbo Provider */ - public static final String DUBBO_PROVIDER_SERVICES_PARAM_NAME = "dubbo-provider-services"; + public static final String DUBBO_PROVIDER_SERVICES_PARAM_NAME = "dubbo.provider-services"; /** * All services of Dubbo Provider 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 000000000..60faa7c3b --- /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/resources/META-INF/spring.factories b/spring-cloud-alibaba-dubbo/src/main/resources/META-INF/spring.factories index 6f0ffd963..515af6f50 100644 --- a/spring-cloud-alibaba-dubbo/src/main/resources/META-INF/spring.factories +++ b/spring-cloud-alibaba-dubbo/src/main/resources/META-INF/spring.factories @@ -6,5 +6,10 @@ org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 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 \ No newline at end of file + org.springframework.cloud.alibaba.dubbo.context.DubboServiceRegistrationApplicationContextInitializer + + +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/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 index 46fcf5e29..0bff5e0c6 100644 --- 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 @@ -1,188 +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); +//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; // } - - 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; - } -} +//}