Skip to content

Commit

Permalink
Merge pull request #2926 from Maijh97/develop
Browse files Browse the repository at this point in the history
[ISSUE #2858] Unified implementation of Http requests
  • Loading branch information
KomachiSion authored Jun 12, 2020
2 parents c6d9426 + 95272fe commit 81f9eff
Show file tree
Hide file tree
Showing 22 changed files with 1,690 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

package com.alibaba.nacos.api.exception.runtime;

import java.lang.reflect.Type;

/**
* Nacos deserialization exception.
*
Expand All @@ -42,6 +44,10 @@ public NacosDeserializationException(Class<?> targetClass) {
this.targetClass = targetClass;
}

public NacosDeserializationException(Type targetType) {
super(ERROR_CODE, String.format(MSG_FOR_SPECIFIED_CLASS, targetType.toString()));
}

public NacosDeserializationException(Throwable throwable) {
super(ERROR_CODE, DEFAULT_MSG, throwable);
}
Expand All @@ -51,6 +57,14 @@ public NacosDeserializationException(Class<?> targetClass, Throwable throwable)
this.targetClass = targetClass;
}

public NacosDeserializationException(Type targetType, Throwable throwable) {
super(ERROR_CODE, String.format(MSG_FOR_SPECIFIED_CLASS, targetType.toString()), throwable);
}





public Class<?> getTargetClass() {
return targetClass;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,10 @@ public interface HttpHeaderConsts {
String CLIENT_VERSION_HEADER = "Client-Version";
String USER_AGENT_HEADER = "User-Agent";
String REQUEST_SOURCE_HEADER = "Request-Source";
String CONTENT_TYPE = "Content-Type";
String CONTENT_LENGTH = "Content-Length";
String ACCEPT_CHARSET = "Accept-Charset";
String ACCEPT_ENCODING = "Accept-Encoding";
String CONTENT_ENCODING = "Content-Encoding";

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,22 @@

package com.alibaba.nacos.common.http;

import com.alibaba.nacos.api.common.Constants;
import com.alibaba.nacos.common.http.handler.RequestHandler;
import com.alibaba.nacos.common.http.param.Header;
import com.alibaba.nacos.common.http.param.MediaType;
import com.alibaba.nacos.common.utils.HttpMethod;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpRequest;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpHead;
Expand All @@ -34,6 +42,7 @@
import org.apache.http.client.methods.HttpTrace;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.message.BasicNameValuePair;

/**
* @author <a href="mailto:[email protected]">liaochuntao</a>
Expand Down Expand Up @@ -157,7 +166,6 @@ public void initEntity(Object body, String mediaType) throws Exception {
if (body == null) {
return;
}

if (requestBase instanceof HttpEntityEnclosingRequest) {
HttpEntityEnclosingRequest request = (HttpEntityEnclosingRequest) requestBase;
ContentType contentType = ContentType.create(mediaType);
Expand All @@ -166,6 +174,21 @@ public void initEntity(Object body, String mediaType) throws Exception {
}
}

public void initFromEntity(Map<String, String> body, String charset) throws Exception{
if (body.isEmpty()) {
return;
}
List<NameValuePair> params = new ArrayList<NameValuePair>(body.size());
for (Map.Entry<String, String> entry : body.entrySet()) {
params.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
}
if (requestBase instanceof HttpEntityEnclosingRequest) {
HttpEntityEnclosingRequest request = (HttpEntityEnclosingRequest) requestBase;
HttpEntity entity = new UrlEncodedFormEntity(params, charset);
request.setEntity(entity);
}
}

public HttpRequestBase getRequestBase() {
return (HttpRequestBase) requestBase;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,12 @@

package com.alibaba.nacos.common.http;

import com.alibaba.nacos.common.utils.ExceptionUtil;
import com.alibaba.nacos.common.http.client.DefaultAsyncHttpClientRequest;
import com.alibaba.nacos.common.http.client.DefaultHttpClientRequest;
import com.alibaba.nacos.common.http.client.NacosAsyncRestTemplate;
import com.alibaba.nacos.common.http.client.NacosRestTemplate;
import com.alibaba.nacos.common.utils.ShutdownUtils;
import com.alibaba.nacos.common.utils.ExceptionUtil;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.nio.client.HttpAsyncClients;
Expand Down Expand Up @@ -47,8 +51,15 @@ public class HttpClientManager {
private static final NAsyncHttpClient ASYNC_HTTP_CLIENT = new NacosAsyncHttpClient(
HttpAsyncClients.custom().setDefaultRequestConfig(DEFAULT_CONFIG).build());

private static final NacosRestTemplate NACOS_REST_TEMPLATE = new NacosRestTemplate(
new DefaultHttpClientRequest(HttpClients.custom().setDefaultRequestConfig(DEFAULT_CONFIG).build()));

private static final NacosAsyncRestTemplate NACOS_ASYNC_REST_TEMPLATE = new NacosAsyncRestTemplate(
new DefaultAsyncHttpClientRequest(HttpAsyncClients.custom().setDefaultRequestConfig(DEFAULT_CONFIG).build()));

private static final AtomicBoolean alreadyShutdown = new AtomicBoolean(false);


static {
ShutdownUtils.addShutdownHook(new Runnable() {
@Override
Expand All @@ -67,6 +78,14 @@ public static NAsyncHttpClient getAsyncHttpClient() {
return ASYNC_HTTP_CLIENT;
}

public static NacosRestTemplate getNacosRestTemplate() {
return NACOS_REST_TEMPLATE;
}

public static NacosAsyncRestTemplate getNacosAsyncRestTemplate() {
return NACOS_ASYNC_REST_TEMPLATE;
}

public static void shutdown() {
if (!alreadyShutdown.compareAndSet(false, true)) {
return;
Expand All @@ -75,6 +94,8 @@ public static void shutdown() {
try {
SYNC_HTTP_CLIENT.close();
ASYNC_HTTP_CLIENT.close();
NACOS_REST_TEMPLATE.close();
NACOS_ASYNC_REST_TEMPLATE.close();
}
catch (Exception ex) {
logger.error("An exception occurred when the HTTP client was closed : {}",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* 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;

import com.alibaba.nacos.common.http.param.Header;
import com.alibaba.nacos.common.model.RestResult;

/**
* http RestResult
*
* @author mai.jh
* @date 2020/5/31
*/
public class HttpRestResult<T> extends RestResult<T> {

private static final long serialVersionUID = 3766947816720175947L;
private Header header;

public HttpRestResult() {
}

public HttpRestResult(Header header, int code, T data) {
super(code, data);
this.header = header;
}

public Header getHeader() {
return header;
}

public void setHeader(Header header) {
this.header = header;
}
}
16 changes: 16 additions & 0 deletions common/src/main/java/com/alibaba/nacos/common/http/HttpUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,12 @@

package com.alibaba.nacos.common.http;

import com.alibaba.nacos.common.http.param.Query;
import com.alibaba.nacos.common.utils.StringUtils;

import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.HashMap;
Expand Down Expand Up @@ -120,6 +123,19 @@ public static String decode(String str, String encode) throws UnsupportedEncodin
return innerDecode(null, str, encode);
}

