1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 package org.apache.hc.client5.http.examples;
29
30 import java.io.IOException;
31 import java.nio.ByteBuffer;
32 import java.nio.charset.StandardCharsets;
33 import java.util.concurrent.Future;
34 import java.util.concurrent.atomic.AtomicLong;
35
36 import org.apache.hc.client5.http.async.AsyncExecCallback;
37 import org.apache.hc.client5.http.async.AsyncExecChain;
38 import org.apache.hc.client5.http.async.AsyncExecChainHandler;
39 import org.apache.hc.client5.http.async.methods.SimpleHttpRequest;
40 import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
41 import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
42 import org.apache.hc.client5.http.impl.ChainElement;
43 import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
44 import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
45 import org.apache.hc.core5.concurrent.FutureCallback;
46 import org.apache.hc.core5.http.ContentType;
47 import org.apache.hc.core5.http.EntityDetails;
48 import org.apache.hc.core5.http.Header;
49 import org.apache.hc.core5.http.HttpException;
50 import org.apache.hc.core5.http.HttpRequest;
51 import org.apache.hc.core5.http.HttpRequestInterceptor;
52 import org.apache.hc.core5.http.HttpResponse;
53 import org.apache.hc.core5.http.HttpStatus;
54 import org.apache.hc.core5.http.impl.BasicEntityDetails;
55 import org.apache.hc.core5.http.message.BasicHttpResponse;
56 import org.apache.hc.core5.http.message.StatusLine;
57 import org.apache.hc.core5.http.nio.AsyncDataConsumer;
58 import org.apache.hc.core5.http.nio.AsyncEntityProducer;
59 import org.apache.hc.core5.http.protocol.HttpContext;
60 import org.apache.hc.core5.io.CloseMode;
61 import org.apache.hc.core5.reactor.IOReactorConfig;
62 import org.apache.hc.core5.util.Timeout;
63
64
65
66
67
68 public class AsyncClientInterceptors {
69
70 public static void main(final String[] args) throws Exception {
71
72 final IOReactorConfig ioReactorConfig = IOReactorConfig.custom()
73 .setSoTimeout(Timeout.ofSeconds(5))
74 .build();
75
76 final CloseableHttpAsyncClient client = HttpAsyncClients.custom()
77 .setIOReactorConfig(ioReactorConfig)
78
79
80
81 .addRequestInterceptorFirst(new HttpRequestInterceptor() {
82
83 private final AtomicLong count = new AtomicLong(0);
84
85 @Override
86 public void process(
87 final HttpRequest request,
88 final EntityDetails entity,
89 final HttpContext context) throws HttpException, IOException {
90 request.setHeader("request-id", Long.toString(count.incrementAndGet()));
91 }
92 })
93
94
95
96 .addExecInterceptorAfter(ChainElement.PROTOCOL.name(), "custom", new AsyncExecChainHandler() {
97
98 @Override
99 public void execute(
100 final HttpRequest request,
101 final AsyncEntityProducer requestEntityProducer,
102 final AsyncExecChain.Scope scope,
103 final AsyncExecChain chain,
104 final AsyncExecCallback asyncExecCallback) throws HttpException, IOException {
105 final Header idHeader = request.getFirstHeader("request-id");
106 if (idHeader != null && "13".equalsIgnoreCase(idHeader.getValue())) {
107 final HttpResponse response = new BasicHttpResponse(HttpStatus.SC_NOT_FOUND, "Oppsie");
108 final ByteBuffer content = ByteBuffer.wrap("bad luck".getBytes(StandardCharsets.US_ASCII));
109 final AsyncDataConsumer asyncDataConsumer = asyncExecCallback.handleResponse(
110 response,
111 new BasicEntityDetails(content.remaining(), ContentType.TEXT_PLAIN));
112 asyncDataConsumer.consume(content);
113 asyncDataConsumer.streamEnd(null);
114 } else {
115 chain.proceed(request, requestEntityProducer, scope, asyncExecCallback);
116 }
117 }
118
119 })
120
121 .build();
122
123 client.start();
124
125 final String requestUri = "http://httpbin.org/get";
126 for (int i = 0; i < 20; i++) {
127 final SimpleHttpRequest request = SimpleRequestBuilder.get(requestUri).build();
128 System.out.println("Executing request " + request);
129 final Future<SimpleHttpResponse> future = client.execute(
130 request,
131 new FutureCallback<SimpleHttpResponse>() {
132
133 @Override
134 public void completed(final SimpleHttpResponse response) {
135 System.out.println(request + "->" + new StatusLine(response));
136 System.out.println(response.getBody());
137 }
138
139 @Override
140 public void failed(final Exception ex) {
141 System.out.println(request + "->" + ex);
142 }
143
144 @Override
145 public void cancelled() {
146 System.out.println(request + " cancelled");
147 }
148
149 });
150 future.get();
151 }
152
153 System.out.println("Shutting down");
154 client.close(CloseMode.GRACEFUL);
155 }
156
157 }
158