You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by jg...@apache.org on 2007/12/06 21:27:38 UTC

svn commit: r601844 - in /geronimo/sandbox/AsyncHttpClient/src: main/java/org/apache/ahc/ main/java/org/apache/ahc/codec/ test/java/org/apache/ahc/

Author: jgenender
Date: Thu Dec  6 12:27:37 2007
New Revision: 601844

URL: http://svn.apache.org/viewvc?rev=601844&view=rev
Log:
GERONIMO-3615 and GERONIMO-3616

Added:
    geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/ResponseFuture.java   (with props)
    geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/AsyncHttpClientWithFutureTest.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/AbstractTest.java
    geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/AsyncHttpClientTest.java
    geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/AuthTest.java
    geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/TimeoutTest.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=601844&r1=601843&r2=601844&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 Dec  6 12:27:37 2007
@@ -21,10 +21,18 @@
 
 import java.net.InetSocketAddress;
 import java.security.GeneralSecurityException;
+import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.ScheduledExecutorService;
+
 import javax.net.ssl.SSLContext;
 
+import org.apache.ahc.codec.HttpIoHandler;
+import org.apache.ahc.codec.HttpProtocolCodecFactory;
+import org.apache.ahc.codec.HttpRequestMessage;
+import org.apache.ahc.codec.ResponseFuture;
+import org.apache.ahc.ssl.TrustManagerFactoryImpl;
+import org.apache.ahc.util.AsyncHttpClientException;
 import org.apache.mina.common.ConnectFuture;
 import org.apache.mina.common.IoFuture;
 import org.apache.mina.common.IoFutureListener;
@@ -35,12 +43,6 @@
 import org.apache.mina.transport.socket.nio.SocketConnector;
 import org.apache.mina.transport.socket.nio.SocketSessionConfig;
 
-import org.apache.ahc.codec.HttpIoHandler;
-import org.apache.ahc.codec.HttpProtocolCodecFactory;
-import org.apache.ahc.codec.HttpRequestMessage;
-import org.apache.ahc.ssl.TrustManagerFactoryImpl;
-import org.apache.ahc.util.AsyncHttpClientException;
-
 
 /**
  * Main class to use for sending asynchronous HTTP requests to servers.
@@ -322,19 +324,56 @@
     }
 
     /**
-     * Sends a request.
+     * Sends a request.  The call is non-blocking, and returns a future object
+     * with which the caller can synchronize on the completion of the request.
+     * This does not use a completion queue as provided by the other version of
+     * <code>sendRequest()</code> method.
      *
      * @param message the <code>HttpRequestMessage</code> to send to the remote server.
+     * @return a future object that allows tracking of the progress.  If the
+     * future object already exists in the request, then the same future is
+     * returned.
      * @see HttpRequestMessage
      */
