Skip to content

Commit 9c6a97a

Browse files
authored
S3 vector client autoconfiguration (#1425)
1 parent bd07b5d commit 9c6a97a

File tree

8 files changed

+247
-5
lines changed

8 files changed

+247
-5
lines changed

docs/src/main/asciidoc/s3.adoc

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -604,17 +604,51 @@ The Spring Boot Starter for S3 provides the following configuration options:
604604
| `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.
605605
|===
606606

607+
=== S3 Vector Client support
608+
609+
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.
610+
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`.
611+
612+
To enable autoconfiguration you should add the following dependencies
613+
[source,xml]
614+
----
615+
<dependency>
616+
<groupId>io.awspring.cloud</groupId>
617+
<artifactId>spring-cloud-aws-starter</artifactId>
618+
</dependency>
619+
620+
<dependency>
621+
<groupId>software.amazon.awssdk</groupId>
622+
<artifactId>s3vectors</artifactId>
623+
</dependency>
624+
----
625+
626+
After dependencies are introduced Spring Cloud AWS will automatically create a `S3VectorsClient` bean which can than be autowired and used.
627+
628+
[cols="2,3,1,1"]
629+
|===
630+
| Name | Description | Required | Default value
631+
| `spring.cloud.aws.s3.vector.config.enabled` | Enables the S3 config import integration. | No | `true`
632+
| `spring.cloud.aws.s3.config.reload.strategy` | `Enum` | `refresh` | The strategy to use when firing a reload (`refresh`, `restart_context`)
633+
| `spring.cloud.aws.s3.config.reload.period` | `Duration`| `15s` | The period for verifying changes
634+
| `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.
635+
|===
607636

608637
=== IAM Permissions
609638

610639
Following IAM permissions are required by Spring Cloud AWS:
611640

612-
[cols="2,1"]
613-
|===
614-
| Downloading files | `s3:GetObject`
615-
| Searching files | `s3:ListObjects`
616-
| Uploading files | `s3:PutObject`
641+
[cols="2,3,1,1"]
617642
|===
643+
| Name | Description | Required | Default value
644+
| `spring.cloud.aws.s3.vector.enabled` | Enables the S3VectorsClient autoconfiguration. | No | `true`
645+
| `spring.cloud.aws.s3.vector.endpoint` | Configures endpoint used by `S3VectorsClient`. | No | `http://localhost:4566`
646+
| `spring.cloud.aws.s3.vector.region` | Configures region used by `S3VectorsClient`. | No | `eu-west-1`
647+
648+
649+
650+
651+
=== Example of IAM policy for Spring Cloud AWS demo bucket
618652

619653
Sample IAM policy granting access to `spring-cloud-aws-demo` bucket:
620654

spring-cloud-aws-autoconfigure/pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,12 @@
186186
<artifactId>amazon-s3-encryption-client-java</artifactId>
187187
<optional>true</optional>
188188
</dependency>
189+
190+
<dependency>
191+
<groupId>software.amazon.awssdk</groupId>
192+
<artifactId>s3vectors</artifactId>
193+
<optional>true</optional>
194+
</dependency>
189195
<dependency>
190196
<groupId>io.micrometer</groupId>
191197
<artifactId>micrometer-observation-test</artifactId>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/*
2+
* Copyright 2013-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.awspring.cloud.autoconfigure.s3vectors;
17+
18+
import io.awspring.cloud.autoconfigure.AwsSyncClientCustomizer;
19+
import io.awspring.cloud.autoconfigure.core.*;
20+
import org.springframework.beans.factory.ObjectProvider;
21+
import org.springframework.boot.autoconfigure.AutoConfiguration;
22+
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
23+
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
24+
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
25+
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
26+
import org.springframework.boot.context.properties.EnableConfigurationProperties;
27+
import org.springframework.context.annotation.Bean;
28+
import software.amazon.awssdk.services.s3vectors.S3VectorsClient;
29+
import software.amazon.awssdk.services.s3vectors.S3VectorsClientBuilder;
30+
31+
/**
32+
* @author Matej Nedic
33+
* @since 4.0.0
34+
*/
35+
@AutoConfiguration
36+
@ConditionalOnClass({ S3VectorsClient.class })
37+
@EnableConfigurationProperties({ S3VectorProperties.class, AwsProperties.class })
38+
@AutoConfigureAfter({ CredentialsProviderAutoConfiguration.class, RegionProviderAutoConfiguration.class })
39+
@ConditionalOnProperty(name = "spring.cloud.aws.s3.vector.enabled", havingValue = "true", matchIfMissing = true)
40+
public class S3VectorClientAutoConfiguration {
41+
42+
private final S3VectorProperties properties;
43+
44+
public S3VectorClientAutoConfiguration(S3VectorProperties properties) {
45+
this.properties = properties;
46+
}
47+
48+
@Bean
49+
@ConditionalOnMissingBean
50+
S3VectorsClientBuilder s3VectorsClientBuilder(AwsClientBuilderConfigurer awsClientBuilderConfigurer,
51+
ObjectProvider<AwsConnectionDetails> connectionDetails,
52+
ObjectProvider<S3VectorClientCustomizer> s3ClientCustomizers,
53+
ObjectProvider<AwsSyncClientCustomizer> awsSyncClientCustomizers) {
54+
55+
return awsClientBuilderConfigurer.configureSyncClient(S3VectorsClient.builder(), this.properties,
56+
connectionDetails.getIfAvailable(), s3ClientCustomizers.orderedStream(),
57+
awsSyncClientCustomizers.orderedStream());
58+
}
59+
60+
@Bean
61+
S3VectorsClient s3VectorsClient(S3VectorsClientBuilder builder) {
62+
return builder.build();
63+
}
64+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright 2013-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.awspring.cloud.autoconfigure.s3vectors;
17+
18+
import io.awspring.cloud.autoconfigure.AwsClientCustomizer;
19+
import software.amazon.awssdk.services.s3vectors.S3VectorsClientBuilder;
20+
21+
/**
22+
* Callback interface that can be used to customize a {@link S3VectorsClientBuilder}.
23+
*
24+
* @author Matej Nedic
25+
* @since 4.0.0
26+
*/
27+
@FunctionalInterface
28+
public interface S3VectorClientCustomizer extends AwsClientCustomizer<S3VectorsClientBuilder> {
29+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Copyright 2013-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.awspring.cloud.autoconfigure.s3vectors;
17+
18+
import io.awspring.cloud.autoconfigure.AwsClientProperties;
19+
import org.springframework.boot.context.properties.ConfigurationProperties;
20+
21+
/**
22+
* @author Matej Nedic
23+
* @since 4.0.0
24+
*/
25+
@ConfigurationProperties(prefix = S3VectorProperties.PREFIX)
26+
public class S3VectorProperties extends AwsClientProperties {
27+
28+
/**
29+
* The prefix used for S3 related properties.
30+
*/
31+
public static final String PREFIX = "spring.cloud.aws.s3.vector";
32+
33+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
* Copyright 2013-2022 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
/**
18+
* Auto-configuration for S3Vector integration.
19+
*/
20+
@org.springframework.lang.NonNullApi
21+
@org.springframework.lang.NonNullFields
22+
package io.awspring.cloud.autoconfigure.s3vectors;

spring-cloud-aws-autoconfigure/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ io.awspring.cloud.autoconfigure.ses.SesAutoConfiguration
77
io.awspring.cloud.autoconfigure.s3.S3TransferManagerAutoConfiguration
88
io.awspring.cloud.autoconfigure.s3.S3AutoConfiguration
99
io.awspring.cloud.autoconfigure.s3.S3CrtAsyncClientAutoConfiguration
10+
io.awspring.cloud.autoconfigure.s3vectors.S3VectorClientAutoConfiguration
1011
io.awspring.cloud.autoconfigure.sns.SnsAutoConfiguration
1112
io.awspring.cloud.autoconfigure.sqs.SqsAutoConfiguration
1213
io.awspring.cloud.autoconfigure.dynamodb.DynamoDbAutoConfiguration
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright 2013-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package io.awspring.cloud.autoconfigure.s3vectors;
17+
18+
import static org.assertj.core.api.Assertions.assertThat;
19+
20+
import io.awspring.cloud.autoconfigure.core.AwsAutoConfiguration;
21+
import io.awspring.cloud.autoconfigure.core.CredentialsProviderAutoConfiguration;
22+
import io.awspring.cloud.autoconfigure.core.RegionProviderAutoConfiguration;
23+
import org.junit.jupiter.api.Test;
24+
import org.springframework.boot.autoconfigure.AutoConfigurations;
25+
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
26+
import software.amazon.awssdk.services.s3vectors.S3VectorsClient;
27+
28+
/**
29+
* Test for {@link S3VectorAutoConfigurationTests} class
30+
*
31+
* @author Matej Nedic
32+
*/
33+
public class S3VectorAutoConfigurationTests {
34+
35+
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
36+
.withPropertyValues("spring.cloud.aws.region.static:eu-west-1")
37+
.withConfiguration(AutoConfigurations.of(AwsAutoConfiguration.class, RegionProviderAutoConfiguration.class,
38+
CredentialsProviderAutoConfiguration.class, S3VectorClientAutoConfiguration.class));
39+
40+
@Test
41+
void createsS3VectorClientBean() {
42+
this.contextRunner.run(context -> {
43+
assertThat(context).hasSingleBean(S3VectorsClient.class);
44+
});
45+
}
46+
47+
@Test
48+
void s3VectorClientAutoConfigurationIsDisabled() {
49+
this.contextRunner.withPropertyValues("spring.cloud.aws.s3.vector.enabled:false").run(context -> {
50+
assertThat(context).doesNotHaveBean(S3VectorsClient.class);
51+
});
52+
}
53+
}

0 commit comments

Comments
 (0)