Skip to content

Commit

Permalink
[ISSUE #3197] NacosRestTemplate enhance (#3198)
Browse files Browse the repository at this point in the history
* enhance nacosRestTemplate

* enhance nacosRestTemplate

* supplement throw exception

* Modify the iterate method of the interceptor and modify some method name

* Adjust the way to get HttpClientRequest implement in NacosRestTempalte

* Fix code style issue

* Fix code style issue

* Fix code style issue

* Fix code style issue

* Log output change
  • Loading branch information
Maijh97 authored Jul 13, 2020
1 parent 092a089 commit c1515b6
Show file tree
Hide file tree
Showing 8 changed files with 401 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@

import com.alibaba.nacos.common.constant.HttpHeaderConsts;
import com.alibaba.nacos.common.http.BaseHttpMethod;
import com.alibaba.nacos.common.http.HttpClientConfig;
import com.alibaba.nacos.common.http.param.Header;
import com.alibaba.nacos.common.http.param.MediaType;
import com.alibaba.nacos.common.model.RequestHttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.impl.client.CloseableHttpClient;
Expand Down Expand Up @@ -69,7 +71,24 @@ static HttpRequestBase build(URI uri, String method, RequestHttpEntity requestHt
} else {
httpMethod.initEntity(requestHttpEntity.getBody(), headers.getValue(HttpHeaderConsts.CONTENT_TYPE));
}
return httpMethod.getRequestBase();
HttpRequestBase requestBase = httpMethod.getRequestBase();
replaceDefaultConfig(requestBase, requestHttpEntity.getHttpClientConfig());
return requestBase;
}

