private BuilderImpl(AwsErrorDetails awsErrorDetails) { this.errorMessage = awsErrorDetails.errorMessage(); this.errorCode = awsErrorDetails.errorCode(); this.serviceName = awsErrorDetails.serviceName(); this.sdkHttpResponse = awsErrorDetails.sdkHttpResponse(); this.rawResponse = awsErrorDetails.rawResponse(); }
@Override public AwsErrorDetails build() { return new AwsErrorDetails(this); } }
@Override public AwsServiceException handle(SdkHttpFullResponse response, ExecutionAttributes executionAttributes) { Pair<XmlElement, SdkBytes> xmlAndBytes = parseXml(response); XmlElement document = xmlAndBytes.left(); Optional<XmlElement> errorRoot = errorRootExtractor.apply(document); String errorCode = getErrorCode(errorRoot); AwsServiceException.Builder builder = errorRoot .map(e -> invokeSafely(() -> unmarshallFromErrorCode(response, e, errorCode))) .orElseGet(this::defaultException); AwsErrorDetails awsErrorDetails = AwsErrorDetails.builder() .errorCode(errorCode) .errorMessage(builder.message()) .rawResponse(xmlAndBytes.right()) .sdkHttpResponse(response) .serviceName(executionAttributes.getAttribute(AwsExecutionAttribute.SERVICE_NAME)) .build(); builder.requestId(getRequestId(response, document)) .statusCode(response.statusCode()) .awsErrorDetails(awsErrorDetails); return builder.build(); }
public FeatureState retrieveFeatureStateFromS3(final Feature feature) { final GetObjectRequest getRequest = GetObjectRequest.builder() .bucket(togglzProperties.getS3().getBucketName()) .key(keyForFeature(feature)) .build(); try (final ResponseInputStream<GetObjectResponse> responseStream = s3Client.getObject(getRequest)) { if (responseStream != null) { final FeatureStateStorageWrapper wrapper = objectMapper.reader() .forType(FeatureStateStorageWrapper.class) .readValue(responseStream); return FeatureStateStorageWrapper.featureStateForWrapper(feature, wrapper); } } catch (final S3Exception ae) { if (ERR_NO_SUCH_KEY.equals(ae.awsErrorDetails().errorCode()) || ae.awsErrorDetails().sdkHttpResponse().statusCode() == 404) { return null; } throw ae; } catch (final IOException e) { throw new RuntimeException("Failed to get the feature state", e); } return null; }
} catch (AwsServiceException awsServiceException) { if (holdLockOnServiceUnavailable && awsServiceException.awsErrorDetails().sdkHttpResponse().statusCode() == HttpStatusCode.SERVICE_UNAVAILABLE) {
@Override public boolean isClockSkewException() { return Optional.ofNullable(awsErrorDetails) .map(a -> AwsErrorCode.CLOCK_SKEW_ERROR_CODES.contains(a.errorCode())) .orElse(false); }
@Override public String getMessage() { if (awsErrorDetails != null) { return awsErrorDetails().errorMessage() + " (Service: " + awsErrorDetails().serviceName() + ", Status Code: " + statusCode() + ", Request ID: " + requestId() + ")"; } return super.getMessage(); }
@Override public AwsServiceException handle(SdkHttpFullResponse response, ExecutionAttributes executionAttributes) { Pair<XmlElement, SdkBytes> xmlAndBytes = parseXml(response); XmlElement document = xmlAndBytes.left(); Optional<XmlElement> errorRoot = errorRootExtractor.apply(document); String errorCode = getErrorCode(errorRoot); AwsServiceException.Builder builder = errorRoot .map(e -> invokeSafely(() -> unmarshallFromErrorCode(response, e, errorCode))) .orElseGet(this::defaultException); AwsErrorDetails awsErrorDetails = AwsErrorDetails.builder() .errorCode(errorCode) .errorMessage(builder.message()) .rawResponse(xmlAndBytes.right()) .sdkHttpResponse(response) .serviceName(executionAttributes.getAttribute(AwsExecutionAttribute.SERVICE_NAME)) .build(); builder.requestId(getRequestId(response, document)) .statusCode(response.statusCode()) .awsErrorDetails(awsErrorDetails); return builder.build(); }
.sdkHttpResponse() .firstMatchingHeader("x-amz-request-id") .orElse(null);
@Override public boolean isThrottlingException() { return super.isThrottlingException() || Optional.ofNullable(awsErrorDetails) .map(a -> AwsErrorCode.THROTTLING_ERROR_CODES.contains(a.errorCode())) .orElse(false); }
/** * Build the {@link AwsErrorDetails} from the metadata in the response. * * @param response HTTP response. * @param executionAttributes Execution attributes. * @param jsonContent Parsed JSON content. * @param errorCode Parsed error code/type. * @param errorMessage Parsed error message. * @return AwsErrorDetails */ private AwsErrorDetails extractAwsErrorDetails(SdkHttpFullResponse response, ExecutionAttributes executionAttributes, JsonContent jsonContent, String errorCode, String errorMessage) { AwsErrorDetails.Builder errorDetails = AwsErrorDetails.builder() .errorCode(errorCode) .serviceName(executionAttributes.getAttribute(SdkExecutionAttribute.SERVICE_NAME)) .sdkHttpResponse(response); if (jsonContent.getRawContent() != null) { errorDetails.rawResponse(SdkBytes.fromByteArray(jsonContent.getRawContent())); } errorDetails.errorMessage(errorMessage); return errorDetails.build(); }
@Override public boolean shouldRetry(RetryPolicyContext context) { Exception ex = context.exception(); if (ex instanceof AwsServiceException) { AwsServiceException exception = (AwsServiceException) ex; return retryableErrorCodes.contains(exception.awsErrorDetails().errorCode()); } return false; }
/** * Build the {@link AwsErrorDetails} from the metadata in the response. * * @param response HTTP response. * @param executionAttributes Execution attributes. * @param jsonContent Parsed JSON content. * @param errorCode Parsed error code/type. * @param errorMessage Parsed error message. * @return AwsErrorDetails */ private AwsErrorDetails extractAwsErrorDetails(SdkHttpFullResponse response, ExecutionAttributes executionAttributes, JsonContent jsonContent, String errorCode, String errorMessage) { AwsErrorDetails.Builder errorDetails = AwsErrorDetails.builder() .errorCode(errorCode) .serviceName(executionAttributes.getAttribute(SdkExecutionAttribute.SERVICE_NAME)) .sdkHttpResponse(response); if (jsonContent.getRawContent() != null) { errorDetails.rawResponse(SdkBytes.fromByteArray(jsonContent.getRawContent())); } errorDetails.errorMessage(errorMessage); return errorDetails.build(); }
@Override public FeatureState getFeatureState(final Feature feature) { final GetObjectRequest getRequest = GetObjectRequest.builder() .bucket(s3TogglzProperties.getBucketName()) .key(keyForFeature(feature)) .build(); try (ResponseInputStream<GetObjectResponse> responseStream = s3Client.getObject(getRequest)) { if (responseStream != null) { final FeatureStateStorageWrapper wrapper = objectMapper.reader() .forType(FeatureStateStorageWrapper.class) .readValue(responseStream); return FeatureStateStorageWrapper.featureStateForWrapper(feature, wrapper); } } catch (final S3Exception ae) { if (ERR_NO_SUCH_KEY.equals(ae.awsErrorDetails().errorCode())) { return null; } throw ae; } catch (final IOException e) { throw new RuntimeException("Failed to get the feature state", e); } return null; }
@SuppressWarnings("unchecked") @Override public ResponseInputStream<GetObjectResponse> getObject(final GetObjectRequest getObjectRequest) throws S3Exception { final Map<String, BucketItem> bucketItemMap = bucketsWithContents.get(getObjectRequest.bucket()); final BucketItem bucketItem = bucketItemMap.get(getObjectRequest.key()); if (bucketItem != null) { try { return new ResponseInputStream<>(GetObjectResponse.builder().build(), toAbortableInputStream(bucketItem)); } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException | InstantiationException e) { throw SdkClientException.create("", e); } } else { throw NoSuchKeyException.builder().message("NoSuchKey").awsErrorDetails(AwsErrorDetails.builder().errorCode("NoSuchKey").build()).build(); } }