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 package org.apache.hc.core5.http2.impl.nio.bootstrap;
28
29 import java.util.ArrayList;
30 import java.util.List;
31
32 import org.apache.hc.core5.annotation.Experimental;
33 import org.apache.hc.core5.function.Callback;
34 import org.apache.hc.core5.function.Decorator;
35 import org.apache.hc.core5.function.Supplier;
36 import org.apache.hc.core5.http.HttpHost;
37 import org.apache.hc.core5.http.config.CharCodingConfig;
38 import org.apache.hc.core5.http.config.Http1Config;
39 import org.apache.hc.core5.http.impl.DefaultConnectionReuseStrategy;
40 import org.apache.hc.core5.http.impl.DefaultContentLengthStrategy;
41 import org.apache.hc.core5.http.impl.Http1StreamListener;
42 import org.apache.hc.core5.http.impl.HttpProcessors;
43 import org.apache.hc.core5.http.impl.nio.ClientHttp1StreamDuplexerFactory;
44 import org.apache.hc.core5.http.impl.nio.DefaultHttpRequestWriterFactory;
45 import org.apache.hc.core5.http.impl.nio.DefaultHttpResponseParserFactory;
46 import org.apache.hc.core5.http.impl.routing.RequestRouter;
47 import org.apache.hc.core5.http.nio.AsyncPushConsumer;
48 import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
49 import org.apache.hc.core5.http.protocol.HttpProcessor;
50 import org.apache.hc.core5.http.protocol.UriPatternType;
51 import org.apache.hc.core5.http2.HttpVersionPolicy;
52 import org.apache.hc.core5.http2.config.H2Config;
53 import org.apache.hc.core5.http2.impl.H2Processors;
54 import org.apache.hc.core5.http2.impl.nio.ClientH2StreamMultiplexerFactory;
55 import org.apache.hc.core5.http2.impl.nio.ClientHttpProtocolNegotiationStarter;
56 import org.apache.hc.core5.http2.impl.nio.H2StreamListener;
57 import org.apache.hc.core5.http2.nio.support.DefaultAsyncPushConsumerFactory;
58 import org.apache.hc.core5.http2.ssl.H2ClientTlsStrategy;
59 import org.apache.hc.core5.pool.ConnPoolListener;
60 import org.apache.hc.core5.pool.DefaultDisposalCallback;
61 import org.apache.hc.core5.pool.LaxConnPool;
62 import org.apache.hc.core5.pool.ManagedConnPool;
63 import org.apache.hc.core5.pool.PoolConcurrencyPolicy;
64 import org.apache.hc.core5.pool.PoolReusePolicy;
65 import org.apache.hc.core5.pool.StrictConnPool;
66 import org.apache.hc.core5.reactor.IOEventHandlerFactory;
67 import org.apache.hc.core5.reactor.IOReactorConfig;
68 import org.apache.hc.core5.reactor.IOSession;
69 import org.apache.hc.core5.reactor.IOSessionListener;
70 import org.apache.hc.core5.util.Args;
71 import org.apache.hc.core5.util.TimeValue;
72 import org.apache.hc.core5.util.Timeout;
73
74
75
76
77
78
79 public class H2RequesterBootstrap {
80
81 private final List<RequestRouter.Entry<Supplier<AsyncPushConsumer>>> routeEntries;
82 private UriPatternType uriPatternType;
83 private IOReactorConfig ioReactorConfig;
84 private HttpProcessor httpProcessor;
85 private CharCodingConfig charCodingConfig;
86 private HttpVersionPolicy versionPolicy;
87 private H2Config h2Config;
88 private Http1Config http1Config;
89 private int defaultMaxPerRoute;
90 private int maxTotal;
91 private TimeValue timeToLive;
92 private PoolReusePolicy poolReusePolicy;
93 private PoolConcurrencyPolicy poolConcurrencyPolicy;
94 private TlsStrategy tlsStrategy;
95 private Timeout handshakeTimeout;
96 private Decorator<IOSession> ioSessionDecorator;
97 private Callback<Exception> exceptionCallback;
98 private IOSessionListener sessionListener;
99 private H2StreamListener streamListener;
100 private Http1StreamListener http1StreamListener;
101 private ConnPoolListener<HttpHost> connPoolListener;
102
103 private H2RequesterBootstrap() {
104 this.routeEntries = new ArrayList<>();
105 }
106
107 public static H2RequesterBootstrap bootstrap() {
108 return new H2RequesterBootstrap();
109 }
110
111
112
113
114 public final H2RequesterBootstrap setIOReactorConfig(final IOReactorConfig ioReactorConfig) {
115 this.ioReactorConfig = ioReactorConfig;
116 return this;
117 }
118
119
120
121
122 public final H2RequesterBootstrap setHttpProcessor(final HttpProcessor httpProcessor) {
123 this.httpProcessor = httpProcessor;
124 return this;
125 }
126
127
128
129
130 public final H2RequesterBootstrap setVersionPolicy(final HttpVersionPolicy versionPolicy) {
131 this.versionPolicy = versionPolicy;
132 return this;
133 }
134
135
136
137
138 public final H2RequesterBootstrap setH2Config(final H2Config h2Config) {
139 this.h2Config = h2Config;
140 return this;
141 }
142
143
144
145
146 public final H2RequesterBootstrap setHttp1Config(final Http1Config http1Config) {
147 this.http1Config = http1Config;
148 return this;
149 }
150
151
152
153
154 public final H2RequesterBootstrap setCharCodingConfig(final CharCodingConfig charCodingConfig) {
155 this.charCodingConfig = charCodingConfig;
156 return this;
157 }
158
159 public final H2RequesterBootstrap setDefaultMaxPerRoute(final int defaultMaxPerRoute) {
160 this.defaultMaxPerRoute = defaultMaxPerRoute;
161 return this;
162 }
163
164 public final H2RequesterBootstrap setMaxTotal(final int maxTotal) {
165 this.maxTotal = maxTotal;
166 return this;
167 }
168
169 public final H2RequesterBootstrap setTimeToLive(final TimeValue timeToLive) {
170 this.timeToLive = timeToLive;
171 return this;
172 }
173
174
175
176
177 public final H2RequesterBootstrap setPoolReusePolicy(final PoolReusePolicy poolReusePolicy) {
178 this.poolReusePolicy = poolReusePolicy;
179 return this;
180 }
181
182
183
184
185 @Experimental
186 public final H2RequesterBootstrap setPoolConcurrencyPolicy(final PoolConcurrencyPolicy poolConcurrencyPolicy) {
187 this.poolConcurrencyPolicy = poolConcurrencyPolicy;
188 return this;
189 }
190
191
192
193
194 public final H2RequesterBootstrap setTlsStrategy(final TlsStrategy tlsStrategy) {
195 this.tlsStrategy = tlsStrategy;
196 return this;
197 }
198
199 public final H2RequesterBootstrap setHandshakeTimeout(final Timeout handshakeTimeout) {
200 this.handshakeTimeout = handshakeTimeout;
201 return this;
202 }
203
204
205
206
207 public final H2RequesterBootstrap setIOSessionDecorator(final Decorator<IOSession> ioSessionDecorator) {
208 this.ioSessionDecorator = ioSessionDecorator;
209 return this;
210 }
211
212
213
214
215 public final H2RequesterBootstrap setExceptionCallback(final Callback<Exception> exceptionCallback) {
216 this.exceptionCallback = exceptionCallback;
217 return this;
218 }
219
220
221
222
223 public final H2RequesterBootstrap setIOSessionListener(final IOSessionListener sessionListener) {
224 this.sessionListener = sessionListener;
225 return this;
226 }
227
228
229
230
231 public final H2RequesterBootstrap setStreamListener(final H2StreamListener streamListener) {
232 this.streamListener = streamListener;
233 return this;
234 }
235
236
237
238
239 public final H2RequesterBootstrap setStreamListener(final Http1StreamListener http1StreamListener) {
240 this.http1StreamListener = http1StreamListener;
241 return this;
242 }
243
244
245
246
247 public final H2RequesterBootstrap setConnPoolListener(final ConnPoolListener<HttpHost> connPoolListener) {
248 this.connPoolListener = connPoolListener;
249 return this;
250 }
251
252
253
254
255 public final H2RequesterBootstrap setUriPatternType(final UriPatternType uriPatternType) {
256 this.uriPatternType = uriPatternType;
257 return this;
258 }
259
260
261
262
263
264
265
266
267 public final H2RequesterBootstrap register(final String uriPattern, final Supplier<AsyncPushConsumer> supplier) {
268 Args.notBlank(uriPattern, "URI pattern");
269 Args.notNull(supplier, "Push consumer supplier");
270 routeEntries.add(new RequestRouter.Entry<>(uriPattern, supplier));
271 return this;
272 }
273
274
275
276
277
278
279
280
281
282
283
284 public final H2RequesterBootstrap register(final String hostname, final String uriPattern, final Supplier<AsyncPushConsumer> supplier) {
285 Args.notBlank(hostname, "Hostname");
286 Args.notBlank(uriPattern, "URI pattern");
287 Args.notNull(supplier, "Push consumer supplier");
288 routeEntries.add(new RequestRouter.Entry<>(hostname, uriPattern, supplier));
289 return this;
290 }
291
292
293
294
295 @Deprecated
296 public final H2RequesterBootstrap registerVirtual(final String hostname, final String uriPattern, final Supplier<AsyncPushConsumer> supplier) {
297 return register(hostname, uriPattern, supplier);
298 }
299
300 public H2AsyncRequester create() {
301 final ManagedConnPool<HttpHost, IOSession> connPool;
302 switch (poolConcurrencyPolicy != null ? poolConcurrencyPolicy : PoolConcurrencyPolicy.STRICT) {
303 case LAX:
304 connPool = new LaxConnPool<>(
305 defaultMaxPerRoute > 0 ? defaultMaxPerRoute : 20,
306 timeToLive,
307 poolReusePolicy,
308 new DefaultDisposalCallback<>(),
309 connPoolListener);
310 break;
311 case STRICT:
312 default:
313 connPool = new StrictConnPool<>(
314 defaultMaxPerRoute > 0 ? defaultMaxPerRoute : 20,
315 maxTotal > 0 ? maxTotal : 50,
316 timeToLive,
317 poolReusePolicy,
318 new DefaultDisposalCallback<>(),
319 connPoolListener);
320 break;
321 }
322 final RequestRouter<Supplier<AsyncPushConsumer>> requestRouter = RequestRouter.create(
323 null, uriPatternType, routeEntries, RequestRouter.LOCAL_AUTHORITY_RESOLVER, null);
324
325 final ClientH2StreamMultiplexerFactory http2StreamHandlerFactory = new ClientH2StreamMultiplexerFactory(
326 httpProcessor != null ? httpProcessor : H2Processors.client(),
327 new DefaultAsyncPushConsumerFactory(requestRouter),
328 h2Config != null ? h2Config : H2Config.DEFAULT,
329 charCodingConfig != null ? charCodingConfig : CharCodingConfig.DEFAULT,
330 streamListener);
331
332 final TlsStrategy actualTlsStrategy = tlsStrategy != null ? tlsStrategy : new H2ClientTlsStrategy();
333
334 final ClientHttp1StreamDuplexerFactory http1StreamHandlerFactory = new ClientHttp1StreamDuplexerFactory(
335 httpProcessor != null ? httpProcessor : HttpProcessors.client(),
336 http1Config != null ? http1Config : Http1Config.DEFAULT,
337 charCodingConfig != null ? charCodingConfig : CharCodingConfig.DEFAULT,
338 DefaultConnectionReuseStrategy.INSTANCE,
339 new DefaultHttpResponseParserFactory(http1Config),
340 DefaultHttpRequestWriterFactory.INSTANCE,
341 DefaultContentLengthStrategy.INSTANCE,
342 DefaultContentLengthStrategy.INSTANCE,
343 http1StreamListener);
344
345 final IOEventHandlerFactory ioEventHandlerFactory = new ClientHttpProtocolNegotiationStarter(
346 http1StreamHandlerFactory,
347 http2StreamHandlerFactory,
348 versionPolicy != null ? versionPolicy : HttpVersionPolicy.NEGOTIATE,
349 actualTlsStrategy,
350 handshakeTimeout);
351
352 return new H2AsyncRequester(
353 versionPolicy != null ? versionPolicy : HttpVersionPolicy.NEGOTIATE,
354 ioReactorConfig,
355 ioEventHandlerFactory,
356 ioSessionDecorator,
357 exceptionCallback,
358 sessionListener,
359 connPool,
360 actualTlsStrategy,
361 handshakeTimeout);
362 }
363
364 }