private void populateAndEndSubsegment(Subsegment currentSubsegment, Request<?> request, Response<?> response) { if (null != response) { String requestId = null; if (response.getAwsResponse() instanceof AmazonWebServiceResult<?>) { // Not all services return responses extending AmazonWebServiceResult (e.g. S3) ResponseMetadata metadata = ((AmazonWebServiceResult<?>) response.getAwsResponse()).getSdkResponseMetadata(); if (null != metadata) { requestId = metadata.getRequestId(); if (null != requestId) { currentSubsegment.putAws(REQUEST_ID_SUBSEGMENT_KEY, requestId); } } } else if (null != response.getHttpResponse()) { // S3 does not follow request id header convention if (null != response.getHttpResponse().getHeader(S3_REQUEST_ID_HEADER_KEY)) { currentSubsegment.putAws(REQUEST_ID_SUBSEGMENT_KEY, response.getHttpResponse().getHeader(S3_REQUEST_ID_HEADER_KEY)); } if (null != response.getHttpResponse().getHeader(S3_EXTENDED_REQUEST_ID_HEADER_KEY)) { currentSubsegment.putAws(EXTENDED_REQUEST_ID_SUBSEGMENT_KEY, response.getHttpResponse().getHeader(S3_EXTENDED_REQUEST_ID_HEADER_KEY)); } } currentSubsegment.putAllAws(extractResponseParameters(request, response.getAwsResponse())); currentSubsegment.putAllHttp(extractHttpResponseInformation(response.getHttpResponse())); } finalizeSubsegment(request); }
private void populateAndEndSubsegment(Subsegment currentSubsegment, Request<?> request, Response<?> response, AmazonServiceException ase) { if (null != response) { populateAndEndSubsegment(currentSubsegment, request, response); return; } else if (null != ase) { if (null != ase.getRequestId()) { currentSubsegment.putAws(REQUEST_ID_SUBSEGMENT_KEY, ase.getRequestId()); } if (null != ase.getHttpHeaders() && null != ase.getHttpHeaders().get(S3_EXTENDED_REQUEST_ID_HEADER_KEY)) { currentSubsegment.putAws(EXTENDED_REQUEST_ID_SUBSEGMENT_KEY, ase.getHttpHeaders().get(S3_EXTENDED_REQUEST_ID_HEADER_KEY)); } if (null != ase.getErrorMessage()) { currentSubsegment.getCause().setMessage(ase.getErrorMessage()); } currentSubsegment.putAllHttp(extractHttpResponseInformation(ase)); } finalizeSubsegment(request); }
/** * Executes the request and returns the result. * * @param request The AmazonWebServices request to send to the remote server * @param responseHandler A response handler to accept a successful response from the * remote server * @param errorResponseHandler A response handler to accept an unsuccessful response from the * remote server * @param executionContext Additional information about the context of this web service * call * @deprecated Use {@link #requestExecutionBuilder()} to configure and execute a HTTP request. */ @Deprecated public <T> Response<T> execute(Request<?> request, HttpResponseHandler<AmazonWebServiceResponse<T>> responseHandler, HttpResponseHandler<AmazonServiceException> errorResponseHandler, ExecutionContext executionContext) { HttpResponseHandler<T> adaptedRespHandler = new AwsResponseHandlerAdapter<T>( getNonNullResponseHandler(responseHandler), request, executionContext.getAwsRequestMetrics(), responseMetadataCache); return requestExecutionBuilder() .request(request) .requestConfig(new AmazonWebServiceRequestAdapter(request.getOriginalRequest())) .errorResponseHandler(new AwsErrorResponseHandler(errorResponseHandler, executionContext.getAwsRequestMetrics())) .executionContext(executionContext) .execute(adaptedRespHandler); }
private void execRequest(String endpoint, int status) { AWSRequestMetrics metrics = new AWSRequestMetricsFullSupport(); metrics.addProperty(AWSRequestMetrics.Field.ServiceName, "AmazonCloudWatch"); metrics.addProperty(AWSRequestMetrics.Field.ServiceEndpoint, endpoint); metrics.addProperty(AWSRequestMetrics.Field.StatusCode, "" + status); if (status == 503) { metrics.addProperty(AWSRequestMetrics.Field.AWSErrorCode, "Throttled"); } String counterName = "BytesProcessed"; String timerName = "ClientExecuteTime"; metrics.setCounter(counterName, 12345); metrics.getTimingInfo().addSubMeasurement(timerName, TimingInfo.unmodifiableTimingInfo(100000L, 200000L)); Request<?> req = new DefaultRequest(new ListMetricsRequest(), "AmazonCloudWatch"); req.setAWSRequestMetrics(metrics); req.setEndpoint(URI.create(endpoint)); HttpResponse hr = new HttpResponse(req, new HttpPost(endpoint)); hr.setStatusCode(status); Response<?> resp = new Response<>(null, new HttpResponse(req, new HttpPost(endpoint))); collector.collectMetrics(req, resp); }
private <T> T invoke(HttpMethodName httpMethodName, String resourcePath, Object representation, HttpResponseHandler<AmazonWebServiceResponse<T>> responseHandler) throws AmazonClientException { ExecutionContext executionContext = createExecutionContext(); AWSRequestMetrics awsRequestMetrics = executionContext.getAwsRequestMetrics(); awsRequestMetrics.startEvent(AWSRequestMetrics.Field.RequestMarshallTime.name()); Request request = buildRequest(httpMethodName, resourcePath, representation); awsRequestMetrics.endEvent(AWSRequestMetrics.Field.RequestMarshallTime.name()); awsRequestMetrics.startEvent(AWSRequestMetrics.Field.CredentialsRequestTime.name()); AWSCredentials credentials = awsCredentialsProvider.getCredentials(); awsRequestMetrics.endEvent(AWSRequestMetrics.Field.CredentialsRequestTime.name()); executionContext.setCredentials(credentials); awsRequestMetrics.startEvent(AWSRequestMetrics.Field.ClientExecuteTime.name()); Response<T> response = client.execute(request, responseHandler, errorResponseHandler, executionContext); awsRequestMetrics.endEvent(AWSRequestMetrics.Field.ClientExecuteTime.name()); awsRequestMetrics.log(); return response.getAwsResponse(); }
@Override public void afterResponse(Request<?> request, Response<?> response) { if (isSubsegmentDuplicate(recorder.getCurrentSubsegmentOptional(), request)) { Optional<Subsegment> currentSubsegmentOptional = recorder.getCurrentSubsegmentOptional(); if (!currentSubsegmentOptional.isPresent()) { return; } Subsegment currentSubsegment = currentSubsegmentOptional.get(); populateAndEndSubsegment(currentSubsegment, request, response, null); } }
@Override public <Output> Response<Output> execute(HttpResponseHandler<Output> responseHandler) { RequestConfig config = requestConfig != null ? requestConfig : new AmazonWebServiceRequestAdapter(request.getOriginalRequest()); return new RequestExecutor<Output>(request, config, getNonNullResponseHandler(errorResponseHandler), getNonNullResponseHandler(responseHandler), executionContext, getRequestHandlers() ).execute(); }
/** * Executes the request and returns the result. */ private Response<Output> execute() { if (executionContext == null) { throw new SdkClientException( "Internal SDK Error: No execution context parameter specified."); } try { return executeWithTimer(); } catch (InterruptedException ie) { throw handleInterruptedException(ie); } catch (AbortedException ae) { throw handleAbortedException(ae); } }
/** * Start and end client execution timer around the execution of the request. It's important * that the client execution task is canceled before the InterruptedExecption is handled by * {@link #execute()} so * the interrupt status doesn't leak out to the callers code */ private Response<Output> executeWithTimer() throws InterruptedException { try { executionContext.setClientExecutionTrackerTask( clientExecutionTimer.startTimer(getClientExecutionTimeout(requestConfig))); return doExecute(); } finally { executionContext.getClientExecutionTrackerTask().cancelTask(); } }
private Response<Output> doExecute() throws InterruptedException { runBeforeRequestHandlers(); setSdkTransactionId(request); setUserAgent(request); ProgressListener listener = requestConfig.getProgressListener(); // add custom headers request.getHeaders().putAll(config.getHeaders()); request.getHeaders().putAll(requestConfig.getCustomRequestHeaders()); // add custom query parameters mergeQueryParameters(requestConfig.getCustomQueryParameters()); Response<Output> response = null; final InputStream origContent = request.getContent(); final InputStream toBeClosed = beforeRequest(); // for progress tracking // make "notCloseable", so reset would work with retries final InputStream notCloseable = (toBeClosed == null) ? null : ReleasableInputStream.wrap(toBeClosed).disableClose(); request.setContent(notCloseable); try { publishProgress(listener, ProgressEventType.CLIENT_REQUEST_STARTED_EVENT); response = executeHelper(); publishProgress(listener, ProgressEventType.CLIENT_REQUEST_SUCCESS_EVENT); awsRequestMetrics.getTimingInfo().endTiming(); afterResponse(response); return response; } catch (AmazonClientException e) { publishProgress(listener, ProgressEventType.CLIENT_REQUEST_FAILED_EVENT); afterError(response, e); throw e; } finally { // Always close so any progress tracking would get the final events propagated. closeQuietly(toBeClosed, log); request.setContent(origContent); // restore the original content } }
private void afterError(Response<?> response, AmazonClientException e) throws InterruptedException { for (RequestHandler2 handler2 : requestHandler2s) { handler2.afterError(request, response, e); checkInterrupted(response); } }
@Override public <Input, Output> Output execute( ClientExecutionParams<Input, Output> executionParams) { final Input input = executionParams.getInput(); ExecutionContext executionContext = createExecutionContext( executionParams.getRequestConfig()); AWSRequestMetrics awsRequestMetrics = executionContext.getAwsRequestMetrics(); awsRequestMetrics.startEvent(AWSRequestMetrics.Field.ClientExecuteTime); Request<Input> request = null; Response<Output> response = null; try { awsRequestMetrics.startEvent(AWSRequestMetrics.Field.RequestMarshallTime); try { request = executionParams.getMarshaller().marshall(input); request.setAWSRequestMetrics(awsRequestMetrics); } finally { awsRequestMetrics.endEvent(AWSRequestMetrics.Field.RequestMarshallTime); } response = invoke(request, executionParams.getRequestConfig(), executionContext, executionParams.getResponseHandler(), executionParams.getErrorResponseHandler()); return response.getAwsResponse(); } finally { endClientExecution(awsRequestMetrics, executionParams.getRequestConfig(), request, response); } }
/** * Normal invoke with authentication. Credentials are required and may be overriden at the * request level. **/ private <Output, Input> Response<Output> invoke(Request<Input> request, RequestConfig requestConfig, ExecutionContext executionContext, HttpResponseHandler<Output> responseHandler, HttpResponseHandler<? extends SdkBaseException> errorResponseHandler) { executionContext.setCredentialsProvider(CredentialUtils.getCredentialsProvider( requestConfig, awsCredentialsProvider)); return doInvoke(request, requestConfig, executionContext, responseHandler, errorResponseHandler); }
/** * Invoke the request using the http client. Assumes credentials (or lack thereof) have been * configured in the ExecutionContext beforehand. **/ private <Output, Input> Response<Output> doInvoke(Request<Input> request, RequestConfig requestConfig, ExecutionContext executionContext, HttpResponseHandler<Output> responseHandler, HttpResponseHandler<? extends SdkBaseException> errorResponseHandler) { request.setEndpoint(endpoint); return client.requestExecutionBuilder() .request(request) .requestConfig(requestConfig) .executionContext(executionContext) .errorResponseHandler(errorResponseHandler) .execute(responseHandler); }
/** * Convenient method to end the client execution without logging the awsRequestMetrics. */ private void endClientExecution(AWSRequestMetrics awsRequestMetrics, RequestConfig requestConfig, Request<?> request, Response<?> response) { if (request != null) { awsRequestMetrics.endEvent(AWSRequestMetrics.Field.ClientExecuteTime); awsRequestMetrics.getTimingInfo().endTiming(); RequestMetricCollector metricCollector = findRequestMetricCollector(requestConfig); metricCollector.collectMetrics(request, response); awsRequestMetrics.log(); } }
@SuppressWarnings("deprecation") @Override public void afterResponse(Request<?> request, Response<?> response) { AWSRequestMetrics awsRequestMetrics = request == null ? null : request .getAWSRequestMetrics(); Object awsResponse = response == null ? null : response .getAwsResponse(); TimingInfo timingInfo = awsRequestMetrics == null ? null : awsRequestMetrics.getTimingInfo(); old.afterResponse(request, awsResponse, timingInfo); }
@Before public void setup() { MockitoAnnotations.initMocks(this); stackedRequestHandler = new StackedRequestHandler(new ArrayList<RequestHandler2>()); response = new Response<String>("Dummy response", new HttpResponse(request, new HttpGet())); }
@Before public void setup() { MockitoAnnotations.initMocks(this); stackedRequestHandler = new StackedRequestHandler(only); response = new Response<String>("Dummy response", new HttpResponse(request, new HttpGet())); }
@Before public void setup() { MockitoAnnotations.initMocks(this); stackedRequestHandler = new StackedRequestHandler(first, second, third); response = new Response<String>("Dummy response", new HttpResponse(request, new HttpGet())); }
/** * Perform this request. */ @Override public T perform() { final Response<T> rsp = new AmazonHttpClient(new ClientConfiguration()) .requestExecutionBuilder() .executionContext(new ExecutionContext(true)) .request(this.request) .errorResponseHandler(this.errHandler) .execute(this.respHandler); return rsp.getAwsResponse(); }
@Override public void collectMetrics(Request<?> request, Response<?> response) { AWSRequestMetrics metrics = request.getAWSRequestMetrics(); TimingInfo timingInfo = metrics.getTimingInfo(); Number requestCounts = timingInfo.getCounter(Field.RequestCount.name()); Number retryCounts = timingInfo.getCounter(Field.HttpClientRetryCount.name()); Number throttleExceptions = timingInfo.getCounter(Field.ThrottleException.name()); TimingInfo requestTime = timingInfo.getSubMeasurement(Field.HttpRequestTime.name()); if (requestCounts != null) { stats.updateAwsRequestCount(requestCounts.longValue()); } if (retryCounts != null) { stats.updateAwsRetryCount(retryCounts.longValue()); } if (throttleExceptions != null) { stats.updateAwsThrottleExceptionsCount(throttleExceptions.longValue()); } if (requestTime != null && requestTime.getTimeTakenMillisIfKnown() != null) { stats.addAwsRequestTime(new Duration(requestTime.getTimeTakenMillisIfKnown(), MILLISECONDS)); } }
@Override public void collectMetrics(Request<?> request, Response<?> response) { final AWSRequestMetrics metrics = request.getAWSRequestMetrics(); if (metrics.isEnabled()) { final Map<String, String> baseTags = getBaseTags(request); final TimingInfo timing = metrics.getTimingInfo(); for (Field counter : COUNTERS) { Optional.ofNullable(timing.getCounter(counter.name())) .filter(v -> v.longValue() > 0) .ifPresent(v -> registry.counter(metricId(counter, baseTags)).increment(v.longValue())); } for (Field timer : TIMERS) { Optional.ofNullable(timing.getLastSubMeasurement(timer.name())) .filter(TimingInfo::isEndTimeKnown) .ifPresent(t -> registry.timer(metricId(timer, baseTags)) .record(t.getEndTimeNano() - t.getStartTimeNano(), TimeUnit.NANOSECONDS)); } notEmpty(metrics.getProperty(Field.ThrottleException)).ifPresent(throttleExceptions -> { final Id throttling = metricId("throttling", baseTags); throttleExceptions.forEach(ex -> registry.counter(throttling.withTag("throttleException", ex.getClass().getSimpleName())) .increment()); }); } }
@Override public CreateSpeechResult createSpeech(CreateSpeechRequest createSpeechRequest) throws AmazonServiceException, AmazonClientException { ExecutionContext executionContext = createExecutionContext(createSpeechRequest); Request<CreateSpeechRequest> request = CreateSpeechRequestMarshallerFactory.getMarshaller( createSpeechRequest.getMethodType()).marshall(createSpeechRequest); CreateSpeechResultUnmarshaller unmarshaller = new CreateSpeechResultUnmarshaller(); StreamResponseHandler<CreateSpeechResult> responseHandler = new StreamResponseHandler<CreateSpeechResult>(unmarshaller); Response<CreateSpeechResult> response = invoke(request, responseHandler, executionContext); return response.getAwsResponse(); }
@Override public ListVoicesResult listVoices(ListVoicesRequest listVoicesRequest) throws AmazonServiceException, AmazonClientException { ExecutionContext executionContext = createExecutionContext(listVoicesRequest); Request<ListVoicesRequest> request = ListVoicesRequestMarshallerFactory.getMarshaller( listVoicesRequest.getMethodType()).marshall(listVoicesRequest); Unmarshaller<ListVoicesResult, JsonUnmarshallerContext> unmarshaller = new ListVoicesResultJsonUnmarshaller(); JsonResponseHandler<ListVoicesResult> responseHandler = new JsonResponseHandler<ListVoicesResult>(unmarshaller); Response<ListVoicesResult> response = invoke(request, responseHandler, executionContext); return response.getAwsResponse(); }
@Override public GetLexiconResult getLexicon(GetLexiconRequest getLexiconRequest) throws AmazonServiceException, AmazonClientException { ExecutionContext executionContext = createExecutionContext(getLexiconRequest); GetLexiconRequestMarshaller marshaller = new GetLexiconPostRequestMarshaller(); Request<GetLexiconRequest> request = marshaller.marshall(getLexiconRequest); Unmarshaller<GetLexiconResult, JsonUnmarshallerContext> unmarshaller = new GetLexiconResultJsonUnmarshaller(); JsonResponseHandler<GetLexiconResult> responseHandler = new JsonResponseHandler<GetLexiconResult>(unmarshaller); Response<GetLexiconResult> response = invoke(request, responseHandler, executionContext); return response.getAwsResponse(); }
@Override public ListLexiconsResult listLexicons() { ListLexiconsRequest listLexiconsRequest = new ListLexiconsRequest(); ExecutionContext executionContext = createExecutionContext(listLexiconsRequest); ListLexiconsRequestMarshaller marshaller = new ListLexiconsPostRequestMarshaller(); Request<ListLexiconsRequest> request = marshaller.marshall(listLexiconsRequest); Unmarshaller<ListLexiconsResult, JsonUnmarshallerContext> unmarshaller = new ListLexiconsResultJsonUnmarshaller(); JsonResponseHandler<ListLexiconsResult> responseHandler = new JsonResponseHandler<ListLexiconsResult>(unmarshaller); Response<ListLexiconsResult> response = invoke(request, responseHandler, executionContext); return response.getAwsResponse(); }
@Override public void afterResponse(Request<?> request, Response<?> response) { /* * The following is a hit and miss for multi-threaded clients as the * cache size is only 50 entries */ String awsRequestId = dynamoDBClient.getCachedResponseMetadata(request.getOriginalRequest()).getRequestId(); logger.info("AWS RequestID: " + awsRequestId); /* * Here you could inspect and alter the response object to see how your * application behaves for specific data */ if (request.getOriginalRequest() instanceof GetItemRequest) { GetItemResult result = (GetItemResult) response.getAwsResponse(); Map<String, AttributeValue> item = result.getItem(); if (item.get("name").getS().equals("Airplane")) { // Alter the item item.put("name", new AttributeValue("newAirplane")); item.put("new attr", new AttributeValue("new attr")); // Add some delay try { Thread.sleep(500); } catch (InterruptedException ie) { logger.info(ie); throw new RuntimeException(ie); } } } }
@Override public void afterError(Request<?> request, Response<?> response, Exception e) { if (isSubsegmentDuplicate(recorder.getCurrentSubsegmentOptional(), request)) { Optional<Subsegment> currentSubsegmentOptional = recorder.getCurrentSubsegmentOptional(); if (!currentSubsegmentOptional.isPresent()) { return; } Subsegment currentSubsegment = currentSubsegmentOptional.get(); int statusCode = -1; if (null != response) { statusCode = response.getHttpResponse().getStatusCode(); } else { if (e instanceof AmazonServiceException) { AmazonServiceException ase = (AmazonServiceException) e; statusCode = ase.getStatusCode(); /* * The S3 client will throw and re-swallow AmazonServiceExceptions if they have these status codes. Customers will never see the exceptions in their application code but they still * travel through our TracingHandler#afterError method. We special case these status codes in order to prevent addition of the full exception object to the current subsegment. * Instead, we'll just add any exception error message to the current subsegment's cause's message. */ if ((304 == statusCode || 412 == statusCode) && S3_SERVICE_NAME.equals(ase.getServiceName())) { populateAndEndSubsegment(currentSubsegment, request, response, ase); return; } if (RetryUtils.isThrottlingException(ase)) { currentSubsegment.setError(true); currentSubsegment.setThrottle(true); } } } if (-1 != statusCode) { int statusCodePrefix = statusCode / 100; if (4 == statusCodePrefix) { currentSubsegment.setError(true); if (429 == statusCode) { currentSubsegment.setThrottle(true); } } } currentSubsegment.addException(e); if (e instanceof AmazonServiceException) { populateAndEndSubsegment(currentSubsegment, request, response, (AmazonServiceException) e); } else { populateAndEndSubsegment(currentSubsegment, request, response); } } }
@Override public Response<Void> execute() { return execute(null); }
private <T> void afterResponse(Response<T> response) throws InterruptedException { for (RequestHandler2 handler2 : requestHandler2s) { handler2.afterResponse(request, response); checkInterrupted(response); } }
public SdkInterruptedException(Response<?> response) { this.response = response; }
public Response<?> getResponse() { return response; }
@Override public void afterResponse(Request<?> request, Response<?> response) { for(RequestHandler2 handler : reverseOrderRequestHandlers) { handler.afterResponse(request, response); } }
@Override public void afterError(Request<?> request, Response<?> response, Exception e) { for(RequestHandler2 handler : reverseOrderRequestHandlers) { handler.afterError(request, response, e); } }
@Override public void afterResponse(Request<?> request, Response<?> response) { }
@Override public void afterError(Request<?> request, Response<?> response, Exception e) { }
@SuppressWarnings("deprecation") @Override public void afterError(Request<?> request, Response<?> response, Exception e) { old.afterError(request, e); }
@Override public void afterResponse(Request<?> request, Response<?> response) { wait(afterResponseWait); }
@Override public void afterError(Request<?> request, Response<?> response, Exception e) { wait(afterErrorWait); }
private <X, Y extends AmazonWebServiceRequest> Response<X> invoke( Request<Y> request, HttpResponseHandler<AmazonWebServiceResponse<X>> responseHandler, ExecutionContext executionContext) { JsonErrorResponseHandler errorResponseHandler = new JsonErrorResponseHandler(exceptionUnmarshallers); Response<X> result = client.execute( prepareRequest(request, executionContext), responseHandler, errorResponseHandler, executionContext); return result; }