Skip to content

Commit

Permalink
Add client customizer interface for each supported integration. (#1229)
Browse files Browse the repository at this point in the history
  • Loading branch information
maciejwalkowiak authored Sep 29, 2024
1 parent 2bf3fe8 commit 8020ef1
Show file tree
Hide file tree
Showing 47 changed files with 1,811 additions and 94 deletions.
27 changes: 27 additions & 0 deletions docs/src/main/asciidoc/cloudwatch.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,30 @@ Following configuration properties are available to configure CloudWatch integra
|
|The specific region for CloudWatch integration.
|===

=== Client Customization

`CloudWatchAsyncClient` can be further customized by providing a bean of type `CloudWatchAsyncClientCustomizer`:

[source,java]
----
@Bean
CloudWatchAsyncClientCustomizer customizer() {
return builder -> {
builder.overrideConfiguration(builder.overrideConfiguration().copy(c -> {
c.apiCallTimeout(Duration.ofMillis(1500));
}));
};
}
----

[WARNING]
====
`builder.overrideConfiguration(..)` replaces the configuration object, so always make sure to use `builder.overrideConfiguration().copy(c -> ..)` to configure only certain properties and keep the already pre-configured values for others.
====

`CloudWatchAsyncClientCustomizer` is a functional interface that enables configuring `CloudWatchAsyncClientBuilder` before the `CloudWatchAsyncClient` is built in auto-configuration.

There can be multiple `CloudWatchAsyncClientCustomizer` beans present in single application context. `@Order(..)` annotation can be used to define the order of the execution.

Note that `CloudWatchAsyncClientCustomizer` beans are applied **after** `AwsAsyncClientCustomizer` beans and therefore can overwrite previously set configurations.
63 changes: 37 additions & 26 deletions docs/src/main/asciidoc/core.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -214,38 +214,49 @@ To simplify using services with AWS compatible APIs, or running applications aga

=== Customizing AWS Clients

To configure an AWS client with custom HTTP client or `ClientOverrideConfiguration`, define a bean of type `AwsClientConfigurer` with a type parameter indicating configured client builder.
Properties cover the most common configuration needs. When more advanced configuration is required, Spring Cloud AWS offers a set of customizer interfaces that can be implemented to customize AWS clients.

[source,java,indent=0]
----
import io.awspring.cloud.autoconfigure.core.AwsClientCustomizer;
import org.springframework.context.annotation.Bean;
There are two types of AWS clients - synchronous and asynchronous. Each Spring Cloud AWS integration use one or the other type:

import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration;
import software.amazon.awssdk.http.SdkHttpClient;
import software.amazon.awssdk.http.apache.ApacheHttpClient;
import software.amazon.awssdk.services.sns.SnsClientBuilder;
[cols="2*", options="header"]
|===
|client type
|integrations

import java.time.Duration;
|synchronous
|DynamoDB, SES, SNS, Parameter Store, Secrets Manager, S3

@Configuration
class S3AwsClientConfigurerConfiguration {
|asynchronous
|SQS, CloudWatch
|===

@Bean
AwsClientCustomizer<S3ClientBuilder> s3ClientBuilderAwsClientConfigurer() {
return new S3AwsClientClientConfigurer();
}
To customize every synchronous client, provide a bean of type `AwsSyncClientCustomizer`. For example:

[source,java,indent=0]
----
import io.awspring.cloud.autoconfigure.AwsSyncClientCustomizer;
static class S3AwsClientClientConfigurer implements AwsClientCustomizer<S3ClientBuilder> {
@Override
public ClientOverrideConfiguration overrideConfiguration() {
return ClientOverrideConfiguration.builder().apiCallTimeout(Duration.ofMillis(500)).build();
}
@Bean
AwsSyncClientCustomizer awsSyncClientCustomizer() {
return builder -> {
builder.httpClient(ApacheHttpClient.builder().connectionTimeout(Duration.ofSeconds(1)).build());
};
}
----

@Override
public SdkHttpClient httpClient() {
return ApacheHttpClient.builder().connectionTimeout(Duration.ofMillis(1000)).build();
}
}
To customize every asynchronous client, provide a bean of type `AwsAsyncClientCustomizer`. For example:

[source,java,indent=0]
----
@Bean
AwsAsyncClientCustomizer awsAsyncClientCustomizer() {
return builder -> {
builder.httpClient(NettyNioAsyncHttpClient.builder().connectionTimeout(Duration.ofSeconds(1)).build());
};
}
----

There can be multiple customizer beans present in single application context and all of them will be used to configure AWS clients. If order of customizer matters, use `@Order` annotation on customizer beans.

Client-specific customizations can be applied through client-specific customizer interfaces (for example `S3ClientCustomizer` for S3). See integrations documentation for details.

27 changes: 27 additions & 0 deletions docs/src/main/asciidoc/dynamodb.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,33 @@ The Spring Boot Starter for DynamoDb provides the following configuration option
| `spring.cloud.aws.dynamodb.dax.skip-host-name-verification` | Skips hostname verification in url. | No |
|===

=== Client Customization

`DynamoDbClient` can be further customized by providing a bean of type `DynamoDbClientCustomizer`:

[source,java]
----
@Bean
DynamoDbClientCustomizer customizer() {
return builder -> {
builder.overrideConfiguration(builder.overrideConfiguration().copy(c -> {
c.apiCallTimeout(Duration.ofMillis(1500));
}));
};
}
----

[WARNING]
====
`builder.overrideConfiguration(..)` replaces the configuration object, so always make sure to use `builder.overrideConfiguration().copy(c -> ..)` to configure only certain properties and keep the already pre-configured values for others.
====

`DynamoDbClientCustomizer` is a functional interface that enables configuring `DynamoDbClientBuilder` before the `DynamoDbClient` is built in auto-configuration.

There can be multiple `DynamoDbClientCustomizer` beans present in single application context. `@Order(..)` annotation can be used to define the order of the execution.

Note that `DynamoDbClientCustomizer` beans are applied **after** `AwsSyncClientCustomizer` beans and therefore can overwrite previously set configurations.

=== IAM Permissions

Since it depends on how you will use DynamoDb integration providing a list of IAM policies would be pointless since least privilege model should be used.
Expand Down
25 changes: 8 additions & 17 deletions docs/src/main/asciidoc/parameter-store.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ The starter automatically configures and registers a `SsmClient` bean in the Spr

[source,java]
----
import org.springframework.stereotype.Component;
import org.springframework.beans.factory.annotation.Autowired;
import software.amazon.awssdk.services.ssm.SsmClient;
...
@Autowired
Expand Down Expand Up @@ -139,14 +139,14 @@ Note that this class must be listed under `org.springframework.boot.BootstrapReg
org.springframework.boot.BootstrapRegistryInitializer=com.app.ParameterStoreBootstrapConfiguration
----

If you want to use autoconfigured `SsmClient` but change underlying SDKClient or ClientOverrideConfiguration you will need to register bean of type `AwsClientConfigurerParameterStore`:
If you want to use autoconfigured `SsmClient` but change underlying `SDKClient` or `ClientOverrideConfiguration` you will need to register bean of type `SsmClientCustomizer`:
Autoconfiguration will configure `SsmClient` Bean with provided values after that, for example:

[source,java]
----
package com.app;
import io.awspring.cloud.autoconfigure.config.parameterstore.AwsParameterStoreClientCustomizer;
import io.awspring.cloud.autoconfigure.config.parameterstore.SsmClientCustomizer;
import java.time.Duration;
import org.springframework.boot.BootstrapRegistry;
import org.springframework.boot.BootstrapRegistryInitializer;
Expand All @@ -159,20 +159,11 @@ class ParameterStoreBootstrapConfiguration implements BootstrapRegistryInitializ
@Override
public void initialize(BootstrapRegistry registry) {
registry.register(AwsParameterStoreClientCustomizer.class,
context -> new AwsParameterStoreClientCustomizer() {
@Override
public ClientOverrideConfiguration overrideConfiguration() {
return ClientOverrideConfiguration.builder().apiCallTimeout(Duration.ofMillis(500))
.build();
}
@Override
public SdkHttpClient httpClient() {
return ApacheHttpClient.builder().connectionTimeout(Duration.ofMillis(1000)).build();
}
});
registry.register(SsmClientCustomizer.class, context -> (builder -> {
builder.overrideConfiguration(builder.overrideConfiguration().copy(c -> {
c.apiCallTimeout(Duration.ofMillis(2000));
}));
}));
}
}
----
Expand Down
27 changes: 27 additions & 0 deletions docs/src/main/asciidoc/s3.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,33 @@ The Spring Boot Starter for S3 provides the following configuration options:
| `spring.cloud.aws.s3.transfer-manager.follow-symbolic-links` | Specifies whether to follow symbolic links when traversing the file tree in `S3TransferManager#uploadDirectory` operation | No | `null` (falls back to SDK default)
|===

=== Client Customization

`S3Client` can be further customized by providing a bean of type `S3ClientCustomizer`:

[source,java]
----
@Bean
S3ClientCustomizer customizer() {
return builder -> {
builder.overrideConfiguration(builder.overrideConfiguration().copy(c -> {
c.apiCallTimeout(Duration.ofMillis(1500));
}));
};
}
----

[WARNING]
====
`builder.overrideConfiguration(..)` replaces the configuration object, so always make sure to use `builder.overrideConfiguration().copy(c -> ..)` to configure only certain properties and keep the already pre-configured values for others.
====

`S3ClientCustomizer` is a functional interface that enables configuring `S3ClientBuilder` before the `S3Client` is built in auto-configuration.

There can be multiple `S3ClientCustomizer` beans present in single application context. `@Order(..)` annotation can be used to define the order of the execution.

Note that `S3ClientCustomizer` beans are applied **after** `AwsSyncClientCustomizer` beans and therefore can overwrite previously set configurations.

=== IAM Permissions

Following IAM permissions are required by Spring Cloud AWS:
Expand Down
25 changes: 8 additions & 17 deletions docs/src/main/asciidoc/secrets-manager.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ The starter automatically configures and registers a `SecretsManagerClient` bean

[source,java]
----
import org.springframework.stereotype.Component;
import org.springframework.beans.factory.annotation.Autowired;
import software.amazon.awssdk.services.secretsmanager.SecretsManagerClient;
import software.amazon.awssdk.services.secretsmanager.model.CreateSecretRequest;
...
Expand Down Expand Up @@ -191,14 +191,14 @@ Note that this class must be listed under `org.springframework.boot.BootstrapReg
org.springframework.boot.BootstrapRegistryInitializer=com.app.SecretsManagerBootstrapConfiguration
----

If you want to use autoconfigured `SecretsManagerClient` but change underlying SDKClient or ClientOverrideConfiguration you will need to register bean of type `AwsClientConfigurerSecretsManager`:
If you want to use autoconfigured `SecretsManagerClient` but change underlying SDKClient or `ClientOverrideConfiguration` you will need to register bean of type `SecretsManagerClientCustomizer`:
Autoconfiguration will configure `SecretsManagerClient` Bean with provided values after that, for example:

[source,java]
----
package com.app;
import io.awspring.cloud.autoconfigure.config.secretsmanager.AwsSecretsManagerClientCustomizer;
import io.awspring.cloud.autoconfigure.config.secretsmanager.SecretsManagerClientCustomizer;
import java.time.Duration;
import org.springframework.boot.BootstrapRegistry;
import org.springframework.boot.BootstrapRegistryInitializer;
Expand All @@ -211,20 +211,11 @@ class SecretsManagerBootstrapConfiguration implements BootstrapRegistryInitializ
@Override
public void initialize(BootstrapRegistry registry) {
registry.register(AwsSecretsManagerClientCustomizer.class,
context -> new AwsSecretsManagerClientCustomizer() {
@Override
public ClientOverrideConfiguration overrideConfiguration() {
return ClientOverrideConfiguration.builder().apiCallTimeout(Duration.ofMillis(500))
.build();
}
@Override
public SdkHttpClient httpClient() {
return ApacheHttpClient.builder().connectionTimeout(Duration.ofMillis(1000)).build();
}
});
registry.register(SecretsManagerClientCustomizer.class, context -> (builder -> {
builder.overrideConfiguration(builder.overrideConfiguration().copy(c -> {
c.apiCallTimeout(Duration.ofMillis(2001));
}));
}));
}
}
----
Expand Down
27 changes: 27 additions & 0 deletions docs/src/main/asciidoc/ses.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,33 @@ spring.cloud.aws.ses.from-arn=arn:aws:ses:eu-west-1:123456789012:identity/exampl
spring.cloud.aws.ses.configuration-set-name=ConfigSet
----

=== Client Customization

`SesClient` can be further customized by providing a bean of type `SesClientCustomizer`:

[source,java]
----
@Bean
SesClientCustomizer customizer() {
return builder -> {
builder.overrideConfiguration(builder.overrideConfiguration().copy(c -> {
c.apiCallTimeout(Duration.ofMillis(1500));
}));
};
}
----

[WARNING]
====
`builder.overrideConfiguration(..)` replaces the configuration object, so always make sure to use `builder.overrideConfiguration().copy(c -> ..)` to configure only certain properties and keep the already pre-configured values for others.
====

`SesClientCustomizer` is a functional interface that enables configuring `SesClientBuilder` before the `SesClient` is built in auto-configuration.

There can be multiple `SesClientCustomizer` beans present in single application context. `@Order(..)` annotation can be used to define the order of the execution.

Note that `SesClientCustomizer` beans are applied **after** `AwsSyncClientCustomizer` beans and therefore can overwrite previously set configurations.

=== IAM Permissions
Following IAM permissions are required by Spring Cloud AWS:

Expand Down
29 changes: 28 additions & 1 deletion docs/src/main/asciidoc/sns.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,33 @@ The Spring Boot Starter for SNS provides the following configuration options:
| `spring.cloud.aws.sns.region` | Configures region used by `SnsClient`. | No | `eu-west-1`
|===

=== Client Customization

`SnsClient` can be further customized by providing a bean of type `SnsClientCustomizer`:

[source,java]
----
@Bean
SnsClientCustomizer customizer() {
return builder -> {
builder.overrideConfiguration(builder.overrideConfiguration().copy(c -> {
c.apiCallTimeout(Duration.ofMillis(1500));
}));
};
}
----

[WARNING]
====
`builder.overrideConfiguration(..)` replaces the configuration object, so always make sure to use `builder.overrideConfiguration().copy(c -> ..)` to configure only certain properties and keep the already pre-configured values for others.
====

`SnsClientCustomizer` is a functional interface that enables configuring `SnsClientBuilder` before the `SnsClient` is built in auto-configuration.

There can be multiple `SnsClientCustomizer` beans present in single application context. `@Order(..)` annotation can be used to define the order of the execution.

Note that `SnsClientCustomizer` beans are applied **after** `AwsSyncClientCustomizer` beans and therefore can overwrite previously set configurations.

=== IAM Permissions
Following IAM permissions are required by Spring Cloud AWS:

Expand All @@ -237,7 +264,7 @@ Following IAM permissions are required by Spring Cloud AWS:
| To publish notification you will also need | `sns:ListTopics`
| To use Annotation-driven HTTP notification endpoint | `sns:ConfirmSubscription`
| For resolving topic name to ARN | `sns:CreateTopic`
| For validating topic existence by ARN | `sns:GetTopicAttributes`
| For validating topic existence by ARN | `sns:GetTopicAttributes`
|===

Sample IAM policy granting access to SNS:
Expand Down
28 changes: 28 additions & 0 deletions docs/src/main/asciidoc/sqs.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -1682,6 +1682,34 @@ When providing a custom executor, it's important that it's configured to support
IMPORTANT: To avoid unnecessary thread hopping between blocking components, a `MessageExecutionThreadFactory` MUST be set to the executor.


=== Client Customization

`SqsAsyncClient` can be further customized by providing a bean of type `SqsAsyncClientCustomizer`:

[source,java]
----
@Bean
SqsAsyncClientCustomizer customizer() {
return builder -> {
builder.overrideConfiguration(builder.overrideConfiguration().copy(c -> {
c.apiCallTimeout(Duration.ofMillis(1500));
}));
};
}
----

[WARNING]
====
`builder.overrideConfiguration(..)` replaces the configuration object, so always make sure to use `builder.overrideConfiguration().copy(c -> ..)` to configure only certain properties and keep the already pre-configured values for others.
====

`SqsAsyncClientCustomizer` is a functional interface that enables configuring `SqsAsyncClientBuilder` before the `SqsAsyncClient` is built in auto-configuration.

There can be multiple `SqsAsyncClientCustomizer` beans present in single application context. `@Order(..)` annotation can be used to define the order of the execution.

Note that `SqsAsyncClientCustomizer` beans are applied **after** `AwsAsyncClientCustomizer` beans and therefore can overwrite previously set configurations.


=== IAM Permissions
Following IAM permissions are required by Spring Cloud AWS SQS:

Expand Down
Loading

0 comments on commit 8020ef1

Please sign in to comment.