diff --git a/docs/src/main/asciidoc/s3.adoc b/docs/src/main/asciidoc/s3.adoc index 6a9fc318a..9391dff14 100644 --- a/docs/src/main/asciidoc/s3.adoc +++ b/docs/src/main/asciidoc/s3.adoc @@ -604,17 +604,51 @@ The Spring Boot Starter for S3 provides the following configuration options: | `spring.cloud.aws.s3.config.reload.max-wait-time-for-restart` | `Duration`| `2s` | The maximum time between the detection of changes in property source and the application context restart when `restart_context` strategy is used. |=== +=== S3 Vector Client support + +https://aws.amazon.com/blogs/aws/introducing-amazon-s3-vectors-first-cloud-storage-with-native-vector-support-at-scale/[S3 Vector Store] is a vector storage which supports uploading, storing and querying vectors. +To allow users simpler use of `S3VectorsClient` with https://github.com/spring-projects/spring-ai[Spring AI] project or use of a plain client, we support autoconfiguration of the `S3VectorsClient`. + +To enable autoconfiguration you should add the following dependencies +[source,xml] +---- + + io.awspring.cloud + spring-cloud-aws-starter + + + + software.amazon.awssdk + s3vectors + +---- + +After dependencies are introduced Spring Cloud AWS will automatically create a `S3VectorsClient` bean which can than be autowired and used. + +[cols="2,3,1,1"] +|=== +| Name | Description | Required | Default value +| `spring.cloud.aws.s3.vector.config.enabled` | Enables the S3 config import integration. | No | `true` +| `spring.cloud.aws.s3.config.reload.strategy` | `Enum` | `refresh` | The strategy to use when firing a reload (`refresh`, `restart_context`) +| `spring.cloud.aws.s3.config.reload.period` | `Duration`| `15s` | The period for verifying changes +| `spring.cloud.aws.s3.config.reload.max-wait-time-for-restart` | `Duration`| `2s` | The maximum time between the detection of changes in property source and the application context restart when `restart_context` strategy is used. +|=== === IAM Permissions Following IAM permissions are required by Spring Cloud AWS: -[cols="2,1"] -|=== -| Downloading files | `s3:GetObject` -| Searching files | `s3:ListObjects` -| Uploading files | `s3:PutObject` +[cols="2,3,1,1"] |=== +| Name | Description | Required | Default value +| `spring.cloud.aws.s3.vector.enabled` | Enables the S3VectorsClient autoconfiguration. | No | `true` +| `spring.cloud.aws.s3.vector.endpoint` | Configures endpoint used by `S3VectorsClient`. | No | `http://localhost:4566` +| `spring.cloud.aws.s3.vector.region` | Configures region used by `S3VectorsClient`. | No | `eu-west-1` + + + + +=== Example of IAM policy for Spring Cloud AWS demo bucket Sample IAM policy granting access to `spring-cloud-aws-demo` bucket: diff --git a/spring-cloud-aws-autoconfigure/pom.xml b/spring-cloud-aws-autoconfigure/pom.xml index a0eee3ee5..8d7e8e4ab 100644 --- a/spring-cloud-aws-autoconfigure/pom.xml +++ b/spring-cloud-aws-autoconfigure/pom.xml @@ -186,6 +186,12 @@ amazon-s3-encryption-client-java true + + + software.amazon.awssdk + s3vectors + true + io.micrometer micrometer-observation-test diff --git a/spring-cloud-aws-autoconfigure/src/main/java/io/awspring/cloud/autoconfigure/s3vectors/S3VectorClientAutoConfiguration.java b/spring-cloud-aws-autoconfigure/src/main/java/io/awspring/cloud/autoconfigure/s3vectors/S3VectorClientAutoConfiguration.java new file mode 100644 index 000000000..523233970 --- /dev/null +++ b/spring-cloud-aws-autoconfigure/src/main/java/io/awspring/cloud/autoconfigure/s3vectors/S3VectorClientAutoConfiguration.java @@ -0,0 +1,64 @@ +/* + * Copyright 2013-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.awspring.cloud.autoconfigure.s3vectors; + +import io.awspring.cloud.autoconfigure.AwsSyncClientCustomizer; +import io.awspring.cloud.autoconfigure.core.*; +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.context.annotation.Bean; +import software.amazon.awssdk.services.s3vectors.S3VectorsClient; +import software.amazon.awssdk.services.s3vectors.S3VectorsClientBuilder; + +/** + * @author Matej Nedic + * @since 4.0.0 + */ +@AutoConfiguration +@ConditionalOnClass({ S3VectorsClient.class }) +@EnableConfigurationProperties({ S3VectorProperties.class, AwsProperties.class }) +@AutoConfigureAfter({ CredentialsProviderAutoConfiguration.class, RegionProviderAutoConfiguration.class }) +@ConditionalOnProperty(name = "spring.cloud.aws.s3.vector.enabled", havingValue = "true", matchIfMissing = true) +public class S3VectorClientAutoConfiguration { + + private final S3VectorProperties properties; + + public S3VectorClientAutoConfiguration(S3VectorProperties properties) { + this.properties = properties; + } + + @Bean + @ConditionalOnMissingBean + S3VectorsClientBuilder s3VectorsClientBuilder(AwsClientBuilderConfigurer awsClientBuilderConfigurer, + ObjectProvider connectionDetails, + ObjectProvider s3ClientCustomizers, + ObjectProvider awsSyncClientCustomizers) { + + return awsClientBuilderConfigurer.configureSyncClient(S3VectorsClient.builder(), this.properties, + connectionDetails.getIfAvailable(), s3ClientCustomizers.orderedStream(), + awsSyncClientCustomizers.orderedStream()); + } + + @Bean + S3VectorsClient s3VectorsClient(S3VectorsClientBuilder builder) { + return builder.build(); + } +} diff --git a/spring-cloud-aws-autoconfigure/src/main/java/io/awspring/cloud/autoconfigure/s3vectors/S3VectorClientCustomizer.java b/spring-cloud-aws-autoconfigure/src/main/java/io/awspring/cloud/autoconfigure/s3vectors/S3VectorClientCustomizer.java new file mode 100644 index 000000000..636914f5a --- /dev/null +++ b/spring-cloud-aws-autoconfigure/src/main/java/io/awspring/cloud/autoconfigure/s3vectors/S3VectorClientCustomizer.java @@ -0,0 +1,29 @@ +/* + * Copyright 2013-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.awspring.cloud.autoconfigure.s3vectors; + +import io.awspring.cloud.autoconfigure.AwsClientCustomizer; +import software.amazon.awssdk.services.s3vectors.S3VectorsClientBuilder; + +/** + * Callback interface that can be used to customize a {@link S3VectorsClientBuilder}. + * + * @author Matej Nedic + * @since 4.0.0 + */ +@FunctionalInterface +public interface S3VectorClientCustomizer extends AwsClientCustomizer { +} diff --git a/spring-cloud-aws-autoconfigure/src/main/java/io/awspring/cloud/autoconfigure/s3vectors/S3VectorProperties.java b/spring-cloud-aws-autoconfigure/src/main/java/io/awspring/cloud/autoconfigure/s3vectors/S3VectorProperties.java new file mode 100644 index 000000000..3e12f5b69 --- /dev/null +++ b/spring-cloud-aws-autoconfigure/src/main/java/io/awspring/cloud/autoconfigure/s3vectors/S3VectorProperties.java @@ -0,0 +1,33 @@ +/* + * Copyright 2013-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.awspring.cloud.autoconfigure.s3vectors; + +import io.awspring.cloud.autoconfigure.AwsClientProperties; +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * @author Matej Nedic + * @since 4.0.0 + */ +@ConfigurationProperties(prefix = S3VectorProperties.PREFIX) +public class S3VectorProperties extends AwsClientProperties { + + /** + * The prefix used for S3 related properties. + */ + public static final String PREFIX = "spring.cloud.aws.s3.vector"; + +} diff --git a/spring-cloud-aws-autoconfigure/src/main/java/io/awspring/cloud/autoconfigure/s3vectors/package-info.java b/spring-cloud-aws-autoconfigure/src/main/java/io/awspring/cloud/autoconfigure/s3vectors/package-info.java new file mode 100644 index 000000000..06b170a2c --- /dev/null +++ b/spring-cloud-aws-autoconfigure/src/main/java/io/awspring/cloud/autoconfigure/s3vectors/package-info.java @@ -0,0 +1,22 @@ +/* + * Copyright 2013-2022 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * Auto-configuration for S3Vector integration. + */ +@org.springframework.lang.NonNullApi +@org.springframework.lang.NonNullFields +package io.awspring.cloud.autoconfigure.s3vectors; diff --git a/spring-cloud-aws-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-cloud-aws-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports index 657cbf245..685d3a75a 100644 --- a/spring-cloud-aws-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ b/spring-cloud-aws-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -7,6 +7,7 @@ io.awspring.cloud.autoconfigure.ses.SesAutoConfiguration io.awspring.cloud.autoconfigure.s3.S3TransferManagerAutoConfiguration io.awspring.cloud.autoconfigure.s3.S3AutoConfiguration io.awspring.cloud.autoconfigure.s3.S3CrtAsyncClientAutoConfiguration +io.awspring.cloud.autoconfigure.s3vectors.S3VectorClientAutoConfiguration io.awspring.cloud.autoconfigure.sns.SnsAutoConfiguration io.awspring.cloud.autoconfigure.sqs.SqsAutoConfiguration io.awspring.cloud.autoconfigure.dynamodb.DynamoDbAutoConfiguration diff --git a/spring-cloud-aws-autoconfigure/src/test/java/io/awspring/cloud/autoconfigure/s3vectors/S3VectorAutoConfigurationTests.java b/spring-cloud-aws-autoconfigure/src/test/java/io/awspring/cloud/autoconfigure/s3vectors/S3VectorAutoConfigurationTests.java new file mode 100644 index 000000000..76dd18a43 --- /dev/null +++ b/spring-cloud-aws-autoconfigure/src/test/java/io/awspring/cloud/autoconfigure/s3vectors/S3VectorAutoConfigurationTests.java @@ -0,0 +1,53 @@ +/* + * Copyright 2013-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.awspring.cloud.autoconfigure.s3vectors; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.awspring.cloud.autoconfigure.core.AwsAutoConfiguration; +import io.awspring.cloud.autoconfigure.core.CredentialsProviderAutoConfiguration; +import io.awspring.cloud.autoconfigure.core.RegionProviderAutoConfiguration; +import org.junit.jupiter.api.Test; +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.test.context.runner.ApplicationContextRunner; +import software.amazon.awssdk.services.s3vectors.S3VectorsClient; + +/** + * Test for {@link S3VectorAutoConfigurationTests} class + * + * @author Matej Nedic + */ +public class S3VectorAutoConfigurationTests { + + private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() + .withPropertyValues("spring.cloud.aws.region.static:eu-west-1") + .withConfiguration(AutoConfigurations.of(AwsAutoConfiguration.class, RegionProviderAutoConfiguration.class, + CredentialsProviderAutoConfiguration.class, S3VectorClientAutoConfiguration.class)); + + @Test + void createsS3VectorClientBean() { + this.contextRunner.run(context -> { + assertThat(context).hasSingleBean(S3VectorsClient.class); + }); + } + + @Test + void s3VectorClientAutoConfigurationIsDisabled() { + this.contextRunner.withPropertyValues("spring.cloud.aws.s3.vector.enabled:false").run(context -> { + assertThat(context).doesNotHaveBean(S3VectorsClient.class); + }); + } +}