Http Client Factory

Available since version 3.1.2

Purpose

Apache HttpComponents since version 4.2 contains a fluent API which is often easier to use than the low-level CloseableHttpClient API.

However, there is no direct support for OSGi configuration admin for either API which means that HttpClients and Fluent Executors/Requests must be created manually. Apache HttpComponents only comes with some support for OSGi configuration of HTTP proxies via factory PID org.apache.http.proxyconfigurator.

The OSGi service com.adobe.acs.commons.http.HttpClientFactory manages the lifecycle of fluent HTTP Executors/Requests. There is an instance available per OSGi configuration bound via factory PID com.adobe.acs.commons.http.impl.HttpClientFactoryImpl (with name ACS AEM Commons - Http Components Fluent Executor Factory). Each service instance only holds a single HTTP Client/Request/Executor object (despite its class name suffix Factory).

The client is only closed once the service is stopped by the OSGi runtime, so be aware of potentially open sockets in the underlying connection manager and release the service once you no longer need it. Also make sure to release the response (and its input streams) once you no longer need it and optionally tweak the TTL for HTTP connections via a custom org.apache.http.conn.ConnectionKeepAliveStrategy.

How to Use

Create one or multiple OSGi configurations for factory PID com.adobe.acs.commons.http.impl.HttpClientFactoryImpl to automatically register an OSGi service implementing com.adobe.acs.commons.http.HttpClientFactory.

image

The proxy configurations via the dedicated configuration factory PID org.apache.http.proxyconfigurator are considered.

image

Then access the instance in code like this

@Component
public class MyComponent {

    /**
     * Inject specific configuration by targeting its "factory.name"
     */
    @Activate
    public MyComponent(@Reference(target = "(factory.name=pim2)") HttpClientFactory httpClientFactory) {
        Request request = httpClientFactory.get("my/request/path"); // this is appended to the configured "hostname"
        request.execute().handleResponse(new ResponseHandler<Document>() {
           ...
        });
    }

Alternative Approaches

  1. One can use the OSGi service org.apache.http.osgi.services.HttpClientBuilderFactory or org.apache.http.osgi.services.CachingHttpClientBuilderFactory directly to create (Caching) Http Clients (and Fluent API objects). This service is used under the hood by com.adobe.acs.commons.http.impl.HttpClientFactoryImpl as well. You use them like this

     @Component
     public class MyComponent {
         @Activate
         public MyComponent(@Reference org.apache.http.osgi.services.HttpClientBuilderFactory httpClientBuilderFactory) {
             try (CloseableHttpClient client = httpClientBuilderFactory.newBuilder().build()) {
                 // do something with the client here
             }
         }
    
  2. Alternatively there is OSGi configuration admin support similar to the one provided by ACS AEM Commons in https://github.com/code-distillery/httpclient-configuration-support but with no special support for Fluent API.

  3. As AEM 6.5/AEMaaCS supports Java 11 one can also leverage the Java Http Client, but there is no OSGi configuration support for it.