HTTPCLIENT-734: API refinements

git-svn-id: https://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk@639506 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Oleg Kalnichevski 2008-03-21 00:40:54 +00:00
parent a72e883d9c
commit c51f3a980f
15 changed files with 179 additions and 266 deletions

View File

@ -39,6 +39,7 @@ import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.routing.HttpRoute;
import org.apache.http.conn.ClientConnectionRequest;
import org.apache.http.conn.ManagedClientConnection;
import org.apache.http.conn.PlainSocketFactory;
import org.apache.http.conn.Scheme;
@ -106,7 +107,8 @@ public class ManagerConnectDirect {
(target, null, supportedSchemes.getScheme(target).isLayered());
System.out.println("requesting connection for " + route);
ManagedClientConnection conn = clcm.getConnection(route);
ClientConnectionRequest connRequest = clcm.requestConnection(route);
ManagedClientConnection conn = connRequest.getConnection(0, null);
try {
System.out.println("opening connection");
conn.open(route, ctx, getParams());

View File

@ -39,6 +39,7 @@ import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.routing.HttpRoute;
import org.apache.http.conn.ClientConnectionRequest;
import org.apache.http.conn.ManagedClientConnection;
import org.apache.http.conn.PlainSocketFactory;
import org.apache.http.conn.Scheme;
@ -112,7 +113,8 @@ public class ManagerConnectProxy {
supportedSchemes.getScheme(target).isLayered());
System.out.println("requesting connection for " + route);
ManagedClientConnection conn = clcm.getConnection(route);
ClientConnectionRequest connRequest = clcm.requestConnection(route);
ManagedClientConnection conn = connRequest.getConnection(0, null);
try {
System.out.println("opening connection");
conn.open(route, ctx, getParams());

View File

@ -31,6 +31,7 @@
package org.apache.http.client.methods;
import org.apache.http.conn.ClientConnectionRequest;
import org.apache.http.conn.ConnectionReleaseTrigger;
/**
@ -46,6 +47,8 @@ import org.apache.http.conn.ConnectionReleaseTrigger;
*/
public interface AbortableHttpRequest {
void setConnectionRequest(ClientConnectionRequest connRequest);
void setReleaseTrigger(ConnectionReleaseTrigger releaseTrigger);
void abort();

View File

@ -33,9 +33,12 @@ package org.apache.http.client.methods;
import java.io.IOException;
import java.net.URI;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.apache.http.ProtocolVersion;
import org.apache.http.RequestLine;
import org.apache.http.conn.ClientConnectionRequest;
import org.apache.http.conn.ConnectionReleaseTrigger;
import org.apache.http.message.AbstractHttpMessage;
import org.apache.http.message.BasicRequestLine;
@ -53,11 +56,17 @@ import org.apache.http.params.HttpProtocolParams;
abstract class HttpRequestBase extends AbstractHttpMessage
implements HttpUriRequest, AbortableHttpRequest {
private final Lock abortLock;
private volatile boolean aborted;
private URI uri;
private ClientConnectionRequest connRequest;
private ConnectionReleaseTrigger releaseTrigger;
public HttpRequestBase() {
super();
this.abortLock = new ReentrantLock();
}
public abstract String getMethod();
@ -88,11 +97,41 @@ abstract class HttpRequestBase extends AbstractHttpMessage
this.uri = uri;
}
public void setConnectionRequest(final ClientConnectionRequest connRequest) {
if (this.aborted) {
return;
}
this.abortLock.lock();
try {
this.connRequest = connRequest;
} finally {
this.abortLock.unlock();
}
}
public void setReleaseTrigger(final ConnectionReleaseTrigger releaseTrigger) {
if (this.aborted) {
return;
}
this.abortLock.lock();
try {
this.connRequest = null;
this.releaseTrigger = releaseTrigger;
} finally {
this.abortLock.unlock();
}
}
public void abort() {
if (this.aborted) {
return;
}
this.aborted = true;
this.abortLock.lock();
try {
if (this.connRequest != null) {
this.connRequest.abortRequest();
}
if (this.releaseTrigger != null) {
try {
this.releaseTrigger.abortConnection();
@ -100,6 +139,9 @@ abstract class HttpRequestBase extends AbstractHttpMessage
// ignore
}
}
} finally {
this.abortLock.unlock();
}
}
}

View File

@ -74,57 +74,12 @@ public interface ClientConnectionManager {
;
/**
* Obtains a connection.
* This method will block until a connection becomes available
* or the connection manager is {@link #shutdown shut down}.
*
* @param route where the connection should point to
*
* @return a connection that can be used to communicate
* along the given route
*
* @throws InterruptedException
* if the calling thread is interrupted while waiting
*/
ManagedClientConnection getConnection(HttpRoute route)
throws InterruptedException
;
/**
* Obtains a connection within a given time.
* This method will block until a connection becomes available,
* the timeout expires, or the connection manager is
* {@link #shutdown shut down}.
* Timeouts are handled with millisecond precision
*
* @param route where the connection should point to
* @param timeout the timeout, 0 or negative for no timeout
* @param tunit the unit for the <code>timeout</code>,
* may be <code>null</code> only if there is no timeout
*
* @return a connection that can be used to communicate
* along the given route
*
* @throws ConnectionPoolTimeoutException
* in case of a timeout
* @throws InterruptedException
* if the calling thread is interrupted while waiting
*/
ManagedClientConnection getConnection(HttpRoute route,
long timeout,
TimeUnit tunit)
throws ConnectionPoolTimeoutException, InterruptedException
;
/**
* Returns a new {@link ClientConnectionRequest}, from which a
* {@link ManagedClientConnection} can be obtained, or the request can be
* aborted.
*/
ClientConnectionRequest newConnectionRequest()
ClientConnectionRequest requestConnection(HttpRoute route)
;

View File

@ -20,7 +20,6 @@ public interface ClientConnectionRequest {
* before this began, an {@link InterruptedException} will
* be thrown.
*
* @param route where the connection should point to
* @param timeout the timeout, 0 or negative for no timeout
* @param tunit the unit for the <code>timeout</code>,
* may be <code>null</code> only if there is no timeout
@ -33,9 +32,8 @@ public interface ClientConnectionRequest {
* @throws InterruptedException
* if the calling thread is interrupted while waiting
*/
ManagedClientConnection getConnection(HttpRoute route, long timeout,
TimeUnit unit) throws InterruptedException,
ConnectionPoolTimeoutException;
ManagedClientConnection getConnection(long timeout, TimeUnit unit)
throws InterruptedException, ConnectionPoolTimeoutException;
/**
* Aborts the call to {@link #getConnection(HttpRoute, long, TimeUnit)},

View File

@ -35,6 +35,9 @@ import java.util.regex.Pattern;
public class InetAddressUtils {
private InetAddressUtils() {
}
private static final Pattern IPV4_PATTERN =
Pattern.compile(
"^(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}$");

View File

@ -70,7 +70,6 @@ import org.apache.http.client.utils.URLUtils;
import org.apache.http.conn.BasicManagedEntity;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.ClientConnectionRequest;
import org.apache.http.conn.ConnectionReleaseTrigger;
import org.apache.http.conn.ManagedClientConnection;
import org.apache.http.conn.Scheme;
import org.apache.http.conn.routing.BasicRouteDirector;
@ -289,19 +288,18 @@ public class DefaultClientRequestDirector
HttpRoute route = roureq.getRoute();
ReleaseTrigger releaseTrigger = new ReleaseTrigger();
if (orig instanceof AbortableHttpRequest) {
((AbortableHttpRequest) orig).setReleaseTrigger(releaseTrigger);
}
// Allocate connection if needed
if (managedConn == null) {
ClientConnectionRequest connectionRequest = allocateConnection();
releaseTrigger.setClientConnectionRequest(connectionRequest);
managedConn = connectionRequest.getConnection(route, timeout, TimeUnit.MILLISECONDS);
ClientConnectionRequest connRequest = connManager.requestConnection(route);
if (orig instanceof AbortableHttpRequest) {
((AbortableHttpRequest) orig).setConnectionRequest(connRequest);
}
managedConn = connRequest.getConnection(timeout, TimeUnit.MILLISECONDS);
}
releaseTrigger.setConnectionReleaseTrigger(managedConn);
if (orig instanceof AbortableHttpRequest) {
((AbortableHttpRequest) orig).setReleaseTrigger(managedConn);
}
// Reopen connection if needed
if (!managedConn.isOpen()) {
@ -494,15 +492,6 @@ public class DefaultClientRequestDirector
}
/**
* Obtains a connection request, from which the connection can be retrieved.
*/
protected ClientConnectionRequest allocateConnection() {
return connManager.newConnectionRequest();
} // allocateConnection
/**
* Establishes the target route.
*
@ -1020,69 +1009,4 @@ public class DefaultClientRequestDirector
authState.setCredentials(creds);
}
/**
* A {@link ConnectionReleaseTrigger} that delegates either a
* {@link ClientConnectionRequest} or another ConnectionReleaseTrigger
* for aborting.
*/
private static class ReleaseTrigger implements ConnectionReleaseTrigger {
private boolean aborted = false;
private ClientConnectionRequest delegateRequest;
private ConnectionReleaseTrigger delegateTrigger;
void setConnectionReleaseTrigger(ConnectionReleaseTrigger releaseTrigger) throws IOException {
synchronized(this) {
if(aborted) {
throw new IOException("already aborted!");
}
this.delegateTrigger = releaseTrigger;
this.delegateRequest = null;
}
}
void setClientConnectionRequest(ClientConnectionRequest connectionRequest) throws IOException {
synchronized(this) {
if(aborted) {
throw new IOException("already aborted");
}
this.delegateRequest = connectionRequest;
this.delegateTrigger = null;
}
}
public void abortConnection() throws IOException {
ConnectionReleaseTrigger releaseTrigger;
ClientConnectionRequest connectionRequest;
synchronized(this) {
if(aborted)
throw new IOException("already aborted");
aborted = true;
// capture references within lock
releaseTrigger = delegateTrigger;
connectionRequest = delegateRequest;
}
if(connectionRequest != null)
connectionRequest.abortRequest();
if(releaseTrigger != null) {
releaseTrigger.abortConnection();
}
}
public void releaseConnection() throws IOException {
ConnectionReleaseTrigger releaseTrigger;
synchronized(this) {
releaseTrigger = delegateTrigger; // capture reference within lock
}
if(releaseTrigger != null)
releaseTrigger.releaseConnection();
}
}
} // class DefaultClientRequestDirector

View File

@ -178,25 +178,7 @@ public class SingleClientConnManager implements ClientConnectionManager {
}
/**
* Obtains a connection.
* Maps to {@link #getConnection(HttpRoute) getConnection(HttpRoute)}
* since this manager never blocks the caller.
*
* @param route where the connection should point to
* @param timeout ignored
* @param tunit ignored
*
* @return a connection that can be used to communicate
* along the given route
*/
public final ManagedClientConnection getConnection(HttpRoute route,
long timeout,
TimeUnit tunit) {
return getConnection(route);
}
public final ClientConnectionRequest newConnectionRequest() {
public final ClientConnectionRequest requestConnection(final HttpRoute route) {
return new ClientConnectionRequest() {
@ -204,7 +186,7 @@ public class SingleClientConnManager implements ClientConnectionManager {
// Nothing to abort, since requests are immediate.
}
public ManagedClientConnection getConnection(HttpRoute route,
public ManagedClientConnection getConnection(
long timeout, TimeUnit tunit) {
return SingleClientConnManager.this.getConnection(route);
}

View File

@ -147,36 +147,7 @@ public class ThreadSafeClientConnManager
}
// non-javadoc, see interface ClientConnectionManager
public final ManagedClientConnection getConnection(HttpRoute route)
throws InterruptedException {
while (true) {
try {
return getConnection(route, 0, null);
} catch (ConnectionPoolTimeoutException e) {
// We'll go ahead and log this, but it should never happen.
// These exceptions are only thrown when the timeout occurs
// and since we have no timeout, it doesn't happen.
LOG.debug
("Unexpected exception while waiting for connection.", e);
//@@@ throw RuntimeException or Error to indicate the problem?
}
}
}
// non-javadoc, see interface ClientConnectionManager
public final ManagedClientConnection getConnection(HttpRoute route,
long timeout,
TimeUnit tunit)
throws ConnectionPoolTimeoutException, InterruptedException {
return newConnectionRequest().getConnection(route, timeout, tunit);
}
public ClientConnectionRequest newConnectionRequest() {
public ClientConnectionRequest requestConnection(final HttpRoute route) {
final PoolEntryRequest poolRequest = connectionPool.newPoolEntryRequest();
@ -186,7 +157,7 @@ public class ThreadSafeClientConnManager
poolRequest.abortRequest();
}
public ManagedClientConnection getConnection(HttpRoute route,
public ManagedClientConnection getConnection(
long timeout, TimeUnit tunit) throws InterruptedException,
ConnectionPoolTimeoutException {
if (route == null) {
@ -302,20 +273,5 @@ public class ThreadSafeClientConnManager
return this.params;
}
/* *
* Assigns {@link HttpParams parameters} for this
* connection manager.
* /
//@@@ this is basically a no-op unless we pass the params to the pool
public void setParams(final HttpParams params) {
if (params == null) {
throw new IllegalArgumentException("Parameters may not be null");
}
this.params = params;
}
*/
} // class ThreadSafeClientConnManager

View File

@ -184,6 +184,7 @@ public class TestDefaultClientRequestDirector extends ServerTestBase {
}
private static class ConnMan2 implements ClientConnectionManager {
private ManagedClientConnection allocatedConnection;
private ManagedClientConnection releasedConnection;
@ -204,12 +205,15 @@ public class TestDefaultClientRequestDirector extends ServerTestBase {
throw new UnsupportedOperationException("just a mockup");
}
public ClientConnectionRequest newConnectionRequest() {
public ClientConnectionRequest requestConnection(final HttpRoute route) {
return new ClientConnectionRequest() {
public void abortRequest() {
throw new UnsupportedOperationException("just a mockup");
}
public ManagedClientConnection getConnection(HttpRoute route,
public ManagedClientConnection getConnection(
long timeout, TimeUnit unit)
throws InterruptedException,
ConnectionPoolTimeoutException {
@ -267,14 +271,17 @@ public class TestDefaultClientRequestDirector extends ServerTestBase {
throw new UnsupportedOperationException("just a mockup");
}
public ClientConnectionRequest newConnectionRequest() {
public ClientConnectionRequest requestConnection(final HttpRoute route) {
final Thread currentThread = Thread.currentThread();
return new ClientConnectionRequest() {
public void abortRequest() {
currentThread.interrupt();
}
public ManagedClientConnection getConnection(HttpRoute route,
public ManagedClientConnection getConnection(
long timeout, TimeUnit tunit)
throws InterruptedException,
ConnectionPoolTimeoutException {

View File

@ -60,7 +60,7 @@ public class GetConnThread extends Thread {
*/
public GetConnThread(ClientConnectionManager mgr,
HttpRoute route, long timeout) {
this(mgr.newConnectionRequest(), route, timeout);
this(mgr.requestConnection(route), route, timeout);
}
/**
@ -83,7 +83,7 @@ public class GetConnThread extends Thread {
public void run() {
try {
connection = conn_request.getConnection
(conn_route, conn_timeout, TimeUnit.MILLISECONDS);
(conn_timeout, TimeUnit.MILLISECONDS);
} catch (Throwable dart) {
exception = dart;
}

View File

@ -38,6 +38,7 @@ import junit.framework.TestSuite;
import org.apache.http.HttpHost;
import org.apache.http.HttpVersion;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.ClientConnectionRequest;
import org.apache.http.conn.ConnectionPoolTimeoutException;
import org.apache.http.conn.ManagedClientConnection;
@ -73,6 +74,22 @@ public class TestTSCCMNoServer extends TestCase {
}
private static ManagedClientConnection getConnection(
final ClientConnectionManager mgr,
final HttpRoute route,
long timeout,
TimeUnit unit) throws ConnectionPoolTimeoutException, InterruptedException {
ClientConnectionRequest connRequest = mgr.requestConnection(route);
return connRequest.getConnection(timeout, unit);
}
private static ManagedClientConnection getConnection(
final ClientConnectionManager mgr,
final HttpRoute route) throws ConnectionPoolTimeoutException, InterruptedException {
ClientConnectionRequest connRequest = mgr.requestConnection(route);
return connRequest.getConnection(0, null);
}
/**
* Helper to instantiate a <code>ThreadSafeClientConnManager</code>.
*
@ -160,13 +177,14 @@ public class TestTSCCMNoServer extends TestCase {
} // testConstructor
public void testGetConnection() throws InterruptedException {
public void testGetConnection()
throws InterruptedException, ConnectionPoolTimeoutException {
ThreadSafeClientConnManager mgr = createTSCCM(null, null);
HttpHost target = new HttpHost("www.test.invalid", 80, "http");
HttpRoute route = new HttpRoute(target, null, false);
ManagedClientConnection conn = mgr.getConnection(route);
ManagedClientConnection conn = getConnection(mgr, route);
assertNotNull(conn);
assertNull(conn.getRoute());
assertFalse(conn.isOpen());
@ -174,7 +192,7 @@ public class TestTSCCMNoServer extends TestCase {
mgr.releaseConnection(conn);
try {
conn = mgr.getConnection(null);
conn = getConnection(mgr, null);
fail("null route not detected");
} catch (IllegalArgumentException iax) {
// expected
@ -187,7 +205,8 @@ public class TestTSCCMNoServer extends TestCase {
// several other tests here rely on timeout behavior
public void testMaxConnTotal() throws InterruptedException {
public void testMaxConnTotal()
throws InterruptedException, ConnectionPoolTimeoutException {
HttpParams params = createDefaultParams();
HttpConnectionManagerParams.setDefaultMaxConnectionsPerHost(params, 1);
@ -200,14 +219,14 @@ public class TestTSCCMNoServer extends TestCase {
HttpHost target2 = new HttpHost("www.test2.invalid", 80, "http");
HttpRoute route2 = new HttpRoute(target2, null, false);
ManagedClientConnection conn1 = mgr.getConnection(route1);
ManagedClientConnection conn1 = getConnection(mgr, route1);
assertNotNull(conn1);
ManagedClientConnection conn2 = mgr.getConnection(route2);
ManagedClientConnection conn2 = getConnection(mgr, route2);
assertNotNull(conn2);
try {
// this should fail quickly, connection has not been released
mgr.getConnection(route2, 100L, TimeUnit.MILLISECONDS);
getConnection(mgr, route2, 100L, TimeUnit.MILLISECONDS);
fail("ConnectionPoolTimeoutException should have been thrown");
} catch (ConnectionPoolTimeoutException e) {
// expected
@ -219,7 +238,7 @@ public class TestTSCCMNoServer extends TestCase {
// there should be a connection available now
try {
conn2 = mgr.getConnection(route2, 100L, TimeUnit.MILLISECONDS);
conn2 = getConnection(mgr, route2, 100L, TimeUnit.MILLISECONDS);
} catch (ConnectionPoolTimeoutException cptx) {
cptx.printStackTrace();
fail("connection should have been available: " + cptx);
@ -248,38 +267,38 @@ public class TestTSCCMNoServer extends TestCase {
// route 3, limit 3
ManagedClientConnection conn1 =
mgr.getConnection(route3, 10L, TimeUnit.MILLISECONDS);
getConnection(mgr, route3, 10L, TimeUnit.MILLISECONDS);
assertNotNull(conn1);
ManagedClientConnection conn2 =
mgr.getConnection(route3, 10L, TimeUnit.MILLISECONDS);
getConnection(mgr, route3, 10L, TimeUnit.MILLISECONDS);
assertNotNull(conn2);
ManagedClientConnection conn3 =
mgr.getConnection(route3, 10L, TimeUnit.MILLISECONDS);
getConnection(mgr, route3, 10L, TimeUnit.MILLISECONDS);
assertNotNull(conn3);
try {
// should fail quickly, connection has not been released
mgr.getConnection(route3, 10L, TimeUnit.MILLISECONDS);
getConnection(mgr, route3, 10L, TimeUnit.MILLISECONDS);
fail("ConnectionPoolTimeoutException should have been thrown");
} catch (ConnectionPoolTimeoutException e) {
// expected
}
// route 2, limit 2
conn1 = mgr.getConnection(route2, 10L, TimeUnit.MILLISECONDS);
conn2 = mgr.getConnection(route2, 10L, TimeUnit.MILLISECONDS);
conn1 = getConnection(mgr, route2, 10L, TimeUnit.MILLISECONDS);
conn2 = getConnection(mgr, route2, 10L, TimeUnit.MILLISECONDS);
try {
// should fail quickly, connection has not been released
mgr.getConnection(route2, 10L, TimeUnit.MILLISECONDS);
getConnection(mgr, route2, 10L, TimeUnit.MILLISECONDS);
fail("ConnectionPoolTimeoutException should have been thrown");
} catch (ConnectionPoolTimeoutException e) {
// expected
}
// route 1, should use default limit of 1
conn1 = mgr.getConnection(route1, 10L, TimeUnit.MILLISECONDS);
conn1 = getConnection(mgr, route1, 10L, TimeUnit.MILLISECONDS);
try {
// should fail quickly, connection has not been released
mgr.getConnection(route1, 10L, TimeUnit.MILLISECONDS);
getConnection(mgr, route1, 10L, TimeUnit.MILLISECONDS);
fail("ConnectionPoolTimeoutException should have been thrown");
} catch (ConnectionPoolTimeoutException e) {
// expected
@ -321,11 +340,11 @@ public class TestTSCCMNoServer extends TestCase {
// the first three allocations should pass
ManagedClientConnection conn1 =
mgr.getConnection(route1, 10L, TimeUnit.MILLISECONDS);
getConnection(mgr, route1, 10L, TimeUnit.MILLISECONDS);
ManagedClientConnection conn2 =
mgr.getConnection(route2, 10L, TimeUnit.MILLISECONDS);
getConnection(mgr, route2, 10L, TimeUnit.MILLISECONDS);
ManagedClientConnection conn3 =
mgr.getConnection(route3, 10L, TimeUnit.MILLISECONDS);
getConnection(mgr, route3, 10L, TimeUnit.MILLISECONDS);
assertNotNull(conn1);
assertNotNull(conn2);
assertNotNull(conn3);
@ -333,19 +352,19 @@ public class TestTSCCMNoServer extends TestCase {
// obtaining another connection for either of the three should fail
// this is somehow redundant with testMaxConnPerHost
try {
mgr.getConnection(route1, 10L, TimeUnit.MILLISECONDS);
getConnection(mgr, route1, 10L, TimeUnit.MILLISECONDS);
fail("ConnectionPoolTimeoutException should have been thrown");
} catch (ConnectionPoolTimeoutException e) {
// expected
}
try {
mgr.getConnection(route2, 10L, TimeUnit.MILLISECONDS);
getConnection(mgr, route2, 10L, TimeUnit.MILLISECONDS);
fail("ConnectionPoolTimeoutException should have been thrown");
} catch (ConnectionPoolTimeoutException e) {
// expected
}
try {
mgr.getConnection(route3, 10L, TimeUnit.MILLISECONDS);
getConnection(mgr, route3, 10L, TimeUnit.MILLISECONDS);
fail("ConnectionPoolTimeoutException should have been thrown");
} catch (ConnectionPoolTimeoutException e) {
// expected
@ -355,16 +374,16 @@ public class TestTSCCMNoServer extends TestCase {
mgr.releaseConnection(conn2);
conn2 = null;
try {
mgr.getConnection(route1, 10L, TimeUnit.MILLISECONDS);
getConnection(mgr, route1, 10L, TimeUnit.MILLISECONDS);
fail("ConnectionPoolTimeoutException should have been thrown");
} catch (ConnectionPoolTimeoutException e) {
// expected
}
// this one succeeds
conn2 = mgr.getConnection(route2, 10L, TimeUnit.MILLISECONDS);
conn2 = getConnection(mgr, route2, 10L, TimeUnit.MILLISECONDS);
assertNotNull(conn2);
try {
mgr.getConnection(route3, 10L, TimeUnit.MILLISECONDS);
getConnection(mgr, route3, 10L, TimeUnit.MILLISECONDS);
fail("ConnectionPoolTimeoutException should have been thrown");
} catch (ConnectionPoolTimeoutException e) {
// expected
@ -374,14 +393,15 @@ public class TestTSCCMNoServer extends TestCase {
}
public void testDeleteClosedConnections() throws InterruptedException {
public void testDeleteClosedConnections()
throws InterruptedException, ConnectionPoolTimeoutException {
ThreadSafeClientConnManager mgr = createTSCCM(null, null);
HttpHost target = new HttpHost("www.test.invalid", 80, "http");
HttpRoute route = new HttpRoute(target, null, false);
ManagedClientConnection conn = mgr.getConnection(route);
ManagedClientConnection conn = getConnection(mgr, route);
assertEquals("connectionsInPool",
mgr.getConnectionsInPool(), 1);
@ -422,7 +442,7 @@ public class TestTSCCMNoServer extends TestCase {
// on shutdown, the extra thread should get an exception
ManagedClientConnection conn =
mgr.getConnection(route, 1L, TimeUnit.MILLISECONDS);
getConnection(mgr, route, 1L, TimeUnit.MILLISECONDS);
GetConnThread gct = new GetConnThread(mgr, route, 0L); // no timeout
gct.start();
Thread.sleep(100); // give extra thread time to block
@ -446,7 +466,7 @@ public class TestTSCCMNoServer extends TestCase {
// the manager is down, we should not be able to get a connection
try {
conn = mgr.getConnection(route, 1L, TimeUnit.MILLISECONDS);
conn = getConnection(mgr, route, 1L, TimeUnit.MILLISECONDS);
fail("shut-down manager does not raise exception");
} catch (IllegalStateException isx) {
// expected
@ -467,7 +487,7 @@ public class TestTSCCMNoServer extends TestCase {
// get the only connection, then start an extra thread
ManagedClientConnection conn =
mgr.getConnection(route, 1L, TimeUnit.MILLISECONDS);
getConnection(mgr, route, 1L, TimeUnit.MILLISECONDS);
GetConnThread gct = new GetConnThread(mgr, route, 0L); // no timeout
gct.start();
Thread.sleep(100); // give extra thread time to block
@ -486,7 +506,7 @@ public class TestTSCCMNoServer extends TestCase {
// make sure the manager is still working
try {
mgr.getConnection(route, 10L, TimeUnit.MILLISECONDS);
getConnection(mgr, route, 10L, TimeUnit.MILLISECONDS);
fail("should have gotten a timeout");
} catch (ConnectionPoolTimeoutException e) {
// expected
@ -494,7 +514,7 @@ public class TestTSCCMNoServer extends TestCase {
mgr.releaseConnection(conn);
// this time: no exception
conn = mgr.getConnection(route, 10L, TimeUnit.MILLISECONDS);
conn = getConnection(mgr, route, 10L, TimeUnit.MILLISECONDS);
assertNotNull("should have gotten a connection", conn);
mgr.shutdown();
@ -517,7 +537,7 @@ public class TestTSCCMNoServer extends TestCase {
// get the only connection, then start two extra threads
ManagedClientConnection conn =
mgr.getConnection(route1, 1L, TimeUnit.MILLISECONDS);
getConnection(mgr, route1, 1L, TimeUnit.MILLISECONDS);
GetConnThread gct1 = new GetConnThread(mgr, route1, 1000L);
GetConnThread gct2 = new GetConnThread(mgr, route2, 1000L);
@ -554,8 +574,8 @@ public class TestTSCCMNoServer extends TestCase {
HttpRoute route = new HttpRoute(target, null, false);
// get the only connection, then start an extra thread
ManagedClientConnection conn = mgr.getConnection(route, 1L, TimeUnit.MILLISECONDS);
ClientConnectionRequest request = mgr.newConnectionRequest();
ManagedClientConnection conn = getConnection(mgr, route, 1L, TimeUnit.MILLISECONDS);
ClientConnectionRequest request = mgr.requestConnection(route);
GetConnThread gct = new GetConnThread(request, route, 0L); // no timeout
gct.start();
Thread.sleep(100); // give extra thread time to block
@ -571,7 +591,7 @@ public class TestTSCCMNoServer extends TestCase {
// make sure the manager is still working
try {
mgr.getConnection(route, 10L, TimeUnit.MILLISECONDS);
getConnection(mgr, route, 10L, TimeUnit.MILLISECONDS);
fail("should have gotten a timeout");
} catch (ConnectionPoolTimeoutException e) {
// expected
@ -579,7 +599,7 @@ public class TestTSCCMNoServer extends TestCase {
mgr.releaseConnection(conn);
// this time: no exception
conn = mgr.getConnection(route, 10L, TimeUnit.MILLISECONDS);
conn = getConnection(mgr, route, 10L, TimeUnit.MILLISECONDS);
assertNotNull("should have gotten a connection", conn);
mgr.shutdown();
@ -596,8 +616,8 @@ public class TestTSCCMNoServer extends TestCase {
// get the only connection, then start an extra thread
ManagedClientConnection conn = mgr.getConnection(route, 1L, TimeUnit.MILLISECONDS);
ClientConnectionRequest request = mgr.newConnectionRequest();
ManagedClientConnection conn = getConnection(mgr, route, 1L, TimeUnit.MILLISECONDS);
ClientConnectionRequest request = mgr.requestConnection(route);
request.abortRequest();
GetConnThread gct = new GetConnThread(request, route, 0L); // no timeout
@ -613,7 +633,7 @@ public class TestTSCCMNoServer extends TestCase {
// make sure the manager is still working
try {
mgr.getConnection(route, 10L, TimeUnit.MILLISECONDS);
getConnection(mgr, route, 10L, TimeUnit.MILLISECONDS);
fail("should have gotten a timeout");
} catch (ConnectionPoolTimeoutException e) {
// expected
@ -621,7 +641,7 @@ public class TestTSCCMNoServer extends TestCase {
mgr.releaseConnection(conn);
// this time: no exception
conn = mgr.getConnection(route, 10L, TimeUnit.MILLISECONDS);
conn = getConnection(mgr, route, 10L, TimeUnit.MILLISECONDS);
assertNotNull("should have gotten a connection", conn);
mgr.shutdown();

View File

@ -44,6 +44,8 @@ import org.apache.http.HttpStatus;
import org.apache.http.HttpVersion;
import org.apache.http.conn.ConnectionPoolTimeoutException;
import org.apache.http.conn.routing.HttpRoute;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.ClientConnectionRequest;
import org.apache.http.conn.ManagedClientConnection;
import org.apache.http.conn.SchemeRegistry;
import org.apache.http.conn.params.HttpConnectionManagerParams;
@ -174,6 +176,21 @@ public class TestTSCCMWithServer extends ServerTestBase {
mgr.shutdown();
}
private static ManagedClientConnection getConnection(
final ClientConnectionManager mgr,
final HttpRoute route,
long timeout,
TimeUnit unit) throws ConnectionPoolTimeoutException, InterruptedException {
ClientConnectionRequest connRequest = mgr.requestConnection(route);
return connRequest.getConnection(timeout, unit);
}
private static ManagedClientConnection getConnection(
final ClientConnectionManager mgr,
final HttpRoute route) throws ConnectionPoolTimeoutException, InterruptedException {
ClientConnectionRequest connRequest = mgr.requestConnection(route);
return connRequest.getConnection(0, null);
}
/**
* Tests releasing and re-using a connection after a response is read.
@ -193,7 +210,7 @@ public class TestTSCCMWithServer extends ServerTestBase {
HttpRequest request =
new BasicHttpRequest("GET", uri, HttpVersion.HTTP_1_1);
ManagedClientConnection conn = mgr.getConnection(route);
ManagedClientConnection conn = getConnection(mgr, route);
conn.open(route, httpContext, defaultParams);
// a new context is created for each testcase, no need to reset
@ -212,7 +229,7 @@ public class TestTSCCMWithServer extends ServerTestBase {
// check that there is no auto-release by default
try {
// this should fail quickly, connection has not been released
mgr.getConnection(route, 10L, TimeUnit.MILLISECONDS);
getConnection(mgr, route, 10L, TimeUnit.MILLISECONDS);
fail("ConnectionPoolTimeoutException should have been thrown");
} catch (ConnectionPoolTimeoutException e) {
// expected
@ -221,7 +238,7 @@ public class TestTSCCMWithServer extends ServerTestBase {
// release connection without marking for re-use
// expect the next connection obtained to be closed
mgr.releaseConnection(conn);
conn = mgr.getConnection(route);
conn = getConnection(mgr, route);
assertFalse("connection should have been closed", conn.isOpen());
// repeat the communication, no need to prepare the request again
@ -242,7 +259,7 @@ public class TestTSCCMWithServer extends ServerTestBase {
// expect the next connection obtained to be open
conn.markReusable();
mgr.releaseConnection(conn);
conn = mgr.getConnection(route);
conn = getConnection(mgr, route);
assertTrue("connection should have been open", conn.isOpen());
// repeat the communication, no need to prepare the request again
@ -282,7 +299,7 @@ public class TestTSCCMWithServer extends ServerTestBase {
HttpRequest request =
new BasicHttpRequest("GET", uri, HttpVersion.HTTP_1_1);
ManagedClientConnection conn = mgr.getConnection(route);
ManagedClientConnection conn = getConnection(mgr, route);
conn.open(route, httpContext, defaultParams);
// a new context is created for each testcase, no need to reset
@ -296,7 +313,7 @@ public class TestTSCCMWithServer extends ServerTestBase {
// first check that we can't get another connection
try {
// this should fail quickly, connection has not been released
mgr.getConnection(route, 10L, TimeUnit.MILLISECONDS);
getConnection(mgr, route, 10L, TimeUnit.MILLISECONDS);
fail("ConnectionPoolTimeoutException should have been thrown");
} catch (ConnectionPoolTimeoutException e) {
// expected
@ -315,7 +332,7 @@ public class TestTSCCMWithServer extends ServerTestBase {
Thread.sleep(1000);
assertNull("connection not garbage collected", wref.get());
conn = mgr.getConnection(route, 10L, TimeUnit.MILLISECONDS);
conn = getConnection(mgr, route, 10L, TimeUnit.MILLISECONDS);
assertFalse("GCed connection not closed", conn.isOpen());
mgr.shutdown();
@ -338,7 +355,7 @@ public class TestTSCCMWithServer extends ServerTestBase {
HttpRequest request =
new BasicHttpRequest("GET", uri, HttpVersion.HTTP_1_1);
ManagedClientConnection conn = mgr.getConnection(route);
ManagedClientConnection conn = getConnection(mgr, route);
conn.open(route, httpContext, defaultParams);
// a new context is created for each testcase, no need to reset

View File

@ -39,6 +39,7 @@ import junit.framework.TestSuite;
import org.apache.http.HttpHost;
import org.apache.http.HttpVersion;
import org.apache.http.conn.ClientConnectionRequest;
import org.apache.http.conn.ManagedClientConnection;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.PlainSocketFactory;
@ -150,7 +151,8 @@ public class TestSpuriousWakeup extends TestCase {
try {
// take out the only connection
ManagedClientConnection conn = mgr.getConnection(ROUTE);
ClientConnectionRequest connRequest = mgr.requestConnection(ROUTE);
ManagedClientConnection conn = connRequest.getConnection(0, null);
assertNotNull(conn);
// send a thread waiting