1 /*
2 * Copyright 2010-2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License").
5 * You may not use this file except in compliance with the License.
6 * A copy of the License is located at
7 *
8 * http://aws.amazon.com/apache2.0
9 *
10 * or in the "license" file accompanying this file. This file is distributed
11 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 * express or implied. See the License for the specific language governing
13 * permissions and limitations under the License.
14 */
15 package com.amazonaws;
16
17 import com.amazonaws.annotation.NotThreadSafe;
18 import com.amazonaws.http.IdleConnectionReaper;
19 import com.amazonaws.http.SystemPropertyTlsKeyManagersProvider;
20 import com.amazonaws.http.TlsKeyManagersProvider;
21 import com.amazonaws.retry.PredefinedRetryPolicies;
22 import com.amazonaws.retry.RetryMode;
23 import com.amazonaws.retry.RetryPolicy;
24 import com.amazonaws.util.StringUtils;
25 import com.amazonaws.util.ValidationUtils;
26 import com.amazonaws.util.VersionInfoUtils;
27 import java.net.InetAddress;
28 import java.net.MalformedURLException;
29 import java.net.URL;
30 import java.security.SecureRandom;
31 import java.util.ArrayList;
32 import java.util.Collections;
33 import java.util.HashMap;
34 import java.util.List;
35 import java.util.Map;
36 import java.util.concurrent.atomic.AtomicReference;
37 import org.apache.commons.logging.Log;
38 import org.apache.commons.logging.LogFactory;
39
40 /**
41 * Client configuration options such as proxy settings, user agent string, max retry attempts, etc.
42 *
43 * @see PredefinedClientConfigurations
44 */
45 @NotThreadSafe
46 public class ClientConfiguration {
47 private static final Log log = LogFactory.getLog(ClientConfiguration.class);
48
49 /** The default timeout for creating new connections. */
50 public static final int DEFAULT_CONNECTION_TIMEOUT = 10 * 1000;
51
52 /** The default timeout for reading from a connected socket. */
53 public static final int DEFAULT_SOCKET_TIMEOUT = 50 * 1000;
54
55 /**
56 * The default timeout for a request. This is disabled by default.
57 */
58 public static final int DEFAULT_REQUEST_TIMEOUT = 0;
59
60 /**
61 * The default timeout for a request. This is disabled by default.
62 */
63 public static final int DEFAULT_CLIENT_EXECUTION_TIMEOUT = 0;
64
65 /**
66 * The default on whether to disable {@code Socket} proxies.
67 */
68 public static final boolean DEFAULT_DISABLE_SOCKET_PROXY = false;
69
70 /** The default max connection pool size. */
71 public static final int DEFAULT_MAX_CONNECTIONS = 50;
72
73 /**
74 * The default on whether to utilize the USE_EXPECT_CONTINUE handshake for operations. Currently
75 * only honored for PUT operations.
76 */
77 public static final boolean DEFAULT_USE_EXPECT_CONTINUE = true;
78
79 /** The default HTTP user agent header for AWS Java SDK clients. */
80 public static final String DEFAULT_USER_AGENT = VersionInfoUtils.getUserAgent();
81
82 /**
83 * Default request retry policy, including the maximum retry count of 3, the default retry
84 * condition and the default back-off strategy.
85 *
86 * @see PredefinedRetryPolicies#DEFAULT
87 * @see PredefinedRetryPolicies#DYNAMODB_DEFAULT
88 */
89 public static final RetryPolicy DEFAULT_RETRY_POLICY = PredefinedRetryPolicies.DEFAULT;
90
91 /**
92 * The default on whether to use the {@link IdleConnectionReaper} to manage stale connections
93 *
94 * @see IdleConnectionReaper
95 */
96 public static final boolean DEFAULT_USE_REAPER = true;
97
98 /**
99 * The default on whether to use gzip decompression.
100 */
101 public static final boolean DEFAULT_USE_GZIP = false;
102
103 /**
104 * The default expiration time (in milliseconds) for a connection in the connection pool.
105 */
106 public static final long DEFAULT_CONNECTION_TTL = -1;
107
108 /**
109 * The default maximum idle time (in milliseconds) for a connection in the connection pool.
110 */
111 public static final long DEFAULT_CONNECTION_MAX_IDLE_MILLIS = 60 * 1000;
112
113 /**
114 * The default time a connection can be idle in the connection pool before it must be validated that it's still open.
115 */
116 public static final int DEFAULT_VALIDATE_AFTER_INACTIVITY_MILLIS = 5 * 1000;
117
118 /**
119 * The default on whether to use TCP KeepAlive.
120 */
121 public static final boolean DEFAULT_TCP_KEEP_ALIVE = false;
122
123 /**
124 * The default on whether to throttle retries.
125 */
126 public static final boolean DEFAULT_THROTTLE_RETRIES = true;
127
128 /**
129 * The default on whether to cache response metadata.
130 */
131 public static final boolean DEFAULT_CACHE_RESPONSE_METADATA = true;
132
133 /**
134 * The default response metadata cache size.
135 */
136 public static final int DEFAULT_RESPONSE_METADATA_CACHE_SIZE = 50;
137
138 public static final int DEFAULT_MAX_CONSECUTIVE_RETRIES_BEFORE_THROTTLING = 100;
139
140
141 /** A prefix to the HTTP user agent header passed with all HTTP requests. */
142 private String userAgentPrefix = DEFAULT_USER_AGENT;
143
144 /** A suffix to the HTTP user agent header. */
145 private String userAgentSuffix;
146
147 /**
148 * The maximum number of times that a retryable failed request (ex: a 5xx response from a
149 * service) will be retried. Or -1 if the user has not explicitly set this value, in which case
150 * the configured RetryPolicy will be used to control the retry count.
151 */
152 private int maxErrorRetry = -1;
153
154 /** The retry policy upon failed requests. **/
155 private RetryPolicy retryPolicy = DEFAULT_RETRY_POLICY;
156
157 /** Optionally specifies the local address to bind to */
158 private InetAddress localAddress;
159
160 /**
161 * The protocol to use when connecting to Amazon Web Services.
162 * <p>
163 * The default configuration is to use HTTPS for all requests for increased security.
164 */
165 private Protocol protocol = Protocol.HTTPS;
166
167 /**
168 * The protocol to use when connecting to an HTTP proxy.
169 * <p>
170 * The default configuration is to use {@link Protocol#HTTP}.
171 */
172 private Protocol proxyProtocol = Protocol.HTTP;
173
174 /** Optionally specifies the proxy host to connect through. */
175 private String proxyHost = null;
176
177 /** Optionally specifies the port on the proxy host to connect through. */
178 private int proxyPort = -1;
179
180 /** Optionally specifies the user name to use when connecting through a proxy. */
181 private String proxyUsername = null;
182
183 /** Optionally specifies the password to use when connecting through a proxy. */
184 private String proxyPassword = null;
185
186 /** Optional Windows domain name for configuring NTLM proxy support. */
187 private String proxyDomain = null;
188
189 /** Optional Windows workstation name for configuring NTLM proxy support. */
190 private String proxyWorkstation = null;
191
192 /** Optional specifies the hosts that should be accessed without going through the proxy. */
193 private String nonProxyHosts = null;
194
195 /** Specifies the proxy authentication methods that should be used, in priority order. */
196 private List<ProxyAuthenticationMethod> proxyAuthenticationMethods = null;
197
198 /**
199 * Controls whether {@link java.net.Socket}s created by the client should
200 * use the default {@link java.net.ProxySelector} when connecting to the
201 * remote host to find an appropriate proxy or connect directly to the
202 * host.
203 * <p />
204 * Note this property is only guaranteed to be honored when using the
205 * default connection factories.
206 */
207 private boolean disableSocketProxy = DEFAULT_DISABLE_SOCKET_PROXY;
208
209 /**
210 * Whether to pre-emptively authenticate against a proxy server using basic authentication
211 */
212 private boolean preemptiveBasicProxyAuth;
213
214 /** The maximum number of open HTTP connections. */
215 private int maxConnections = DEFAULT_MAX_CONNECTIONS;
216
217 /**
218 * The amount of time to wait (in milliseconds) for data to be transferred over an established,
219 * open connection before the connection is timed out. A value of 0 means infinity, and is not
220 * recommended.
221 */
222 private int socketTimeout = DEFAULT_SOCKET_TIMEOUT;
223
224 /**
225 * The amount of time to wait (in milliseconds) when initially establishing a connection before
226 * giving up and timing out. A value of 0 means infinity, and is not recommended.
227 */
228 private int connectionTimeout = DEFAULT_CONNECTION_TIMEOUT;
229
230 /**
231 * The amount of time to wait (in milliseconds) for a request to complete before giving up and
232 * timing out. A value of 0 means infinity. Consider setting this if a harder guarantee is
233 * required on the maximum amount of time a request will take for non-streaming operations, and
234 * are willing to spin up a background thread to enforce it.
235 */
236 private int requestTimeout = DEFAULT_REQUEST_TIMEOUT;
237
238 private int clientExecutionTimeout = DEFAULT_CLIENT_EXECUTION_TIMEOUT;
239
240 private boolean throttleRetries = DEFAULT_THROTTLE_RETRIES;
241
242 /**
243 * Optional size hint (in bytes) for the low level TCP send buffer. This is an advanced option
244 * for advanced users who want to tune low level TCP parameters to try and squeeze out more
245 * performance.
246 */
247 private int socketSendBufferSizeHint = 0;
248
249 /**
250 * Optional size hint (in bytes) for the low level TCP receive buffer. This is an advanced
251 * option for advanced users who want to tune low level TCP parameters to try and squeeze out
252 * more performance.
253 */
254 private int socketReceiveBufferSizeHint = 0;
255
256 /**
257 * Optional whether to use the {@link IdleConnectionReaper} to manage stale connections. A
258 * reason for not running the {@link IdleConnectionReaper} can be if running in an environment
259 * where the modifyThread and modifyThreadGroup permissions are not allowed.
260 */
261 private boolean useReaper = DEFAULT_USE_REAPER;
262
263 /**
264 * Optional whether to use gzip decompression when receiving HTTP responses.
265 */
266 private boolean useGzip = DEFAULT_USE_GZIP;
267
268 /**
269 * Optional override to control which signature algorithm should be used to sign requests to the
270 * service. If not explicitly set, the client will determine the algorithm to use by inspecting
271 * a configuration file baked in to the SDK.
272 */
273 private String signerOverride;
274
275 /**
276 * Optional expiration time for a connection in the connection pool. When a connection is
277 * retrieved from the connection pool, this parameter is checked to see if the connection can be
278 * reused.
279 */
280 private long connectionTTL = DEFAULT_CONNECTION_TTL;
281
282 /**
283 * The maximum idle time for a connection in the connection pool.
284 */
285 private long connectionMaxIdleMillis = DEFAULT_CONNECTION_MAX_IDLE_MILLIS;
286
287 private int validateAfterInactivityMillis = DEFAULT_VALIDATE_AFTER_INACTIVITY_MILLIS;
288
289 /**
290 * Optional override to enable support for TCP KeepAlive (not to be confused with HTTP
291 * KeepAlive). TCP KeepAlive can be used to detect misbehaving routers or down servers through
292 * the use of special, empty-data keep alive packets.
293 * <p>
294 * Actual TCP KeepAlive values (timeout, number of packets, etc) are configured via the
295 * operating system (sysctl on Linux, and Registry values on Windows).
296 */
297 private boolean tcpKeepAlive = DEFAULT_TCP_KEEP_ALIVE;
298
299 /**
300 * Whether or not to cache response metadata.
301 * <p>
302 * Response metadata is typically used for troubleshooting issues with AWS support staff when
303 * services aren't acting as expected.
304 * </p>
305 * <p>
306 * While this feature is useful for debugging it adds overhead and disabling it may
307 * be desired in high throughput applications.
308 * </p>
309 */
310 private boolean cacheResponseMetadata = DEFAULT_CACHE_RESPONSE_METADATA;
311
312 /**
313 * Size of the response metadata cache, if it is enabled.
314 * <p>
315 * Response metadata is typically used for troubleshooting issues with AWS support staff when
316 * services aren't acting as expected.
317 */
318 private int responseMetadataCacheSize = DEFAULT_RESPONSE_METADATA_CACHE_SIZE;
319
320 /**
321 * The DNS Resolver to resolve IP addresses of Amazon Web Services.
322 */
323 private DnsResolver dnsResolver = new SystemDefaultDnsResolver();
324
325 /**
326 * An instance of {@link SecureRandom} configured by the user; or the JDK default will be used
327 * if it is set to null or not explicitly configured.
328 */
329 private SecureRandom secureRandom;
330
331 /**
332 * Headers to be added to all requests
333 */
334 private Map<String, String> headers = new HashMap<String, String>();
335
336 /**
337 * Optional override to enable/disable support for HTTP/1.1 handshake utilizing EXPECT:
338 * 100-Continue. The default value is true.
339 * <p>
340 * The detail of HTTP Expect Continue is defined at
341 * <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.2.3"> Use of the 100
342 * (Continue) Status</a>. Setting this as false will reduce latency when you want to send small
343 * size of payload. It is highly recommended to use the default value if you want to transfer a
344 * large amount of data to the server, such as uploading a big file to S3 bucket.
345 */
346 private boolean useExpectContinue = DEFAULT_USE_EXPECT_CONTINUE;
347
348 /**
349 * The maximum number of throttled retries if the initial request
350 * fails.
351 */
352 private int maxConsecutiveRetriesBeforeThrottling = DEFAULT_MAX_CONSECUTIVE_RETRIES_BEFORE_THROTTLING;
353
354 /**
355 * Can be used to specify custom specific Apache HTTP client configurations.
356 */
357 private final ApacheHttpClientConfig apacheHttpClientConfig;
358
359 /**
360 * Configuration option to disable the host prefix injection.
361 *
362 * The hostPrefix template is specified in the service model and is used by the SDK to modify the endpoint
363 * the request is sent to. Host prefix injection is enabled by default. This option can be set to disable the behavior.
364 */
365 private boolean disableHostPrefixInjection;
366
367 private final AtomicReference<URLHolder> httpProxyHolder = new AtomicReference<URLHolder>();
368
369 private final AtomicReference<URLHolder> httpsProxyHolder = new AtomicReference<URLHolder>();
370
371 private TlsKeyManagersProvider tlsKeyManagersProvider;
372 private RetryMode retryMode;
373
374 public ClientConfiguration() {
375 apacheHttpClientConfig = new ApacheHttpClientConfig();
376 }
377
378 public ClientConfiguration(ClientConfiguration other) {
379 this.connectionTimeout = other.getConnectionTimeout();
380 this.maxConnections = other.getMaxConnections();
381 this.maxErrorRetry = other.getMaxErrorRetry();
382 this.retryPolicy = other.getRetryPolicy();
383 this.throttleRetries = other.useThrottledRetries();
384 this.localAddress = other.getLocalAddress();
385 this.protocol = other.getProtocol();
386 this.proxyProtocol = other.getProxyProtocol();
387 this.proxyDomain = other.getProxyDomain();
388 this.proxyHost = other.getProxyHost();
389 this.proxyPassword = other.getProxyPassword();
390 this.proxyPort = other.getProxyPort();
391 this.proxyUsername = other.getProxyUsername();
392 this.proxyWorkstation = other.getProxyWorkstation();
393 this.nonProxyHosts = other.getNonProxyHosts();
394 this.disableSocketProxy = other.disableSocketProxy();
395 this.proxyAuthenticationMethods = other.getProxyAuthenticationMethods();
396 this.preemptiveBasicProxyAuth = other.isPreemptiveBasicProxyAuth();
397 this.socketTimeout = other.getSocketTimeout();
398 this.requestTimeout = other.getRequestTimeout();
399 this.clientExecutionTimeout = other.getClientExecutionTimeout();
400 this.userAgentPrefix = other.getUserAgentPrefix();
401 this.userAgentSuffix = other.getUserAgentSuffix();
402 this.useReaper = other.useReaper();
403 this.useGzip = other.useGzip();
404 this.socketSendBufferSizeHint = other.getSocketBufferSizeHints()[0];
405 this.socketReceiveBufferSizeHint = other.getSocketBufferSizeHints()[1];
406 this.signerOverride = other.getSignerOverride();
407 this.responseMetadataCacheSize = other.getResponseMetadataCacheSize();
408 this.dnsResolver = other.getDnsResolver();
409 this.useExpectContinue = other.isUseExpectContinue();
410 this.apacheHttpClientConfig = new ApacheHttpClientConfig(other.getApacheHttpClientConfig());
411 this.cacheResponseMetadata = other.getCacheResponseMetadata();
412 this.connectionTTL = other.getConnectionTTL();
413 this.connectionMaxIdleMillis = other.getConnectionMaxIdleMillis();
414 this.validateAfterInactivityMillis = other.getValidateAfterInactivityMillis();
415 this.tcpKeepAlive = other.useTcpKeepAlive();
416 this.secureRandom = other.getSecureRandom();
417 this.headers.clear();
418 this.headers.putAll(other.getHeaders());
419 this.maxConsecutiveRetriesBeforeThrottling = other.getMaxConsecutiveRetriesBeforeThrottling();
420 this.disableHostPrefixInjection = other.disableHostPrefixInjection;
421 this.httpProxyHolder.set(other.httpProxyHolder.get());
422 this.httpsProxyHolder.set(other.httpsProxyHolder.get());
423 this.tlsKeyManagersProvider = other.tlsKeyManagersProvider;
424 this.retryMode = other.retryMode;
425 }
426
427 /**
428 * Returns the protocol (HTTP or HTTPS) to use when connecting to Amazon Web Services.
429 * <p>
430 * The default configuration is to use HTTPS for all requests for increased security.
431 * <p>
432 * Individual clients can also override this setting by explicitly including the protocol as
433 * part of the endpoint URL when calling {@link AmazonWebServiceClient#setEndpoint(String)}.
434 *
435 * @return The protocol to use when connecting to Amazon Web Services.
436 */
437 public Protocol getProtocol() {
438 return protocol;
439 }
440
441 /**
442 * Sets the protocol (i.e. HTTP or HTTPS) to use when connecting to Amazon Web Services.
443 * <p>
444 * The default configuration is to use HTTPS for all requests for increased security.
445 * <p>
446 * Individual clients can also override this setting by explicitly including the protocol as
447 * part of the endpoint URL when calling {@link AmazonWebServiceClient#setEndpoint(String)}.
448 *
449 * @param protocol
450 * The protocol to use when connecting to Amazon Web Services.
451 */
452 public void setProtocol(Protocol protocol) {
453 this.protocol = protocol;
454 }
455
456 /**
457 * Sets the protocol (i.e. HTTP or HTTPS) to use when connecting to Amazon Web Services, and
458 * returns the updated ClientConfiguration object so that additional calls may be chained
459 * together.
460 * <p>
461 * The default configuration is to use HTTPS for all requests for increased security.
462 * <p>
463 * Individual clients can also override this setting by explicitly including the protocol as
464 * part of the endpoint URL when calling {@link AmazonWebServiceClient#setEndpoint(String)}.
465 *
466 * @param protocol
467 * The protocol to use when connecting to Amazon Web Services.
468 * @return The updated ClientConfiguration object with the new max HTTP connections setting.
469 */
470 public ClientConfiguration withProtocol(Protocol protocol) {
471 setProtocol(protocol);
472 return this;
473 }
474
475 /**
476 * Returns the maximum number of allowed open HTTP connections.
477 *
478 * @return The maximum number of allowed open HTTP connections.
479 */
480 public int getMaxConnections() {
481 return maxConnections;
482 }
483
484 /**
485 * Sets the maximum number of allowed open HTTP connections.
486 *
487 * @param maxConnections
488 * The maximum number of allowed open HTTP connections.
489 */
490 public void setMaxConnections(int maxConnections) {
491 this.maxConnections = maxConnections;
492 }
493
494 /**
495 * Sets the maximum number of allowed open HTTP connections and returns the updated
496 * ClientConfiguration object.
497 *
498 * @param maxConnections
499 * The maximum number of allowed open HTTP connections.
500 * @return The updated ClientConfiguration object with the new max HTTP connections setting.
501 */
502 public ClientConfiguration withMaxConnections(int maxConnections) {
503 setMaxConnections(maxConnections);
504 return this;
505 }
506
507 /**
508 * @deprecated Replaced by {@link #getUserAgentPrefix()} and {@link #getUserAgentSuffix()}
509 * @return The user agent string to use when sending requests.
510 */
511 @Deprecated
512 public String getUserAgent() {
513 return getUserAgentPrefix();
514 }
515
516 /**
517 * @deprecated Replaced by {@link #setUserAgentPrefix(String)} and {@link #setUserAgentSuffix(String)}
518 * @param userAgent
519 * The user agent string to use when sending requests.
520 */
521 @Deprecated
522 public void setUserAgent(String userAgent) {
523 setUserAgentPrefix(userAgent);
524 }
525
526 /**
527 * @deprecated Replaced by {@link #withUserAgentPrefix(String)} and {@link #withUserAgentSuffix(String)}
528 * @param userAgent
529 * The user agent string to use when sending requests.
530 * @return The updated ClientConfiguration object.
531 */
532 @Deprecated
533 public ClientConfiguration withUserAgent(String userAgent) {
534 return withUserAgentPrefix(userAgent);
535 }
536
537 /**
538 * Returns the HTTP user agent header prefix to send with all requests.
539 *
540 * @return The user agent string prefix to use when sending requests.
541 */
542 public String getUserAgentPrefix() {
543 return userAgentPrefix;
544 }
545
546 /**
547 * Sets the HTTP user agent prefix to send with all requests.
548 *
549 * @param prefix
550 * The string to prefix to user agent to use when sending requests.
551 */
552 public void setUserAgentPrefix(String prefix) {
553 this.userAgentPrefix = prefix;
554 }
555
556 /**
557 * Sets the HTTP user agent prefix header used in requests and returns the updated ClientConfiguration
558 * object.
559 *
560 * @param prefix
561 * The string to prefix to user agent to use when sending requests.
562 * @return The updated ClientConfiguration object.
563 */
564 public ClientConfiguration withUserAgentPrefix(String prefix) {
565 setUserAgentPrefix(prefix);
566 return this;
567 }
568
569 /**
570 * Returns the HTTP user agent header suffix to add to the end of the user agent header on all requests.
571 *
572 * @return The user agent string suffix to use when sending requests.
573 */
574 public String getUserAgentSuffix() {
575 return userAgentSuffix;
576 }
577
578 /**
579 * Sets the HTTP user agent suffix to send with all requests.
580 *
581 * @param suffix
582 * The string to suffix to user agent to use when sending requests.
583 */
584 public void setUserAgentSuffix(String suffix) {
585 this.userAgentSuffix = suffix;
586 }
587
588 /**
589 * Sets the HTTP user agent suffix header used in requests and returns the updated ClientConfiguration
590 * object.
591 *
592 * @param suffix
593 * The string to suffix to user agent to use when sending requests.
594 * @return The updated ClientConfiguration object.
595 */
596 public ClientConfiguration withUserAgentSuffix(String suffix) {
597 setUserAgentSuffix(suffix);
598 return this;
599 }
600
601 /**
602 * Returns the optional local address the client will bind to.
603 *
604 * @return The local address the client will bind to.
605 */
606 public InetAddress getLocalAddress() {
607 return localAddress;
608 }
609
610 /**
611 * Sets the optional local address the client will bind to.
612 *
613 * @param localAddress
614 * The local address the client will bind to.
615 */
616 public void setLocalAddress(InetAddress localAddress) {
617 this.localAddress = localAddress;
618 }
619
620 /**
621 * Sets the optional local address the client will bind to and returns the updated
622 * ClientConfiguration object.
623 *
624 * @param localAddress
625 * The local address the client will bind to.
626 * @return The updated ClientConfiguration object.
627 */
628 public ClientConfiguration withLocalAddress(InetAddress localAddress) {
629 setLocalAddress(localAddress);
630 return this;
631 }
632
633 /**
634 * Returns the value for the given system property.
635 */
636 private String getSystemProperty(String property) {
637 return System.getProperty(property);
638 }
639
640 /**
641 * Returns the value for the given environment variable.
642 */
643 private String getEnvironmentVariable(String environmentVariable) {
644 String value = StringUtils.trim(System.getenv(environmentVariable));
645 return StringUtils.hasValue(value) ? value : null;
646 }
647
648 /**
649 * Returns the value for the given environment variable if its set, otherwise returns
650 * the lowercase version of variable.
651 */
652 private String getEnvironmentVariableCaseInsensitive(String environmentVariable) {
653 String result = getEnvironmentVariable(environmentVariable);
654 return result != null ? result : getEnvironmentVariable(environmentVariable.toLowerCase());
655 }
656
657 /**
658 * @return The {@link Protocol} to use for connecting to the proxy.
659 */
660 public Protocol getProxyProtocol() {
661 return proxyProtocol;
662 }
663
664 /**
665 * Set the {@link Protocol} to use for connecting to the proxy.
666 *
667 * @param proxyProtocol The protocol.
668 * @return The updated ClientConfiguration object.
669 */
670 public ClientConfiguration withProxyProtocol(Protocol proxyProtocol) {
671 this.proxyProtocol = proxyProtocol == null ? Protocol.HTTP : proxyProtocol;
672 return this;
673 }
674
675 /**
676 * Set the {@link Protocol} to use for connecting to the proxy.
677 *
678 * @param proxyProtocol The protocol.
679 */
680 public void setProxyProtocol(Protocol proxyProtocol) {
681 withProxyProtocol(proxyProtocol);
682 }
683
684 /**
685 * Returns the Java system property for proxy host depending on
686 * {@link #getProtocol()}: i.e. if protocol is https, returns
687 * the value of the system property https.proxyHost, otherwise
688 * returns value of http.proxyHost.
689 */
690 private String getProxyHostProperty() {
691 return getProtocol() == Protocol.HTTPS
692 ? getSystemProperty("https.proxyHost")
693 : getSystemProperty("http.proxyHost");
694 }
695
696 /**
697 * Returns the environment variable for proxy host depending on
698 * {@link #getProtocol()}: i.e. if protocol is https, returns
699 * the host in the value of the environment variable HTTPS_PROXY/https_proxy,
700 * otherwise, returns the host in the value of the environment
701 * variable HTTP_PROXY/http_proxy.
702 */
703 private String getProxyHostEnvironment() {
704 URL httpProxy = getHttpProxyEnvironmentVariable();
705 if (httpProxy != null) {
706 return httpProxy.getHost();
707 }
708 return null;
709 }
710
711 /**
712 * Returns the optional proxy host the client will connect
713 * through. Returns either the proxyHost set on this object, or
714 * if not provided, checks the value of the Java system property
715 * for proxy host according to {@link #getProtocol()}: i.e. if
716 * protocol is https, returns the value of the system property
717 * https.proxyHost, otherwise returns value of http.proxyHost.
718 * If neither are set, checks the value of the environment variable
719 * according to {@link #getProtocol()}: i.e. if protocol is https,
720 * returns the host in the value of the HTTPS_PROXY/https_proxy
721 * environment variable, otherwise returns the host in the value
722 * of the HTTP_PROXY/http_proxy environment variable.
723 *
724 * @return The proxy host the client will connect through.
725 */
726 public String getProxyHost() {
727 if (proxyHost != null) {
728 return proxyHost;
729 } else if (getProxyHostProperty() != null) {
730 return getProxyHostProperty();
731 } else {
732 return getProxyHostEnvironment();
733 }
734 }
735
736 /**
737 * Sets the optional proxy host the client will connect through.
738 *
739 * @param proxyHost
740 * The proxy host the client will connect through.
741 */
742 public void setProxyHost(String proxyHost) {
743 this.proxyHost = proxyHost;
744 }
745
746 /**
747 * Sets the optional proxy host the client will connect through and returns the updated
748 * ClientConfiguration object.
749 *
750 * @param proxyHost
751 * The proxy host the client will connect through.
752 * @return The updated ClientConfiguration object.
753 */
754 public ClientConfiguration withProxyHost(String proxyHost) {
755 setProxyHost(proxyHost);
756 return this;
757 }
758
759 /**
760 * Returns the Java system property for proxy port depending on
761 * {@link #getProtocol()}: i.e. if protocol is https, returns
762 * the value of the system property https.proxyPort, otherwise
763 * returns value of http.proxyPort. Defaults to {@link this.proxyPort}
764 * if the system property is not set with a valid port number.
765 */
766 private int getProxyPortProperty() {
767 try {
768 return getProtocol() == Protocol.HTTPS
769 ? Integer.parseInt(getSystemProperty("https.proxyPort"))
770 : Integer.parseInt(getSystemProperty("http.proxyPort"));
771 } catch (NumberFormatException e) {
772 return proxyPort;
773 }
774 }
775
776 /**
777 * Returns the environment variable for proxy port depending on
778 * {@link #getProtocol()}: i.e. if protocol is https, returns
779 * the port in the value of the environment variable HTTPS_PROXY/https_proxy,
780 * otherwise, returns the port in the value of the environment
781 * variable HTTP_PROXY/http_proxy.
782 */
783 private int getProxyPortEnvironment() {
784 URL httpProxy = getHttpProxyEnvironmentVariable();
785 if (httpProxy != null) {
786 return httpProxy.getPort();
787 }
788 return proxyPort;
789 }
790
791 /**
792 * Returns the optional proxy port the client will connect
793 * through. Returns either the proxyPort set on this object, or
794 * if not provided, checks the value of the Java system property
795 * for proxy port according to {@link #getProtocol()}: i.e. if
796 * protocol is https, returns the value of the system property
797 * https.proxyPort, otherwise returns value of http.proxyPort.
798 * If neither are set, checks the value of the environment variable
799 * according to {@link #getProtocol()}: i.e. if protocol is https,
800 * returns the port in the value of the HTTPS_PROXY/https_proxy
801 * environment variable, otherwise returns the port in the value
802 * of the HTTP_PROXY/http_proxy environment variable.
803 *
804 * @return The proxy port the client will connect through.
805 */
806 public int getProxyPort() {
807 if (proxyPort >= 0) {
808 return proxyPort;
809 } else if (getProxyPortProperty() >= 0) {
810 return getProxyPortProperty();
811 } else {
812 return getProxyPortEnvironment();
813 }
814 }
815
816 /**
817 * Sets the optional proxy port the client will connect through.
818 *
819 * @param proxyPort
820 * The proxy port the client will connect through.
821 */
822 public void setProxyPort(int proxyPort) {
823 this.proxyPort = proxyPort;
824 }
825
826 /**
827 * Sets the optional proxy port the client will connect through and returns the updated
828 * ClientConfiguration object.
829 *
830 * @param proxyPort
831 * The proxy port the client will connect through.
832 * @return The updated ClientConfiguration object.
833 */
834 public ClientConfiguration withProxyPort(int proxyPort) {
835 setProxyPort(proxyPort);
836 return this;
837 }
838
839 /**
840 * Set whether to disable proxies at the socket level.
841 *
842 * @param disableSocketProxy Whether to disable proxies at the socket level.
843 *
844 * @return The updated ClientConfiguration object.
845 */
846 public ClientConfiguration withDisableSocketProxy(boolean disableSocketProxy) {
847 this.disableSocketProxy = disableSocketProxy;
848 return this;
849 }
850
851 /**
852 * Set whether to disable proxies at the socket level.
853 *
854 * @param disableSocketProxy Whether to disable proxies at the socket level.
855 */
856 public void setDisableSocketProxy(boolean disableSocketProxy) {
857 withDisableSocketProxy(disableSocketProxy);
858 }
859
860 /**
861 * @return Whether to disable proxies at the socket level.
862 */
863 public boolean disableSocketProxy() {
864 return disableSocketProxy;
865 }
866
867 /**
868 * Returns the Java system property for proxy user name depending on
869 * {@link #getProtocol()}: i.e. if protocol is https, returns
870 * the value of the system property https.proxyUser, otherwise
871 * returns value of http.proxyUser.
872 */
873 private String getProxyUsernameProperty() {
874 return (getProtocol() == Protocol.HTTPS)
875 ? getSystemProperty("https.proxyUser")
876 : getSystemProperty("http.proxyUser");
877 }
878
879 /**
880 * Returns the environment variable for proxy host depending on
881 * {@link #getProtocol()}: i.e. if protocol is https, returns
882 * the user name in the value of the environment variable
883 * HTTPS_PROXY/https_proxy, otherwise, returns the user name in
884 * the value of the environment variable HTTP_PROXY/http_proxy.
885 */
886 private String getProxyUsernameEnvironment() {
887 URL httpProxy = getHttpProxyEnvironmentVariable();
888 if (httpProxy != null) {
889 try {
890 return httpProxy.getUserInfo().split(":", 2)[0];
891 } catch (Exception ignored) {
892 }
893 }
894 return null;
895 }
896
897 /**
898 * Returns the optional proxy user name to use if connecting
899 * through a proxy. Returns either the proxyUsername set on this
900 * object, or if not provided, checks the value of the Java system
901 * property for proxy user name according to {@link #getProtocol()}:
902 * i.e. if protocol is https, returns the value of the system
903 * property https.proxyUser, otherwise returns value of
904 * http.proxyUser. If neither are set, checks the value of the
905 * environment variable according to {@link #getProtocol()}: i.e.
906 * if protocol is https, returns the user name in the value of the
907 * HTTPS_PROXY/https_proxy environment variable, otherwise returns
908 * the user name in the value of the HTTP_PROXY/http_proxy environment
909 * variable.
910 *
911 * @return The optional proxy user name the configured client will use if connecting through a
912 * proxy.
913 */
914 public String getProxyUsername() {
915 if (proxyUsername != null) {
916 return proxyUsername;
917 } else if (getProxyUsernameProperty() != null) {
918 return getProxyUsernameProperty();
919 } else {
920 return getProxyUsernameEnvironment();
921 }
922 }
923
924 /**
925 * Sets the optional proxy user name to use if connecting through a proxy.
926 *
927 * @param proxyUsername
928 * The proxy user name to use if connecting through a proxy.
929 */
930 public void setProxyUsername(String proxyUsername) {
931 this.proxyUsername = proxyUsername;
932 }
933
934 /**
935 * Sets the optional proxy user name and returns the updated ClientConfiguration object.
936 *
937 * @param proxyUsername
938 * The proxy user name to use if connecting through a proxy.
939 * @return The updated ClientConfiguration object.
940 */
941 public ClientConfiguration withProxyUsername(String proxyUsername) {
942 setProxyUsername(proxyUsername);
943 return this;
944 }
945
946 /**
947 * Returns the Java system property for proxy password depending on
948 * {@link #getProtocol()}: i.e. if protocol is https, returns
949 * the value of the system property https.proxyPassword, otherwise
950 * returns value of http.proxyPassword.
951 */
952 private String getProxyPasswordProperty() {
953 return (getProtocol() == Protocol.HTTPS)
954 ? getSystemProperty("https.proxyPassword")
955 : getSystemProperty("http.proxyPassword");
956 }
957
958 /**
959 * Returns the environment variable for proxy host depending on
960 * {@link #getProtocol()}: i.e. if protocol is https, returns
961 * the password in the value of the environment variable HTTPS_PROXY/https_proxy,
962 * otherwise, returns the password in the value of the environment
963 * variable HTTP_PROXY/http_proxy.
964 */
965 private String getProxyPasswordEnvironment() {
966 URL httpProxy = getHttpProxyEnvironmentVariable();
967 if (httpProxy != null) {
968 try {
969 return httpProxy.getUserInfo().split(":", 2)[1];
970 } catch (Exception ignored) {
971 }
972 }
973 return null;
974 }
975
976 /**
977 * Returns the optional proxy password to use if connecting
978 * through a proxy. Returns either the proxyPassword set on this
979 * object, or if not provided, checks the value of the Java system
980 * property for proxy password according to {@link #getProtocol()}:
981 * i.e. if protocol is https, returns the value of the system
982 * property https.proxyPassword, otherwise returns value of
983 * http.proxyPassword. If neither are set, checks the value of the
984 * environment variable according to {@link #getProtocol()}: i.e. if
985 * protocol is https, returns the password in the value of the
986 * HTTPS_PROXY/https_proxy environment variable, otherwise returns
987 * the password in the value of the HTTP_PROXY/http_proxy environment
988 * variable.
989 *
990 * @return The password to use when connecting through a proxy.
991 */
992 public String getProxyPassword() {
993 if (proxyPassword != null) {
994 return proxyPassword;
995 } else if (getProxyPasswordProperty() != null) {
996 return getProxyPasswordProperty();
997 } else {
998 return getProxyPasswordEnvironment();
999 }
1000 }
1001
1002 /**
1003 * Sets the optional proxy password to use when connecting through a proxy.
1004 *
1005 * @param proxyPassword
1006 * The password to use when connecting through a proxy.
1007 */
1008 public void setProxyPassword(String proxyPassword) {
1009 this.proxyPassword = proxyPassword;
1010 }
1011
1012 /**
1013 * Sets the optional proxy password to use when connecting through a proxy, and returns the
1014 * updated ClientConfiguration object.
1015 *
1016 * @param proxyPassword
1017 * The password to use when connecting through a proxy.
1018 * @return The updated ClientConfiguration object.
1019 */
1020 public ClientConfiguration withProxyPassword(String proxyPassword) {
1021 setProxyPassword(proxyPassword);
1022 return this;
1023 }
1024
1025 /**
1026 * Returns the optional Windows domain name for configuring an NTLM proxy. If you aren't using a
1027 * Windows NTLM proxy, you do not need to set this field.
1028 *
1029 * @return The optional Windows domain name for configuring an NTLM proxy.
1030 */
1031 public String getProxyDomain() {
1032 return proxyDomain;
1033 }
1034
1035 /**
1036 * Sets the optional Windows domain name for configuration an NTLM proxy. If you aren't using a
1037 * Windows NTLM proxy, you do not need to set this field.
1038 *
1039 * @param proxyDomain
1040 * The optional Windows domain name for configuring an NTLM proxy.
1041 */
1042 public void setProxyDomain(String proxyDomain) {
1043 this.proxyDomain = proxyDomain;
1044 }
1045
1046 /**
1047 * Sets the optional Windows domain name for configuration an NTLM proxy and returns a reference
1048 * to this updated ClientConfiguration object so that additional method calls can be chained
1049 * together. If you aren't using a Windows NTLM proxy, you do not need to set this field.
1050 *
1051 * @param proxyDomain
1052 * The optional Windows domain name for configuring an NTLM proxy.
1053 * @return The updated ClientConfiguration object.
1054 */
1055 public ClientConfiguration withProxyDomain(String proxyDomain) {
1056 setProxyDomain(proxyDomain);
1057 return this;
1058 }
1059
1060 /**
1061 * Returns the optional Windows workstation name for configuring NTLM proxy support. If you
1062 * aren't using a Windows NTLM proxy, you do not need to set this field.
1063 *
1064 * @return The optional Windows workstation name for configuring NTLM proxy support.
1065 */
1066 public String getProxyWorkstation() {
1067 return proxyWorkstation;
1068 }
1069
1070 /**
1071 * Sets the optional Windows workstation name for configuring NTLM proxy support. If you aren't
1072 * using a Windows NTLM proxy, you do not need to set this field.
1073 *
1074 * @param proxyWorkstation
1075 * The optional Windows workstation name for configuring NTLM proxy support.
1076 */
1077 public void setProxyWorkstation(String proxyWorkstation) {
1078 this.proxyWorkstation = proxyWorkstation;
1079 }
1080
1081 /**
1082 * Sets the optional Windows workstation name for configuring NTLM proxy support, and returns
1083 * the updated ClientConfiguration object so that additional method calls can be chained
1084 * together. If you aren't using a Windows NTLM proxy, you do not need to set this field.
1085 *
1086 * @param proxyWorkstation
1087 * The optional Windows workstation name for configuring NTLM proxy support.
1088 * @return The updated ClientConfiguration object.
1089 */
1090 public ClientConfiguration withProxyWorkstation(String proxyWorkstation) {
1091 setProxyWorkstation(proxyWorkstation);
1092 return this;
1093 }
1094
1095 /**
1096 * Returns the Java system property for nonProxyHosts. We still honor this property even
1097 * {@link #getProtocol()} is https, see http://docs.oracle.com/javase/7/docs/api/java/net/doc-files/net-properties.html.
1098 *
1099 * This method expects the property to be set as pipe separated list.
1100 */
1101 private String getNonProxyHostsProperty() {
1102 return getSystemProperty("http.nonProxyHosts");
1103 }
1104
1105 /**
1106 * Returns the value of the environment variable NO_PROXY/no_proxy. This method expects
1107 * the environment variable to be set as a comma separated list, so this method
1108 * converts the comma separated list to pipe separated list to be used internally.
1109 */
1110 private String getNonProxyHostsEnvironment() {
1111 String nonProxyHosts = getEnvironmentVariableCaseInsensitive("NO_PROXY");
1112 if (nonProxyHosts != null) {
1113 nonProxyHosts = nonProxyHosts.replace(",", "|");
1114 }
1115
1116 return nonProxyHosts;
1117 }
1118
1119 /**
1120 * Returns the optional hosts the client will access without going
1121 * through the proxy. Returns either the nonProxyHosts set on this
1122 * object, or if not provided, returns the value of the Java system property
1123 * http.nonProxyHosts. We still honor this property even when
1124 * {@link #getProtocol()} is https, see http://docs.oracle.com/javase/7/docs/api/java/net/doc-files/net-properties.html.
1125 * This property is expected to be set as a pipe separated list. If neither are set,
1126 * returns the value of the environment variable NO_PROXY/no_proxy. This environment
1127 * variable is expected to be set as a comma separated list.
1128 *
1129 * @return The hosts the client will connect through bypassing the proxy.
1130 */
1131 public String getNonProxyHosts() {
1132 if (nonProxyHosts != null) {
1133 return nonProxyHosts;
1134 } else if (getNonProxyHostsProperty() != null) {
1135 return getNonProxyHostsProperty();
1136 } else {
1137 return getNonProxyHostsEnvironment();
1138 }
1139 }
1140
1141 /**
1142 * Set the optional hosts the client will access without going
1143 * through the proxy.
1144 *
1145 * @param nonProxyHosts
1146 * The hosts the client will access without going through the proxy.
1147 */
1148 public void setNonProxyHosts(String nonProxyHosts) {
1149 this.nonProxyHosts = nonProxyHosts;
1150 }
1151
1152 /**
1153 * Set the optional hosts the client will access without going
1154 * through the proxy.
1155 *
1156 * @param nonProxyHosts
1157 * The hosts the client will access without going through the proxy.
1158 * @return The updated ClientConfiguration object.
1159 */
1160 public ClientConfiguration withNonProxyHosts(String nonProxyHosts) {
1161 setNonProxyHosts(nonProxyHosts);
1162 return this;
1163 }
1164
1165 /**
1166 * Returns the list of authentication methods that should be used when authenticating against an HTTP proxy, in the order they
1167 * should be attempted.
1168 *
1169 * @return An unmodifiable view of the proxy authentication methods that should be attempted, in order.
1170 */
1171 public List<ProxyAuthenticationMethod> getProxyAuthenticationMethods() {
1172 return this.proxyAuthenticationMethods;
1173 }
1174
1175 /**
1176 * Configure the list of authentication methods that should be used when authenticating against an HTTP proxy, in the order
1177 * they should be attempted. Any methods not included in this list will not be attempted. If one authentication method fails,
1178 * the next method will be attempted, until a working method is found (or all methods have been attempted).
1179 *
1180 * <p>Setting this value to null indicates using the default behavior, which is to try all authentication methods in an
1181 * unspecified order.</p>
1182 *
1183 * @param proxyAuthenticationMethods The proxy authentication methods to be attempted, in the order they should be attempted.
1184 */
1185 public void setProxyAuthenticationMethods(List<ProxyAuthenticationMethod> proxyAuthenticationMethods) {
1186 if(proxyAuthenticationMethods == null) {
1187 this.proxyAuthenticationMethods = null;
1188 } else {
1189 ValidationUtils.assertNotEmpty(proxyAuthenticationMethods, "proxyAuthenticationMethods");
1190 this.proxyAuthenticationMethods =
1191 Collections.unmodifiableList(new ArrayList<ProxyAuthenticationMethod>(proxyAuthenticationMethods));
1192 }
1193 }
1194
1195 /**
1196 * Configure the list of authentication methods that should be used when authenticating against an HTTP proxy, in the order
1197 * they should be attempted. Any methods not included in this list will not be attempted. If one authentication method fails,
1198 * the next method will be attempted, until a working method is found (or all methods have been attempted).
1199 *
1200 * <p>Setting this value to null indicates using the default behavior, which is to try all authentication methods in an
1201 * unspecified order.</p>
1202 *
1203 * @param proxyAuthenticationMethods The proxy authentication methods to be attempted, in the order they should be attempted.
1204 * @return The updated ClientConfiguration object.
1205 */
1206 public ClientConfiguration withProxyAuthenticationMethods(List<ProxyAuthenticationMethod> proxyAuthenticationMethods) {
1207 setProxyAuthenticationMethods(proxyAuthenticationMethods);
1208 return this;
1209 }
1210
1211 /**
1212 * Returns the retry policy upon failed requests.
1213 *
1214 * @return The retry policy upon failed requests.
1215 */
1216 public RetryPolicy getRetryPolicy() {
1217 return retryPolicy;
1218 }
1219
1220 /**
1221 * Sets the retry policy upon failed requests. User could specify whether the RetryPolicy should
1222 * honor maxErrorRetry set by {@link #setMaxErrorRetry(int)}.
1223 *
1224 * @param retryPolicy
1225 * The retry policy upon failed requests.
1226 */
1227 public void setRetryPolicy(RetryPolicy retryPolicy) {
1228 this.retryPolicy = retryPolicy;
1229 }
1230
1231 /**
1232 * Sets the retry policy upon failed requests, and returns the updated ClientConfiguration
1233 * object. User could specify whether the RetryPolicy should honor maxErrorRetry set by
1234 * {@link #setMaxErrorRetry(int)}
1235 *
1236 * @param retryPolicy
1237 * The retry policy upon failed requests.
1238 */
1239 public ClientConfiguration withRetryPolicy(RetryPolicy retryPolicy) {
1240 setRetryPolicy(retryPolicy);
1241 return this;
1242 }
1243
1244 /**
1245 * Returns the maximum number of retry attempts for failed retryable requests (ex: 5xx error
1246 * responses from a service). This method returns -1 before a maxErrorRetry value is explicitly
1247 * set by {@link #setMaxErrorRetry(int)}, in which case the configured RetryPolicy will be used
1248 * to control the retry count.
1249 *
1250 * @return The maximum number of retry attempts for failed retryable requests, or -1 if
1251 * maxErrorRetry has not been set by {@link #setMaxErrorRetry(int)}.
1252 */
1253 public int getMaxErrorRetry() {
1254 return maxErrorRetry;
1255 }
1256
1257 /**
1258 * Sets the maximum number of retry attempts for failed retryable requests (ex: 5xx error
1259 * responses from services).
1260 *
1261 * @param maxErrorRetry
1262 * The maximum number of retry attempts for failed retryable requests. This value
1263 * should not be negative.
1264 */
1265 public void setMaxErrorRetry(int maxErrorRetry) {
1266 if (maxErrorRetry < 0) {
1267 throw new IllegalArgumentException("maxErrorRetry should be non-negative");
1268 }
1269 this.maxErrorRetry = maxErrorRetry;
1270 }
1271
1272 /**
1273 * Sets the maximum number of retry attempts for failed retryable requests (ex: 5xx error
1274 * responses from services), and returns the updated ClientConfiguration object.
1275 *
1276 * @param maxErrorRetry
1277 * The maximum number of retry attempts for failed retryable requests. This value
1278 * should not be negative.
1279 * @return The updated ClientConfiguration object.
1280 */
1281 public ClientConfiguration withMaxErrorRetry(int maxErrorRetry) {
1282 setMaxErrorRetry(maxErrorRetry);
1283 return this;
1284 }
1285
1286 /**
1287 * Sets the RetryMode to use
1288 *
1289 * @param retryMode the retryMode
1290 * @return The updated ClientConfiguration object.
1291 */
1292 public ClientConfiguration withRetryMode(RetryMode retryMode) {
1293 setRetryMode(retryMode);
1294 return this;
1295 }
1296
1297 /**
1298 * Sets the RetryMode to use
1299 *
1300 * @param retryMode the retryMode
1301 */
1302 public void setRetryMode(RetryMode retryMode) {
1303 this.retryMode = retryMode;
1304 }
1305
1306 /**
1307 * @return the retryMode
1308 */
1309 public RetryMode getRetryMode() {
1310 return retryMode;
1311 }
1312
1313 /**
1314 * Returns the amount of time to wait (in milliseconds) for data to be transferred over an
1315 * established, open connection before the connection times out and is closed. A value of 0
1316 * means infinity, and isn't recommended.
1317 *
1318 * @return The amount of time to wait (in milliseconds) for data to be transferred over an
1319 * established, open connection before the connection times out and is closed.
1320 */
1321 public int getSocketTimeout() {
1322 return socketTimeout;
1323 }
1324
1325 /**
1326 * Sets the amount of time to wait (in milliseconds) for data to be transferred over an
1327 * established, open connection before the connection times out and is closed. A value of 0
1328 * means infinity, and isn't recommended.
1329 *
1330 * @param socketTimeout
1331 * The amount of time to wait (in milliseconds) for data to be transferred over an
1332 * established, open connection before the connection times out and is closed.
1333 */
1334 public void setSocketTimeout(int socketTimeout) {
1335 this.socketTimeout = socketTimeout;
1336 }
1337
1338 /**
1339 * Sets the amount of time to wait (in milliseconds) for data to be transferred over an
1340 * established, open connection before the connection times out and is closed, and returns the
1341 * updated ClientConfiguration object so that additional method calls may be chained together.
1342 *
1343 * @param socketTimeout
1344 * The amount of time to wait (in milliseconds) for data to be transferred over an
1345 * established, open connection before the connection times out and is closed.
1346 * @return The updated ClientConfiguration object.
1347 */
1348 public ClientConfiguration withSocketTimeout(int socketTimeout) {
1349 setSocketTimeout(socketTimeout);
1350 return this;
1351 }
1352
1353 /**
1354 * Returns the amount of time to wait (in milliseconds) when initially establishing a connection
1355 * before giving up and timing out. A value of 0 means infinity, and is not recommended.
1356 *
1357 * @return The amount of time to wait (in milliseconds) when initially establishing a connection
1358 * before giving up and timing out.
1359 */
1360 public int getConnectionTimeout() {
1361 return connectionTimeout;
1362 }
1363
1364 /**
1365 * Sets the amount of time to wait (in milliseconds) when initially establishing a connection
1366 * before giving up and timing out. A value of 0 means infinity, and is not recommended.
1367 *
1368 * @param connectionTimeout
1369 * The amount of time to wait (in milliseconds) when initially establishing a
1370 * connection before giving up and timing out.
1371 */
1372 public void setConnectionTimeout(int connectionTimeout) {
1373 this.connectionTimeout = connectionTimeout;
1374 }
1375
1376 /**
1377 * Sets the amount of time to wait (in milliseconds) when initially establishing a connection
1378 * before giving up and timing out, and returns the updated ClientConfiguration object so that
1379 * additional method calls may be chained together.
1380 *
1381 * @param connectionTimeout
1382 * the amount of time to wait (in milliseconds) when initially establishing a
1383 * connection before giving up and timing out.
1384 * @return The updated ClientConfiguration object.
1385 */
1386 public ClientConfiguration withConnectionTimeout(int connectionTimeout) {
1387 setConnectionTimeout(connectionTimeout);
1388 return this;
1389 }
1390
1391 /**
1392 * Returns the amount of time to wait (in milliseconds) for the request to complete before
1393 * giving up and timing out. A non-positive value disables this feature.
1394 * <p>
1395 * This feature requires buffering the entire response (for non-streaming APIs) into memory to
1396 * enforce a hard timeout when reading the response. For APIs that return large responses this
1397 * could be expensive.
1398 * <p>
1399 * <p>
1400 * The request timeout feature doesn't have strict guarantees on how quickly a request is
1401 * aborted when the timeout is breached. The typical case aborts the request within a few
1402 * milliseconds but there may occasionally be requests that don't get aborted until several
1403 * seconds after the timer has been breached. Because of this, the request timeout feature
1404 * should not be used when absolute precision is needed.
1405 * </p>
1406 * <b>Note:</b> This feature is not compatible with Java 1.6.
1407 * </p>
1408 *
1409 * @return The amount of time to wait (in milliseconds) for the request to complete before
1410 * giving up and timing out.
1411 * @see {@link ClientConfiguration#setClientExecutionTimeout(int)} to enforce a timeout across
1412 * all retries
1413 */
1414 public int getRequestTimeout() {
1415 return requestTimeout;
1416 }
1417
1418 /**
1419 * Sets the amount of time to wait (in milliseconds) for the request to complete before giving
1420 * up and timing out. A non-positive value disables this feature.
1421 * <p>
1422 * This feature requires buffering the entire response (for non-streaming APIs) into memory to
1423 * enforce a hard timeout when reading the response. For APIs that return large responses this
1424 * could be expensive.
1425 * <p>
1426 * <p>
1427 * The request timeout feature doesn't have strict guarantees on how quickly a request is
1428 * aborted when the timeout is breached. The typical case aborts the request within a few
1429 * milliseconds but there may occasionally be requests that don't get aborted until several
1430 * seconds after the timer has been breached. Because of this, the request timeout feature
1431 * should not be used when absolute precision is needed.
1432 * </p>
1433 * <p>
1434 * <b>Note:</b> This feature is not compatible with Java 1.6.
1435 * </p>
1436 *
1437 * @param requestTimeout
1438 * The amount of time to wait (in milliseconds) for the request to complete before
1439 * giving up and timing out.
1440 * @see {@link ClientConfiguration#setClientExecutionTimeout(int)} to enforce a timeout across
1441 * all retries
1442 */
1443 public void setRequestTimeout(int requestTimeout) {
1444 this.requestTimeout = requestTimeout;
1445 }
1446
1447 /**
1448 * Sets the amount of time to wait (in milliseconds) for the request to complete before giving
1449 * up and timing out. A non-positive value disables this feature. Returns the updated
1450 * ClientConfiguration object so that additional method calls may be chained together.
1451 * <p>
1452 * This feature requires buffering the entire response (for non-streaming APIs) into memory to
1453 * enforce a hard timeout when reading the response. For APIs that return large responses this
1454 * could be expensive.
1455 * <p>
1456 * <p>
1457 * The request timeout feature doesn't have strict guarantees on how quickly a request is
1458 * aborted when the timeout is breached. The typical case aborts the request within a few
1459 * milliseconds but there may occasionally be requests that don't get aborted until several
1460 * seconds after the timer has been breached. Because of this, the request timeout feature
1461 * should not be used when absolute precision is needed.
1462 * </p>
1463 * <p>
1464 * <b>Note:</b> This feature is not compatible with Java 1.6.
1465 * </p>
1466 *
1467 * @param requestTimeout
1468 * The amount of time to wait (in milliseconds) for the request to complete before
1469 * giving up and timing out.
1470 * @return The updated ClientConfiguration object.
1471 * @see {@link ClientConfiguration#setClientExecutionTimeout(int)} to enforce a timeout across
1472 * all retries
1473 */
1474 public ClientConfiguration withRequestTimeout(int requestTimeout) {
1475 setRequestTimeout(requestTimeout);
1476 return this;
1477 }
1478
1479 /**
1480 * Returns the amount of time (in milliseconds) to allow the client to complete the execution of
1481 * an API call. This timeout covers the entire client execution except for marshalling. This
1482 * includes request handler execution, all HTTP request including retries, unmarshalling, etc.
1483 * <p>
1484 * This feature requires buffering the entire response (for non-streaming APIs) into memory to
1485 * enforce a hard timeout when reading the response. For APIs that return large responses this
1486 * could be expensive.
1487 * <p>
1488 * <p>
1489 * The client execution timeout feature doesn't have strict guarantees on how quickly a request
1490 * is aborted when the timeout is breached. The typical case aborts the request within a few
1491 * milliseconds but there may occasionally be requests that don't get aborted until several
1492 * seconds after the timer has been breached. Because of this, the client execution timeout
1493 * feature should not be used when absolute precision is needed.
1494 * </p>
1495 * <p>
1496 * This may be used together with {@link ClientConfiguration#setRequestTimeout(int)} to enforce
1497 * both a timeout on each individual HTTP request (i.e. each retry) and the total time spent on
1498 * all requests across retries (i.e. the 'client execution' time). A non-positive value disables
1499 * this feature.
1500 * </p>
1501 * <p>
1502 * <b>Note:</b> This feature is not compatible with Java 1.6.
1503 * </p>
1504 *
1505 * @return The amount of time (in milliseconds) to allow the client to complete the execution of
1506 * an API call.
1507 * @see {@link ClientConfiguration#setRequestTimeout(int)} to enforce a timeout per HTTP request
1508 */
1509 public int getClientExecutionTimeout() {
1510 return this.clientExecutionTimeout;
1511 }
1512
1513 /**
1514 * Sets the amount of time (in milliseconds) to allow the client to complete the execution of
1515 * an API call. This timeout covers the entire client execution except for marshalling. This
1516 * includes request handler execution, all HTTP request including retries, unmarshalling, etc.
1517 * <p>
1518 * This feature requires buffering the entire response (for non-streaming APIs) into memory to
1519 * enforce a hard timeout when reading the response. For APIs that return large responses this
1520 * could be expensive.
1521 * <p>
1522 * <p>
1523 * The client execution timeout feature doesn't have strict guarantees on how quickly a request
1524 * is aborted when the timeout is breached. The typical case aborts the request within a few
1525 * milliseconds but there may occasionally be requests that don't get aborted until several
1526 * seconds after the timer has been breached. Because of this, the client execution timeout
1527 * feature should not be used when absolute precision is needed.
1528 * </p>
1529 * <p>
1530 * This may be used together with {@link ClientConfiguration#setRequestTimeout(int)} to enforce
1531 * both a timeout on each individual HTTP request (i.e. each retry) and the total time spent on
1532 * all requests across retries (i.e. the 'client execution' time). A non-positive value disables
1533 * this feature.
1534 * </p>
1535 * <p>
1536 * <b>Note:</b> This feature is not compatible with Java 1.6.
1537 * </p>
1538 *
1539 * @param clientExecutionTimeout
1540 * The amount of time (in milliseconds) to allow the client to complete the execution
1541 * of an API call. A value of '0' disables this feature.
1542 * @see {@link ClientConfiguration#setRequestTimeout(int)} to enforce a timeout per HTTP request
1543 */
1544 public void setClientExecutionTimeout(int clientExecutionTimeout) {
1545 this.clientExecutionTimeout = clientExecutionTimeout;
1546 }
1547
1548 /**
1549 * Sets the amount of time (in milliseconds) to allow the client to complete the execution of
1550 * an API call. This timeout covers the entire client execution except for marshalling. This
1551 * includes request handler execution, all HTTP request including retries, unmarshalling, etc.
1552 * <p>
1553 * This feature requires buffering the entire response (for non-streaming APIs) into memory to
1554 * enforce a hard timeout when reading the response. For APIs that return large responses this
1555 * could be expensive.
1556 * <p>
1557 * <p>
1558 * The client execution timeout feature doesn't have strict guarantees on how quickly a request
1559 * is aborted when the timeout is breached. The typical case aborts the request within a few
1560 * milliseconds but there may occasionally be requests that don't get aborted until several
1561 * seconds after the timer has been breached. Because of this, the client execution timeout
1562 * feature should not be used when absolute precision is needed.
1563 * </p>
1564 * <p>
1565 * This may be used together with {@link ClientConfiguration#setRequestTimeout(int)} to enforce
1566 * both a timeout on each individual HTTP request (i.e. each retry) and the total time spent on
1567 * all requests across retries (i.e. the 'client execution' time). A non-positive value disables
1568 * this feature.
1569 * </p>
1570 * <p>
1571 * <b>Note:</b> This feature is not compatible with Java 1.6.
1572 * </p>
1573 *
1574 * @param clientExecutionTimeout
1575 * The amount of time (in milliseconds) to allow the client to complete the execution
1576 * of an API call. A value of '0' disables this feature.
1577 * @return The updated ClientConfiguration object for method chaining
1578 * @see {@link ClientConfiguration#setRequestTimeout(int)} to enforce a timeout per HTTP request
1579 */
1580 public ClientConfiguration withClientExecutionTimeout(int clientExecutionTimeout) {
1581 setClientExecutionTimeout(clientExecutionTimeout);
1582 return this;
1583 }
1584
1585 /**
1586 * Checks if the {@link IdleConnectionReaper} is to be started
1587 *
1588 * @return if the {@link IdleConnectionReaper} is to be started
1589 */
1590 public boolean useReaper() {
1591 return useReaper;
1592 }
1593
1594 /**
1595 * Sets whether the {@link IdleConnectionReaper} is to be started as a daemon thread
1596 *
1597 * @param use
1598 * whether the {@link IdleConnectionReaper} is to be started as a daemon thread
1599 * @see IdleConnectionReaper
1600 */
1601 public void setUseReaper(boolean use) {
1602 this.useReaper = use;
1603 }
1604
1605 /**
1606 * Sets whether the {@link IdleConnectionReaper} is to be started as a daemon thread
1607 *
1608 * @param use
1609 * the {@link IdleConnectionReaper} is to be started as a daemon thread
1610 * @return The updated ClientConfiguration object.
1611 */
1612 public ClientConfiguration withReaper(boolean use) {
1613 setUseReaper(use);
1614 return this;
1615 }
1616
1617 /**
1618 * Returns whether retry throttling will be used.
1619 * <p>
1620 * Retry throttling is a feature which intelligently throttles retry attempts when a
1621 * large percentage of requests are failing and retries are unsuccessful, particularly
1622 * in scenarios of degraded service health. In these situations the client will drain its
1623 * internal retry capacity and slowly roll off from retry attempts until requests begin
1624 * to succeed again. At that point the retry capacity pool will begin to refill and
1625 * retries will once again be permitted.
1626 * </p>
1627 * <p>
1628 * In situations where retries have been throttled this feature will effectively result in
1629 * fail-fast behavior from the client. Because retries are circumvented exceptions will
1630 * be immediately returned to the caller if the initial request is unsuccessful. This
1631 * will result in a greater number of exceptions being returned up front but prevents
1632 * requests being tied up attempting subsequent retries which are also likely to fail.
1633 * </p>
1634 *
1635 * @return true if retry throttling will be used
1636 */
1637 public boolean useThrottledRetries() {
1638 return throttleRetries || getSystemProperty(
1639 SDKGlobalConfiguration.RETRY_THROTTLING_SYSTEM_PROPERTY) != null;
1640 }
1641
1642 /**
1643 * Sets whether throttled retries should be used
1644 * <p>
1645 * Retry throttling is a feature which intelligently throttles retry attempts when a
1646 * large percentage of requests are failing and retries are unsuccessful, particularly
1647 * in scenarios of degraded service health. In these situations the client will drain its
1648 * internal retry capacity and slowly roll off from retry attempts until requests begin
1649 * to succeed again. At that point the retry capacity pool will begin to refill and
1650 * retries will once again be permitted.
1651 * </p>
1652 * <p>
1653 * In situations where retries have been throttled this feature will effectively result in
1654 * fail-fast behavior from the client. Because retries are circumvented exceptions will
1655 * be immediately returned to the caller if the initial request is unsuccessful. This
1656 * will result in a greater number of exceptions being returned up front but prevents
1657 * requests being tied up attempting subsequent retries which are also likely to fail.
1658 * </p>
1659 *
1660 * @param use
1661 * true if throttled retries should be used
1662 */
1663 public void setUseThrottleRetries(boolean use) { this.throttleRetries = use; }
1664
1665 /**
1666 * Sets whether throttled retries should be used
1667 * <p>
1668 * Retry throttling is a feature which intelligently throttles retry attempts when a
1669 * large percentage of requests are failing and retries are unsuccessful, particularly
1670 * in scenarios of degraded service health. In these situations the client will drain its
1671 * internal retry capacity and slowly roll off from retry attempts until requests begin
1672 * to succeed again. At that point the retry capacity pool will begin to refill and
1673 * retries will once again be permitted.
1674 * </p>
1675 * <p>
1676 * In situations where retries have been throttled this feature will effectively result in
1677 * fail-fast behavior from the client. Because retries are circumvented exceptions will
1678 * be immediately returned to the caller if the initial request is unsuccessful. This
1679 * will result in a greater number of exceptions being returned up front but prevents
1680 * requests being tied up attempting subsequent retries which are also likely to fail.
1681 * </p>
1682
1683 * @param use
1684 * true if throttled retries should be used
1685 * @return The updated ClientConfiguration object.
1686 */
1687 public ClientConfiguration withThrottledRetries(boolean use) {
1688 setUseThrottleRetries(use);
1689 return this;
1690 }
1691
1692 /**
1693 * Set the maximum number of consecutive failed retries that the client will permit before
1694 * throttling all subsequent retries of failed requests.
1695 * <p>
1696 * Note: This does not guarantee that each failed request will be retried up to this many times.
1697 * Depending on the configured {@link RetryPolicy} and the number of past failed and successful
1698 * requests, the actual number of retries attempted may be less.
1699 * <p>
1700 * This has a default value of {@link #DEFAULT_MAX_CONSECUTIVE_RETRIES_BEFORE_THROTTLING}.
1701 *
1702 * @param maxConsecutiveRetriesBeforeThrottling The maximum number of consecutive retries.
1703 */
1704 public void setMaxConsecutiveRetriesBeforeThrottling(int maxConsecutiveRetriesBeforeThrottling) {
1705 this.maxConsecutiveRetriesBeforeThrottling = ValidationUtils.assertIsPositive(maxConsecutiveRetriesBeforeThrottling,
1706 "maxConsecutiveRetriesBeforeThrottling");
1707 }
1708 /**
1709 * Set the maximum number of consecutive failed retries that the client will permit before
1710 * throttling all subsequent retries of failed requests.
1711 * <p>
1712 * Note: This does not guarantee that each failed request will be retried up to this many times.
1713 * Depending on the configured {@link RetryPolicy} and the number of past failed and successful
1714 * requests, the actual number of retries attempted may be less.
1715 * <p>
1716 * This has a default value of {@link #DEFAULT_MAX_CONSECUTIVE_RETRIES_BEFORE_THROTTLING}.
1717 *
1718 * @param maxConsecutiveRetriesBeforeThrottling The maximum number of consecutive retries.
1719 *
1720 * @return This object for chaining.
1721 */
1722 public ClientConfiguration withMaxConsecutiveRetriesBeforeThrottling(int maxConsecutiveRetriesBeforeThrottling) {
1723 setMaxConsecutiveRetriesBeforeThrottling(maxConsecutiveRetriesBeforeThrottling);
1724 return this;
1725 }
1726
1727 /**
1728 * @return Set the maximum number of consecutive failed retries that the client will permit
1729 * before throttling all subsequent retries of failed requests.
1730 */
1731 public int getMaxConsecutiveRetriesBeforeThrottling() {
1732 return maxConsecutiveRetriesBeforeThrottling;
1733 }
1734
1735 /**
1736 * Checks if gzip decompression is used when receiving HTTP responses.
1737 *
1738 * @return if gzip decompression is used
1739 */
1740 public boolean useGzip() {
1741 return useGzip;
1742 }
1743
1744 /**
1745 * Sets whether gzip decompression should be used when receiving HTTP responses.
1746 *
1747 * <p>
1748 * <b>Note</b>
1749 * useGzip should only be enabled if the HTTP response is gzipped
1750 *
1751 * @param use
1752 * whether gzip decompression should be used
1753 */
1754 public void setUseGzip(boolean use) {
1755 this.useGzip = use;
1756 }
1757
1758 /**
1759 * Sets whether gzip decompression should be used when receiving HTTP responses.
1760 *
1761 * <p>
1762 * <b>Note</b>
1763 * useGzip should only be enabled if the HTTP response is gzipped
1764 *
1765 * @param use
1766 * whether gzip decompression should be used
1767 * @return The updated ClientConfiguration object.
1768 */
1769 public ClientConfiguration withGzip(boolean use) {
1770 setUseGzip(use);
1771 return this;
1772 }
1773
1774 /**
1775 * Returns the optional size hints (in bytes) for the low level TCP send and receive buffers.
1776 * This is an advanced option for advanced users who want to tune low level TCP parameters to
1777 * try and squeeze out more performance.
1778 * <p>
1779 * The optimal TCP buffer sizes for a particular application are highly dependent on network
1780 * configuration and operating system configuration and capabilities. For example, most modern
1781 * operating systems provide auto-tuning functionality for TCP buffer sizes, which can have a
1782 * big impact on performance for TCP connections that are held open long enough for the
1783 * auto-tuning to optimize buffer sizes.
1784 * <p>
1785 * Large buffer sizes (ex: 2MB) will allow the operating system to buffer more data in memory
1786 * without requiring the remote server to acknowledge receipt of that information, so can be
1787 * particularly useful when the network has high latency.
1788 * <p>
1789 * This is only a <b>hint</b>, and the operating system may choose not to honor it. When using
1790 * this option, users should <b>always</b> check the operating system's configured limits and
1791 * defaults. Most OS's have a maximum TCP buffer size limit configured, and won't let you go
1792 * beyond that limit unless you explicitly raise the max TCP buffer size limit.
1793 * <p>
1794 * There are many resources available online to help with configuring TCP buffer sizes and
1795 * operating system specific TCP settings, including:
1796 * <ul>
1797 * <li>http://onlamp.com/pub/a/onlamp/2005/11/17/tcp_tuning.html</li>
1798 * <li>http://fasterdata.es.net/TCP-tuning/</li>
1799 * </ul>
1800 *
1801 * @return A two element array containing first the TCP send buffer size hint and then the TCP
1802 * receive buffer size hint.
1803 */
1804 public int[] getSocketBufferSizeHints() {
1805 return new int[] { socketSendBufferSizeHint, socketReceiveBufferSizeHint };
1806 }
1807
1808 /**
1809 * Sets the optional size hints (in bytes) for the low level TCP send and receive buffers. This
1810 * is an advanced option for advanced users who want to tune low level TCP parameters to try and
1811 * squeeze out more performance.
1812 * <p>
1813 * The optimal TCP buffer sizes for a particular application are highly dependent on network
1814 * configuration and operating system configuration and capabilities. For example, most modern
1815 * operating systems provide auto-tuning functionality for TCP buffer sizes, which can have a
1816 * big impact on performance for TCP connections that are held open long enough for the
1817 * auto-tuning to optimize buffer sizes.
1818 * <p>
1819 * Large buffer sizes (ex: 2MB) will allow the operating system to buffer more data in memory
1820 * without requiring the remote server to acknowledge receipt of that information, so can be
1821 * particularly useful when the network has high latency.
1822 * <p>
1823 * This is only a <b>hint</b>, and the operating system may choose not to honor it. When using
1824 * this option, users should <b>always</b> check the operating system's configured limits and
1825 * defaults. Most OS's have a maximum TCP buffer size limit configured, and won't let you go
1826 * beyond that limit unless you explicitly raise the max TCP buffer size limit.
1827 * <p>
1828 * There are many resources available online to help with configuring TCP buffer sizes and
1829 * operating system specific TCP settings, including:
1830 * <ul>
1831 * <li>http://onlamp.com/pub/a/onlamp/2005/11/17/tcp_tuning.html</li>
1832 * <li>http://fasterdata.es.net/TCP-tuning/</li>
1833 * </ul>
1834 *
1835 * @param socketSendBufferSizeHint
1836 * The size hint (in bytes) for the low level TCP send buffer.
1837 * @param socketReceiveBufferSizeHint
1838 * The size hint (in bytes) for the low level TCP receive buffer.
1839 */
1840 public void setSocketBufferSizeHints(int socketSendBufferSizeHint, int socketReceiveBufferSizeHint) {
1841 this.socketSendBufferSizeHint = socketSendBufferSizeHint;
1842 this.socketReceiveBufferSizeHint = socketReceiveBufferSizeHint;
1843 }
1844
1845 /**
1846 * Sets the optional size hints (in bytes) for the low level TCP send and receive buffers, and
1847 * returns the updated ClientConfiguration object so that additional method calls may be chained
1848 * together.
1849 * <p>
1850 * This is an advanced option for advanced users who want to tune low level TCP parameters to
1851 * try and squeeze out more performance.
1852 * <p>
1853 * The optimal TCP buffer sizes for a particular application are highly dependent on network
1854 * configuration and operating system configuration and capabilities. For example, most modern
1855 * operating systems provide auto-tuning functionality for TCP buffer sizes, which can have a
1856 * big impact on performance for TCP connections that are held open long enough for the
1857 * auto-tuning to optimize buffer sizes.
1858 * <p>
1859 * Large buffer sizes (ex: 2MB) will allow the operating system to buffer more data in memory
1860 * without requiring the remote server to acknowledge receipt of that information, so can be
1861 * particularly useful when the network has high latency.
1862 * <p>
1863 * This is only a <b>hint</b>, and the operating system may choose not to honor it. When using
1864 * this option, users should <b>always</b> check the operating system's configured limits and
1865 * defaults. Most OS's have a maximum TCP buffer size limit configured, and won't let you go
1866 * beyond that limit unless you explicitly raise the max TCP buffer size limit.
1867 * <p>
1868 * There are many resources available online to help with configuring TCP buffer sizes and
1869 * operating system specific TCP settings, including:
1870 * <ul>
1871 * <li>http://onlamp.com/pub/a/onlamp/2005/11/17/tcp_tuning.html</li>
1872 * <li>http://fasterdata.es.net/TCP-tuning/</li>
1873 * </ul>
1874 *
1875 * @param socketSendBufferSizeHint
1876 * The size hint (in bytes) for the low level TCP send buffer.
1877 * @param socketReceiveBufferSizeHint
1878 * The size hint (in bytes) for the low level TCP receive buffer.
1879 * @return The updated ClientConfiguration object.
1880 */
1881 public ClientConfiguration withSocketBufferSizeHints(int socketSendBufferSizeHint,
1882 int socketReceiveBufferSizeHint) {
1883 setSocketBufferSizeHints(socketSendBufferSizeHint, socketReceiveBufferSizeHint);
1884 return this;
1885 }
1886
1887 /**
1888 * Returns the name of the signature algorithm to use for signing requests made by this client.
1889 * If not set or explicitly set to null, the client will choose a signature algorithm to use
1890 * based on a configuration file of supported signature algorithms for the service and region.
1891 * <p>
1892 * Most users do not need to concern themselves with which signature algorithm is being used, as
1893 * the defaults will be sufficient. This setting exists only so advanced users can opt in to
1894 * newer signature protocols which have not yet been made the default for a particular
1895 * service/region.
1896 * <p>
1897 * Not all services support all signature algorithms, and configuring an unsupported signature
1898 * algorithm will lead to authentication failures. Use me at your own risk, and only after
1899 * consulting the documentation for the service to ensure it actually does supports your chosen
1900 * algorithm.
1901 * <p>
1902 * If non-null, the name returned from this method is used to look up a {@code Signer} class
1903 * implementing the chosen algorithm by the {@code com.amazonaws.auth.SignerFactory} class.
1904 *
1905 * @return The signature algorithm to use for this client, or null to use the default.
1906 */
1907 public String getSignerOverride() {
1908 return signerOverride;
1909 }
1910
1911 /**
1912 * Sets the name of the signature algorithm to use for signing requests made by this client. If
1913 * not set or explicitly set to null, the client will choose a signature algorithm to use based
1914 * on a configuration file of supported signature algorithms for the service and region.
1915 * <p>
1916 * Most users do not need to concern themselves with which signature algorithm is being used, as
1917 * the defaults will be sufficient. This setting exists only so advanced users can opt in to
1918 * newer signature protocols which have not yet been made the default for a particular
1919 * service/region.
1920 * <p>
1921 * Not all services support all signature algorithms, and configuring an unsupported signature
1922 * algorithm will lead to authentication failures. Use me at your own risk, and only after
1923 * consulting the documentation for the service to ensure it actually does supports your chosen
1924 * algorithm.
1925 * <p>
1926 * If non-null, the name returned from this method is used to look up a {@code Signer} class
1927 * implementing the chosen algorithm by the {@code com.amazonaws.auth.SignerFactory} class.
1928 *
1929 * @param value
1930 * The signature algorithm to use for this client, or null to use the default.
1931 */
1932 public void setSignerOverride(final String value) {
1933 signerOverride = value;
1934 }
1935
1936 /**
1937 * Sets the name of the signature algorithm to use for signing requests made by this client. If
1938 * not set or explicitly set to null, the client will choose a signature algorithm to use based
1939 * on a configuration file of supported signature algorithms for the service and region.
1940 * <p>
1941 * Most users do not need to concern themselves with which signature algorithm is being used, as
1942 * the defaults will be sufficient. This setting exists only so advanced users can opt in to
1943 * newer signature protocols which have not yet been made the default for a particular
1944 * service/region.
1945 * <p>
1946 * Not all services support all signature algorithms, and configuring an unsupported signature
1947 * algorithm will lead to authentication failures. Use me at your own risk, and only after
1948 * consulting the documentation for the service to ensure it actually does supports your chosen
1949 * algorithm.
1950 * <p>
1951 * If non-null, the name returned from this method is used to look up a {@code Signer} class
1952 * implementing the chosen algorithm by the {@code com.amazonaws.auth.SignerFactory} class.
1953 *
1954 * @param value
1955 * The signature algorithm to use for this client, or null to use the default.
1956 * @return The updated ClientConfiguration object.
1957 */
1958 public ClientConfiguration withSignerOverride(final String value) {
1959 setSignerOverride(value);
1960 return this;
1961 }
1962
1963 /**
1964 * Returns whether to attempt to authenticate preemptively against proxy servers using basic
1965 * authentication
1966 *
1967 * @return Whether to authenticate preemptively against proxy server.
1968 */
1969 public boolean isPreemptiveBasicProxyAuth() {
1970 return preemptiveBasicProxyAuth;
1971 }
1972
1973 /**
1974 * Sets whether to attempt to authenticate preemptively against proxy servers using basic
1975 * authentication
1976 *
1977 * @param preemptiveBasicProxyAuth
1978 * Whether to authenticate preemptively against proxy server.
1979 */
1980 public void setPreemptiveBasicProxyAuth(Boolean preemptiveBasicProxyAuth) {
1981 this.preemptiveBasicProxyAuth = preemptiveBasicProxyAuth;
1982 }
1983
1984 /**
1985 * Sets whether to attempt to authenticate preemptively against proxy servers using basic
1986 * authentication, and returns the updated ClientConfiguration object so that additional method
1987 * calls may be chained together.
1988 *
1989 * @param preemptiveBasicProxyAuth
1990 * Whether to authenticate preemptively against proxy server.
1991 * @return The updated ClientConfiguration object.
1992 */
1993 public ClientConfiguration withPreemptiveBasicProxyAuth(boolean preemptiveBasicProxyAuth) {
1994 setPreemptiveBasicProxyAuth(preemptiveBasicProxyAuth);
1995 return this;
1996 }
1997
1998 /**
1999 * Returns the expiration time (in milliseconds) for a connection in the connection pool. When
2000 * retrieving a connection from the pool to make a request, the total time that the connection
2001 * has been open is compared against this value. Connections which have been open for longer are
2002 * discarded, and if needed a new connection is created.
2003 * <p>
2004 * Tuning this setting down (together with an appropriately-low setting for Java's DNS cache
2005 * TTL) ensures that your application will quickly rotate over to new IP addresses when the
2006 * service begins announcing them through DNS, at the cost of having to re-establish new
2007 * connections more frequently.
2008 *
2009 * @return the connection TTL, in milliseconds
2010 */
2011 public long getConnectionTTL() {
2012 return connectionTTL;
2013 }
2014
2015 /**
2016 * Sets the expiration time (in milliseconds) for a connection in the connection pool. When
2017 * retrieving a connection from the pool to make a request, the total time that the connection
2018 * has been open is compared against this value. Connections which have been open for longer are
2019 * discarded, and if needed a new connection is created.
2020 * <p>
2021 * Tuning this setting down (together with an appropriately-low setting for Java's DNS cache
2022 * TTL) ensures that your application will quickly rotate over to new IP addresses when the
2023 * service begins announcing them through DNS, at the cost of having to re-establish new
2024 * connections more frequently.
2025 * <p>
2026 * By default, it is set to {@code -1], i.e. connections do not expire.
2027 *
2028 * @param connectionTTL
2029 * the connection TTL, in milliseconds
2030 */
2031 public void setConnectionTTL(long connectionTTL) {
2032 this.connectionTTL = connectionTTL;
2033 }
2034
2035 /**
2036 * Sets the expiration time (in milliseconds) for a connection in the connection pool. When
2037 * retrieving a connection from the pool to make a request, the total time that the connection
2038 * has been open is compared against this value. Connections which have been open for longer are
2039 * discarded, and if needed a new connection is created.
2040 * <p>
2041 * Tuning this setting down (together with an appropriately-low setting for Java's DNS cache
2042 * TTL) ensures that your application will quickly rotate over to new IP addresses when the
2043 * service begins announcing them through DNS, at the cost of having to re-establish new
2044 * connections more frequently.
2045 * <p>
2046 * By default, it is set to {@code -1}, i.e. connections do not expire.
2047 *
2048 * @param connectionTTL
2049 * the connection TTL, in milliseconds
2050 * @return the updated ClientConfiguration object
2051 */
2052 public ClientConfiguration withConnectionTTL(long connectionTTL) {
2053 setConnectionTTL(connectionTTL);
2054 return this;
2055 }
2056
2057 /**
2058 * Returns the maximum amount of time that an idle connection may sit in the connection pool and
2059 * still be eligible for reuse. When retrieving a connection from the pool to make a request,
2060 * the amount of time the connection has been idle is compared against this value. Connections
2061 * which have been idle for longer are discarded, and if needed a new connection is created.
2062 * <p>
2063 * Tuning this setting down reduces the likelihood of a race condition (wherein you begin
2064 * sending a request down a connection which appears to be healthy, but before it arrives the
2065 * service decides the connection has been idle for too long and closes it) at the cost of
2066 * having to re-establish new connections more frequently.
2067 *
2068 * @return the connection maximum idle time, in milliseconds
2069 */
2070 public long getConnectionMaxIdleMillis() {
2071 return connectionMaxIdleMillis;
2072 }
2073
2074 /**
2075 * Sets the maximum amount of time that an idle connection may sit in the connection pool and
2076 * still be eligible for reuse. When retrieving a connection from the pool to make a request,
2077 * the amount of time the connection has been idle is compared against this value. Connections
2078 * which have been idle for longer are discarded, and if needed a new connection is created.
2079 * <p>
2080 * Tuning this setting down reduces the likelihood of a race condition (wherein you begin
2081 * sending a request down a connection which appears to be healthy, but before it arrives the
2082 * service decides the connection has been idle for too long and closes it) at the cost of
2083 * having to re-establish new connections more frequently.
2084 * <p>
2085 * By default, it is set to one minute (60000ms).
2086 *
2087 * @param connectionMaxIdleMillis
2088 * the connection maximum idle time, in milliseconds
2089 */
2090 public void setConnectionMaxIdleMillis(long connectionMaxIdleMillis) {
2091 this.connectionMaxIdleMillis = connectionMaxIdleMillis;
2092 }
2093
2094 /**
2095 * Sets the maximum amount of time that an idle connection may sit in the connection pool and
2096 * still be eligible for reuse. When retrieving a connection from the pool to make a request,
2097 * the amount of time the connection has been idle is compared against this value. Connections
2098 * which have been idle for longer are discarded, and if needed a new connection is created.
2099 * <p>
2100 * Tuning this setting down reduces the likelihood of a race condition (wherein you begin
2101 * sending a request down a connection which appears to be healthy, but before it arrives the
2102 * service decides the connection has been idle for too long and closes it) at the cost of
2103 * having to re-establish new connections more frequently.
2104 * <p>
2105 * By default, it is set to one minute (60000ms).
2106 *
2107 * @param connectionMaxIdleMillis
2108 * the connection maximum idle time, in milliseconds
2109 * @return the updated ClientConfiguration object
2110 */
2111 public ClientConfiguration withConnectionMaxIdleMillis(long connectionMaxIdleMillis) {
2112
2113 setConnectionMaxIdleMillis(connectionMaxIdleMillis);
2114 return this;
2115 }
2116
2117 /**
2118 * Returns the amount of time (in milliseconds) that a connection can be idle in the connection pool before it must be
2119 * validated to ensure it's still open. This "stale connection check" adds a small bit of overhead to validate the
2120 * connection. Setting this value to larger values may increase the likelihood that the connection is not usable, potentially
2121 * resulting in a {@link org.apache.http.NoHttpResponseException}. Lowering this setting increases the overhead when leasing
2122 * connections from the connection pool. It is recommended to tune this setting based on how long a service allows a
2123 * connection to be idle before closing.
2124 *
2125 * <p>A non positive value disables validation of connections.</p>
2126 *
2127 * <p>The default value is {@value #DEFAULT_VALIDATE_AFTER_INACTIVITY_MILLIS} milliseconds.</p>
2128 */
2129 public int getValidateAfterInactivityMillis() {
2130 return validateAfterInactivityMillis;
2131 }
2132
2133 /**
2134 * Sets the amount of time (in milliseconds) that a connection can be idle in the connection pool before it must be validated
2135 * to ensure it's still open. This "stale connection check" adds a small bit of overhead to validate the connection. Setting
2136 * this value to larger values may increase the likelihood that the connection is not usable, potentially resulting in a
2137 * {@link org.apache.http.NoHttpResponseException}. Lowering this setting increases the overhead when leasing connections
2138 * from the connection pool. It is recommended to tune this setting based on how long a service allows a connection to be
2139 * idle before closing.
2140 *
2141 * <p>A non positive value disables validation of connections.</p>
2142 *
2143 * <p>The default value is {@value #DEFAULT_VALIDATE_AFTER_INACTIVITY_MILLIS} milliseconds.</p>
2144 *
2145 * @param validateAfterInactivityMillis The allowed time, in milliseconds, a connection can be idle before it must be
2146 * re-validated.
2147 */
2148 public void setValidateAfterInactivityMillis(int validateAfterInactivityMillis) {
2149 this.validateAfterInactivityMillis = validateAfterInactivityMillis;
2150 }
2151
2152 /**
2153 * Sets the amount of time (in milliseconds) that a connection can be idle in the connection pool before it must be validated
2154 * to ensure it's still open. This "stale connection check" adds a small bit of overhead to validate the connection. Setting
2155 * this value to larger values may increase the likelihood that the connection is not usable, potentially resulting in a
2156 * {@link org.apache.http.NoHttpResponseException}. Lowering this setting increases the overhead when leasing connections
2157 * from the connection pool. It is recommended to tune this setting based on how long a service allows a connection to be
2158 * idle before closing.
2159 *
2160 * <p>A non positive value disables validation of connections.</p>
2161 *
2162 * <p>The default value is {@value #DEFAULT_VALIDATE_AFTER_INACTIVITY_MILLIS} milliseconds.</p>
2163 *
2164 * @param validateAfterInactivityMillis The allowed time, in milliseconds, a connection can be idle before it must be
2165 * re-validated.
2166 * @return The updated {@link ClientConfiguration} object.
2167 */
2168 public ClientConfiguration withValidateAfterInactivityMillis(int validateAfterInactivityMillis) {
2169 setValidateAfterInactivityMillis(validateAfterInactivityMillis);
2170 return this;
2171 }
2172
2173 /**
2174 * Returns whether or not TCP KeepAlive support is enabled.
2175 */
2176 public boolean useTcpKeepAlive() {
2177 return tcpKeepAlive;
2178 }
2179
2180 /**
2181 * Sets whether or not to enable TCP KeepAlive support at the socket level.
2182 */
2183 public void setUseTcpKeepAlive(final boolean use) {
2184 this.tcpKeepAlive = use;
2185 }
2186
2187 /**
2188 * Sets whether or not to enable TCP KeepAlive support at the socket level.
2189 *
2190 * @return The updated ClientConfiguration object.
2191 */
2192 public ClientConfiguration withTcpKeepAlive(final boolean use) {
2193 setUseTcpKeepAlive(use);
2194 return this;
2195 }
2196
2197 /**
2198 * Returns the DnsResolver for resolving AWS IP addresses.
2199 * Returns the {@link SystemDefaultDnsResolver} by default if not
2200 * explicitly configured by the user.
2201 */
2202 public DnsResolver getDnsResolver() {
2203 return dnsResolver;
2204 }
2205
2206 /**
2207 * Sets the DNS Resolver that should be used to for resolving AWS IP addresses.
2208 */
2209 public void setDnsResolver(final DnsResolver resolver) {
2210 if (resolver == null) {
2211 throw new IllegalArgumentException("resolver cannot be null");
2212 }
2213 this.dnsResolver = resolver;
2214 }
2215
2216 /**
2217 * Sets the DNS Resolver that should be used to for resolving AWS IP addresses.
2218 *
2219 * @return The updated ClientConfiguration object.
2220 */
2221 public ClientConfiguration withDnsResolver(final DnsResolver resolver) {
2222 setDnsResolver(resolver);
2223 return this;
2224 }
2225
2226 /**
2227 * Returns whether or not to cache response metadata.
2228 * <p>
2229 * Response metadata is typically used for troubleshooting issues with AWS support staff when
2230 * services aren't acting as expected.
2231 * </p>
2232 * <p>
2233 * While this feature is useful for debugging it adds overhead and disabling it may
2234 * be desired in high throughput applications.
2235 * </p>
2236 *
2237 * @return true if response metadata will be cached
2238 */
2239 public boolean getCacheResponseMetadata() { return cacheResponseMetadata; }
2240
2241 /**
2242 * Sets whether or not to cache response metadata.
2243 * <p>
2244 * Response metadata is typically used for troubleshooting issues with AWS support staff when
2245 * services aren't acting as expected.
2246 * </p>
2247 * <p>
2248 * While this feature is useful for debugging it adds overhead and disabling it may
2249 * be desired in high throughput applications.
2250 * </p>
2251 *
2252 * @param shouldCache true if response metadata should be cached
2253 */
2254 public void setCacheResponseMetadata(boolean shouldCache) {
2255 this.cacheResponseMetadata = shouldCache;
2256 }
2257
2258 /**
2259 * Sets whether or not to cache response metadata.
2260 * <p>
2261 * Response metadata is typically used for troubleshooting issues with AWS support staff when
2262 * services aren't acting as expected.
2263 * </p>
2264 * <p>
2265 * While this feature is useful for debugging it adds overhead and disabling it may
2266 * be desired in high throughput applications.
2267 * </p>
2268 *
2269 * @param shouldCache true if response metadata should be cached
2270 * @return The updated ClientConfiguration object.
2271 */
2272 public ClientConfiguration withCacheResponseMetadata(final boolean shouldCache) {
2273 setCacheResponseMetadata(shouldCache);
2274 return this;
2275 }
2276
2277 /**
2278 * Returns the response metadata cache size.
2279 */
2280 public int getResponseMetadataCacheSize() {
2281 return responseMetadataCacheSize;
2282 }
2283
2284 /**
2285 * Sets the response metadata cache size. By default, it is set to
2286 * {@value #DEFAULT_RESPONSE_METADATA_CACHE_SIZE}.
2287 *
2288 * @param responseMetadataCacheSize
2289 * maximum cache size.
2290 */
2291 public void setResponseMetadataCacheSize(int responseMetadataCacheSize) {
2292 this.responseMetadataCacheSize = responseMetadataCacheSize;
2293 }
2294
2295 /**
2296 * Sets the response metadata cache size. By default, it is set to
2297 * {@value #DEFAULT_RESPONSE_METADATA_CACHE_SIZE}.
2298 *
2299 * @param responseMetadataCacheSize
2300 * maximum cache size.
2301 * @return The updated ClientConfiguration object.
2302 */
2303 public ClientConfiguration withResponseMetadataCacheSize(int responseMetadataCacheSize) {
2304 setResponseMetadataCacheSize(responseMetadataCacheSize);
2305 return this;
2306 }
2307
2308 /**
2309 * Returns a non-null object that can be used to specify Apache HTTP client specific custom
2310 * configurations.
2311 */
2312 public ApacheHttpClientConfig getApacheHttpClientConfig() {
2313 return apacheHttpClientConfig;
2314 }
2315
2316 /**
2317 * Returns the instance of {@link SecureRandom} configured by the user; or the JDK default if it
2318 * is null.
2319 *
2320 * @return a non-null instance of SecureRandom.
2321 */
2322 public SecureRandom getSecureRandom() {
2323 if (secureRandom == null)
2324 secureRandom = new SecureRandom();
2325 return secureRandom;
2326 }
2327
2328 /**
2329 * Sets an instance of {@link SecureRandom} to be used by the SDK.
2330 */
2331 public void setSecureRandom(SecureRandom secureRandom) {
2332 this.secureRandom = secureRandom;
2333 }
2334
2335 /**
2336 * Fluent API for {@link #setSecureRandom(SecureRandom)}.
2337 */
2338 public ClientConfiguration withSecureRandom(SecureRandom secureRandom) {
2339 setSecureRandom(secureRandom);
2340 return this;
2341 }
2342
2343 /**
2344 * Returns the use expect continue flag
2345 */
2346 public boolean isUseExpectContinue() {
2347 return useExpectContinue;
2348 }
2349
2350 /**
2351 * Sets if use expect continue should be enabled. By default, it is set to
2352 * {@value #DEFAULT_USE_EXPECT_CONTINUE}.
2353 *
2354 * @param useExpectContinue
2355 * use expect continue HTTP/1.1 header.
2356 */
2357 public void setUseExpectContinue(boolean useExpectContinue) {
2358 this.useExpectContinue = useExpectContinue;
2359 }
2360
2361 /**
2362 * Sets if use expect continue should be enabled. By default, it is set to
2363 * {@value #DEFAULT_USE_EXPECT_CONTINUE}.
2364 *
2365 * @param useExpectContinue
2366 * use expect continue HTTP/1.1 header.
2367 * @return The updated ClientConfiguration object.
2368 */
2369 public ClientConfiguration withUseExpectContinue(boolean useExpectContinue) {
2370 setUseExpectContinue(useExpectContinue);
2371
2372 return this;
2373 }
2374
2375 /**
2376 * Adds a header to be added on all requests and returns the {@link ClientConfiguration} object
2377 *
2378 * @param name
2379 * the name of the header
2380 * @param value
2381 * the value of the header
2382 *
2383 * @return The updated ClientConfiguration object.
2384 */
2385 public ClientConfiguration withHeader(String name, String value) {
2386 addHeader(name, value);
2387 return this;
2388 }
2389
2390 /**
2391 * Adds a header to be added on all requests
2392 *
2393 * @param name
2394 * the name of the header
2395 * @param value
2396 * the value of the header
2397 */
2398 public void addHeader(String name, String value) {
2399 headers.put(name, value);
2400 }
2401
2402 /**
2403 * Returns headers to be added to all requests
2404 *
2405 * @return headers to be added to all requests
2406 */
2407 public Map<String, String> getHeaders() {
2408 return Collections.unmodifiableMap(headers);
2409 }
2410
2411 /**
2412 * Returns the boolean value to indicate if the host prefix injection is disabled or not.
2413 *
2414 * The hostPrefix template is specified in the service model and is used by the SDK to modify the endpoint
2415 * the request is sent to. Host prefix injection is enabled by default. This option can be set to disable the behavior.
2416 */
2417 public boolean isDisableHostPrefixInjection() {
2418 return disableHostPrefixInjection;
2419 }
2420
2421 /**
2422 * Sets the configuration option to disable the host prefix injection.
2423 *
2424 * The hostPrefix template is specified in the service model and is used by the SDK to modify the endpoint
2425 * the request is sent to. Host prefix injection is enabled by default. This option can be set to disable the behavior.
2426 */
2427 public void setDisableHostPrefixInjection(boolean disableHostPrefixInjection) {
2428 this.disableHostPrefixInjection = disableHostPrefixInjection;
2429 }
2430
2431 /**
2432 * Sets the configuration option to disable the host prefix injection.
2433 *
2434 * The hostPrefix template is specified in the service model and is used by the SDK to modify the endpoint
2435 * the request is sent to. Host prefix injection is enabled by default. This option can be set to disable the behavior.
2436 */
2437 public ClientConfiguration withDisableHostPrefixInjection(boolean disableHostPrefixInjection) {
2438 setDisableHostPrefixInjection(disableHostPrefixInjection);
2439 return this;
2440 }
2441
2442 /**
2443 * @return {@link TlsKeyManagersProvider} that will provide the {@link javax.net.ssl.KeyManager}s to use when
2444 * constructing the client's SSL context.
2445 * <p>
2446 * The default is {@link SystemPropertyTlsKeyManagersProvider}.
2447 */
2448 public TlsKeyManagersProvider getTlsKeyManagersProvider() {
2449 return tlsKeyManagersProvider;
2450 }
2451
2452 /**
2453 * Sets {@link TlsKeyManagersProvider} that will provide the {@link javax.net.ssl.KeyManager}s to use when
2454 * constructing the client's SSL context.
2455 * <p>
2456 * The default is {@link SystemPropertyTlsKeyManagersProvider}.
2457 */
2458 public ClientConfiguration withTlsKeyManagersProvider(TlsKeyManagersProvider tlsKeyManagersProvider) {
2459 this.tlsKeyManagersProvider = tlsKeyManagersProvider;
2460 return this;
2461 }
2462
2463 /**
2464 * Sets {@link TlsKeyManagersProvider} that will provide the {@link javax.net.ssl.KeyManager}s to use when
2465 * constructing the client's SSL context.
2466 * <p>
2467 * The default used by the client will be {@link SystemPropertyTlsKeyManagersProvider}. Set an instance {@link
2468 * com.amazonaws.http.NoneTlsKeyManagersProvider} or another instance of {@link TlsKeyManagersProvider} to override
2469 * it.
2470 */
2471 public void setTlsKeyManagersProvider(TlsKeyManagersProvider tlsKeyManagersProvider) {
2472 withTlsKeyManagersProvider(tlsKeyManagersProvider);
2473 }
2474
2475 private URL getHttpProxyEnvironmentVariable() {
2476 if (getProtocol() == Protocol.HTTP) {
2477 return getUrlEnvVar(httpProxyHolder, "HTTP_PROXY");
2478 }
2479 return getUrlEnvVar(httpsProxyHolder, "HTTPS_PROXY");
2480 }
2481
2482 private URL getUrlEnvVar(AtomicReference<URLHolder> cache, String name) {
2483 if (cache.get() == null) {
2484 URLHolder holder = new URLHolder();
2485 String value = getEnvironmentVariableCaseInsensitive(name);
2486 if (value != null) {
2487 try {
2488 holder.url = new URL(value);
2489 } catch (MalformedURLException e) {
2490 if (log.isWarnEnabled()) {
2491 log.warn(String.format("Unable to parse %s environment variable value '%s' as URL. It is " +
2492 "malformed.", name, value), e);
2493 }
2494 }
2495 }
2496 cache.compareAndSet(null, holder);
2497 }
2498 return cache.get().url;
2499 }
2500
2501 static class URLHolder {
2502 private URL url;
2503 }
2504 }
2505