public class AmazonHttpClient
extends java.lang.Object
Modifier and Type | Class and Description |
---|---|
private static class |
AmazonHttpClient.ExecOneRequestParams
Stateful parameters that are used for executing a single httpClientSettings request.
|
Modifier and Type | Field and Description |
---|---|
private ClientExecutionTimer |
clientExecutionTimer
Timer to enforce timeouts on the whole execution of the request (request handlers, retries, backoff strategy,
unmarshalling, etc)
|
private ClientConfiguration |
config
Client configuration options, such as proxy httpClientSettings, max retries, etc.
|
static java.lang.String |
HEADER_SDK_RETRY_INFO |
static java.lang.String |
HEADER_SDK_TRANSACTION_ID |
static java.lang.String |
HEADER_USER_AGENT |
private ConnectionManagerAwareHttpClient |
httpClient
Internal client for sending HTTP requests
|
private static HttpClientFactory<ConnectionManagerAwareHttpClient> |
httpClientFactory |
private HttpClientSettings |
httpClientSettings
Client configuration options, such as proxy httpClientSettings, max retries, etc.
|
private HttpRequestFactory<org.apache.http.client.methods.HttpRequestBase> |
httpRequestFactory |
private HttpRequestTimer |
httpRequestTimer
Timer to enforce HTTP request timeouts.
|
(package private) static org.apache.commons.logging.Log |
log
Logger for more detailed debugging information, that might not be as useful for end users (ex: HTTP client
configuration, etc).
|
private static org.apache.commons.logging.Log |
requestIdLog
Logger used for the purpose of logging the AWS request id extracted either from the httpClientSettings header response or from
the response body.
|
private static org.apache.commons.logging.Log |
requestLog
Logger providing detailed information on requests/responses.
|
private RequestMetricCollector |
requestMetricCollector
A request metric collector used specifically for this httpClientSettings client; or null if there is none.
|
private ResponseMetadataCache |
responseMetadataCache
Cache of metadata for recently executed requests for diagnostic purposes
|
private CapacityManager |
retryCapacity
Retry capacity manager, used to manage throttled retry resource
|
private static int |
THROTTLED_RETRIES
When throttled retries are enabled, this is the total number of subsequent failed retries
that may be attempted before retry capacity is fully drained.
|
private static int |
THROTTLED_RETRY_COST
When throttled retries are enabled, each retry attempt will consume this much capacity.
|
private int |
timeOffset
The time difference in seconds between this client and AWS.
|
private static UnreliableTestConfig |
unreliableTestConfig
Used for testing via failure injection.
|
Modifier | Constructor and Description |
---|---|
|
AmazonHttpClient(ClientConfiguration config)
Constructs a new AWS client using the specified client configuration options (ex: max retry attempts, proxy
httpClientSettings, etc).
|
|
AmazonHttpClient(ClientConfiguration clientConfig,
ConnectionManagerAwareHttpClient httpClient,
RequestMetricCollector requestMetricCollector)
Package-protected constructor for unit test purposes.
|
|
AmazonHttpClient(ClientConfiguration config,
RequestMetricCollector requestMetricCollector)
Constructs a new AWS client using the specified client configuration options (ex: max retry attempts, proxy
httpClientSettings, etc), and request metric collector.
|
|
AmazonHttpClient(ClientConfiguration config,
RequestMetricCollector requestMetricCollector,
boolean useBrowserCompatibleHostNameVerifier)
Constructs a new AWS client using the specified client configuration options (ex: max retry attempts, proxy
httpClientSettings, etc), and request metric collector.
|
private |
AmazonHttpClient(ClientConfiguration clientConfig,
RequestMetricCollector requestMetricCollector,
HttpClientSettings httpClientSettings) |
Modifier and Type | Method and Description |
---|---|
private void |
afterError(Request<?> request,
Response<?> response,
java.util.List<RequestHandler2> requestHandler2s,
AmazonClientException e) |
private <T> void |
afterResponse(Request<?> request,
java.util.List<RequestHandler2> requestHandler2s,
Response<T> response,
TimingInfo timingInfo) |
private java.io.InputStream |
beforeRequest(Request<?> request)
Publishes the "request content length" event, and returns an input stream, which will be made mark-and-resettable
if possible, for progress tracking purposes.
|
private HttpResponse |
beforeUnmarshalling(java.util.List<RequestHandler2> requestHandler2s,
Request<?> request,
HttpResponse origHttpResponse)
|
private void |
captureConnectionPoolMetrics(AWSRequestMetrics awsRequestMetrics)
Captures the connection pool metrics.
|
private <T extends java.lang.Throwable> |
captureExceptionMetrics(T t,
AWSRequestMetrics awsRequestMetrics)
Capture the metrics for the given throwable.
|
private void |
checkInterrupted()
Check if the thread has been interrupted.
|
private void |
checkInterrupted(Response<?> response)
Check if the thread has been interrupted.
|
(package private) static void |
configUnreliableTestConditions(UnreliableTestConfig config)
Used to configure the test conditions for injecting intermittent failures to the content input stream.
|
private HttpResponse |
createResponse(org.apache.http.client.methods.HttpRequestBase method,
Request<?> request,
org.apache.http.HttpResponse apacheHttpResponse)
Creates and initializes an HttpResponse object suitable to be passed to an HTTP response handler object.
|
private static java.lang.String |
createUserAgentString(java.lang.String existingUserAgentString,
java.lang.String userAgent)
Appends the given user-agent string to the existing one and returns it.
|
private <T> Response<T> |
doExecute(Request<?> request,
HttpResponseHandler<AmazonWebServiceResponse<T>> responseHandler,
HttpResponseHandler<AmazonServiceException> errorResponseHandler,
ExecutionContext executionContext) |
private void |
doPauseBeforeRetry(AmazonWebServiceRequest originalRequest,
AmazonClientException previousException,
int requestCount,
RetryPolicy retryPolicy,
AmazonHttpClient.ExecOneRequestParams execOneParams)
Sleep for a period of time on failed request to avoid flooding a service with retries.
|
<T> Response<T> |
execute(Request<?> request,
HttpResponseHandler<AmazonWebServiceResponse<T>> responseHandler,
HttpResponseHandler<AmazonServiceException> errorResponseHandler,
ExecutionContext executionContext)
Executes the request and returns the result.
|
private <T> Response<T> |
executeHelper(Request<?> request,
HttpResponseHandler<AmazonWebServiceResponse<T>> responseHandler,
HttpResponseHandler<AmazonServiceException> errorResponseHandler,
ExecutionContext executionContext,
java.util.List<RequestHandler2> requestHandlers)
Internal method to execute the HTTP method given.
|
private <T> Response<T> |
executeOneRequest(Request<?> request,
HttpResponseHandler<AmazonWebServiceResponse<T>> responseHandler,
HttpResponseHandler<AmazonServiceException> errorResponseHandler,
ExecutionContext execContext,
AWSRequestMetrics awsRequestMetrics,
AmazonHttpClient.ExecOneRequestParams execOneParams,
java.util.List<RequestHandler2> requestHandlers)
Returns the response from executing one httpClientSettings request; or null for retry.
|
<T> Response<T> |
executeWithTimer(Request<?> request,
HttpResponseHandler<AmazonWebServiceResponse<T>> responseHandler,
HttpResponseHandler<AmazonServiceException> errorResponseHandler,
ExecutionContext executionContext)
Start and end client execution timer around the execution of the request.
|
protected void |
finalize() |
private int |
getClientExecutionTimeout(AmazonWebServiceRequest request)
Gets the correct client execution timeout taking into account precedence of the configuration in
AmazonWebServiceRequest versus ClientConfiguration |
ClientExecutionTimer |
getClientExecutionTimer()
Package protected for unit-testing
|
private AWSCredentials |
getCredentialsFromContext(ExecutionContext executionContext,
AWSRequestMetrics requestMetrics)
Returns the credentials from the execution if exists.
|
HttpRequestTimer |
getHttpRequestTimer()
Package protected for unit-testing
|
private <T> HttpResponseHandler<T> |
getNonNullResponseHandler(HttpResponseHandler<T> responseHandler)
Ensures the response handler is not null.
|
RequestMetricCollector |
getRequestMetricCollector()
Returns the httpClientSettings client specific request metric collector; or null if there is none.
|
private int |
getRequestTimeout(AmazonWebServiceRequest request)
Gets the correct request timeout taking into account precedence of the configuration in
AmazonWebServiceRequest versus ClientConfiguration |
ResponseMetadata |
getResponseMetadataForRequest(AmazonWebServiceRequest request)
Returns additional response metadata for an executed request.
|
private java.lang.String |
getServerDateFromException(java.lang.String body)
Returns date string from the exception message body in form of yyyyMMdd'T'HHmmss'Z' We needed to extract date
from the message body because SQS is the only service that does not provide date header in the response.
|
int |
getTimeOffset()
Returns the time difference in seconds between this client and AWS.
|
private AmazonServiceException |
handleErrorResponse(Request<?> request,
HttpResponseHandler<AmazonServiceException> errorResponseHandler,
org.apache.http.client.methods.HttpRequestBase method,
org.apache.http.HttpResponse apacheHttpResponse)
Responsible for handling an error response, including unmarshalling the error response into the most specific
exception type possible, and throwing the exception.
|
private java.lang.RuntimeException |
handleInterruptedException(ExecutionContext executionContext,
java.lang.InterruptedException e)
Determine if an interrupted exception is caused by the client execution timer interrupting the current thread or
some other task interrupting the thread for another purpose.
|
private <T> T |
handleResponse(Request<?> request,
HttpResponseHandler<AmazonWebServiceResponse<T>> responseHandler,
org.apache.http.client.methods.HttpRequestBase method,
HttpResponse httpResponse,
org.apache.http.HttpResponse apacheHttpResponse,
ExecutionContext executionContext,
boolean isHeaderReqIdAvail,
java.util.List<RequestHandler2> requestHandlers)
Handles a successful response from a service call by unmarshalling the results using the specified response
handler.
|
private boolean |
isRequestSuccessful(org.apache.http.HttpResponse response) |
private static boolean |
isTemporaryRedirect(org.apache.http.HttpResponse response) |
private <T extends java.lang.Throwable> |
lastReset(T t,
Request<?> req)
Used to perform a last reset on the content input stream (if mark-supported); this is so that, for backward
compatibility reason, any "blind" retry (ie without calling reset) by user of this library with the same input
stream (such as ByteArrayInputStream) could still succeed.
|
private boolean |
logHeaderRequestId(org.apache.http.HttpResponse res)
Used to log the "x-amzn-RequestId" header at DEBUG level, if any, from the response.
|
private void |
logResponseRequestId(java.lang.String awsRequestId)
Used to log the request id (extracted from the response) at DEBUG level.
|
private void |
mergeQueryParameters(Request<?> request,
java.util.Map<java.lang.String,java.util.List<java.lang.String>> params)
Merge query parameters into the given request.
|
private int |
parseClockSkewOffset(org.apache.http.HttpResponse response,
AmazonServiceException exception)
Returns the difference between the client's clock time and the service clock time in unit of seconds.
|
private void |
pauseBeforeRetry(Request<?> request,
AWSRequestMetrics awsRequestMetrics,
AmazonHttpClient.ExecOneRequestParams execOneParams,
ProgressListener listener)
Pause before the next retry and record metrics around retry behavior.
|
private java.util.List<RequestHandler2> |
requestHandler2s(Request<?> request,
ExecutionContext executionContext) |
private void |
resetRequestInputStream(Request<?> request)
Reset the input stream of the request before a retry.
|
private void |
setSdkTransactionId(Request<?> request)
Create a client side identifier that will be sent with the initial request and each retry.
|
private void |
setUserAgent(Request<?> request)
Sets a User-Agent for the specified request, taking into account any custom data.
|
private boolean |
shouldBufferHttpEntity(boolean needsConnectionLeftOpen,
ExecutionContext execContext,
AmazonHttpClient.ExecOneRequestParams execParams,
HttpRequestAbortTaskTracker requestAbortTaskTracker) |
private boolean |
shouldRetry(AmazonWebServiceRequest originalRequest,
AmazonHttpClient.ExecOneRequestParams params,
AmazonClientException exception,
ExecutionContext executionContext)
Returns true if a failed request should be retried.
|
void |
shutdown()
Shuts down this HTTP client object, releasing any resources that might be held open.
|
private void |
updateRetryHeaderInfo(Request<?> request,
AmazonHttpClient.ExecOneRequestParams execOneRequestParams)
Adds Retry information to the
HEADER_SDK_RETRY_INFO header. |
public static final java.lang.String HEADER_USER_AGENT
public static final java.lang.String HEADER_SDK_TRANSACTION_ID
public static final java.lang.String HEADER_SDK_RETRY_INFO
static final org.apache.commons.logging.Log log
private static final org.apache.commons.logging.Log requestIdLog
private static final org.apache.commons.logging.Log requestLog
private static final HttpClientFactory<ConnectionManagerAwareHttpClient> httpClientFactory
private static UnreliableTestConfig unreliableTestConfig
private static final int THROTTLED_RETRY_COST
private static final int THROTTLED_RETRIES
private final HttpRequestFactory<org.apache.http.client.methods.HttpRequestBase> httpRequestFactory
private ConnectionManagerAwareHttpClient httpClient
private final ClientConfiguration config
private final HttpClientSettings httpClientSettings
private final ResponseMetadataCache responseMetadataCache
private final HttpRequestTimer httpRequestTimer
private final CapacityManager retryCapacity
private final ClientExecutionTimer clientExecutionTimer
private final RequestMetricCollector requestMetricCollector
AwsSdkMetrics
private volatile int timeOffset
public AmazonHttpClient(ClientConfiguration config)
config
- Configuration options specifying how this client will communicate with AWS (ex: proxy httpClientSettings,
retry count, etc.).public AmazonHttpClient(ClientConfiguration config, RequestMetricCollector requestMetricCollector)
config
- Configuration options specifying how this client will communicate with AWS (ex:
proxy httpClientSettings, retry count, etc.).requestMetricCollector
- client specific request metric collector, which takes precedence over the one at
the AWS SDK level; or null if there is none.public AmazonHttpClient(ClientConfiguration config, RequestMetricCollector requestMetricCollector, boolean useBrowserCompatibleHostNameVerifier)
config
- Configuration options specifying how this client will communicate with AWS (ex:
proxy httpClientSettings, retry count, etc.).requestMetricCollector
- client specific request metric collector, which takes precedence over the one at
the AWS SDK level; or null if there is none.public AmazonHttpClient(ClientConfiguration clientConfig, ConnectionManagerAwareHttpClient httpClient, RequestMetricCollector requestMetricCollector)
private AmazonHttpClient(ClientConfiguration clientConfig, RequestMetricCollector requestMetricCollector, HttpClientSettings httpClientSettings)
private static java.lang.String createUserAgentString(java.lang.String existingUserAgentString, java.lang.String userAgent)
private static boolean isTemporaryRedirect(org.apache.http.HttpResponse response)
static void configUnreliableTestConditions(UnreliableTestConfig config)
config
- unreliable test configuration for failure injection; or null to disable such test.public HttpRequestTimer getHttpRequestTimer()
public ClientExecutionTimer getClientExecutionTimer()
public ResponseMetadata getResponseMetadataForRequest(AmazonWebServiceRequest request)
request
- A previously executed AmazonWebServiceRequest object, whose response metadata is desired.public <T> Response<T> execute(Request<?> request, HttpResponseHandler<AmazonWebServiceResponse<T>> responseHandler, HttpResponseHandler<AmazonServiceException> errorResponseHandler, ExecutionContext executionContext)
request
- The AmazonWebServices request to send to the remote serverresponseHandler
- A response handler to accept a successful response from the remote servererrorResponseHandler
- A response handler to accept an unsuccessful response from the remote serverexecutionContext
- Additional information about the context of this web service callprivate <T> HttpResponseHandler<T> getNonNullResponseHandler(HttpResponseHandler<T> responseHandler)
responseHandler
- Response handler passed to execute(Request, HttpResponseHandler,
HttpResponseHandler, ExecutionContext)
public <T> Response<T> executeWithTimer(Request<?> request, HttpResponseHandler<AmazonWebServiceResponse<T>> responseHandler, HttpResponseHandler<AmazonServiceException> errorResponseHandler, ExecutionContext executionContext) throws java.lang.InterruptedException
execute(Request,
HttpResponseHandler, HttpResponseHandler, ExecutionContext)
so the interrupt status doesn't leak out to the
callers codejava.lang.InterruptedException
private <T> Response<T> doExecute(Request<?> request, HttpResponseHandler<AmazonWebServiceResponse<T>> responseHandler, HttpResponseHandler<AmazonServiceException> errorResponseHandler, ExecutionContext executionContext) throws java.lang.InterruptedException
java.lang.InterruptedException
private java.lang.RuntimeException handleInterruptedException(ExecutionContext executionContext, java.lang.InterruptedException e)
executionContext
- e
- ClientExecutionTimeoutException
if the InterruptedException
was caused by the ClientExecutionTimer
. Otherwise re-interrupts the current thread and returns an AmazonClientException
wrapping an InterruptedException
private void checkInterrupted() throws java.lang.InterruptedException
InterruptedException
. Long running tasks should
be periodically checked if the current thread has been interrupted and handle it appropriatelyjava.lang.InterruptedException
- If thread has been interruptedprivate void checkInterrupted(Response<?> response) throws java.lang.InterruptedException
InterruptedException
. Long running tasks should
be periodically checked if the current thread has been interrupted and handle it appropriatelyresponse
- Response to be closed before returning control to the caller to avoid leaking the connection.java.lang.InterruptedException
- If thread has been interruptedprivate void mergeQueryParameters(Request<?> request, java.util.Map<java.lang.String,java.util.List<java.lang.String>> params)
private java.io.InputStream beforeRequest(Request<?> request)
private void afterError(Request<?> request, Response<?> response, java.util.List<RequestHandler2> requestHandler2s, AmazonClientException e) throws java.lang.InterruptedException
java.lang.InterruptedException
private <T> void afterResponse(Request<?> request, java.util.List<RequestHandler2> requestHandler2s, Response<T> response, TimingInfo timingInfo) throws java.lang.InterruptedException
java.lang.InterruptedException
private java.util.List<RequestHandler2> requestHandler2s(Request<?> request, ExecutionContext executionContext)
private <T> Response<T> executeHelper(Request<?> request, HttpResponseHandler<AmazonWebServiceResponse<T>> responseHandler, HttpResponseHandler<AmazonServiceException> errorResponseHandler, ExecutionContext executionContext, java.util.List<RequestHandler2> requestHandlers) throws java.lang.InterruptedException
java.lang.InterruptedException
private <T extends java.lang.Throwable> T lastReset(T t, Request<?> req)
t
- the failurereq
- the request, if known; or null otherwise.private AWSCredentials getCredentialsFromContext(ExecutionContext executionContext, AWSRequestMetrics requestMetrics)
private <T> Response<T> executeOneRequest(Request<?> request, HttpResponseHandler<AmazonWebServiceResponse<T>> responseHandler, HttpResponseHandler<AmazonServiceException> errorResponseHandler, ExecutionContext execContext, AWSRequestMetrics awsRequestMetrics, AmazonHttpClient.ExecOneRequestParams execOneParams, java.util.List<RequestHandler2> requestHandlers) throws java.io.IOException, java.lang.InterruptedException
java.io.IOException
java.lang.InterruptedException
private void resetRequestInputStream(Request<?> request) throws ResetException
request
- Request containing input stream to resetResetException
- If Input Stream can't be reset which means the request can't be retriedprivate boolean shouldBufferHttpEntity(boolean needsConnectionLeftOpen, ExecutionContext execContext, AmazonHttpClient.ExecOneRequestParams execParams, HttpRequestAbortTaskTracker requestAbortTaskTracker)
HttpEntity
should be wrapped in a BufferedHttpEntity
private boolean logHeaderRequestId(org.apache.http.HttpResponse res)
private void logResponseRequestId(java.lang.String awsRequestId)
private void captureConnectionPoolMetrics(AWSRequestMetrics awsRequestMetrics)
private <T extends java.lang.Throwable> T captureExceptionMetrics(T t, AWSRequestMetrics awsRequestMetrics)
private void setSdkTransactionId(Request<?> request)
private void setUserAgent(Request<?> request)
private void updateRetryHeaderInfo(Request<?> request, AmazonHttpClient.ExecOneRequestParams execOneRequestParams)
HEADER_SDK_RETRY_INFO
header. Used for analysis of retry policy.request
- Request to add header toexecOneRequestParams
- Request context containing retry informationpublic void shutdown()
private boolean shouldRetry(AmazonWebServiceRequest originalRequest, AmazonHttpClient.ExecOneRequestParams params, AmazonClientException exception, ExecutionContext executionContext)
originalRequest
- The original service request that is being executed.params
- Params for the individual request being executed.exception
- The client/service exception from the failed request.executionContext
- The execution context for the request being executed.private boolean isRequestSuccessful(org.apache.http.HttpResponse response)
private <T> T handleResponse(Request<?> request, HttpResponseHandler<AmazonWebServiceResponse<T>> responseHandler, org.apache.http.client.methods.HttpRequestBase method, HttpResponse httpResponse, org.apache.http.HttpResponse apacheHttpResponse, ExecutionContext executionContext, boolean isHeaderReqIdAvail, java.util.List<RequestHandler2> requestHandlers) throws java.io.IOException, java.lang.InterruptedException
T
- The type of object expected in the response.request
- The original request that generated the response being handled.responseHandler
- The response unmarshaller used to interpret the contents of the response.method
- The HTTP method that was invoked, and contains the contents of the response.executionContext
- Extra state information about the request currently being executed.isHeaderReqIdAvail
- true if the AWS request id is available from the httpClientSettings response header; false
otherwise.java.io.IOException
- If any problems were encountered reading the response contents from the HTTP method object.java.lang.InterruptedException
private HttpResponse beforeUnmarshalling(java.util.List<RequestHandler2> requestHandler2s, Request<?> request, HttpResponse origHttpResponse)
requestHandler2s
- List of request handlers to invokerequest
- Original requestorigHttpResponse
- Original HttpResponse
HttpResponse
object to pass to unmarshaller. May have been modified or replaced by the request
handlersprivate AmazonServiceException handleErrorResponse(Request<?> request, HttpResponseHandler<AmazonServiceException> errorResponseHandler, org.apache.http.client.methods.HttpRequestBase method, org.apache.http.HttpResponse apacheHttpResponse) throws java.io.IOException, java.lang.InterruptedException
request
- The request that generated the error response being handled.errorResponseHandler
- The response handler responsible for unmarshalling the error response.method
- The HTTP method containing the actual response content.java.io.IOException
- If any problems are encountering reading the error response.java.lang.InterruptedException
private HttpResponse createResponse(org.apache.http.client.methods.HttpRequestBase method, Request<?> request, org.apache.http.HttpResponse apacheHttpResponse) throws java.io.IOException
method
- The HTTP method that was invoked to get the response.request
- The HTTP request associated with the response.java.io.IOException
- If there were any problems getting any response information from the HttpClient method
object.private void pauseBeforeRetry(Request<?> request, AWSRequestMetrics awsRequestMetrics, AmazonHttpClient.ExecOneRequestParams execOneParams, ProgressListener listener) throws java.lang.InterruptedException
java.lang.InterruptedException
private void doPauseBeforeRetry(AmazonWebServiceRequest originalRequest, AmazonClientException previousException, int requestCount, RetryPolicy retryPolicy, AmazonHttpClient.ExecOneRequestParams execOneParams) throws java.lang.InterruptedException
originalRequest
- The original service request that is being executed.previousException
- Exception information for the previous attempt, if any.requestCount
- current request count (including the next attempt after the delay)retryPolicy
- The retry policy configured in this httpClientSettings client.java.lang.InterruptedException
private java.lang.String getServerDateFromException(java.lang.String body)
body
- The message from where the server time is being extractedprivate int parseClockSkewOffset(org.apache.http.HttpResponse response, AmazonServiceException exception)
protected void finalize() throws java.lang.Throwable
finalize
in class java.lang.Object
java.lang.Throwable
public RequestMetricCollector getRequestMetricCollector()
public int getTimeOffset()
private int getRequestTimeout(AmazonWebServiceRequest request)
AmazonWebServiceRequest
versus ClientConfiguration
request
- Current requestprivate int getClientExecutionTimeout(AmazonWebServiceRequest request)
AmazonWebServiceRequest
versus ClientConfiguration
request
- Current request