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.util.Arrays;
31  import java.util.Collection;
32  import java.util.LinkedList;
33  import java.util.Queue;
34  import java.util.Random;
35  import java.util.concurrent.ExecutionException;
36  import java.util.concurrent.Future;
37  
38  import org.apache.http.client.methods.HttpHead;
39  import org.apache.http.localserver.HttpAsyncTestBase;
40  import org.apache.http.HttpEntity;
41  import org.apache.http.HttpHost;
42  import org.apache.http.HttpResponse;
43  import org.apache.http.client.methods.HttpGet;
44  import org.apache.http.client.methods.HttpPost;
45  import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
46  import org.apache.http.impl.nio.client.HttpAsyncClients;
47  import org.apache.http.localserver.EchoHandler;
48  import org.apache.http.localserver.RandomHandler;
49  import org.apache.http.nio.ContentDecoder;
50  import org.apache.http.nio.IOControl;
51  import org.apache.http.nio.client.methods.HttpAsyncMethods;
52  import org.apache.http.nio.client.util.HttpAsyncClientUtils;
53  import org.apache.http.nio.entity.NByteArrayEntity;
54  import org.apache.http.nio.protocol.BasicAsyncRequestHandler;
55  import org.apache.http.nio.protocol.BasicAsyncResponseConsumer;
56  import org.apache.http.nio.protocol.HttpAsyncRequestProducer;
57  import org.apache.http.util.EntityUtils;
58  import org.junit.Assert;
59  import org.junit.Before;
60  import org.junit.Test;
61  import org.junit.runner.RunWith;
62  import org.junit.runners.Parameterized;
63  
64  @RunWith(Parameterized.class)
65  public class TestHttpAsync extends HttpAsyncTestBase {
66  
67      @Parameterized.Parameters(name = "{0}")
68      public static Collection<Object[]> protocols() {
69          return Arrays.asList(new Object[][]{
70                  { ProtocolScheme.http },
71                  { ProtocolScheme.https },
72          });
73      }
74  
75      public TestHttpAsync(final ProtocolScheme scheme) {
76          super(scheme);
77      }
78  
79      @Before @Override
80      public void setUp() throws Exception {
81          super.setUp();
82          this.serverBootstrap.registerHandler("/echo/*", new BasicAsyncRequestHandler(new EchoHandler()));
83          this.serverBootstrap.registerHandler("/random/*", new BasicAsyncRequestHandler(new RandomHandler()));
84      }
85  
86      @Test
87      public void testSingleGet() throws Exception {
88          final HttpHost target = start();
89          final HttpGet httpget = new HttpGet("/random/2048");
90          final Future<HttpResponse> future = this.httpclient.execute(target, httpget, null);
91          final HttpResponse response = future.get();
92          Assert.assertNotNull(response);
93          Assert.assertEquals(200, response.getStatusLine().getStatusCode());
94      }
95  
96      @Test
97      public void testMultipleHead() throws Exception {
98          final HttpHost target = start();
99          for (int i = 0; i < 3; i++) {
100             final HttpHead httpHead = new HttpHead("/random/2048");
101             final Future<HttpResponse> future = this.httpclient.execute(target, httpHead, null);
102             final HttpResponse response = future.get();
103             Assert.assertNotNull(response);
104             Assert.assertEquals(200, response.getStatusLine().getStatusCode());
105         }
106     }
107 
108     @Test
109     public void testSinglePost() throws Exception {
110         final HttpHost target = start();
111         final byte[] b1 = new byte[1024];
112         final Random rnd = new Random(System.currentTimeMillis());
113         rnd.nextBytes(b1);
114 
115         final HttpPost httppost = new HttpPost("/echo/stuff");
116         httppost.setEntity(new NByteArrayEntity(b1));
117 
118         final Future<HttpResponse> future = this.httpclient.execute(target, httppost, null);
119         final HttpResponse response = future.get();
120         Assert.assertNotNull(response);
121         Assert.assertEquals(200, response.getStatusLine().getStatusCode());
122         final HttpEntity entity = response.getEntity();
123         Assert.assertNotNull(entity);
124         final byte[] b2 = EntityUtils.toByteArray(entity);
125         Assert.assertArrayEquals(b1, b2);
126     }
127 
128     @Test
129     public void testHttpAsyncMethods() throws Exception {
130         final HttpHost target = start();
131         final byte[] b1 = new byte[1024];
132         final Random rnd = new Random(System.currentTimeMillis());
133         rnd.nextBytes(b1);
134 
135         final Future<HttpResponse> future = this.httpclient.execute(
136             HttpAsyncMethods.createPost(target + "/echo/post", b1, null),
137             new BasicAsyncResponseConsumer(),
138             null);
139         final HttpResponse response = future.get();
140         Assert.assertNotNull(response);
141         Assert.assertEquals(200, response.getStatusLine().getStatusCode());
142         final HttpEntity entity = response.getEntity();
143         Assert.assertNotNull(entity);
144         final byte[] b2 = EntityUtils.toByteArray(entity);
145         Assert.assertArrayEquals(b1, b2);
146     }
147 
148     @Test
149     public void testMultiplePostsOverMultipleConnections() throws Exception {
150         final HttpHost target = start();
151         final byte[] b1 = new byte[1024];
152         final Random rnd = new Random(System.currentTimeMillis());
153         rnd.nextBytes(b1);
154 
155         final int reqCount = 20;
156 
157         this.connMgr.setDefaultMaxPerRoute(reqCount);
158         this.connMgr.setMaxTotal(100);
159 
160         final Queue<Future<HttpResponse>> queue = new LinkedList<Future<HttpResponse>>();
161 
162         for (int i = 0; i < reqCount; i++) {
163             final HttpPost httppost = new HttpPost("/echo/stuff");
164             httppost.setEntity(new NByteArrayEntity(b1));
165             queue.add(this.httpclient.execute(target, httppost, null));
166         }
167 
168         while (!queue.isEmpty()) {
169             final Future<HttpResponse> future = queue.remove();
170             final HttpResponse response = future.get();
171             Assert.assertNotNull(response);
172             Assert.assertEquals(200, response.getStatusLine().getStatusCode());
173             final HttpEntity entity = response.getEntity();
174             Assert.assertNotNull(entity);
175             final byte[] b2 = EntityUtils.toByteArray(entity);
176             Assert.assertArrayEquals(b1, b2);
177         }
178     }
179 
180     @Test
181     public void testMultiplePostsOverSingleConnection() throws Exception {
182         final HttpHost target = start();
183         final byte[] b1 = new byte[1024];
184         final Random rnd = new Random(System.currentTimeMillis());
185         rnd.nextBytes(b1);
186 
187         final int reqCount = 20;
188 
189         this.connMgr.setDefaultMaxPerRoute(1);
190         this.connMgr.setMaxTotal(100);
191 
192         final Queue<Future<HttpResponse>> queue = new LinkedList<Future<HttpResponse>>();
193 
194         for (int i = 0; i < reqCount; i++) {
195             final HttpPost httppost = new HttpPost("/echo/stuff");
196             httppost.setEntity(new NByteArrayEntity(b1));
197             queue.add(this.httpclient.execute(target, httppost, null));
198         }
199 
200         while (!queue.isEmpty()) {
201             final Future<HttpResponse> future = queue.remove();
202             final HttpResponse response = future.get();
203             Assert.assertNotNull(response);
204             Assert.assertEquals(200, response.getStatusLine().getStatusCode());
205             final HttpEntity entity = response.getEntity();
206             Assert.assertNotNull(entity);
207             final byte[] b2 = EntityUtils.toByteArray(entity);
208             Assert.assertArrayEquals(b1, b2);
209         }
210     }
211 
212     @Test
213     public void testRequestFailure() throws Exception {
214         final HttpHost target = start();
215         final HttpGet httpget = new HttpGet("/random/2048");
216         final HttpAsyncRequestProducer requestProducer = HttpAsyncMethods.create(target, httpget) ;
217         final BasicAsyncResponseConsumer responseConsumer = new BasicAsyncResponseConsumer() {
218 
219             @Override
220             public void onContentReceived(final ContentDecoder decoder, final IOControl ioctrl)
221                     throws IOException {
222                 throw new IOException("Kaboom");
223             }
224 
225         };
226         final Future<HttpResponse> future = this.httpclient.execute(requestProducer, responseConsumer, null);
227         try {
228             future.get();
229             Assert.fail("ExecutionException expected");
230         } catch (final ExecutionException ex) {
231             final Throwable t = ex.getCause();
232             Assert.assertNotNull(t);
233             Assert.assertTrue(t instanceof IOException);
234             Assert.assertEquals("Kaboom", t.getMessage());
235         }
236     }
237 
238     @Test
239     public void testSharedPool() throws Exception {
240         final HttpHost target = start();
241         final HttpGet httpget = new HttpGet("/random/2048");
242         final Future<HttpResponse> future = this.httpclient.execute(target, httpget, null);
243         final HttpResponse response = future.get();
244         Assert.assertNotNull(response);
245         Assert.assertEquals(200, response.getStatusLine().getStatusCode());
246 
247 
248         final CloseableHttpAsyncClient httpclient2 = HttpAsyncClients.custom()
249                 .setConnectionManager(this.connMgr)
250                 .setConnectionManagerShared(true)
251                 .build();
252         try {
253             httpclient2.start();
254             final HttpGet httpget2 = new HttpGet("/random/2048");
255             final Future<HttpResponse> future2 = httpclient2.execute(target, httpget2, null);
256             final HttpResponse response2 = future2.get();
257             Assert.assertNotNull(response2);
258             Assert.assertEquals(200, response2.getStatusLine().getStatusCode());
259 
260         } finally {
261             httpclient2.close();
262         }
263 
264         final HttpGet httpget3 = new HttpGet("/random/2048");
265         final Future<HttpResponse> future3 = this.httpclient.execute(target, httpget3, null);
266         final HttpResponse response3 = future3.get();
267         Assert.assertNotNull(response3);
268         Assert.assertEquals(200, response3.getStatusLine().getStatusCode());
269     }
270 
271     @Test
272     public void testClientCloseloseQuietly() throws Exception {
273         final HttpHost target = start();
274         final HttpGet httpget = new HttpGet("/random/2048");
275         final Future<HttpResponse> future = this.httpclient.execute(target, httpget, null);
276         final HttpResponse response = future.get();
277         Assert.assertNotNull(response);
278         Assert.assertEquals(200, response.getStatusLine().getStatusCode());
279 
280         HttpAsyncClientUtils.closeQuietly(this.httpclient);
281         // Close it twice
282         HttpAsyncClientUtils.closeQuietly(this.httpclient);
283     }
284 
285 }