ConnManagerParams.setMaxTotalConnections(mgrpar, 1);
final CountDownLatch connectLatch = new CountDownLatch(1);
final AtomicReference<StallingOperator> operatorRef = new AtomicReference<StallingOperator>();
ThreadSafeClientConnManager mgr = new ThreadSafeClientConnManager(mgrpar, supportedSchemes) {
@Override
protected ClientConnectionOperator createConnectionOperator(
SchemeRegistry schreg) {
operatorRef.set(new StallingOperator(connectLatch, WaitPolicy.AFTER_OPEN, super.createConnectionOperator(schreg)));
return operatorRef.get();
}
};
assertNotNull(operatorRef.get());
final HttpHost target = getServerHttp();
final HttpRoute route = new HttpRoute(target, null, false);
final ManagedClientConnection conn = getConnection(mgr, route);
assertTrue(conn instanceof AbstractClientConnAdapter);
final AtomicReference<Throwable> throwRef = new AtomicReference<Throwable>();
Thread abortingThread = new Thread(new Runnable() {
public void run() {
try {
operatorRef.get().waitForState();
conn.abortConnection();
connectLatch.countDown();
} catch (Throwable e) {
throwRef.set(e);
}
}
});
abortingThread.start();
try {
conn.open(route, httpContext, defaultParams);
fail("expected exception");
} catch(IOException iox) {
assertEquals("Request aborted", iox.getMessage());
}
abortingThread.join(5000);
if(throwRef.get() != null)
throw new RuntimeException(throwRef.get());
assertFalse(conn.isOpen());
// Give the server a bit of time to accept the connection, but
// ensure that it can accept it.
for(int i = 0; i < 10; i++) {
if(localServer.getAcceptedConnectionCount() == 1)
break;
Thread.sleep(100);
}
assertEquals(1, localServer.getAcceptedConnectionCount());
// check that there are no connections available
try {
// this should fail quickly, connection has not been released
getConnection(mgr, route, 100L, TimeUnit.MILLISECONDS);
fail("ConnectionPoolTimeoutException should have been thrown");
} catch (ConnectionPoolTimeoutException e) {
// expected
}
// return it back to the manager
((AbstractClientConnAdapter) conn).releaseConnection();
// the connection is expected to be released back to the manager
ManagedClientConnection conn2 = getConnection(mgr, route, 5L, TimeUnit.SECONDS);
assertFalse("connection should have been closed", conn2.isOpen());
mgr.releaseConnection(conn2, -1, null);
mgr.shutdown();
}