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