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.nio.AsyncPushConsumer;
47 import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
48 import org.apache.hc.core5.http.protocol.HttpProcessor;
49 import org.apache.hc.core5.http.protocol.RequestHandlerRegistry;
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.ClientHttpProtocolNegotiatorFactory;
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<HandlerEntry<Supplier<AsyncPushConsumer>>> pushConsumerList;
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.pushConsumerList = 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, "Supplier");
270 pushConsumerList.add(new HandlerEntry<>(null, uriPattern, supplier));
271 return this;
272 }
273
274
275
276
277
278
279
280
281
282 public final H2RequesterBootstrap registerVirtual(final String hostname, final String uriPattern, final Supplier<AsyncPushConsumer> supplier) {
283 Args.notBlank(hostname, "Hostname");
284 Args.notBlank(uriPattern, "URI pattern");
285 Args.notNull(supplier, "Supplier");
286 pushConsumerList.add(new HandlerEntry<>(hostname, uriPattern, supplier));
287 return this;
288 }
289
290 public H2AsyncRequester create() {
291 final ManagedConnPool<HttpHost, IOSession> connPool;
292 switch (poolConcurrencyPolicy != null ? poolConcurrencyPolicy : PoolConcurrencyPolicy.STRICT) {
293 case LAX:
294 connPool = new LaxConnPool<>(
295 defaultMaxPerRoute > 0 ? defaultMaxPerRoute : 20,
296 timeToLive,
297 poolReusePolicy,
298 new DefaultDisposalCallback<IOSession>(),
299 connPoolListener);
300 break;
301 case STRICT:
302 default:
303 connPool = new StrictConnPool<>(
304 defaultMaxPerRoute > 0 ? defaultMaxPerRoute : 20,
305 maxTotal > 0 ? maxTotal : 50,
306 timeToLive,
307 poolReusePolicy,
308 new DefaultDisposalCallback<IOSession>(),
309 connPoolListener);
310 break;
311 }
312 final RequestHandlerRegistry<Supplier<AsyncPushConsumer>> registry = new RequestHandlerRegistry<>(uriPatternType);
313 for (final HandlerEntry<Supplier<AsyncPushConsumer>> entry: pushConsumerList) {
314 registry.register(entry.hostname, entry.uriPattern, entry.handler);
315 }
316
317 final ClientH2StreamMultiplexerFactoryactory.html#ClientH2StreamMultiplexerFactory">ClientH2StreamMultiplexerFactory http2StreamHandlerFactory = new ClientH2StreamMultiplexerFactory(
318 httpProcessor != null ? httpProcessor : H2Processors.client(),
319 new DefaultAsyncPushConsumerFactory(registry),
320 h2Config != null ? h2Config : H2Config.DEFAULT,
321 charCodingConfig != null ? charCodingConfig : CharCodingConfig.DEFAULT,
322 streamListener);
323
324 final HttpVersionPolicy actualVersionProtocol = versionPolicy != null ? versionPolicy : HttpVersionPolicy.NEGOTIATE;
325 final TlsStrategy actualTlsStrategy = tlsStrategy != null ? tlsStrategy : new H2ClientTlsStrategy();
326
327 final ClientHttp1StreamDuplexerFactoryctory.html#ClientHttp1StreamDuplexerFactory">ClientHttp1StreamDuplexerFactory http1StreamHandlerFactory = new ClientHttp1StreamDuplexerFactory(
328 httpProcessor != null ? httpProcessor : HttpProcessors.client(),
329 http1Config != null ? http1Config : Http1Config.DEFAULT,
330 charCodingConfig != null ? charCodingConfig : CharCodingConfig.DEFAULT,
331 DefaultConnectionReuseStrategy.INSTANCE,
332 new DefaultHttpResponseParserFactory(http1Config),
333 DefaultHttpRequestWriterFactory.INSTANCE,
334 DefaultContentLengthStrategy.INSTANCE,
335 DefaultContentLengthStrategy.INSTANCE,
336 http1StreamListener);
337
338 final IOEventHandlerFactory ioEventHandlerFactory = new ClientHttpProtocolNegotiatorFactory(
339 http1StreamHandlerFactory,
340 http2StreamHandlerFactory,
341 actualVersionProtocol,
342 actualTlsStrategy,
343 handshakeTimeout);
344
345 return new H2AsyncRequester(
346 versionPolicy != null ? versionPolicy : HttpVersionPolicy.NEGOTIATE,
347 ioReactorConfig,
348 ioEventHandlerFactory,
349 ioSessionDecorator,
350 exceptionCallback,
351 sessionListener,
352 connPool);
353 }
354
355 }