/**
* build URI By url and query
* @param url url
* @param query query param {@link Query}
* @return
*/
public static URI buildUri(String url, Query query) throws URISyntaxException {
if (!query.isEmpty()) {
url = url + "?" + query.toQueryUrl();
}
return new URI(url);
}

private static String innerDecode(String pre, String now, String encode) throws UnsupportedEncodingException {
// Because the data may be encoded by the URL more than once,
// it needs to be decoded recursively until it is fully successful
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* 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.http.Callback;
import com.alibaba.nacos.common.model.RequestHttpEntity;

import java.io.Closeable;
import java.lang.reflect.Type;
import java.net.URI;

/**
* Represents a client-side Async HTTP request.
* Created via an implementation execute.
*
* @author mai.jh
* @date 2020/5/29
*/
public interface AsyncHttpClientRequest extends Closeable {


/**
* execute async http request
*
* @param uri http url
* @param httpMethod http request method
* @param requestHttpEntity http request entity
* @param responseType http response type
* @param callback http response callback
* @throws Exception ex
*/
<T> void execute(URI uri, String httpMethod, RequestHttpEntity requestHttpEntity,
final Type responseType, final Callback<T> callback) throws Exception;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
* 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.http.Callback;
import com.alibaba.nacos.common.http.HttpRestResult;
import com.alibaba.nacos.common.http.handler.ResponseHandler;
import com.alibaba.nacos.common.model.RequestHttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.concurrent.FutureCallback;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;

import java.io.IOException;
import java.lang.reflect.Type;
import java.net.URI;

/**
* {@link AsyncHttpClientRequest} implementation that uses apache async http client to
* execute streaming requests
*
* @author mai.jh
* @date 2020/5/29
*/
public class DefaultAsyncHttpClientRequest implements AsyncHttpClientRequest {

private final CloseableHttpAsyncClient asyncClient;

public DefaultAsyncHttpClientRequest(CloseableHttpAsyncClient asyncClient) {
this.asyncClient = asyncClient;
if (!this.asyncClient.isRunning()) {
this.asyncClient.start();
}
}

@Override
public <T> void execute(URI uri, String httpMethod, RequestHttpEntity requestHttpEntity, final Type responseType, final Callback<T> callback) throws Exception {
HttpRequestBase httpRequestBase = DefaultHttpClientRequest.build(uri, httpMethod, requestHttpEntity);
asyncClient.execute(httpRequestBase, new FutureCallback<HttpResponse>() {
@Override
public void completed(HttpResponse result) {
DefaultClientHttpResponse response = new DefaultClientHttpResponse(result);
try {
HttpRestResult<T> httpRestResult = ResponseHandler.responseEntityExtractor(response, responseType);
callback.onReceive(httpRestResult);
} catch (Exception e) {
callback.onError(e);
}
}

@Override
public void failed(Exception ex) {
callback.onError(ex);
}

@Override
public void cancelled() {

}
});

}

@Override
public void close() throws IOException {
this.asyncClient.close();
}
}
Loading

0 comments on commit 81f9eff

Please sign in to comment.