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

com.adobe.target.edge.client.http.ApacheClientFactory Maven / Gradle / Ivy

There is a newer version: 2.6.1
Show newest version
/*
 * Copyright 2023 Adobe. All rights reserved.
 * This file is licensed to you under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License. You may obtain a copy
 * of the License at http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under
 * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
 * OF ANY KIND, either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
package com.adobe.target.edge.client.http;

import com.adobe.target.edge.client.ClientConfig;
import com.adobe.target.edge.client.exception.TargetClientException;
import kong.unirest.Config;
import kong.unirest.Proxy;
import kong.unirest.apache.ApacheAsyncClient;
import kong.unirest.apache.ApacheClient;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.HttpClient;
import org.apache.http.client.RedirectStrategy;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
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 org.apache.http.nio.conn.NoopIOSessionStrategy;
import org.apache.http.nio.conn.SchemeIOSessionStrategy;
import org.apache.http.nio.conn.ssl.SSLIOSessionStrategy;
import org.apache.http.protocol.HttpContext;

import java.util.concurrent.TimeUnit;

public class ApacheClientFactory {
  static class ApacheNoRedirectStrategy implements RedirectStrategy {
    @Override
    public boolean isRedirected(HttpRequest request, HttpResponse response, HttpContext context) {
      return false;
    }

    @Override
    public HttpUriRequest getRedirect(HttpRequest request, HttpResponse response, HttpContext context) {
      return null;
    }
  }

  public static ApacheClient initializeSyncClient(ClientConfig clientConfig, Config config) {
    PoolingHttpClientConnectionManager manager = createConnectionManager(clientConfig, config);
    HttpClient newClient = createCustomClient(clientConfig, config, manager);
    return new ApacheClient(newClient, config, manager);
  }

  public static ApacheAsyncClient initializeAsyncClient(ClientConfig clientConfig, Config config) {
    ApacheAsyncClient client;
    try {
      PoolingNHttpClientConnectionManager manager = createConnectionManager(config);
      TargetAsyncIdleConnectionMonitorThread monitor = new TargetAsyncIdleConnectionMonitorThread(manager, clientConfig);
      CloseableHttpAsyncClient asyncClient = createCustomClient(config, manager);
      asyncClient.start();
      monitor.tryStart();
      client = new ApacheAsyncClient(asyncClient, config, manager, monitor);
    } catch (Exception e) {
      throw new TargetClientException("Error occurred while initializing ApacheAsyncClient", e);
    }
    return client;
  }

  private static RequestConfig toRequestConfig(Config config) {
    HttpHost proxy = toApacheProxy(config.getProxy());
    return RequestConfig.custom()
      .setConnectTimeout(config.getConnectionTimeout())
      .setSocketTimeout(config.getSocketTimeout())
      .setConnectionRequestTimeout(config.getSocketTimeout())
      .setProxy(proxy)
      .build();
  }

  private static CredentialsProvider toApacheCreds(Proxy proxy) {
    if (proxy != null && proxy.isAuthenticated()) {
      CredentialsProvider proxyCredentials = new BasicCredentialsProvider();
      proxyCredentials.setCredentials(new AuthScope(proxy.getHost(), proxy.getPort()),
        new UsernamePasswordCredentials(proxy.getUsername(), proxy.getPassword()));
      return proxyCredentials;
    }
    return null;
  }

  private static PoolingHttpClientConnectionManager createConnectionManager(ClientConfig clientConfig, Config config) {
    PoolingHttpClientConnectionManager manager = new PoolingHttpClientConnectionManager(createDefaultSyncRegistry(),
      null, null, null,
      config.getTTL(), TimeUnit.MILLISECONDS);

    manager.setMaxTotal(config.getMaxConnections());
    manager.setDefaultMaxPerRoute(config.getMaxPerRoutes());
    manager.setValidateAfterInactivity(clientConfig.getIdleConnectionValidationMs());

    return manager;
  }

  private static HttpClient createCustomClient(ClientConfig clientConfig, Config config, PoolingHttpClientConnectionManager manager) {
    HttpClientBuilder cb = HttpClients.custom()
      .setDefaultRequestConfig(toRequestConfig(config))
      .setDefaultCredentialsProvider(toApacheCreds(config.getProxy()))
      .setConnectionManager(manager)
      .evictIdleConnections(clientConfig.getEvictIdleConnectionsAfterSecs(), TimeUnit.SECONDS)
      .useSystemProperties();

    setOptions(cb, config);
    return cb.build();
  }

  private static Registry createDefaultSyncRegistry() {
    return RegistryBuilder.create()
      .register("http", PlainConnectionSocketFactory.getSocketFactory())
      .register("https", SSLConnectionSocketFactory.getSocketFactory())
      .build();
  }

  private static HttpHost toApacheProxy(Proxy proxy){
    if (proxy == null){
      return null;
    }
    return new HttpHost(proxy.getHost(), proxy.getPort());
  }

  private static void setOptions(HttpClientBuilder cb, Config config) {
    if (!config.isAutomaticRetries()) {
      cb.disableAutomaticRetries();
    }
    if (!config.isRequestCompressionOn()) {
      cb.disableContentCompression();
    }
    if (config.useSystemProperties()) {
      cb.useSystemProperties();
    }
    if (!config.getFollowRedirects()) {
      cb.disableRedirectHandling();
    }
    if (!config.getEnabledCookieManagement()) {
      cb.disableCookieManagement();
    }
    config.getInterceptor().stream().forEach(cb::addInterceptorFirst);
  }

  private static PoolingNHttpClientConnectionManager createConnectionManager(Config config) throws Exception {
    PoolingNHttpClientConnectionManager manager = new PoolingNHttpClientConnectionManager(new DefaultConnectingIOReactor(),
      null,
      createDefaultAsyncRegistry(),
      null,
      null,
      config.getTTL(), TimeUnit.MILLISECONDS);

    manager.setMaxTotal(config.getMaxConnections());
    manager.setDefaultMaxPerRoute(config.getMaxPerRoutes());

    return manager;
  }

  private static CloseableHttpAsyncClient createCustomClient(Config config, PoolingNHttpClientConnectionManager manager) {
    HttpAsyncClientBuilder ab = HttpAsyncClientBuilder.create()
      .setDefaultRequestConfig(toRequestConfig(config))
      .setConnectionManager(manager)
      .setDefaultCredentialsProvider(toApacheCreds(config.getProxy()))
      .useSystemProperties();

    setOptions(ab, config);

    return ab.build();
  }

  private static Registry createDefaultAsyncRegistry() {
    return RegistryBuilder.create()
      .register("http", NoopIOSessionStrategy.INSTANCE)
      .register("https", SSLIOSessionStrategy.getDefaultStrategy())
      .build();
  }

  private static void setOptions(HttpAsyncClientBuilder ab, Config config) {
    if (config.useSystemProperties()) {
      ab.useSystemProperties();
    }
    if (!config.getFollowRedirects()) {
      ab.setRedirectStrategy(new ApacheNoRedirectStrategy());
    }
    if (!config.getEnabledCookieManagement()) {
      ab.disableCookieManagement();
    }
    config.getInterceptor().forEach(ab::addInterceptorFirst);
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy