Redesign of classic and asynchronous connection manager APIs
This commit is contained in:
parent
a65c8e9e1a
commit
d2b3385ba2
|
@ -27,7 +27,6 @@
|
|||
|
||||
package org.apache.hc.client5.testing.sync;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
|
@ -35,10 +34,14 @@ import org.apache.hc.client5.http.HttpRoute;
|
|||
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
|
||||
import org.apache.hc.client5.http.io.ConnectionEndpoint;
|
||||
import org.apache.hc.client5.http.io.LeaseRequest;
|
||||
import org.apache.hc.client5.http.socket.ConnectionSocketFactory;
|
||||
import org.apache.hc.client5.http.socket.PlainConnectionSocketFactory;
|
||||
import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory;
|
||||
import org.apache.hc.core5.http.ClassicHttpRequest;
|
||||
import org.apache.hc.core5.http.ClassicHttpResponse;
|
||||
import org.apache.hc.core5.http.HttpHost;
|
||||
import org.apache.hc.core5.http.HttpStatus;
|
||||
import org.apache.hc.core5.http.config.RegistryBuilder;
|
||||
import org.apache.hc.core5.http.impl.io.HttpRequestExecutor;
|
||||
import org.apache.hc.core5.http.message.BasicClassicHttpRequest;
|
||||
import org.apache.hc.core5.http.protocol.BasicHttpContext;
|
||||
|
@ -48,6 +51,8 @@ import org.apache.hc.core5.http.protocol.HttpProcessor;
|
|||
import org.apache.hc.core5.http.protocol.RequestConnControl;
|
||||
import org.apache.hc.core5.http.protocol.RequestContent;
|
||||
import org.apache.hc.core5.http.protocol.RequestTargetHost;
|
||||
import org.apache.hc.core5.pool.PoolConcurrencyPolicy;
|
||||
import org.apache.hc.core5.pool.PoolReusePolicy;
|
||||
import org.apache.hc.core5.util.TimeValue;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
@ -220,21 +225,18 @@ public class TestConnectionManagement extends LocalServerTestBase {
|
|||
final ConnectionEndpoint endpoint1 = leaseRequest1.get(0, TimeUnit.MILLISECONDS);
|
||||
this.connManager.connect(endpoint1, TimeValue.NEG_ONE_MILLISECONDS, context);
|
||||
|
||||
Assert.assertEquals(Collections.singleton(route), this.connManager.getRoutes());
|
||||
Assert.assertEquals(1, this.connManager.getTotalStats().getLeased());
|
||||
Assert.assertEquals(1, this.connManager.getStats(route).getLeased());
|
||||
|
||||
this.connManager.release(endpoint1, null, TimeValue.ofMillis(100));
|
||||
|
||||
// Released, still active.
|
||||
Assert.assertEquals(Collections.singleton(route), this.connManager.getRoutes());
|
||||
Assert.assertEquals(1, this.connManager.getTotalStats().getAvailable());
|
||||
Assert.assertEquals(1, this.connManager.getStats(route).getAvailable());
|
||||
|
||||
this.connManager.closeExpired();
|
||||
|
||||
// Time has not expired yet.
|
||||
Assert.assertEquals(Collections.singleton(route), this.connManager.getRoutes());
|
||||
Assert.assertEquals(1, this.connManager.getTotalStats().getAvailable());
|
||||
Assert.assertEquals(1, this.connManager.getStats(route).getAvailable());
|
||||
|
||||
|
@ -243,7 +245,6 @@ public class TestConnectionManagement extends LocalServerTestBase {
|
|||
this.connManager.closeExpired();
|
||||
|
||||
// Time expired now, connections are destroyed.
|
||||
Assert.assertEquals(Collections.emptySet(), this.connManager.getRoutes());
|
||||
Assert.assertEquals(0, this.connManager.getTotalStats().getAvailable());
|
||||
Assert.assertEquals(0, this.connManager.getStats(route).getAvailable());
|
||||
|
||||
|
@ -253,7 +254,14 @@ public class TestConnectionManagement extends LocalServerTestBase {
|
|||
@Test
|
||||
public void testCloseExpiredTTLConnections() throws Exception {
|
||||
|
||||
this.connManager = new PoolingHttpClientConnectionManager(TimeValue.ofMillis(100));
|
||||
this.connManager = new PoolingHttpClientConnectionManager(
|
||||
RegistryBuilder.<ConnectionSocketFactory>create()
|
||||
.register("http", PlainConnectionSocketFactory.getSocketFactory())
|
||||
.register("https", SSLConnectionSocketFactory.getSocketFactory())
|
||||
.build(),
|
||||
PoolConcurrencyPolicy.STRICT,
|
||||
PoolReusePolicy.LIFO,
|
||||
TimeValue.ofMillis(100));
|
||||
this.clientBuilder.setConnectionManager(this.connManager);
|
||||
|
||||
this.connManager.setMaxTotal(1);
|
||||
|
@ -266,21 +274,18 @@ public class TestConnectionManagement extends LocalServerTestBase {
|
|||
final ConnectionEndpoint endpoint1 = leaseRequest1.get(0, TimeUnit.MILLISECONDS);
|
||||
this.connManager.connect(endpoint1, TimeValue.NEG_ONE_MILLISECONDS, context);
|
||||
|
||||
Assert.assertEquals(Collections.singleton(route), this.connManager.getRoutes());
|
||||
Assert.assertEquals(1, this.connManager.getTotalStats().getLeased());
|
||||
Assert.assertEquals(1, this.connManager.getStats(route).getLeased());
|
||||
// Release, let remain idle for forever
|
||||
this.connManager.release(endpoint1, null, TimeValue.NEG_ONE_MILLISECONDS);
|
||||
|
||||
// Released, still active.
|
||||
Assert.assertEquals(Collections.singleton(route), this.connManager.getRoutes());
|
||||
Assert.assertEquals(1, this.connManager.getTotalStats().getAvailable());
|
||||
Assert.assertEquals(1, this.connManager.getStats(route).getAvailable());
|
||||
|
||||
this.connManager.closeExpired();
|
||||
|
||||
// Time has not expired yet.
|
||||
Assert.assertEquals(Collections.singleton(route), this.connManager.getRoutes());
|
||||
Assert.assertEquals(1, this.connManager.getTotalStats().getAvailable());
|
||||
Assert.assertEquals(1, this.connManager.getStats(route).getAvailable());
|
||||
|
||||
|
@ -289,7 +294,6 @@ public class TestConnectionManagement extends LocalServerTestBase {
|
|||
this.connManager.closeExpired();
|
||||
|
||||
// TTL expired now, connections are destroyed.
|
||||
Assert.assertEquals(Collections.emptySet(), this.connManager.getRoutes());
|
||||
Assert.assertEquals(0, this.connManager.getTotalStats().getAvailable());
|
||||
Assert.assertEquals(0, this.connManager.getStats(route).getAvailable());
|
||||
|
||||
|
|
|
@ -78,6 +78,8 @@ import org.apache.hc.core5.http.io.entity.EntityUtils;
|
|||
import org.apache.hc.core5.http.message.BasicHeader;
|
||||
import org.apache.hc.core5.http.message.BasicLineParser;
|
||||
import org.apache.hc.core5.http.message.LineParser;
|
||||
import org.apache.hc.core5.pool.PoolConcurrencyPolicy;
|
||||
import org.apache.hc.core5.pool.PoolReusePolicy;
|
||||
import org.apache.hc.core5.ssl.SSLContexts;
|
||||
import org.apache.hc.core5.util.CharArrayBuffer;
|
||||
import org.apache.hc.core5.util.TimeValue;
|
||||
|
@ -166,7 +168,8 @@ public class ClientConfiguration {
|
|||
|
||||
// Create a connection manager with custom configuration.
|
||||
final PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(
|
||||
socketFactoryRegistry, connFactory, dnsResolver);
|
||||
socketFactoryRegistry, PoolConcurrencyPolicy.STRICT, PoolReusePolicy.LIFO, TimeValue.ofMinutes(5),
|
||||
null, dnsResolver, null);
|
||||
|
||||
// Create socket configuration
|
||||
final SocketConfig socketConfig = SocketConfig.custom()
|
||||
|
|
|
@ -49,6 +49,7 @@ import org.apache.hc.core5.http.impl.io.HttpRequestExecutor;
|
|||
import org.apache.hc.core5.io.ShutdownType;
|
||||
import org.apache.hc.core5.util.Args;
|
||||
import org.apache.hc.core5.util.TimeValue;
|
||||
import org.apache.hc.core5.util.Timeout;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
class ExecRuntimeImpl implements ExecRuntime, Cancellable {
|
||||
|
@ -92,7 +93,9 @@ class ExecRuntimeImpl implements ExecRuntime, Cancellable {
|
|||
public void acquireConnection(final HttpRoute route, final Object object, final HttpClientContext context) throws IOException {
|
||||
Args.notNull(route, "Route");
|
||||
if (endpointRef.get() == null) {
|
||||
final LeaseRequest connRequest = manager.lease(route, object);
|
||||
final RequestConfig requestConfig = context.getRequestConfig();
|
||||
final Timeout requestTimeout = requestConfig.getConnectionRequestTimeout();
|
||||
final LeaseRequest connRequest = manager.lease(route, requestTimeout, object);
|
||||
state = object;
|
||||
if (cancellableAware != null) {
|
||||
if (cancellableAware.isCancelled()) {
|
||||
|
@ -102,9 +105,7 @@ class ExecRuntimeImpl implements ExecRuntime, Cancellable {
|
|||
cancellableAware.setCancellable(connRequest);
|
||||
}
|
||||
try {
|
||||
final RequestConfig requestConfig = context.getRequestConfig();
|
||||
final TimeValue timeout = requestConfig.getConnectionRequestTimeout();
|
||||
final ConnectionEndpoint connectionEndpoint = connRequest.get(timeout.getDuration(), timeout.getTimeUnit());
|
||||
final ConnectionEndpoint connectionEndpoint = connRequest.get(requestTimeout.getDuration(), requestTimeout.getTimeUnit());
|
||||
endpointRef.set(connectionEndpoint);
|
||||
reusable = connectionEndpoint.isConnected();
|
||||
if (cancellableAware != null) {
|
||||
|
|
|
@ -65,6 +65,7 @@ import org.apache.hc.core5.util.Args;
|
|||
import org.apache.hc.core5.util.Asserts;
|
||||
import org.apache.hc.core5.util.LangUtils;
|
||||
import org.apache.hc.core5.util.TimeValue;
|
||||
import org.apache.hc.core5.util.Timeout;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
|
@ -181,8 +182,12 @@ public class BasicHttpClientConnectionManager implements HttpClientConnectionMan
|
|||
this.socketConfig = socketConfig != null ? socketConfig : SocketConfig.DEFAULT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LeaseRequest lease(final HttpRoute route, final Object state) {
|
||||
return lease(route, Timeout.DISABLED, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LeaseRequest lease(final HttpRoute route, final Timeout requestTimeout, final Object state) {
|
||||
return new LeaseRequest() {
|
||||
|
||||
@Override
|
||||
|
|
|
@ -47,6 +47,7 @@ import org.apache.hc.client5.http.protocol.HttpClientContext;
|
|||
import org.apache.hc.client5.http.socket.ConnectionSocketFactory;
|
||||
import org.apache.hc.client5.http.socket.LayeredConnectionSocketFactory;
|
||||
import org.apache.hc.core5.annotation.Contract;
|
||||
import org.apache.hc.core5.annotation.Internal;
|
||||
import org.apache.hc.core5.annotation.ThreadingBehavior;
|
||||
import org.apache.hc.core5.http.ConnectionClosedException;
|
||||
import org.apache.hc.core5.http.HttpHost;
|
||||
|
@ -65,6 +66,7 @@ import org.apache.logging.log4j.Logger;
|
|||
*
|
||||
* @since 4.4
|
||||
*/
|
||||
@Internal
|
||||
@Contract(threading = ThreadingBehavior.IMMUTABLE_CONDITIONAL)
|
||||
public class DefaultHttpClientConnectionOperator implements HttpClientConnectionOperator {
|
||||
|
||||
|
|
|
@ -56,9 +56,10 @@ import org.apache.logging.log4j.Logger;
|
|||
|
||||
/**
|
||||
* Default {@link ManagedHttpClientConnection} implementation.
|
||||
*
|
||||
* @since 4.3
|
||||
*/
|
||||
public class DefaultManagedHttpClientConnection
|
||||
final class DefaultManagedHttpClientConnection
|
||||
extends DefaultBHttpClientConnection implements ManagedHttpClientConnection, Identifiable {
|
||||
|
||||
private final Logger log = LogManager.getLogger(DefaultManagedHttpClientConnection.class);
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
package org.apache.hc.client5.http.impl.io;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
@ -49,13 +48,12 @@ import org.apache.hc.client5.http.socket.ConnectionSocketFactory;
|
|||
import org.apache.hc.client5.http.socket.PlainConnectionSocketFactory;
|
||||
import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory;
|
||||
import org.apache.hc.core5.annotation.Contract;
|
||||
import org.apache.hc.core5.annotation.Internal;
|
||||
import org.apache.hc.core5.annotation.ThreadingBehavior;
|
||||
import org.apache.hc.core5.function.Callback;
|
||||
import org.apache.hc.core5.http.ClassicHttpRequest;
|
||||
import org.apache.hc.core5.http.ClassicHttpResponse;
|
||||
import org.apache.hc.core5.http.HttpException;
|
||||
import org.apache.hc.core5.http.HttpHost;
|
||||
import org.apache.hc.core5.http.config.Lookup;
|
||||
import org.apache.hc.core5.http.config.Registry;
|
||||
import org.apache.hc.core5.http.config.RegistryBuilder;
|
||||
import org.apache.hc.core5.http.config.SocketConfig;
|
||||
|
@ -64,6 +62,9 @@ import org.apache.hc.core5.http.io.HttpConnectionFactory;
|
|||
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||
import org.apache.hc.core5.io.ShutdownType;
|
||||
import org.apache.hc.core5.pool.ConnPoolControl;
|
||||
import org.apache.hc.core5.pool.LaxConnPool;
|
||||
import org.apache.hc.core5.pool.ManagedConnPool;
|
||||
import org.apache.hc.core5.pool.PoolConcurrencyPolicy;
|
||||
import org.apache.hc.core5.pool.PoolEntry;
|
||||
import org.apache.hc.core5.pool.PoolReusePolicy;
|
||||
import org.apache.hc.core5.pool.PoolStats;
|
||||
|
@ -71,6 +72,7 @@ import org.apache.hc.core5.pool.StrictConnPool;
|
|||
import org.apache.hc.core5.util.Args;
|
||||
import org.apache.hc.core5.util.Asserts;
|
||||
import org.apache.hc.core5.util.TimeValue;
|
||||
import org.apache.hc.core5.util.Timeout;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
|
@ -107,95 +109,113 @@ public class PoolingHttpClientConnectionManager
|
|||
public static final int DEFAULT_MAX_TOTAL_CONNECTIONS = 25;
|
||||
public static final int DEFAULT_MAX_CONNECTIONS_PER_ROUTE = 5;
|
||||
|
||||
private final StrictConnPool<HttpRoute, ManagedHttpClientConnection> pool;
|
||||
private final HttpConnectionFactory<ManagedHttpClientConnection> connFactory;
|
||||
private final HttpClientConnectionOperator connectionOperator;
|
||||
private final ManagedConnPool<HttpRoute, ManagedHttpClientConnection> pool;
|
||||
private final HttpConnectionFactory<ManagedHttpClientConnection> connFactory;
|
||||
private final AtomicBoolean closed;
|
||||
|
||||
private volatile SocketConfig defaultSocketConfig;
|
||||
private volatile TimeValue validateAfterInactivity;
|
||||
|
||||
private static Registry<ConnectionSocketFactory> getDefaultRegistry() {
|
||||
return RegistryBuilder.<ConnectionSocketFactory>create()
|
||||
public PoolingHttpClientConnectionManager() {
|
||||
this(RegistryBuilder.<ConnectionSocketFactory>create()
|
||||
.register("http", PlainConnectionSocketFactory.getSocketFactory())
|
||||
.register("https", SSLConnectionSocketFactory.getSocketFactory())
|
||||
.build();
|
||||
}
|
||||
|
||||
public PoolingHttpClientConnectionManager() {
|
||||
this(getDefaultRegistry());
|
||||
}
|
||||
|
||||
public PoolingHttpClientConnectionManager(final TimeValue timeToLive) {
|
||||
this(getDefaultRegistry(), null, null ,null, PoolReusePolicy.LIFO, timeToLive);
|
||||
.build());
|
||||
}
|
||||
|
||||
public PoolingHttpClientConnectionManager(
|
||||
final Registry<ConnectionSocketFactory> socketFactoryRegistry) {
|
||||
this(socketFactoryRegistry, null, null);
|
||||
}
|
||||
|
||||
public PoolingHttpClientConnectionManager(
|
||||
final Registry<ConnectionSocketFactory> socketFactoryRegistry,
|
||||
final DnsResolver dnsResolver) {
|
||||
this(socketFactoryRegistry, null, dnsResolver);
|
||||
this(socketFactoryRegistry, null);
|
||||
}
|
||||
|
||||
public PoolingHttpClientConnectionManager(
|
||||
final Registry<ConnectionSocketFactory> socketFactoryRegistry,
|
||||
final HttpConnectionFactory<ManagedHttpClientConnection> connFactory) {
|
||||
this(socketFactoryRegistry, connFactory, null);
|
||||
this(socketFactoryRegistry, PoolConcurrencyPolicy.STRICT, TimeValue.NEG_ONE_MILLISECONDS, connFactory);
|
||||
}
|
||||
|
||||
public PoolingHttpClientConnectionManager(
|
||||
final Registry<ConnectionSocketFactory> socketFactoryRegistry,
|
||||
final PoolConcurrencyPolicy poolConcurrencyPolicy,
|
||||
final TimeValue timeToLive,
|
||||
final HttpConnectionFactory<ManagedHttpClientConnection> connFactory) {
|
||||
this(getDefaultRegistry(), connFactory, null);
|
||||
this(socketFactoryRegistry, poolConcurrencyPolicy, PoolReusePolicy.LIFO, timeToLive, connFactory);
|
||||
}
|
||||
|
||||
public PoolingHttpClientConnectionManager(
|
||||
final Registry<ConnectionSocketFactory> socketFactoryRegistry,
|
||||
final HttpConnectionFactory<ManagedHttpClientConnection> connFactory,
|
||||
final DnsResolver dnsResolver) {
|
||||
this(socketFactoryRegistry, connFactory, null, dnsResolver, PoolReusePolicy.LIFO, TimeValue.NEG_ONE_MILLISECONDS);
|
||||
final PoolConcurrencyPolicy poolConcurrencyPolicy,
|
||||
final PoolReusePolicy poolReusePolicy,
|
||||
final TimeValue timeToLive) {
|
||||
this(socketFactoryRegistry, poolConcurrencyPolicy, poolReusePolicy, timeToLive, null);
|
||||
}
|
||||
|
||||
public PoolingHttpClientConnectionManager(
|
||||
final Registry<ConnectionSocketFactory> socketFactoryRegistry,
|
||||
final HttpConnectionFactory<ManagedHttpClientConnection> connFactory,
|
||||
final PoolConcurrencyPolicy poolConcurrencyPolicy,
|
||||
final PoolReusePolicy poolReusePolicy,
|
||||
final TimeValue timeToLive,
|
||||
final HttpConnectionFactory<ManagedHttpClientConnection> connFactory) {
|
||||
this(socketFactoryRegistry, poolConcurrencyPolicy, poolReusePolicy, timeToLive, null, null, connFactory);
|
||||
}
|
||||
|
||||
public PoolingHttpClientConnectionManager(
|
||||
final Registry<ConnectionSocketFactory> socketFactoryRegistry,
|
||||
final PoolConcurrencyPolicy poolConcurrencyPolicy,
|
||||
final PoolReusePolicy poolReusePolicy,
|
||||
final TimeValue timeToLive,
|
||||
final SchemePortResolver schemePortResolver,
|
||||
final DnsResolver dnsResolver,
|
||||
final PoolReusePolicy poolReusePolicy,
|
||||
final TimeValue timeToLive) {
|
||||
final HttpConnectionFactory<ManagedHttpClientConnection> connFactory) {
|
||||
this(new DefaultHttpClientConnectionOperator(socketFactoryRegistry, schemePortResolver, dnsResolver),
|
||||
connFactory, poolReusePolicy, timeToLive);
|
||||
poolConcurrencyPolicy,
|
||||
poolReusePolicy,
|
||||
timeToLive,
|
||||
connFactory);
|
||||
}
|
||||
|
||||
public PoolingHttpClientConnectionManager(
|
||||
@Internal
|
||||
protected PoolingHttpClientConnectionManager(
|
||||
final HttpClientConnectionOperator httpClientConnectionOperator,
|
||||
final HttpConnectionFactory<ManagedHttpClientConnection> connFactory,
|
||||
final PoolConcurrencyPolicy poolConcurrencyPolicy,
|
||||
final PoolReusePolicy poolReusePolicy,
|
||||
final TimeValue timeToLive) {
|
||||
final TimeValue timeToLive,
|
||||
final HttpConnectionFactory<ManagedHttpClientConnection> connFactory) {
|
||||
super();
|
||||
this.connectionOperator = Args.notNull(httpClientConnectionOperator, "Connection operator");
|
||||
switch (poolConcurrencyPolicy != null ? poolConcurrencyPolicy : PoolConcurrencyPolicy.STRICT) {
|
||||
case STRICT:
|
||||
this.pool = new StrictConnPool<>(
|
||||
DEFAULT_MAX_CONNECTIONS_PER_ROUTE,
|
||||
DEFAULT_MAX_TOTAL_CONNECTIONS,
|
||||
timeToLive,
|
||||
poolReusePolicy,
|
||||
null);
|
||||
break;
|
||||
case LAX:
|
||||
this.pool = new LaxConnPool<>(
|
||||
DEFAULT_MAX_CONNECTIONS_PER_ROUTE,
|
||||
timeToLive,
|
||||
poolReusePolicy,
|
||||
null);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unexpected PoolConcurrencyPolicy value: " + poolConcurrencyPolicy);
|
||||
}
|
||||
this.connFactory = connFactory != null ? connFactory : ManagedHttpClientConnectionFactory.INSTANCE;
|
||||
this.pool = new StrictConnPool<>(DEFAULT_MAX_CONNECTIONS_PER_ROUTE, DEFAULT_MAX_TOTAL_CONNECTIONS, timeToLive,
|
||||
poolReusePolicy, null);
|
||||
this.closed = new AtomicBoolean(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Visible for test.
|
||||
*/
|
||||
PoolingHttpClientConnectionManager(
|
||||
final StrictConnPool<HttpRoute, ManagedHttpClientConnection> pool,
|
||||
final Lookup<ConnectionSocketFactory> socketFactoryRegistry,
|
||||
final SchemePortResolver schemePortResolver,
|
||||
final DnsResolver dnsResolver) {
|
||||
@Internal
|
||||
protected PoolingHttpClientConnectionManager(
|
||||
final HttpClientConnectionOperator httpClientConnectionOperator,
|
||||
final ManagedConnPool<HttpRoute, ManagedHttpClientConnection> pool,
|
||||
final HttpConnectionFactory<ManagedHttpClientConnection> connFactory) {
|
||||
super();
|
||||
this.connectionOperator = new DefaultHttpClientConnectionOperator(
|
||||
socketFactoryRegistry, schemePortResolver, dnsResolver);
|
||||
this.connFactory = ManagedHttpClientConnectionFactory.INSTANCE;
|
||||
this.pool = pool;
|
||||
this.connectionOperator = Args.notNull(httpClientConnectionOperator, "Connection operator");
|
||||
this.pool = Args.notNull(pool, "Connection pool");
|
||||
this.connFactory = connFactory != null ? connFactory : ManagedHttpClientConnectionFactory.INSTANCE;
|
||||
this.closed = new AtomicBoolean(false);
|
||||
}
|
||||
|
||||
|
@ -225,15 +245,24 @@ public class PoolingHttpClientConnectionManager
|
|||
}
|
||||
}
|
||||
|
||||
public LeaseRequest lease(final HttpRoute route, final Object state) {
|
||||
return lease(route, Timeout.DISABLED, state);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LeaseRequest lease(
|
||||
final HttpRoute route,
|
||||
final Timeout requestTimeout,
|
||||
final Object state) {
|
||||
Args.notNull(route, "HTTP route");
|
||||
if (this.log.isDebugEnabled()) {
|
||||
this.log.debug("Connection request: " + ConnPoolSupport.formatStats(null, route, state, this.pool));
|
||||
}
|
||||
final Future<PoolEntry<HttpRoute, ManagedHttpClientConnection>> leaseFuture = this.pool.lease(route, state, null);
|
||||
//TODO: fix me.
|
||||
if (log.isWarnEnabled() && Timeout.isPositive(requestTimeout)) {
|
||||
log.warn("Connection request timeout is not supported");
|
||||
}
|
||||
final Future<PoolEntry<HttpRoute, ManagedHttpClientConnection>> leaseFuture = this.pool.lease(route, state, /** requestTimeout, */ null);
|
||||
return new LeaseRequest() {
|
||||
|
||||
private volatile ConnectionEndpoint endpoint;
|
||||
|
@ -391,14 +420,6 @@ public class PoolingHttpClientConnectionManager
|
|||
this.pool.closeExpired();
|
||||
}
|
||||
|
||||
protected void enumAvailable(final Callback<PoolEntry<HttpRoute, ManagedHttpClientConnection>> callback) {
|
||||
this.pool.enumAvailable(callback);
|
||||
}
|
||||
|
||||
protected void enumLeased(final Callback<PoolEntry<HttpRoute, ManagedHttpClientConnection>> callback) {
|
||||
this.pool.enumLeased(callback);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMaxTotal() {
|
||||
return this.pool.getMaxTotal();
|
||||
|
@ -439,13 +460,6 @@ public class PoolingHttpClientConnectionManager
|
|||
return this.pool.getStats(route);
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 4.4
|
||||
*/
|
||||
public Set<HttpRoute> getRoutes() {
|
||||
return this.pool.getRoutes();
|
||||
}
|
||||
|
||||
public SocketConfig getDefaultSocketConfig() {
|
||||
return this.defaultSocketConfig;
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory;
|
|||
import org.apache.hc.core5.http.config.RegistryBuilder;
|
||||
import org.apache.hc.core5.http.config.SocketConfig;
|
||||
import org.apache.hc.core5.http.io.HttpConnectionFactory;
|
||||
import org.apache.hc.core5.pool.PoolConcurrencyPolicy;
|
||||
import org.apache.hc.core5.pool.PoolReusePolicy;
|
||||
import org.apache.hc.core5.util.TimeValue;
|
||||
|
||||
|
@ -72,6 +73,7 @@ public class PoolingHttpClientConnectionManagerBuilder {
|
|||
private LayeredConnectionSocketFactory sslSocketFactory;
|
||||
private SchemePortResolver schemePortResolver;
|
||||
private DnsResolver dnsResolver;
|
||||
private PoolConcurrencyPolicy poolConcurrencyPolicy;
|
||||
private PoolReusePolicy poolReusePolicy;
|
||||
private SocketConfig defaultSocketConfig;
|
||||
|
||||
|
@ -125,6 +127,14 @@ public class PoolingHttpClientConnectionManagerBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns {@link PoolConcurrencyPolicy} value.
|
||||
*/
|
||||
public final PoolingHttpClientConnectionManagerBuilder setPoolConcurrencyPolicy(final PoolConcurrencyPolicy poolConcurrencyPolicy) {
|
||||
this.poolConcurrencyPolicy = poolConcurrencyPolicy;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns {@link PoolReusePolicy} value.
|
||||
*/
|
||||
|
@ -195,11 +205,12 @@ public class PoolingHttpClientConnectionManagerBuilder {
|
|||
SSLConnectionSocketFactory.getSystemSocketFactory() :
|
||||
SSLConnectionSocketFactory.getSocketFactory()))
|
||||
.build(),
|
||||
connectionFactory,
|
||||
poolConcurrencyPolicy,
|
||||
poolReusePolicy,
|
||||
timeToLive != null ? timeToLive : TimeValue.NEG_ONE_MILLISECONDS,
|
||||
schemePortResolver,
|
||||
dnsResolver,
|
||||
poolReusePolicy,
|
||||
timeToLive != null ? timeToLive : TimeValue.NEG_ONE_MILLISECONDS);
|
||||
connectionFactory);
|
||||
poolingmgr.setValidateAfterInactivity(this.validateAfterInactivity);
|
||||
if (defaultSocketConfig != null) {
|
||||
poolingmgr.setDefaultSocketConfig(defaultSocketConfig);
|
||||
|
|
|
@ -41,6 +41,9 @@ import org.apache.hc.client5.http.SchemePortResolver;
|
|||
import org.apache.hc.client5.http.SystemDefaultDnsResolver;
|
||||
import org.apache.hc.client5.http.UnsupportedSchemeException;
|
||||
import org.apache.hc.client5.http.impl.DefaultSchemePortResolver;
|
||||
import org.apache.hc.client5.http.nio.AsyncClientConnectionOperator;
|
||||
import org.apache.hc.client5.http.nio.ManagedAsyncClientConnection;
|
||||
import org.apache.hc.core5.annotation.Internal;
|
||||
import org.apache.hc.core5.concurrent.ComplexFuture;
|
||||
import org.apache.hc.core5.concurrent.FutureCallback;
|
||||
import org.apache.hc.core5.http.HttpHost;
|
||||
|
@ -51,21 +54,28 @@ import org.apache.hc.core5.reactor.IOSession;
|
|||
import org.apache.hc.core5.util.Args;
|
||||
import org.apache.hc.core5.util.TimeValue;
|
||||
|
||||
final class AsyncClientConnectionOperator {
|
||||
/**
|
||||
* Default {@link AsyncClientConnectionOperator} implementation.
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
@Internal
|
||||
final class DefaultAsyncClientConnectionOperator implements AsyncClientConnectionOperator {
|
||||
|
||||
private final SchemePortResolver schemePortResolver;
|
||||
private final DnsResolver dnsResolver;
|
||||
private final Lookup<TlsStrategy> tlsStrategyLookup;
|
||||
|
||||
AsyncClientConnectionOperator(
|
||||
DefaultAsyncClientConnectionOperator(
|
||||
final Lookup<TlsStrategy> tlsStrategyLookup,
|
||||
final SchemePortResolver schemePortResolver,
|
||||
final DnsResolver dnsResolver,
|
||||
final Lookup<TlsStrategy> tlsStrategyLookup) {
|
||||
final DnsResolver dnsResolver) {
|
||||
this.tlsStrategyLookup = Args.notNull(tlsStrategyLookup, "TLS strategy lookup");
|
||||
this.schemePortResolver = schemePortResolver != null ? schemePortResolver : DefaultSchemePortResolver.INSTANCE;
|
||||
this.dnsResolver = dnsResolver != null ? dnsResolver : SystemDefaultDnsResolver.INSTANCE;
|
||||
this.tlsStrategyLookup = tlsStrategyLookup;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Future<ManagedAsyncClientConnection> connect(
|
||||
final ConnectionInitiator connectionInitiator,
|
||||
final HttpHost host,
|
||||
|
@ -108,7 +118,7 @@ final class AsyncClientConnectionOperator {
|
|||
|
||||
@Override
|
||||
public void completed(final IOSession session) {
|
||||
final ManagedAsyncClientConnection connection = new ManagedAsyncClientConnection(session);
|
||||
final DefaultManagedAsyncClientConnection connection = new DefaultManagedAsyncClientConnection(session);
|
||||
if (tlsStrategy != null) {
|
||||
tlsStrategy.upgrade(
|
||||
connection,
|
||||
|
@ -152,6 +162,7 @@ final class AsyncClientConnectionOperator {
|
|||
return future;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void upgrade(final ManagedAsyncClientConnection connection, final HttpHost host, final Object attachment) {
|
||||
final TlsStrategy tlsStrategy = tlsStrategyLookup != null ? tlsStrategyLookup.lookup(host.getSchemeName()) : null;
|
||||
if (tlsStrategy != null) {
|
|
@ -35,6 +35,8 @@ import javax.net.ssl.SSLContext;
|
|||
import javax.net.ssl.SSLSession;
|
||||
|
||||
import org.apache.hc.client5.http.impl.ConnPoolSupport;
|
||||
import org.apache.hc.client5.http.nio.ManagedAsyncClientConnection;
|
||||
import org.apache.hc.core5.annotation.Internal;
|
||||
import org.apache.hc.core5.http.EndpointDetails;
|
||||
import org.apache.hc.core5.http.HttpConnection;
|
||||
import org.apache.hc.core5.http.HttpVersion;
|
||||
|
@ -53,14 +55,20 @@ import org.apache.hc.core5.util.Identifiable;
|
|||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
final class ManagedAsyncClientConnection implements Identifiable, HttpConnection, TransportSecurityLayer {
|
||||
/**
|
||||
* Default {@link ManagedAsyncClientConnection} implementation.
|
||||
*
|
||||
* @since 5.0
|
||||
*/
|
||||
@Internal
|
||||
final class DefaultManagedAsyncClientConnection implements ManagedAsyncClientConnection, Identifiable {
|
||||
|
||||
private final Logger log = LogManager.getLogger(getClass());
|
||||
|
||||
private final IOSession ioSession;
|
||||
private final AtomicBoolean closed;
|
||||
|
||||
public ManagedAsyncClientConnection(final IOSession ioSession) {
|
||||
public DefaultManagedAsyncClientConnection(final IOSession ioSession) {
|
||||
this.ioSession = ioSession;
|
||||
this.closed = new AtomicBoolean();
|
||||
}
|
||||
|
@ -162,6 +170,7 @@ final class ManagedAsyncClientConnection implements Identifiable, HttpConnection
|
|||
return tlsDetails != null ? tlsDetails.getSSLSession() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void submitPriorityCommand(final Command command) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug(getId() + ": priority command " + command);
|
||||
|
@ -169,6 +178,7 @@ final class ManagedAsyncClientConnection implements Identifiable, HttpConnection
|
|||
ioSession.addFirst(command);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void submitCommand(final Command command) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug(getId() + ": command " + command);
|
|
@ -40,8 +40,12 @@ import org.apache.hc.client5.http.SchemePortResolver;
|
|||
import org.apache.hc.client5.http.impl.ConnPoolSupport;
|
||||
import org.apache.hc.client5.http.impl.ConnectionShutdownException;
|
||||
import org.apache.hc.client5.http.nio.AsyncClientConnectionManager;
|
||||
import org.apache.hc.client5.http.nio.AsyncClientConnectionOperator;
|
||||
import org.apache.hc.client5.http.nio.AsyncConnectionEndpoint;
|
||||
import org.apache.hc.client5.http.nio.ManagedAsyncClientConnection;
|
||||
import org.apache.hc.client5.http.ssl.H2TlsStrategy;
|
||||
import org.apache.hc.core5.annotation.Contract;
|
||||
import org.apache.hc.core5.annotation.Internal;
|
||||
import org.apache.hc.core5.annotation.ThreadingBehavior;
|
||||
import org.apache.hc.core5.concurrent.ComplexFuture;
|
||||
import org.apache.hc.core5.concurrent.FutureCallback;
|
||||
|
@ -50,6 +54,7 @@ import org.apache.hc.core5.http.HttpHost;
|
|||
import org.apache.hc.core5.http.HttpVersion;
|
||||
import org.apache.hc.core5.http.ProtocolVersion;
|
||||
import org.apache.hc.core5.http.config.Lookup;
|
||||
import org.apache.hc.core5.http.config.RegistryBuilder;
|
||||
import org.apache.hc.core5.http.nio.AsyncClientExchangeHandler;
|
||||
import org.apache.hc.core5.http.nio.command.ExecutionCommand;
|
||||
import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
|
||||
|
@ -58,6 +63,9 @@ import org.apache.hc.core5.http2.nio.command.PingCommand;
|
|||
import org.apache.hc.core5.http2.nio.support.BasicPingHandler;
|
||||
import org.apache.hc.core5.io.ShutdownType;
|
||||
import org.apache.hc.core5.pool.ConnPoolControl;
|
||||
import org.apache.hc.core5.pool.LaxConnPool;
|
||||
import org.apache.hc.core5.pool.ManagedConnPool;
|
||||
import org.apache.hc.core5.pool.PoolConcurrencyPolicy;
|
||||
import org.apache.hc.core5.pool.PoolEntry;
|
||||
import org.apache.hc.core5.pool.PoolReusePolicy;
|
||||
import org.apache.hc.core5.pool.PoolStats;
|
||||
|
@ -94,20 +102,86 @@ public class PoolingAsyncClientConnectionManager implements AsyncClientConnectio
|
|||
|
||||
private final Logger log = LogManager.getLogger(getClass());
|
||||
|
||||
public static final int DEFAULT_MAX_TOTAL_CONNECTIONS = 25;
|
||||
public static final int DEFAULT_MAX_CONNECTIONS_PER_ROUTE = 5;
|
||||
|
||||
private final ManagedConnPool<HttpRoute, ManagedAsyncClientConnection> pool;
|
||||
private final AsyncClientConnectionOperator connectionOperator;
|
||||
private final StrictConnPool<HttpRoute, ManagedAsyncClientConnection> pool;
|
||||
private final AtomicBoolean closed;
|
||||
|
||||
private volatile TimeValue validateAfterInactivity;
|
||||
|
||||
public PoolingAsyncClientConnectionManager() {
|
||||
this(RegistryBuilder.<TlsStrategy>create()
|
||||
.register("https", H2TlsStrategy.getDefault())
|
||||
.build());
|
||||
}
|
||||
|
||||
public PoolingAsyncClientConnectionManager(final Lookup<TlsStrategy> tlsStrategyLookup) {
|
||||
this(tlsStrategyLookup, PoolConcurrencyPolicy.STRICT, TimeValue.NEG_ONE_MILLISECONDS);
|
||||
}
|
||||
|
||||
public PoolingAsyncClientConnectionManager(
|
||||
final Lookup<TlsStrategy> tlsStrategyLookup,
|
||||
final SchemePortResolver schemePortResolver,
|
||||
final DnsResolver dnsResolver,
|
||||
final PoolConcurrencyPolicy poolConcurrencyPolicy,
|
||||
final TimeValue timeToLive) {
|
||||
this(tlsStrategyLookup, poolConcurrencyPolicy, PoolReusePolicy.LIFO, timeToLive);
|
||||
}
|
||||
|
||||
public PoolingAsyncClientConnectionManager(
|
||||
final Lookup<TlsStrategy> tlsStrategyLookup,
|
||||
final PoolConcurrencyPolicy poolConcurrencyPolicy,
|
||||
final PoolReusePolicy poolReusePolicy,
|
||||
final TimeValue timeToLive) {
|
||||
this(tlsStrategyLookup, poolConcurrencyPolicy, poolReusePolicy, timeToLive, null, null);
|
||||
}
|
||||
|
||||
public PoolingAsyncClientConnectionManager(
|
||||
final Lookup<TlsStrategy> tlsStrategyLookup,
|
||||
final PoolConcurrencyPolicy poolConcurrencyPolicy,
|
||||
final PoolReusePolicy poolReusePolicy,
|
||||
final TimeValue timeToLive,
|
||||
final PoolReusePolicy poolReusePolicy) {
|
||||
this.connectionOperator = new AsyncClientConnectionOperator(schemePortResolver, dnsResolver, tlsStrategyLookup);
|
||||
this.pool = new StrictConnPool<>(20, 50, timeToLive, poolReusePolicy != null ? poolReusePolicy : PoolReusePolicy.LIFO, null);
|
||||
final SchemePortResolver schemePortResolver,
|
||||
final DnsResolver dnsResolver) {
|
||||
this(new DefaultAsyncClientConnectionOperator(tlsStrategyLookup, schemePortResolver, dnsResolver),
|
||||
poolConcurrencyPolicy, poolReusePolicy, timeToLive);
|
||||
}
|
||||
|
||||
@Internal
|
||||
protected PoolingAsyncClientConnectionManager(
|
||||
final AsyncClientConnectionOperator connectionOperator,
|
||||
final PoolConcurrencyPolicy poolConcurrencyPolicy,
|
||||
final PoolReusePolicy poolReusePolicy,
|
||||
final TimeValue timeToLive) {
|
||||
this.connectionOperator = Args.notNull(connectionOperator, "Connection operator");
|
||||
switch (poolConcurrencyPolicy != null ? poolConcurrencyPolicy : PoolConcurrencyPolicy.STRICT) {
|
||||
case STRICT:
|
||||
this.pool = new StrictConnPool<>(
|
||||
DEFAULT_MAX_CONNECTIONS_PER_ROUTE,
|
||||
DEFAULT_MAX_TOTAL_CONNECTIONS,
|
||||
timeToLive,
|
||||
poolReusePolicy,
|
||||
null);
|
||||
break;
|
||||
case LAX:
|
||||
this.pool = new LaxConnPool<>(
|
||||
DEFAULT_MAX_CONNECTIONS_PER_ROUTE,
|
||||
timeToLive,
|
||||
poolReusePolicy,
|
||||
null);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unexpected PoolConcurrencyPolicy value: " + poolConcurrencyPolicy);
|
||||
}
|
||||
this.closed = new AtomicBoolean(false);
|
||||
}
|
||||
|
||||
@Internal
|
||||
protected PoolingAsyncClientConnectionManager(
|
||||
final ManagedConnPool<HttpRoute, ManagedAsyncClientConnection> pool,
|
||||
final AsyncClientConnectionOperator connectionOperator) {
|
||||
this.connectionOperator = Args.notNull(connectionOperator, "Connection operator");
|
||||
this.pool = Args.notNull(pool, "Connection pool");
|
||||
this.closed = new AtomicBoolean(false);
|
||||
}
|
||||
|
||||
|
@ -141,14 +215,18 @@ public class PoolingAsyncClientConnectionManager implements AsyncClientConnectio
|
|||
public Future<AsyncConnectionEndpoint> lease(
|
||||
final HttpRoute route,
|
||||
final Object state,
|
||||
final Timeout timeout,
|
||||
final Timeout requestTimeout,
|
||||
final FutureCallback<AsyncConnectionEndpoint> callback) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Connection request: " + ConnPoolSupport.formatStats(null, route, state, pool));
|
||||
}
|
||||
final ComplexFuture<AsyncConnectionEndpoint> resultFuture = new ComplexFuture<>(callback);
|
||||
//TODO: fix me.
|
||||
if (log.isWarnEnabled() && Timeout.isPositive(requestTimeout)) {
|
||||
log.warn("Connection request timeout is not supported");
|
||||
}
|
||||
final Future<PoolEntry<HttpRoute, ManagedAsyncClientConnection>> leaseFuture = pool.lease(
|
||||
route, state, timeout, new FutureCallback<PoolEntry<HttpRoute, ManagedAsyncClientConnection>>() {
|
||||
route, state, /** requestTimeout, **/ new FutureCallback<PoolEntry<HttpRoute, ManagedAsyncClientConnection>>() {
|
||||
|
||||
void leaseCompleted(final PoolEntry<HttpRoute, ManagedAsyncClientConnection> poolEntry) {
|
||||
if (log.isDebugEnabled()) {
|
||||
|
|
|
@ -35,6 +35,7 @@ import org.apache.hc.client5.http.SchemePortResolver;
|
|||
import org.apache.hc.client5.http.ssl.H2TlsStrategy;
|
||||
import org.apache.hc.core5.http.config.RegistryBuilder;
|
||||
import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
|
||||
import org.apache.hc.core5.pool.PoolConcurrencyPolicy;
|
||||
import org.apache.hc.core5.pool.PoolReusePolicy;
|
||||
import org.apache.hc.core5.util.TimeValue;
|
||||
|
||||
|
@ -69,6 +70,7 @@ public class PoolingAsyncClientConnectionManagerBuilder {
|
|||
private TlsStrategy tlsStrategy;
|
||||
private SchemePortResolver schemePortResolver;
|
||||
private DnsResolver dnsResolver;
|
||||
private PoolConcurrencyPolicy poolConcurrencyPolicy;
|
||||
private PoolReusePolicy poolReusePolicy;
|
||||
|
||||
private boolean systemProperties;
|
||||
|
@ -112,6 +114,14 @@ public class PoolingAsyncClientConnectionManagerBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns {@link PoolConcurrencyPolicy} value.
|
||||
*/
|
||||
public final PoolingAsyncClientConnectionManagerBuilder setPoolConcurrencyPolicy(final PoolConcurrencyPolicy poolConcurrencyPolicy) {
|
||||
this.poolConcurrencyPolicy = poolConcurrencyPolicy;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns {@link PoolReusePolicy} value.
|
||||
*/
|
||||
|
@ -165,15 +175,29 @@ public class PoolingAsyncClientConnectionManagerBuilder {
|
|||
}
|
||||
|
||||
public PoolingAsyncClientConnectionManager build() {
|
||||
final TlsStrategy tlsStrategyCopy;
|
||||
if (tlsStrategy != null) {
|
||||
tlsStrategyCopy = tlsStrategy;
|
||||
} else if (systemProperties) {
|
||||
tlsStrategyCopy = AccessController.doPrivileged(new PrivilegedAction<TlsStrategy>() {
|
||||
@Override
|
||||
public TlsStrategy run() {
|
||||
return H2TlsStrategy.getSystemDefault();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
tlsStrategyCopy = H2TlsStrategy.getDefault();
|
||||
}
|
||||
@SuppressWarnings("resource")
|
||||
final PoolingAsyncClientConnectionManager poolingmgr = new PoolingAsyncClientConnectionManager(
|
||||
RegistryBuilder.<TlsStrategy>create()
|
||||
.register("https", getTlsStrategy())
|
||||
.register("https", tlsStrategyCopy)
|
||||
.build(),
|
||||
schemePortResolver,
|
||||
dnsResolver,
|
||||
poolConcurrencyPolicy,
|
||||
poolReusePolicy,
|
||||
timeToLive,
|
||||
poolReusePolicy);
|
||||
schemePortResolver,
|
||||
dnsResolver);
|
||||
poolingmgr.setValidateAfterInactivity(this.validateAfterInactivity);
|
||||
if (maxConnTotal > 0) {
|
||||
poolingmgr.setMaxTotal(maxConnTotal);
|
||||
|
@ -184,18 +208,4 @@ public class PoolingAsyncClientConnectionManagerBuilder {
|
|||
return poolingmgr;
|
||||
}
|
||||
|
||||
private TlsStrategy getTlsStrategy() {
|
||||
if (tlsStrategy != null) {
|
||||
return tlsStrategy;
|
||||
} else if (systemProperties) {
|
||||
return AccessController.doPrivileged(new PrivilegedAction<TlsStrategy>() {
|
||||
@Override
|
||||
public TlsStrategy run() {
|
||||
return H2TlsStrategy.getSystemDefault();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
return H2TlsStrategy.getDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ import java.io.IOException;
|
|||
import org.apache.hc.client5.http.HttpRoute;
|
||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||
import org.apache.hc.core5.util.TimeValue;
|
||||
import org.apache.hc.core5.util.Timeout;
|
||||
|
||||
/**
|
||||
* Represents a manager of persistent client connections.
|
||||
|
@ -64,10 +65,12 @@ public interface HttpClientConnectionManager extends Closeable {
|
|||
* executed a {@code CONNECT} method to all intermediate proxy hops.
|
||||
*
|
||||
* @param route HTTP route of the requested connection.
|
||||
* @param requestTimeout lease request timeout.
|
||||
* @param state expected state of the connection or {@code null}
|
||||
* if the connection is not expected to carry any state.
|
||||
* @since 5.0
|
||||
*/
|
||||
LeaseRequest lease(HttpRoute route, Object state);
|
||||
LeaseRequest lease(HttpRoute route, Timeout requestTimeout, Object state);
|
||||
|
||||
/**
|
||||
* Releases the endpoint back to the manager making it potentially
|
||||
|
|
|
@ -30,6 +30,7 @@ package org.apache.hc.client5.http.io;
|
|||
import java.io.IOException;
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
import org.apache.hc.core5.annotation.Internal;
|
||||
import org.apache.hc.core5.http.HttpHost;
|
||||
import org.apache.hc.core5.http.config.SocketConfig;
|
||||
import org.apache.hc.core5.http.protocol.HttpContext;
|
||||
|
@ -44,6 +45,7 @@ import org.apache.hc.core5.util.TimeValue;
|
|||
*
|
||||
* @since 4.4
|
||||
*/
|
||||
@Internal
|
||||
public interface HttpClientConnectionOperator {
|
||||
|
||||
void connect(
|
||||
|
|
|
@ -32,6 +32,7 @@ import java.net.Socket;
|
|||
|
||||
import javax.net.ssl.SSLSession;
|
||||
|
||||
import org.apache.hc.core5.annotation.Internal;
|
||||
import org.apache.hc.core5.http.io.HttpClientConnection;
|
||||
|
||||
/**
|
||||
|
@ -42,6 +43,7 @@ import org.apache.hc.core5.http.io.HttpClientConnection;
|
|||
*
|
||||
* @since 4.3
|
||||
*/
|
||||
@Internal
|
||||
public interface ManagedHttpClientConnection extends HttpClientConnection {
|
||||
|
||||
/**
|
||||
|
|
|
@ -71,13 +71,13 @@ public interface AsyncClientConnectionManager extends Closeable {
|
|||
* @param route HTTP route of the requested connection.
|
||||
* @param state expected state of the connection or {@code null}
|
||||
* if the connection is not expected to carry any state.
|
||||
* @param timeout lease request timeout.
|
||||
* @param requestTimeout lease request timeout.
|
||||
* @param callback result callback.
|
||||
*/
|
||||
Future<AsyncConnectionEndpoint> lease(
|
||||
HttpRoute route,
|
||||
Object state,
|
||||
Timeout timeout,
|
||||
Timeout requestTimeout,
|
||||
FutureCallback<AsyncConnectionEndpoint> callback);
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* 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 CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.hc.client5.http.nio;
|
||||
|
||||
import java.net.SocketAddress;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
import org.apache.hc.core5.annotation.Internal;
|
||||
import org.apache.hc.core5.concurrent.FutureCallback;
|
||||
import org.apache.hc.core5.http.HttpHost;
|
||||
import org.apache.hc.core5.reactor.ConnectionInitiator;
|
||||
import org.apache.hc.core5.util.TimeValue;
|
||||
|
||||
/**
|
||||
* @since 5.0
|
||||
*/
|
||||
@Internal
|
||||
public interface AsyncClientConnectionOperator {
|
||||
|
||||
Future<ManagedAsyncClientConnection> connect(
|
||||
ConnectionInitiator connectionInitiator,
|
||||
HttpHost host,
|
||||
SocketAddress localAddress,
|
||||
TimeValue connectTimeout,
|
||||
Object attachment,
|
||||
FutureCallback<ManagedAsyncClientConnection> callback);
|
||||
|
||||
void upgrade(ManagedAsyncClientConnection connection, HttpHost host, Object attachment);
|
||||
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* ====================================================================
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* 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 CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
* ====================================================================
|
||||
*
|
||||
* This software consists of voluntary contributions made by many
|
||||
* individuals on behalf of the Apache Software Foundation. For more
|
||||
* information on the Apache Software Foundation, please see
|
||||
* <http://www.apache.org/>.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.hc.client5.http.nio;
|
||||
|
||||
import org.apache.hc.core5.annotation.Internal;
|
||||
import org.apache.hc.core5.http.HttpConnection;
|
||||
import org.apache.hc.core5.reactor.Command;
|
||||
import org.apache.hc.core5.reactor.ssl.TransportSecurityLayer;
|
||||
|
||||
@Internal
|
||||
public interface ManagedAsyncClientConnection extends HttpConnection, TransportSecurityLayer {
|
||||
|
||||
void submitPriorityCommand(Command command);
|
||||
|
||||
void submitCommand(Command command);
|
||||
|
||||
}
|
|
@ -43,6 +43,7 @@ import org.apache.hc.core5.http.HttpHost;
|
|||
import org.apache.hc.core5.http.impl.io.HttpRequestExecutor;
|
||||
import org.apache.hc.core5.io.ShutdownType;
|
||||
import org.apache.hc.core5.util.TimeValue;
|
||||
import org.apache.hc.core5.util.Timeout;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
|
@ -88,7 +89,7 @@ public class TestExecRuntimeImpl {
|
|||
context.setRequestConfig(config);
|
||||
final HttpRoute route = new HttpRoute(new HttpHost("host", 80));
|
||||
|
||||
Mockito.when(mgr.lease(route, null)).thenReturn(leaseRequest);
|
||||
Mockito.when(mgr.lease(Mockito.eq(route), Mockito.<Timeout>any(), Mockito.any())).thenReturn(leaseRequest);
|
||||
Mockito.when(leaseRequest.get(
|
||||
Mockito.anyLong(), Mockito.<TimeUnit>any())).thenReturn(connectionEndpoint);
|
||||
|
||||
|
@ -109,7 +110,7 @@ public class TestExecRuntimeImpl {
|
|||
public void testAcquireEndpointAlreadyAcquired() throws Exception {
|
||||
final HttpClientContext context = HttpClientContext.create();
|
||||
|
||||
Mockito.when(mgr.lease(route, null)).thenReturn(leaseRequest);
|
||||
Mockito.when(mgr.lease(Mockito.eq(route), Mockito.<Timeout>any(), Mockito.any())).thenReturn(leaseRequest);
|
||||
Mockito.when(leaseRequest.get(
|
||||
Mockito.anyLong(), Mockito.<TimeUnit>any())).thenReturn(connectionEndpoint);
|
||||
|
||||
|
@ -125,7 +126,7 @@ public class TestExecRuntimeImpl {
|
|||
public void testAcquireEndpointLeaseRequestTimeout() throws Exception {
|
||||
final HttpClientContext context = HttpClientContext.create();
|
||||
|
||||
Mockito.when(mgr.lease(route, null)).thenReturn(leaseRequest);
|
||||
Mockito.when(mgr.lease(Mockito.eq(route), Mockito.<Timeout>any(), Mockito.any())).thenReturn(leaseRequest);
|
||||
Mockito.when(leaseRequest.get(
|
||||
Mockito.anyLong(), Mockito.<TimeUnit>any())).thenThrow(new TimeoutException());
|
||||
|
||||
|
@ -136,7 +137,7 @@ public class TestExecRuntimeImpl {
|
|||
public void testAcquireEndpointLeaseRequestFailure() throws Exception {
|
||||
final HttpClientContext context = HttpClientContext.create();
|
||||
|
||||
Mockito.when(mgr.lease(route, null)).thenReturn(leaseRequest);
|
||||
Mockito.when(mgr.lease(Mockito.eq(route), Mockito.<Timeout>any(), Mockito.any())).thenReturn(leaseRequest);
|
||||
Mockito.when(leaseRequest.get(
|
||||
Mockito.anyLong(), Mockito.<TimeUnit>any())).thenThrow(new ExecutionException(new IllegalStateException()));
|
||||
|
||||
|
@ -146,7 +147,7 @@ public class TestExecRuntimeImpl {
|
|||
@Test
|
||||
public void testAbortEndpoint() throws Exception {
|
||||
final HttpClientContext context = HttpClientContext.create();
|
||||
Mockito.when(mgr.lease(route, null)).thenReturn(leaseRequest);
|
||||
Mockito.when(mgr.lease(Mockito.eq(route), Mockito.<Timeout>any(), Mockito.any())).thenReturn(leaseRequest);
|
||||
Mockito.when(leaseRequest.get(
|
||||
Mockito.anyLong(), Mockito.<TimeUnit>any())).thenReturn(connectionEndpoint);
|
||||
|
||||
|
@ -172,7 +173,7 @@ public class TestExecRuntimeImpl {
|
|||
public void testCancell() throws Exception {
|
||||
final HttpClientContext context = HttpClientContext.create();
|
||||
|
||||
Mockito.when(mgr.lease(route, null)).thenReturn(leaseRequest);
|
||||
Mockito.when(mgr.lease(Mockito.eq(route), Mockito.<Timeout>any(), Mockito.any())).thenReturn(leaseRequest);
|
||||
Mockito.when(leaseRequest.get(
|
||||
Mockito.anyLong(), Mockito.<TimeUnit>any())).thenReturn(connectionEndpoint);
|
||||
|
||||
|
@ -199,7 +200,7 @@ public class TestExecRuntimeImpl {
|
|||
public void testReleaseEndpointReusable() throws Exception {
|
||||
final HttpClientContext context = HttpClientContext.create();
|
||||
|
||||
Mockito.when(mgr.lease(route, null)).thenReturn(leaseRequest);
|
||||
Mockito.when(mgr.lease(Mockito.eq(route), Mockito.<Timeout>any(), Mockito.any())).thenReturn(leaseRequest);
|
||||
Mockito.when(leaseRequest.get(
|
||||
Mockito.anyLong(), Mockito.<TimeUnit>any())).thenReturn(connectionEndpoint);
|
||||
|
||||
|
@ -229,7 +230,7 @@ public class TestExecRuntimeImpl {
|
|||
public void testReleaseEndpointNonReusable() throws Exception {
|
||||
final HttpClientContext context = HttpClientContext.create();
|
||||
|
||||
Mockito.when(mgr.lease(route, null)).thenReturn(leaseRequest);
|
||||
Mockito.when(mgr.lease(Mockito.eq(route), Mockito.<Timeout>any(), Mockito.any())).thenReturn(leaseRequest);
|
||||
Mockito.when(leaseRequest.get(
|
||||
Mockito.anyLong(), Mockito.<TimeUnit>any())).thenReturn(connectionEndpoint);
|
||||
|
||||
|
@ -265,7 +266,7 @@ public class TestExecRuntimeImpl {
|
|||
.build();
|
||||
context.setRequestConfig(config);
|
||||
|
||||
Mockito.when(mgr.lease(route, null)).thenReturn(leaseRequest);
|
||||
Mockito.when(mgr.lease(Mockito.eq(route), Mockito.<Timeout>any(), Mockito.any())).thenReturn(leaseRequest);
|
||||
Mockito.when(leaseRequest.get(
|
||||
Mockito.anyLong(), Mockito.<TimeUnit>any())).thenReturn(connectionEndpoint);
|
||||
|
||||
|
@ -285,7 +286,7 @@ public class TestExecRuntimeImpl {
|
|||
public void testDisonnectEndpoint() throws Exception {
|
||||
final HttpClientContext context = HttpClientContext.create();
|
||||
|
||||
Mockito.when(mgr.lease(route, null)).thenReturn(leaseRequest);
|
||||
Mockito.when(mgr.lease(Mockito.eq(route), Mockito.<Timeout>any(), Mockito.any())).thenReturn(leaseRequest);
|
||||
Mockito.when(leaseRequest.get(
|
||||
Mockito.anyLong(), Mockito.<TimeUnit>any())).thenReturn(connectionEndpoint);
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ public class TestPoolingHttpClientConnectionManager {
|
|||
public void setup() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mgr = new PoolingHttpClientConnectionManager(
|
||||
pool, socketFactoryRegistry, schemePortResolver, dnsResolver);
|
||||
new DefaultHttpClientConnectionOperator(socketFactoryRegistry, schemePortResolver, dnsResolver), pool, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
Loading…
Reference in New Issue