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.testing.async.extension;
29
30 import java.net.InetSocketAddress;
31 import java.util.function.Consumer;
32
33 import org.apache.hc.client5.http.config.ConnectionConfig;
34 import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
35 import org.apache.hc.client5.http.impl.async.H2AsyncClientBuilder;
36 import org.apache.hc.client5.http.impl.async.HttpAsyncClientBuilder;
37 import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
38 import org.apache.hc.client5.http.impl.async.MinimalH2AsyncClient;
39 import org.apache.hc.client5.http.impl.async.MinimalHttpAsyncClient;
40 import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManager;
41 import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBuilder;
42 import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
43 import org.apache.hc.client5.testing.SSLTestContexts;
44 import org.apache.hc.client5.testing.sync.extension.TestClientResources;
45 import org.apache.hc.core5.function.Decorator;
46 import org.apache.hc.core5.http.HttpHost;
47 import org.apache.hc.core5.http.URIScheme;
48 import org.apache.hc.core5.http.config.Http1Config;
49 import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
50 import org.apache.hc.core5.http.protocol.HttpProcessor;
51 import org.apache.hc.core5.http2.config.H2Config;
52 import org.apache.hc.core5.io.CloseMode;
53 import org.apache.hc.core5.reactor.IOReactorConfig;
54 import org.apache.hc.core5.testing.nio.H2TestServer;
55 import org.apache.hc.core5.util.TimeValue;
56 import org.apache.hc.core5.util.Timeout;
57 import org.junit.jupiter.api.Assertions;
58 import org.junit.jupiter.api.extension.AfterEachCallback;
59 import org.junit.jupiter.api.extension.BeforeEachCallback;
60 import org.junit.jupiter.api.extension.ExtensionContext;
61 import org.slf4j.Logger;
62 import org.slf4j.LoggerFactory;
63
64 public class TestAsyncResources implements BeforeEachCallback, AfterEachCallback {
65
66 private static final Logger LOG = LoggerFactory.getLogger(TestClientResources.class);
67
68 private final URIScheme scheme;
69 private final Timeout timeout;
70
71 private H2TestServer server;
72 private InetSocketAddress socketAddress;
73 private PoolingAsyncClientConnectionManager connManager;
74 private CloseableHttpAsyncClient client;
75
76 public TestAsyncResources(final URIScheme scheme, final Timeout timeout) {
77 this.scheme = scheme;
78 this.timeout = timeout;
79 }
80
81 @Override
82 public void beforeEach(final ExtensionContext extensionContext) throws Exception {
83 LOG.debug("Starting up test server");
84 server = new H2TestServer(
85 IOReactorConfig.custom()
86 .setSoTimeout(timeout)
87 .build(),
88 scheme == URIScheme.HTTPS ? SSLTestContexts.createServerSSLContext() : null,
89 null,
90 null);
91 }
92
93 @Override
94 public void afterEach(final ExtensionContext extensionContext) throws Exception {
95 LOG.debug("Shutting down test server");
96
97 if (client != null) {
98 client.close(CloseMode.GRACEFUL);
99 }
100
101 if (connManager != null) {
102 connManager.close(CloseMode.IMMEDIATE);
103 }
104
105 if (server != null) {
106 server.shutdown(TimeValue.ofSeconds(5));
107 }
108 }
109
110 public URIScheme scheme() {
111 return this.scheme;
112 }
113
114 public H2TestServer startServer(
115 final H2Config h2Config,
116 final HttpProcessor httpProcessor,
117 final Decorator<AsyncServerExchangeHandler> exchangeHandlerDecorator) throws Exception {
118 Assertions.assertNotNull(server);
119 socketAddress = server.start(httpProcessor, exchangeHandlerDecorator, h2Config);
120 return server;
121 }
122
123 public H2TestServer startServer(
124 final Http1Config http1Config,
125 final HttpProcessor httpProcessor,
126 final Decorator<AsyncServerExchangeHandler> exchangeHandlerDecorator) throws Exception {
127 Assertions.assertNotNull(server);
128 socketAddress = server.start(httpProcessor, exchangeHandlerDecorator, http1Config);
129 return server;
130 }
131
132 public HttpHost targetHost() {
133 Assertions.assertNotNull(socketAddress);
134 return new HttpHost(scheme.id, "localhost", socketAddress.getPort());
135 }
136
137 public CloseableHttpAsyncClient startClient(
138 final Consumer<PoolingAsyncClientConnectionManagerBuilder> connManagerCustomizer,
139 final Consumer<HttpAsyncClientBuilder> clientCustomizer) throws Exception {
140 Assertions.assertNull(connManager);
141 Assertions.assertNull(client);
142
143 final PoolingAsyncClientConnectionManagerBuilder connManagerBuilder = PoolingAsyncClientConnectionManagerBuilder.create();
144 connManagerBuilder.setTlsStrategy(new DefaultClientTlsStrategy(SSLTestContexts.createClientSSLContext()));
145 connManagerBuilder.setDefaultConnectionConfig(ConnectionConfig.custom()
146 .setSocketTimeout(timeout)
147 .setConnectTimeout(timeout)
148 .build());
149 connManagerCustomizer.accept(connManagerBuilder);
150
151 connManager = connManagerBuilder.build();
152
153 final HttpAsyncClientBuilder clientBuilder = HttpAsyncClientBuilder.create()
154 .setConnectionManager(connManager)
155 .setIOReactorConfig(IOReactorConfig.custom()
156 .setSoTimeout(timeout)
157 .build());
158
159 clientCustomizer.accept(clientBuilder);
160 client = clientBuilder.build();
161 client.start();
162 return client;
163 }
164
165 public CloseableHttpAsyncClient startClient(
166 final Consumer<HttpAsyncClientBuilder> clientCustomizer) throws Exception {
167 return startClient(b -> {
168 }, clientCustomizer);
169 }
170
171 public PoolingAsyncClientConnectionManager connManager() {
172 Assertions.assertNotNull(connManager);
173 return connManager;
174 }
175
176 public CloseableHttpAsyncClient startH2Client(
177 final Consumer<H2AsyncClientBuilder> clientCustomizer) throws Exception {
178 Assertions.assertNull(connManager);
179 Assertions.assertNull(client);
180
181 final H2AsyncClientBuilder clientBuilder = H2AsyncClientBuilder.create();
182 clientBuilder.setIOReactorConfig(IOReactorConfig.custom()
183 .setSoTimeout(timeout)
184 .build());
185 clientBuilder.setTlsStrategy(new DefaultClientTlsStrategy(SSLTestContexts.createClientSSLContext()));
186 clientCustomizer.accept(clientBuilder);
187 client = clientBuilder.build();
188 client.start();
189 return client;
190 }
191
192 public MinimalHttpAsyncClient startMinimalClient(
193 final Http1Config http1Config,
194 final H2Config h2Config,
195 final Consumer<PoolingAsyncClientConnectionManagerBuilder> connManagerCustomizer) throws Exception {
196 Assertions.assertNull(connManager);
197 Assertions.assertNull(client);
198
199 final PoolingAsyncClientConnectionManagerBuilder connManagerBuilder = PoolingAsyncClientConnectionManagerBuilder.create();
200 connManagerBuilder.setTlsStrategy(new DefaultClientTlsStrategy(SSLTestContexts.createClientSSLContext()));
201 connManagerBuilder.setDefaultConnectionConfig(ConnectionConfig.custom()
202 .setSocketTimeout(timeout)
203 .setConnectTimeout(timeout)
204 .build());
205 connManagerCustomizer.accept(connManagerBuilder);
206
207 connManager = connManagerBuilder.build();
208
209 final MinimalHttpAsyncClient minimal = HttpAsyncClients.createMinimal(
210 h2Config,
211 http1Config,
212 IOReactorConfig.custom()
213 .setSoTimeout(timeout)
214 .build(),
215 connManager);
216 client = minimal;
217 client.start();
218 return minimal;
219 }
220
221 public MinimalH2AsyncClient startMinimalH2Client(final H2Config h2Config) throws Exception {
222 Assertions.assertNull(client);
223
224 final MinimalH2AsyncClient minimal = HttpAsyncClients.createHttp2Minimal(
225 h2Config,
226 IOReactorConfig.custom()
227 .setSoTimeout(timeout)
228 .build(),
229 new DefaultClientTlsStrategy(SSLTestContexts.createClientSSLContext()));
230 client = minimal;
231 client.start();
232 return minimal;
233 }
234
235 }