View Javadoc

1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  package org.apache.http.nio.client.integration;
28  
29  import java.io.IOException;
30  import java.net.InetSocketAddress;
31  import java.util.LinkedList;
32  import java.util.Queue;
33  import java.util.Random;
34  import java.util.concurrent.ExecutionException;
35  import java.util.concurrent.Future;
36  
37  import org.apache.http.HttpAsyncTestBase;
38  import org.apache.http.HttpEntity;
39  import org.apache.http.HttpHost;
40  import org.apache.http.HttpResponse;
41  import org.apache.http.client.methods.HttpGet;
42  import org.apache.http.client.methods.HttpPost;
43  import org.apache.http.config.ConnectionConfig;
44  import org.apache.http.impl.DefaultConnectionReuseStrategy;
45  import org.apache.http.impl.DefaultHttpResponseFactory;
46  import org.apache.http.impl.nio.DefaultNHttpServerConnection;
47  import org.apache.http.impl.nio.DefaultNHttpServerConnectionFactory;
48  import org.apache.http.impl.nio.client.HttpAsyncClients;
49  import org.apache.http.localserver.EchoHandler;
50  import org.apache.http.localserver.RandomHandler;
51  import org.apache.http.nio.ContentDecoder;
52  import org.apache.http.nio.IOControl;
53  import org.apache.http.nio.NHttpConnectionFactory;
54  import org.apache.http.nio.client.methods.HttpAsyncMethods;
55  import org.apache.http.nio.entity.NByteArrayEntity;
56  import org.apache.http.nio.protocol.BasicAsyncRequestHandler;
57  import org.apache.http.nio.protocol.BasicAsyncResponseConsumer;
58  import org.apache.http.nio.protocol.HttpAsyncExpectationVerifier;
59  import org.apache.http.nio.protocol.HttpAsyncRequestHandlerMapper;
60  import org.apache.http.nio.protocol.HttpAsyncRequestProducer;
61  import org.apache.http.nio.protocol.HttpAsyncService;
62  import org.apache.http.nio.protocol.UriHttpAsyncRequestHandlerMapper;
63  import org.apache.http.nio.reactor.IOReactorStatus;
64  import org.apache.http.nio.reactor.ListenerEndpoint;
65  import org.apache.http.util.EntityUtils;
66  import org.junit.After;
67  import org.junit.Assert;
68  import org.junit.Before;
69  import org.junit.Test;
70  
71  public class TestHttpAsync extends HttpAsyncTestBase {
72  
73      @Before
74      public void setUp() throws Exception {
75          initServer();
76          initConnectionManager();
77          this.httpclient = HttpAsyncClients.custom()
78              .setConnectionManager(this.connMgr)
79              .build();
80      }
81  
82      @After
83      public void tearDown() throws Exception {
84          shutDownClient();
85          shutDownServer();
86      }
87  
88      @Override
89      protected NHttpConnectionFactory<DefaultNHttpServerConnection> createServerConnectionFactory(
90              final ConnectionConfig config) throws Exception {
91          return new DefaultNHttpServerConnectionFactory(config);
92      }
93  
94      @Override
95      protected String getSchemeName() {
96          return "http";
97      }
98  
99      private HttpHost start(
100             final HttpAsyncRequestHandlerMapper requestHandlerResolver,
101             final HttpAsyncExpectationVerifier expectationVerifier) throws Exception {
102         final HttpAsyncService serviceHandler = new HttpAsyncService(
103                 this.serverHttpProc,
104                 DefaultConnectionReuseStrategy.INSTANCE,
105                 DefaultHttpResponseFactory.INSTANCE,
106                 requestHandlerResolver,
107                 expectationVerifier);
108         this.server.start(serviceHandler);
109         this.httpclient.start();
110 
111         final ListenerEndpoint endpoint = this.server.getListenerEndpoint();
112         endpoint.waitFor();
113 
114         Assert.assertEquals("Test server status", IOReactorStatus.ACTIVE, this.server.getStatus());
115         final InetSocketAddress address = (InetSocketAddress) endpoint.getAddress();
116         return new HttpHost("localhost", address.getPort(), getSchemeName());
117     }
118 
119     private HttpHost start() throws Exception {
120         final UriHttpAsyncRequestHandlerMapper registry = new UriHttpAsyncRequestHandlerMapper();
121         registry.register("/echo/*", new BasicAsyncRequestHandler(new EchoHandler()));
122         registry.register("/random/*", new BasicAsyncRequestHandler(new RandomHandler()));
123         return start(registry, null);
124     }
125 
126     @Test
127     public void testSingleGet() throws Exception {
128         final HttpHost target = start();
129         final HttpGet httpget = new HttpGet("/random/2048");
130         final Future<HttpResponse> future = this.httpclient.execute(target, httpget, null);
131         final HttpResponse response = future.get();
132         Assert.assertNotNull(response);
133         Assert.assertEquals(200, response.getStatusLine().getStatusCode());
134     }
135 
136     @Test
137     public void testSinglePost() throws Exception {
138         final HttpHost target = start();
139         final byte[] b1 = new byte[1024];
140         final Random rnd = new Random(System.currentTimeMillis());
141         rnd.nextBytes(b1);
142 
143         final HttpPost httppost = new HttpPost("/echo/stuff");
144         httppost.setEntity(new NByteArrayEntity(b1));
145 
146         final Future<HttpResponse> future = this.httpclient.execute(target, httppost, null);
147         final HttpResponse response = future.get();
148         Assert.assertNotNull(response);
149         Assert.assertEquals(200, response.getStatusLine().getStatusCode());
150         final HttpEntity entity = response.getEntity();
151         Assert.assertNotNull(entity);
152         final byte[] b2 = EntityUtils.toByteArray(entity);
153         Assert.assertArrayEquals(b1, b2);
154     }
155 
156     @Test
157     public void testMultiplePostsOverMultipleConnections() throws Exception {
158         final HttpHost target = start();
159         final byte[] b1 = new byte[1024];
160         final Random rnd = new Random(System.currentTimeMillis());
161         rnd.nextBytes(b1);
162 
163         final int reqCount = 20;
164 
165         this.connMgr.setDefaultMaxPerRoute(reqCount);
166         this.connMgr.setMaxTotal(100);
167 
168         final Queue<Future<HttpResponse>> queue = new LinkedList<Future<HttpResponse>>();
169 
170         for (int i = 0; i < reqCount; i++) {
171             final HttpPost httppost = new HttpPost("/echo/stuff");
172             httppost.setEntity(new NByteArrayEntity(b1));
173             queue.add(this.httpclient.execute(target, httppost, null));
174         }
175 
176         while (!queue.isEmpty()) {
177             final Future<HttpResponse> future = queue.remove();
178             final HttpResponse response = future.get();
179             Assert.assertNotNull(response);
180             Assert.assertEquals(200, response.getStatusLine().getStatusCode());
181             final HttpEntity entity = response.getEntity();
182             Assert.assertNotNull(entity);
183             final byte[] b2 = EntityUtils.toByteArray(entity);
184             Assert.assertArrayEquals(b1, b2);
185         }
186     }
187 
188     @Test
189     public void testMultiplePostsOverSingleConnection() throws Exception {
190         final HttpHost target = start();
191         final byte[] b1 = new byte[1024];
192         final Random rnd = new Random(System.currentTimeMillis());
193         rnd.nextBytes(b1);
194 
195         final int reqCount = 20;
196 
197         this.connMgr.setDefaultMaxPerRoute(1);
198         this.connMgr.setMaxTotal(100);
199 
200         final Queue<Future<HttpResponse>> queue = new LinkedList<Future<HttpResponse>>();
201 
202         for (int i = 0; i < reqCount; i++) {
203             final HttpPost httppost = new HttpPost("/echo/stuff");
204             httppost.setEntity(new NByteArrayEntity(b1));
205             queue.add(this.httpclient.execute(target, httppost, null));
206         }
207 
208         while (!queue.isEmpty()) {
209             final Future<HttpResponse> future = queue.remove();
210             final HttpResponse response = future.get();
211             Assert.assertNotNull(response);
212             Assert.assertEquals(200, response.getStatusLine().getStatusCode());
213             final HttpEntity entity = response.getEntity();
214             Assert.assertNotNull(entity);
215             final byte[] b2 = EntityUtils.toByteArray(entity);
216             Assert.assertArrayEquals(b1, b2);
217         }
218     }
219 
220     @Test
221     public void testRequestFailure() throws Exception {
222         final HttpHost target = start();
223         final HttpGet httpget = new HttpGet("/random/2048");
224         final HttpAsyncRequestProducer requestProducer = HttpAsyncMethods.create(target, httpget) ;
225         final BasicAsyncResponseConsumer responseConsumer = new BasicAsyncResponseConsumer() {
226 
227             @Override
228             public void onContentReceived(final ContentDecoder decoder, final IOControl ioctrl)
229                     throws IOException {
230                 throw new IOException("Kaboom");
231             }
232 
233         };
234         final Future<HttpResponse> future = this.httpclient.execute(requestProducer, responseConsumer, null);
235         try {
236             future.get();
237             Assert.fail("ExecutionException expected");
238         } catch (final ExecutionException ex) {
239             final Throwable t = ex.getCause();
240             Assert.assertNotNull(t);
241             Assert.assertTrue(t instanceof IOException);
242             Assert.assertEquals("Kaboom", t.getMessage());
243         }
244     }
245 
246 }