Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ISSUE #3197] NacosRestTemplate enhance #3198

Merged
merged 12 commits into from
Jul 13, 2020
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,19 +16,23 @@

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.handler.ResponseHandler;
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 @@ -42,7 +46,9 @@ public class NacosRestTemplate {

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) {
this.requestClient = requestClient;
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;
}

private <T> HttpRestResult<T> execute(String url, String httpMethod, RequestHttpEntity requestEntity,
Type responseType) throws Exception {
URI uri = HttpUtils.buildUri(url, requestEntity.getQuery());
Expand All @@ -327,7 +451,7 @@ private <T> HttpRestResult<T> execute(String url, String httpMethod, RequestHttp
}
HttpClientResponse response = null;
try {
response = requestClient.execute(uri, httpMethod, requestEntity);
response = this.requestClient().execute(uri, httpMethod, requestEntity);
return ResponseHandler.responseEntityExtractor(response, responseType);
} finally {
if (response != null) {
Expand All @@ -336,6 +460,16 @@ private <T> HttpRestResult<T> execute(String url, String httpMethod, RequestHttp
}
}

private HttpClientRequest requestClient() {
if (CollectionUtils.isNotEmpty(interceptors)) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Execute via interceptor");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we print the interceptor name or class name?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay

}
return new InterceptingHttpClientRequest(requestClient, interceptors.iterator());
}
return requestClient;
}

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