software.amazon.awssdk.core.exception.SdkException Java Examples

The following examples show how to use software.amazon.awssdk.core.exception.SdkException. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: DeleteHandlerTest.java    From aws-cloudformation-resource-providers-ses with Apache License 2.0 6 votes vote down vote up
@Test
public void handleRequest_FailedDelete_UnknownError() {
    final DeleteHandler handler = new DeleteHandler();

    // all Exceptions should be thrown so they can be handled by wrapper
    doThrow(SdkException.builder().message("test error").build())
        .when(proxy)
        .injectCredentialsAndInvokeV2(
            ArgumentMatchers.any(),
            ArgumentMatchers.any()
        );

    final ResourceModel model = ResourceModel.builder()
        .name("test-set")
        .build();

    final ResourceHandlerRequest<ResourceModel> request = ResourceHandlerRequest.<ResourceModel>builder()
        .desiredResourceState(model)
        .build();

    assertThrows(SdkException.class, () -> {
        handler.handleRequest(proxy, request, null, logger);
    });
}
 
Example #2
Source File: KinesisDataFetcherTest.java    From amazon-kinesis-client with Apache License 2.0 6 votes vote down vote up
@Test
public void testGetRecordsThrowsSdkException() throws Exception {
    expectedExceptionRule.expect(SdkException.class);
    expectedExceptionRule.expectMessage("Test Exception");

    CompletableFuture<GetShardIteratorResponse> getShardIteratorFuture = CompletableFuture
            .completedFuture(GetShardIteratorResponse.builder().shardIterator("test").build());

    // Set up proxy mock methods
    when(kinesisClient.getShardIterator(any(GetShardIteratorRequest.class))).thenReturn(getShardIteratorFuture);
    when(kinesisClient.getRecords(any(GetRecordsRequest.class))).thenReturn(getRecordsResponseFuture);
    when(getRecordsResponseFuture.get(anyLong(), any(TimeUnit.class)))
            .thenThrow(new ExecutionException(SdkException.builder().message("Test Exception").build()));

    // Create data fectcher and initialize it with latest type checkpoint
    kinesisDataFetcher.initialize(SentinelCheckpoint.LATEST.toString(), INITIAL_POSITION_LATEST);
    final GetRecordsRetrievalStrategy getRecordsRetrievalStrategy = new SynchronousGetRecordsRetrievalStrategy(
            kinesisDataFetcher);

    // Call records of dataFetcher which will throw an exception
    getRecordsRetrievalStrategy.getRecords(MAX_RECORDS);

}
 
Example #3
Source File: AWSQueueUtils.java    From para with Apache License 2.0 6 votes vote down vote up
/**
 * Creates a new SQS queue on AWS.
 * @param name queue name
 * @return the queue URL or null
 */
protected static String createQueue(String name) {
	if (StringUtils.isBlank(name)) {
		return null;
	}
	String queueURL = getQueueURL(name);
	if (queueURL == null) {
		try {
			queueURL = getClient().createQueue(b -> b.queueName(name)).get().queueUrl();
		} catch (AwsServiceException ase) {
			logException(ase);
		} catch (SdkException ace) {
			logger.error("Could not reach SQS. {0}", ace.toString());
		} catch (InterruptedException | ExecutionException ex) {
			logger.error(null, ex);
			Thread.currentThread().interrupt();
		}
	}
	return queueURL;
}
 
Example #4
Source File: getEndpointURL.java    From aws-doc-sdk-examples with Apache License 2.0 6 votes vote down vote up
public static void main(String[] args) {
    try {
        // snippet-start:[mediaconvert.java.getendpointurl.build_mediaconvertclient]
        MediaConvertClient mc = MediaConvertClient.builder().build();
        // snippet-end:[mediaconvert.java.getendpointurl.build_mediaconvertclient]
        // snippet-start:[mediaconvert.java.getendpointurl.retrieve_endpoints]
        DescribeEndpointsResponse res = mc
                .describeEndpoints(DescribeEndpointsRequest.builder().maxResults(20).build());

        Iterator<Endpoint> endpoints = res.endpoints().iterator();
        while (endpoints.hasNext()) {
            System.out.println(endpoints.next().url());
        }
        // snippet-end:[mediaconvert.java.getendpointurl.retrieve_endpoints]
    } catch (SdkException e) {
        System.out.println(e.toString());
    } finally {
    }
}
 
