Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

import java.io.IOException;
import java.net.URISyntaxException;
import java.util.concurrent.locks.ReentrantLock;

import org.apache.hc.client5.http.auth.AuthCache;
import org.apache.hc.client5.http.auth.AuthScope;
Expand All @@ -36,15 +37,21 @@
import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
import org.apache.hc.client5.http.config.ConnectionConfig;
import org.apache.hc.client5.http.cookie.CookieStore;
import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
import org.apache.hc.client5.http.impl.async.HttpAsyncClientBuilder;
import org.apache.hc.client5.http.impl.auth.BasicAuthCache;
import org.apache.hc.client5.http.impl.auth.BasicCredentialsProvider;
import org.apache.hc.client5.http.impl.auth.BasicScheme;
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
import org.apache.hc.client5.http.impl.compat.ClassicToAsyncAdaptor;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
import org.apache.hc.client5.http.protocol.HttpClientContext;
import org.apache.hc.core5.annotation.Experimental;
import org.apache.hc.core5.http.HttpHost;
import org.apache.hc.core5.util.TimeValue;
import org.apache.hc.core5.util.Timeout;

/**
* Executor for {@link Request}s.
Expand All @@ -56,30 +63,82 @@
*/
public class Executor {

final static CloseableHttpClient CLIENT;
private static final ReentrantLock LOCK = new ReentrantLock();
private static volatile CloseableHttpClient CLIENT;
private static volatile CloseableHttpClient ASYNC_CLIENT;

static {
CLIENT = HttpClientBuilder.create()
.setConnectionManager(PoolingHttpClientConnectionManagerBuilder.create()
static CloseableHttpClient GET_CLASSIC_CLIENT() {
final CloseableHttpClient client = CLIENT;
if (client != null) {
return client;
}
LOCK.lock();
try {
if (CLIENT == null) {
CLIENT = HttpClientBuilder.create()
.setConnectionManager(PoolingHttpClientConnectionManagerBuilder.create()
.useSystemProperties()
.setMaxConnPerRoute(100)
.setMaxConnTotal(200)
.setDefaultConnectionConfig(ConnectionConfig.custom()
.setValidateAfterInactivity(TimeValue.ofSeconds(10))
.build())
.build())
.useSystemProperties()
.setMaxConnPerRoute(100)
.setMaxConnTotal(200)
.setDefaultConnectionConfig(ConnectionConfig.custom()
.setValidateAfterInactivity(TimeValue.ofSeconds(10))
.evictExpiredConnections()
.evictIdleConnections(TimeValue.ofMinutes(1))
.build();
}
return CLIENT;
} finally {
LOCK.unlock();
}
}

static CloseableHttpClient GET_ASYNC_CLIENT() {
final CloseableHttpClient client = ASYNC_CLIENT;
if (client != null) {
return client;
}
LOCK.lock();
try {
if (ASYNC_CLIENT == null) {
ASYNC_CLIENT = new ClassicToAsyncAdaptor(HttpAsyncClientBuilder.create()
.setConnectionManager(PoolingAsyncClientConnectionManagerBuilder.create()
.useSystemProperties()
.setMaxConnPerRoute(100)
.setMaxConnTotal(200)
.setMessageMultiplexing(true)
.setDefaultConnectionConfig(ConnectionConfig.custom()
.setValidateAfterInactivity(TimeValue.ofSeconds(10))
.build())
.build())
.build())
.useSystemProperties()
.evictExpiredConnections()
.evictIdleConnections(TimeValue.ofMinutes(1))
.build();
.useSystemProperties()
.evictExpiredConnections()
.evictIdleConnections(TimeValue.ofMinutes(1))
.build(), Timeout.ofMinutes(5));
}
return ASYNC_CLIENT;
} finally {
LOCK.unlock();
}
}

public static Executor newInstance() {
return new Executor(CLIENT);
return new Executor(GET_CLASSIC_CLIENT());
}

public static Executor newInstance(final CloseableHttpClient httpclient) {
return new Executor(httpclient != null ? httpclient : CLIENT);
return new Executor(httpclient != null ? httpclient : GET_CLASSIC_CLIENT());
}

/**
* This feature is considered experimental and may be discontinued in the future.
* @since 5.5
*/
@Experimental
public static Executor newInstance(final CloseableHttpAsyncClient httpclient) {
return new Executor(httpclient != null ? new ClassicToAsyncAdaptor(httpclient, Timeout.ofMinutes(5)) : GET_ASYNC_CLIENT());
}

private final CloseableHttpClient httpclient;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
import org.apache.hc.client5.http.protocol.HttpClientContext;
import org.apache.hc.client5.http.utils.DateUtils;
import org.apache.hc.core5.annotation.Experimental;
import org.apache.hc.core5.http.ClassicHttpRequest;
import org.apache.hc.core5.http.ClassicHttpResponse;
import org.apache.hc.core5.http.ContentType;
Expand Down Expand Up @@ -202,7 +203,20 @@ ClassicHttpResponse internalExecute(
}

public Response execute() throws IOException {
return execute(Executor.CLIENT);
return execute(Executor.GET_CLASSIC_CLIENT());
}

/**
* Execute the request using an HTTP/2 capable engine. The exact protocol version
* will still have to be negotiated by individual connections.
* <p>
* This feature is considered experimental and may be discontinued in the future.
*
* @since 5.5
*/
@Experimental
public Response executeHttp2() throws IOException {
return execute(Executor.GET_ASYNC_CLIENT());
}

public Response execute(final CloseableHttpClient client) throws IOException {
Expand Down