@Test(groups = {"online", "default_provider"})
  public void testConfigProxy()
      throws IOException, InterruptedException, ExecutionException, TimeoutException {
    AsyncHttpClientConfig.Builder b = new AsyncHttpClientConfig.Builder();
    b.setFollowRedirects(true);

    ProxyServer ps = new ProxyServer(ProxyServer.Protocol.HTTPS, "127.0.0.1", port1);
    b.setProxyServer(ps);

    AsyncHttpClientConfig config = b.build();
    AsyncHttpClient asyncHttpClient = getAsyncHttpClient(config);

    RequestBuilder rb = new RequestBuilder("GET").setUrl(getTargetUrl2());
    Future<Response> responseFuture =
        asyncHttpClient.executeRequest(
            rb.build(),
            new AsyncCompletionHandlerBase() {

              public void onThrowable(Throwable t) {
                t.printStackTrace();
                log.debug(t.getMessage(), t);
              }

              @Override
              public Response onCompleted(Response response) throws Exception {
                return response;
              }
            });
    Response r = responseFuture.get();
    assertEquals(r.getStatusCode(), 200);
    assertEquals(r.getHeader("X-Proxy-Connection"), "keep-alive");

    asyncHttpClient.close();
  }
  /**
   * Create an {@link AsyncHttpClientConfig} instance based on the values from {@link
   * RepositorySystemSession}
   *
   * @param session {link RepositorySystemSession}
   * @return a configured instance of
   */
  private AsyncHttpClientConfig createConfig(
      RepositorySystemSession session, RemoteRepository repository, boolean useCompression) {
    AsyncHttpClientConfig.Builder configBuilder = new AsyncHttpClientConfig.Builder();

    String userAgent =
        ConfigUtils.getString(
            session,
            ConfigurationProperties.DEFAULT_USER_AGENT,
            ConfigurationProperties.USER_AGENT);
    if (!StringUtils.isEmpty(userAgent)) {
      configBuilder.setUserAgent(userAgent);
    }
    int connectTimeout =
        ConfigUtils.getInteger(
            session,
            ConfigurationProperties.DEFAULT_CONNECT_TIMEOUT,
            ConfigurationProperties.CONNECT_TIMEOUT);

    configBuilder.setConnectionTimeoutInMs(connectTimeout);
    configBuilder.setCompressionEnabled(useCompression);
    configBuilder.setFollowRedirects(true);
    configBuilder.setRequestTimeoutInMs(
        ConfigUtils.getInteger(
            session,
            ConfigurationProperties.DEFAULT_REQUEST_TIMEOUT,
            ConfigurationProperties.REQUEST_TIMEOUT));

    configBuilder.setProxyServer(getProxy(repository));
    configBuilder.setRealm(getRealm(repository));

    return configBuilder.build();
  }
  public Client create(final OpenOptions options) {
    checkNotNull(options);

    AhcConfig config = new DefaultAhcConfig();
    AsyncHttpClientConfig.Builder builder = config.getAsyncHttpClientConfigBuilder();
    if (options.getUsername() != null && options.getPassword() != null) {
      Realm realm =
          new Realm.RealmBuilder()
              .setScheme(Realm.AuthScheme.BASIC)
              .setUsePreemptiveAuth(
                  true) // FIXME: ATM we must configure preemptive auth, to be replaced by session
                        // token
              .setPrincipal(options.getUsername())
              .setPassword(options.getPassword())
              .build();
      builder.setRealm(realm);
    }

    if (options.getProxyHost() != null) {
      ProxyServer proxyServer =
          new ProxyServer(
              ProxyServer.Protocol.HTTP,
              options.getProxyHost(),
              options.getProxyPort(),
              options.getProxyUsername(),
              options.getProxyPassword());
      builder.setProxyServer(proxyServer);
    }

    config.getClasses().add(JacksonProvider.class);

    AhcHttpClient client = AhcHttpClient.create(config, componentProviderFactory);
    client.setFollowRedirects(options.isFollowRedirects());

    // Last filter added is the first filter invoked
    client.addFilter(new FaultDecodingFilter());
    client.addFilter(new LoggingFilter());

    return client;
  }
  /**
   * @param kbServerUrl Kill Bill url
   * @param username Kill Bill username
   * @param password Kill Bill password
   * @param apiKey Kill Bill api key
   * @param apiSecret Kill Bill api secret
   * @param proxyHost hostname of a proxy server that the client should use
   * @param proxyPort port number of a proxy server that the client should use
   * @param connectTimeOut connect timeout in milliseconds
   * @param readTimeOut read timeout in milliseconds
   * @param requestTimeout request timeout in milliseconds
   */
  public KillBillHttpClient(
      final String kbServerUrl,
      final String username,
      final String password,
      final String apiKey,
      final String apiSecret,
      final String proxyHost,
      final Integer proxyPort,
      final Integer connectTimeOut,
      final Integer readTimeOut,
      final Integer requestTimeout) {
    this.kbServerUrl = kbServerUrl;
    this.username = username;
    this.password = password;
    this.apiKey = apiKey;
    this.apiSecret = apiSecret;

    final AsyncHttpClientConfig.Builder cfg = new AsyncHttpClientConfig.Builder();

    cfg.setConnectTimeout(
        MoreObjects.firstNonNull(connectTimeOut, DEFAULT_HTTP_TIMEOUT_SEC * 1000));
    cfg.setReadTimeout(MoreObjects.firstNonNull(readTimeOut, DEFAULT_HTTP_TIMEOUT_SEC * 1000));
    cfg.setRequestTimeout(
        MoreObjects.firstNonNull(requestTimeout, DEFAULT_HTTP_TIMEOUT_SEC * 1000));
    cfg.setUserAgent(USER_AGENT);

    if (proxyHost != null && proxyPort != null) {
      final ProxyServer proxyServer = new ProxyServer(proxyHost, proxyPort);
      cfg.setProxyServer(proxyServer);
    }

    this.httpClient = new AsyncHttpClient(cfg.build());

    mapper = new ObjectMapper();
    mapper.registerModule(new JodaModule());
  }