View Javadoc
1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
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 }