/**
* Replace the HTTP config created by default with the HTTP config specified in the request.
*
* @param requestBase requestBase
* @param httpClientConfig http config
*/
private static void replaceDefaultConfig(HttpRequestBase requestBase, HttpClientConfig httpClientConfig) {
if (httpClientConfig == null) {
return;
}
requestBase.setConfig(RequestConfig.custom()
.setConnectTimeout(httpClientConfig.getConTimeOutMillis())
.setSocketTimeout(httpClientConfig.getReadTimeOutMillis()).build());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed 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 com.alibaba.nacos.common.http.client;

import com.alibaba.nacos.common.model.RequestHttpEntity;

import java.net.URI;

/**
* Intercepts client-side HTTP requests. Implementations of this interface can be.
*
* @author mai.jh
*/
public interface HttpClientRequestInterceptor {

/**
* is intercept.
*
* @param uri uri
* @param httpMethod http method
* @param requestHttpEntity request entity
* @return boolean
*/
boolean isIntercept(URI uri, String httpMethod, RequestHttpEntity requestHttpEntity);

/**
* if isIntercept method is true Intercept the given request, and return a response Otherwise,
* the {@link HttpClientRequest} will be used for execution.
*
* @return HttpClientResponse
*/
HttpClientResponse intercept();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright 1999-2018 Alibaba Group Holding Ltd.
*
* Licensed 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 com.alibaba.nacos.common.http.client;

import com.alibaba.nacos.common.model.RequestHttpEntity;

import java.io.IOException;
import java.net.URI;
import java.util.Iterator;

/**
* Wrap http client request and perform corresponding interception.
*
* @author mai.jh
*/
public class InterceptingHttpClientRequest implements HttpClientRequest {

private final HttpClientRequest httpClientRequest;

private final Iterator<HttpClientRequestInterceptor> interceptors;

public InterceptingHttpClientRequest(HttpClientRequest httpClientRequest,
Iterator<HttpClientRequestInterceptor> interceptors) {
this.httpClientRequest = httpClientRequest;
this.interceptors = interceptors;
}

@Override
public HttpClientResponse execute(URI uri, String httpMethod, RequestHttpEntity requestHttpEntity)
throws Exception {
while (interceptors.hasNext()) {
HttpClientRequestInterceptor nextInterceptor = interceptors.next();
if (nextInterceptor.isIntercept(uri, httpMethod, requestHttpEntity)) {
return nextInterceptor.intercept();
}
}
return httpClientRequest.execute(uri, httpMethod, requestHttpEntity);
}

@Override
public void close() throws IOException {
httpClientRequest.close();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,22 @@

package com.alibaba.nacos.common.http.client;

import com.alibaba.nacos.common.http.HttpClientConfig;
import com.alibaba.nacos.common.http.HttpRestResult;
import com.alibaba.nacos.common.http.HttpUtils;
import com.alibaba.nacos.common.http.param.Header;
import com.alibaba.nacos.common.http.param.MediaType;
import com.alibaba.nacos.common.http.param.Query;
import com.alibaba.nacos.common.model.RequestHttpEntity;
import com.alibaba.nacos.common.utils.CollectionUtils;
import com.alibaba.nacos.common.utils.HttpMethod;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Type;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
Expand All @@ -41,7 +45,9 @@ public class NacosRestTemplate extends AbstractNacosRestTemplate {

private static final Logger LOGGER = LoggerFactory.getLogger(NacosRestTemplate.class);

private HttpClientRequest requestClient;
private final HttpClientRequest requestClient;

private final List<HttpClientRequestInterceptor> interceptors = new ArrayList<HttpClientRequestInterceptor>();

public NacosRestTemplate(HttpClientRequest requestClient) {
super();
Expand Down Expand Up @@ -83,6 +89,28 @@ public <T> HttpRestResult<T> get(String url, Header header, Map<String, String>
return execute(url, HttpMethod.GET, requestHttpEntity, responseType);
}

/**
* http get URL request params are expanded using the given query {@link Query}.
*
* <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type.
*
* <p>{@code config} Specify the request config via {@link HttpClientConfig}
*
* @param url url
* @param config http config
* @param header headers
* @param paramValues paramValues
* @param responseType return type
* @return {@link HttpRestResult}
* @throws Exception ex
*/
public <T> HttpRestResult<T> get(String url, HttpClientConfig config, Header header,
Map<String, String> paramValues, Type responseType) throws Exception {
RequestHttpEntity requestHttpEntity = new RequestHttpEntity(config, header,
Query.newInstance().initParams(paramValues));
return execute(url, HttpMethod.GET, requestHttpEntity, responseType);
}

/**
* get request, may be pulling a lot of data URL request params are expanded using the given query {@link Query},
* More request parameters can be set via body.
Expand Down Expand Up @@ -118,6 +146,27 @@ public <T> HttpRestResult<T> delete(String url, Header header, Query query, Type
return execute(url, HttpMethod.DELETE, new RequestHttpEntity(header, query), responseType);
}

/**
* http delete URL request params are expanded using the given query {@link Query}.
*
* <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type.
*
* <p>{@code config} Specify the request config via {@link HttpClientConfig}
*
* @param url url
* @param config http config
* @param header http header param
* @param paramValues http query param
* @param responseType return type
* @return {@link HttpRestResult}
* @throws Exception ex
*/
public <T> HttpRestResult<T> delete(String url, HttpClientConfig config, Header header,
Map<String, String> paramValues, Type responseType) throws Exception {
return execute(url, HttpMethod.DELETE,
new RequestHttpEntity(config, header, Query.newInstance().initParams(paramValues)), responseType);
}

/**
* http put Create a new resource by PUTting the given body to http request.
*
Expand Down Expand Up @@ -208,6 +257,33 @@ public <T> HttpRestResult<T> putForm(String url, Header header, Map<String, Stri
return execute(url, HttpMethod.PUT, requestHttpEntity, responseType);
}

/**
* http put from Create a new resource by PUTting the given map {@code bodyValues} to http request, http header
* contentType default 'application/x-www-form-urlencoded;charset=utf-8'.
*
* <p>URL request params are expanded using the given map {@code paramValues}.
*
* <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type.
*
* <p>{@code config} Specify the request config via {@link HttpClientConfig}
*
* @param url url
* @param config http config
* @param header http header param
* @param paramValues http query param
* @param bodyValues http body param
* @param responseType return type
* @return {@link HttpRestResult}
* @throws Exception ex
*/
public <T> HttpRestResult<T> putForm(String url, HttpClientConfig config, Header header,
Map<String, String> paramValues, Map<String, String> bodyValues, Type responseType) throws Exception {
RequestHttpEntity requestHttpEntity = new RequestHttpEntity(config,
header.setContentType(MediaType.APPLICATION_FORM_URLENCODED),
Query.newInstance().initParams(paramValues), bodyValues);
return execute(url, HttpMethod.PUT, requestHttpEntity, responseType);
}

/**
* http post Create a new resource by POSTing the given object to the http request.
*
Expand Down Expand Up @@ -298,6 +374,33 @@ public <T> HttpRestResult<T> postForm(String url, Header header, Map<String, Str
return execute(url, HttpMethod.POST, requestHttpEntity, responseType);
}

/**
* http post from Create a new resource by PUTting the given map {@code bodyValues} to http request, http header
* contentType default 'application/x-www-form-urlencoded;charset=utf-8'.
*
* <p>URL request params are expanded using the given map {@code paramValues}.
*
* <p>{@code responseType} can be an HttpRestResult or HttpRestResult data {@code T} type.
*
* <p>{@code config} Specify the request config via {@link HttpClientConfig}
*
* @param url url
* @param config http config
* @param header http header param
* @param paramValues http query param
* @param bodyValues http body param
* @param responseType return type
* @return {@link HttpRestResult}
* @throws Exception ex
*/
public <T> HttpRestResult<T> postForm(String url, HttpClientConfig config, Header header,
Map<String, String> paramValues, Map<String, String> bodyValues, Type responseType) throws Exception {
RequestHttpEntity requestHttpEntity = new RequestHttpEntity(config,
header.setContentType(MediaType.APPLICATION_FORM_URLENCODED),
Query.newInstance().initParams(paramValues), bodyValues);
return execute(url, HttpMethod.POST, requestHttpEntity, responseType);
}

/**
* Execute the HTTP method to the given URI template, writing the given request entity to the request, and returns
* the response as {@link HttpRestResult}.
Expand All @@ -319,6 +422,27 @@ public <T> HttpRestResult<T> exchangeForm(String url, Header header, Map<String,
return execute(url, httpMethod, requestHttpEntity, responseType);
}

/**
* Set the request interceptors that this accessor should use.
*
* @param interceptors {@link HttpClientRequestInterceptor}
*/
public void setInterceptors(List<HttpClientRequestInterceptor> interceptors) {
if (this.interceptors != interceptors) {
this.interceptors.clear();
this.interceptors.addAll(interceptors);
}
}

/**
* Return the request interceptors that this accessor uses.
*
* <p>The returned {@link List} is active and may get appended to.
*/
public List<HttpClientRequestInterceptor> getInterceptors() {
return interceptors;
}

@SuppressWarnings("unchecked")
private <T> HttpRestResult<T> execute(String url, String httpMethod, RequestHttpEntity requestEntity,
Type responseType) throws Exception {
Expand All @@ -329,7 +453,7 @@ private <T> HttpRestResult<T> execute(String url, String httpMethod, RequestHttp
ResponseHandler<T> responseHandler = super.selectResponseHandler(responseType);
HttpClientResponse response = null;
try {
response = requestClient.execute(uri, httpMethod, requestEntity);
response = this.requestClient().execute(uri, httpMethod, requestEntity);
return responseHandler.handle(response);
} finally {
if (response != null) {
Expand All @@ -338,6 +462,16 @@ private <T> HttpRestResult<T> execute(String url, String httpMethod, RequestHttp
}
}

private HttpClientRequest requestClient() {
if (CollectionUtils.isNotEmpty(interceptors)) {
if (LOGGER.isDebugEnabled()) {
LOGGER.info("Execute via interceptors :{}", interceptors);
}
return new InterceptingHttpClientRequest(requestClient, interceptors.iterator());
}
return requestClient;
}

/**
* close request client.
*/
Expand Down
Loading

0 comments on commit c1515b6

Please sign in to comment.