The existing `com.amazonaws:dynamodb-lock-client` does not implement
a locking algorithm properly and there is no easy way to determine if
lock has been abandoned according to the current `leaseDuration` behavior.
* Implement `DynamoDbLockRepository` to interact with lock table in this manner:
- `lockKey` as a primary key
- `lockOwner` as a unique owner client for the lock
- `createdAt` just an info when the lock was created by the client
- `expiredAt` the time in epoch seconds how long the lock is treated as valid
- this `expiredAt` can be configured as a DynamoDb `TTL` feature
* The `DynamoDbLockRepository` uses a `leaseDuration` to calculate an `expiredAt`
and compares it with the current epoch seconds to see if lock is not valid anymore
* Rework `DynamoDbLockRegistry` to rely on the `DynamoDbLockRepository`
* Remove `com.amazonaws:dynamodb-lock-client` dependency as we don't need it anymore
* Implement `RenewableLockRegistry` contract for simple `expiredAt` update
Fixes https://github.com/spring-cloud/spring-cloud-stream-binder-aws-kinesis/issues/186
The `DynamoDbLockClient` waits extra `leaseDuration` time in a loop breaking a `tryLock()` contract.
* Fix `DynamoDbLockRegistry.tryLock()` to decrease an actual `additionalTimeToWait` by `leaseDuration`,
so the target `DynamoDbLockClient` when it adds this `leaseDuration` will wait an actual timeout requested
by the `tryLock()` contract.
This way a `tryLock(0)` will definitely return immediately since we really are not interested in blocking
**cherry-pick to 2.5.x**
Fixes https://github.com/spring-cloud/spring-cloud-stream-binder-aws-kinesis/issues/187
The `ShardConsumer` performs a `getShardIterator()` request with some sequence number from checkpointer.
When the shard is closed, it fails with an `InvalidArgumentException` not letting us mark such a consumer a stopped.
* Catch `InvalidArgumentException` on the `getShardIterator()` and see if error is related to a closed shard.
Log such a message and proceed to a `STOP` state for the current `ShardConsumer`.
**Cherry-pick to `2.5.x`**
Related to https://github.com/spring-cloud/spring-cloud-stream-binder-aws-kinesis/issues/180
* Treat non-positive `DynamoDbLockRegistry.heartbeatPeriod` as no heartbeat.
This way locks renewal is a responsibility of the target `DynamoDbLockRegistry` consumer.
For example, the `KinesisMessageDrivenChannelAdapter` does call `tryLock()` in a loop
for locks on shards it is consuming at the moment
* Increase locks loop sleep timeout in the `KinesisMessageDrivenChannelAdapter` to one second
to avoid many requests to DynamoDB
**Cherry-pick to `2.5.x`**
Fixes https://github.com/spring-projects/spring-integration-aws/issues/219
Turns out the `AmazonDynamoDBLockClient` doesn't have a proper logic to
determine correct `lookupTime` and if we want to skip blocking waits,
the item is always treated as not expired because just obtained item from DB
is updated to the current time for its `lookupTime` property
* Remove the logic in the `DynamoDbLockRegistry` setting `withShouldSkipBlockingWait(true)`
**Cherry-pick to `2.5.x`**
Fixes https://github.com/spring-projects/spring-integration-aws/issues/218
The `AbstractMessageAttributesHeaderMapper` incorrectly logs only for
SQS service.
* Fix `logger` property to be a `protected` and not `static` to make it
rely on the `getClass()` context
* Fix logging message in the `fromHeaders()` from just `SQS` to `the current AWS service`
**Cherry-pick to `2.5.x`**
* Upgrade to Gradle `7.6`
* Apply Spring Integration code style
* Replace obsolete Travis CI with GitHub Actions
* Fix test XML configs for the latest Mockito
Fixes https://github.com/spring-projects/spring-integration-aws/issues/196
* Add support for SNS FIFO message group and deduplication IDs
* Add Javadoc, clean up formatting
* Fix Javadoc formatting
* Add SNS FIFO information to README
* Change XML snippet indentation to tabs
* Code samples throughout the README mix tabs and spaces, but this
snippet was using tabs, so this updates the new lines to match.
* Minor code style clean up
**Cherry-pick to `main`**
Fixes https://github.com/spring-projects/spring-integration-aws/issues/207
* Expose `failOnMissingQueue` flag support for `SqsMessageDrivenChannelAdapter`
* Upgrade to `spring-cloud-aws-2.4.2`
* `fail-on-missing-queue` property support
* `SqsMessageDrivenChannelAdapterParserTests` update
**Cherry-pick to `main`**
# Conflicts:
# build.gradle
Fixes https://github.com/spring-projects/spring-integration-aws/issues/206
* Provide a Glue Schema support for `KplMessageHandler`.
When `UserRecord` is built from the request message, a
`glueSchemaExpression` is evaluated to supply into a `UserRecord`
to produce.
The `GlueSchemaRegistryConfiguration` must be supplied into a `KinesisProducerConfiguration`
* Fix the `buildPutRecordRequest()` algorithm to copy the data
from the `UserRecord` in the request message payload instead of
false-leading expression evaluations and conversions from the request message
**Cherry-pick to `2.5.x`**
The `withReuse(true)` and `testcontainers.reuse.enable=true` don't work together with `@Container`.
The JUnit extension gathers those containers and stop them in the end of test class unconditionally.
* Remove `@Container` annotation usage
* Use `@BeforeAll` and `GenericContainer.start()` manually
This way the container ensures to reuse existing running container and don't start a fresh one.
Since the container instance is stored in a `static` property, it is really started only once.
The rest tests in a suite just reuse that existing container.
Ryuk container will take care about their stopping and removal eventually after JVM exit.
Fixes https://github.com/spring-projects/spring-integration-aws/issues/205
The `AmazonDynamoDBLockClient.acquireLock()` steps into a busy-wait loop with a sleep timeout.
* Use `AcquireLockOptions.shouldSkipBlockingWait = true` for `tryLock()` without timeout
to have an immediate answer according `tryLock()` contract
* Reset flag to `false` for all other use-cases with `AcquireLockOptions`
**Cherry-pick to `2.5.x`**
It's misleading to see an error for interrupted `KinesisMessageDrivenChannelAdapter.ShardConsumerManager`
on shutdown.
* Move `this.shardConsumerManagerFuture.cancel(true)` in the `doStop()` after `this.active = false;`
* fix(KinesisMessageDrivenChannelAdapter): added logic to not use the NextShardIterator if Manual Checkpointer hasnt reached the last checkpoint
* fix(KinesisMessageDrivenChannel): added logs for getNextShardIterator
* fix(KinesisMessageDrivenChannelAdapter): fixed logic and comments issue
* feat(KinesisMessageDrivenChannelAdapter): implemented integration tests for getNextShardIterator new usecase
* feat(KinesisMessageDrivenChannelAdapter): updated @author
* feat(KinesisMessageDrivenChannelAdapterTests): added author data