mirror of
https://gitee.com/mirrors/Spring-Cloud-Alibaba.git
synced 2021-06-26 13:25:11 +08:00
To add Gateway demo
This commit is contained in:
parent
8a8097ce00
commit
a50324c43a
@ -20,6 +20,7 @@
|
||||
<module>spring-cloud-dubbo-provider-sample</module>
|
||||
<module>spring-cloud-dubbo-consumer-sample</module>
|
||||
<module>spring-cloud-dubbo-provider-web-sample</module>
|
||||
<module>spring-cloud-dubbo-servlet-gateway-sample</module>
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
|
@ -0,0 +1,39 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>spring-cloud-alibaba-dubbo-examples</artifactId>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<version>0.2.2.BUILD-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-dubbo-servlet-gateway-sample</artifactId>
|
||||
<name>Spring Cloud Dubbo Servlet Gateway Sample</name>
|
||||
|
||||
<dependencies>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Sample API -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-dubbo-sample-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Spring Cloud Open Feign -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-openfeign</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
</project>
|
@ -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);
|
||||
}
|
||||
}
|
@ -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<String, String> 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<String, List<String>> getHeaders(HttpServletRequest request) {
|
||||
Map<String, List<String>> map = new LinkedHashMap<>();
|
||||
Enumeration<String> headerNames = request.getHeaderNames();
|
||||
while (headerNames.hasMoreElements()) {
|
||||
String headerName = headerNames.nextElement();
|
||||
Enumeration<String> headerValues = request.getHeaders(headerName);
|
||||
map.put(headerName, Collections.list(headerValues));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
private Map<String, List<String>> getParams(HttpServletRequest request) {
|
||||
Map<String, List<String>> map = new LinkedHashMap<>();
|
||||
for (Map.Entry<String, String[]> entry : request.getParameterMap().entrySet()) {
|
||||
map.put(entry.getKey(), Arrays.asList(entry.getValue()));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
}
|
@ -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
|
@ -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
|
Loading…
x
Reference in New Issue
Block a user