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

com.imperva.shcf4j.HttpClientBuilderFactory Maven / Gradle / Ivy

Go to download

The Simple HTTP Client Facade for Java (SHCF4J) serves as a simple facade or abstraction for various HTTP client frameworks (e.g. java.net.HttpURLConnection, Apache HttpClient, etc.) allowing the end user to plug in the desired HTTP client framework at deployment time.

The newest version!
package com.imperva.shcf4j;

import com.imperva.shcf4j.helpers.NOPServiceProvider;
import com.imperva.shcf4j.helpers.Util;
import com.imperva.shcf4j.spi.SHC4JServiceProvider;

import java.util.LinkedList;
import java.util.List;
import java.util.ServiceLoader;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;


/**
 * HttpClientBuilderFactory
 *
 * @author maxim.kirilov
 */
public class HttpClientBuilderFactory {


    static final AtomicReference PROVIDER = new AtomicReference<>();
    static final AtomicReference FACTORY_STATE = new AtomicReference<>(State.UNINITIALIZED);

    static final String UNSUCCESSFUL_INIT_MSG =
            "com.imperva.shcf4j.HttpClientBuilderFactory in failed state. Original exception was thrown EARLIER.";

    private enum State {
        UNINITIALIZED,
        FAILED_INITIALIZATION,
        SUCCESSFUL_INITIALIZATION,
        NOP_FALLBACK_INITIALIZATION
    }

    static {
        bind();
    }


    private HttpClientBuilderFactory() {
    }

    private static List findServiceProviders() {
        return StreamSupport
                .stream(ServiceLoader.load(SHC4JServiceProvider.class).spliterator(), false)
                .collect(Collectors.toCollection(LinkedList::new));
    }


    private final static void bind() {
        try {
            List providersList = findServiceProviders();
            reportMultipleBindingAmbiguity(providersList);
            if ( !providersList.isEmpty() ) {
                PROVIDER.set(providersList.get(0));
                PROVIDER.get().initialize();
                Util.report("Actual provider is of type [" + PROVIDER.get().getClass().getCanonicalName() + "]");
                FACTORY_STATE.set(State.SUCCESSFUL_INITIALIZATION);
            } else {
                Util.report("No SHCF4J providers were found");
                Util.report("Defaulting to no-operation (NOP) HTTP Client implementation");
                FACTORY_STATE.set(State.NOP_FALLBACK_INITIALIZATION);
            }
        } catch (Exception e) {
            FACTORY_STATE.set(State.FAILED_INITIALIZATION);
            failedBinding(e);
            throw new IllegalStateException("Unexpected initialization failure", e);
        }
    }


    static void failedBinding(Throwable t) {
        Util.report("Failed to instantiate SLF4J LoggerFactory", t);
    }


    /**
     * Prints a warning message on the console if multiple bindings were found
     * on the class path. No reporting is done otherwise.
     */
    private static  void reportMultipleBindingAmbiguity(List providerList) {
        if (isAmbiguousProviderList(providerList)) {
            Util.report("Class path contains multiple SHCF4J providers.");
            for (T provider : providerList) {
                Util.report("Found provider [" + provider.getClass().getCanonicalName() + "]");
            }
        }
    }


    private static  boolean isAmbiguousProviderList(List providerList) {
        return providerList.size() > 1;
    }


    static SHC4JServiceProvider getProvider() {
        switch (FACTORY_STATE.get()) {
            case SUCCESSFUL_INITIALIZATION:
                return PROVIDER.get();
            case NOP_FALLBACK_INITIALIZATION:
                return NOPServiceProvider.INSTANCE;
            case FAILED_INITIALIZATION:
                throw new IllegalStateException(UNSUCCESSFUL_INIT_MSG);
        }
        throw new IllegalStateException("Unreachable code");
    }


    /**
     * @return a {@link SyncHttpClientBuilder}
     */
    public static SyncHttpClientBuilder getHttpClientBuilder() {
        return getProvider().getHttpClientBuilder();
    }


    /**
     * @return a {@link AsyncHttpClientBuilder}
     */
    public static AsyncHttpClientBuilder getHttpAsyncClientBuilder() {
        return getProvider().getHttpAsyncClientBuilder();
    }


}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy