use of org.apache.http.HttpConnectionMetrics in project lucene-solr by apache.
the class ConnectionReuseTest method testConnectionReuse.
@Test
public void testConnectionReuse() throws Exception {
URL url = cluster.getJettySolrRunners().get(0).getBaseUrl();
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
CloseableHttpClient httpClient = HttpClientUtil.createClient(null, cm);
try (SolrClient client = buildClient(httpClient, url)) {
HttpHost target = new HttpHost(url.getHost(), url.getPort(), isSSLMode() ? "https" : "http");
HttpRoute route = new HttpRoute(target);
ConnectionRequest mConn = getClientConnectionRequest(httpClient, route, cm);
HttpClientConnection conn1 = getConn(mConn);
headerRequest(target, route, conn1, cm);
cm.releaseConnection(conn1, null, -1, TimeUnit.MILLISECONDS);
int queueBreaks = 0;
int cnt1 = atLeast(3);
int cnt2 = atLeast(30);
for (int j = 0; j < cnt1; j++) {
boolean done = false;
for (int i = 0; i < cnt2; i++) {
AddUpdateCommand c = new AddUpdateCommand(null);
c.solrDoc = sdoc("id", id.incrementAndGet());
try {
client.add(c.solrDoc);
} catch (Exception e) {
e.printStackTrace();
}
if (!done && i > 0 && i < cnt2 - 1 && client instanceof ConcurrentUpdateSolrClient && random().nextInt(10) > 8) {
queueBreaks++;
done = true;
// wait past streaming client poll time of 250ms
Thread.sleep(350);
}
}
if (client instanceof ConcurrentUpdateSolrClient) {
((ConcurrentUpdateSolrClient) client).blockUntilFinished();
}
}
route = new HttpRoute(new HttpHost(url.getHost(), url.getPort(), isSSLMode() ? "https" : "http"));
mConn = cm.requestConnection(route, HttpSolrClient.cacheKey);
HttpClientConnection conn2 = getConn(mConn);
HttpConnectionMetrics metrics = conn2.getMetrics();
headerRequest(target, route, conn2, cm);
cm.releaseConnection(conn2, null, -1, TimeUnit.MILLISECONDS);
assertNotNull("No connection metrics found - is the connection getting aborted? server closing the connection? " + client.getClass().getSimpleName(), metrics);
// we try and make sure the connection we get has handled all of the requests in this test
if (client instanceof ConcurrentUpdateSolrClient) {
// we can't fully control queue polling breaking up requests - allow a bit of leeway
int exp = cnt1 + queueBreaks + 2;
assertTrue("We expected all communication via streaming client to use one connection! expected=" + exp + " got=" + metrics.getRequestCount(), Math.max(exp, metrics.getRequestCount()) - Math.min(exp, metrics.getRequestCount()) < 3);
} else {
assertTrue("We expected all communication to use one connection! " + client.getClass().getSimpleName() + " " + metrics.getRequestCount(), cnt1 * cnt2 + 2 <= metrics.getRequestCount());
}
} finally {
HttpClientUtil.close(httpClient);
}
}
use of org.apache.http.HttpConnectionMetrics in project jmeter by apache.
the class HTTPHC4Impl method sample.
@Override
protected HTTPSampleResult sample(URL url, String method, boolean areFollowingRedirect, int frameDepth) {
if (log.isDebugEnabled()) {
log.debug("Start : sample {} method {} followingRedirect {} depth {}", url, method, areFollowingRedirect, frameDepth);
}
JMeterVariables jMeterVariables = JMeterContextService.getContext().getVariables();
HTTPSampleResult res = createSampleResult(url, method);
CloseableHttpClient httpClient = null;
HttpRequestBase httpRequest = null;
HttpContext localContext = new BasicHttpContext();
HttpClientContext clientContext = HttpClientContext.adapt(localContext);
clientContext.setAttribute(CONTEXT_ATTRIBUTE_AUTH_MANAGER, getAuthManager());
HttpClientKey key = createHttpClientKey(url);
MutableTriple<CloseableHttpClient, AuthState, PoolingHttpClientConnectionManager> triple;
try {
triple = setupClient(key, jMeterVariables, clientContext);
httpClient = triple.getLeft();
URI uri = url.toURI();
httpRequest = createHttpRequest(uri, method, areFollowingRedirect);
// can throw IOException
setupRequest(url, httpRequest, res);
} catch (Exception e) {
res.sampleStart();
res.sampleEnd();
errorResult(e, res);
return res;
}
setupClientContextBeforeSample(jMeterVariables, localContext);
res.sampleStart();
final CacheManager cacheManager = getCacheManager();
if (cacheManager != null && HTTPConstants.GET.equalsIgnoreCase(method) && cacheManager.inCache(url, httpRequest.getAllHeaders())) {
return updateSampleResultForResourceInCache(res);
}
CloseableHttpResponse httpResponse = null;
try {
currentRequest = httpRequest;
handleMethod(method, res, httpRequest, localContext);
// store the SampleResult in LocalContext to compute connect time
localContext.setAttribute(CONTEXT_ATTRIBUTE_SAMPLER_RESULT, res);
// perform the sample
httpResponse = executeRequest(httpClient, httpRequest, localContext, url);
saveProxyAuth(triple, localContext);
if (log.isDebugEnabled()) {
log.debug("Headers in request before:{}", Arrays.asList(httpRequest.getAllHeaders()));
}
// Needs to be done after execute to pick up all the headers
final HttpRequest request = (HttpRequest) localContext.getAttribute(HttpCoreContext.HTTP_REQUEST);
if (log.isDebugEnabled()) {
log.debug("Headers in request after:{}, in localContext#request:{}", Arrays.asList(httpRequest.getAllHeaders()), Arrays.asList(request.getAllHeaders()));
}
extractClientContextAfterSample(jMeterVariables, localContext);
// We've finished with the request, so we can add the LocalAddress to it for display
if (localAddress != null) {
request.addHeader(HEADER_LOCAL_ADDRESS, localAddress.toString());
}
res.setRequestHeaders(getAllHeadersExceptCookie(request));
Header contentType = httpResponse.getLastHeader(HTTPConstants.HEADER_CONTENT_TYPE);
if (contentType != null) {
String ct = contentType.getValue();
res.setContentType(ct);
res.setEncodingAndType(ct);
}
HttpEntity entity = httpResponse.getEntity();
if (entity != null) {
res.setResponseData(readResponse(res, entity.getContent(), entity.getContentLength()));
}
// Done with the sampling proper.
res.sampleEnd();
currentRequest = null;
// Now collect the results into the HTTPSampleResult:
StatusLine statusLine = httpResponse.getStatusLine();
int statusCode = statusLine.getStatusCode();
res.setResponseCode(Integer.toString(statusCode));
res.setResponseMessage(statusLine.getReasonPhrase());
res.setSuccessful(isSuccessCode(statusCode));
res.setResponseHeaders(getResponseHeaders(httpResponse));
if (res.isRedirect()) {
final Header headerLocation = httpResponse.getLastHeader(HTTPConstants.HEADER_LOCATION);
if (headerLocation == null) {
// HTTP protocol violation, but avoids NPE
throw new IllegalArgumentException("Missing location header in redirect for " + httpRequest.getRequestLine());
}
String redirectLocation = headerLocation.getValue();
res.setRedirectLocation(redirectLocation);
}
// record some sizes to allow HTTPSampleResult.getBytes() with different options
long headerBytes = // condensed length (without \r)
(long) res.getResponseHeaders().length() + // Add \r for each header
(long) httpResponse.getAllHeaders().length + // Add \r for initial header
1L + // final \r\n before data
2L;
HttpConnectionMetrics metrics = (HttpConnectionMetrics) localContext.getAttribute(CONTEXT_ATTRIBUTE_METRICS);
long totalBytes = metrics.getReceivedBytesCount();
res.setHeadersSize((int) headerBytes);
res.setBodySize(totalBytes - headerBytes);
res.setSentBytes((Long) localContext.getAttribute(CONTEXT_ATTRIBUTE_SENT_BYTES));
if (log.isDebugEnabled()) {
long total = res.getHeadersSize() + res.getBodySizeAsLong();
log.debug("ResponseHeadersSize={} Content-Length={} Total={}", res.getHeadersSize(), res.getBodySizeAsLong(), total);
}
// If we redirected automatically, the URL may have changed
if (getAutoRedirects()) {
HttpUriRequest req = (HttpUriRequest) localContext.getAttribute(HttpCoreContext.HTTP_REQUEST);
HttpHost target = (HttpHost) localContext.getAttribute(HttpCoreContext.HTTP_TARGET_HOST);
URI redirectURI = req.getURI();
if (redirectURI.isAbsolute()) {
res.setURL(redirectURI.toURL());
} else {
res.setURL(new URL(new URL(target.toURI()), redirectURI.toString()));
}
}
// Store any cookies received in the cookie manager:
saveConnectionCookies(httpResponse, res.getURL(), getCookieManager());
// Save cache information
if (cacheManager != null) {
cacheManager.saveDetails(httpResponse, res);
}
// Follow redirects and download page resources if appropriate:
res = resultProcessing(areFollowingRedirect, frameDepth, res);
if (!isSuccessCode(statusCode)) {
EntityUtils.consumeQuietly(httpResponse.getEntity());
}
} catch (IOException e) {
log.debug("IOException", e);
if (res.getEndTime() == 0) {
res.sampleEnd();
}
// pick up headers if failed to execute the request
if (res.getRequestHeaders() != null) {
log.debug("Overwriting request old headers: {}", res.getRequestHeaders());
}
res.setRequestHeaders(getAllHeadersExceptCookie((HttpRequest) localContext.getAttribute(HttpCoreContext.HTTP_REQUEST)));
errorResult(e, res);
return res;
} catch (RuntimeException e) {
log.debug("RuntimeException", e);
if (res.getEndTime() == 0) {
res.sampleEnd();
}
errorResult(e, res);
return res;
} finally {
JOrphanUtils.closeQuietly(httpResponse);
currentRequest = null;
JMeterContextService.getContext().getSamplerContext().remove(CONTEXT_ATTRIBUTE_PARENT_SAMPLE_CLIENT_STATE);
}
return res;
}
use of org.apache.http.HttpConnectionMetrics in project jersey by jersey.
the class HelloWorldTest method testConnectionClosingOnExceptionsForErrorResponses.
/**
* JERSEY-2157 reproducer.
* <p>
* The test ensures that entities of the error responses which cause
* WebApplicationException being thrown by a JAX-RS client are buffered
* and that the underlying input connections are automatically released
* in such case.
*/
@Test
public void testConnectionClosingOnExceptionsForErrorResponses() {
final BasicClientConnectionManager cm = new BasicClientConnectionManager();
final AtomicInteger connectionCounter = new AtomicInteger(0);
final ClientConfig config = new ClientConfig().property(ApacheClientProperties.CONNECTION_MANAGER, new ClientConnectionManager() {
@Override
public SchemeRegistry getSchemeRegistry() {
return cm.getSchemeRegistry();
}
@Override
public ClientConnectionRequest requestConnection(final HttpRoute route, final Object state) {
connectionCounter.incrementAndGet();
final ClientConnectionRequest wrappedRequest = cm.requestConnection(route, state);
/**
* To explain the following long piece of code:
*
* All the code does is to just create a wrapper implementations
* for the AHC connection management interfaces.
*
* The only really important piece of code is the
* {@link org.apache.http.conn.ManagedClientConnection#releaseConnection()} implementation,
* where the connectionCounter is decremented when a managed connection instance
* is released by AHC runtime. In our test, this is expected to happen
* as soon as the exception is created for an error response
* (as the error response entity gets buffered in
* {@link org.glassfish.jersey.client.JerseyInvocation#convertToException(javax.ws.rs.core.Response)}).
*/
return new ClientConnectionRequest() {
@Override
public ManagedClientConnection getConnection(long timeout, TimeUnit tunit) throws InterruptedException, ConnectionPoolTimeoutException {
final ManagedClientConnection wrappedConnection = wrappedRequest.getConnection(timeout, tunit);
return new ManagedClientConnection() {
@Override
public boolean isSecure() {
return wrappedConnection.isSecure();
}
@Override
public HttpRoute getRoute() {
return wrappedConnection.getRoute();
}
@Override
public SSLSession getSSLSession() {
return wrappedConnection.getSSLSession();
}
@Override
public void open(HttpRoute route, HttpContext context, HttpParams params) throws IOException {
wrappedConnection.open(route, context, params);
}
@Override
public void tunnelTarget(boolean secure, HttpParams params) throws IOException {
wrappedConnection.tunnelTarget(secure, params);
}
@Override
public void tunnelProxy(HttpHost next, boolean secure, HttpParams params) throws IOException {
wrappedConnection.tunnelProxy(next, secure, params);
}
@Override
public void layerProtocol(HttpContext context, HttpParams params) throws IOException {
wrappedConnection.layerProtocol(context, params);
}
@Override
public void markReusable() {
wrappedConnection.markReusable();
}
@Override
public void unmarkReusable() {
wrappedConnection.unmarkReusable();
}
@Override
public boolean isMarkedReusable() {
return wrappedConnection.isMarkedReusable();
}
@Override
public void setState(Object state) {
wrappedConnection.setState(state);
}
@Override
public Object getState() {
return wrappedConnection.getState();
}
@Override
public void setIdleDuration(long duration, TimeUnit unit) {
wrappedConnection.setIdleDuration(duration, unit);
}
@Override
public boolean isResponseAvailable(int timeout) throws IOException {
return wrappedConnection.isResponseAvailable(timeout);
}
@Override
public void sendRequestHeader(HttpRequest request) throws HttpException, IOException {
wrappedConnection.sendRequestHeader(request);
}
@Override
public void sendRequestEntity(HttpEntityEnclosingRequest request) throws HttpException, IOException {
wrappedConnection.sendRequestEntity(request);
}
@Override
public HttpResponse receiveResponseHeader() throws HttpException, IOException {
return wrappedConnection.receiveResponseHeader();
}
@Override
public void receiveResponseEntity(HttpResponse response) throws HttpException, IOException {
wrappedConnection.receiveResponseEntity(response);
}
@Override
public void flush() throws IOException {
wrappedConnection.flush();
}
@Override
public void close() throws IOException {
wrappedConnection.close();
}
@Override
public boolean isOpen() {
return wrappedConnection.isOpen();
}
@Override
public boolean isStale() {
return wrappedConnection.isStale();
}
@Override
public void setSocketTimeout(int timeout) {
wrappedConnection.setSocketTimeout(timeout);
}
@Override
public int getSocketTimeout() {
return wrappedConnection.getSocketTimeout();
}
@Override
public void shutdown() throws IOException {
wrappedConnection.shutdown();
}
@Override
public HttpConnectionMetrics getMetrics() {
return wrappedConnection.getMetrics();
}
@Override
public InetAddress getLocalAddress() {
return wrappedConnection.getLocalAddress();
}
@Override
public int getLocalPort() {
return wrappedConnection.getLocalPort();
}
@Override
public InetAddress getRemoteAddress() {
return wrappedConnection.getRemoteAddress();
}
@Override
public int getRemotePort() {
return wrappedConnection.getRemotePort();
}
@Override
public void releaseConnection() throws IOException {
connectionCounter.decrementAndGet();
wrappedConnection.releaseConnection();
}
@Override
public void abortConnection() throws IOException {
wrappedConnection.abortConnection();
}
@Override
public String getId() {
return wrappedConnection.getId();
}
@Override
public void bind(Socket socket) throws IOException {
wrappedConnection.bind(socket);
}
@Override
public Socket getSocket() {
return wrappedConnection.getSocket();
}
};
}
@Override
public void abortRequest() {
wrappedRequest.abortRequest();
}
};
}
@Override
public void releaseConnection(ManagedClientConnection conn, long keepalive, TimeUnit tunit) {
cm.releaseConnection(conn, keepalive, tunit);
}
@Override
public void closeExpiredConnections() {
cm.closeExpiredConnections();
}
@Override
public void closeIdleConnections(long idletime, TimeUnit tunit) {
cm.closeIdleConnections(idletime, tunit);
}
@Override
public void shutdown() {
cm.shutdown();
}
});
config.connectorProvider(new ApacheConnectorProvider());
final Client client = ClientBuilder.newClient(config);
final WebTarget rootTarget = client.target(getBaseUri()).path(ROOT_PATH);
// Test that connection is getting closed properly for error responses.
try {
final String response = rootTarget.path("error").request().get(String.class);
fail("Exception expected. Received: " + response);
} catch (InternalServerErrorException isee) {
// do nothing - connection should be closed properly by now
}
// Fail if the previous connection has not been closed automatically.
assertEquals(0, connectionCounter.get());
try {
final String response = rootTarget.path("error2").request().get(String.class);
fail("Exception expected. Received: " + response);
} catch (InternalServerErrorException isee) {
assertEquals("Received unexpected data.", "Error2.", isee.getResponse().readEntity(String.class));
// Test buffering:
// second read would fail if entity was not buffered
assertEquals("Unexpected data in the entity buffer.", "Error2.", isee.getResponse().readEntity(String.class));
}
assertEquals(0, connectionCounter.get());
}
Aggregations