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 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.io.ManagedHttpClientConnection;
36  import org.apache.hc.client5.http.socket.ConnectionSocketFactory;
37  import org.apache.hc.client5.http.socket.LayeredConnectionSocketFactory;
38  import org.apache.hc.client5.http.socket.PlainConnectionSocketFactory;
39  import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory;
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 LayeredConnectionSocketFactory sslSocketFactory;
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 LayeredConnectionSocketFactory} instance.
112      */
113     public final PoolingHttpClientConnectionManagerBuilder setSSLSocketFactory(
114             final LayeredConnectionSocketFactory sslSocketFactory) {
115         this.sslSocketFactory = sslSocketFactory;
116         return this;
117     }
118 
119     /**
120      * Assigns {@link DnsResolver} instance.
121      */
122     public final PoolingHttpClientConnectionManagerBuilder setDnsResolver(final DnsResolver dnsResolver) {
123         this.dnsResolver = dnsResolver;
124         return this;
125     }
126 
127     /**
128      * Assigns {@link SchemePortResolver} instance.
129      */
130     public final PoolingHttpClientConnectionManagerBuilder setSchemePortResolver(final SchemePortResolver schemePortResolver) {
131         this.schemePortResolver = schemePortResolver;
132         return this;
133     }
134 
135     /**
136      * Assigns {@link PoolConcurrencyPolicy} value.
137      */
138     public final PoolingHttpClientConnectionManagerBuilder setPoolConcurrencyPolicy(final PoolConcurrencyPolicy poolConcurrencyPolicy) {
139         this.poolConcurrencyPolicy = poolConcurrencyPolicy;
140         return this;
141     }
142 
143     /**
144      * Assigns {@link PoolReusePolicy} value.
145      */
146     public final PoolingHttpClientConnectionManagerBuilder setConnPoolPolicy(final PoolReusePolicy poolReusePolicy) {
147         this.poolReusePolicy = poolReusePolicy;
148         return this;
149     }
150 
151     /**
152      * Assigns maximum total connection value.
153      */
154     public final PoolingHttpClientConnectionManagerBuilder setMaxConnTotal(final int maxConnTotal) {
155         this.maxConnTotal = maxConnTotal;
156         return this;
157     }
158 
159     /**
160      * Assigns maximum connection per route value.
161      */
162     public final PoolingHttpClientConnectionManagerBuilder setMaxConnPerRoute(final int maxConnPerRoute) {
163         this.maxConnPerRoute = maxConnPerRoute;
164         return this;
165     }
166 
167     /**
168      * Assigns the same {@link SocketConfig} for all routes.
169      */
170     public final PoolingHttpClientConnectionManagerBuilder setDefaultSocketConfig(final SocketConfig config) {
171         this.socketConfigResolver = (route) -> config;
172         return this;
173     }
174 
175     /**
176      * Assigns {@link Resolver} of {@link SocketConfig} on a per route basis.
177      *
178      * @since 5.2
179      */
180     public final PoolingHttpClientConnectionManagerBuilder setSocketConfigResolver(
181             final Resolver<HttpRoute, SocketConfig> socketConfigResolver) {
182         this.socketConfigResolver = socketConfigResolver;
183         return this;
184     }
185 
186     /**
187      * Assigns the same {@link ConnectionConfig} for all routes.
188      *
189      * @since 5.2
190      */
191     public final PoolingHttpClientConnectionManagerBuilder setDefaultConnectionConfig(final ConnectionConfig config) {
192         this.connectionConfigResolver = (route) -> config;
193         return this;
194     }
195 
196     /**
197      * Assigns {@link Resolver} of {@link ConnectionConfig} on a per route basis.
198      *
199      * @since 5.2
200      */
201     public final PoolingHttpClientConnectionManagerBuilder setConnectionConfigResolver(
202             final Resolver<HttpRoute, ConnectionConfig> connectionConfigResolver) {
203         this.connectionConfigResolver = connectionConfigResolver;
204         return this;
205     }
206 
207     /**
208      * Assigns the same {@link TlsConfig} for all hosts.
209      *
210      * @since 5.2
211      */
212     public final PoolingHttpClientConnectionManagerBuilder setDefaultTlsConfig(final TlsConfig config) {
213         this.tlsConfigResolver = (host) -> config;
214         return this;
215     }
216 
217     /**
218      * Assigns {@link Resolver} of {@link TlsConfig} on a per host basis.
219      *
220      * @since 5.2
221      */
222     public final PoolingHttpClientConnectionManagerBuilder setTlsConfigResolver(
223             final Resolver<HttpHost, TlsConfig> tlsConfigResolver) {
224         this.tlsConfigResolver = tlsConfigResolver;
225         return this;
226     }
227 
228     /**
229      * Sets maximum time to live for persistent connections
230      *
231      * @deprecated Use {@link #setDefaultConnectionConfig(ConnectionConfig)}.
232      */
233     @Deprecated
234     public final PoolingHttpClientConnectionManagerBuilder setConnectionTimeToLive(final TimeValue timeToLive) {
235         setDefaultConnectionConfig(ConnectionConfig.custom()
236                 .setTimeToLive(timeToLive)
237                 .build());
238         return this;
239     }
240 
241     /**
242      * Sets period after inactivity after which persistent
243      * connections must be checked to ensure they are still valid.
244      *
245      * @deprecated Use {@link #setDefaultConnectionConfig(ConnectionConfig)}.
246      */
247     @Deprecated
248     public final PoolingHttpClientConnectionManagerBuilder setValidateAfterInactivity(final TimeValue validateAfterInactivity) {
249         setDefaultConnectionConfig(ConnectionConfig.custom()
250                 .setValidateAfterInactivity(validateAfterInactivity)
251                 .build());
252         return this;
253     }
254 
255     /**
256      * Use system properties when creating and configuring default
257      * implementations.
258      */
259     public final PoolingHttpClientConnectionManagerBuilder useSystemProperties() {
260         this.systemProperties = true;
261         return this;
262     }
263 
264     public PoolingHttpClientConnectionManager build() {
265         @SuppressWarnings("resource") final PoolingHttpClientConnectionManager poolingmgr = new PoolingHttpClientConnectionManager(
266                 RegistryBuilder.<ConnectionSocketFactory>create()
267                         .register(URIScheme.HTTP.id, PlainConnectionSocketFactory.getSocketFactory())
268                         .register(URIScheme.HTTPS.id, sslSocketFactory != null ? sslSocketFactory :
269                                 (systemProperties ?
270                                         SSLConnectionSocketFactory.getSystemSocketFactory() :
271                                         SSLConnectionSocketFactory.getSocketFactory()))
272                         .build(),
273                 poolConcurrencyPolicy,
274                 poolReusePolicy,
275                 null,
276                 schemePortResolver,
277                 dnsResolver,
278                 connectionFactory);
279         poolingmgr.setSocketConfigResolver(socketConfigResolver);
280         poolingmgr.setConnectionConfigResolver(connectionConfigResolver);
281         poolingmgr.setTlsConfigResolver(tlsConfigResolver);
282         if (maxConnTotal > 0) {
283             poolingmgr.setMaxTotal(maxConnTotal);
284         }
285         if (maxConnPerRoute > 0) {
286             poolingmgr.setDefaultMaxPerRoute(maxConnPerRoute);
287         }
288         return poolingmgr;
289     }
290 
291 }