diff --git a/services-custom/s3-transfer-manager/src/main/java/software/amazon/awssdk/transfer/s3/S3ClientConfiguration.java b/services-custom/s3-transfer-manager/src/main/java/software/amazon/awssdk/transfer/s3/S3ClientConfiguration.java index c6b6328024e8..f9741a5c0f10 100644 --- a/services-custom/s3-transfer-manager/src/main/java/software/amazon/awssdk/transfer/s3/S3ClientConfiguration.java +++ b/services-custom/s3-transfer-manager/src/main/java/software/amazon/awssdk/transfer/s3/S3ClientConfiguration.java @@ -15,6 +15,7 @@ package software.amazon.awssdk.transfer.s3; +import java.net.URI; import java.util.Objects; import java.util.Optional; import software.amazon.awssdk.annotations.SdkPreviewApi; @@ -39,6 +40,7 @@ public final class S3ClientConfiguration implements ToCopyableBuilder maxConcurrency() { return Optional.ofNullable(maxConcurrency); } + /** + * @return the optional endpoint override with which the SDK should communicate. + */ + public Optional endpointOverride() { + return Optional.ofNullable(endpointOverride); + } + @Override public Builder toBuilder() { return new DefaultBuilder(this); @@ -112,7 +122,10 @@ public boolean equals(Object o) { if (!Objects.equals(targetThroughputInGbps, that.targetThroughputInGbps)) { return false; } - return Objects.equals(maxConcurrency, that.maxConcurrency); + if (!Objects.equals(maxConcurrency, that.maxConcurrency)) { + return false; + } + return Objects.equals(endpointOverride, that.endpointOverride); } @Override @@ -122,6 +135,7 @@ public int hashCode() { result = 31 * result + (minimumPartSizeInBytes != null ? minimumPartSizeInBytes.hashCode() : 0); result = 31 * result + (targetThroughputInGbps != null ? targetThroughputInGbps.hashCode() : 0); result = 31 * result + (maxConcurrency != null ? maxConcurrency.hashCode() : 0); + result = 31 * result + (endpointOverride != null ? endpointOverride.hashCode() : 0); return result; } @@ -216,6 +230,14 @@ public interface Builder extends CopyableBuilder * @see #targetThroughputInGbps(Double) */ Builder maxConcurrency(Integer maxConcurrency); + + /** + * Configure the endpoint override with which the SDK should communicate. + * + * @param endpointOverride the endpoint override to be used + * @return this builder for method chaining. + */ + Builder endpointOverride(URI endpointOverride); } private static final class DefaultBuilder implements Builder { @@ -224,6 +246,7 @@ private static final class DefaultBuilder implements Builder { private Long minimumPartSizeInBytes; private Double targetThroughputInGbps; private Integer maxConcurrency; + private URI endpointOverride; private DefaultBuilder() { } @@ -234,6 +257,7 @@ private DefaultBuilder(S3ClientConfiguration configuration) { this.minimumPartSizeInBytes = configuration.minimumPartSizeInBytes; this.targetThroughputInGbps = configuration.targetThroughputInGbps; this.maxConcurrency = configuration.maxConcurrency; + this.endpointOverride = configuration.endpointOverride; } @Override @@ -266,6 +290,12 @@ public Builder maxConcurrency(Integer maxConcurrency) { return this; } + @Override + public Builder endpointOverride(URI endpointOverride) { + this.endpointOverride = endpointOverride; + return this; + } + @Override public S3ClientConfiguration build() { return new S3ClientConfiguration(this); diff --git a/services-custom/s3-transfer-manager/src/main/java/software/amazon/awssdk/transfer/s3/internal/DefaultS3CrtAsyncClient.java b/services-custom/s3-transfer-manager/src/main/java/software/amazon/awssdk/transfer/s3/internal/DefaultS3CrtAsyncClient.java index 22ab7a518001..e687bbf4b6d0 100644 --- a/services-custom/s3-transfer-manager/src/main/java/software/amazon/awssdk/transfer/s3/internal/DefaultS3CrtAsyncClient.java +++ b/services-custom/s3-transfer-manager/src/main/java/software/amazon/awssdk/transfer/s3/internal/DefaultS3CrtAsyncClient.java @@ -18,6 +18,7 @@ import static software.amazon.awssdk.core.interceptor.SdkInternalExecutionAttribute.SDK_HTTP_EXECUTION_ATTRIBUTES; import static software.amazon.awssdk.transfer.s3.internal.S3InternalSdkHttpExecutionAttribute.OPERATION_NAME; +import java.net.URI; import java.util.concurrent.CompletableFuture; import software.amazon.awssdk.annotations.SdkInternalApi; import software.amazon.awssdk.annotations.SdkTestInternalApi; @@ -58,6 +59,7 @@ private DefaultS3CrtAsyncClient(DefaultS3CrtClientBuilder builder) { .minimumPartSizeInBytes(builder.minimumPartSizeInBytes()) .maxConcurrency(builder.maxConcurrency) .region(builder.region) + .endpointOverride(builder.endpointOverride) .credentialsProvider(builder.credentialsProvider) .build(); @@ -79,6 +81,7 @@ private S3AsyncClient initializeS3AsyncClient(DefaultS3CrtClientBuilder builder) .checksumValidationEnabled(false) .build()) .region(builder.region) + .endpointOverride(builder.endpointOverride) .credentialsProvider(builder.credentialsProvider) .overrideConfiguration(o -> o.putAdvancedOption(SdkAdvancedClientOption.SIGNER, new NoOpSigner()) @@ -144,6 +147,7 @@ public static final class DefaultS3CrtClientBuilder implements S3CrtAsyncClientB private Long minimalPartSizeInBytes; private Double targetThroughputInGbps; private Integer maxConcurrency; + private URI endpointOverride; public AwsCredentialsProvider credentialsProvider() { return credentialsProvider; @@ -165,6 +169,11 @@ public Integer maxConcurrency() { return maxConcurrency; } + public URI endpointOverride() { + return endpointOverride; + } + + @Override public S3CrtAsyncClientBuilder credentialsProvider(AwsCredentialsProvider credentialsProvider) { this.credentialsProvider = credentialsProvider; @@ -195,6 +204,12 @@ public S3CrtAsyncClientBuilder maxConcurrency(Integer maxConcurrency) { return this; } + @Override + public S3CrtAsyncClientBuilder endpointOverride(URI endpointOverride) { + this.endpointOverride = endpointOverride; + return this; + } + @Override public S3CrtAsyncClient build() { return new DefaultS3CrtAsyncClient(this); diff --git a/services-custom/s3-transfer-manager/src/main/java/software/amazon/awssdk/transfer/s3/internal/DefaultS3TransferManager.java b/services-custom/s3-transfer-manager/src/main/java/software/amazon/awssdk/transfer/s3/internal/DefaultS3TransferManager.java index 90dcf49f5f5c..d371130e5b70 100644 --- a/services-custom/s3-transfer-manager/src/main/java/software/amazon/awssdk/transfer/s3/internal/DefaultS3TransferManager.java +++ b/services-custom/s3-transfer-manager/src/main/java/software/amazon/awssdk/transfer/s3/internal/DefaultS3TransferManager.java @@ -96,6 +96,7 @@ private static S3CrtAsyncClient initializeS3CrtClient(DefaultBuilder tmBuilder) tmBuilder.s3ClientConfiguration.minimumPartSizeInBytes().ifPresent(clientBuilder::minimumPartSizeInBytes); tmBuilder.s3ClientConfiguration.region().ifPresent(clientBuilder::region); tmBuilder.s3ClientConfiguration.targetThroughputInGbps().ifPresent(clientBuilder::targetThroughputInGbps); + tmBuilder.s3ClientConfiguration.endpointOverride().ifPresent(clientBuilder::endpointOverride); return clientBuilder.build(); } diff --git a/services-custom/s3-transfer-manager/src/main/java/software/amazon/awssdk/transfer/s3/internal/S3CrtAsyncClient.java b/services-custom/s3-transfer-manager/src/main/java/software/amazon/awssdk/transfer/s3/internal/S3CrtAsyncClient.java index 9236a47b5995..63b00a47d434 100644 --- a/services-custom/s3-transfer-manager/src/main/java/software/amazon/awssdk/transfer/s3/internal/S3CrtAsyncClient.java +++ b/services-custom/s3-transfer-manager/src/main/java/software/amazon/awssdk/transfer/s3/internal/S3CrtAsyncClient.java @@ -15,6 +15,7 @@ package software.amazon.awssdk.transfer.s3.internal; +import java.net.URI; import software.amazon.awssdk.annotations.SdkInternalApi; import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; import software.amazon.awssdk.regions.Region; @@ -39,6 +40,8 @@ interface S3CrtAsyncClientBuilder extends SdkBuilder execute(AsyncExecuteRequest request) { + public CompletableFuture execute(AsyncExecuteRequest asyncRequest) { CompletableFuture executeFuture = new CompletableFuture<>(); - HttpRequest httpRequest = toCrtRequest(request); - S3CrtResponseHandlerAdapter responseHandler = new S3CrtResponseHandlerAdapter(executeFuture, request.responseHandler()); + URI uri = asyncRequest.request().getUri(); + HttpRequest httpRequest = toCrtRequest(uri, asyncRequest); + S3CrtResponseHandlerAdapter responseHandler = + new S3CrtResponseHandlerAdapter(executeFuture, asyncRequest.responseHandler()); - S3MetaRequestOptions.MetaRequestType requestType = requestType(request); + S3MetaRequestOptions.MetaRequestType requestType = requestType(asyncRequest); S3MetaRequestOptions requestOptions = new S3MetaRequestOptions() .withHttpRequest(httpRequest) .withMetaRequestType(requestType) - .withResponseHandler(responseHandler); + .withResponseHandler(responseHandler) + .withEndpoint(s3NativeClientConfiguration.endpointOverride()); try (S3MetaRequest s3MetaRequest = crtS3Client.makeMetaRequest(requestOptions)) { closeResourcesWhenComplete(executeFuture, s3MetaRequest); @@ -100,8 +106,8 @@ public String clientName() { return "s3crt"; } - private static S3MetaRequestOptions.MetaRequestType requestType(AsyncExecuteRequest request) { - String operationName = request.httpExecutionAttributes().getAttribute(OPERATION_NAME); + private static S3MetaRequestOptions.MetaRequestType requestType(AsyncExecuteRequest asyncRequest) { + String operationName = asyncRequest.httpExecutionAttributes().getAttribute(OPERATION_NAME); if (operationName != null) { switch (operationName) { case "GetObject": @@ -128,8 +134,7 @@ private static void closeResourcesWhenComplete(CompletableFuture executeFu }); } - private static HttpRequest toCrtRequest(AsyncExecuteRequest asyncRequest) { - URI uri = asyncRequest.request().getUri(); + private static HttpRequest toCrtRequest(URI uri, AsyncExecuteRequest asyncRequest) { SdkHttpRequest sdkRequest = asyncRequest.request(); String method = sdkRequest.method().name(); @@ -166,6 +171,7 @@ public static final class Builder implements SdkAsyncHttpClient.Builder