diff --git a/spring-cloud-alibaba-dubbo/pom.xml b/spring-cloud-alibaba-dubbo/pom.xml index 25750683a..863aac557 100644 --- a/spring-cloud-alibaba-dubbo/pom.xml +++ b/spring-cloud-alibaba-dubbo/pom.xml @@ -15,7 +15,6 @@ 2.7.1 - 2.7.0 2.1.0.RELEASE 2.1.0.RELEASE 4.0.1 @@ -179,7 +178,7 @@ org.apache.dubbo dubbo-spring-boot-starter - ${dubbo-spring-boot.version} + ${dubbo.version} diff --git a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboServiceAutoConfiguration.java b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboServiceAutoConfiguration.java index 02f190de5..3b9d71bb0 100644 --- a/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboServiceAutoConfiguration.java +++ b/spring-cloud-alibaba-dubbo/src/main/java/org/springframework/cloud/alibaba/dubbo/autoconfigure/DubboServiceAutoConfiguration.java @@ -16,12 +16,8 @@ */ package org.springframework.cloud.alibaba.dubbo.autoconfigure; -import org.apache.dubbo.common.utils.Assert; -import org.apache.dubbo.config.spring.util.PropertySourcesUtils; - import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.context.properties.source.ConfigurationPropertySources; import org.springframework.cloud.alibaba.dubbo.env.DubboCloudProperties; import org.springframework.cloud.alibaba.dubbo.service.DubboGenericServiceExecutionContextFactory; import org.springframework.cloud.alibaba.dubbo.service.DubboGenericServiceFactory; @@ -32,18 +28,6 @@ import org.springframework.cloud.alibaba.dubbo.service.parameter.RequestParamSer import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; -import org.springframework.context.annotation.Primary; -import org.springframework.core.env.AbstractEnvironment; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.MapPropertySource; -import org.springframework.core.env.MutablePropertySources; -import org.springframework.core.env.PropertyResolver; -import org.springframework.lang.Nullable; - -import java.util.Map; - -import static org.apache.dubbo.spring.boot.util.DubboUtils.BASE_PACKAGES_PROPERTY_RESOLVER_BEAN_NAME; -import static org.apache.dubbo.spring.boot.util.DubboUtils.DUBBO_SCAN_PREFIX; /** * Spring Boot Auto-Configuration class for Dubbo Service @@ -71,81 +55,81 @@ public class DubboServiceAutoConfiguration { static class ParameterResolversConfiguration { } - /** - * Bugfix code for an issue : https://github.com/apache/incubator-dubbo-spring-boot-project/issues/459 - * - * @param environment {@link ConfigurableEnvironment} - * @return a Bean of {@link PropertyResolver} - */ - @Primary - @Bean(name = BASE_PACKAGES_PROPERTY_RESOLVER_BEAN_NAME) - public PropertyResolver dubboScanBasePackagesPropertyResolver(ConfigurableEnvironment environment) { - ConfigurableEnvironment propertyResolver = new AbstractEnvironment() { - @Override - protected void customizePropertySources(MutablePropertySources propertySources) { - Map dubboScanProperties = PropertySourcesUtils.getSubProperties(environment, DUBBO_SCAN_PREFIX); - propertySources.addLast(new MapPropertySource("dubboScanProperties", dubboScanProperties)); - } - }; - ConfigurationPropertySources.attach(propertyResolver); - return new DelegatingPropertyResolver(propertyResolver); - } - - - private static class DelegatingPropertyResolver implements PropertyResolver { - - private final PropertyResolver delegate; - - DelegatingPropertyResolver(PropertyResolver delegate) { - Assert.notNull(delegate, "The delegate of PropertyResolver must not be null"); - this.delegate = delegate; - } - - @Override - public boolean containsProperty(String key) { - return delegate.containsProperty(key); - } - - @Override - @Nullable - public String getProperty(String key) { - return delegate.getProperty(key); - } - - @Override - public String getProperty(String key, String defaultValue) { - return delegate.getProperty(key, defaultValue); - } - - @Override - @Nullable - public T getProperty(String key, Class targetType) { - return delegate.getProperty(key, targetType); - } - - @Override - public T getProperty(String key, Class targetType, T defaultValue) { - return delegate.getProperty(key, targetType, defaultValue); - } - - @Override - public String getRequiredProperty(String key) throws IllegalStateException { - return delegate.getRequiredProperty(key); - } - - @Override - public T getRequiredProperty(String key, Class targetType) throws IllegalStateException { - return delegate.getRequiredProperty(key, targetType); - } - - @Override - public String resolvePlaceholders(String text) { - return delegate.resolvePlaceholders(text); - } - - @Override - public String resolveRequiredPlaceholders(String text) throws IllegalArgumentException { - return delegate.resolveRequiredPlaceholders(text); - } - } +// /** +// * Bugfix code for an issue : https://github.com/apache/incubator-dubbo-spring-boot-project/issues/459 +// * +// * @param environment {@link ConfigurableEnvironment} +// * @return a Bean of {@link PropertyResolver} +// */ +// @Primary +// @Bean(name = BASE_PACKAGES_PROPERTY_RESOLVER_BEAN_NAME) +// public PropertyResolver dubboScanBasePackagesPropertyResolver(ConfigurableEnvironment environment) { +// ConfigurableEnvironment propertyResolver = new AbstractEnvironment() { +// @Override +// protected void customizePropertySources(MutablePropertySources propertySources) { +// Map dubboScanProperties = PropertySourcesUtils.getSubProperties(environment, DUBBO_SCAN_PREFIX); +// propertySources.addLast(new MapPropertySource("dubboScanProperties", dubboScanProperties)); +// } +// }; +// ConfigurationPropertySources.attach(propertyResolver); +// return new DelegatingPropertyResolver(propertyResolver); +// } +// +// +// private static class DelegatingPropertyResolver implements PropertyResolver { +// +// private final PropertyResolver delegate; +// +// DelegatingPropertyResolver(PropertyResolver delegate) { +// Assert.notNull(delegate, "The delegate of PropertyResolver must not be null"); +// this.delegate = delegate; +// } +// +// @Override +// public boolean containsProperty(String key) { +// return delegate.containsProperty(key); +// } +// +// @Override +// @Nullable +// public String getProperty(String key) { +// return delegate.getProperty(key); +// } +// +// @Override +// public String getProperty(String key, String defaultValue) { +// return delegate.getProperty(key, defaultValue); +// } +// +// @Override +// @Nullable +// public T getProperty(String key, Class targetType) { +// return delegate.getProperty(key, targetType); +// } +// +// @Override +// public T getProperty(String key, Class targetType, T defaultValue) { +// return delegate.getProperty(key, targetType, defaultValue); +// } +// +// @Override +// public String getRequiredProperty(String key) throws IllegalStateException { +// return delegate.getRequiredProperty(key); +// } +// +// @Override +// public T getRequiredProperty(String key, Class targetType) throws IllegalStateException { +// return delegate.getRequiredProperty(key, targetType); +// } +// +// @Override +// public String resolvePlaceholders(String text) { +// return delegate.resolvePlaceholders(text); +// } +// +// @Override +// public String resolveRequiredPlaceholders(String text) throws IllegalArgumentException { +// return delegate.resolveRequiredPlaceholders(text); +// } +// } } \ 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 0bff5e0c6..b3c56d248 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,181 @@ -//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; -// } -//} +package org.springframework.cloud.alibaba.dubbo.gateway; + +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.DubboRestServiceMetadata; +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.PathMatcher; +import org.springframework.util.StreamUtils; +import org.springframework.web.servlet.HttpServletBean; +import org.springframework.web.util.UriComponents; + +import javax.servlet.ServletException; +import javax.servlet.ServletInputStream; +import javax.servlet.annotation.WebServlet; +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.Arrays; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import static org.apache.commons.lang3.StringUtils.substringAfter; +import static org.apache.commons.lang3.StringUtils.substringBetween; +import static org.springframework.web.util.UriComponentsBuilder.fromUriString; + +@WebServlet(urlPatterns = "/dsc/*") +public class DubboGatewayServlet extends HttpServletBean { + + private final DubboServiceMetadataRepository repository; + + private final DubboGenericServiceFactory serviceFactory; + + private final DubboGenericServiceExecutionContextFactory contextFactory; + + private final PathMatcher pathMatcher = new AntPathMatcher(); + + private final Map dubboTranslatedAttributes = new HashMap<>(); + + public DubboGatewayServlet(DubboServiceMetadataRepository repository, + DubboGenericServiceFactory serviceFactory, + DubboGenericServiceExecutionContextFactory contextFactory) { + this.repository = repository; + this.serviceFactory = serviceFactory; + this.contextFactory = contextFactory; + dubboTranslatedAttributes.put("protocol", "dubbo"); + dubboTranslatedAttributes.put("cluster", "failover"); + } + + private String resolveServiceName(HttpServletRequest request) { + + // /g/{app-name}/{rest-path} + String requestURI = request.getRequestURI(); + // /g/ + String servletPath = request.getServletPath(); + + String part = substringAfter(requestURI, servletPath); + + String serviceName = substringBetween(part, "/", "/"); + + return serviceName; + } + + public void service(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { + + String serviceName = resolveServiceName(request); + + String restPath = substringAfter(request.getRequestURI(), serviceName); + + // 初始化 serviceName 的 REST 请求元数据 + repository.initialize(serviceName); + // 将 HttpServletRequest 转化为 RequestMetadata + RequestMetadata clientMetadata = buildRequestMetadata(request, restPath); + + DubboRestServiceMetadata dubboRestServiceMetadata = repository.get(serviceName, clientMetadata); + + if (dubboRestServiceMetadata == null) { + // if DubboServiceMetadata is not found, executes next + throw new ServletException("DubboServiceMetadata can't be found!"); + } + + RestMethodMetadata dubboRestMethodMetadata = dubboRestServiceMetadata.getRestMethodMetadata(); + + GenericService genericService = serviceFactory.create(dubboRestServiceMetadata, dubboTranslatedAttributes); + + // TODO: Get the Request Body from HttpServletRequest + byte[] body = getRequestBody(request); + + MutableHttpServerRequest httpServerRequest = new MutableHttpServerRequest(new HttpRequestAdapter(request), body); + + 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(); + } + } + + 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; + } +}