diff --git a/docs/src/main/asciidoc/appconfig.adoc b/docs/src/main/asciidoc/appconfig.adoc index 6381c931a..0c159cf0a 100644 --- a/docs/src/main/asciidoc/appconfig.adoc +++ b/docs/src/main/asciidoc/appconfig.adoc @@ -112,8 +112,8 @@ org.springframework.boot.BootstrapRegistryInitializer=com.app.AppConfigBootstrap ---- -If you want to use autoconfigured `AppConfigDataClient` but change underlying SDKClient or `ClientOverrideConfiguration` you will need to register bean of type `AppConfigClientCustomizer`: -Autoconfiguration will configure `AppConfigDataClient` Bean with provided values after that, for example: +If you want to use the auto-configured `AppConfigDataClient` but change the underlying SDK client or `ClientOverrideConfiguration`, you will need to register a bean of type `AppConfigClientCustomizer`. +Auto-configuration will then configure the `AppConfigDataClient` bean with the provided values. For example: [source,java] ---- diff --git a/docs/src/main/asciidoc/cloudwatch.adoc b/docs/src/main/asciidoc/cloudwatch.adoc index 54bc22571..c19e2463b 100644 --- a/docs/src/main/asciidoc/cloudwatch.adoc +++ b/docs/src/main/asciidoc/cloudwatch.adoc @@ -12,7 +12,7 @@ To send metrics to CloudWatch add a dependency to `micrometer-registry-cloudwatc Additionally, CloudWatch integration requires a value provided for `management.cloudwatch.metrics.export.namespace` configuration property. -Following configuration properties are available to configure CloudWatch integration: +The following configuration properties are available to configure CloudWatch integration: [cols="3*", options="header"] |=== @@ -22,7 +22,7 @@ Following configuration properties are available to configure CloudWatch integra |management.cloudwatch.metrics.export.namespace | -|The namespace which will be used when sending metrics to CloudWatch. This property is needed and must not be null. +|The namespace used when sending metrics to CloudWatch. This property is required and must not be null. |management.cloudwatch.metrics.export.step |1m @@ -30,7 +30,7 @@ Following configuration properties are available to configure CloudWatch integra |spring.cloud.aws.cloudwatch.enabled |true -|If CloudWatch integration should be enabled. This property should be likely set to `false` for a local development profile. +|Whether CloudWatch integration is enabled. This property should typically be set to `false` for local development profiles. |spring.cloud.aws.cloudwatch.endpoint | @@ -89,6 +89,6 @@ CloudWatchAsyncClientCustomizer customizer() { `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. +There can be multiple `CloudWatchAsyncClientCustomizer` beans present in a single application context. The `@Order(..)` annotation can be used to define the order of execution. Note that `CloudWatchAsyncClientCustomizer` beans are applied **after** `AwsAsyncClientCustomizer` beans and therefore can overwrite previously set configurations. diff --git a/docs/src/main/asciidoc/contributing.adoc b/docs/src/main/asciidoc/contributing.adoc index de0d61696..b1a9ee081 100644 --- a/docs/src/main/asciidoc/contributing.adoc +++ b/docs/src/main/asciidoc/contributing.adoc @@ -1 +1 @@ -NOTE: Spring Cloud AWS is released under the non-restrictive Apache 2.0 license. If you would like to contribute to this section of the documentation or if you find an error, please find the source code and issue trackers in the project at https://github.com/awspring/spring-cloud-aws[github]. +NOTE: Spring Cloud AWS is released under the non-restrictive Apache 2.0 license. If you would like to contribute to this section of the documentation or if you find an error, please find the source code and issue tracker in the project at https://github.com/awspring/spring-cloud-aws[GitHub]. diff --git a/docs/src/main/asciidoc/core.adoc b/docs/src/main/asciidoc/core.adoc index a0e94b7ff..d5dbb00f6 100644 --- a/docs/src/main/asciidoc/core.adoc +++ b/docs/src/main/asciidoc/core.adoc @@ -26,7 +26,7 @@ public interface AwsCredentialsProvider { } ---- -There are 3 ways in which the `AwsCredentialsProvider` in Spring Cloud AWS can be configured: +There are three ways in which the `AwsCredentialsProvider` in Spring Cloud AWS can be configured: 1. `DefaultCredentialsProvider` 2. `StsWebIdentityTokenFileCredentialsProvider` - recommended for EKS @@ -47,7 +47,7 @@ By default, Spring Cloud AWS starter auto-configures a `DefaultCredentialsProvid 2. Environment Variables - `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` 3. Web Identity Token credentials from system properties or environment variables 4. Credential profiles file at the default location (`~/.aws/credentials`) shared by all AWS SDKs and the AWS CLI -5. Credentials delivered through the Amazon EC2 container service if `AWS_CONTAINER_CREDENTIALS_RELATIVE_URI`" environment variable is set and security manager has permission to access the variable, +5. Credentials delivered through the Amazon EC2 container service if the `AWS_CONTAINER_CREDENTIALS_RELATIVE_URI` environment variable is set and the security manager has permission to access the variable, 6. Instance profile credentials delivered through the Amazon EC2 metadata service If it does not serve your project needs, this behavior can be changed by setting additional properties: @@ -116,7 +116,7 @@ STS credentials configuration supports following properties: ==== Custom AwsCredentialsProvider -It is also possible to configure custom `AwsCredentialsProvider` bean which will prevent Spring Cloud AWS from auto-configuring credentials provider: +It is also possible to configure a custom `AwsCredentialsProvider` bean, which will prevent Spring Cloud AWS from auto-configuring a credentials provider: [source,java,indent=0] ---- @@ -146,7 +146,7 @@ public interface AwsRegionProvider { } ---- -By default, Spring Cloud AWS starter auto-configures a `DefaultAwsRegionProviderChain`, which looks resolves AWS region in this order: +By default, Spring Cloud AWS starter auto-configures a `DefaultAwsRegionProviderChain`, which resolves the AWS region in this order: 1. Check the `aws.region` system property for the region. 2. Check the `AWS_REGION` environment variable for the region. @@ -175,10 +175,10 @@ If it does not serve your project needs, this behavior can be changed by setting |spring.cloud.aws.region.profile.path |`~/.aws/credentials` -|The file path where the profile configuration file is located. Defaults to `~/.aws/credentials` if value is not provided +|The file path where the profile configuration file is located. Defaults to `~/.aws/credentials` if a value is not provided |=== -It is also possible to configure custom `AwsRegionProvider` bean which will prevent Spring Cloud AWS from auto-configuring region provider: +It is also possible to configure a custom `AwsRegionProvider` bean, which will prevent Spring Cloud AWS from auto-configuring a region provider: [source,java,indent=0] ---- @@ -256,7 +256,7 @@ AwsAsyncClientCustomizer awsAsyncClientCustomizer() { } ---- -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. +There can be multiple customizer beans present in a single application context, and all of them will be used to configure AWS clients. If the order of customizers matters, use the `@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. diff --git a/docs/src/main/asciidoc/dynamodb.adoc b/docs/src/main/asciidoc/dynamodb.adoc index 83acf7b22..48fc54794 100644 --- a/docs/src/main/asciidoc/dynamodb.adoc +++ b/docs/src/main/asciidoc/dynamodb.adoc @@ -1,7 +1,7 @@ [#spring-cloud-aws-dynamoDb] == DynamoDb Integration -https://aws.amazon.com/dynamodb/[DynamoDb] is a fully managed serverless key/value Nosql database designed for high performance. +https://aws.amazon.com/dynamodb/[DynamoDB] is a fully managed, serverless, key-value NoSQL database designed for high performance. A Spring Boot starter is provided to auto-configure DynamoDb integration beans. Maven coordinates, using <>: @@ -14,7 +14,7 @@ Maven coordinates, using <>: ---- -DynamoDb integration will only provide autoconfiguration and simple `DynamoDbOperations` which can be used to communicate with DynamoDb, build repositories and so on... +The DynamoDB integration provides auto-configuration and a `DynamoDbOperations` interface that can be used to communicate with DynamoDB, build repositories, and more. === DynamoDbOperations @@ -22,7 +22,7 @@ The starter automatically configures and registers a `DynamoDbOperations` bean p `DynamoDbTemplate` - a default `DynamoDbOperations` implementation - being built on top of `DynamoDbEnhancedClient` uses annotations provided by AWS. The list of supported annotations can be found https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/mapper/annotations/package-summary.html[here]. -`DynamoDbEnchancedClient` supports a programming model similar to JPA - where a class is turned into an entity through applying certain annotations: +`DynamoDbEnhancedClient` supports a programming model similar to JPA, where a class is turned into an entity by applying certain annotations: [source,java] ---- @@ -72,9 +72,9 @@ To use a custom implementation, declare a bean of type `DynamoDbTableNameResolve ==== Resolving Table Schema -To resolve a table schema for an entity, `DynamoDbTemplate` uses a bean of type `DynamoDbTableSchemaResolver`. The default implementation caches `TableSchema` objects in internal map. +To resolve a table schema for an entity, `DynamoDbTemplate` uses a bean of type `DynamoDbTableSchemaResolver`. The default implementation caches `TableSchema` objects in an internal map. To use custom implementation, declare a bean of type `DynamoDbTableSchemaResolver` and it will get injected into `DynamoDbTemplate` automatically during auto-configuration. -To register a custom table schema for a DynamoDB entity a bean of type `TableSchema` should be created: +To register a custom table schema for a DynamoDB entity, a bean of type `TableSchema` should be created: [source, java] ---- @Configuration @@ -91,9 +91,9 @@ IMPORTANT: Because of classloader related https://github.com/aws/aws-sdk-java-v2 === Using DynamoDb Client -Autoconfiguration automatically configures `DynamoDbClient` which can be used for low level api calls and `DynamoDbEnhancedClient` if `DynamoDbOperations` are not enough. +Auto-configuration automatically configures a `DynamoDbClient` for low-level API calls, and a `DynamoDbEnhancedClient` when `DynamoDbOperations` are not sufficient. -If autoconfigured `DynamoDbClient` or `DynamoDbEnhancedClient` bean configuration does not meet your needs, it can be replaced by creating your custom bean. +If the auto-configured `DynamoDbClient` or `DynamoDbEnhancedClient` bean configuration does not meet your needs, it can be replaced by declaring a custom bean. [source,java] ---- @@ -178,14 +178,14 @@ DynamoDbClientCustomizer customizer() { `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. +There can be multiple `DynamoDbClientCustomizer` beans present in a single application context. The `@Order(..)` annotation can be used to define the order of 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. -To check what IAM policies DynamoDb uses and see which ones you should use please check https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/using-identity-based-policies.html[IAM policies] +Since the required IAM permissions depend on which DynamoDB operations you use, a definitive list cannot be provided here. The principle of least privilege should be applied. +For a full list of available DynamoDB IAM policies, see https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/using-identity-based-policies.html[IAM policies for DynamoDB]. [#spring-integration-support] === Spring Integration Support diff --git a/docs/src/main/asciidoc/imds.adoc b/docs/src/main/asciidoc/imds.adoc index 62ed38ca8..dad4db4bb 100644 --- a/docs/src/main/asciidoc/imds.adoc +++ b/docs/src/main/asciidoc/imds.adoc @@ -1,20 +1,20 @@ [#spring-cloud-aws-imds] == Instance Metadata Service Integration -Spring Cloud AWS applications can use the Instance MetaData Service (IMDS) to acquire EC2 instance metadata when running within an EC2-based compute environment. This metadata can be used for a wide variety of reasons, including detecting the availability zone, public IP address, MAC address, and so on. When available, properties can be referenced using the @Value annotation: +Spring Cloud AWS applications can use the Instance Metadata Service (IMDS) to acquire EC2 instance metadata when running within an EC2-based compute environment. This metadata can be used for a wide variety of purposes, including detecting the availability zone, public IP address, MAC address, and more. When available, properties can be referenced using the `@Value` annotation: [source,java] ---- @Value("${placement/availability-zone}") String availabilityZone; -@Value("${public-ipv4"}") String publicIPAddress; +@Value("${public-ipv4}") String publicIPAddress; @Value("${mac}") String macAddress; ---- -A full list of instance metadata tags is available in the AWS reference documentation at link:https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-categories.html[AWS EC2 User Guide - Instance Metadata Categories]. Spring Cloud AWS always retrieves the "latest" categories of metadata and removes the prefix so that "/latest/meta-data/instance-id" is available as "instance-id". The "spring.cloud.aws" prefix is also omitted. +A full list of instance metadata categories is available in the AWS reference documentation: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-categories.html[AWS EC2 User Guide - Instance Metadata Categories]. Spring Cloud AWS always retrieves the "latest" categories of metadata and removes the prefix so that `/latest/meta-data/instance-id` is available as `instance-id`. The `spring.cloud.aws` prefix is also omitted. === Enabling -To enable instance metadata, add the spring-cloud-aws-starter-imds starter. +To enable instance metadata, add the `spring-cloud-aws-starter-imds` starter. [source,xml] ---- @@ -24,20 +24,20 @@ To enable instance metadata, add the spring-cloud-aws-starter-imds starter. ---- -This adds the software.amazon.awssdk/imds dependency to the classpath which is used to query the IMDS. Depending on resources, metadata loading can add a half-second delay to application start time. Loading can be explicitly disabled by setting spring.cloud.aws.imds.enabled propery: +This adds the `software.amazon.awssdk:imds` dependency to the classpath, which is used to query the IMDS. Depending on available resources, metadata loading can add up to half a second to application startup time. Loading can be explicitly disabled by setting the `spring.cloud.aws.imds.enabled` property: [source,properties] ---- spring.cloud.aws.imds.enabled=false ---- -Instance metadata is generally available on any EC2-based compute environment, which includes EC2, Elastic Beanstalk, Elastic Container Service (ECS), Elastic Kubernetes Service (EKS), etc. It is not available in non-EC2 environments such as Lambda or Fargate. Even within EC2-based compute environments instance metadata may be disabled or may be subject to an internal firewall which prohibits it. Whenever instance metadata is unavailable, including when running on a local environment, the autoconfiguration process silently ignores its absence. +Instance metadata is generally available in any EC2-based compute environment, including EC2, Elastic Beanstalk, Elastic Container Service (ECS), and Elastic Kubernetes Service (EKS). It is not available in non-EC2 environments such as Lambda or Fargate. Even within EC2-based environments, instance metadata may be disabled or subject to an internal firewall. Whenever instance metadata is unavailable — including when running locally — the auto-configuration process silently ignores its absence. === Considerations -Instance metadata is retrieved on a best effort basis and not all keys are always available. For example, the "ipv6" key would only be present if IPv6 addresses were being used, "public-hostname" would only be available for instances running in public subnets with DNS hostnames enabled. +Instance metadata is retrieved on a best-effort basis and not all keys are always present. For example, the `ipv6` key would only be present if IPv6 addresses are in use, and `public-hostname` would only be available for instances running in public subnets with DNS hostnames enabled. -Instance metadata is retrieved at application start time and is not updated as the application runs. Both IDMS v1 and v2 are supported. Certain keys / ranges are not retrieved, including "block-device-mapping/\*", "events/\*", "iam/security-credentials/\*", "network/interfaces/\*", "public-keys/\*", "spot/\*" for various reasons including security. For example, Some keys such as "spot/termination-time" are only reliable if polled on an interval; presenting their static values obtained at startup time would be deceptive. If you have such a requirement, consider polling the key yourself using the Ec2MetadataClient from the SDK: +Instance metadata is retrieved at application startup and is not updated while the application is running. Both IMDSv1 and IMDSv2 are supported. Certain key ranges are not retrieved, including `block-device-mapping/*`, `events/*`, `iam/security-credentials/*`, `network/interfaces/*`, `public-keys/*`, and `spot/*`, for various reasons including security. For example, keys such as `spot/termination-time` are only meaningful if polled on an interval; presenting their static values obtained at startup would be misleading. If you have such a requirement, consider polling the key directly using the `Ec2MetadataClient` from the AWS SDK: [source,java] ---- @@ -48,4 +48,3 @@ import software.amazon.awssdk.imds.Ec2MetadataResponse; @Autowired Ec2MetadataClient client; client.get("/latest/meta-data/spot/termination-time"); ---- - diff --git a/docs/src/main/asciidoc/index.adoc b/docs/src/main/asciidoc/index.adoc index 287ce51c2..10f51e7ca 100644 --- a/docs/src/main/asciidoc/index.adoc +++ b/docs/src/main/asciidoc/index.adoc @@ -9,19 +9,19 @@ include::contributing.adoc[] == Using Amazon Web Services -AWS provides a https://aws.amazon.com/sdk-for-java/[Java SDK] to issue requests for the all services provided by the -https://aws.amazon.com[Amazon Web Service] platform. While the SDK offers all functionality available on AWS, there is a considerable amount of low level code needed to use it in Spring idiomatic way. -Spring Cloud AWS provides application developers already integrated Spring-based modules to consume the most popular AWS services and avoid low level code as much as possible. +AWS provides a https://aws.amazon.com/sdk-for-java/[Java SDK] to issue requests for all services provided by the +https://aws.amazon.com[Amazon Web Services] platform. While the SDK offers all functionality available on AWS, there is a considerable amount of low-level code needed to use it in a Spring-idiomatic way. +Spring Cloud AWS provides application developers with pre-integrated Spring-based modules to consume the most popular AWS services and avoid low-level code as much as possible. -Thanks to Spring Cloud AWS modularity you can include only dependencies relevant to the particular AWS service you want to integrate with. +Thanks to Spring Cloud AWS's modularity, you can include only the dependencies relevant to the particular AWS service you want to integrate with. -It also simplifies creating any non-integrated AWS SDK client by auto-configuring region and credentials providers. +It also simplifies the creation of any non-integrated AWS SDK client by auto-configuring the region and credentials providers. -That being said, it is perfectly valid option to use AWS SDK without using Spring Cloud AWS. +That being said, it is a perfectly valid option to use the AWS SDK without using Spring Cloud AWS. [TIP] ==== -Note, that Spring provides support for other AWS services in following projects: +Note that Spring provides support for other AWS services in the following projects: * https://github.com/spring-cloud/spring-cloud-stream-binder-aws-kinesis[Spring Cloud Stream Binder AWS Kinesis] * https://github.com/spring-cloud/spring-cloud-config[Spring Cloud Config Server] supports AWS Parameter Store and Secrets Manager @@ -72,7 +72,7 @@ Each starter contains all the dependencies and transitive dependencies needed to For example, if you wish to write a Spring application with S3, you would include the `spring-cloud-aws-starter-s3` dependency in your project. You do *not* need to include the underlying `spring-cloud-aws-s3` dependency, because the `starter` dependency includes it. -A summary of these artifacts are provided below. +A summary of these artifacts is provided below. |=== | Spring Cloud AWS Starter | Description | Maven Artifact Name @@ -117,8 +117,8 @@ A summary of these artifacts are provided below. === Choosing AWS SDK version -The AWS SDK is released more frequently than Spring Cloud AWS. If you need to use a newer version of the SDK than -the one configured by Spring Cloud AWS, add the SDK BOM to the dependency management section making sure it is declared +The AWS SDK is released more frequently than Spring Cloud AWS. If you need to use a newer version of the SDK than +the one configured by Spring Cloud AWS, add the SDK BOM to the dependency management section, making sure it is declared before any other BOM dependency that configures AWS SDK dependencies. [source,xml,indent=0] diff --git a/docs/src/main/asciidoc/intro.adoc b/docs/src/main/asciidoc/intro.adoc index ad998ba12..37f617bc8 100644 --- a/docs/src/main/asciidoc/intro.adoc +++ b/docs/src/main/asciidoc/intro.adoc @@ -1 +1 @@ -Spring Cloud AWS simplifies using AWS managed services in a Spring and Spring Boot applications. It offers a convenient way to interact with AWS provided services using well-known Spring idioms and APIs. +Spring Cloud AWS simplifies using AWS managed services in Spring and Spring Boot applications. It offers a convenient way to interact with AWS-provided services using well-known Spring idioms and APIs. diff --git a/docs/src/main/asciidoc/kinesis-stream-binder.adoc b/docs/src/main/asciidoc/kinesis-stream-binder.adoc index 2e5cd0451..3590b27ee 100644 --- a/docs/src/main/asciidoc/kinesis-stream-binder.adoc +++ b/docs/src/main/asciidoc/kinesis-stream-binder.adoc @@ -28,7 +28,7 @@ image::images/kinesis-binder.png[width=300,scaledwidth="50%"] Unlike https://kafka.apache.org/[Apache Kafka], the AWS Kinesis doesn't provide out-of-the-box support for consumer groups. The support of this feature is implemented as a part of `MetadataStore` key for shard checkpoints in the `KinesisMessageDrivenChannelAdapter` - `[CONSUMER_GROUP]:[STREAM]:[SHARD_ID]`. In addition, the `LockRegistry` is used to ensure exclusive access to each shard. -This way only one channel adapter in the same consumer group will consumer messages from a single shard in the stream it is configured for. +This ensures that only one channel adapter in the same consumer group will consume messages from a single shard in the stream it is configured for. The partitioning logic in AWS Kinesis is similar to the Apache Kafka support but with slightly different logic. The `partitionKey` on the producer side determines which shard in the stream the data record is assigned to. @@ -36,8 +36,8 @@ Partition keys are Unicode strings with a maximum length limit of 256 characters AWS Kinesis uses the partition key as input to a hash function that maps the partition key and associated data to a specific shard. Specifically, an MD5 hash function is used to map partition keys to 128-bit integer values and to map associated data records to shards. As a result of this hashing mechanism, all data records with the same partition key map to the same shard within the stream. -But at the same time we can't select a target shard to send explicitly. -Although calculating the hash manually (and use `explicitHashKeyExpression` for producer, respectively), we may track the target shard by inclusion into its `HashKeyRange`. +However, it is not possible to explicitly select a target shard for sending. +By calculating the hash manually and using `explicitHashKeyExpression` on the producer side, the target shard can be tracked by checking inclusion in its `HashKeyRange`. By default, a partition key is a result of the `Object.hash()` from the message `payload`. @@ -47,7 +47,7 @@ On the consumer side the `instanceCount` and `instanceIndex` are used to distrib This has an effect only for regular `KinesisMessageDrivenChannelAdapter` which can assign specific shards for the target Kinesis consumer. == Consumer Groups -Consumer groups are implemented with a focus on high availability, message ordering and guaranteed message delivery in Spring cloud stream. +Consumer groups are implemented with a focus on high availability, message ordering, and guaranteed message delivery in Spring Cloud Stream. A `single consumer` for the message is ensured by https://docs.spring.io/spring-cloud-stream/reference/spring-cloud-stream/consumer-groups.html[consumer group abstraction]. To have a highly available consumer group for your kinesis stream: @@ -169,8 +169,8 @@ See https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/TTL.html[Dy No default - means no record expiration. === LockRegistry -LockRegistry is used to ensure exclusive access to each shard so that only one channel adapter in the same consumer group will consumer messages from a single shard in the stream. -This is implemented using xref:dynamodb.adoc#spring-integration-support[DynamoDbLockRegistry] +The `LockRegistry` is used to ensure exclusive access to each shard so that only one channel adapter in the same consumer group will consume messages from a single shard in the stream. +This is implemented using xref:dynamodb.adoc#spring-integration-support[DynamoDbLockRegistry]. DynamoDB `LockRegistry` properties are prefixed with `spring.cloud.stream.kinesis.binder.locks.` @@ -464,7 +464,7 @@ If you're going to allow spring-cloud-stream-binder-kinesis to create the resour } ---- -If [Server-Side Encryption](https://docs.aws.amazon.com/streams/latest/dev/what-is-sse.html) is enabled, you'll need the following set of policies to encrypt and decrypt Kinesis messages. +If https://docs.aws.amazon.com/streams/latest/dev/what-is-sse.html[Server-Side Encryption] is enabled, you will need the following policies to encrypt and decrypt Kinesis messages. [source,json] ---- { diff --git a/docs/src/main/asciidoc/kinesis.adoc b/docs/src/main/asciidoc/kinesis.adoc index 2f8532db9..cb86b76f3 100644 --- a/docs/src/main/asciidoc/kinesis.adoc +++ b/docs/src/main/asciidoc/kinesis.adoc @@ -7,17 +7,17 @@ The https://aws.amazon.com/kinesis/[Kinesis] is a platform for streaming data on === Spring Integration Support -Also, starting with version 4.0, Spring Cloud AWS provides https://spring.io/projects/spring-integration[Spring Integration] channel adapters for Amazon Kinesis. +Starting with version 4.0, Spring Cloud AWS provides https://spring.io/projects/spring-integration[Spring Integration] channel adapters for Amazon Kinesis. The `KinesisMessageHandler` is an `AbstractMessageHandler` to perform put record(s) to the Kinesis stream. The stream, partition key (or explicit hash key) and sequence number can be determined against a request message via evaluation provided expressions or can be specified statically. They also can be specified as `KinesisHeaders.STREAM`, `KinesisHeaders.PARTITION_KEY` and `KinesisHeaders.SEQUENCE_NUMBER` respectively. The `KinesisMessageHandler` can be configured with the `outputChannel` for sending a `Message` on successful put operation. -The payload is the original request and additional `KinesisHeaders.SHARD` and `KinesisHeaders.SEQUENCE_NUMBER` headers are populated from the `PutRecordResposne`. +The payload is the original request, and the `KinesisHeaders.SHARD` and `KinesisHeaders.SEQUENCE_NUMBER` headers are populated from the `PutRecordResponse`. If the request payload is a `PutRecordsRequest`, the full `PutRecordsResponse` is populated in the `KinesisHeaders.SERVICE_RESULT` header instead. -When an async failure is happened on the put operation, the `ErrorMessage` is sent to the `errorChannel` header or global one. +When an async failure occurs during the put operation, an `ErrorMessage` is sent to the `errorChannel` header or to the global error channel. The payload is an `MessageHandlingException`. The `payload` of request message can be: @@ -49,7 +49,7 @@ An offset of the records for the consuming shard is stored in the `ConcurrentMet If the `CheckpointMode` of the `KinesisMessageDrivenChannelAdapter` is set to `manual`, then `KinesisHeaders.CHECKPOINTER` is populated to the message this channel adapter produces downstream. The check-pointed offset is used to initiate an iterator on the shard after the application restart. -The `KinesisMessageDrivenChannelAdapter` can be configured with a distributed `LockRegistry` to managed exclusive access to the shard in the cluster of the application consuming from the Kinesis. +The `KinesisMessageDrivenChannelAdapter` can be configured with a distributed `LockRegistry` to manage exclusive access to shards across a cluster of application instances consuming from Kinesis. For example, the xref:dynamodb.adoc#spring-integration-support[`DynamoDbLockRegistry`] can be used to manage distributed locks via DynamoDB. In the case of many instances of the same consuming application in cluster, a distributed implementation of the `ConcurrentMetadataStore` is recommended, too, e.g. xref:dynamodb.adoc#spring-integration-support[`DynamoDbMetadataStore`]. This way, when one instance leaves the cluster, it releases its locks for shards, and another instance can obtain those locks and continue consuming from the shard according to the stored offset in the mentioned shared meta-data store. @@ -60,7 +60,7 @@ The `KinesisShardOffset` abstraction is used to represent an initial shard itera Or it can be used as an argument of the overloaded `KinesisMessageDrivenChannelAdapter` to consume from the specific shards. The concurrency and checkpoint management remain the same even for an explicit shard configuration. -The `KinesisMessageDrivenChannelAdapter` also supports a `batch` mode to produce a message with a payload as a list of just returned by the shard iterator records. +The `KinesisMessageDrivenChannelAdapter` also supports a `batch` mode that produces a message with a payload containing a list of records returned by the shard iterator. Each record data can be converted from `byte[]` via `Converter` setting. By default, a `DeserializingConverter` is used based on Java serialization specification. Which is aligned with the settings of the mentioned above `KinesisMessageHandler`. @@ -119,7 +119,7 @@ The configuration and behavior are similar to the `KinesisMessageHandler` descri The request message payload could be as a `UserRecord`. Otherwise, such an instance is built against request messages and respective `KplMessageHandler` options, include https://docs.aws.amazon.com/streams/latest/dev/kpl-with-schemaregistry.html[AWS Glue Schema] for the record serialization. -Due to asynchronous behavior and buffer of the `KinesisProducer`, a `KplBackpressureException` could be thrown from the `KplMessageHandler` when `backPressureThreshold` as the number of outstanding records is provided. +Due to the asynchronous nature and internal buffering of the `KinesisProducer`, a `KplBackpressureException` may be thrown from the `KplMessageHandler` when a `backPressureThreshold` is configured as the maximum number of outstanding records. The configuration of the `KplMessageHandler` is straightforward: @@ -155,7 +155,7 @@ Therefore, a `CloudWatchAsyncClient` and `DynamoDbAsyncClient` can also be injec They are used by the KCL for checkpointing and `Kinesis` consumers coordination. By default, this channel adapter relies on the https://docs.aws.amazon.com/streams/latest/dev/building-enhanced-consumers-api.html[fan-out] retrieval strategy. -The configuration of the `KclMessageDrivenChannelAdapter` is like following: +The configuration of the `KclMessageDrivenChannelAdapter` is as follows: [source,java] ---- diff --git a/docs/src/main/asciidoc/migration.adoc b/docs/src/main/asciidoc/migration.adoc index 7b4678f5d..c285257fa 100644 --- a/docs/src/main/asciidoc/migration.adoc +++ b/docs/src/main/asciidoc/migration.adoc @@ -49,7 +49,7 @@ spring.security.oauth2.resourceserver.jwt.issuer-uri=http://127.0.0.1:4566/us-ea spring.security.oauth2.resourceserver.jwt.jwk-set-uri=http://127.0.0.1:4566/us-east-1_f865f8979c4d4361b6af703db533dbb4/.well-known/jwks.json ---- -The example above set the URIs to LocalStack's Cognito Server. +The example above sets the URIs to LocalStack's Cognito server. === Parameter store migration @@ -59,7 +59,7 @@ In 2.x, parameter store items were resolved using a combination of the following * `aws.paramstore.defaultContext` for shared config items * `aws.paramstore.name` for application-specific config items -For example, if all you had done was set `aws.paramstore.enabled=true`, and your `spring.application.name` was `my-service`, then parameter store items could be resolved from either `/config/application` (for shared config items) and `/config/my-service` (for application specific config items) +For example, if all you had done was set `aws.paramstore.enabled=true`, and your `spring.application.name` was `my-service`, then parameter store items could be resolved from either `/config/application` (for shared config items) or `/config/my-service` (for application-specific config items). If you overrode one or more of the settings, then there could potentially be other prefixes where the application would look for parameters. diff --git a/docs/src/main/asciidoc/parameter-store.adoc b/docs/src/main/asciidoc/parameter-store.adoc index 2de39f024..0f9930167 100644 --- a/docs/src/main/asciidoc/parameter-store.adoc +++ b/docs/src/main/asciidoc/parameter-store.adoc @@ -36,7 +36,7 @@ spring.config.import=aws-parameterstore:/config/spring/ Two parameters are added to environment: `message` and `httpUrl`. -If a given path in Parameter Store does not exist, application will fail to start. If parameters retrieved from Parameter Store are not required for the application, and it should continue to startup even when the path is missing, add `optional` before prefix: +If a given path in Parameter Store does not exist, the application will fail to start. If parameters retrieved from Parameter Store are not required for the application and it should continue to start up even when the path is missing, add `optional` before the prefix: [source,properties] ---- @@ -63,7 +63,7 @@ these will become accessible as array properties `cloud.aws.stack[0].name`, `clo ==== Adding prefix to property keys -To avoid property key collisions it is possible to configure a property key prefix that gets added to each resolved parameter. +To avoid property key collisions, it is possible to configure a property key prefix that is added to each resolved parameter. As an example, assuming the following parameters are stored under path `/config/my-datasource/`: @@ -88,14 +88,14 @@ With such config, properties `spring.datasource.url` and `spring.datasource.user NOTE: Prefixes are added as-is to all property names returned by Parameter Store. If you want key names to be separated with a dot between the prefix and key name, make sure to add a trailing dot to the prefix. -Sometimes it is useful to group multiple properties in a text-based format, similar to application.properties. With Spring Cloud AWS, you can load a Parameter Store parameter as a text-based key/value configuration by using the spring.config.import property with the ?extension= suffix: +Sometimes it is useful to group multiple properties in a text-based format, similar to `application.properties`. With Spring Cloud AWS, you can load a Parameter Store parameter as a text-based key/value configuration by using the `spring.config.import` property with the `?extension=` suffix: [source,properties] ---- spring.config.import=aws-parameterstore:/config/my-datasource/?extension=properties ---- -NOTE: Supported ?extension= types are `properties`, `json` and `yaml`. When any other format is specified exception will be raised and application will fail to start! +NOTE: Supported `?extension=` types are `properties`, `json`, and `yaml`. If any other format is specified, an exception will be raised and the application will fail to start. All parameters stored under this path will be interpreted as key/value pairs. For example, if the value of a parameter is: @@ -106,9 +106,10 @@ my.properties.sqs.queue_name=random_name my.properties.dynamodb.table_name=random_table_name ---- -Spring Cloud AWS will automatically load these as: -Key: `my.properties.sqs.queue_name`, Value: `random_name` -Key: `my.properties.dynamodb.table_name`, Value: `random_table_name` +Spring Cloud AWS automatically loads these as: + +* Key: `my.properties.sqs.queue_name`, Value: `random_name` +* Key: `my.properties.dynamodb.table_name`, Value: `random_table_name` NOTE: Standard Parameter Store parameters are limited to 4 KB of data. @@ -166,8 +167,8 @@ 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 `SsmClientCustomizer`: -Autoconfiguration will configure `SsmClient` Bean with provided values after that, for example: +If you want to use the auto-configured `SsmClient` but change the underlying SDK client or `ClientOverrideConfiguration`, you will need to register a bean of type `SsmClientCustomizer`. +Auto-configuration will then configure the `SsmClient` bean with the provided values. For example: [source,java] ---- @@ -200,7 +201,7 @@ class ParameterStoreBootstrapConfiguration implements BootstrapRegistryInitializ Some applications may need to detect changes on external property sources and update their internal status to reflect the new configuration. The reload feature of Spring Cloud AWS Parameter Store integration is able to trigger an application reload when a related parameter value changes. -By default, this feature is disabled. You can enable it by using the `spring.cloud.aws.parameterstore.reload.strategy` configuration property (for example, in the `application.properties` file) and adding following dependencies: +By default, this feature is disabled. You can enable it by using the `spring.cloud.aws.parameterstore.reload.strategy` configuration property (for example, in the `application.properties` file) and adding the following dependencies: [source,xml] ---- @@ -269,18 +270,18 @@ public class MyBean { } ---- -The reload feature periodically re-creates the configuration from config maps and secrets to see if it has changed. -You can configure the polling period by using the `spring.cloud.aws.parameter.reload.period` (default value is 1 minute). +The reload feature periodically re-creates the configuration from Parameter Store to see if it has changed. +You can configure the polling period by using the `spring.cloud.aws.parameterstore.reload.period` property (default value is 1 minute). === Loading properties using profiles -When using `spring.config.import` feature it is not possible to `bind` profile specific values from properties. -This is very important design specification to have in mind when working with Parameterstore integration and profile specific configuration properties. +When using the `spring.config.import` feature, it is not possible to bind profile-specific values from properties. +This is an important design consideration when working with Parameter Store integration and profile-specific configuration properties. -Let's say you have 3 profiles `dev`, `uat` and `prod`. -In `dev` profile you don't want to have loading from Parameterstore, but in other profiles you want load to happen. +For example, consider three profiles: `dev`, `uat`, and `prod`. +In the `dev` profile you may not want to load from Parameter Store, whereas in other profiles you do. -Our recommended way is to use `spring.config.import=aws-parameterstore:/` in profile `application-$\{profile\}.properties` specific configuration files. +The recommended approach is to use `spring.config.import=aws-parameterstore:/` in profile-specific `application-$\{profile\}.properties` configuration files. `application.properties` [source,properties] @@ -310,8 +311,8 @@ spring.cloud.aws.parameterstore.reload.max-wait-for-restart=60s ---- -With this setup in place you won't be using integration in `dev` profile, but you would be using it in other active profiles. -This means you want to place `spring.config.import` in profile specific configuration property. +With this setup, Parameter Store integration is not active in the `dev` profile, but is active in other profiles. +The `spring.config.import` property should therefore be placed in the relevant profile-specific configuration file. @@ -332,7 +333,7 @@ The Spring Boot Starter for Parameter Store provides the following configuration |=== === IAM Permissions -Following IAM permissions are required by Spring Cloud AWS: +The following IAM permissions are required by Spring Cloud AWS: [cols="2"] |=== diff --git a/docs/src/main/asciidoc/s3.adoc b/docs/src/main/asciidoc/s3.adoc index c65e7be23..c9da36fa0 100644 --- a/docs/src/main/asciidoc/s3.adoc +++ b/docs/src/main/asciidoc/s3.adoc @@ -1,7 +1,7 @@ [#spring-cloud-aws-s3] == S3 Integration -https://aws.amazon.com/s3/[S3] allows storing files in a cloud. +https://aws.amazon.com/s3/[S3] allows storing files in the cloud. A Spring Boot starter is provided to auto-configure the various S3 integration related components. Maven coordinates, using <>: @@ -62,7 +62,7 @@ The starter automatically configures and registers a `software.amazon.awssdk.tra ---- -Transfer Manager works the best with CRT S3 Client. To auto-configure CRT based `S3AsyncClient` add following dependency to your project: +Transfer Manager works best with the CRT-based S3 Client. To auto-configure a CRT-based `S3AsyncClient`, add the following dependency to your project: [source,xml] ---- @@ -72,7 +72,7 @@ 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`. +When no `S3AsyncClient` bean is created, the default `S3AsyncClient` provided by the AWS SDK is used. To benefit from maximum throughput, multipart upload/download, and resumable file upload, consider using a CRT-based `S3AsyncClient`. === S3 Objects as Spring Resources @@ -129,10 +129,10 @@ try (OutputStream outputStream = s3Resource.getOutputStream()) { === S3 Client Side Encryption -AWS offers encryption library which is integrated inside of S3 Client called https://docs.aws.amazon.com/amazon-s3-encryption-client/latest/developerguide/what-is-s3-encryption-client.html[S3EncryptionClient]. -With encryption client you are going to encrypt your files before sending them to S3 bucket. +AWS offers an encryption library integrated with the S3 Client, called the https://docs.aws.amazon.com/amazon-s3-encryption-client/latest/developerguide/what-is-s3-encryption-client.html[S3EncryptionClient]. +The encryption client encrypts files before they are sent to the S3 bucket. -To autoconfigure Encryption Client simply add the following dependency. +To auto-configure the encryption client, add the following dependency. [source,xml] ---- @@ -143,13 +143,13 @@ To autoconfigure Encryption Client simply add the following dependency. ---- -We are supporting 3 types of encryption. +Three types of encryption are supported. ==== KMS Key Encryption -To configure encryption via KMS key specify `spring.cloud.aws.s3.encryption.key-id` with KMS key arn and this key will be used to encrypt your files. +To configure encryption via a KMS key, set `spring.cloud.aws.s3.encryption.key-id` to the KMS key ARN. That key will then be used to encrypt files. -Also, following dependency is required. +The following dependency is also required. [source,xml] ---- @@ -162,7 +162,7 @@ Also, following dependency is required. ==== RSA Asymmetric Encryption -Asymmetric encryption is possible via RSA. To enable it you will have to implement `io.awspring.cloud.autoconfigure.s3.S3RsaProvider`. +Asymmetric encryption is supported via RSA. To enable it, implement `io.awspring.cloud.autoconfigure.s3.S3RsaProvider`. NOTE: You will have to store private and public keys yourself otherwise you won't be able to decrypt the data later. @@ -190,7 +190,7 @@ public class MyRsaProvider implements S3RsaProvider { ==== AES Symmetric Encryption -If you want to use symmetric algorithm, this is possible via `io.awspring.cloud.autoconfigure.s3.S3AesProvider`. +If you want to use a symmetric algorithm, this is possible via `io.awspring.cloud.autoconfigure.s3.S3AesProvider`. NOTE: Ensure the private key is stored using secure storage mechanisms that prevent unauthorized access. @@ -219,7 +219,7 @@ public class MyAesProvider implements S3AesProvider { === S3 Output Stream -Under the hood by default `S3Resource` uses a `io.awspring.cloud.s3.InMemoryBufferingS3OutputStream`. When data is written to the resource, is gets sent to S3 using multipart upload. +By default, `S3Resource` uses `io.awspring.cloud.s3.InMemoryBufferingS3OutputStream`. When data is written to the resource, it is sent to S3 using multipart upload. If a network error occurs during upload, `S3Client` has a built-in retry mechanism that will retry each failed part. If the upload fails after retries, multipart upload gets aborted and `S3Resource` throws `io.awspring.cloud.s3.S3Exception`. If `InMemoryBufferingS3OutputStream` behavior does not fit your needs, you can use `io.awspring.cloud.s3.DiskBufferingS3OutputStream` by defining a bean of type `DiskBufferingS3OutputStreamProvider` which will override the default output stream provider. @@ -278,10 +278,10 @@ Resolving resources throughout all buckets can be very time consuming depending === Using S3 Access grants -Sometimes there is a need to make access control to S3 bucket contents fine grained. -Since IAM polices and S3 Policies only support 10kbs size, S3 Access Grant is solving this by allowing fine grained access control over content in bucket. +Sometimes there is a need for fine-grained access control over S3 bucket contents. +Since IAM policies and S3 bucket policies are limited to 10 KB in size, S3 Access Grants address this by enabling fine-grained access control over objects in a bucket. -To use S3 Access Grants out of the box with `S3Client` and `S3Template` introduce following plugin: +To use S3 Access Grants with `S3Client` and `S3Template`, add the following plugin: [source,xml] ---- @@ -293,9 +293,9 @@ To use S3 Access Grants out of the box with `S3Client` and `S3Template` introduc === Using S3Template -Spring Cloud AWS provides a higher abstraction on the top of `S3Client` providing methods for the most common use cases when working with S3. +Spring Cloud AWS provides a higher-level abstraction on top of `S3Client`, offering methods for the most common use cases when working with S3. -On the top of self-explanatory methods for creating and deleting buckets, `S3Template` provides a simple methods for uploading and downloading files: +In addition to self-explanatory methods for creating and deleting buckets, `S3Template` provides simple methods for uploading and downloading files: [source,java] ---- @@ -328,7 +328,7 @@ Person loadedPerson = s3Template.read(BUCKET, "person.json", Person.class); By default, if Jackson 3 is on the classpath, `S3Template` uses `JsonMapper` based `Jackson2JsonS3ObjectConverter` to convert from S3 object to Java object and vice versa. If Jackson 3 is not on classpath and Jackson 2 is, `S3Template` uses `ObjectMapper` based `LegacyJackson2JsonS3ObjectConverter` to convert from S3 object to Java object and vice versa. -This behavior can be overwritten by providing custom bean of type `S3ObjectConverter`. +This behavior can be overridden by providing a custom bean of type `S3ObjectConverter`. === Determining S3 Objects Content Type @@ -383,13 +383,13 @@ S3ClientCustomizer customizer() { `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. +There can be multiple `S3ClientCustomizer` beans present in a single application context. The `@Order(..)` annotation can be used to define the order of execution. Note that `S3ClientCustomizer` beans are applied **after** `AwsSyncClientCustomizer` beans and therefore can overwrite previously set configurations. === Loading External Configuration -Just like Spring Boot supports configuring application through `application.properties` stored in the file system, Spring Cloud AWS S3 integration extends this capability with fetching application configuration the S3 bucket through `spring.config.import` property. +Just as Spring Boot supports configuring an application through an `application.properties` file stored in the file system, Spring Cloud AWS S3 integration extends this capability by fetching application configuration from an S3 bucket via the `spring.config.import` property. For example, assuming that there is a file `config.properties` in a bucket named `bucket-name`, to include it as Spring Boot configuration, add a following property to `application.properties` or `application.yml`: @@ -398,7 +398,7 @@ For example, assuming that there is a file `config.properties` in a bucket named spring.config.import=aws-s3:/bucket-name/config.properties ---- -If a file with given name does not exist in S3, application will fail to start. If file configuration is not required for the application, and it should continue to startup even when file configuration is missing, add `optional` before prefix: +If a file with the given name does not exist in S3, the application will fail to start. If the file configuration is not required for the application and it should continue to start up even when the file is missing, add `optional` before the prefix: [source,properties] ---- @@ -420,7 +420,7 @@ spring.config.import[0]=optional:bucket-name/config.properties spring.config.import[1]=aws-s3=/another-name/config.yml ---- -Fetched files configuration can be referenced with `@Value`, bound to `@ConfigurationProperties` classes, or referenced in `application.properties` file. +Fetched file configuration can be referenced with `@Value`, bound to `@ConfigurationProperties` classes, or referenced in the `application.properties` file. `JSON`, Java Properties and `YAML` configuration file formats are supported. @@ -486,8 +486,8 @@ Note that this class must be listed under `org.springframework.boot.BootstrapReg org.springframework.boot.BootstrapRegistryInitializer=com.app.S3ClientBootstrapConfiguration ---- -If you want to use autoconfigured `S3Client` but change underlying SDKClient or `ClientOverrideConfiguration` you will need to register bean of type `S3ClientCustomizer`: -Autoconfiguration will configure `S3Client` Bean with provided values after that, for example: +If you want to use the auto-configured `S3Client` but change the underlying SDK client or `ClientOverrideConfiguration`, you will need to register a bean of type `S3ClientCustomizer`. +Auto-configuration will then configure the `S3Client` bean with the provided values. For example: [source,java] ---- @@ -562,7 +562,7 @@ management: Assuming that the reload feature is enabled with default settings (`refresh` mode), the following bean is refreshed when the file changes: ==== -[java, source] +[source,java] ---- @Configuration @ConfigurationProperties(prefix = "bean") @@ -630,7 +630,7 @@ To enable autoconfiguration you should add the following dependencies ---- -After dependencies are introduced Spring Cloud AWS will automatically create a `S3VectorsClient` bean which can than be autowired and used. +Once these dependencies are present, Spring Cloud AWS will automatically create an `S3VectorsClient` bean, which can then be autowired and used. [cols="2,3,1,1"] |=== @@ -643,7 +643,7 @@ After dependencies are introduced Spring Cloud AWS will automatically create a ` === IAM Permissions -Following IAM permissions are required by Spring Cloud AWS: +The following IAM permissions are required by Spring Cloud AWS: [cols="2,3,1,1"] |=== @@ -683,7 +683,7 @@ Sample IAM policy granting access to `spring-cloud-aws-demo` bucket: === Spring Integration Support -Starting with version 4.0, Spring Cloud AWS provides https://spring.io/projects/spring-integration[Spring Integration] channel adapters for Amazon SQS. +Starting with version 4.0, Spring Cloud AWS provides https://spring.io/projects/spring-integration[Spring Integration] channel adapters for Amazon S3. The S3 Channel Adapters are based on the `S3Client` template and `S3TransferManager`. See their specification and Javadocs for more information. @@ -783,10 +783,10 @@ public class S3JavaApplication { } ---- -> NOTE: Unlike the non-streaming inbound channel adapter, this adapter does not prevent duplicates by default. -> If you do not delete the remote file and wish to prevent the file being processed again, you can configure an `S3PersistentFileListFilter` in the `filter` attribute. -> If you don’t want to persist the state, an in-memory `SimpleMetadataStore` can be used with the filter. -> If you wish to use a filename pattern (or regex) as well, use a `CompositeFileListFilter`. +NOTE: Unlike the non-streaming inbound channel adapter, this adapter does not prevent duplicates by default. +If you do not delete the remote file and wish to prevent the file from being processed again, you can configure an `S3PersistentFileListFilter` in the `filter` attribute. +If you do not want to persist the state, an in-memory `SimpleMetadataStore` can be used with the filter. +If you also wish to use a filename pattern (or regex), use a `CompositeFileListFilter`. The `S3MessageHandler` is an Outbound Channel Adapter and allows performing `upload`, `download` and `copy` (see `S3MessageHandler.Command` enum) operations in the provided S3 bucket. diff --git a/docs/src/main/asciidoc/secrets-manager.adoc b/docs/src/main/asciidoc/secrets-manager.adoc index a44478f6b..2251d242e 100644 --- a/docs/src/main/asciidoc/secrets-manager.adoc +++ b/docs/src/main/asciidoc/secrets-manager.adoc @@ -26,7 +26,7 @@ For example, assuming that the secret name in Secrets Manager is `/secrets/datab spring.config.import=aws-secretsmanager:/secrets/database-secrets ---- -If a secret with given name does not exist in Secrets Manager, application will fail to start. If secret value is not required for the application, and it should continue to startup even when secret is missing, add `optional` before prefix: +If a secret with the given name does not exist in Secrets Manager, the application will fail to start. If the secret is not required for the application and it should continue to start up even when the secret is missing, add `optional` before the prefix: [source,properties] ---- @@ -40,7 +40,7 @@ To load multiple secrets, separate their names with `;`: spring.config.import=aws-secretsmanager:/secrets/database-secrets;/secrets/webclient-secrets ---- -If you have the requirement to load secrets from another AWS account you can achieve this using the secret's ARN. +If you need to load secrets from another AWS account, you can do so using the secret's ARN. [source,properties] ---- @@ -59,8 +59,8 @@ Fetched secrets can be referenced with `@Value`, bound to `@ConfigurationPropert ==== Using Key-Value (JSON) Secrets -Secrets resolved with `spring.config.import` can be also referenced in `application.properties`. -When a content of `SecretString` in a JSON, all top level JSON keys are added as properties to Spring Environment. +Secrets resolved with `spring.config.import` can also be referenced in `application.properties`. +When the content of a `SecretString` is JSON, all top-level JSON keys are added as properties to the Spring environment. For example, with a file `mycreds.json` containing following JSON structure: @@ -99,8 +99,8 @@ private String password; ==== Using plain text secrets -If a `SecretString` is a plain text or if you are using `SecretBinary` , use secret name to retrieve its value. -For example, we will JDBC saved as plain text secret type with name `/secrets/my-certificate`: +If a `SecretString` is plain text or if you are using `SecretBinary`, use the secret name to retrieve its value. +For example, a JDBC URL saved as a plain text secret with the name `/secrets/prod/jdbc-url`: [source] ---- @@ -123,9 +123,9 @@ spring.datasource.url=${jdbc-url} ==== Adding prefix to property keys -To avoid property keys collisions it is possible to configure property key prefix that gets added to each resolved property from a secret. +To avoid property key collisions, it is possible to configure a property key prefix that is added to each resolved property from a secret. -As an example lets consider following JSON secret with a name `/secrets/database-secrets`: +As an example, consider the following JSON secret with the name `/secrets/database-secrets`: [source,json] ---- @@ -135,7 +135,7 @@ As an example lets consider following JSON secret with a name `/secrets/database } ---- -By default, `usernmame` and `password` properties will be added to the Spring environment. To add a prefix to property keys configure `spring.config.import` property with `?prefix=` added to the secret name: +By default, `username` and `password` properties will be added to the Spring environment. To add a prefix to property keys configure `spring.config.import` property with `?prefix=` added to the secret name: [source,properties] ---- @@ -198,8 +198,8 @@ 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 `SecretsManagerClientCustomizer`: -Autoconfiguration will configure `SecretsManagerClient` Bean with provided values after that, for example: +If you want to use the auto-configured `SecretsManagerClient` but change the underlying SDK client or `ClientOverrideConfiguration`, you will need to register a bean of type `SecretsManagerClientCustomizer`. +Auto-configuration will then configure the `SecretsManagerClient` bean with the provided values. For example: [source,java] ---- @@ -232,7 +232,7 @@ class SecretsManagerBootstrapConfiguration implements BootstrapRegistryInitializ Some applications may need to detect changes on external property sources and update their internal status to reflect the new configuration. The reload feature of Spring Cloud AWS Secrets Manager integration is able to trigger an application reload when a related secret value changes. -By default, this feature is disabled. You can enable it by using the `spring.cloud.aws.secretsmanager.reload.strategy` configuration property (for example, in the `application.properties` file) and adding following dependencies. +By default, this feature is disabled. You can enable it by using the `spring.cloud.aws.secretsmanager.reload.strategy` configuration property (for example, in the `application.properties` file) and adding the following dependencies. [source,xml] ---- @@ -274,7 +274,7 @@ management: Assuming that the reload feature is enabled with default settings (`refresh` mode), the following bean is refreshed when the secret changes: ==== -[java, source] +[source,java] ---- @Configuration @ConfigurationProperties(prefix = "bean") @@ -307,8 +307,8 @@ public class MyBean { ---- ==== -The reload feature periodically re-creates the configuration from config maps and secrets to see if it has changed. -You can configure the polling period by using the `spring.cloud.aws.secretsmanager.reload.period` (default value is 1 minute). +The reload feature periodically re-creates the configuration from Secrets Manager to see if it has changed. +You can configure the polling period by using the `spring.cloud.aws.secretsmanager.reload.period` property (default value is 1 minute). === Configuration @@ -326,7 +326,7 @@ The Spring Boot Starter for Secrets Manager provides the following configuration |=== === IAM Permissions -Following IAM permissions are required by Spring Cloud AWS: +The following IAM permissions are required by Spring Cloud AWS: [cols="2"] |=== diff --git a/docs/src/main/asciidoc/ses.adoc b/docs/src/main/asciidoc/ses.adoc index 404f325e7..bc5b7b730 100644 --- a/docs/src/main/asciidoc/ses.adoc +++ b/docs/src/main/asciidoc/ses.adoc @@ -1,11 +1,11 @@ [#spring-cloud-aws-ses] == SES Integration -Spring has a built-in support to send e-mails based on the https://www.oracle.com/technetwork/java/javamail/index.html[Java Mail API] -to avoid any static method calls while using the Java Mail API and thus supporting the testability of an application. -Spring Cloud AWS supports the https://aws.amazon.com/de/ses/[Amazon SES] as an implementation of the Spring Mail abstraction. +Spring provides built-in support for sending e-mails through the https://www.oracle.com/technetwork/java/javamail/index.html[Java Mail API], +which avoids static method calls and promotes testability. +Spring Cloud AWS supports https://aws.amazon.com/de/ses/[Amazon SES] as an implementation of the Spring Mail abstraction. -As a result Spring Cloud AWS users can decide to use the Spring Cloud AWS implementation of the Amazon SES service or -use the standard Java Mail API based implementation that sends e-mails via SMTP to Amazon SES. +As a result, Spring Cloud AWS users can choose to use the Spring Cloud AWS implementation of the Amazon SES service or +the standard Java Mail API-based implementation that sends e-mails via SMTP to Amazon SES. [TIP] ==== @@ -27,7 +27,7 @@ Maven coordinates, using <>: ---- === Sending simple mails -Application developers can inject the `MailSender` into their application code and directly send simple text based e-mail +Application developers can inject the `MailSender` into their application code to send simple text-based e-mail messages. The sample below demonstrates the creation of a simple mail message. [source,java,indent=0] @@ -57,10 +57,10 @@ class MailSendingService { === Sending attachments and/or HTML e-mails -Sending attachments with e-mail or HTML e-mails requires MIME messages to be created and sent. In order to create MIME messages, -the Java Mail API dependency and an implementation need to be in the classpath. Spring Cloud AWS will detect the -dependency and create a `org.springframework.mail.javamail.JavaMailSender` implementation that allows to create and -build MIME messages and send them. Dependencies for the Java Mail API and an implementation are the only needed configuration changes as shown below. +Sending e-mail attachments or HTML e-mails requires MIME messages. To create MIME messages, +the Java Mail API dependency and an implementation must be on the classpath. Spring Cloud AWS detects this +dependency and creates a `org.springframework.mail.javamail.JavaMailSender` implementation that allows building +and sending MIME messages. Adding the Java Mail API and an implementation are the only required configuration changes, as shown below. [source,xml,indent=0] ---- @@ -141,19 +141,18 @@ The Spring Boot Starter for SES provides the following configuration options: |=== Amazon SES is not available in all https://docs.aws.amazon.com/ses/latest/DeveloperGuide/regions.html[regions] of the -Amazon Web Services cloud. Therefore, an application hosted and operated in a region that does not support the mail -service will produce an error while using the mail service. Therefore, the region must be overridden for the mail -sender configuration. The example below shows a typical combination of a region (`EU-CENTRAL-1`) that does not provide +Amazon Web Services cloud. An application hosted in a region that does not support the mail service will encounter an +error when attempting to send mail. In such cases, the region must be overridden in the mail sender configuration. The example below shows a typical combination of a region (`EU-CENTRAL-1`) that does not provide an SES service where the client is overridden to use a valid region (`EU-WEST-1`). -`sourceArn` is the ARN of the identity that is associated with the sending authorization policy. For information about when to use this parameter, see the -description see https://docs.aws.amazon.com/ses/latest/dg/sending-authorization-delegate-sender-tasks-email.html[Amazon SES Developer Guide]. +`sourceArn` is the ARN of the identity associated with the sending authorization policy. For information about when to use this parameter, see the +https://docs.aws.amazon.com/ses/latest/dg/sending-authorization-delegate-sender-tasks-email.html[Amazon SES Developer Guide]. -`fromArn` is the ARN of the identity that is associated with the sending authorization policy that permits you to specify a particular "From" address in the header of the raw email. -For information about when to use this parameter, see the description see https://docs.aws.amazon.com/ses/latest/dg/sending-authorization-delegate-sender-tasks-email.html[Amazon SES Developer Guide]. +`fromArn` is the ARN of the identity associated with the sending authorization policy that permits you to specify a particular "From" address in the header of the raw email. +For information about when to use this parameter, see the https://docs.aws.amazon.com/ses/latest/dg/sending-authorization-delegate-sender-tasks-email.html[Amazon SES Developer Guide]. -`configurationSetName` sets the configuration set name on mail sender level and applies to every mail. For information about when to use this parameter, see the -description https://docs.aws.amazon.com/ses/latest/dg/using-configuration-sets.html[Using configuration sets in Amazon SES]. +`configurationSetName` sets the configuration set name at the mail sender level and applies to every message. For information about when to use this parameter, see +https://docs.aws.amazon.com/ses/latest/dg/using-configuration-sets.html[Using configuration sets in Amazon SES]. [source,properties,indent=0] ---- @@ -186,12 +185,12 @@ SesClientCustomizer customizer() { `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. +There can be multiple `SesClientCustomizer` beans present in a single application context. The `@Order(..)` annotation can be used to define the order of 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: +The following IAM permissions are required by Spring Cloud AWS: [cols="2"] |=== diff --git a/docs/src/main/asciidoc/sns.adoc b/docs/src/main/asciidoc/sns.adoc index d5c6afce8..bf607fb68 100644 --- a/docs/src/main/asciidoc/sns.adoc +++ b/docs/src/main/asciidoc/sns.adoc @@ -1,7 +1,7 @@ [#spring-cloud-aws-sns] == SNS Integration -https://aws.amazon.com/sns/[SNS] is a pub/sub messaging service that allows clients to publish notifications to a particuluar topic. +https://aws.amazon.com/sns/[SNS] is a pub/sub messaging service that allows clients to publish notifications to a particular topic. A Spring Boot starter is provided to auto-configure SNS integration beans. Maven coordinates, using <>: @@ -27,7 +27,7 @@ It supports sending notifications with payload of type: * `Object` - which if Jackson 3 is on classpath gets serialized to JSON using `org.springframework.messaging.converter.JacksonJsonMessageConverter` and Jackson's `tools.jackson.databind.json.JsonMapper` autoconfigured by Spring Boot. * `Object` - which if Jackson 3 is not on classpath but Jackson 2 is gets serialized to JSON using `org.springframework.messaging.converter.MappingJackson2MessageConverter` and Jackson's `com.fasterxml.jackson.databind.ObjectMapper` autoconfigured by Spring Boot. -Additionally, it exposes handful of methods supporting `org.springframework.messaging.Message`. +Additionally, it exposes a handful of methods that accept `org.springframework.messaging.Message`. [source,java] ---- @@ -59,13 +59,13 @@ class NotificationService { If autoconfigured converters do not meet your needs, you can provide a custom `SnsTemplate` bean with a message converter of your choice. -When sending SNS notification, it is required to provide a topic ARN. Spring Cloud AWS simplifies it and allows providing a topic name instead, under a condition that topic with that name has already been created. -Otherwise, Spring Cloud AWS will make an attempt to create topic with this name with a first call. +When sending an SNS notification, a topic ARN is required. Spring Cloud AWS simplifies this by allowing a topic name to be provided instead, on the condition that a topic with that name already exists. +Otherwise, Spring Cloud AWS will attempt to create a topic with that name on the first call. The behavior of resolving topic ARN by a topic name can be altered by providing a custom bean of type `io.awspring.cloud.sns.core.TopicArnResolver`. -If resolving topic name by create topic call is not possible you can autoconfigure Bean of `io.awspring.cloud.sns.core.TopicsListingTopicArnResolver`. -Autoconfiguration will automatically configure `SnsTemplate` with `TopicArnResolverConfiguration`. +If resolving a topic name via a `CreateTopic` call is not feasible, you can register a bean of type `io.awspring.cloud.sns.core.TopicsListingTopicArnResolver`. +Auto-configuration will then automatically configure `SnsTemplate` with that resolver. ---- import org.springframework.context.annotation.Bean; @@ -86,12 +86,12 @@ public class TopicArnResolverConfiguration { ---- -However, when using the topic ARN in your application, the `SnsTemplate` provides a `topicExists` method to validate the existence of the SNS topic at application startup itself. +When using a topic ARN directly, `SnsTemplate` provides a `topicExists` method to validate that the SNS topic exists at application startup. ==== SNS Operations -Because of Spring Messaging compatibility, `SnsTemplate` exposes many methods that you may not need if you don't need Spring Messaging abstractions. -In such case, we recommend using `SnsOperations` - an interface implemented by `SnsTemplate`, that exposes a convenient method for sending SNS notification, including support for FIFO topics. +Due to Spring Messaging compatibility, `SnsTemplate` exposes many methods that may not be needed if Spring Messaging abstractions are not required. +In such cases, we recommend using `SnsOperations` — an interface implemented by `SnsTemplate` — which exposes a convenient API for sending SNS notifications, including support for FIFO topics. [source,java] ---- @@ -190,7 +190,7 @@ The `SnsMessageConverter` interface controls how Spring messages are converted t === Sending SMS Messages -The starter automatically configures and registers a `SnsSmsTemplate` bean providing higher level abstractions for sending SMS messages to SNS topic or directly to a phone number. +The starter automatically configures and registers a `SnsSmsTemplate` bean, providing higher-level abstractions for sending SMS messages to an SNS topic or directly to a phone number. - https://docs.amazonaws.cn/en_us/sns/latest/dg/sns-mobile-phone-number-as-subscriber.html[Mobile text messaging (SMS)] - https://docs.amazonaws.cn/en_us/sns/latest/dg/sms_publish-to-phone.html[Publishing to a mobile phone] @@ -223,7 +223,7 @@ class NotificationService { The starter automatically configures and registers a `SnsAsyncTemplate` bean when `SnsAsyncClient` bean is registered by user, providing non-blocking SNS operations. `SnsAsyncTemplate` returns `CompletableFuture` for all operations, making it suitable for high-throughput async applications. -It supports the same payload types as `SnsTemplate` and uses the same Spring `MessageConverter` hirarchy inside of `DefaultSnsPublishMessageConverter` to convert payloads. +It supports the same payload types as `SnsTemplate` and uses the same Spring `MessageConverter` hierarchy within `DefaultSnsPublishMessageConverter` to convert payloads. [source,java] ---- @@ -255,7 +255,7 @@ public SnsPublishMessageConverter customConverter() { } ---- -Autoconfiguration will pick it up and configure `SnsAsyncTemplate` automatically with it. +Auto-configuration will automatically pick it up and configure `SnsAsyncTemplate` accordingly. === Using SNS Client @@ -282,8 +282,8 @@ class NotificationService { === Annotation-driven HTTP notification endpoint -SNS supports multiple endpoint types (SQS, Email, HTTP, HTTPS), Spring Cloud AWS provides support for HTTP(S) endpoints. -SNS sends three type of requests to an HTTP topic listener endpoint, for each of them annotations are provided: +SNS supports multiple endpoint types (SQS, Email, HTTP, HTTPS). Spring Cloud AWS provides support for HTTP(S) endpoints. +SNS sends three types of requests to an HTTP topic listener endpoint, and annotations are provided for each of them: * Subscription request -> `@NotificationSubscriptionMapping` * Notification request -> `@NotificationMessageMapping` @@ -291,12 +291,12 @@ SNS sends three type of requests to an HTTP topic listener endpoint, for each of [NOTE] ==== -Since 4.1.0 verification has been introduced for Notification request and is turned on by default. Verification uses the same region as `SNSClient`. -To turn off verification simply set property `spring.cloud.aws.sns.verification=false`. -For more information about SNS verification https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/sns/message/SnsMessageManager.html[here]. +Since 4.1.0, message verification has been introduced for notification requests and is enabled by default. Verification uses the same region as `SnsClient`. +To disable verification, set the `spring.cloud.aws.sns.verification` property to `false`. +For more information about SNS message verification, see https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/sns/message/SnsMessageManager.html[SnsMessageManager]. ==== -HTTP endpoints are based on Spring MVC controllers. Spring Cloud AWS added some custom argument resolvers to extract the message and subject out of the notification requests. +HTTP endpoints are based on Spring MVC controllers. Spring Cloud AWS provides custom argument resolvers to extract the message and subject from notification requests. Example of integration: @@ -369,12 +369,12 @@ SnsClientCustomizer customizer() { `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. +There can be multiple `SnsClientCustomizer` beans present in a single application context. The `@Order(..)` annotation can be used to define the order of 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: +The following IAM permissions are required by Spring Cloud AWS: [cols="2,1"] |=== @@ -419,11 +419,11 @@ Sample IAM policy granting access to SNS: Starting with version 4.0, Spring Cloud AWS provides https://spring.io/projects/spring-integration[Spring Integration] channel adapters for Amazon SNS. -The `SnsInboundChannelAdapter` is an extension of `HttpRequestHandlingMessagingGateway` and must be as a part of Spring MVC application. -Its URL must be used from the AWS Management Console to add this endpoint as a subscriber to the SNS Topic. +The `SnsInboundChannelAdapter` is an extension of `HttpRequestHandlingMessagingGateway` and must be used as part of a Spring MVC application. +Its URL must be registered in the AWS Management Console to add this endpoint as a subscriber to the SNS topic. However, before receiving any notification itself, this HTTP endpoint must confirm the subscription. -If you want to use Jackson 3 with spring cloud aws integrations you should use `SnsInboundChannelAdapter`. If you are still using Jackson 2 you should use `LegacyJackson2SnsInboundChannelAdapter`. +If you want to use Jackson 3 with Spring Cloud AWS integrations, use `SnsInboundChannelAdapter`. If you are still using Jackson 2, use `LegacyJackson2SnsInboundChannelAdapter`. See `SnsInboundChannelAdapter` and `LegacyJackson2SnsInboundChannelAdapter` JavaDocs for more information. @@ -432,9 +432,9 @@ This `boolean` flag indicates if the adapter should send `SubscriptionConfirmati If that is a case, the `SnsHeaders.NOTIFICATION_STATUS_HEADER` message header is present in the message with the `NotificationStatus` object, which can be used in the downstream flow to confirm subscription or not. Or "re-confirm" it in the case of `UnsubscribeConfirmation` message. -In addition, the `SnsHeaders.SNS_MESSAGE_TYPE_HEADER` message header is represented to simplify a routing in the downstream flow. +In addition, the `SnsHeaders.SNS_MESSAGE_TYPE_HEADER` message header is populated to simplify routing in the downstream flow. -The Java Configuration is pretty simple: +The Java configuration is straightforward: [source,java] ---- @@ -459,9 +459,9 @@ public static class MyConfiguration { } ---- -Note: by default, the message `payload` is a `Map` converted from the received Topic JSON message. -For the convenience a `payload-expression` is provided with the `Message` as a root object of the evaluation context. -Hence, even some HTTP headers, populated by the `DefaultHttpHeaderMapper`, are available for the evaluation context. +NOTE: By default, the message `payload` is a `Map` converted from the received topic JSON message. +For convenience, a `payload-expression` is provided with the `Message` as the root object of the evaluation context. +As a result, HTTP headers populated by the `DefaultHttpHeaderMapper` are also available in the evaluation context. The `SnsMessageHandler` is a simple one-way Outbound Channel Adapter to send Topic Notification using `SnsAsyncClient` service. diff --git a/docs/src/main/asciidoc/spring-modulith.adoc b/docs/src/main/asciidoc/spring-modulith.adoc index ea87420e1..159ab48e2 100644 --- a/docs/src/main/asciidoc/spring-modulith.adoc +++ b/docs/src/main/asciidoc/spring-modulith.adoc @@ -1,9 +1,7 @@ [#spring-cloud-aws-modulith] == Spring Modulith Integration -Spring Cloud AWS comes with externalized events - -Integration with https://spring.io/projects/spring-modulith[Spring Modulith] provides capability to send externalized events to SNS and SQS. Read more about externalizing events in https://docs.spring.io/spring-modulith/reference/events.html#externalization[Spring Modulith Reference Guide]. +Integration with https://spring.io/projects/spring-modulith[Spring Modulith] provides the capability to send externalized events to SNS and SQS. For more information about externalizing events, see the https://docs.spring.io/spring-modulith/reference/events.html#externalization[Spring Modulith Reference Guide]. === SNS @@ -17,7 +15,7 @@ Maven coordinates, using <>: ---- -The logical routing key will be used as SNS message group id. When routing key is set, requires SNS to be configured as a FIFO topic with content based deduplication enabled. +The logical routing key is used as the SNS message group ID. When a routing key is set, SNS must be configured as a FIFO topic with content-based deduplication enabled. === SQS @@ -31,4 +29,4 @@ Maven coordinates, using <>: ---- -The logical routing key will be used as SQS message group id. When routing key is set, requires SQS queue to be configured as a FIFO queue. +The logical routing key is used as the SQS message group ID. When a routing key is set, the SQS queue must be configured as a FIFO queue. diff --git a/docs/src/main/asciidoc/sqs.adoc b/docs/src/main/asciidoc/sqs.adoc index 9b69146b0..fb97d0501 100644 --- a/docs/src/main/asciidoc/sqs.adoc +++ b/docs/src/main/asciidoc/sqs.adoc @@ -46,9 +46,9 @@ public class SqsApplication { } ---- -IMPORTANT: Due to a classloader related https://github.com/awspring/spring-cloud-aws/issues/657[issue] it is currently not possible to use @SqsListener together with Spring Boot DevTools. +IMPORTANT: Due to a classloader-related https://github.com/awspring/spring-cloud-aws/issues/657[issue], it is currently not possible to use `@SqsListener` together with Spring Boot DevTools. -Without Spring Boot, it's necessary to import the `SqsBootstrapConfiguration` class in a `@Configuration`, as well as declare a `SqsMessageListenerContainerFactory` bean. +Without Spring Boot, it is necessary to import the `SqsBootstrapConfiguration` class in a `@Configuration`, as well as declare a `SqsMessageListenerContainerFactory` bean. [source, java] ---- @@ -92,7 +92,7 @@ public class SQSConfiguration { [[sqs-template-send]] ==== SqsTemplate -When using `Spring Boot` and autoconfiguration, a `SqsTemplate` instance is autowired by default in case no other template bean is found in the context. +When using `Spring Boot` and auto-configuration, a `SqsTemplate` instance is autowired by default if no other template bean is found in the context. This template instance is backed by the autoconfigured `SqsAsyncClient`, with any configurations provided. `SqsTemplate` instances are immutable and thread-safe. @@ -101,7 +101,7 @@ NOTE: The endpoint to which the message will be sent can be either the queue nam ==== Creating a SqsTemplate Instance `SqsTemplate` implements two `Operations` interfaces: `SqsOperations` contains blocking methods, and `SqsAsyncOperations` contains async methods that return `CompletableFuture` instances. -In case only sync or async operations are to be used, the corresponding interface can be utilized to eliminate unnecessary methods. +If only sync or async operations are to be used, the corresponding interface can be used to narrow down the available methods. The following methods can be used to create new `SqsTemplate` instances with default options: @@ -115,7 +115,7 @@ SqsAsyncOperations asyncTemplate = SqsTemplate.newAsyncTemplate(sqsAsyncClient); NOTE: The returned object is always the `SqsTemplate`, and the separate methods are only for convenience of the interface return type. -In case more complex configuration is required, a builder is also provided, and a set of options: +If more complex configuration is required, a builder is also provided along with a set of options: ```java SqsTemplate template = SqsTemplate.builder() @@ -178,7 +178,7 @@ See <> for more information. |Class |null |The default class to which payloads should be converted to. -Note that messages sent with the `SqsTemplate` by default contains a header with the type information, so no configuration is needed. +Note that messages sent with the `SqsTemplate` by default contain a header with the type information, so no configuration is needed. See <> for more information. |`additionalHeaderForReceive` @@ -307,7 +307,7 @@ When the send operation fails for single message operations, a `MessagingOperati For `Batch` send operations, a `SendResult.Batch` object is returned. This object contains a `Collection` of `successful` and `failed` results. -In case there are messages that failed to be sent within a batch, corresponding `SendResult.Failed` objects are generated. +If there are messages that failed to be sent within a batch, corresponding `SendResult.Failed` objects are generated. The `SendBatch.Failed` object contains: * the `errorMessage` returned by SQS @@ -315,7 +315,7 @@ The `SendBatch.Failed` object contains: * the `Message` instance that was tried to be sent, with any additional headers that might have been added by the framework * an `additionalInformation` map with the `code` and `senderFault` parameters returned by SQS. -By default, if there's at least one failed message in a send batch operation, a `SendBatchOperationFailedException` will be thrown. +By default, if there is at least one failed message in a send batch operation, a `SendBatchOperationFailedException` will be thrown. Such exception contains a `SendResult.Batch` property containing both successful and failed messages. This behavior can be configured using the `sendBatchFailureHandlingStrategy` option when creating the template. @@ -399,7 +399,7 @@ If `null` is returned by the function, no header with type information is added. The `typeHeaderName` can be configured using the `setPayloadTypeHeader` method. -In case type mapping information is not available, the payload class can be specified either in the <> or in the `receive()` method variants: +If type mapping information is not available, the payload class can be specified either in the <> or in the `receive()` method variants: ```java Optional> receivedMessage = template @@ -540,7 +540,7 @@ public interface AsyncMessageListener { ==== SqsMessageListenerContainer -The `MessageListenerContainer` manages the entire messages` lifecycle, from polling, to processing, to acknowledging. +The `MessageListenerContainer` manages the entire message lifecycle, from polling, to processing, to acknowledging. It can be instantiated directly, using a `SqsMessageListenerContainerFactory`, or using `@SqsListener` annotations. If declared as a `@Bean`, the `Spring` context will manage its lifecycle, starting the container on application startup and stopping it on application shutdown. @@ -667,7 +667,7 @@ MessageListenerContainer myListenerContainer(SqsAsyncClient sqsAsyncClie The simplest way to consume `SQS` messages is by annotating a method in a `@Component` class with the `@SqsListener` annotation. The framework will then create the `MessageListenerContainer` and set a `MessagingMessageListenerAdapter` to invoke the method when a message is received. -IMPORTANT: Due to a classloader related https://github.com/awspring/spring-cloud-aws/issues/657[issue] it is currently not possible to use @SqsListener together with Spring Boot DevTools. +IMPORTANT: Due to a classloader-related https://github.com/awspring/spring-cloud-aws/issues/657[issue], it is currently not possible to use `@SqsListener` together with Spring Boot DevTools. When using `Spring Boot` with `auto-configuration`, no configuration is necessary. @@ -675,7 +675,7 @@ Most attributes on the annotation can be resolved from SpEL `(#{...})` or proper ===== Queue Names -One or more queues can be specified in the annotation through the `queueNames` or `value` properties - there's no distinction between the two properties. +One or more queues can be specified in the annotation through the `queueNames` or `value` properties — there is no distinction between the two. Instead of queue names, queue urls can also be provided. Using urls instead of queue names can result in slightly faster startup times since it prevents the framework from looking up the queue url when the containers start. @@ -694,8 +694,8 @@ NOTE: Queues declared in the same annotation will share the container, though ea ===== Handling Different Payload In The Same Listener -It's possible to handle different payloads in the same listener by annotating handler methods with the `@SqsHandler` annotation. -Here's a sample: +It is possible to handle different payloads in the same listener by annotating handler methods with the `@SqsHandler` annotation. +The following is a sample: [source, java] ---- @SqsListener("myQueue") @@ -718,7 +718,7 @@ public class MyListener { } ---- -The `isDefault = true` parameter designates a method as the fallback handler for messages that don't match any other handler's parameter type. +The `isDefault = true` parameter designates a method as the fallback handler for messages that do not match any other handler's parameter type. To determine which handler method to invoke, the framework needs to know the payload type before deserialization. A custom `PayloadTypeMapper` should be configured to map incoming messages to their concrete types. @@ -734,7 +734,7 @@ See <> for more information. ===== SNS Messages -Since 3.1.1, when receiving SNS messages through the `@SqsListener`, the message includes all attributes of the `SnsNotification`. To only receive need the `Message` part of the payload, you can utilize the `@SnsNotificationMessage` annotation. +Since 3.1.1, when receiving SNS messages through the `@SqsListener`, the message includes all attributes of the `SnsNotification`. To receive only the `Message` part of the payload, use the `@SnsNotificationMessage` annotation. For handling individual message processing, the @SnsNotificationMessage annotation can be used in the following manner: @@ -756,7 +756,7 @@ public void listen(@SnsNotificationMessage List pojos) { } ---- -Since 3.3.1 you can also retrieve the subject of the SNS message through the `@SnsNotificationSubject` annotation. +Since 3.3.1, you can also retrieve the subject of the SNS message through the `@SnsNotificationSubject` annotation. [source, java] ---- @@ -840,7 +840,7 @@ See <> for how to specify the queue attributes t NOTE: To receive a collection of objects in a single message, the collection must be wrapped in an object. See <>. -Here's a sample with many arguments: +The following is a sample with many arguments: [source, java] ---- @@ -876,7 +876,7 @@ Alternatively, `SqsContainerOptions` can be set to `ListenerMode.BATCH` in the ` NOTE: The same factory can be used to create both `single message` and `batch` containers for `@SqsListener` methods. -IMPORTANT: In case the same factory is shared by both delivery methods, any supplied `ErrorHandler`, `MessageInterceptor` or `MessageListener` should implement the proper methods. +IMPORTANT: If the same factory is shared by both delivery methods, any supplied `ErrorHandler`, `MessageInterceptor`, or `MessageListener` should implement the appropriate methods. ==== Automatic Request Batching with SqsAsyncBatchManager @@ -1049,7 +1049,7 @@ The Spring Boot Starter for SQS provides the following auto-configuration proper |10 |The maximum number of messages from each queue that can be processed simultaneously in this container. This number will be used for defining the thread pool size for the container following (maxConcurrentMessages * number of queues). -For batching acknowledgements a message is considered as no longer inflight when it's handed to the acknowledgement queue. +For batching acknowledgements, a message is considered as no longer inflight when it is handed to the acknowledgement queue. See <>. |<> @@ -1083,7 +1083,7 @@ See <>. |`autoStartup` |true, false |true -|Determines wherever container should start automatically. When set to false the +|Determines whether the container should start automatically. When set to `false`, the container will not launch on startup, requiring manual intervention to start it. See <>. @@ -1109,7 +1109,7 @@ See <>. |`SINGLE_MESSAGE`, `BATCH` |`SINGLE_MESSAGE` |Configures whether this container will use `single message` or `batch` listeners. -This value is overriden by `@SqsListener` depending on whether the listener method contains a `List` argument. +This value is overridden by `@SqsListener` depending on whether the listener method contains a `List` argument. See <>. |`queueAttributeNames` @@ -1227,12 +1227,12 @@ NOTE: By default, no `QueueAttributes` and `ALL` `MessageAttributes` and `Messag The `MessageListenerContainer` interface extends `SmartLifecycle`, which provides methods to control the container's lifecycle. Containers created from `@SqsListener` annotations are registered in a `MessageListenerContainerRegistry` bean that is registered by the framework. -The containers themselves are not Spring-managed beans, and the registry is responsible for managing these containers` lifecycle in application startup and shutdown. +The containers themselves are not Spring-managed beans, and the registry is responsible for managing these containers' lifecycle during application startup and shutdown. -NOTE: The `DefaultListenerContainerRegistry ` implementation provided by the framework allows the phase value to be set through the `setPhase` method. The default value is `MessageListenerContainer.DEFAULT_PHASE`. +NOTE: The `DefaultListenerContainerRegistry` implementation provided by the framework allows the phase value to be set through the `setPhase` method. The default value is `MessageListenerContainer.DEFAULT_PHASE`. -At startup, the containers will make requests to `SQS` to retrieve the queues` urls for the provided queue names or ARNs, and for retrieving `QueueAttributes` if so configured. -Providing queue urls instead of names and not requesting queue attributes can result in slightly better startup times since there's no need for such requests. +At startup, the containers will make requests to `SQS` to retrieve the queues' URLs for the provided queue names or ARNs, and for retrieving `QueueAttributes` if so configured. +Providing queue URLs instead of names and not requesting queue attributes can result in slightly better startup times since there is no need for such requests. NOTE: If retrieving the queue url fails due to the queue not existing, the framework can be configured to either create the queue or fail. If a URL is provided instead of a queue name the framework will not make this request at startup, and thus if the queue does not exist it will fail at runtime. @@ -1244,7 +1244,7 @@ After this period, operations will be canceled and the container will attempt to ===== Containers as Spring Beans Manually created containers can be registered as beans, e.g. by declaring a `@Bean` in a `@Configuration` annotated class. -In these cases the containers lifecycle will be managed by the `Spring` context at application startup and shutdown. +In these cases, the container's lifecycle will be managed by the Spring context at application startup and shutdown. [source, java] ---- @@ -1259,11 +1259,11 @@ MessageListenerContainer listenerContainer(SqsAsyncClient sqsAsyncClient } ---- -NOTE: The `SqsMessageListenerContainer.builder()` allows to specify the `SmartLifecycle.phase`, to override the default value defined in `MessageListenerContainer.DEFAULT_PHASE` +NOTE: The `SqsMessageListenerContainer.builder()` allows specifying the `SmartLifecycle.phase` to override the default value defined in `MessageListenerContainer.DEFAULT_PHASE`. ===== Retrieving Containers from the Registry -Containers can be retrieved by fetching the `MessageListenerContainer` bean from the container and using the `getListenerContainers` and `getContainerById` methods. +Containers can be retrieved by fetching the `MessageListenerContainerRegistry` bean from the context and using the `getListenerContainers` and `getContainerById` methods. Then lifecycle methods can be used to start and stop instances. [source,java] @@ -1289,9 +1289,9 @@ NOTE: Spring-managed `MessageListenerContainer` beans' lifecycle actions are alw ==== FIFO Support -`FIFO` SQS queues are fully supported for receiving messages - queues with names that ends in `.fifo` will automatically be setup as such. +`FIFO` SQS queues are fully supported for receiving messages — queues with names that end in `.fifo` will automatically be set up as such. -* Messages are polled with a `receiveRequestAttemptId`, and the received batch of messages is split according to the message`s `MessageGroupId`. +* Messages are polled with a `receiveRequestAttemptId`, and the received batch of messages is split according to the message's `MessageGroupId`. * Each message from a given group will then be processed in order, while each group is processed in parallel. * To receive messages from multiple groups in a `batch`, set `fifoBatchGroupingStrategy` to `PROCESS_MULTIPLE_GROUPS_IN_SAME_BATCH` in `SqsContainerOptions`. * If processing fails for a message, the following messages from the same message group are discarded so they will be served again after their `message visibility` expires. @@ -1394,12 +1394,12 @@ NOTE: Multiple interceptors can be added to the same factory or container. The `intercept` methods are executed `before` a message is processed, and a different message can be returned. -IMPORTANT: In case a different message is returned, it's important to add the `SqsHeaders.SQS_RECEIPT_HANDLE_HEADER` with the value of the original handler so the original message is acknowledged after processing. +IMPORTANT: If a different message is returned, it is important to set the `SqsHeaders.SQS_RECEIPT_HANDLE_HEADER` to the receipt handle of the original message so that the original message is acknowledged after processing. Also, a `SqsHeaders.SQS_MESSAGE_ID_HEADER` must always be present. IMPORTANT: The `intercept` methods must not return null. -The `afterProcessing` methods are executed after message is processed and the `ErrorHandler` is invoked, but before the message is acknowledged. +The `afterProcessing` methods are executed after a message is processed and the `ErrorHandler` is invoked, but before the message is acknowledged. === Error Handling @@ -1471,7 +1471,7 @@ public SqsMessageListenerContainerFactory defaultSqsListenerContainerFac If the error handler execution succeeds, i.e. no error is thrown from the error handler, the message is considered to be recovered and is acknowledged according to the acknowledgement configuration. -IMPORTANT: If the message should not be acknowledged and the `ON_SUCCESS` acknowledgement mode is set, it's important to propagate the error. +IMPORTANT: If the message should not be acknowledged and the `ON_SUCCESS` acknowledgement mode is set, it is important to propagate the error. For simply executing an action in case of errors, an `interceptor` should be used instead, checking the presence of the `throwable` argument for detecting a failed execution. ==== Immediate Retry Error Handler @@ -1479,7 +1479,7 @@ As mentioned in <>, by default, messages that cause an error in Starting with version 3.4, Spring Cloud AWS SQS includes the `ImmediateRetryAsyncErrorHandler`, which sets the visibility timeout to zero to enable immediate retry of failed messages. -When using auto-configured factory, simply declare a `@Bean` and the error handler will be set +When using the auto-configured factory, simply declare a `@Bean` and the error handler will be set: [source, java] ---- @@ -1603,7 +1603,7 @@ NOTE: The maximum visibility timeout allowed by SQS is 43200 seconds (12 hours). If the value provided to the `maxVisibilityTimeoutSeconds` parameter exceeds this limit, an `IllegalArgumentException` will be thrown. -To enable half jitter, `jitter(Jitter.HALF)` on the builder: +To enable half jitter, set `jitter(Jitter.HALF)` on the builder: [source, java] ---- @@ -1638,8 +1638,7 @@ NOTE: The maximum visibility timeout allowed by SQS is 43200 seconds (12 hours). If the value provided to the `maxVisibilityTimeoutSeconds` parameter exceeds this limit, an `IllegalArgumentException` will be thrown. -When using auto-configured factory, simply declare a `@Bean` and the error -handler will be set +When using the auto-configured factory, simply declare a `@Bean` and the error handler will be set: [source, java] ---- @@ -1908,7 +1907,7 @@ In `SQS` acknowledging a message is the same as deleting the message from the qu A number of `Acknowledgement` strategies are available and can be configured via `SqsContainerOptions`. Optionally, a callback action can be added to be executed after either a successful or failed acknowledgement. -Here's an example of a possible configuration: +The following is an example of a possible configuration: [source, java] ---- @@ -1935,7 +1934,7 @@ NOTE: All options are available for both `single message` and `batch` message li - `ON_SUCCESS` - Acknowledges a message or batch of messages after successful processing. - `ALWAYS` - Acknowledges a message or batch of messages after processing returns success or error. -- `MANUAL` - The framework won't acknowledge messages automatically and `Acknowledgement` objects can be received in the listener method. +- `MANUAL` - The framework will not acknowledge messages automatically and `Acknowledgement` objects can be received in the listener method. The `Acknowledgement` strategy can be configured in the `SqsContainerOptions` or in the `@SqsListener` annotation. @@ -1946,7 +1945,7 @@ Acknowledgements will be executed after either the amount of time specified in t Setting `acknowledgementInterval` to `Duration.ZERO` will disable the periodic acknowledgement, which will be executed only when the number of messages to acknowledge reaches the specified `acknowledgementThreshold`. -Setting `acknowledgementThreshold` to `0` will disable acknowledging per number of messages, and messages will be acknowledged only on the specified `acknowldgementInterval` +Setting `acknowledgementThreshold` to `0` will disable acknowledging per number of messages, and messages will be acknowledged only on the specified `acknowledgementInterval`. IMPORTANT: When using acknowledgement batching messages stay inflight for SQS purposes until their respective batch is acknowledged. `MessageVisibility` should be taken into consideration when configuring this strategy. @@ -1961,7 +1960,7 @@ IMPORTANT: If an immediate acknowledging triggers an error, message processing i ==== Manual Acknowledgement Acknowledgements can be handled manually by setting `AcknowledgementMode.MANUAL` in the `SqsContainerOptions`. -Manual acknowledgement can be used in conjunction with acknowledgement batching - the message will be queued for acknowledgement but won't be executed until one of the acknowledgement thresholds is reached. +Manual acknowledgement can be used in conjunction with acknowledgement batching — the message will be queued for acknowledgement but will not be executed until one of the acknowledgement thresholds is reached. It can also be used in conjunction with immediate acknowledgement. The `Acknowledgement#acknowledge` and `Acknowledgement#acknowledgeAsync` methods are also available to acknowledge messages received in `MANUAL` acknowledgement mode. @@ -2202,8 +2201,8 @@ Defaults to 10. This value is enforced per queue, meaning the number of inflight messages in a container can be up to (number of queues in container * maxConcurrentMessages). -NOTE: When using acknowledgement batching, a message is considered as no longer inflight when it's delivered to the acknowledgement queue. In this case, the actual number of inflight messages on AWS SQS console can be higher than the configured value. -When using immediate acknowledgement, a message is considered as no longer inflight after it's been acknowledged or throws an error. +NOTE: When using acknowledgement batching, a message is considered as no longer inflight when it is delivered to the acknowledgement queue. In this case, the actual number of inflight messages on the AWS SQS console can be higher than the configured value. +When using immediate acknowledgement, a message is considered as no longer inflight after it has been acknowledged or throws an error. ===== maxMessagesPerPoll @@ -2227,7 +2226,7 @@ This wait is applied per queue and one queue has no interference in another in t Defaults to 10 seconds. ===== pollBackOffPolicy -Since 3.2 it's possible to specify a `BackOffPolicy` which will be applied when a polling thread throws an exception. +Since 3.2, it is possible to specify a `BackOffPolicy` that will be applied when a polling thread throws an exception. The default policy is an exponential back off with a delay of 1000ms, a 2.0 multiplier, and a 10000ms maximum delay. Note that in highly concurrent environments with many polling threads it may happen that a successful poll cancels the next scheduled backoff before it happens, and as such no back offs need to be executed. @@ -2236,15 +2235,15 @@ By default, the framework starts all queues in `low throughput mode`, where it w When a poll returns at least one message, the queue enters a `high throughput mode` where it will try to fulfill `maxConcurrentMessages` messages by making (maxConcurrentMessages / maxMessagesPerPoll) parallel polls to the queue. Any poll that returns no messages will trigger a `low throughput mode` again, until at least one message is returned, triggering `high throughput mode` again, and so forth. -After `maxDelayBetweenPolls`, if `maxMessagesPerPoll` permits are not available, it'll poll for the difference, i.e. as many messages as have been processed so far, if any. +After `maxDelayBetweenPolls`, if `maxMessagesPerPoll` permits are not available, the container will poll for the difference — that is, as many messages as have been processed so far, if any. -E.g. Let's consider a scenario where the container is configured for: `maxConcurrentMessages` = 20, `maxMessagesPerPoll` = 10, `maxDelayBetweenPolls` = 5 seconds, and a `pollTimeout` = 10 seconds. +For example, consider a scenario where the container is configured for `maxConcurrentMessages` = 20, `maxMessagesPerPoll` = 10, `maxDelayBetweenPolls` = 5 seconds, and `pollTimeout` = 10 seconds. -The container starts in `low throughput mode`, meaning it'll attempt a single poll for 10 messages. -If any messages are returned, it'll switch to `high throughput mode`, and will make up to 2 simultaneous polls for 10 messages each. -If all 20 messages are retrieved, it'll not attempt any more polls until messages are processed. -If after the 5 seconds for `maxDelayBetweenPolls` 6 messages have been processed, the framework will poll for the 6 messages. -If the queue is depleted and a poll returns no messages, it'll enter `low throughput` mode again and perform only one poll at a time. +The container starts in `low throughput mode`, meaning it will attempt a single poll for 10 messages. +If any messages are returned, it will switch to `high throughput mode` and make up to two simultaneous polls for 10 messages each. +If all 20 messages are retrieved, it will not attempt any more polls until messages are processed. +If after 5 seconds for `maxDelayBetweenPolls` six messages have been processed, the framework will poll for those six messages. +If the queue is depleted and a poll returns no messages, it will enter `low throughput` mode again and perform only one poll at a time. ==== Configuring BackPressureMode The default `BackPressureHandler` can be configured to optimize the polling behavior based on the application's throughput requirements. @@ -2331,7 +2330,7 @@ When a `MessageListener`, `MessageInterceptor`, and `ErrorHandler` implementatio Listener methods annotated with `@SqsListener` can either return a simple value, e.g. `void`, or a `CompletableFuture`. The listener method will then be wrapped in either a `MessagingMessageListenerAdapter` or a `AsyncMessagingMessageListenerAdapter` respectively. -NOTE: In order to achieve higher throughput, it's encouraged that, at least for simpler logic in message listeners, `interceptors` and `error handlers`, the async variants are used. +NOTE: To achieve higher throughput, it is encouraged that, at least for simpler logic in message listeners, `interceptors`, and `error handlers`, the async variants are used. ==== Threading and Blocking Components @@ -2341,9 +2340,9 @@ Message processing always starts in a framework thread from the default or provi If an async component is invoked and the execution returns to the framework on a different thread, such thread will be used until a `blocking` component is found, when the execution switches back to a `TaskExecutor` thread to avoid blocking i.e. `SqsAsyncClient` or `HttpClient` threads. -If by the time the execution reaches a `blocking` component it's already on a framework thread, it remains in the same thread to avoid excessive thread allocation and hopping. +If by the time the execution reaches a `blocking` component it is already on a framework thread, it remains in the same thread to avoid excessive thread allocation and hopping. -IMPORTANT: When using `async` methods it's critical not to block the incoming thread, which might be very detrimental to overall performance. +IMPORTANT: When using `async` methods, it is critical not to block the incoming thread, as this can be very detrimental to overall performance. If thread-blocking logic has to be used, the blocking logic should be executed on another thread, e.g. using `CompletableFuture.supplyAsync(() -> myLogic(), myExecutor)`. Otherwise, a `sync` interface should be used. @@ -2351,7 +2350,7 @@ Otherwise, a `sync` interface should be used. The default `TaskExecutor` is a `ThreadPoolTaskExecutor`, and a different `componentTaskExecutor` supplier can be set in the `SqsContainerOptions`. -When providing a custom executor, it's important that it's configured to support all threads that will be created, which should be (maxConcurrentMessages * total number of queues). +When providing a custom executor, it is important that it is configured to support all threads that will be created, which should be `maxConcurrentMessages * total number of queues`. Since 4.1.0, the framework supports <>. If platform threads are used, a `MessageExecutionThreadFactory` MUST be set to the executor to avoid unnecessary thread hopping between blocking components. @@ -2405,7 +2404,7 @@ SqsAsyncClientCustomizer customizer() { `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. +There can be multiple `SqsAsyncClientCustomizer` beans present in a single application context. The `@Order(..)` annotation can be used to define the order of execution. Note that `SqsAsyncClientCustomizer` beans are applied **after** `AwsAsyncClientCustomizer` beans and therefore can overwrite previously set configurations. @@ -2557,7 +2556,7 @@ try (Scope scope = ContextSnapshotFactory.builder() IMPORTANT: The scope should be closed in the same thread where it was opened to prevent thread local leakage. === IAM Permissions -Following IAM permissions are required by Spring Cloud AWS SQS: +The following IAM permissions are required by Spring Cloud AWS SQS: [cols="2"] |=== @@ -2573,7 +2572,7 @@ Following IAM permissions are required by Spring Cloud AWS SQS: | Delete message from queue | `sqs:DeleteMessage` -| To use sqsListener with SimpleMessageListenerContainerFactory you will need to add as well +| To use `@SqsListener` with `SqsMessageListenerContainerFactory`, the following permission is also required | `sqs:GetQueueAttributes` |=== @@ -2596,6 +2595,8 @@ Sample IAM policy granting access to SQS: ], "Resource": "yourARN" } + ] +} ---- === Spring Integration Support @@ -2604,7 +2605,7 @@ Starting with version 4.0, Spring Cloud AWS provides https://spring.io/projects/ The `SqsMessageHandler` is for publishing a single message (or their batch) to SQS queue configured explicitly on the `SqsMessageHandler` or resolved via SpEL expression against the request message. The logic of this `MessageHandler` is to consume Spring Integration messages from an `inputChannel` and internally it is heavily based on the `SqsAsyncOperations` mentioned above. -When the `SqsMessageHandler` is set into an `async` mode, the result of the send operation is produced as a reply message into the `outputChannel`. +When the `SqsMessageHandler` is set to `async` mode, the result of the send operation is produced as a reply message into the `outputChannel`. For a single request, the reply message is created based on the `SendResult`. With request message payload as a `Collection>`, the `SqsAsyncOperations.sendManyAsync()` is performed; the `SendResult.Batch` is produced as is as a payload of the reply message. The minimal configuration for this channel adapter is as follows: