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