Index: httpclient/src/main/java/org/apache/http/client/jmx/HostStats.java
===================================================================
--- httpclient/src/main/java/org/apache/http/client/jmx/HostStats.java (revision )
+++ httpclient/src/main/java/org/apache/http/client/jmx/HostStats.java (revision )
@@ -0,0 +1,184 @@
+/*
+ * ====================================================================
+ * 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
+ * .
+ *
+ */
+
+package org.apache.http.client.jmx;
+
+import org.apache.http.conn.ConnectTimeoutException;
+import org.apache.http.conn.ConnectionPoolTimeoutException;
+
+import java.io.IOException;
+import java.util.Date;
+
+/**
+ * Houses per-host statistics related to HTTP instrumentation. These statistics
+ * cover areas of transaction rates, errors, and connection pooling.
+ *
+ * To obtain a HostStats object, see the HostStatsManager class.
+ *
+ * @see HostStatsManager
+ */
+public class HostStats implements HostStatsMBean {
+
+ private long statsStartTime;
+
+ // Request duration related stats
+ private long totalRequestDurationMillis;
+ private Long minRequestDurationMillis;
+ private long minRequestTime;
+ private long maxRequestDurationMillis = 0;
+ private long maxRequestTime;
+ private int requestCount;
+
+ // Timeout related stats
+ private int poolTimeoutCount;
+ private long mostRecentPoolTimeoutTime;
+ private int connectionTimeoutCount;
+ private long mostRecentConnectionTimeoutTime;
+ private int requestTimeoutCount;
+ private long mostRecentRequestTimeoutTime;
+
+ /**
+ * Default constructor.
+ */
+ public HostStats() {
+ this.statsStartTime = System.currentTimeMillis();
+ }
+
+ /**
+ * Records information about an request.
+ *
+ * @param requestDuration The duration of the request
+ */
+ public void recordDuration(long requestDuration) {
+ this.requestCount++;
+ this.totalRequestDurationMillis += requestDuration;
+
+ if (this.minRequestDurationMillis == null || requestDuration <= this.minRequestDurationMillis) {
+ this.minRequestDurationMillis = requestDuration;
+ this.minRequestTime = System.currentTimeMillis();
+ }
+
+ if (requestDuration >= this.maxRequestDurationMillis) {
+ this.maxRequestDurationMillis = requestDuration;
+ this.maxRequestTime = System.currentTimeMillis();
+ }
+ }
+
+ /**
+ * Records exception statistics.
+ *
+ * @param e The exception that occurred
+ */
+ public void recordException(Throwable e) {
+ if (e instanceof ConnectionPoolTimeoutException) {
+ this.poolTimeoutCount++;
+ this.mostRecentPoolTimeoutTime = System.currentTimeMillis();
+ } else if (e instanceof ConnectTimeoutException) {
+ this.connectionTimeoutCount++;
+ this.mostRecentConnectionTimeoutTime = System.currentTimeMillis();
+ } else if (e instanceof IOException) {
+ this.requestTimeoutCount++;
+ this.mostRecentRequestTimeoutTime = System.currentTimeMillis();
+ }
+ }
+
+ public Date getStatsStartTime() {
+ return new Date(this.statsStartTime);
+ }
+
+ public int getRequestCount() {
+ return this.requestCount;
+ }
+
+ public long getTotalRequestDurationMillis() {
+ return this.totalRequestDurationMillis;
+ }
+
+ public long getAverageRequestDurationMillis() {
+ return this.totalRequestDurationMillis / this.requestCount;
+ }
+
+ public long getMinimumRequestDurationMillis() {
+ return this.minRequestDurationMillis;
+ }
+
+ public Date getMinimumRequestTime() {
+ if (this.minRequestTime > 0) {
+ return new Date(this.minRequestTime);
+ } else {
+ return null;
+ }
+ }
+
+ public long getMaximumRequestDurationMillis() {
+ return this.maxRequestDurationMillis;
+ }
+
+ public Date getMaximumRequestTime() {
+ if (this.maxRequestTime > 0) {
+ return new Date(this.maxRequestTime);
+ } else {
+ return null;
+ }
+ }
+
+ public int getConnectionTimeoutCount() {
+ return this.connectionTimeoutCount;
+ }
+
+ public Date getMostRecentConnectionTimeoutTime() {
+ if (this.mostRecentConnectionTimeoutTime > 0) {
+ return new Date(this.mostRecentConnectionTimeoutTime);
+ } else {
+ return null;
+ }
+ }
+
+ public Date getMostRecentPoolTimeoutTime() {
+ if (this.mostRecentPoolTimeoutTime > 0) {
+ return new Date(this.mostRecentPoolTimeoutTime);
+ } else {
+ return null;
+ }
+ }
+
+ public Date getMostRecentRequestTimeoutTime() {
+ if (this.mostRecentRequestTimeoutTime > 0) {
+ return new Date(this.mostRecentRequestTimeoutTime);
+ } else {
+ return null;
+ }
+ }
+
+ public int getPoolTimeoutCount() {
+ return this.poolTimeoutCount;
+ }
+
+ public int getRequestTimeoutCount() {
+ return this.requestTimeoutCount;
+ }
+}
Index: httpclient/src/test/java/org/apache/http/client/jmx/HostStatsManagerTest.java
===================================================================
--- httpclient/src/test/java/org/apache/http/client/jmx/HostStatsManagerTest.java (revision )
+++ httpclient/src/test/java/org/apache/http/client/jmx/HostStatsManagerTest.java (revision )
@@ -0,0 +1,70 @@
+/*
+ * ====================================================================
+ * 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
+ * .
+ *
+ */
+
+package org.apache.http.client.jmx;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertNotNull;
+
+public class HostStatsManagerTest {
+
+ private static final String defaultUrl = "http://www.fakeurl.com";
+
+ private HostStatsManager hostStatsManager;
+
+ @Before
+ public void initialize() {
+ hostStatsManager = new HostStatsManager();
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void emptyUrl() throws Exception {
+ hostStatsManager.getHostStats("");
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void invalidUrl() throws Exception {
+ hostStatsManager.getHostStats("bad-url-goes-here");
+ }
+
+ @Test
+ public void testCreateHostStats() {
+ HostStats myHostStats = hostStatsManager.getHostStats(defaultUrl);
+
+ assertNotNull("test that getHostStats creates one if one does not exist", myHostStats);
+ }
+
+ @Test
+ public void unregisterStats() throws Exception {
+ // Nothing to check here, but we can at least exercise the code and make sure
+ // it doesn't throw an exception
+ hostStatsManager.getHostStats(defaultUrl);
+ hostStatsManager.unregisterHostStats();
+ }
+}
Index: httpclient/src/test/java/org/apache/http/client/jmx/HostStatsTest.java
===================================================================
--- httpclient/src/test/java/org/apache/http/client/jmx/HostStatsTest.java (revision )
+++ httpclient/src/test/java/org/apache/http/client/jmx/HostStatsTest.java (revision )
@@ -0,0 +1,105 @@
+/*
+ * ====================================================================
+ * 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
+ * .
+ *
+ */
+
+package org.apache.http.client.jmx;
+
+import org.apache.http.conn.ConnectTimeoutException;
+import org.apache.http.conn.ConnectionPoolTimeoutException;
+import org.junit.Before;
+import org.junit.Test;
+
+import javax.management.MalformedObjectNameException;
+import java.io.IOException;
+
+import static junit.framework.Assert.assertEquals;
+
+public class HostStatsTest {
+
+ private static final String defaultUrl = "http://www.fakeurl.com";
+
+ private HostStatsManager hostStatsManager;
+
+ @Before
+ public void initialize() {
+ hostStatsManager = new HostStatsManager();
+ }
+
+ @Test
+ public void testDurationHostStats() {
+ HostStats hostStats = hostStatsManager.getHostStats(defaultUrl);
+
+ hostStats.recordDuration(100);
+ hostStats.recordDuration(200);
+ hostStats.recordDuration(300);
+ hostStats.recordDuration(400);
+ hostStats.recordDuration(500);
+
+ // Look it up again and make sure it matches
+ HostStats durationHostStats = hostStatsManager.getHostStats(defaultUrl);
+
+ // Now verify the statistics themselves
+ assertEquals("test hostStats produces the correct request count", 5, durationHostStats.getRequestCount());
+ assertEquals("test hostStats produces the correct average request duration", 300, durationHostStats.getAverageRequestDurationMillis());
+ assertEquals("test hostStats produces the correct max request duration", 500, durationHostStats.getMaximumRequestDurationMillis());
+ assertEquals("test hostStats produces the correct min request duration", 100, durationHostStats.getMinimumRequestDurationMillis());
+ assertEquals("test hostStats produces the correct total request duration", 1500, durationHostStats.getTotalRequestDurationMillis());
+ }
+
+ @Test
+ public void testRequestDurationExceededThresholdStats() throws MalformedObjectNameException {
+ int threshold = 98765;
+
+ hostStatsManager.unregisterHostStats();
+ HostStats myHostStats = hostStatsManager.getHostStats(defaultUrl);
+
+ myHostStats.recordDuration(0);
+ myHostStats.recordDuration(threshold - 1);
+ myHostStats.recordDuration(threshold);
+ myHostStats.recordDuration(threshold + 1);
+ myHostStats.recordDuration(Integer.MAX_VALUE);
+
+ HostStats durationHostStats = hostStatsManager.getHostStats(defaultUrl);
+ assertEquals("test hostStats produces the correct max request duration", Integer.MAX_VALUE, durationHostStats.getMaximumRequestDurationMillis());
+ assertEquals("test hostStats produces the correct min request duration", 0, durationHostStats.getMinimumRequestDurationMillis());
+ }
+
+ @Test
+ public void testExceptionsHostStats() {
+
+ HostStats hostStats = hostStatsManager.getHostStats(defaultUrl);
+ hostStats.recordException(new ConnectionPoolTimeoutException());
+ hostStats.recordException(new ConnectTimeoutException());
+ hostStats.recordException(new IOException());
+ hostStats.recordException(new NullPointerException());
+ hostStats.recordException(new ConnectionPoolTimeoutException());
+
+ HostStats exceptionHostStats = hostStatsManager.getHostStats(defaultUrl);
+ assertEquals("test hostStats produces the correct connection timeout count", 1, exceptionHostStats.getConnectionTimeoutCount());
+ assertEquals("test hostStats produces the correct pool timeout count", 2, exceptionHostStats.getPoolTimeoutCount());
+ assertEquals("test hostStats produces the correct request timeout count", 1, exceptionHostStats.getRequestTimeoutCount());
+ }
+}
Index: httpclient/src/main/java/org/apache/http/client/jmx/HostStatsMBean.java
===================================================================
--- httpclient/src/main/java/org/apache/http/client/jmx/HostStatsMBean.java (revision )
+++ httpclient/src/main/java/org/apache/http/client/jmx/HostStatsMBean.java (revision )
@@ -0,0 +1,106 @@
+/*
+ * ====================================================================
+ * 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
+ * .
+ *
+ */
+
+package org.apache.http.client.jmx;
+
+import java.util.Date;
+
+/**
+ * Bean definition for host-specific JMX statistics.
+ */
+public interface HostStatsMBean {
+
+ /**
+ * @return The time at which statistics collection began
+ */
+ Date getStatsStartTime();
+
+ /**
+ * @return The number of HTTP requests that have been processed
+ */
+ int getRequestCount();
+
+ /**
+ * @return The total duration of all requests in milliseconds
+ */
+ long getTotalRequestDurationMillis();
+
+ /**
+ * @return The average request duration in milliseconds
+ */
+ long getAverageRequestDurationMillis();
+
+ /**
+ * @return The duration of the shortest request in milliseconds
+ */
+ long getMinimumRequestDurationMillis();
+
+ /**
+ * @return The time at which the shortest request occurred
+ */
+ Date getMinimumRequestTime();
+
+ /**
+ * @return The duration of the longest request in milliseconds
+ */
+ long getMaximumRequestDurationMillis();
+
+ /**
+ * @return The time at which the longest request occurred
+ */
+ Date getMaximumRequestTime();
+
+ /**
+ * @return The number of times a connection was not available from the pool
+ */
+ int getPoolTimeoutCount();
+
+ /**
+ * @return The time at which the most recent pool timeout occurred
+ */
+ Date getMostRecentPoolTimeoutTime();
+
+ /**
+ * @return The number of times timeouts occurred which establishing a connection to the host
+ */
+ int getConnectionTimeoutCount();
+
+ /**
+ * @return The time at which the most recent connection timeout occurred
+ */
+ Date getMostRecentConnectionTimeoutTime();
+
+ /**
+ * @return The number of times a request has timed out
+ */
+ int getRequestTimeoutCount();
+
+ /**
+ * @return The time of the most recent request timeout
+ */
+ Date getMostRecentRequestTimeoutTime();
+}
Index: httpclient/src/main/java/org/apache/http/client/jmx/HostStatsManager.java
===================================================================
--- httpclient/src/main/java/org/apache/http/client/jmx/HostStatsManager.java (revision )
+++ httpclient/src/main/java/org/apache/http/client/jmx/HostStatsManager.java (revision )
@@ -0,0 +1,154 @@
+/*
+ * ====================================================================
+ * 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
+ * .
+ *
+ */
+
+package org.apache.http.client.jmx;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.http.HttpHost;
+
+import javax.management.JMException;
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectInstance;
+import javax.management.ObjectName;
+import java.lang.management.ManagementFactory;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Creates and hands out HostsStats objects to callers. Also has
+ * utility methods for any tasks that deal with the entire
+ * HostStats collection.
+ */
+public class HostStatsManager {
+
+ private static final Log log = LogFactory.getLog(HostStatsManager.class);
+
+ private MBeanServer beanServer = ManagementFactory.getPlatformMBeanServer();
+ private Map hostStatBeans = new HashMap();
+
+ /**
+ * Look in our map of statistics to see if we've already instantiated one for the request.
+ * If so, hand it out. If not, instantiate one, register it, add it to our map, then hand it out.
+ *
+ * @param uriAsString The uri being used for the current request
+ * @return A HostStats object
+ */
+ public HostStats getHostStats(String uriAsString) {
+
+ // Take the incoming uri string and parse it apart. We do this so we can
+ // create the Host object, which the key for obtaining a HostStats object,
+ // and we also do it to create the bean name. Characters in a uri
+ // are not valid inside the bean naming structure.
+ URI uri;
+ HttpHost host;
+ String beanName;
+
+ try {
+ uri = new URI(uriAsString);
+ host = new HttpHost(uri.getHost(), uri.getPort(), uri.getScheme());
+ beanName = uri.getScheme() + "-" + uri.getHost() + "-" + uri.getPort();
+ } catch (URISyntaxException e) {
+ log.error("Exception: ", e);
+ return null;
+ }
+
+ log.trace("looking up stats object for " + host);
+
+ // Find the stats for the given host. If the stats object doesn't exist, create it.
+ HostStats hostStats = getHostStats(host, beanName);
+
+ log.trace("returning HostStats for " + host);
+
+ return hostStats;
+ }
+
+ /**
+ * Manages handing out and creating HostStats objects.
+ *
+ * @param host The HttpHost we want our stats object for
+ * @param beanName The bean name to use in case the HostStats object needs to be created
+ * @return A HostStats object for the given host
+ */
+ private synchronized HostStats getHostStats(HttpHost host, String beanName) {
+ HostStats hostStats = hostStatBeans.get(host);
+ if (hostStats == null) {
+ log.trace("creating MBean for " + host);
+ try {
+ ObjectName name = new ObjectName(makeJmxName(beanName));
+ hostStats = new HostStats();
+ beanServer.registerMBean(hostStats, name);
+ log.debug("registered bean " + name);
+ } catch (Throwable e) {
+ log.error("could not register MBean for " + host.toString(), e);
+ }
+ hostStatBeans.put(host, hostStats);
+ }
+
+ return hostStats;
+ }
+
+ /**
+ * Method to unregister all JMX beans we've registered as the webapp is shutting down.
+ *
+ * @throws javax.management.MalformedObjectNameException when object name is invalid
+ */
+ public void unregisterHostStats() throws MalformedObjectNameException {
+
+ log.debug("Unregistering JMX Beans");
+
+ // Create a wildcarded name to query for all beans that we registered
+ ObjectName queryName = new ObjectName(makeJmxName("*"));
+
+ // Query for all the beans we registered and unregister each of them
+ Set beans = beanServer.queryMBeans(queryName, null);
+ for (ObjectInstance oi : beans) {
+ try {
+ beanServer.unregisterMBean(oi.getObjectName());
+ log.debug("Unregistered " + oi.getObjectName());
+ } catch (JMException e) {
+ log.error("Exception unregistering " + oi.getObjectName() + ": ", e);
+ }
+ }
+
+ hostStatBeans.clear();
+ }
+
+ /**
+ * Creates a JMX name given the logical name.
+ *
+ * @param name The logical name of the bean
+ * @return A JMX-friendly name for the bean
+ */
+ private String makeJmxName(String name) {
+ return "org.apache.http:category=" + name + ",type=Pools";
+ }
+}
Index: httpclient/src/main/java/org/apache/http/client/jmx/JmxEnabledHttpClient.java
===================================================================
--- httpclient/src/main/java/org/apache/http/client/jmx/JmxEnabledHttpClient.java (revision )
+++ httpclient/src/main/java/org/apache/http/client/jmx/JmxEnabledHttpClient.java (revision )
@@ -0,0 +1,217 @@
+/*
+ * ====================================================================
+ * 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
+ * .
+ *
+ */
+
+package org.apache.http.client.jmx;
+
+import org.apache.http.HttpHost;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.ResponseHandler;
+import org.apache.http.client.methods.HttpUriRequest;
+import org.apache.http.conn.ClientConnectionManager;
+import org.apache.http.params.HttpParams;
+import org.apache.http.protocol.HttpContext;
+
+import java.io.IOException;
+
+/**
+ * This class uses the decorator pattern to introduce JMX statistics to
+ * Apache HttpClient version 4.
+ */
+public class JmxEnabledHttpClient implements HttpClient {
+
+ private HttpClient client;
+
+ private HostStatsManager hostStatsManager;
+
+ /**
+ * Constructs an JmxEnabledHttpClient given an HttpClient.
+ *
+ * @param client The HttpClient to decorate
+ */
+ public JmxEnabledHttpClient(HttpClient client) {
+ this.client = client;
+ this.hostStatsManager = new HostStatsManager();
+ }
+
+ public HttpResponse execute(HttpUriRequest request) throws IOException {
+ HttpResponse response;
+
+ HostStats stats = hostStatsManager.getHostStats(request.getRequestLine().getUri());
+ long requestStartTime = System.currentTimeMillis();
+
+ try {
+ response = this.client.execute(request);
+ } catch (IOException e) {
+ stats.recordException(e);
+ throw e;
+ }
+
+ recordDuration(stats, System.currentTimeMillis() - requestStartTime);
+
+ return response;
+ }
+
+ public HttpResponse execute(HttpUriRequest request, HttpContext context) throws IOException {
+ HttpResponse response;
+
+ HostStats stats = hostStatsManager.getHostStats(request.getRequestLine().getUri());
+ long requestStartTime = System.currentTimeMillis();
+
+ try {
+ response = this.client.execute(request, context);
+ } catch (IOException e) {
+ stats.recordException(e);
+ throw e;
+ }
+
+ recordDuration(stats, System.currentTimeMillis() - requestStartTime);
+
+ return response;
+ }
+
+ public HttpResponse execute(HttpHost target, HttpRequest request) throws IOException {
+ HttpResponse response;
+
+ HostStats stats = hostStatsManager.getHostStats(request.getRequestLine().getUri());
+ long requestStartTime = System.currentTimeMillis();
+
+ try {
+ response = this.client.execute(target, request);
+ } catch (IOException e) {
+ stats.recordException(e);
+ throw e;
+ }
+
+ recordDuration(stats, System.currentTimeMillis() - requestStartTime);
+
+ return response;
+ }
+
+ public T execute(HttpUriRequest request, ResponseHandler extends T> responseHandler) throws IOException {
+ T response;
+
+ HostStats stats = hostStatsManager.getHostStats(request.getRequestLine().getUri());
+ long requestStartTime = System.currentTimeMillis();
+
+ try {
+ response = this.client.execute(request, responseHandler);
+ } catch (IOException e) {
+ stats.recordException(e);
+ throw e;
+ }
+
+ recordDuration(stats, System.currentTimeMillis() - requestStartTime);
+
+ return response;
+ }
+
+ public T execute(HttpUriRequest request, ResponseHandler extends T> responseHandler, HttpContext context) throws IOException {
+ T response;
+
+ HostStats stats = hostStatsManager.getHostStats(request.getRequestLine().getUri());
+ long requestStartTime = System.currentTimeMillis();
+
+ try {
+ response = this.client.execute(request, responseHandler, context);
+ } catch (IOException e) {
+ stats.recordException(e);
+ throw e;
+ }
+
+ recordDuration(stats, System.currentTimeMillis() - requestStartTime);
+
+ return response;
+ }
+
+ public T execute(HttpHost target, HttpRequest request, ResponseHandler extends T> responseHandler) throws IOException {
+ T response;
+
+ HostStats stats = hostStatsManager.getHostStats(request.getRequestLine().getUri());
+ long requestStartTime = System.currentTimeMillis();
+
+ try {
+ response = this.client.execute(target, request, responseHandler);
+ } catch (IOException e) {
+ stats.recordException(e);
+ throw e;
+ }
+
+ recordDuration(stats, System.currentTimeMillis() - requestStartTime);
+
+ return response;
+ }
+
+ public T execute(HttpHost target, HttpRequest request, ResponseHandler extends T> responseHandler, HttpContext context) throws IOException {
+ T response;
+
+ HostStats stats = hostStatsManager.getHostStats(request.getRequestLine().getUri());
+ long requestStartTime = System.currentTimeMillis();
+
+ try {
+ response = this.client.execute(target, request, responseHandler, context);
+ } catch (IOException e) {
+ stats.recordException(e);
+ throw e;
+ }
+
+ recordDuration(stats, System.currentTimeMillis() - requestStartTime);
+
+ return response;
+ }
+
+ public HttpResponse execute(HttpHost target, HttpRequest request, HttpContext context) throws IOException {
+ HttpResponse response;
+
+ HostStats stats = hostStatsManager.getHostStats(request.getRequestLine().getUri());
+ long requestStartTime = System.currentTimeMillis();
+
+ try {
+ response = this.client.execute(target, request, context);
+ } catch (IOException e) {
+ stats.recordException(e);
+ throw e;
+ }
+
+ recordDuration(stats, System.currentTimeMillis() - requestStartTime);
+
+ return response;
+ }
+
+ public ClientConnectionManager getConnectionManager() {
+ return this.client.getConnectionManager();
+ }
+
+ public HttpParams getParams() {
+ return this.client.getParams();
+ }
+
+ private void recordDuration(HostStats stats, long duration) {
+ stats.recordDuration(duration);
+ }
+}