private static String getRequestId(SdkHttpFullResponse response) { return response.firstMatchingHeader(X_AMZN_REQUEST_ID_HEADER).orElse(null); }
/** * Buffers the response content into an {@link SdkBytes} object. Used to fill the {@link AwsErrorDetails}. If * an {@link IOException} occurs then this will return {@link #emptyXmlBytes()} so that unmarshalling can proceed. * * @param response HTTP response. * @return Raw bytes of response. */ private SdkBytes getResponseBytes(SdkHttpFullResponse response) { try { return response.content() .map(SdkBytes::fromInputStream) .orElseGet(this::emptyXmlBytes); } catch (Exception e) { return emptyXmlBytes(); } }
private int statusCode(SdkHttpFullResponse response, Optional<ExceptionMetadata> modeledExceptionMetadata) { if (response.statusCode() != 0) { return response.statusCode(); } return modeledExceptionMetadata.filter(m -> m.httpStatusCode() != null) .map(ExceptionMetadata::httpStatusCode) .orElse(500); }
public static SdkHttpFullResponse validate(boolean calculateCrc32FromCompressedData, SdkHttpFullResponse httpResponse) { if (!httpResponse.content().isPresent()) { return httpResponse; } return httpResponse.toBuilder().content( process(calculateCrc32FromCompressedData, httpResponse, httpResponse.content().get())).build(); }
/** * Handles a successful response from a service call by unmarshalling the results using the * specified response handler. * * @return The contents of the response, unmarshalled using the specified response handler. * @throws IOException If any problems were encountered reading the response contents from * the HTTP method object. */ private OutputT handleSuccessResponse(SdkHttpFullResponse httpResponse, RequestExecutionContext context) throws IOException, InterruptedException { try { SdkStandardLogger.REQUEST_LOGGER.debug(() -> "Received successful response: " + httpResponse.statusCode()); return successResponseHandler.handle(httpResponse, context.executionAttributes()); } catch (IOException | InterruptedException | RetryableException e) { throw e; } catch (Exception e) { if (e instanceof SdkException && ((SdkException) e).retryable()) { throw (SdkException) e; } String errorMessage = "Unable to unmarshall response (" + e.getMessage() + "). Response Code: " + httpResponse.statusCode() + ", Response Text: " + httpResponse.statusText().orElse(null); throw SdkClientException.builder().message(errorMessage).cause(e).build(); } }
/** * @see HttpResponseHandler#handle(SdkHttpFullResponse, ExecutionAttributes) */ public T handle(SdkHttpFullResponse response, ExecutionAttributes executionAttributes) throws Exception { SdkStandardLogger.REQUEST_LOGGER.trace(() -> "Parsing service response JSON."); SdkStandardLogger.REQUEST_ID_LOGGER.debug(() -> X_AMZN_REQUEST_ID_HEADER + " : " + response.firstMatchingHeader(X_AMZN_REQUEST_ID_HEADER) .orElse("not available")); try { T result = unmarshaller.unmarshall(pojoSupplier.apply(response), response); // Make sure we read all the data to get an accurate CRC32 calculation. // See https://github.com/aws/aws-sdk-java/issues/1018 if (shouldParsePayloadAsJson() && response.content().isPresent()) { IoUtils.drainInputStream(response.content().get()); } SdkStandardLogger.REQUEST_LOGGER.trace(() -> "Done parsing service response."); return result; } finally { if (!needsConnectionLeftOpen) { response.content().ifPresent(i -> FunctionalUtils.invokeSafely(i::close)); } } }
/** * Transforms an event stream message into a {@link SdkHttpFullResponse} so we can reuse our existing generated unmarshallers. * * @param message Message to transform. */ private SdkHttpFullResponse adaptMessageToResponse(Message message, boolean isException) { Map<String, List<String>> headers = message.getHeaders() .entrySet() .stream() .collect(HashMap::new, (m, e) -> m.put(e.getKey(), singletonList(e.getValue().getString())), Map::putAll); if (requestId != null) { headers.put(X_AMZN_REQUEST_ID_HEADER, singletonList(requestId)); } SdkHttpFullResponse.Builder builder = SdkHttpFullResponse.builder() .content(AbortableInputStream.create(new ByteArrayInputStream(message.getPayload()))) .headers(headers); if (!isException) { builder.statusCode(200); } return builder.build(); }
/** * Attempt to parse the error code from the response headers. Returns null if information is not * present in the header. */ private String parseErrorCodeFromHeader(SdkHttpFullResponse response) { Map<String, List<String>> filteredHeaders = response.headers().entrySet().stream() .filter(e -> errorCodeHeaders.stream() .anyMatch(e.getKey()::equalsIgnoreCase)) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); if (filteredHeaders.isEmpty()) { return null; } if (filteredHeaders.size() > 1) { log.warn("Response contains multiple headers representing the error code: " + filteredHeaders.keySet()); } String headerKey = filteredHeaders.keySet().stream().findFirst().get(); String headerValue = filteredHeaders.get(headerKey).get(0); if (X_AMZN_ERROR_TYPE.equalsIgnoreCase(headerKey)) { return parseErrorCodeFromXAmzErrorType(headerValue); } return headerValue; }
private Response<OutputT> handleResponse(SdkHttpFullResponse httpResponse, RequestExecutionContext context) throws IOException, InterruptedException { if (httpResponse.isSuccessful()) { OutputT response = handleSuccessResponse(httpResponse, context); return Response.fromSuccess(response, httpResponse); } else { return Response.fromFailure(handleErrorResponse(httpResponse, context), httpResponse); } }
/** * @see HttpResponseHandler#handle(SdkHttpFullResponse, ExecutionAttributes) */ public T handle(SdkHttpFullResponse response, ExecutionAttributes executionAttributes) throws Exception { SdkStandardLogger.REQUEST_LOGGER.trace(() -> "Parsing service response JSON."); SdkStandardLogger.REQUEST_ID_LOGGER.debug(() -> X_AMZN_REQUEST_ID_HEADER + " : " + response.firstMatchingHeader(X_AMZN_REQUEST_ID_HEADER) .orElse("not available")); try { T result = unmarshaller.unmarshall(pojoSupplier.apply(response), response); // Make sure we read all the data to get an accurate CRC32 calculation. // See https://github.com/aws/aws-sdk-java/issues/1018 if (shouldParsePayloadAsJson() && response.content().isPresent()) { IoUtils.drainInputStream(response.content().get()); } SdkStandardLogger.REQUEST_LOGGER.trace(() -> "Done parsing service response."); return result; } finally { if (!needsConnectionLeftOpen) { response.content().ifPresent(i -> FunctionalUtils.invokeSafely(i::close)); } } }
/** * Creates and initializes an HttpResponse object suitable to be passed to an HTTP response * handler object. * * @return The new, initialized HttpResponse object ready to be passed to an HTTP response handler object. * @throws IOException If there were any problems getting any response information from the * HttpClient method object. */ private SdkHttpFullResponse createResponse(org.apache.http.HttpResponse apacheHttpResponse, HttpRequestBase apacheRequest) throws IOException { return SdkHttpFullResponse.builder() .statusCode(apacheHttpResponse.getStatusLine().getStatusCode()) .statusText(apacheHttpResponse.getStatusLine().getReasonPhrase()) .content(apacheHttpResponse.getEntity() != null ? toAbortableInputStream(apacheHttpResponse, apacheRequest) : null) .headers(transformHeaders(apacheHttpResponse)) .build(); }
/** * Responsible for handling an error response, including unmarshalling the error response * into the most specific exception type possible, and throwing the exception. * * @throws IOException If any problems are encountering reading the error response. */ private SdkException handleErrorResponse(SdkHttpFullResponse httpResponse, RequestExecutionContext context) throws IOException, InterruptedException { try { SdkException exception = errorResponseHandler.handle(httpResponse, context.executionAttributes()); exception.fillInStackTrace(); SdkStandardLogger.REQUEST_LOGGER.debug(() -> "Received error response: " + exception); return exception; } catch (InterruptedException | IOException e) { throw e; } catch (Exception e) { String errorMessage = String.format("Unable to unmarshall error response (%s). " + "Response Code: %d, Response Text: %s", e.getMessage(), httpResponse.statusCode(), httpResponse.statusText().orElse("null")); throw SdkClientException.builder().message(errorMessage).cause(e).build(); } }
/** * Attempt to parse the error code from the response headers. Returns null if information is not * present in the header. */ private String parseErrorCodeFromHeader(SdkHttpFullResponse response) { Map<String, List<String>> filteredHeaders = response.headers().entrySet().stream() .filter(e -> errorCodeHeaders.stream() .anyMatch(e.getKey()::equalsIgnoreCase)) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); if (filteredHeaders.isEmpty()) { return null; } if (filteredHeaders.size() > 1) { log.warn("Response contains multiple headers representing the error code: " + filteredHeaders.keySet()); } String headerKey = filteredHeaders.keySet().stream().findFirst().get(); String headerValue = filteredHeaders.get(headerKey).get(0); if (X_AMZN_ERROR_TYPE.equalsIgnoreCase(headerKey)) { return parseErrorCodeFromXAmzErrorType(headerValue); } return headerValue; }
private static Optional<Long> getCrc32Checksum(SdkHttpFullResponse httpResponse) { return httpResponse.firstMatchingHeader("x-amz-crc32") .map(Long::valueOf); }
private SdkHttpFullResponse fullResponse(TestItemUnmarshalling item) { AbortableInputStream abortableInputStream = AbortableInputStream.create(new ByteArrayInputStream(item.utf8())); return SdkHttpFullResponse.builder() .statusCode(200) .content(abortableInputStream) .build(); }
private int statusCode(SdkHttpFullResponse response, Optional<ExceptionMetadata> modeledExceptionMetadata) { if (response.statusCode() != 0) { return response.statusCode(); } return modeledExceptionMetadata.filter(m -> m.httpStatusCode() != null) .map(ExceptionMetadata::httpStatusCode) .orElse(500); }
private AwsServiceException unmarshall(SdkHttpFullResponse response, ExecutionAttributes executionAttributes) { JsonContent jsonContent = JsonContent.createJsonContent(response, jsonFactory); String errorCode = errorCodeParser.parseErrorCode(response, jsonContent); Optional<ExceptionMetadata> modeledExceptionMetadata = exceptions.stream() .filter(e -> e.errorCode().equals(errorCode)) .findAny(); SdkPojo sdkPojo = modeledExceptionMetadata.map(ExceptionMetadata::exceptionBuilderSupplier) .orElse(defaultExceptionSupplier) .get(); AwsServiceException.Builder exception = ((AwsServiceException) jsonProtocolUnmarshaller .unmarshall(sdkPojo, response, jsonContent.getJsonNode())).toBuilder(); String errorMessage = errorMessageParser.parseErrorMessage(response, jsonContent.getJsonNode()); exception.awsErrorDetails(extractAwsErrorDetails(response, executionAttributes, jsonContent, errorCode, errorMessage)); // Status code and request id are sdk level fields exception.message(errorMessage); exception.statusCode(statusCode(response, modeledExceptionMetadata)); exception.requestId(getRequestIdFromHeaders(response.headers())); return exception.build(); }
private static String getRequestId(SdkHttpFullResponse response) { return response.firstMatchingHeader(X_AMZN_REQUEST_ID_HEADER).orElse(null); }