Example #5
Source File: AwsSecretsManager.java    From dremio-oss with Apache License 2.0 6 votes vote down vote up
private String getSecret(String[] arnTokens) throws IOException {
  String region = arnTokens[Arn.region.ordinal()];
  String secretName = getSecretName(arnTokens[Arn.secretName.ordinal()]);

  /*
   * Currently, dremio would support access of the secrets manager with base role assigned
   * to EC2 machine. This will be further enhanced, once we have more requirements on it.
   */
  AwsCredentialsProvider awsCredentialsProvider = getAwsCredentials();
  GetSecretValueRequest secretValueRequest = GetSecretValueRequest.builder().secretId(secretName)
    .versionStage(AWS_CURRENT).build();

  try (final SecretsManagerClient secretsManagerClient = SecretsManagerClient.builder()
        .region(Region.of(region))
        .credentialsProvider(awsCredentialsProvider)
        .build()) {
    final GetSecretValueResponse secretValueResponse = secretsManagerClient.getSecretValue(secretValueRequest);
    return (secretValueResponse.secretString() != null) ?
      secretValueResponse.secretString() : secretValueResponse.secretBinary().toString();
  } catch (SdkException e) {
    logger.debug("Unable to retrieve secret for secret {} as {}", secretName, e.getMessage());
    throw new IOException(e.getMessage(), e);
  }
}
 
Example #6
Source File: RetryOnExceptionsCondition.java    From aws-sdk-java-v2 with Apache License 2.0 6 votes vote down vote up
/**
 * @param context Context about the state of the last request and information about the number of requests made.
 * @return True if the exception class matches one of the whitelisted exceptions or if the cause of the exception matches the
 *     whitelisted exception.
 */
@Override
public boolean shouldRetry(RetryPolicyContext context) {

    SdkException exception = context.exception();
    if (exception == null) {
        return false;
    }

    Predicate<Class<? extends Exception>> isRetryableException =
        ex -> ex.isAssignableFrom(exception.getClass());

    Predicate<Class<? extends Exception>> hasRetrableCause =
        ex -> exception.getCause() != null && ex.isAssignableFrom(exception.getCause().getClass());

    return exceptionsToRetryOn.stream().anyMatch(isRetryableException.or(hasRetrableCause));
}
 
Example #7
Source File: BaseAsyncClientHandler.java    From aws-sdk-java-v2 with Apache License 2.0 6 votes vote down vote up
/**
 * Combines and decorates separate success and failure response handlers into a single combined response handler
 * that handles both cases and produces a {@link Response} object that wraps the result. The handlers are
 * decorated with additional behavior (such as CRC32 validation).
 */
private <OutputT extends SdkResponse> TransformingAsyncResponseHandler<Response<OutputT>> createDecoratedHandler(
    HttpResponseHandler<OutputT> successHandler,
    HttpResponseHandler<? extends SdkException> errorHandler,
    ExecutionContext executionContext) {

    HttpResponseHandler<OutputT> decoratedResponseHandlers =
        decorateResponseHandlers(successHandler, executionContext);

    TransformingAsyncResponseHandler<OutputT> decoratedSuccessHandler =
        new AsyncResponseHandler<>(decoratedResponseHandlers,
                                   crc32Validator,
                                   executionContext.executionAttributes());

    TransformingAsyncResponseHandler<? extends SdkException> decoratedErrorHandler =
        resolveErrorResponseHandler(errorHandler, executionContext, crc32Validator);
    return new CombinedResponseAsyncHttpResponseHandler<>(decoratedSuccessHandler, decoratedErrorHandler);
}
 
Example #8
Source File: ClientRetryModeTestSuite.java    From aws-sdk-java-v2 with Apache License 2.0 6 votes vote down vote up
@Test
public void standardRetryModeIncludesThrottlingExceptions() throws InterruptedException {
    stubThrottlingResponse();

    ExecutorService executor = Executors.newFixedThreadPool(51);
    ClientT client = clientBuilder().overrideConfiguration(o -> o.retryPolicy(RetryMode.STANDARD)).build();

    for (int i = 0; i < 51; ++i) {
        executor.execute(() -> assertThatThrownBy(() -> callAllTypes(client)).isInstanceOf(SdkException.class));
    }
    executor.shutdown();
    assertThat(executor.awaitTermination(30, TimeUnit.SECONDS)).isTrue();

    // Would receive 153 without throttling (51 requests * 3 attempts = 153 requests)
    verifyRequestCount(151);
}
 
Example #9
Source File: ClientRetryModeTestSuite.java    From aws-sdk-java-v2 with Apache License 2.0 6 votes vote down vote up
@Test
public void legacyRetryModeExcludesThrottlingExceptions() throws InterruptedException {
    stubThrottlingResponse();

    ExecutorService executor = Executors.newFixedThreadPool(51);
    ClientT client = clientBuilder().overrideConfiguration(o -> o.retryPolicy(RetryMode.LEGACY)).build();

    for (int i = 0; i < 51; ++i) {
        executor.execute(() -> assertThatThrownBy(() -> callAllTypes(client)).isInstanceOf(SdkException.class));
    }
    executor.shutdown();
    assertThat(executor.awaitTermination(30, TimeUnit.SECONDS)).isTrue();

    // 51 requests * 4 attempts = 204 requests
    verifyRequestCount(204);
}
 
Example #10
Source File: CreateHandlerTest.java    From aws-cloudformation-resource-providers-ses with Apache License 2.0 6 votes vote down vote up
@Test
public void handleRequest_FailedCreate_UnknownError() {
    final CreateHandler handler = new CreateHandler();

    doThrow(SdkException.builder().message("test error").build())
        .when(proxy)
        .injectCredentialsAndInvokeV2(
            any(),
            any()
        );

    final ResourceModel model = ResourceModel.builder()
        .name("test-set")
        .build();

    final ResourceHandlerRequest<ResourceModel> request = ResourceHandlerRequest.<ResourceModel>builder()
        .desiredResourceState(model)
        .build();

    assertThrows(SdkException.class, () -> {
        handler.handleRequest(proxy, request, null, logger);
    });
}
 
Example #11
Source File: S3Repository.java    From djl with Apache License 2.0 6 votes vote down vote up
private synchronized Metadata getMetadata() throws IOException {
    if (resolved) {
        return metadata;
    }

    try {
        resolved = true;
        Artifact artifact = listFiles();
        if (artifact == null) {
            logger.debug("No object found in s3 bucket.");
            return null;
        }

        metadata = new Metadata.MatchAllMetadata();
        String hash = md5hash("s3://" + bucket + '/' + prefix);
        MRL mrl = MRL.model(Application.UNDEFINED, DefaultModelZoo.GROUP_ID, hash);
        metadata.setRepositoryUri(mrl.toURI());
        metadata.setArtifactId(artifactId);
        metadata.setArtifacts(Collections.singletonList(artifact));
        return metadata;
    } catch (SdkException e) {
        throw new IOException("Failed scan s3 bucket: " + bucket, e);
    }
}
 
Example #12
Source File: CombinedResponseAsyncHttpResponseHandler.java    From aws-sdk-java-v2 with Apache License 2.0 5 votes vote down vote up
public CombinedResponseAsyncHttpResponseHandler(
    TransformingAsyncResponseHandler<OutputT> successResponseHandler,
    TransformingAsyncResponseHandler<? extends SdkException> errorResponseHandler) {

    this.successResponseHandler = successResponseHandler;
    this.errorResponseHandler = errorResponseHandler;
}
 
Example #13
Source File: ClientRetryModeTestSuite.java    From aws-sdk-java-v2 with Apache License 2.0 5 votes vote down vote up
@Test
public void standardRetryModeIsThreeAttempts() {
    stubThrottlingResponse();
    ClientT client = clientBuilder().overrideConfiguration(o -> o.retryPolicy(RetryMode.STANDARD)).build();
    assertThatThrownBy(() -> callAllTypes(client)).isInstanceOf(SdkException.class);
    verifyRequestCount(3);
}
 
Example #14
Source File: CombinedResponseAsyncHttpResponseHandler.java    From aws-sdk-java-v2 with Apache License 2.0 5 votes vote down vote up
@Override
public CompletableFuture<Response<OutputT>> prepare() {
    this.response.set(null);
    CompletableFuture<OutputT> preparedTransformFuture = successResponseHandler.prepare();

    CompletableFuture<? extends SdkException> preparedErrorTransformFuture = errorResponseHandler == null ? null :
        errorResponseHandler.prepare();

    headersFuture = new CompletableFuture<>();

    return headersFuture.thenCompose(headers -> {
        if (headers.isSuccessful()) {
            return preparedTransformFuture.thenApply(
                r -> Response.<OutputT>builder().response(r)
                                                .httpResponse(response.get())
                                                .isSuccess(true)
                                                .build());
        }

        if (preparedErrorTransformFuture != null) {
            return preparedErrorTransformFuture.thenApply(
                e -> Response.<OutputT>builder().exception(e)
                                                .httpResponse(response.get())
                                                .isSuccess(false)
                                                .build());
        }
        return CompletableFuture.completedFuture(
            Response.<OutputT>builder().httpResponse(response.get())
                                       .isSuccess(false)
                                       .build());
    });
}
 
Example #15
Source File: ThrowableUtils.java    From aws-sdk-java-v2 with Apache License 2.0 5 votes vote down vote up
/**
 * Wraps the given {@code Throwable} in {@link SdkException} if necessary.
 */
public static SdkException asSdkException(Throwable t) {
    if (t instanceof SdkException) {
        return (SdkException) t;
    }
    return SdkClientException.builder().cause(t).build();
}
 
Example #16
Source File: DefaultTokenBucketExceptionCostFunction.java    From aws-sdk-java-v2 with Apache License 2.0 5 votes vote down vote up
@Override
public Integer apply(SdkException e) {
    if (throttlingExceptionCost != null && RetryUtils.isThrottlingException(e)) {
        return throttlingExceptionCost;
    }

    return defaultExceptionCost;
}
 
Example #17
Source File: S3Utilities.java    From aws-sdk-java-v2 with Apache License 2.0 5 votes vote down vote up
/**
 * Returns the URL for an object stored in Amazon S3.
 *
 * If the object identified by the given bucket and key has public read permissions,
 * then this URL can be directly accessed to retrieve the object's data.
 *
 * <p>
 *     If same configuration options are set on both #GetUrlRequest and #S3Utilities objects (for example: region),
 *     the configuration set on the #GetUrlRequest takes precedence.
 * </p>
 *
 * @param getUrlRequest request to construct url
 * @return A URL for an object stored in Amazon S3.
 * @throws MalformedURLException Generated Url is malformed
 */
public URL getUrl(GetUrlRequest getUrlRequest) {
    Region resolvedRegion = resolveRegionForGetUrl(getUrlRequest);
    URI resolvedEndpoint = resolveEndpoint(getUrlRequest.endpoint(), resolvedRegion);
    boolean endpointOverridden = getUrlRequest.endpoint() != null;

    SdkHttpFullRequest marshalledRequest = createMarshalledRequest(getUrlRequest, resolvedEndpoint);

    GetObjectRequest getObjectRequest = GetObjectRequest.builder()
                                                        .bucket(getUrlRequest.bucket())
                                                        .key(getUrlRequest.key())
                                                        .build();

    SdkHttpRequest httpRequest = S3EndpointUtils.applyEndpointConfiguration(marshalledRequest,
                                                                            getObjectRequest,
                                                                            resolvedRegion,
                                                                            s3Configuration,
                                                                            endpointOverridden)
                                                .sdkHttpRequest();

    try {
        return httpRequest.getUri().toURL();
    } catch (MalformedURLException exception) {
        throw SdkException.create("Generated URI is malformed: " + httpRequest.getUri(),
                                  exception);
    }
}
 
Example #18
Source File: ResponseHandlerTestUtils.java    From aws-sdk-java-v2 with Apache License 2.0 5 votes vote down vote up
public static <T> HttpResponseHandler<Response<T>> combinedSyncResponseHandler(
    HttpResponseHandler<T> successResponseHandler,
    HttpResponseHandler<? extends SdkException> failureResponseHandler) {

    return new CombinedResponseHandler<>(
        successResponseHandler == null ? noOpSyncResponseHandler() : successResponseHandler,
        failureResponseHandler == null ? noOpSyncResponseHandler() : failureResponseHandler);
}
 
Example #19
Source File: AsyncResponseHandlerTestUtils.java    From aws-sdk-java-v2 with Apache License 2.0 5 votes vote down vote up
public static <T> TransformingAsyncResponseHandler<Response<T>> combinedAsyncResponseHandler(
    TransformingAsyncResponseHandler<T> successResponseHandler,
    TransformingAsyncResponseHandler<? extends SdkException> failureResponseHandler) {

    return new CombinedResponseAsyncHttpResponseHandler<>(
        successResponseHandler == null ? noOpResponseHandler() : successResponseHandler,
        failureResponseHandler == null ? noOpResponseHandler() : failureResponseHandler);
}
 
Example #20
Source File: EndpointDiscoveryTest.java    From aws-sdk-java-v2 with Apache License 2.0 5 votes vote down vote up
@Test(timeout = 10_000)
public void canBeEnabledViaProfileOnOverrideConfiguration() throws InterruptedException {
    ExecutionInterceptor interceptor = Mockito.spy(AbstractExecutionInterceptor.class);

    String profileFileContent =
        "[default]\n" +
        "aws_endpoint_discovery_enabled = true";

    ProfileFile profileFile = ProfileFile.builder()
                                         .type(ProfileFile.Type.CONFIGURATION)
                                         .content(new StringInputStream(profileFileContent))
                                         .build();

    DynamoDbClient dynamoDb = DynamoDbClient.builder()
                                            .region(Region.US_WEST_2)
                                            .credentialsProvider(AnonymousCredentialsProvider.create())
                                            .overrideConfiguration(c -> c.defaultProfileFile(profileFile)
                                                                         .defaultProfileName("default")
                                                                         .addExecutionInterceptor(interceptor)
                                                                         .retryPolicy(r -> r.numRetries(0)))
                                            .build();

    assertThatThrownBy(dynamoDb::listTables).isInstanceOf(SdkException.class);

    ArgumentCaptor<Context.BeforeTransmission> context;

    do {
        Thread.sleep(1);
        context = ArgumentCaptor.forClass(Context.BeforeTransmission.class);
        Mockito.verify(interceptor, atLeastOnce()).beforeTransmission(context.capture(), any());
    } while (context.getAllValues().size() < 2);

    assertThat(context.getAllValues()
                      .stream()
                      .anyMatch(v -> v.httpRequest()
                                      .firstMatchingHeader("X-Amz-Target")
                                      .map(h -> h.equals("DynamoDB_20120810.DescribeEndpoints"))
                                      .orElse(false)))
        .isTrue();
}
 
Example #21
Source File: KinesisStreamInfoProviderTest.java    From synapse with Apache License 2.0 5 votes vote down vote up
@Test(expected = SdkException.class)
public void shouldThrowOtherExceptions() {
    //given
    when(kinesisAsyncClient
            .describeStream(any(DescribeStreamRequest.class)))
            .thenThrow(SdkException.class);

    //when
    testee.getStreamInfo("someChannelName");
}
 
Example #22
Source File: GlobalRequestHandlerTest.java    From aws-sdk-java-v2 with Apache License 2.0 5 votes vote down vote up
private void callApi(DynamoDbClient client) {
    try {
        client.listTables(ListTablesRequest.builder().build());
    } catch (SdkException expected) {
        // Ignored or expected.
    }
}
 
Example #23
Source File: AWSQueueUtils.java    From para with Apache License 2.0 5 votes vote down vote up
/**
 * Deletes an SQS queue on AWS.
 * @param queueURL URL of the SQS queue
 */
protected static void deleteQueue(String queueURL) {
	if (!StringUtils.isBlank(queueURL)) {
		try {
			getClient().deleteQueue(b -> b.queueUrl(queueURL));
		} catch (AwsServiceException ase) {
			logException(ase);
		} catch (SdkException ace) {
			logger.error("Could not reach SQS. {0}", ace.toString());
		}
	}
}
 
Example #24
Source File: AWSQueueUtils.java    From para with Apache License 2.0 5 votes vote down vote up
/**
 * Returns a list of URLs for all available queues on SQS.
 * @return a list or queue URLs
 */
protected static List<String> listQueues() {
	List<String> list = new ArrayList<>();
	try {
		list = getClient().listQueues().get().queueUrls();
	} catch (AwsServiceException ase) {
		logException(ase);
	} catch (SdkException ace) {
		logger.error("Could not reach SQS. {0}", ace.toString());
	} catch (InterruptedException | ExecutionException ex) {
		logger.error(null, ex);
		Thread.currentThread().interrupt();
	}
	return list;
}
 
Example #25
Source File: AWSQueueUtils.java    From para with Apache License 2.0 5 votes vote down vote up
/**
 * Pushes a number of messages in batch to an SQS queue.
 * @param queueURL the URL of the SQS queue
 * @param messages the massage bodies
 */