-    public void sendRequest(HttpRequestMessage message) {
+    public ResponseFuture sendRequest(HttpRequestMessage message) {
+    	return sendRequest(message, null);
+    }
+    
+    /**
+     * Sends a request.  The call is non-blocking, and returns a future object
+     * with which the caller can synchronize on the completion of the request.
+     * Once the call is complete, the future will also be placed in the queue 
+     * that is provided in the arguments.
+     * 
+     * @param message the <code>HttpRequestMessage</code> to send to the remote
+     * server.
+     * @param queue the completion queue on which the future will be added once
+     * it is complete.  May be null.  If the future object already exists in the
+     * request (i.e. <tt>sendRequest()</tt> was called repeatedly on the same
+     * request), then the queue is ignored, and the queue that's associated with
+     * the existing future object will be used.
+     * @return a future object that allows tracking of the progress.  If the
+     * future object already exists in the request, then the same future is
+     * returned.
+     */
+    public ResponseFuture sendRequest(HttpRequestMessage message, 
+    		BlockingQueue<ResponseFuture> queue) {
         if (threadPool != null && threadPool.isShutdown()) {
             throw new IllegalStateException("AsyncHttpClient has been destroyed and cannot be reused.");
         }
+        
+        // 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)
+        if (message.getResponseFuture() == null) {
+        	message.setResponseFuture(new ResponseFuture(message, queue));
+        }
+        
         String host = message.getHost();
         int port = message.getPort();
         ConnectFuture future = connector.connect(new InetSocketAddress(host, port), handler);
         future.addListener(new FutureListener(message));
+        return message.getResponseFuture();
     }
 
     /**

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=601844&r1=601843&r2=601844&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 Dec  6 12:27:37 2007
@@ -24,9 +24,7 @@
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.TimeUnit;
-
-import org.apache.mina.common.IoHandlerAdapter;
-import org.apache.mina.common.IoSession;
+import java.util.concurrent.TimeoutException;
 
 import org.apache.ahc.AsyncHttpClient;
 import org.apache.ahc.AsyncHttpClientCallback;
@@ -35,6 +33,8 @@
 import org.apache.ahc.auth.AuthScheme;
 import org.apache.ahc.auth.AuthState;
 import org.apache.ahc.util.NameValuePair;
+import org.apache.mina.common.IoHandlerAdapter;
+import org.apache.mina.common.IoSession;
 
 
 /**
@@ -158,8 +158,10 @@
 
         cancelTasks(request);
 
-        AsyncHttpClientCallback callback = request.getCallback();
-        callback.onResponse(response);
+        // complete the future which will also fire the callback
+        ResponseFuture result = request.getResponseFuture();
+        result.set(response);
+        
         ioSession.close();
     }
 
@@ -177,8 +179,9 @@
         HttpRequestMessage request = (HttpRequestMessage) ioSession.getAttribute(CURRENT_REQUEST);
         cancelTasks(request);
 
-        AsyncHttpClientCallback callback = request.getCallback();
-        callback.onException(throwable);
+        // complete the future which will also fire the callback
+        ResponseFuture result = request.getResponseFuture();
+        result.setException(throwable);
 
         //Exception is bad, so just close it up
         ioSession.close();
@@ -196,7 +199,9 @@
         HttpRequestMessage request = (HttpRequestMessage) ioSession.getAttribute(CURRENT_REQUEST);
         cancelTasks(request);
         AsyncHttpClientCallback callback = request.getCallback();
-        callback.onClosed();
+        if (callback != null) {
+        	callback.onClosed();
+        }
     }
 
     /**
@@ -261,9 +266,11 @@
          * @see java.lang.Runnable#run()
          */
         public void run() {
-            HttpRequestMessage request = (HttpRequestMessage) sess.getAttribute(CURRENT_REQUEST);
-            AsyncHttpClientCallback callback = request.getCallback();
-            callback.onTimeout();
+            // complete the future which will also fire the callback
+            HttpRequestMessage request = (HttpRequestMessage)sess.getAttribute(CURRENT_REQUEST);
+            ResponseFuture result = request.getResponseFuture();
+            result.setException(new TimeoutException());
+            
             //Close the session, its no good since the server is timing out
             sess.close();
         }

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=601844&r1=601843&r2=601844&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 Dec  6 12:27:37 2007
@@ -112,6 +112,11 @@
     private ScheduledFuture timeoutHandle;
 
     /**
+     * The response future.
+     */
+    private volatile ResponseFuture responseFuture;
+    
+    /**
      * The callback.
      */
     private AsyncHttpClientCallback callback;
@@ -199,6 +204,19 @@
         return requestMethod;
     }
 
