mirror of
https://gitee.com/mirrors/Spring-Cloud-Alibaba.git
synced 2021-06-26 13:25:11 +08:00
Polish spring-cloud-incubator/spring-cloud-alibaba#348 : Reactor
This commit is contained in:
@@ -26,7 +26,8 @@ import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.context.event.ApplicationStartedEvent;
|
||||
import org.springframework.cloud.alibaba.dubbo.annotation.DubboTransported;
|
||||
import org.springframework.cloud.alibaba.dubbo.client.loadbalancer.DubboAdapterLoadBalancerInterceptor;
|
||||
import org.springframework.cloud.alibaba.dubbo.client.loadbalancer.DubboMetadataInitializerInterceptor;
|
||||
import org.springframework.cloud.alibaba.dubbo.client.loadbalancer.DubboTransporterInterceptor;
|
||||
import org.springframework.cloud.alibaba.dubbo.metadata.DubboTransportedMetadata;
|
||||
import org.springframework.cloud.alibaba.dubbo.metadata.repository.DubboServiceMetadataRepository;
|
||||
import org.springframework.cloud.alibaba.dubbo.service.DubboGenericServiceExecutionContextFactory;
|
||||
@@ -124,7 +125,7 @@ public class DubboLoadBalancedRestTemplateAutoConfiguration implements BeanClass
|
||||
|
||||
|
||||
/**
|
||||
* Adapt the instance of {@link DubboAdapterLoadBalancerInterceptor} to the {@link LoadBalancerInterceptor} Bean.
|
||||
* Adapt the instance of {@link DubboTransporterInterceptor} to the {@link LoadBalancerInterceptor} Bean.
|
||||
*
|
||||
* @param restTemplate {@link LoadBalanced @LoadBalanced} {@link RestTemplate} Bean
|
||||
* @param dubboTranslatedAttributes the annotation dubboTranslatedAttributes {@link RestTemplate} bean being annotated
|
||||
@@ -138,11 +139,13 @@ public class DubboLoadBalancedRestTemplateAutoConfiguration implements BeanClass
|
||||
|
||||
int index = interceptors.indexOf(loadBalancerInterceptor);
|
||||
|
||||
if (index > -1) {
|
||||
interceptors.set(index, new DubboAdapterLoadBalancerInterceptor(repository, loadBalancerInterceptor,
|
||||
restTemplate.getMessageConverters(), classLoader,
|
||||
dubboTransportedMetadata, serviceFactory, contextFactory));
|
||||
}
|
||||
index = index < 0 ? 0 : index;
|
||||
|
||||
// Add ClientHttpRequestInterceptor instances before loadBalancerInterceptor
|
||||
interceptors.add(index++, new DubboMetadataInitializerInterceptor(repository));
|
||||
|
||||
interceptors.add(index++, new DubboTransporterInterceptor(repository, restTemplate.getMessageConverters(),
|
||||
classLoader, dubboTransportedMetadata, serviceFactory, contextFactory));
|
||||
|
||||
restTemplate.setInterceptors(interceptors);
|
||||
}
|
||||
|
@@ -29,7 +29,7 @@ import java.io.InputStream;
|
||||
* Dubbo {@link ClientHttpResponse} implementation
|
||||
*
|
||||
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||
* @see DubboAdapterLoadBalancerInterceptor
|
||||
* @see DubboTransporterInterceptor
|
||||
*/
|
||||
class DubboClientHttpResponse implements ClientHttpResponse {
|
||||
|
||||
|
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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.client.loadbalancer;
|
||||
|
||||
import org.springframework.cloud.alibaba.dubbo.metadata.repository.DubboServiceMetadataRepository;
|
||||
import org.springframework.http.HttpRequest;
|
||||
import org.springframework.http.client.ClientHttpRequestExecution;
|
||||
import org.springframework.http.client.ClientHttpRequestInterceptor;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* Dubbo Metadata {@link ClientHttpRequestInterceptor} Initializing Interceptor executes intercept before
|
||||
* {@link DubboTransporterInterceptor}
|
||||
*
|
||||
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||
*/
|
||||
public class DubboMetadataInitializerInterceptor implements ClientHttpRequestInterceptor {
|
||||
|
||||
private final DubboServiceMetadataRepository repository;
|
||||
|
||||
public DubboMetadataInitializerInterceptor(DubboServiceMetadataRepository repository) {
|
||||
this.repository = repository;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
|
||||
|
||||
URI originalUri = request.getURI();
|
||||
|
||||
String serviceName = originalUri.getHost();
|
||||
|
||||
repository.initialize(serviceName);
|
||||
|
||||
// Execute next
|
||||
return execution.execute(request, body);
|
||||
}
|
||||
}
|
@@ -19,7 +19,7 @@ package org.springframework.cloud.alibaba.dubbo.client.loadbalancer;
|
||||
import com.alibaba.dubbo.rpc.service.GenericException;
|
||||
import com.alibaba.dubbo.rpc.service.GenericService;
|
||||
|
||||
import org.springframework.cloud.alibaba.dubbo.http.DefaultHttpServerRequest;
|
||||
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;
|
||||
@@ -34,26 +34,28 @@ import org.springframework.http.client.ClientHttpRequestExecution;
|
||||
import org.springframework.http.client.ClientHttpRequestInterceptor;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.util.AntPathMatcher;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.PathMatcher;
|
||||
import org.springframework.web.util.UriComponents;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.springframework.web.util.UriComponentsBuilder.fromUri;
|
||||
|
||||
/**
|
||||
* Dubbo {@link ClientHttpRequestInterceptor} implementation to adapt {@link LoadBalancerInterceptor}
|
||||
* Dubbo Transporter {@link ClientHttpRequestInterceptor} implementation
|
||||
*
|
||||
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||
* @see LoadBalancerInterceptor
|
||||
*/
|
||||
public class DubboAdapterLoadBalancerInterceptor implements ClientHttpRequestInterceptor {
|
||||
public class DubboTransporterInterceptor implements ClientHttpRequestInterceptor {
|
||||
|
||||
private final DubboServiceMetadataRepository repository;
|
||||
|
||||
private final LoadBalancerInterceptor loadBalancerInterceptor;
|
||||
|
||||
private final DubboClientHttpResponseFactory clientHttpResponseFactory;
|
||||
|
||||
private final DubboTransportedMetadata dubboTransportedMetadata;
|
||||
@@ -62,15 +64,15 @@ public class DubboAdapterLoadBalancerInterceptor implements ClientHttpRequestInt
|
||||
|
||||
private final DubboGenericServiceExecutionContextFactory contextFactory;
|
||||
|
||||
public DubboAdapterLoadBalancerInterceptor(DubboServiceMetadataRepository dubboServiceMetadataRepository,
|
||||
LoadBalancerInterceptor loadBalancerInterceptor,
|
||||
List<HttpMessageConverter<?>> messageConverters,
|
||||
ClassLoader classLoader,
|
||||
DubboTransportedMetadata dubboTransportedMetadata,
|
||||
DubboGenericServiceFactory serviceFactory,
|
||||
DubboGenericServiceExecutionContextFactory contextFactory) {
|
||||
private final PathMatcher pathMatcher = new AntPathMatcher();
|
||||
|
||||
public DubboTransporterInterceptor(DubboServiceMetadataRepository dubboServiceMetadataRepository,
|
||||
List<HttpMessageConverter<?>> messageConverters,
|
||||
ClassLoader classLoader,
|
||||
DubboTransportedMetadata dubboTransportedMetadata,
|
||||
DubboGenericServiceFactory serviceFactory,
|
||||
DubboGenericServiceExecutionContextFactory contextFactory) {
|
||||
this.repository = dubboServiceMetadataRepository;
|
||||
this.loadBalancerInterceptor = loadBalancerInterceptor;
|
||||
this.dubboTransportedMetadata = dubboTransportedMetadata;
|
||||
this.clientHttpResponseFactory = new DubboClientHttpResponseFactory(messageConverters, classLoader);
|
||||
this.serviceFactory = serviceFactory;
|
||||
@@ -84,22 +86,24 @@ public class DubboAdapterLoadBalancerInterceptor implements ClientHttpRequestInt
|
||||
|
||||
String serviceName = originalUri.getHost();
|
||||
|
||||
repository.initialize(serviceName);
|
||||
|
||||
RequestMetadata clientMetadata = buildRequestMetadata(request);
|
||||
|
||||
DubboServiceMetadata dubboServiceMetadata = repository.get(serviceName, clientMetadata);
|
||||
|
||||
if (dubboServiceMetadata == null) { // if DubboServiceMetadata is not found
|
||||
return loadBalancerInterceptor.intercept(request, body, execution);
|
||||
if (dubboServiceMetadata == null) {
|
||||
// if DubboServiceMetadata is not found, executes next
|
||||
return execution.execute(request, body);
|
||||
}
|
||||
|
||||
RestMethodMetadata dubboRestMethodMetadata = dubboServiceMetadata.getRestMethodMetadata();
|
||||
|
||||
GenericService genericService = serviceFactory.create(dubboServiceMetadata, dubboTransportedMetadata);
|
||||
|
||||
DubboGenericServiceExecutionContext context = contextFactory.create(dubboRestMethodMetadata,
|
||||
new DefaultHttpServerRequest(request, body));
|
||||
MutableHttpServerRequest httpServerRequest = new MutableHttpServerRequest(request, body);
|
||||
|
||||
customizeRequest(httpServerRequest, dubboRestMethodMetadata, clientMetadata);
|
||||
|
||||
DubboGenericServiceExecutionContext context = contextFactory.create(dubboRestMethodMetadata, httpServerRequest);
|
||||
|
||||
Object result = null;
|
||||
GenericException exception = null;
|
||||
@@ -113,7 +117,22 @@ public class DubboAdapterLoadBalancerInterceptor implements ClientHttpRequestInt
|
||||
return clientHttpResponseFactory.build(result, exception, clientMetadata, dubboRestMethodMetadata);
|
||||
}
|
||||
|
||||
public static RequestMetadata buildRequestMetadata(HttpRequest request) {
|
||||
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(HttpRequest request) {
|
||||
UriComponents uriComponents = fromUri(request.getURI()).build(true);
|
||||
RequestMetadata requestMetadata = new RequestMetadata();
|
||||
requestMetadata.setPath(uriComponents.getPath());
|
@@ -16,7 +16,6 @@
|
||||
*/
|
||||
package org.springframework.cloud.alibaba.dubbo.http;
|
||||
|
||||
import org.springframework.http.HttpCookie;
|
||||
import org.springframework.http.HttpInputMessage;
|
||||
import org.springframework.http.HttpRequest;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
@@ -36,13 +35,8 @@ public interface HttpServerRequest extends HttpRequest, HttpInputMessage {
|
||||
String getPath();
|
||||
|
||||
/**
|
||||
* Return a read-only map with parsed and decoded query parameter values.
|
||||
* Return a map with parsed and decoded query parameter values.
|
||||
*/
|
||||
MultiValueMap<String, String> getQueryParams();
|
||||
|
||||
/**
|
||||
* Return a read-only map of cookies sent by the client.
|
||||
*/
|
||||
MultiValueMap<String, HttpCookie> getCookies();
|
||||
|
||||
}
|
||||
|
@@ -26,17 +26,17 @@ import org.springframework.util.MultiValueMap;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.springframework.cloud.alibaba.dubbo.http.util.HttpUtils.getParameters;
|
||||
import static org.springframework.cloud.alibaba.dubbo.http.util.HttpUtils.parseCookies;
|
||||
import static org.springframework.http.HttpHeaders.readOnlyHttpHeaders;
|
||||
|
||||
/**
|
||||
* Default {@link HttpServerRequest} implementation
|
||||
* Mutable {@link HttpServerRequest} implementation
|
||||
*
|
||||
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
|
||||
*/
|
||||
public class DefaultHttpServerRequest implements HttpServerRequest {
|
||||
public class MutableHttpServerRequest implements HttpServerRequest {
|
||||
|
||||
private final HttpMethod httpMethod;
|
||||
|
||||
@@ -52,16 +52,21 @@ public class DefaultHttpServerRequest implements HttpServerRequest {
|
||||
|
||||
private final HttpInputMessage httpInputMessage;
|
||||
|
||||
public DefaultHttpServerRequest(HttpRequest httpRequest, byte[] body) {
|
||||
public MutableHttpServerRequest(HttpRequest httpRequest, byte[] body) {
|
||||
this.httpMethod = httpRequest.getMethod();
|
||||
this.uri = httpRequest.getURI();
|
||||
this.path = uri.getPath();
|
||||
this.httpHeaders = readOnlyHttpHeaders(httpRequest.getHeaders());
|
||||
this.httpHeaders = new HttpHeaders(httpRequest.getHeaders());
|
||||
this.queryParams = getParameters(httpRequest);
|
||||
this.httpInputMessage = new ByteArrayHttpInputMessage(body);
|
||||
this.cookies = parseCookies(httpHeaders);
|
||||
}
|
||||
|
||||
public MutableHttpServerRequest params(Map<String, String> params) {
|
||||
queryParams.setAll(params);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getBody() throws IOException {
|
||||
return httpInputMessage.getBody();
|
||||
@@ -96,9 +101,4 @@ public class DefaultHttpServerRequest implements HttpServerRequest {
|
||||
public MultiValueMap<String, String> getQueryParams() {
|
||||
return queryParams;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultiValueMap<String, HttpCookie> getCookies() {
|
||||
return cookies;
|
||||
}
|
||||
}
|
@@ -34,7 +34,6 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.springframework.http.HttpHeaders.COOKIE;
|
||||
import static org.springframework.util.CollectionUtils.unmodifiableMultiValueMap;
|
||||
import static org.springframework.util.StringUtils.delimitedListToStringArray;
|
||||
import static org.springframework.util.StringUtils.hasText;
|
||||
import static org.springframework.util.StringUtils.trimAllWhitespace;
|
||||
@@ -125,7 +124,7 @@ public abstract class HttpUtils {
|
||||
addParam(parameters, name, value);
|
||||
}
|
||||
}
|
||||
return unmodifiableMultiValueMap(parameters);
|
||||
return parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -161,7 +160,7 @@ public abstract class HttpUtils {
|
||||
cookies.add(name, httpCookie);
|
||||
}
|
||||
|
||||
return unmodifiableMultiValueMap(cookies);
|
||||
return cookies;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -114,15 +114,15 @@ public class DubboServiceMetadataRepository {
|
||||
object = map.get(matcher);
|
||||
if (object == null) { // Can't match exactly
|
||||
// Require to match one by one
|
||||
HttpRequest request = builder()
|
||||
.method(requestMetadata.getMethod())
|
||||
.path(requestMetadata.getPath())
|
||||
.params(requestMetadata.getParams())
|
||||
.headers(requestMetadata.getHeaders())
|
||||
.build();
|
||||
|
||||
for (Map.Entry<RequestMetadataMatcher, T> entry : map.entrySet()) {
|
||||
RequestMetadataMatcher possibleMatcher = entry.getKey();
|
||||
HttpRequest request = builder()
|
||||
.method(requestMetadata.getMethod())
|
||||
.path(requestMetadata.getPath())
|
||||
.params(requestMetadata.getParams())
|
||||
.headers(requestMetadata.getHeaders())
|
||||
.build();
|
||||
|
||||
if (possibleMatcher.match(request)) {
|
||||
object = entry.getValue();
|
||||
break;
|
||||
|
Reference in New Issue
Block a user