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.methods;
28  
29  import java.io.IOException;
30  import java.nio.ByteBuffer;
31  import java.nio.CharBuffer;
32  import java.util.concurrent.ExecutionException;
33  import java.util.concurrent.Future;
34  import java.util.concurrent.atomic.AtomicLong;
35  
36  import org.apache.http.Consts;
37  import org.apache.http.localserver.HttpAsyncTestBase;
38  import org.apache.http.HttpException;
39  import org.apache.http.HttpHost;
40  import org.apache.http.HttpResponse;
41  import org.apache.http.entity.ContentType;
42  import org.apache.http.localserver.EchoHandler;
43  import org.apache.http.localserver.RandomHandler;
44  import org.apache.http.nio.IOControl;
45  import org.apache.http.nio.protocol.BasicAsyncRequestHandler;
46  import org.apache.http.nio.protocol.HttpAsyncRequestProducer;
47  import org.apache.http.protocol.HttpContext;
48  import org.junit.Assert;
49  import org.junit.Before;
50  import org.junit.Test;
51  import org.mockito.Mockito;
52  
53  public class TestAsyncConsumers extends HttpAsyncTestBase {
54  
55      @Before @Override
56      public void setUp() throws Exception {
57          super.setUp();
58          this.serverBootstrap.registerHandler("/echo/*", new BasicAsyncRequestHandler(new EchoHandler()));
59          this.serverBootstrap.registerHandler("/random/*", new BasicAsyncRequestHandler(new RandomHandler()));
60      }
61  
62      static class ByteCountingConsumer extends AsyncByteConsumer<Long> {
63  
64          public ByteCountingConsumer() {
65              super();
66          }
67  
68          public ByteCountingConsumer(final int bufSize) {
69              super(bufSize);
70          }
71  
72          private final AtomicLong count = new AtomicLong(0);
73  
74          @Override
75          protected void onResponseReceived(final HttpResponse response) {
76          }
77  
78          @Override
79          protected void onByteReceived(final ByteBuffer buf, final IOControl ioctrl) {
80              this.count.addAndGet(buf.remaining());
81          }
82  
83          @Override
84          protected Long buildResult(final HttpContext context) throws Exception {
85              return count.get();
86          }
87  
88      }
89  
90      @Test
91      public void testByteConsumer() throws Exception {
92          final HttpHost target = start();
93          for (int i = 0; i < 5; i++) {
94              final HttpAsyncRequestProducer httpget = HttpAsyncMethods.createGet(target.toURI() + "/random/20480");
95              final AsyncByteConsumer<Long> consumer = new ByteCountingConsumer();
96              final Future<Long> future = this.httpclient.execute(httpget, consumer, null);
97              final Long count = future.get();
98              Assert.assertEquals(20480, count.longValue());
99          }
100     }
101 
102     @Test
103     public void testByteConsumerSmallBufffer() throws Exception {
104         final HttpHost target = start();
105         for (int i = 0; i < 5; i++) {
106             final HttpAsyncRequestProducer httpget = HttpAsyncMethods.createGet(target.toURI() + "/random/20480");
107             final AsyncByteConsumer<Long> consumer = new ByteCountingConsumer(512);
108             final Future<Long> future = this.httpclient.execute(httpget, consumer, null);
109             final Long count = future.get();
110             Assert.assertEquals(20480, count.longValue());
111         }
112     }
113 
114     static class BufferingCharConsumer extends AsyncCharConsumer<String> {
115 
116         public BufferingCharConsumer() {
117             super();
118         }
119 
120         public BufferingCharConsumer(final int bufSize) {
121             super(bufSize);
122         }
123 
124         private final StringBuilder sb = new StringBuilder();
125 
126         @Override
127         public void onResponseReceived(final HttpResponse response) {
128         }
129 
130         @Override
131         protected void onCharReceived(final CharBuffer buf, final IOControl ioctrl) throws IOException {
132             while (buf.hasRemaining()) {
133                 this.sb.append(buf.get());
134             }
135         }
136 
137         @Override
138         protected void releaseResources() {
139             super.releaseResources();
140             this.sb.setLength(0);
141         }
142 
143         @Override
144         protected String buildResult(final HttpContext context) throws Exception {
145             return this.sb.toString();
146         }
147 
148     }
149 
150     @Test
151     public void testCharConsumer() throws Exception {
152         final HttpHost target = start();
153         final StringBuilder sb = new StringBuilder();
154         for (int i= 0; i < 25; i++) {
155             sb.append("blah blah blah blah\r\n");
156             sb.append("yada yada yada yada\r\n");
157         }
158         final String s = sb.toString();
159 
160         for (int i = 0; i < 5; i++) {
161             final HttpAsyncRequestProducer httppost = HttpAsyncMethods.createPost(
162                     target.toURI() + "/echo/stuff", s,
163                     ContentType.create("text/plain", Consts.ASCII));
164             final AsyncCharConsumer<String> consumer = new BufferingCharConsumer();
165             final Future<String> future = this.httpclient.execute(httppost, consumer, null);
166             final String result = future.get();
167             Assert.assertEquals(s, result);
168         }
169     }
170 
171     @Test
172     public void testCharConsumerSmallBufffer() throws Exception {
173         final HttpHost target = start();
174         final StringBuilder sb = new StringBuilder();
175         for (int i= 0; i < 25; i++) {
176             sb.append("blah blah blah blah\r\n");
177             sb.append("yada yada yada yada\r\n");
178         }
179         final String s = sb.toString();
180 
181         for (int i = 0; i < 5; i++) {
182             final HttpAsyncRequestProducer httppost = HttpAsyncMethods.createPost(
183                     target.toURI() + "/echo/stuff", s,
184                     ContentType.create("text/plain", Consts.ASCII));
185             final AsyncCharConsumer<String> consumer = new BufferingCharConsumer(512);
186             final Future<String> future = this.httpclient.execute(httppost, consumer, null);
187             final String result = future.get();
188             Assert.assertEquals(s, result);
189         }
190     }
191 
192     @Test
193     public void testResourceReleaseOnSuccess() throws Exception {
194         final HttpHost target = start();
195         final StringBuilder sb = new StringBuilder();
196         for (int i= 0; i < 25; i++) {
197             sb.append("blah blah blah blah\r\n");
198             sb.append("yada yada yada yada\r\n");
199         }
200         final String s = sb.toString();
201 
202         final HttpAsyncRequestProducer httppost = HttpAsyncMethods.createPost(
203                 target.toURI() + "/echo/stuff", s,
204                 ContentType.create("text/plain", Consts.ASCII));
205         final BufferingCharConsumer consumer = Mockito.spy(new BufferingCharConsumer());
206         final Future<String> future = this.httpclient.execute(httppost, consumer, null);
207         final String result = future.get();
208         Assert.assertEquals(s, result);
209         Mockito.verify(consumer).buildResult(Mockito.any(HttpContext.class));
210         Mockito.verify(consumer).releaseResources();
211     }
212 
213     @Test
214     public void testResourceReleaseOnException() throws Exception {
215         final HttpHost target = start();
216         final HttpAsyncRequestProducer httppost = HttpAsyncMethods.createPost(
217                 target.toURI() + "/echo/stuff", "stuff",
218                 ContentType.create("text/plain", Consts.ASCII));
219         final AsyncCharConsumer<String> consumer = Mockito.spy(new BufferingCharConsumer());
220         Mockito.doThrow(new IOException("Kaboom")).when(consumer).onCharReceived(
221                 Mockito.any(CharBuffer.class), Mockito.any(IOControl.class));
222 
223         final Future<String> future = this.httpclient.execute(httppost, consumer, null);
224         try {
225             future.get();
226             Assert.fail("ExecutionException expected");
227         } catch (final ExecutionException ex) {
228             final Throwable t = ex.getCause();
229             Assert.assertNotNull(t);
230             Assert.assertTrue(t instanceof IOException);
231             Assert.assertEquals("Kaboom", t.getMessage());
232         }
233         Mockito.verify(consumer).releaseResources();
234     }
235 
236     @Test
237     public void testResourceReleaseOnBuildFailure() throws Exception {
238         final HttpHost target = start();
239         final HttpAsyncRequestProducer httppost = HttpAsyncMethods.createPost(
240                 target.toURI() + "/echo/stuff", "stuff",
241                 ContentType.create("text/plain", Consts.ASCII));
242         final BufferingCharConsumer consumer = Mockito.spy(new BufferingCharConsumer());
243         Mockito.doThrow(new HttpException("Kaboom")).when(consumer).buildResult(Mockito.any(HttpContext.class));
244 
245         final Future<String> future = this.httpclient.execute(httppost, consumer, null);
246         try {
247             future.get();
248             Assert.fail("ExecutionException expected");
249         } catch (final ExecutionException ex) {
250             final Throwable t = ex.getCause();
251             Assert.assertNotNull(t);
252             Assert.assertTrue(t instanceof HttpException);
253             Assert.assertEquals("Kaboom", t.getMessage());
254         }
255         Mockito.verify(consumer).releaseResources();
256     }
257 
258 }