+    /**
+     * Returns the response future object associated with the request.
+     */
+    public ResponseFuture getResponseFuture() {
+    	return responseFuture;
+    }
+
+    /**
+     * Sets the response future object.
+     */
+    public void setResponseFuture(ResponseFuture result) {
+    	responseFuture = result;
+    }
 
     /**
      * Gets the callback.

Added: geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/ResponseFuture.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/ResponseFuture.java?rev=601844&view=auto
==============================================================================
--- geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/ResponseFuture.java (added)
+++ geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/ResponseFuture.java Thu Dec  6 12:27:37 2007
@@ -0,0 +1,129 @@
+/*
+ *  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.codec;
+
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.Callable;
+import java.util.concurrent.Future;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.TimeoutException;
+
+import org.apache.ahc.AsyncHttpClientCallback;
+
+/**
+ * Future that wraps the response of an asynchronous HTTP request.  It simply
+ * extends FutureTask to borrow AQS.  This future transitions to <tt>done</tt> 
+ * through setting the result or the exception.  The instances are considered 
+ * one time objects; i.e. once completed, the instance may not be reused.
+ * <p>
+ * Also, cancellation through this future is not supported.
+ */
+public class ResponseFuture extends FutureTask<HttpResponseMessage> 
+		implements Future<HttpResponseMessage> {
+	// dummy instance because I use the FutureTask constructor
+	// is not really used...
+	private static final Callable<HttpResponseMessage> DUMMY = 
+			new Callable<HttpResponseMessage>() {
+				public HttpResponseMessage call() throws Exception {
+					return null;
+				}
+	};
+	
+	private final HttpRequestMessage request;
+	private final BlockingQueue<ResponseFuture> queue;
+	private final AsyncHttpClientCallback callback;
+	
+	/**
+	 * Constructor.  Optionally one can pass in the completion queue and/or the
+	 * callback object.
+	 * 
+	 * @param queue optional completion queue.  If not null, this future will be
+	 * placed in the queue on completion.
+	 * @param callback optional callback object.  If not null, the callback will
+	 * be invoked at proper stages on completion.
+	 */
+	public ResponseFuture(HttpRequestMessage request, 
+			BlockingQueue<ResponseFuture> queue) {
+		super(DUMMY);
+		this.request = request;
+		this.queue = queue;
+		this.callback = request.getCallback();
+	}
+	
+	public HttpRequestMessage getRequest() {
+		return request;
+	}
+	
+	/**
+	 * On completion, adds this future object to the completion queue if it is 
+	 * not null.
+	 */
+	@Override
+	protected void done() {
+		// add itself to the blocking queue so clients can pick it up
+		if (queue != null) {
+			queue.add(this);
+		}
+	}
+
+	/**
+	 * Sets the response and completes the future.  If a non-null callback was
+	 * provided, the callback will be invoked 
+	 * (<tt>AsyncHttpClientCallback.onResponse()</tt>) on the thread on which
+	 * this method is invoked.
+	 */
+	@Override
+	protected void set(HttpResponseMessage v) {
+		super.set(v);
+		// fire the callback once the future is done
+		if (callback != null) {
+			callback.onResponse(v);
+		}
+	}
+
+	/**
+	 * Sets the exception and completes the future.  If a non-null callback was
+	 * provided, the callback will be invoked 
+	 * (<tt>AsyncHttpClientCallback.onException()</tt> or 
+	 * <tt>AsyncHttpClientCallback.onTimeout()</tt>) on the thread on which
+	 * this method is invoked.
+	 */
+	@Override
+	protected void setException(Throwable t) {
+		super.setException(t);
+		// fire the callback once the future is done
+		if (callback != null) {
+			if (t instanceof TimeoutException) {
+				callback.onTimeout();
+			} else {
+				callback.onException(t);
+			}
+		}
+	}
+	
+	/**
+	 * Canceling via this method is not allowed.  An 
+	 * UnsupportedOperationException will be thrown.
+	 */
+	@Override
+	public boolean cancel(boolean mayInterruptIfRunning) {
+		throw new UnsupportedOperationException("we don't support canceling asynchronous HTTP request via this method...");
+	}
+}

Propchange: geronimo/sandbox/AsyncHttpClient/src/main/java/org/apache/ahc/codec/ResponseFuture.java
------------------------------------------------------------------------------
    svn:executable = *

Modified: geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/AbstractTest.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/AbstractTest.java?rev=601844&r1=601843&r2=601844&view=diff
==============================================================================
--- geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/AbstractTest.java (original)
+++ geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/AbstractTest.java Thu Dec  6 12:27:37 2007
@@ -20,17 +20,17 @@
 package org.apache.ahc;
 
 import java.io.File;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
 
 import junit.framework.TestCase;
 
 import org.apache.ahc.codec.HttpResponseMessage;
-import org.apache.catalina.Context;
 import org.apache.catalina.Engine;
 import org.apache.catalina.Host;
