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

io.joshworks.restclient.http.ClientBuilder Maven / Gradle / Ivy

package io.joshworks.restclient.http;

import org.apache.http.HttpHost;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.HttpResponseInterceptor;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.Credentials;
import org.apache.http.client.CookieStore;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.conn.HttpClientConnectionManager;
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.client.HttpClientBuilder;
import org.apache.http.impl.client.LaxRedirectStrategy;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
import org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager;
import org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor;

import javax.net.ssl.SSLContext;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

public class ClientBuilder {

    private CredentialsProvider credentialsProvider;
    private int maxTotal = 20;
    private int maxRoute = 2;
    private String baseUrl = "";

    private Function urlTransformer = url -> url;
    private Map defaultHeaders = new HashMap<>();

    private RequestConfig.Builder configBuilder = RequestConfig.custom();
    private List requestInterceptors = new LinkedList<>();
    private List responseInterceptor = new LinkedList<>();
    private final CookieStore cookieStore = new BasicCookieStore();
    private SSLContext sslContext;

    ClientBuilder() {

    }

    public RestClient build() {
        try {

            RequestConfig clientConfig = configBuilder.build();

            PoolingHttpClientConnectionManager syncConnectionManager = new PoolingHttpClientConnectionManager();
            syncConnectionManager.setMaxTotal(maxTotal);
            syncConnectionManager.setDefaultMaxPerRoute(maxRoute);
            CloseableHttpClient syncClient = createSyncClient(clientConfig, syncConnectionManager);

            DefaultConnectingIOReactor ioReactor = new DefaultConnectingIOReactor();
            PoolingNHttpClientConnectionManager asyncConnectionManager = new PoolingNHttpClientConnectionManager(ioReactor);
            asyncConnectionManager.setMaxTotal(maxTotal);
            asyncConnectionManager.setDefaultMaxPerRoute(maxRoute);
            CloseableHttpAsyncClient asyncClient = createAsyncClient(clientConfig, asyncConnectionManager);

            RestClient restClient = new RestClient(baseUrl, defaultHeaders, urlTransformer, asyncConnectionManager, syncConnectionManager, asyncClient, syncClient, cookieStore);
            ClientContainer.addClient(restClient);
            return restClient;

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private CloseableHttpAsyncClient createAsyncClient(RequestConfig clientConfig, PoolingNHttpClientConnectionManager manager) {
        HttpAsyncClientBuilder asyncBuilder = HttpAsyncClientBuilder.create()
                .setDefaultRequestConfig(clientConfig)
                .setDefaultCookieStore(cookieStore)
                .setSSLContext(sslContext)
                .setConnectionManager(manager);

        return addInterceptors(asyncBuilder).build();
    }

    private CloseableHttpClient createSyncClient(RequestConfig clientConfig, HttpClientConnectionManager manager) {

        HttpClientBuilder syncBuilder = HttpClientBuilder.create()
                .setDefaultRequestConfig(clientConfig)
                .setDefaultCookieStore(cookieStore)
                .setSSLContext(sslContext)
                .setRedirectStrategy(new LaxRedirectStrategy())
                .setDefaultCredentialsProvider(credentialsProvider)
                .setConnectionManager(manager);

        if(sslContext != null) {
            syncBuilder.setSSLContext(sslContext);
        }

        return addInterceptors(syncBuilder).build();
    }

    private HttpClientBuilder addInterceptors(HttpClientBuilder builder) {
        for (HttpRequestInterceptor interceptor : requestInterceptors) {
            builder.addInterceptorLast(interceptor);
        }
        for (HttpResponseInterceptor interceptor : responseInterceptor) {
            builder.addInterceptorLast(interceptor);
        }
        return builder;
    }

    private HttpAsyncClientBuilder addInterceptors(HttpAsyncClientBuilder builder) {
        for (HttpRequestInterceptor interceptor : requestInterceptors) {
            builder.addInterceptorLast(interceptor);
        }
        for (HttpResponseInterceptor interceptor : responseInterceptor) {
            builder.addInterceptorLast(interceptor);
        }
        return builder;
    }

    public ClientBuilder baseUrl(String baseUrl) {
        this.baseUrl = baseUrl;
        return this;
    }

    public ClientBuilder defaultHeader(String key, String value) {
        this.defaultHeaders.put(key, value);
        return this;
    }

    public ClientBuilder followRedirect(boolean followRedirect) {
        configBuilder.setRedirectsEnabled(followRedirect);
        return this;
    }

    public ClientBuilder sslContext(SSLContext sslContext) {
        this.sslContext = sslContext;
        return this;
    }

    public ClientBuilder interceptor(HttpRequestInterceptor interceptor) {
        this.requestInterceptors.add(interceptor);
        return this;
    }

    public ClientBuilder interceptor(HttpResponseInterceptor interceptor) {
        this.responseInterceptor.add(interceptor);
        return this;
    }

    public ClientBuilder defaultHeader(String key, long value) {
        this.defaultHeaders.put(key, value);
        return this;
    }

    public ClientBuilder credentialProvider(CredentialsProvider provider) {
        this.credentialsProvider = provider;
        return this;
    }

    public ClientBuilder urlTransformer(Function transformer) {
        this.urlTransformer = transformer;
        return this;
    }

    public ClientBuilder cookieSpec(String cookieSpec) {
        configBuilder.setCookieSpec(cookieSpec);
        return this;
    }

    public ClientBuilder proxy(HttpHost proxy) {
        configBuilder.setProxy(proxy);
        return this;
    }

    public ClientBuilder proxy(HttpHost proxy, Credentials credentials) {
        this.credentialsProvider = new BasicCredentialsProvider();
        credentialsProvider.setCredentials(new AuthScope(proxy.getHostName(), proxy.getPort()), credentials);
        return this.proxy(proxy);
    }

    /**
     * Set the connection timeout and socket timeout
     *
     * @param connectionTimeout The timeout until a connection with the server is established (in milliseconds). Default is 10000. Set to zero to disable the timeout.
     * @param readTimeout       The timeout to receive data (in milliseconds). Default is 60000. Set to zero to disable the timeout.
     */
    public ClientBuilder timeout(int connectionTimeout, int readTimeout) {
        configBuilder.setSocketTimeout(readTimeout).setConnectTimeout(connectionTimeout);
        return this;
    }

    /**
     * Set the concurrency levels
     *
     * @param maxTotal Defines the overall connection limit for a connection pool. Default is 20.
     */
    public ClientBuilder concurrency(int maxTotal) {
        this.maxTotal = maxTotal;
        return this;
    }

    /**
     * Set the concurrency levels per host
     *
     * @param maxRoute Defines the connection limit for a connection pool per host. Default is 2.
     */
    public ClientBuilder routeConcurrency(int maxRoute){
        this.maxRoute = maxRoute;
        return this;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy