All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.ultreia.gc.http.GcResponseBuilder Maven / Gradle / Ivy

There is a newer version: 1.3.4
Show newest version
package io.ultreia.gc.http;

/*
 * #%L
 * GC toolkit :: API
 * %%
 * Copyright (C) 2017 Ultreia.io
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU 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 Public License for more details.
 * 
 * You should have received a copy of the GNU General Public
 * License along with this program.  If not, see
 * .
 * #L%
 */

import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.ConnectException;
import java.net.UnknownHostException;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.Header;
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.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.http.impl.cookie.BasicClientCookie;

/**
 * @author Tony Chemit - [email protected]
 */
public class GcResponseBuilder implements Closeable {

    private static final Log log = LogFactory.getLog(GcResponseBuilder.class);

    public static GcResponseBuilder create() {
        BasicCookieStore cookieStore = new BasicCookieStore();
        CloseableHttpClient build = HttpClientBuilder.create()
                .setDefaultCookieStore(cookieStore)
                .setConnectionTimeToLive(45, TimeUnit.SECONDS)
                .build();
        return new GcResponseBuilder(build, cookieStore);
    }

    private final CloseableHttpClient client;
    private final BasicCookieStore cookieStore;

    public GcResponse executeRequest(GcRequest request) throws IOException {

        String requestMethod = request.getRequestMethod();
        switch (requestMethod) {
            case HttpGet.METHOD_NAME:
                return get0(request);
            case HttpPost.METHOD_NAME:
                return post0(request);
            case HttpPut.METHOD_NAME:
                return put0(request);
            case HttpDelete.METHOD_NAME:
                return delete0(request);
            default:
                throw new IllegalStateException("Can't come here!");
        }

    }

    private GcResponseBuilder(CloseableHttpClient client, BasicCookieStore cookieStore) {
        this.client = client;
        this.cookieStore = cookieStore;
    }

    private GcResponse get0(GcRequest request) throws IOException {

        String baseUrl = request.getBaseUrl();
        String url = buildUrlWithParameters(baseUrl, request.getParameters());

        HttpGet getMethod = new HttpGet(url);
        addTimeoutToRequest(getMethod, request.getTimeout());
        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 GcResponse post0(GcRequest request) throws IOException {

        String baseUrl = request.getBaseUrl();
        String contentType = request.getContentType();
        String requestBody = request.getRequestBody();

        HttpPost postMethod = new HttpPost(baseUrl);

        addTimeoutToRequest(postMethod, request.getTimeout());

        MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();

        if (contentType == null || contentType.trim().isEmpty()) {
            contentType = "text/plain";
        }

        if (request.withoutFiles()) {
            addHeaders(postMethod, request.getHeaders());
            addRequestBody(postMethod, contentType, requestBody);

            for (NameValuePair param : request.getParameters()) {
                entityBuilder.addTextBody(param.getName(), param.getValue(), ContentType.create(contentType, StandardCharsets.UTF_8));
            }
        } else {
            addHeaders(postMethod, request.getHeaders());
            addRequestBody(postMethod, contentType, requestBody);

            for (Map.Entry paramFile : request.getFiles().entrySet()) {
                entityBuilder.addBinaryBody(paramFile.getKey(), paramFile.getValue());
            }
            for (NameValuePair param : request.getParameters()) {
                entityBuilder.addTextBody(param.getName(), param.getValue(), ContentType.create(contentType, StandardCharsets.UTF_8));
            }

        }

        postMethod.setEntity(entityBuilder.build());

        HttpResponse response = executeRequest(postMethod);

        if (log.isDebugEnabled()) {
            log.debug("POST '" + baseUrl + "' return status code : " + response.getStatusLine().getStatusCode());
        }

        return consumeResponse(request, postMethod, response);

    }

    private GcResponse put0(GcRequest request) throws IOException {

        String baseUrl = request.getBaseUrl();

        HttpPut putMethod = new HttpPut(baseUrl);
        addHeaders(putMethod, request.getHeaders());
        addTimeoutToRequest(putMethod, request.getTimeout());
        String contentType = request.getContentType();
        addParameters(putMethod, contentType, request.getParameters());
        addRequestBody(putMethod, contentType, request.getRequestBody());

        HttpResponse response = executeRequest(putMethod);

        if (log.isDebugEnabled()) {
            log.debug("PUT '" + baseUrl + "' return status code : " + response.getStatusLine().getStatusCode());
        }

        return consumeResponse(request, putMethod, response);

    }

    private GcResponse delete0(GcRequest request) throws IOException {

        String baseUrl = request.getBaseUrl();

        HttpDelete deleteMethod = new HttpDelete(buildUrlWithParameters(baseUrl, request.getParameters()));

        addHeaders(deleteMethod, request.getHeaders());
        addTimeoutToRequest(deleteMethod, request.getTimeout());
        HttpResponse response = executeRequest(deleteMethod);

        if (log.isDebugEnabled()) {
            log.debug("DELETE '" + baseUrl + "' return status code : " + response.getStatusLine().getStatusCode());
        }

        return consumeResponse(request, deleteMethod, response);

    }

    private HttpResponse executeRequest(HttpRequestBase request) throws IOException, GcResponseNotAvailableException {

        try {
            return client.execute(request);
        } catch (UnknownHostException | ConnectException e) {
            // Le service n'est pas accessible
            throw new GcResponseNotAvailableException(request.getURI().toURL());
        }

    }

    private GcResponse consumeResponse(GcRequest 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()) {
        try (ByteArrayOutputStream writer = new ByteArrayOutputStream()) {
            response.getEntity().writeTo(writer);
//                IOUtils.copy(inputStream, writer, "UTF-8");
            responseAsString = writer.toString();
//            }
        }
        return new GcResponse(httpRequestBase, response, statusCode, responseAsString, 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 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) throws UnsupportedEncodingException {
        if (requestBody != null && !requestBody.trim().isEmpty()) {
            if (!contentType.trim().isEmpty()) {
                method.setEntity(new StringEntity(requestBody, ContentType.parse(contentType)));
            } else {
                method.setEntity(new StringEntity(requestBody));
            }
        }
    }

    public void close() throws IOException {
        client.close();
    }

    @Override
    protected void finalize() throws Throwable {

        try {
            client.close();
        } finally {
            super.finalize();
        }

    }

    private void addTimeoutToRequest(HttpRequestBase httpRequestBase, int timeout) {

        RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(timeout).build();
        if (log.isDebugEnabled()) {
            log.debug("Add custom timeout: " + timeout);
        }
        httpRequestBase.setConfig(requestConfig);

    }

    public void setCookie(String name, String value) {
        BasicClientCookie cookie = new BasicClientCookie(name, value);
        cookie.setDomain(".geocaching.com");
        cookie.setPath("/");
        cookie.setSecure(true);
        cookie.setExpiryDate(new Date(new Date().getTime() + 3000));

        cookieStore.addCookie(cookie);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy