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

bdi.glue.http.httpclient.HttpClientGateway Maven / Gradle / Ivy

The newest version!
package bdi.glue.http.httpclient;

import bdi.glue.http.common.*;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHeaders;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.AuthCache;
import org.apache.http.client.CookieStore;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.methods.*;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.BasicAuthCache;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.cookie.BasicClientCookie;
import org.apache.http.message.BasicHeader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.util.List;

/**
 * @author @aloyer
 */
public class HttpClientGateway implements HttpGateway {

    private static final Charset UTF8 = Charset.forName("utf8");

    private Logger log = LoggerFactory.getLogger(HttpClientGateway.class);

    private final HttpClientWorld httpClientWorld;
    private URI hostUri;

    public HttpClientGateway(HttpClientWorld httpClientWorld) {
        this.httpClientWorld = httpClientWorld;
    }

    @Override
    public void defineHost(URI hostUri) {
        this.hostUri = hostUri;
    }

    @SuppressWarnings("unchecked")
    @Override
    public  T getAdapter(Class type) {
        if (type.equals(CloseableHttpClient.class)) {
            return (T) httpClientWorld.httpClient();
        }
        if (type.isAssignableFrom(CookieStore.class)) {
            return (T) httpClientWorld.cookieStore();
        }
        if (type.isAssignableFrom(HttpClientContext.class)) {
            return (T) httpClientWorld.httpClientContext();
        }

        return null;
    }

    @Override
    public HttpResponse invoke(HttpRequestBuilder req) {
        HttpMethod m = HttpMethod.lookup(req.getMethodAsString());
        String requestPath = req.getRequestPath();

        log.info("Building request to invoke {} on {}", m, requestPath);

        HttpHost httpHost = getHttpHost();
        URIBuilder uriBuilder = getUriBuilder(req, httpHost);

        configureParameters(req, uriBuilder);
        URI uri;
        try {
            uri = uriBuilder.build();
        } catch (URISyntaxException e) {
            throw new RuntimeException("Fail to build URI " + uriBuilder);
        }

        HttpRequestBase requestBase = createHttpRequestBase(m);
        configureBody(req, m, requestBase);
        requestBase.setURI(uri);

        HttpClientContext context = httpClientWorld.httpClientContext();
        configureBasicAuth(req, httpHost, context);
        configureHeaders(req, requestBase);

        configureCookies(req);

        try {
            CloseableHttpClient closeableHttpClient = httpClientWorld.httpClient();

            CloseableHttpResponse lastResponse =
                    (httpHost != null) ?
                            closeableHttpClient.execute(
                                    httpHost,
                                    requestBase,
                                    context) :
                            closeableHttpClient.execute(
                                    requestBase,
                                    context);

            log.debug("{}", lastResponse.getStatusLine());
            return new HttpResponseAdapter(lastResponse, httpClientWorld.cookieStore());
        } catch (IOException e) {
            throw new HttpException(e);
        }
    }

    private void configureCookies(HttpRequestBuilder req) {
        BasicCookieStore cookieStore = httpClientWorld.cookieStore();

        // no remove cookie method
        List cookies = cookieStore.getCookies();
        cookieStore.clear();
        List cookiesToRemove = req.getCookiesToRemove();
        for (org.apache.http.cookie.Cookie cookie : cookies) {
            if (!cookiesToRemove.contains(cookie.getName()))
                cookieStore.addCookie(cookie);
        }

        for (Cookie cookie : req.getCookies()) {
            cookieStore.addCookie(new BasicClientCookie(cookie.name(), cookie.value()));
        }
    }

    private void configureBody(HttpRequestBuilder req, HttpMethod m, HttpRequestBase requestBase) {
        String body = req.getBody();
        if (body == null)
            return;

        if (!(requestBase instanceof HttpEntityEnclosingRequestBase)) {
            throw new IllegalArgumentException("Cannot attach body on " + m + " request");
        }

        HttpEntity entity = new ByteArrayEntity(body.getBytes(UTF8));
        ((HttpEntityEnclosingRequestBase) requestBase).setEntity(entity);
    }

    private URIBuilder getUriBuilder(HttpRequestBuilder req, HttpHost httpHost) {
        URIBuilder uriBuilder = new URIBuilder();
        if (httpHost != null) {
            uriBuilder = uriBuilder
                    .setScheme(httpHost.getSchemeName())
                    .setHost(httpHost.toHostString())
                    .setPort(httpHost.getPort());
        }
        return uriBuilder.setPath(req.getRequestPath());
    }

    private void configureParameters(HttpRequestBuilder req, URIBuilder uriBuilder) {
        for (Parameter parameter : req.getParameters()) {
            uriBuilder = uriBuilder.setParameter(parameter.parameterName, parameter.parameterValue);
        }
    }

    private HttpRequestBase createHttpRequestBase(HttpMethod m) {
        switch (m) {
            case GET:
                return new HttpGet();
            case PUT:
                return new HttpPut();
            case POST:
                return new HttpPost();
            case DELETE:
                return new HttpDelete();
            case HEAD:
                return new HttpHead();
            case OPTIONS:
                return new HttpOptions();
            case TRACE:
                return new HttpTrace();
//            case CONNECT:
//                return new HttpConnect()
            case PATCH:
                return new HttpPatch();
            default:
                throw new IllegalArgumentException("Unsupported method " + m + "'");
        }
    }

    private void configureHeaders(HttpRequestBuilder req,
                                  HttpRequestBase requestBase) {

        if (req.getContentType() != null) {
            requestBase.setHeader(HttpHeaders.CONTENT_TYPE, req.getContentType());
        }
        requestBase.setHeaders(convert(req.getHeaders()));
    }

    private void configureBasicAuth(HttpRequestBuilder req,
                                    HttpHost targetHost,
                                    HttpClientContext context) {
        if (req.getUsername() == null && req.getPassword() == null) {
            return;
        }

        CredentialsProvider credsProvider = new BasicCredentialsProvider();
        credsProvider.setCredentials(
                new AuthScope(targetHost.getHostName(), targetHost.getPort()),
                new UsernamePasswordCredentials(req.getUsername(), req.getPassword()));

        // Create AuthCache instance
        AuthCache authCache = new BasicAuthCache();

        // Generate BASIC scheme object and add it to the local auth cache
        BasicScheme basicAuth = new BasicScheme();
        authCache.put(targetHost, basicAuth);

        // Add AuthCache to the execution context
        context.setCredentialsProvider(credsProvider);
        context.setAuthCache(authCache);
    }

    private HttpHost getHttpHost() {
        HttpHost httpHost = null;
        if (hostUri != null) {
            httpHost = new HttpHost(hostUri.getHost(), hostUri.getPort(), hostUri.getScheme());
        }
        return httpHost;
    }

    private static org.apache.http.Header[] convert(List headers) {
        org.apache.http.Header[] array = new org.apache.http.Header[headers.size()];
        for (int i = 0; i < headers.size(); i++) {
            bdi.glue.http.common.Header h = headers.get(i);
            array[i] = new BasicHeader(h.name, h.value);
        }
        return array;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy