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