You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by ri...@apache.org on 2008/01/24 19:24:25 UTC
svn commit: r614952 - in /geronimo/sandbox/AsyncHttpClient/src:
main/java/org/apache/ahc/ main/java/org/apache/ahc/codec/
main/java/org/apache/ahc/util/ test/java/org/apache/ahc/
Author: rickmcguire
Date: Thu Jan 24 10:24:21 2008
New Revision: 614952
URL: http://svn.apache.org/viewvc?rev=614952&view=rev
Log:
GERONIMO-3761 Add data collection and instrumentation to the AsyncHttpClient
Developed with a lot of assistance from Sangjin Lee.
Added:
geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/CountingMonitor.java (with props)
geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/DaemonThreadFactory.java (with props)
geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/EventDispatcher.java (with props)
geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/MonitoringEvent.java (with props)
geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/MonitoringListener.java (with props)
geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/TimeMonitor.java (with props)
geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/MonitoringTest.java (with props)
Modified:
geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/AsyncHttpClient.java
geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpIoHandler.java
geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpRequestMessage.java
geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/RetryTest.java
Modified: geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/AsyncHttpClient.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/AsyncHttpClient.java?rev=614952&r1=614951&r2=614952&view=diff
==============================================================================
--- geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/AsyncHttpClient.java (original)
+++ geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/AsyncHttpClient.java Thu Jan 24 10:24:21 2008
@@ -39,6 +39,9 @@
import org.apache.ahc.proxy.ProxyFilter;
import org.apache.ahc.ssl.TrustManagerFactoryImpl;
import org.apache.ahc.util.AsyncHttpClientException;
+import org.apache.ahc.util.EventDispatcher;
+import org.apache.ahc.util.MonitoringEvent;
+import org.apache.ahc.util.MonitoringListener;
import org.apache.mina.common.ConnectFuture;
import org.apache.mina.common.IoFuture;
import org.apache.mina.common.IoFutureListener;
@@ -144,7 +147,10 @@
/** flag to make this as having been disposed of */
private boolean destroyed = false;
-
+
+ /** a dispatcher for dispatching monitoring events */
+ private EventDispatcher eventDispatcher;
+
public static final String SSL_FILTER = "SSL";
public static final String PROTOCOL_FILTER = "protocolFilter";
public static final String PROXY_FILTER = "proxyFilter";
@@ -453,6 +459,11 @@
throw new IllegalStateException("AsyncHttpClient has been destroyed and cannot be reused.");
}
+ // set the request start time
+ message.setRequestStartTime();
+ // notify any interesting parties that this is starting
+ notifyMonitoringListeners(MonitoringEvent.REQUEST_STARTED, message);
+
// we need to provide a new result future and associate it with the
// request unless it already exists (i.e. sendRequest() is called
// multiple times for the request)
@@ -476,6 +487,12 @@
// if no cached connection is found or keep-alive is disabled, force a
// new connection
if (future == null) {
+ // set the connect start time
+ message.setConnectStartTime();
+ // NB: We broadcast this here rather than in open connection to avoid
+ // having a connection retry result in both a CONNECTION_ATTEMPTED and
+ // CONNECTION_RETRIED event getting dispatched.
+ notifyMonitoringListeners(MonitoringEvent.CONNECTION_ATTEMPTED, message);
future = openConnection(message);
}
ResponseFuture response = message.getResponseFuture();
@@ -498,6 +515,9 @@
* used for the previous attempt.
*/
private void retryConnection(HttpRequestMessage message, ResponseFuture response, FutureListener listener) {
+ // set the connect start time again
+ message.setConnectStartTime();
+ notifyMonitoringListeners(MonitoringEvent.CONNECTION_RETRIED, message);
ConnectFuture future = openConnection(message);
future.addListener(listener);
}
@@ -534,6 +554,9 @@
return null;
}
+ // clear the connect start time to prevent misreporting
+ message.clearConnectStartTime();
+ notifyMonitoringListeners(MonitoringEvent.CONNECTION_REUSED, message);
// create a containing future object and set the session right away
ConnectFuture future = new DefaultConnectFuture();
future.setSession(cached);
@@ -576,6 +599,7 @@
if (connector != null) {
connector.setWorkerTimeout(0);
}
+
// release the thread pool references
threadPool = null;
eventThreadPool = null;
@@ -584,6 +608,48 @@
}
/**
+ * Add a statistics listener to this client object.
+ *
+ * @param listener The listener to add.
+ */
+ public void addMonitoringListener(MonitoringListener listener) {
+ synchronized (this) {
+ // we've deferred creation until we have someone listening
+ if (eventDispatcher == null) {
+ eventDispatcher = new EventDispatcher();
+ }
+ }
+ eventDispatcher.addListener(listener);
+ }
+
+ /**
+ * Remove a listener from the client.
+ *
+ * @param listener The listener to remove.
+ */
+ public void removeMonitoringListener(MonitoringListener listener) {
+ if (eventDispatcher != null) {
+ eventDispatcher.removeListener(listener);
+ }
+ }
+
+ /**
+ * Send a notification event to any monitoring listeners.
+ *
+ * @param type The type of event.
+ * @param request The HttpRequestMessage that triggerd the event.
+ */
+ public void notifyMonitoringListeners(int type, HttpRequestMessage request) {
+ // if there's no event dispatcher, no point in dispatching this
+ if (eventDispatcher == null) {
+ return;
+ }
+
+ MonitoringEvent event = new MonitoringEvent(type, request);
+ eventDispatcher.dispatchEvent(event);
+ }
+
+ /**
* The listener interface for receiving connection events. Its main purpose is to notify the
* callback of any exceptions that may have occurred, or to handle the session and inject
* the proper SSL filter if the connection is to be used for <code>https</code>. If a good
@@ -619,6 +685,7 @@
public void operationComplete(IoFuture future) {
ConnectFuture connFuture = (ConnectFuture) future;
if (connFuture.isConnected()) {
+ notifyMonitoringListeners(MonitoringEvent.CONNECTION_SUCCESSFUL, request);
IoSession sess = future.getSession();
// see if we need to add the SSL filter
@@ -641,6 +708,7 @@
}
else {
try {
+ notifyMonitoringListeners(MonitoringEvent.CONNECTION_FAILED, request);
future.getSession();
response.setException(new AsyncHttpClientException("Connection failed."));
} catch (RuntimeIOException e) {
Modified: geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpIoHandler.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpIoHandler.java?rev=614952&r1=614951&r2=614952&view=diff
==============================================================================
--- geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpIoHandler.java (original)
+++ geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpIoHandler.java Thu Jan 24 10:24:21 2008
@@ -33,6 +33,7 @@
import org.apache.ahc.auth.AuthScheme;
import org.apache.ahc.auth.AuthState;
import org.apache.ahc.util.NameValuePair;
+import org.apache.ahc.util.MonitoringEvent;
import org.apache.mina.common.IoHandlerAdapter;
import org.apache.mina.common.IoSession;
@@ -133,6 +134,8 @@
HttpResponseMessage response = (HttpResponseMessage) object;
HttpRequestMessage request = (HttpRequestMessage) ioSession.getAttribute(CURRENT_REQUEST);
+
+ AsyncHttpClient client = (AsyncHttpClient) ioSession.getAttachment();
//Check if we are to handle redirects
if ((response.getStatusCode() == 301
@@ -140,8 +143,9 @@
|| response.getStatusCode() == 307)
&& request.isFollowRedirects())
{
- AsyncHttpClient client = (AsyncHttpClient) ioSession.getAttachment();
+ // notify any interesting parties that this is starting
+ client.notifyMonitoringListeners(MonitoringEvent.REQUEST_REDIRECTED, request);
//Change the request url to the redirect
request.setUrl(new URL(response.getLocation()));
// if we're redirected via 30x, the request method should be reset to GET
@@ -166,6 +170,8 @@
//Check if we have authentication
if (response.getChallenges().size() > 0) {
+ // notify any interesting parties that this is starting
+ client.notifyMonitoringListeners(MonitoringEvent.REQUEST_CHALLENGED, request);
for (NameValuePair nvp : response.getChallenges()) {
AuthState state = request.getAuthState();
if (state == null) {
@@ -178,14 +184,9 @@
}
}
- AsyncHttpClient client = (AsyncHttpClient) ioSession.getAttachment();
-
//Authenticate
int authCount = request.getAuthCount() + 1;
if (authCount <= 3) {
- request.setAuthCount(authCount);
- client.sendRequest(request);
-
// if we've been provided with a cache, put this session into
// the cache.
SessionCache cache = getSessionCache();
@@ -193,12 +194,18 @@
// cache the session before we return
cache.cacheSession(ioSession);
}
+
+ request.setAuthCount(authCount);
+ client.sendRequest(request);
+
return;
}
}
cancelTasks(request);
+ // notify any interesting parties that this is starting
+ client.notifyMonitoringListeners(MonitoringEvent.REQUEST_COMPLETED, request);
// complete the future which will also fire the callback
ResponseFuture result = request.getResponseFuture();
result.set(response);
@@ -225,11 +232,17 @@
HttpRequestMessage request = (HttpRequestMessage) ioSession.getAttribute(CURRENT_REQUEST);
cancelTasks(request);
+
+ AsyncHttpClient client = (AsyncHttpClient) ioSession.getAttachment();
+ // notify any interesting parties that this is starting
+ client.notifyMonitoringListeners(MonitoringEvent.REQUEST_FAILED, request);
// complete the future which will also fire the callback
ResponseFuture result = request.getResponseFuture();
result.setException(throwable);
+ // notify any interesting parties that this is starting
+ client.notifyMonitoringListeners(MonitoringEvent.CONNECTION_CLOSED_BY_SERVER, request);
//Exception is bad, so just close it up
ioSession.close();
}
@@ -253,6 +266,10 @@
}
HttpRequestMessage request = (HttpRequestMessage) ioSession.getAttribute(CURRENT_REQUEST);
cancelTasks(request);
+ AsyncHttpClient client = (AsyncHttpClient) ioSession.getAttachment();
+ // notify any interesting parties that this is starting
+ client.notifyMonitoringListeners(MonitoringEvent.CONNECTION_CLOSED_BY_SERVER, request);
+
AsyncHttpClientCallback callback = request.getCallback();
if (callback != null) {
callback.onClosed();
@@ -323,6 +340,12 @@
public void run() {
// complete the future which will also fire the callback
HttpRequestMessage request = (HttpRequestMessage)sess.getAttribute(CURRENT_REQUEST);
+
+ AsyncHttpClient client = (AsyncHttpClient) sess.getAttachment();
+
+ // notify any interesting parties that this is starting
+ client.notifyMonitoringListeners(MonitoringEvent.REQUEST_TIMEOUT, request);
+
ResponseFuture result = request.getResponseFuture();
result.setException(new TimeoutException());
Modified: geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpRequestMessage.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpRequestMessage.java?rev=614952&r1=614951&r2=614952&view=diff
==============================================================================
--- geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpRequestMessage.java (original)
+++ geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/HttpRequestMessage.java Thu Jan 24 10:24:21 2008
@@ -158,6 +158,10 @@
private SSLContext sslContext;
private ProxyConfiguration proxyConfig;
+
+ private volatile long requestStartTime = 0L;
+
+ private volatile long connectStartTime = 0L;
/**
* Instantiates a new http request message.
@@ -578,5 +582,54 @@
*/
public boolean isProxyEnabled() {
return proxyConfig != null && !proxyConfig.isExcluded(getUrl());
+ }
+
+ /**
+ * Return the time when the request was first initiated.
+ *
+ * @return The time, in milliseconds, for when request processing
+ * was initiated.
+ */
+ public long getRequestStartTime() {
+ return requestStartTime;
+ }
+
+ /**
+ * Mark the start of request processing.
+ */
+ public void setRequestStartTime() {
+ requestStartTime = System.nanoTime()/1000000;
+ }
+
+ /**
+ * Clear the request starting time back to zero.
+ */
+ public void clearRequestStartTime() {
+ requestStartTime = 0L;
+ }
+
+ /**
+ * Get the time stamp for when the connection request was
+ * started.
+ *
+ * @return The timestamp (in milliseconds) for when the connection
+ * for this message request was initiated.
+ */
+ public long getConnectStartTime() {
+ return connectStartTime;
+ }
+
+ /**
+ * Set the timestamp for connection initiation.
+ */
+ public void setConnectStartTime() {
+ connectStartTime = System.nanoTime()/1000000;
+ }
+
+ /**
+ * Reset the connection start time.
+ */
+ public void clearConnectStartTime() {
+ connectStartTime = 0L;
}
}
Added: geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/CountingMonitor.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/CountingMonitor.java?rev=614952&view=auto
==============================================================================
--- geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/CountingMonitor.java (added)
+++ geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/CountingMonitor.java Thu Jan 24 10:24:21 2008
@@ -0,0 +1,83 @@
+/*
+ * 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.
+ */
+
+package org.apache.ahc.util;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * Simple implementation of an AsyncHttpMonitor that
+ * just keeps a count of all of the events.
+ */
+public class CountingMonitor implements MonitoringListener {
+ private AtomicInteger[] counters =
+ new AtomicInteger[MonitoringEvent.CONNECTION_CLOSED + 1];
+
+ /**
+ * Default constructor
+ */
+ public CountingMonitor() {
+ for (int i = 0; i < counters.length; i++) {
+ counters[i] = new AtomicInteger(0);
+ }
+ }
+
+ /**
+ * Handle a notification event from an AsyncHttpClient.
+ *
+ * @param event The triggered event.
+ */
+ public void notification(MonitoringEvent event) {
+ int type = event.getType();
+ if (type < counters.length) {
+ counters[type].incrementAndGet();
+ }
+ }
+
+
+ /**
+ * Get the counter from a specific MonitoringEvent.
+ *
+ * @param type The type number of the event.
+ *
+ * @return The current counter value.
+ */
+ public int getCount(int type) {
+ // we only return values for ones in the defined range. Anything else is
+ // zero.
+ if (type < counters.length) {
+ return counters[type].get();
+ } else {
+ return 0;
+ }
+ }
+
+
+ /**
+ * Zero all of the event counters.
+ */
+ public void clearCounters() {
+ AtomicInteger[] newCounters = new AtomicInteger[MonitoringEvent.CONNECTION_CLOSED + 1];
+ for (int i = 0; i < newCounters.length; i++) {
+ newCounters[i] = new AtomicInteger(0);
+ }
+ counters = newCounters;
+ }
+}
+
Propchange: geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/CountingMonitor.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/CountingMonitor.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/CountingMonitor.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/DaemonThreadFactory.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/DaemonThreadFactory.java?rev=614952&view=auto
==============================================================================
--- geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/DaemonThreadFactory.java (added)
+++ geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/DaemonThreadFactory.java Thu Jan 24 10:24:21 2008
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+package org.apache.ahc.util;
+
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+
+/**
+ * Simple implementation of a ThreadFactory that
+ * marks all of the threads as daemon threads.
+ */
+public class DaemonThreadFactory implements ThreadFactory {
+ private final ThreadFactory factory = Executors.defaultThreadFactory();
+
+ /**
+ * Create a new thread for the thread pool. The create
+ * thread will be a daemon thread.
+ *
+ * @param r The runnable used by the thread pool.
+ *
+ * @return The newly created thread.
+ */
+ public Thread newThread(Runnable r) {
+ Thread t = factory.newThread(r);
+ if (!t.isDaemon()) {
+ t.setDaemon(true);
+ }
+ return t;
+ }
+
+}
Propchange: geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/DaemonThreadFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/DaemonThreadFactory.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/DaemonThreadFactory.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/EventDispatcher.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/EventDispatcher.java?rev=614952&view=auto
==============================================================================
--- geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/EventDispatcher.java (added)
+++ geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/EventDispatcher.java Thu Jan 24 10:24:21 2008
@@ -0,0 +1,95 @@
+/*
+ * 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.
+ */
+
+package org.apache.ahc.util;
+
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+/**
+ * This is an event dispatcher to dispatch monitoring events on separate threads
+ * from the main thread.
+ * @version $Rev$ $Date$
+ */
+public class EventDispatcher {
+ /** shared thread pool for dispatching events */
+ private static ExecutorService dispatchThreadPool;
+
+ /** list of listeners for monitoring events */
+ private final List<MonitoringListener> listeners =
+ new CopyOnWriteArrayList<MonitoringListener>();
+
+ /**
+ * Creates a new EventDispatcher, including starting the new thread.
+ */
+ public EventDispatcher() {
+ // initialize the thread pool if it is not initialized yet
+ synchronized (EventDispatcher.class) {
+ if (dispatchThreadPool == null) {
+ dispatchThreadPool = Executors.newSingleThreadExecutor(new DaemonThreadFactory());
+ }
+ }
+ }
+
+ /**
+ * Add a listener for the dispatched events.
+ *
+ * @param listener The new listener.
+ */
+ public void addListener(MonitoringListener listener) {
+ listeners.add(listener);
+ }
+
+ /**
+ * Remove a listener from the dispatch queue.
+ *
+ * @param listener The listener to remove.
+ */
+ public void removeListener(MonitoringListener listener) {
+ listeners.remove(listener);
+ }
+
+ /**
+ * Dispatch an event.
+ *
+ * @param event The event to dispatch.
+ */
+ public void dispatchEvent(final MonitoringEvent event) {
+ // if there's no active listeners, no point in dispatching this
+ if (listeners.isEmpty()) {
+ return;
+ }
+
+ Runnable job = new Runnable() {
+ public void run() {
+ // iterate through the listeners list calling the handlers.
+ for (MonitoringListener listener : listeners) {
+ try {
+ event.dispatch(listener);
+ } catch (Throwable e) {
+ // just eat these
+ }
+ }
+ }
+ };
+ dispatchThreadPool.execute(job);
+ }
+}
Propchange: geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/EventDispatcher.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/EventDispatcher.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/EventDispatcher.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/MonitoringEvent.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/MonitoringEvent.java?rev=614952&view=auto
==============================================================================
--- geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/MonitoringEvent.java (added)
+++ geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/MonitoringEvent.java Thu Jan 24 10:24:21 2008
@@ -0,0 +1,162 @@
+/*
+ * 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.
+ */
+
+package org.apache.ahc.util;
+
+import org.apache.ahc.codec.HttpRequestMessage;
+
+/**
+ * An event triggered during various lifecycle events
+ * of an HTTP request. Intended for collection of
+ * performance and general monitoring status.
+ */
+public class MonitoringEvent {
+ /**
+ * The event was triggered by a new HTTP request.
+ */
+ public static final int REQUEST_STARTED = 0;
+ /**
+ * The event was triggered by successful completion of
+ * an HTTP request.
+ */
+ public static final int REQUEST_COMPLETED = 1;
+ /**
+ * The event was triggered by a failure return from
+ * an HTTP request.
+ */
+ public static final int REQUEST_FAILED = 2;
+ /**
+ * The event was triggered due to a timeout while
+ * waiting for an HTTP request to complete.
+ */
+ public static final int REQUEST_TIMEOUT = 3;
+ /**
+ * Indicates a new connection attempt.
+ */
+ public static final int CONNECTION_ATTEMPTED = 4;
+ /**
+ * Indicates a failure occurred when attempting to
+ * connect to a host.
+ */
+ public static final int CONNECTION_FAILED = 5;
+ /**
+ * Indicates an attempt at retrying a host connect.
+ */
+ public static final int CONNECTION_RETRIED = 6;
+ /**
+ * Indicates an existing connection is being reused
+ * for a request.
+ */
+ public static final int CONNECTION_REUSED = 7;
+ /**
+ * Indicates a connection was successfully established
+ * for a request.
+ */
+ public static final int CONNECTION_SUCCESSFUL = 8;
+ /**
+ * The request was redirected to a different location.
+ */
+ public static final int REQUEST_REDIRECTED = 9;
+ /**
+ * An authentication challenge was received for the request
+ */
+ public static final int REQUEST_CHALLENGED = 10;
+ /**
+ * Indicates the connection was closed by the server.
+ */
+ public static final int CONNECTION_CLOSED_BY_SERVER = 11;
+ /**
+ * Indicates the connection was closed by the client.
+ */
+ public static final int CONNECTION_CLOSED = 12;
+
+ /** the type of the event */
+ private final int eventType;
+ /** timestamp of when the event occurred */
+ private final long timeStamp;
+ /** the request message associated with the event */
+ private final HttpRequestMessage request;
+
+ /**
+ * Create a new monitoring event.
+ *
+ * @param eventType The type of event.
+ * @param request The Http request that his event is triggered by.
+ *
+ * @see #REQUEST_STARTED
+ * @see #REQUEST_COMPLETED
+ * @see #REQUEST_FAILED
+ * @see #REQUEST_TIMEOUT
+ * @see #CONNECTION_ATTEMPTED
+ * @see #CONNECTION_FAILED
+ * @see #CONNECTION_RETRIED
+ * @see #CONNECTION_REUSED
+ * @see #CONNECTION_SUCCESSFUL
+ * @see #REQUEST_REDIRECTED
+ * @see #REQUEST_CHALLENGED
+ * @see #CONNECTION_CLOSED_BY_SERVER
+ * @see #CONNECTION_CLOSED
+ */
+ public MonitoringEvent(int eventType, HttpRequestMessage request) {
+ this.eventType = eventType;
+ this.request = request;
+ // timestamp the event (hi-res)
+ this.timeStamp = System.nanoTime()/1000000;
+ }
+
+ /**
+ * Returns the type code for the event.
+ *
+ * @return The integer type code for the event.
+ */
+ public int getType() {
+ return eventType;
+ }
+
+ /**
+ * Get the HTTP request that is associated with this event.
+ *
+ * @return The HTTP message request being processed when one
+ * of these events occurred.
+ */
+ public HttpRequestMessage getRequest()
+ {
+ return request;
+ }
+
+ /**
+ * Returns the timestamp that was taken when the event
+ * was generated.
+ *
+ * @return The hi-res timer value (in ms) for when the
+ * event was generated.
+ */
+ public long getTimeStamp() {
+ return timeStamp;
+ }
+
+ /**
+ * Dispatch an event to a listener.
+ *
+ * @param listener The target listener
+ */
+ public void dispatch(Object listener) {
+ ((MonitoringListener)listener).notification(this);
+ }
+}
Propchange: geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/MonitoringEvent.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/MonitoringEvent.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/MonitoringEvent.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/MonitoringListener.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/MonitoringListener.java?rev=614952&view=auto
==============================================================================
--- geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/MonitoringListener.java (added)
+++ geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/MonitoringListener.java Thu Jan 24 10:24:21 2008
@@ -0,0 +1,34 @@
+/**
+ *
+ * Copyright 2003-2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+package org.apache.ahc.util;
+
+import java.util.EventListener;
+
+/**
+ * The interface for listening for monitoring events.
+ * @version $Rev$ $Date$
+ */
+public interface MonitoringListener extends EventListener {
+ /**
+ * Process a notification for a MonitoringEvent.
+ *
+ * @param event The particular event to be processed.
+ */
+ public void notification(MonitoringEvent event);
+}
+
Propchange: geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/MonitoringListener.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/MonitoringListener.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/MonitoringListener.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/TimeMonitor.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/TimeMonitor.java?rev=614952&view=auto
==============================================================================
--- geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/TimeMonitor.java (added)
+++ geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/TimeMonitor.java Thu Jan 24 10:24:21 2008
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ *
+ */
+package org.apache.ahc.util;
+
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * Simple monitoring listener for tracking average
+ * request times.
+ */
+public final class TimeMonitor extends CountingMonitor {
+ private final AtomicInteger requestCount = new AtomicInteger();
+ private final AtomicLong requestTimes = new AtomicLong();
+
+ @Override
+ /**
+ * Process a notification event. If this is a
+ * REQUEST_COMPLETED event, the request timeing
+ * information is added to the accumulators to that
+ * average response time can be calculated.
+ *
+ * @param event The notification event.
+ */
+ public void notification(MonitoringEvent event) {
+ super.notification(event);
+ // get the response time
+ int type = event.getType();
+ if (type == MonitoringEvent.REQUEST_COMPLETED) {
+ requestCount.incrementAndGet();
+ long elapsed = event.getTimeStamp() - event.getRequest().getRequestStartTime();
+ requestTimes.addAndGet(elapsed);
+ }
+ }
+
+ /**
+ * Return the average calculated response time for
+ * the processed requests.
+ *
+ * @return The average response time, in milliseconds, for
+ * all recorded completed requests.
+ */
+ public long getAverageResponseTime() {
+ if (requestCount.get() == 0) {
+ return 0L;
+ }
+ return requestTimes.get()/requestCount.get();
+ }
+}
Propchange: geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/TimeMonitor.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/TimeMonitor.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/util/TimeMonitor.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/MonitoringTest.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/MonitoringTest.java?rev=614952&view=auto
==============================================================================
--- geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/MonitoringTest.java (added)
+++ geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/MonitoringTest.java Thu Jan 24 10:24:21 2008
@@ -0,0 +1,179 @@
+/*
+ * 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.
+ *
+ */
+package org.apache.ahc;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.ahc.codec.HttpRequestMessage;
+import org.apache.ahc.codec.HttpResponseMessage;
+import org.apache.ahc.util.CountingMonitor;
+import org.apache.ahc.util.MonitoringEvent;
+import org.apache.ahc.util.MonitoringListener;
+
+public class MonitoringTest extends AbstractTest {
+
+ public void testHtmlConnection() throws Exception {
+ TestCallback callback = new TestCallback();
+ CountingMonitor counter = new CountingMonitor();
+ doGetConnection(callback, "http://localhost:8282/", false, true, counter);
+
+ HttpResponseMessage msg = callback.getMessage();
+ assertEquals("\nHello World!", msg.getStringContent());
+
+ // the monitor events are dispatched asynchronously, so give a little time
+ // for them all to be dispatched.
+ Thread.sleep(500);
+ assertEquals(counter.getCount(MonitoringEvent.REQUEST_STARTED), 1);
+ assertEquals(counter.getCount(MonitoringEvent.REQUEST_COMPLETED), 1);
+ assertEquals(counter.getCount(MonitoringEvent.REQUEST_FAILED), 0);
+ assertEquals(counter.getCount(MonitoringEvent.REQUEST_TIMEOUT), 0);
+ assertEquals(counter.getCount(MonitoringEvent.CONNECTION_ATTEMPTED), 1);
+ assertEquals(counter.getCount(MonitoringEvent.CONNECTION_RETRIED), 0);
+ assertEquals(counter.getCount(MonitoringEvent.CONNECTION_REUSED), 0);
+ assertEquals(counter.getCount(MonitoringEvent.CONNECTION_SUCCESSFUL), 1);
+ assertEquals(counter.getCount(MonitoringEvent.REQUEST_REDIRECTED), 0);
+ assertEquals(counter.getCount(MonitoringEvent.REQUEST_CHALLENGED), 0);
+ assertEquals(counter.getCount(MonitoringEvent.CONNECTION_CLOSED_BY_SERVER), 1);
+ assertEquals(counter.getCount(MonitoringEvent.CONNECTION_CLOSED), 0);
+ }
+
+ public void testSSLHtmlConnection() throws Exception {
+ TestCallback callback = new TestCallback();
+ CountingMonitor counter = new CountingMonitor();
+ doGetConnection(callback, "https://localhost:8383/", false, true, counter);
+
+ HttpResponseMessage msg = callback.getMessage();
+ assertEquals("\nHello World!", msg.getStringContent());
+ // the monitor events are dispatched asynchronously, so give a little time
+ // for them all to be dispatched.
+ Thread.sleep(500);
+ assertEquals(counter.getCount(MonitoringEvent.REQUEST_STARTED), 1);
+ assertEquals(counter.getCount(MonitoringEvent.REQUEST_COMPLETED), 1);
+ assertEquals(counter.getCount(MonitoringEvent.REQUEST_FAILED), 0);
+ assertEquals(counter.getCount(MonitoringEvent.REQUEST_TIMEOUT), 0);
+ assertEquals(counter.getCount(MonitoringEvent.CONNECTION_ATTEMPTED), 1);
+ assertEquals(counter.getCount(MonitoringEvent.CONNECTION_RETRIED), 0);
+ assertEquals(counter.getCount(MonitoringEvent.CONNECTION_REUSED), 0);
+ assertEquals(counter.getCount(MonitoringEvent.CONNECTION_SUCCESSFUL), 1);
+ assertEquals(counter.getCount(MonitoringEvent.REQUEST_REDIRECTED), 0);
+ assertEquals(counter.getCount(MonitoringEvent.REQUEST_CHALLENGED), 0);
+ assertEquals(counter.getCount(MonitoringEvent.CONNECTION_CLOSED_BY_SERVER), 1);
+ assertEquals(counter.getCount(MonitoringEvent.CONNECTION_CLOSED), 0);
+ }
+
+ public void testRedirect() throws Exception {
+ TestCallback callback = new TestCallback();
+
+ CountingMonitor counter = new CountingMonitor();
+ //Test that we are following redirects
+ doGetConnection(callback, "http://localhost:8282/redirect.jsp", false, true, counter);
+
+ HttpResponseMessage msg = callback.getMessage();
+ assertEquals("\nHello World!", msg.getStringContent());
+ // the monitor events are dispatched asynchronously, so give a little time
+ // for them all to be dispatched.
+ Thread.sleep(500);
+
+ assertEquals(counter.getCount(MonitoringEvent.REQUEST_STARTED), 2);
+ assertEquals(counter.getCount(MonitoringEvent.REQUEST_COMPLETED), 1);
+ assertEquals(counter.getCount(MonitoringEvent.REQUEST_FAILED), 0);
+ assertEquals(counter.getCount(MonitoringEvent.REQUEST_TIMEOUT), 0);
+ assertEquals(counter.getCount(MonitoringEvent.CONNECTION_ATTEMPTED), 2);
+ assertEquals(counter.getCount(MonitoringEvent.CONNECTION_RETRIED), 0);
+ assertEquals(counter.getCount(MonitoringEvent.CONNECTION_REUSED), 0);
+ assertEquals(counter.getCount(MonitoringEvent.CONNECTION_SUCCESSFUL), 2);
+ assertEquals(counter.getCount(MonitoringEvent.REQUEST_REDIRECTED), 1);
+ assertEquals(counter.getCount(MonitoringEvent.REQUEST_CHALLENGED), 0);
+ assertEquals(counter.getCount(MonitoringEvent.CONNECTION_CLOSED_BY_SERVER), 2);
+ assertEquals(counter.getCount(MonitoringEvent.CONNECTION_CLOSED), 0);
+
+ counter.clearCounters();
+
+ //Test that we are not following redirects
+ callback = new TestCallback();
+ doGetConnection(callback, "http://localhost:8282/redirect.jsp", false, false, counter);
+
+ msg = callback.getMessage();
+ assertEquals(302, msg.getStatusCode());
+ assertEquals(msg.getLocation(), "http://localhost:8282/index.jsp");
+
+ assertEquals(counter.getCount(MonitoringEvent.REQUEST_STARTED), 1);
+ assertEquals(counter.getCount(MonitoringEvent.REQUEST_COMPLETED), 1);
+ assertEquals(counter.getCount(MonitoringEvent.REQUEST_FAILED), 0);
+ assertEquals(counter.getCount(MonitoringEvent.REQUEST_TIMEOUT), 0);
+ assertEquals(counter.getCount(MonitoringEvent.CONNECTION_ATTEMPTED), 1);
+ assertEquals(counter.getCount(MonitoringEvent.CONNECTION_RETRIED), 0);
+ assertEquals(counter.getCount(MonitoringEvent.CONNECTION_REUSED), 0);
+ assertEquals(counter.getCount(MonitoringEvent.CONNECTION_SUCCESSFUL), 1);
+ assertEquals(counter.getCount(MonitoringEvent.REQUEST_REDIRECTED), 0);
+ assertEquals(counter.getCount(MonitoringEvent.REQUEST_CHALLENGED), 0);
+ assertEquals(counter.getCount(MonitoringEvent.CONNECTION_CLOSED_BY_SERVER), 0);
+ assertEquals(counter.getCount(MonitoringEvent.CONNECTION_CLOSED), 0);
+ }
+
+ private void doGetConnection(TestCallback callback, String url,
+ boolean testForException, boolean followRedirects,
+ MonitoringListener listener)
+ throws Exception {
+ HttpRequestMessage request = new HttpRequestMessage(new URL(url), callback);
+ request.setFollowRedirects(followRedirects);
+
+ request.setParameter("TEST1", "Test One");
+ request.setParameter("TEST2", "Test Two");
+ doConnection(request, false, callback, listener);
+ }
+
+ private void doPostConnection(TestCallback callback, String url,
+ boolean testForException, MonitoringListener listener)
+ throws Exception {
+ HttpRequestMessage request = new HttpRequestMessage(new URL(url), callback);
+ request.setParameter("TEST1", "Test One");
+ request.setParameter("TEST2", "Test Two");
+ request.setRequestMethod(HttpRequestMessage.REQUEST_POST);
+ doConnection(request, false, callback, listener);
+ }
+
+ private void doConnection(HttpRequestMessage request, boolean testForException,
+ TestCallback callback, MonitoringListener listener) throws Exception {
+ AsyncHttpClient ahc = new AsyncHttpClient();
+ ahc.addMonitoringListener(listener);
+ ahc.setTcpNoDelay(true);
+
+ ahc.sendRequest(request);
+
+ //We are done...Thread would normally end...
+ //So this little wait simulates the thread going back in the pool
+ //5 second timeout due to no response
+ callback.await(5, TimeUnit.SECONDS);
+
+ if (!testForException) {
+ if (((TestCallback)request.getCallback()).isException()) {
+ throw new Exception(((TestCallback)request.getCallback()).getThrowable());
+ }
+ }
+
+ }
+
+}
+
Propchange: geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/MonitoringTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/MonitoringTest.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/MonitoringTest.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/RetryTest.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/RetryTest.java?rev=614952&r1=614951&r2=614952&view=diff
==============================================================================
--- geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/RetryTest.java (original)
+++ geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/RetryTest.java Thu Jan 24 10:24:21 2008
@@ -19,47 +19,49 @@
*/
package org.apache.ahc;
-import java.io.File;
-import java.io.FileInputStream;
import java.net.URL;
-import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import org.apache.ahc.codec.HttpRequestMessage;
-import org.apache.ahc.codec.HttpResponseMessage;
+import org.apache.ahc.util.CountingMonitor;
+import org.apache.ahc.util.MonitoringEvent;
public class RetryTest extends AbstractTest {
public void testHtmlConnection() throws Exception {
TestCallback callback = new TestCallback();
- doGetConnection(callback, "http://localhost:8284/");
+ CountingMonitor counter = doGetConnection(callback, "http://localhost:8284/");
Thread.sleep(5000);
assertTrue(callback.isException());
+ assertTrue(counter.getCount(MonitoringEvent.CONNECTION_RETRIED) == 3);
}
public void testSSLHtmlConnection() throws Exception {
TestCallback callback = new TestCallback();
- doGetConnection(callback, "https://localhost:8385/");
+ CountingMonitor counter = doGetConnection(callback, "https://localhost:8385/");
Thread.sleep(5000);
assertTrue(callback.isException());
+ assertTrue(counter.getCount(MonitoringEvent.CONNECTION_RETRIED) == 3);
}
- private void doGetConnection(TestCallback callback, String url)
+ private CountingMonitor doGetConnection(TestCallback callback, String url)
throws Exception {
HttpRequestMessage request = new HttpRequestMessage(new URL(url), callback);
request.setParameter("TEST1", "Test One");
request.setParameter("TEST2", "Test Two");
- doConnection(request, callback);
- }
+ return doConnection(request, callback);
+ }
- private void doConnection(HttpRequestMessage request,
+ private CountingMonitor doConnection(HttpRequestMessage request,
TestCallback callback) throws Exception {
AsyncHttpClient ahc = new AsyncHttpClient();
ahc.setTcpNoDelay(true);
ahc.setConnectionRetries(3);
+ CountingMonitor counter = new CountingMonitor();
+ ahc.addMonitoringListener(counter);
// set a short timeout
request.setTimeOut(200);
@@ -69,6 +71,8 @@
//So this little wait simulates the thread going back in the pool
//5 second timeout due to no response
callback.await(5, TimeUnit.SECONDS);
+ // and return our monitor
+ return counter;
}
}