protected static void pushMessages(String queueURL, List<String> messages) {
	if (!StringUtils.isBlank(queueURL) && messages != null) {
		// only allow strings - ie JSON
		try {
			int	j = 0;
			List<SendMessageBatchRequestEntry> msgs = new ArrayList<>(MAX_MESSAGES);
			for (int i = 0; i < messages.size(); i++) {
				String message = messages.get(i);
				if (!StringUtils.isBlank(message)) {
					msgs.add(SendMessageBatchRequestEntry.builder().
							messageBody(message).
							id(Integer.toString(i)).build());
				}
				if (++j >= MAX_MESSAGES || i == messages.size() - 1) {
					if (!msgs.isEmpty()) {
						getClient().sendMessageBatch(b -> b.queueUrl(queueURL).entries(msgs));
						msgs.clear();
					}
					j = 0;
				}
			}
		} catch (AwsServiceException ase) {
			logException(ase);
		} catch (SdkException ace) {
			logger.error("Could not reach SQS. {}", ace.toString());
		}
	}
}
 
Example #26
Source File: KinesisDataFetcher.java    From amazon-kinesis-client with Apache License 2.0 5 votes vote down vote up
private AWSExceptionManager createExceptionManager() {
    final AWSExceptionManager exceptionManager = new AWSExceptionManager();
    exceptionManager.add(ResourceNotFoundException.class, t -> t);
    exceptionManager.add(KinesisException.class, t -> t);
    exceptionManager.add(SdkException.class, t -> t);
    return exceptionManager;
}
 
Example #27
Source File: RetryableStageHelper.java    From aws-sdk-java-v2 with Apache License 2.0 5 votes vote down vote up
/**
 * Update the {@link #getLastException()} value for this helper. This will be used to determine whether the request should
 * be retried.
 */
public void setLastException(Throwable lastException) {
    if (lastException instanceof CompletionException) {
        setLastException(lastException.getCause());
    } else if (lastException instanceof SdkException) {
        this.lastException = (SdkException) lastException;
    } else {
        this.lastException = SdkClientException.create("Unable to execute HTTP request: " + lastException.getMessage(),
                                                       lastException);
    }
}
 
Example #28
Source File: ClientRetryModeTestSuite.java    From aws-sdk-java-v2 with Apache License 2.0 5 votes vote down vote up
@Test
public void legacyRetryModeIsFourAttempts() {
    stubThrottlingResponse();
    ClientT client = clientBuilder().overrideConfiguration(o -> o.retryPolicy(RetryMode.LEGACY)).build();
    assertThatThrownBy(() -> callAllTypes(client)).isInstanceOf(SdkException.class);
    verifyRequestCount(4);
}
 
Example #29
Source File: ClientRetryModeTestSuite.java    From aws-sdk-java-v2 with Apache License 2.0 5 votes vote down vote up
@Test
public void retryModeCanBeSetByProfileFile() {
    ProfileFile profileFile = ProfileFile.builder()
                                         .content(new StringInputStream("[profile foo]\n" +
                                                                        "retry_mode = standard"))
                                         .type(ProfileFile.Type.CONFIGURATION)
                                         .build();
    stubThrottlingResponse();
    ClientT client = clientBuilder().overrideConfiguration(o -> o.defaultProfileFile(profileFile)
                                                                 .defaultProfileName("foo")).build();
    assertThatThrownBy(() -> callAllTypes(client)).isInstanceOf(SdkException.class);
    verifyRequestCount(3);
}
 
Example #30
Source File: ClockSkewAdjustmentTest.java    From aws-sdk-java-v2 with Apache License 2.0 5 votes vote down vote up
private void clientClockSkewAdjustsWithoutRetries(Runnable call) {
    Instant actualTime = Instant.now();
    Instant skewedTime = actualTime.plus(7, HOURS);

    // Force the client time forward
    stubForResponse(skewedTime, 400, "RequestTimeTooSkewed");
    assertThatThrownBy(call::run).isInstanceOfAny(SdkException.class, CompletionException.class);

    // Verify the next call uses that time
    stubForResponse(actualTime, 200, "");
    call.run();
    assertSigningDateApproximatelyEquals(getRecordedRequests().get(0), skewedTime);
}