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.http.impl.nio;
29  
30  import org.apache.hc.client5.http.DnsResolver;
31  import org.apache.hc.client5.http.HttpRoute;
32  import org.apache.hc.client5.http.SchemePortResolver;
33  import org.apache.hc.client5.http.config.ConnectionConfig;
34  import org.apache.hc.client5.http.config.TlsConfig;
35  import org.apache.hc.client5.http.ssl.ConscryptClientTlsStrategy;
36  import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
37  import org.apache.hc.core5.function.Resolver;
38  import org.apache.hc.core5.http.HttpHost;
39  import org.apache.hc.core5.http.URIScheme;
40  import org.apache.hc.core5.http.config.RegistryBuilder;
41  import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
42  import org.apache.hc.core5.pool.PoolConcurrencyPolicy;
43  import org.apache.hc.core5.pool.PoolReusePolicy;
44  import org.apache.hc.core5.util.ReflectionUtils;
45  import org.apache.hc.core5.util.TimeValue;
46  
47  /**
48   * Builder for {@link PoolingAsyncClientConnectionManager} instances.
49   * <p>
50   * When a particular component is not explicitly set this class will
51   * use its default implementation. System properties will be taken
52   * into account when configuring the default implementations when
53   * {@link #useSystemProperties()} method is called prior to calling
54   * {@link #build()}.
55   * </p>
56   * <ul>
57   *  <li>ssl.TrustManagerFactory.algorithm</li>
58   *  <li>javax.net.ssl.trustStoreType</li>
59   *  <li>javax.net.ssl.trustStore</li>
60   *  <li>javax.net.ssl.trustStoreProvider</li>
61   *  <li>javax.net.ssl.trustStorePassword</li>
62   *  <li>ssl.KeyManagerFactory.algorithm</li>
63   *  <li>javax.net.ssl.keyStoreType</li>
64   *  <li>javax.net.ssl.keyStore</li>
65   *  <li>javax.net.ssl.keyStoreProvider</li>
66   *  <li>javax.net.ssl.keyStorePassword</li>
67   *  <li>https.protocols</li>
68   *  <li>https.cipherSuites</li>
69   * </ul>
70   *
71   * @since 5.0
72   */
73  public class PoolingAsyncClientConnectionManagerBuilder {
74  
75      private TlsStrategy tlsStrategy;
76      private SchemePortResolver schemePortResolver;
77      private DnsResolver dnsResolver;
78      private PoolConcurrencyPolicy poolConcurrencyPolicy;
79      private PoolReusePolicy poolReusePolicy;
80  
81      private boolean systemProperties;
82  
83      private int maxConnTotal;
84      private int maxConnPerRoute;
85  
86      private Resolver<HttpRoute, ConnectionConfig> connectionConfigResolver;
87      private Resolver<HttpHost, TlsConfig> tlsConfigResolver;
88  
89      public static PoolingAsyncClientConnectionManagerBuilder create() {
90          return new PoolingAsyncClientConnectionManagerBuilder();
91      }
92  
93      PoolingAsyncClientConnectionManagerBuilder() {
94          super();
95      }
96  
97      /**
98       * Assigns {@link TlsStrategy} instance for TLS connections.
99       */
100     public final PoolingAsyncClientConnectionManagerBuilder setTlsStrategy(
101             final TlsStrategy tlsStrategy) {
102         this.tlsStrategy = tlsStrategy;
103         return this;
104     }
105 
106     /**
107      * Assigns {@link DnsResolver} instance.
108      */
109     public final PoolingAsyncClientConnectionManagerBuilder setDnsResolver(final DnsResolver dnsResolver) {
110         this.dnsResolver = dnsResolver;
111         return this;
112     }
113 
114     /**
115      * Assigns {@link SchemePortResolver} instance.
116      */
117     public final PoolingAsyncClientConnectionManagerBuilder setSchemePortResolver(final SchemePortResolver schemePortResolver) {
118         this.schemePortResolver = schemePortResolver;
119         return this;
120     }
121 
122     /**
123      * Assigns {@link PoolConcurrencyPolicy} value.
124      */
125     public final PoolingAsyncClientConnectionManagerBuilder setPoolConcurrencyPolicy(final PoolConcurrencyPolicy poolConcurrencyPolicy) {
126         this.poolConcurrencyPolicy = poolConcurrencyPolicy;
127         return this;
128     }
129 
130     /**
131      * Assigns {@link PoolReusePolicy} value.
132      */
133     public final PoolingAsyncClientConnectionManagerBuilder setConnPoolPolicy(final PoolReusePolicy poolReusePolicy) {
134         this.poolReusePolicy = poolReusePolicy;
135         return this;
136     }
137 
138     /**
139      * Assigns maximum total connection value.
140      */
141     public final PoolingAsyncClientConnectionManagerBuilder setMaxConnTotal(final int maxConnTotal) {
142         this.maxConnTotal = maxConnTotal;
143         return this;
144     }
145 
146     /**
147      * Assigns maximum connection per route value.
148      */
149     public final PoolingAsyncClientConnectionManagerBuilder setMaxConnPerRoute(final int maxConnPerRoute) {
150         this.maxConnPerRoute = maxConnPerRoute;
151         return this;
152     }
153 
154     /**
155      * Assigns the same {@link ConnectionConfig} for all routes.
156      *
157      * @since 5.2
158      */
159     public final PoolingAsyncClientConnectionManagerBuilder setDefaultConnectionConfig(final ConnectionConfig config) {
160         this.connectionConfigResolver = (route) -> config;
161         return this;
162     }
163 
164     /**
165      * Assigns {@link Resolver} of {@link ConnectionConfig} on a per route basis.
166      *
167      * @since 5.2
168      */
169     public final PoolingAsyncClientConnectionManagerBuilder setConnectionConfigResolver(
170             final Resolver<HttpRoute, ConnectionConfig> connectionConfigResolver) {
171         this.connectionConfigResolver = connectionConfigResolver;
172         return this;
173     }
174 
175     /**
176      * Assigns the same {@link TlsConfig} for all hosts.
177      *
178      * @since 5.2
179      */
180     public final PoolingAsyncClientConnectionManagerBuilder setDefaultTlsConfig(final TlsConfig config) {
181         this.tlsConfigResolver = (host) -> config;
182         return this;
183     }
184 
185     /**
186      * Assigns {@link Resolver} of {@link TlsConfig} on a per host basis.
187      *
188      * @since 5.2
189      */
190     public final PoolingAsyncClientConnectionManagerBuilder setTlsConfigResolver(
191             final Resolver<HttpHost, TlsConfig> tlsConfigResolver) {
192         this.tlsConfigResolver = tlsConfigResolver;
193         return this;
194     }
195 
196     /**
197      * Sets maximum time to live for persistent connections
198      *
199      * @deprecated Use {@link #setDefaultConnectionConfig(ConnectionConfig)}
200      */
201     @Deprecated
202     public final PoolingAsyncClientConnectionManagerBuilder setConnectionTimeToLive(final TimeValue timeToLive) {
203         setDefaultConnectionConfig(ConnectionConfig.custom()
204                 .setTimeToLive(timeToLive)
205                 .build());
206         return this;
207     }
208 
209     /**
210      * Sets period after inactivity after which persistent
211      * connections must be checked to ensure they are still valid.
212      *
213      * @deprecated Use {@link #setConnectionConfigResolver(Resolver)}.
214      */
215     @Deprecated
216     public final PoolingAsyncClientConnectionManagerBuilder setValidateAfterInactivity(final TimeValue validateAfterInactivity) {
217         setDefaultConnectionConfig(ConnectionConfig.custom()
218                 .setValidateAfterInactivity(validateAfterInactivity)
219                 .build());
220         return this;
221     }
222 
223     /**
224      * Use system properties when creating and configuring default
225      * implementations.
226      */
227     public final PoolingAsyncClientConnectionManagerBuilder useSystemProperties() {
228         this.systemProperties = true;
229         return this;
230     }
231 
232     public PoolingAsyncClientConnectionManager build() {
233         final TlsStrategy tlsStrategyCopy;
234         if (tlsStrategy != null) {
235             tlsStrategyCopy = tlsStrategy;
236         } else {
237             if (ReflectionUtils.determineJRELevel() <= 8 && ConscryptClientTlsStrategy.isSupported()) {
238                 if (systemProperties) {
239                     tlsStrategyCopy = ConscryptClientTlsStrategy.getSystemDefault();
240                 } else {
241                     tlsStrategyCopy = ConscryptClientTlsStrategy.getDefault();
242                 }
243             } else {
244                 if (systemProperties) {
245                     tlsStrategyCopy = DefaultClientTlsStrategy.getSystemDefault();
246                 } else {
247                     tlsStrategyCopy = DefaultClientTlsStrategy.getDefault();
248                 }
249             }
250         }
251         final PoolingAsyncClientConnectionManager poolingmgr = new PoolingAsyncClientConnectionManager(
252                 RegistryBuilder.<TlsStrategy>create()
253                         .register(URIScheme.HTTPS.getId(), tlsStrategyCopy)
254                         .build(),
255                 poolConcurrencyPolicy,
256                 poolReusePolicy,
257                 null,
258                 schemePortResolver,
259                 dnsResolver);
260         poolingmgr.setConnectionConfigResolver(connectionConfigResolver);
261         poolingmgr.setTlsConfigResolver(tlsConfigResolver);
262         if (maxConnTotal > 0) {
263             poolingmgr.setMaxTotal(maxConnTotal);
264         }
265         if (maxConnPerRoute > 0) {
266             poolingmgr.setDefaultMaxPerRoute(maxConnPerRoute);
267         }
268         return poolingmgr;
269     }
270 
271 }