Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
io.ultreia.java4all.http.HResponseBuilder Maven / Gradle / Ivy
package io.ultreia.java4all.http;
/*
* #%L
* Http :: Api
* %%
* Copyright (C) 2017 - 2020 Ultreia.io
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* .
* #L%
*/
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.apache.commons.io.IOUtils;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPatch;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.ConnectException;
import java.net.URL;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Supplier;
/**
* @author Tony Chemit - [email protected]
*/
public class HResponseBuilder implements Closeable {
private static final Logger log = LogManager.getLogger(HResponseBuilder.class);
private final CloseableHttpClient client;
private final Supplier gson;
private HResponseBuilder(CloseableHttpClient client, Supplier gson) {
this.client = client;
this.gson = gson == null ? () -> new GsonBuilder().setPrettyPrinting().create() : gson;
}
public static HResponseBuilder create() {
return create(null);
}
public static HResponseBuilder create(Supplier gson, CloseableHttpClient build) {
return new HResponseBuilder(build, gson);
}
public static HResponseBuilder create(Supplier gson) {
return create(gson, HttpClientBuilder.create()
.setDefaultCookieStore(new BasicCookieStore())
.setMaxConnTotal(1000)
.setMaxConnPerRoute(1000)
// .setConnectionTimeToLive(45, TimeUnit.SECONDS)
.build());
}
public Supplier getGson() {
return gson;
}
public HResponse executeRequest(HRequest request, int expectedStatusCode) throws IOException {
HResponse response = executeRequest(request);
Integer statusCode = response.getStatusCode();
if (Objects.equals(statusCode, expectedStatusCode)) {
return response;
}
String baseUrl = request.getBaseUrl();
String responseAsString = response.toString();
if (log.isWarnEnabled()) {
log.warn(String.format("Unexpected status code for url: %s\n%s", baseUrl, responseAsString));
}
if (statusCode >= 400 && statusCode < 500) {
throw new HResponseNotAvailableException(new URL(baseUrl));
}
if (statusCode >= 500) {
HResponseError error;
try {
error = getGson().get().fromJson(responseAsString, HResponseError.class);
} catch (Exception e) {
error = new HResponseError(statusCode, null, responseAsString, null);
}
throw new HResponseErrorException(error);
}
throw new HttpResponseBadStatusCodeException(expectedStatusCode, statusCode);
}
public HResponse executeRequest(HRequest request) throws IOException {
if (log.isInfoEnabled() && !request.isQuiet()) {
log.info(String.format("execute request: [%s] %s", request.getRequestMethod(), request.getBaseUrl()));
}
if (log.isDebugEnabled()) {
log.debug("request params: " + request.getParameters());
}
String requestMethod = request.getRequestMethod();
HResponse response;
switch (requestMethod) {
case HttpGet.METHOD_NAME:
response = get0(request);
break;
case HttpPost.METHOD_NAME:
response = post0(request);
break;
case HttpPut.METHOD_NAME:
response = put0(request);
break;
case HttpDelete.METHOD_NAME:
response = delete0(request);
break;
case HttpPatch.METHOD_NAME:
response = patch0(request);
break;
default:
throw new IllegalStateException("Can't come here!");
}
log.debug("status: " + response.getStatusCode());
for (Header header : response.getResponse().getAllHeaders()) {
log.debug("response header: " + header);
}
return response;
}
private HResponse get0(HRequest request) throws IOException {
String baseUrl = request.getBaseUrl();
String url = buildUrlWithParameters(baseUrl, request.getParameters());
HttpGet getMethod = new HttpGet(url);
addTimeoutToRequest(getMethod, request.getTimeout(),request.getSocketTimeout());
addHeaders(getMethod, request.getHeaders());
HttpResponse response = executeRequest(getMethod);
if (log.isDebugEnabled()) {
log.debug("GET '" + baseUrl + "' return status code : " + response.getStatusLine().getStatusCode());
}
return consumeResponse(request, getMethod, response);
}
private HResponse post0(HRequest request) throws IOException {
String baseUrl = request.getBaseUrl();
String contentType = request.getContentType();
String requestBody = request.getRequestBody();
HttpPost postMethod = new HttpPost(baseUrl);
addTimeoutToRequest(postMethod, request.getTimeout(),request.getSocketTimeout());
addHeaders(postMethod, request.getHeaders());
addRequestBody(postMethod, contentType, requestBody);
if (postMethod.getEntity() == null) {
HttpEntity entity;
if (request.isUseMultipartForm()) {
MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();
if (contentType == null || contentType.trim().isEmpty()) {
contentType = ContentType.TEXT_PLAIN.getMimeType();
}
if (request.withoutFiles()) {
for (NameValuePair param : request.getParameters()) {
entityBuilder.addTextBody(param.getName(), param.getValue(), ContentType.create(contentType, StandardCharsets.UTF_8));
}
} else {
for (Map.Entry paramFile : request.getFiles().entrySet()) {
byte[] content = Files.readAllBytes(paramFile.getValue().toPath());
ContentType contentType1 = ContentType.create(Files.probeContentType(paramFile.getValue().toPath()));
entityBuilder.addBinaryBody(paramFile.getKey(), content, contentType1, paramFile.getValue().getName());
}
for (NameValuePair param : request.getParameters()) {
entityBuilder.addTextBody(param.getName(), param.getValue(), ContentType.create(contentType, StandardCharsets.UTF_8));
}
}
entity = entityBuilder.build();
} else {
String url = URLEncodedUtils.format(request.getParameters(), StandardCharsets.UTF_8);
StringEntity stringEntity = new StringEntity(url, StandardCharsets.UTF_8);
stringEntity.setContentType("application/x-www-form-urlencoded");
entity = stringEntity;
}
postMethod.setEntity(entity);
}
HttpResponse response = executeRequest(postMethod);
if (log.isDebugEnabled()) {
log.debug("POST '" + baseUrl + "' return status code : " + response.getStatusLine().getStatusCode());
}
return consumeResponse(request, postMethod, response);
}
private HResponse put0(HRequest request) throws IOException {
String baseUrl = request.getBaseUrl();
String contentType = request.getContentType();
String requestBody = request.getRequestBody();
HttpPut putMethod = new HttpPut(baseUrl);
addHeaders(putMethod, request.getHeaders());
addTimeoutToRequest(putMethod, request.getTimeout(),request.getSocketTimeout());
addParameters(putMethod, contentType, request.getParameters());
addRequestBody(putMethod, contentType, requestBody);
HttpResponse response = executeRequest(putMethod);
if (log.isDebugEnabled()) {
log.debug("PUT '" + baseUrl + "' return status code : " + response.getStatusLine().getStatusCode());
}
return consumeResponse(request, putMethod, response);
}
private HResponse delete0(HRequest request) throws IOException {
String baseUrl = request.getBaseUrl();
HttpDelete deleteMethod = new HttpDelete(buildUrlWithParameters(baseUrl, request.getParameters()));
addHeaders(deleteMethod, request.getHeaders());
addTimeoutToRequest(deleteMethod, request.getTimeout(),request.getSocketTimeout());
HttpResponse response = executeRequest(deleteMethod);
if (log.isDebugEnabled()) {
log.debug("DELETE '" + baseUrl + "' return status code : " + response.getStatusLine().getStatusCode());
}
return consumeResponse(request, deleteMethod, response);
}
private HResponse patch0(HRequest request) throws IOException {
String baseUrl = request.getBaseUrl();
HttpPatch patchMethod = new HttpPatch(buildUrlWithParameters(baseUrl, request.getParameters()));
addHeaders(patchMethod, request.getHeaders());
addTimeoutToRequest(patchMethod, request.getTimeout(),request.getSocketTimeout());
HttpResponse response = executeRequest(patchMethod);
if (log.isDebugEnabled()) {
log.debug("PATCH '" + baseUrl + "' return status code : " + response.getStatusLine().getStatusCode());
}
return consumeResponse(request, patchMethod, response);
}
private HttpResponse executeRequest(HttpRequestBase request) throws IOException, HResponseNotAvailableException {
try {
return client.execute(request);
} catch (UnknownHostException | ConnectException e) {
// Le service n'est pas accessible
throw new HResponseNotAvailableException(request.getURI().toURL());
} catch (Exception e) {
log.error("something is wrong here...", e);
throw e;
}
}
private HResponse consumeResponse(HRequest request, HttpRequestBase httpRequestBase, HttpResponse response) throws IOException {
String baseUrl = request.getBaseUrl();
Header[] responseHeaders = response.getAllHeaders();
int statusCode = response.getStatusLine().getStatusCode();
if (log.isDebugEnabled()) {
log.debug(request.getRequestMethod() + " '" + baseUrl + "' return status code : " + statusCode);
}
String responseAsString;
try (InputStream inputStream = response.getEntity().getContent()) {
responseAsString = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
}
return new HResponse(httpRequestBase, response, statusCode, responseAsString, gson.get(), responseHeaders);
}
private String buildUrlWithParameters(String baseUrl, List parameters) {
String result = baseUrl;
if (!parameters.isEmpty()) {
result += "?" + URLEncodedUtils.format(parameters, StandardCharsets.UTF_8);
}
return result;
}
private void addHeaders(M httpMethod, Map headers) {
for (Map.Entry entry : headers.entrySet()) {
httpMethod.setHeader(entry.getKey(), entry.getValue());
}
}
private void addParameters(M method, String contentType, List extends NameValuePair> parameters) {
UrlEncodedFormEntity encodedFormEntity = new UrlEncodedFormEntity(parameters, StandardCharsets.UTF_8);
if (!contentType.trim().isEmpty()) {
encodedFormEntity.setContentType(contentType);
}
method.setEntity(encodedFormEntity);
}
private void addRequestBody(M method, String contentType, String requestBody) {
if (requestBody != null && !requestBody.trim().isEmpty()) {
if (!contentType.trim().isEmpty()) {
method.setEntity(new StringEntity(requestBody, ContentType.create(contentType, StandardCharsets.UTF_8)));
} else {
method.setEntity(new StringEntity(requestBody, StandardCharsets.UTF_8));
}
}
}
public void close() throws IOException {
client.close();
}
@Override
protected void finalize() throws Throwable {
try {
client.close();
} finally {
super.finalize();
}
}
private void addTimeoutToRequest(HttpRequestBase httpRequestBase, long timeout, long socketTimeout) {
RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout((int) timeout).setSocketTimeout((int)socketTimeout).build();
if (log.isDebugEnabled()) {
log.debug("Add custom timeout: " + timeout);
}
httpRequestBase.setConfig(requestConfig);
}
}