-import org.apache.catalina.realm.MemoryRealm;
 import org.apache.catalina.connector.Connector;
-import org.apache.catalina.core.StandardHost;
 import org.apache.catalina.core.StandardContext;
+import org.apache.catalina.core.StandardHost;
 import org.apache.catalina.startup.Embedded;
 
 public class AbstractTest extends TestCase {
@@ -42,7 +42,6 @@
     protected static final File ROOT = new File(WEBAPPS, "ROOT");
     protected static final File AUTH_BASIC = new File(WEBAPPS, "auth_basic");
     protected static final File AUTH_DIGEST = new File(WEBAPPS, "auth_digest");
-    protected static Object semaphore = new Object();
     protected static final File WORK = new File(BASEDIR, "target/work");
     protected Embedded server;
 
@@ -120,11 +119,12 @@
 
     class TestCallback implements AsyncHttpClientCallback {
 
-        private boolean timeout;
-        private boolean closed;
-        private boolean exception;
-        private Throwable throwable;
-        private HttpResponseMessage message;
+        private volatile boolean timeout;
+        private volatile boolean closed;
+        private volatile boolean exception;
+        private volatile Throwable throwable;
+        private volatile HttpResponseMessage message;
+        private final CountDownLatch complete = new CountDownLatch(1);
 
         public TestCallback() {
             clear();
@@ -132,29 +132,24 @@
 
         public void onResponse(HttpResponseMessage response) {
             this.message = response;
-            synchronized (semaphore) {
-                semaphore.notify();
-            }
+            complete.countDown();
         }
 
         public void onException(Throwable cause) {
             throwable = cause;
             exception = true;
-            synchronized (semaphore) {
-                semaphore.notify();
-            }
+            complete.countDown();
             cause.printStackTrace();
         }
 
         public void onClosed() {
             closed = true;
+            System.out.println("onClosed()");
         }
 
         public void onTimeout() {
             timeout = true;
-            synchronized (semaphore) {
-                semaphore.notify();
-            }
+            complete.countDown();
         }
 
         public Throwable getThrowable() {
@@ -194,6 +189,10 @@
 
         public void setMessage(HttpResponseMessage message) {
             this.message = message;
+        }
+        
+        public void await(int timeout, TimeUnit unit) throws InterruptedException {
+        	complete.await(timeout, unit);
         }
     }
 }

Modified: geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/AsyncHttpClientTest.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/AsyncHttpClientTest.java?rev=601844&r1=601843&r2=601844&view=diff
==============================================================================
--- geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/AsyncHttpClientTest.java (original)
+++ geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/AsyncHttpClientTest.java Thu Dec  6 12:27:37 2007
@@ -23,6 +23,7 @@
 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;
@@ -56,7 +57,7 @@
         assertEquals("\nHello World!", msg.getStringContent());
 
         //Test that we are not following redirects
-        callback.clear();
+        callback = new TestCallback();
         doGetConnection(callback, "http://localhost:8282/redirect.jsp", false, false);
 
         msg = callback.getMessage();
@@ -120,7 +121,7 @@
 
         request.setParameter("TEST1", "Test One");
         request.setParameter("TEST2", "Test Two");
-        doConnection(request, false);
+        doConnection(request, false, callback);
     }
 
     private void doPostConnection(TestCallback callback, String url, boolean testForException)
@@ -129,21 +130,20 @@
         request.setParameter("TEST1", "Test One");
         request.setParameter("TEST2", "Test Two");
         request.setRequestMethod(HttpRequestMessage.REQUEST_POST);
-        doConnection(request, false);
+        doConnection(request, false, callback);
     }
 
     private void doConnection(HttpRequestMessage request,
-                              boolean testForException) throws Exception {
+                              boolean testForException, 
+                              TestCallback callback) throws Exception {
         AsyncHttpClient ahc = new AsyncHttpClient();
 
         ahc.sendRequest(request);
 
         //We are done...Thread would normally end...
         //So this little wait simulates the thread going back in the pool
-        synchronized (semaphore) {
-            //5 second timeout due to no response
-            semaphore.wait(5000);
-        }
+        //5 second timeout due to no response
+        callback.await(5, TimeUnit.SECONDS);
 
         if (!testForException) {
             if (((TestCallback)request.getCallback()).isException()) {

Added: geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/AsyncHttpClientWithFutureTest.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/AsyncHttpClientWithFutureTest.java?rev=601844&view=auto
==============================================================================
--- geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/AsyncHttpClientWithFutureTest.java (added)
+++ geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/AsyncHttpClientWithFutureTest.java Thu Dec  6 12:27:37 2007
@@ -0,0 +1,128 @@
+/*
+ *  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.net.URL;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.Future;
+import java.util.concurrent.LinkedBlockingQueue;
+
+import org.apache.ahc.codec.HttpRequestMessage;
+import org.apache.ahc.codec.HttpResponseMessage;
+import org.apache.ahc.codec.ResponseFuture;
+
+public class AsyncHttpClientWithFutureTest extends AbstractTest {
+    public void testHtmlRequest() throws Exception {
+        Future<HttpResponseMessage> future = submitGetRequest("http://localhost:8282/", true, null);
+
+        HttpResponseMessage msg = future.get();
+        assertEquals("\nHello World!", msg.getStringContent());
+    }
+
+    public void testSSLHtmlRequest() throws Exception {
+        Future<HttpResponseMessage> future = submitGetRequest("https://localhost:8383/", true, null);
+
+        HttpResponseMessage msg = future.get();
+        assertEquals("\nHello World!", msg.getStringContent());
+    }
+    
+    public void testMultipleRequests() throws Exception {
+    	BlockingQueue<ResponseFuture> completionQueue =
+    			new LinkedBlockingQueue<ResponseFuture>();
+    	
+    	// fire two HTTP requests on the same queue
+    	submitGetRequest("http://localhost:8282/", true, completionQueue);
+    	submitGetRequest("http://localhost:8282/params.jsp", true, completionQueue);
+    	
+    	// check the results
+    	for (int i = 0; i < 2; i++) {
+    		// we don't know which one will complete first
+    		ResponseFuture future = completionQueue.take(); // this blocks
+    		String content = future.get().getStringContent();
+    		String url = future.getRequest().getUrl().toString();
+    		if (url.equals("http://localhost:8282/")) {
+    			assertEquals("\nHello World!", content);
+    		} else {
+    			assertEquals("Test One Test Two", content);
+    		}
+    	}
+    	// the fact we reach here is a success
+    	assertTrue(true);
+    }
+
+    public void testRedirect() throws Exception {
+        //Test that we are following redirects
+        Future<HttpResponseMessage> future = submitGetRequest("http://localhost:8282/redirect.jsp", true, null);
+
+        HttpResponseMessage msg = future.get();
+        assertEquals("\nHello World!", msg.getStringContent());
+
+        //Test that we are not following redirects
+        future = submitGetRequest("http://localhost:8282/redirect.jsp", false, null);
+
+        msg = future.get();
+        assertEquals(302, msg.getStatusCode());
+        assertEquals(msg.getLocation(), "http://localhost:8282/index.jsp"); 
+    }
+
+    public void testGetParameters() throws Exception {
+        Future<HttpResponseMessage> future = 
+        		submitGetRequest("http://localhost:8282/params.jsp", true, null);
+
+        HttpResponseMessage msg = future.get();
+        assertEquals("Test One Test Two", msg.getStringContent());
+    }
+
+    public void testPostParameters() throws Exception {
+        Future<HttpResponseMessage> future = submitPostRequest("http://localhost:8282/params.jsp", null);
+
+        HttpResponseMessage msg = future.get();
+        assertEquals("Test One Test Two", msg.getStringContent());
+    }
+    
+    private Future<HttpResponseMessage> submitGetRequest(String url, 
+    													 boolean followRedirects, 
+    													 BlockingQueue<ResponseFuture> queue) 
+    		throws Exception {
+        HttpRequestMessage request = new HttpRequestMessage(new URL(url), null);
+        request.setFollowRedirects(followRedirects);
+
+        request.setParameter("TEST1", "Test One");
+        request.setParameter("TEST2", "Test Two");
+        return submitRequest(request, queue);
+    }
+    
+    private Future<HttpResponseMessage> submitPostRequest(String url, 
+    													  BlockingQueue<ResponseFuture> queue) 
+    		throws Exception {
+        HttpRequestMessage request = new HttpRequestMessage(new URL(url), null);
+        request.setParameter("TEST1", "Test One");
+        request.setParameter("TEST2", "Test Two");
+        request.setRequestMethod(HttpRequestMessage.REQUEST_POST);
+        return submitRequest(request, queue);
+    }
+    
+    private Future<HttpResponseMessage> submitRequest(HttpRequestMessage request, 
+    												  BlockingQueue<ResponseFuture> queue)
+    		throws Exception {
+    	AsyncHttpClient ahc = new AsyncHttpClient();
+    	return ahc.sendRequest(request, queue);
+    }
+}

Propchange: geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/AsyncHttpClientWithFutureTest.java
------------------------------------------------------------------------------
    svn:executable = *

Modified: geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/AuthTest.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/AuthTest.java?rev=601844&r1=601843&r2=601844&view=diff
==============================================================================
--- geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/AuthTest.java (original)
+++ geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/AuthTest.java Thu Dec  6 12:27:37 2007
@@ -20,10 +20,11 @@
 package org.apache.ahc;
 
 import java.net.URL;
+import java.util.concurrent.TimeUnit;
 
-import org.apache.ahc.codec.HttpRequestMessage;
-import org.apache.ahc.auth.UsernamePasswordCredentials;
 import org.apache.ahc.auth.AuthScope;
+import org.apache.ahc.auth.UsernamePasswordCredentials;
+import org.apache.ahc.codec.HttpRequestMessage;
 
 public class AuthTest extends AbstractTest {
 
@@ -38,11 +39,7 @@
         request.addCredentials(AuthScope.ANY, creds);
         ahc.sendRequest(request);
 
-        synchronized (semaphore) {
-            //5 second timeout due to no response
-            semaphore.wait(5000);
-        }
-
+        callback.await(5, TimeUnit.SECONDS);
 
         assertEquals(200, callback.getMessage().getStatusCode());
         assertEquals("Hello World!\n", callback.getMessage().getStringContent());
@@ -58,10 +55,7 @@
         request.addCredentials(AuthScope.ANY, creds);
         ahc.sendRequest(request);
 
-        synchronized (semaphore) {
-            //5 second timeout due to no response
-            semaphore.wait(5000);
-        }
+        callback.await(5, TimeUnit.SECONDS);
 
         //Should be an auth failure
         assertEquals(401, callback.getMessage().getStatusCode());
@@ -76,10 +70,7 @@
         request.addCredentials(AuthScope.ANY, creds);
         ahc.sendRequest(request);
 
-        synchronized (semaphore) {
-            //5 second timeout due to no response
-            semaphore.wait(5000);
-        }
+        callback.await(5, TimeUnit.SECONDS);
 
         assertEquals(200, callback.getMessage().getStatusCode());
         assertEquals("Hello World!\n", callback.getMessage().getStringContent());

Modified: geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/TimeoutTest.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/TimeoutTest.java?rev=601844&r1=601843&r2=601844&view=diff
==============================================================================
--- geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/TimeoutTest.java (original)
+++ geronimo/sandbox/AsyncHttpClient/src/test/java/org/apache/ahc/TimeoutTest.java Thu Dec  6 12:27:37 2007
@@ -21,6 +21,7 @@
 package org.apache.ahc;
 
 import java.net.URL;
+import java.util.concurrent.TimeUnit;
 
 import org.apache.ahc.codec.HttpRequestMessage;
 
@@ -41,10 +42,8 @@
 
         //We are done...Thread would normally end...
         //So this little wait simulates the thread going back in the pool
-        synchronized (semaphore) {
-            //5 second timeout due to no response
-            semaphore.wait(5000);
-        }
+        //5 second timeout due to no response
+        callback.await(5, TimeUnit.SECONDS);
 
         assertTrue(callback.isTimeout());