From 247f6a0a9e3438b752c23e3861864794a3b6775b Mon Sep 17 00:00:00 2001 From: Maciej Walkowiak Date: Fri, 1 Dec 2023 08:09:12 +0100 Subject: [PATCH] Add support for SDK's cross-region S3 client. (#960) Fixes #848 --- docs/src/main/asciidoc/s3.adoc | 30 ------------------- .../autoconfigure/s3/S3AutoConfiguration.java | 3 ++ .../s3/S3CrtAsyncClientAutoConfiguration.java | 1 + .../s3/properties/S3Properties.java | 15 ++++++++++ .../s3/crossregion/CrossRegionS3Client.java | 5 ++++ 5 files changed, 24 insertions(+), 30 deletions(-) diff --git a/docs/src/main/asciidoc/s3.adoc b/docs/src/main/asciidoc/s3.adoc index 2e8843730..bdb781925 100644 --- a/docs/src/main/asciidoc/s3.adoc +++ b/docs/src/main/asciidoc/s3.adoc @@ -74,36 +74,6 @@ Transfer Manager works the best with CRT S3 Client. To auto-configure CRT based When no `S3AsyncClient` bean is created, the default `S3AsyncClient` created through AWS SDK is used. To benefit from maximum throughput, multipart upload/download and resumable file upload consider using CRT based `S3AsyncClient`. -=== Using Cross-Region S3 client - -`S3Client` implementation provided in AWS SDK is region specific - meaning it can be used only to operate on buckets and objects stored in region for which the client has been configured to use. - -For example, assuming that `DefaultAwsRegionProviderChain` resolves a region `us-east-1`, running any S3 operation that uses a bucket created in another region would result in an exception: - -[source] ----- -software.amazon.awssdk.services.s3.model.S3Exception: The bucket you are attempting to access must be addressed using the specified endpoint. Please send all future requests to this endpoint. (Service: S3, Status Code: 301, Request ID: ..., Extended Request ID: ...) ----- - -Spring Cloud AWS provides a `CrossRegionS3Client` that solves this problem by maintaining an internal dictionary of `S3Client` objects per region. If you need to customize these clients, you can create a custom `S3ClientBuilder` bean that acts as a template to create region-specific S3 clients in `CrossRegionS3Client`. -There is no extra work needed to use cross-region S3 client - it is the `S3Client` auto-configured by Spring Cloud AWS. - -To disable `CrossRegionS3Client` creation and use instead a regular region-specific `S3Client`, you can either create a custom `S3Client` bean, or exclude `spring-cloud-aws-s3-cross-region-client` dependency: - -[source,xml] ----- - - io.awspring.cloud - spring-cloud-aws-starter-s3 - - - io.awspring.cloud - spring-cloud-aws-s3-cross-region-client - - - ----- - === S3 Objects as Spring Resources https://docs.spring.io/spring/docs/current/spring-framework-reference/html/resources.html[Spring Resources] are an abstraction for a number of low-level resources, such as file system files, classpath files, servlet context-relative files, etc. diff --git a/spring-cloud-aws-autoconfigure/src/main/java/io/awspring/cloud/autoconfigure/s3/S3AutoConfiguration.java b/spring-cloud-aws-autoconfigure/src/main/java/io/awspring/cloud/autoconfigure/s3/S3AutoConfiguration.java index 85125c0f4..a6c1a219b 100644 --- a/spring-cloud-aws-autoconfigure/src/main/java/io/awspring/cloud/autoconfigure/s3/S3AutoConfiguration.java +++ b/spring-cloud-aws-autoconfigure/src/main/java/io/awspring/cloud/autoconfigure/s3/S3AutoConfiguration.java @@ -73,6 +73,9 @@ S3ClientBuilder s3ClientBuilder(AwsClientBuilderConfigurer awsClientBuilderConfi ObjectProvider> configurer) { S3ClientBuilder builder = awsClientBuilderConfigurer.configure(S3Client.builder(), this.properties, configurer.getIfAvailable()); + + Optional.ofNullable(this.properties.getCrossRegionEnabled()).ifPresent(builder::crossRegionAccessEnabled); + builder.serviceConfiguration(this.properties.toS3Configuration()); return builder; } diff --git a/spring-cloud-aws-autoconfigure/src/main/java/io/awspring/cloud/autoconfigure/s3/S3CrtAsyncClientAutoConfiguration.java b/spring-cloud-aws-autoconfigure/src/main/java/io/awspring/cloud/autoconfigure/s3/S3CrtAsyncClientAutoConfiguration.java index 25d9449d6..c125b9543 100644 --- a/spring-cloud-aws-autoconfigure/src/main/java/io/awspring/cloud/autoconfigure/s3/S3CrtAsyncClientAutoConfiguration.java +++ b/spring-cloud-aws-autoconfigure/src/main/java/io/awspring/cloud/autoconfigure/s3/S3CrtAsyncClientAutoConfiguration.java @@ -66,6 +66,7 @@ S3AsyncClient s3AsyncClient(AwsCredentialsProvider credentialsProvider) { .region(this.awsClientBuilderConfigurer.resolveRegion(this.properties)); Optional.ofNullable(this.awsProperties.getEndpoint()).ifPresent(builder::endpointOverride); Optional.ofNullable(this.properties.getEndpoint()).ifPresent(builder::endpointOverride); + Optional.ofNullable(this.properties.getCrossRegionEnabled()).ifPresent(builder::crossRegionAccessEnabled); if (this.properties.getCrt() != null) { S3CrtClientProperties crt = this.properties.getCrt(); diff --git a/spring-cloud-aws-autoconfigure/src/main/java/io/awspring/cloud/autoconfigure/s3/properties/S3Properties.java b/spring-cloud-aws-autoconfigure/src/main/java/io/awspring/cloud/autoconfigure/s3/properties/S3Properties.java index 4dff9412c..5a422c843 100644 --- a/spring-cloud-aws-autoconfigure/src/main/java/io/awspring/cloud/autoconfigure/s3/properties/S3Properties.java +++ b/spring-cloud-aws-autoconfigure/src/main/java/io/awspring/cloud/autoconfigure/s3/properties/S3Properties.java @@ -73,6 +73,12 @@ public class S3Properties extends AwsClientProperties { @Nullable private Boolean useArnRegionEnabled; + /** + * Enables cross-region bucket access. + */ + @Nullable + private Boolean crossRegionEnabled; + /** * Configuration properties for {@link S3TransferManager} integration. */ @@ -132,6 +138,15 @@ public void setUseArnRegionEnabled(@Nullable Boolean useArnRegionEnabled) { this.useArnRegionEnabled = useArnRegionEnabled; } + @Nullable + public Boolean getCrossRegionEnabled() { + return crossRegionEnabled; + } + + public void setCrossRegionEnabled(@Nullable Boolean crossRegionEnabled) { + this.crossRegionEnabled = crossRegionEnabled; + } + @Nullable public S3TransferManagerProperties getTransferManager() { return this.transferManager; diff --git a/spring-cloud-aws-s3-parent/spring-cloud-aws-s3-cross-region-client/src/main/java/io/awspring/cloud/s3/crossregion/CrossRegionS3Client.java b/spring-cloud-aws-s3-parent/spring-cloud-aws-s3-cross-region-client/src/main/java/io/awspring/cloud/s3/crossregion/CrossRegionS3Client.java index 07275cb33..3cdea24a9 100644 --- a/spring-cloud-aws-s3-parent/spring-cloud-aws-s3-cross-region-client/src/main/java/io/awspring/cloud/s3/crossregion/CrossRegionS3Client.java +++ b/spring-cloud-aws-s3-parent/spring-cloud-aws-s3-cross-region-client/src/main/java/io/awspring/cloud/s3/crossregion/CrossRegionS3Client.java @@ -31,6 +31,11 @@ import software.amazon.awssdk.services.s3.waiters.S3Waiter; import software.amazon.awssdk.utils.SdkAutoCloseable; +/** + * @deprecated use cross-region client included in SDK: ... + */ +@Deprecated public class CrossRegionS3Client extends AbstractCrossRegionS3Client { private static final Logger LOGGER = LoggerFactory.getLogger("io.awspring.cloud.s3.CrossRegionS3Client");