diff --git a/README.md b/README.md
index 70cfab314..47fb59bd7 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,6 @@
-# Powertools for AWS Lambda (Java)
+# Powertools for AWS Lambda (Java) V2
+
+**This is pre-release code for Powertools for AWS Lambda (Java) V2! Please check out the `main` branch for the stable release**
   [](https://app.codecov.io/gh/aws-powertools/powertools-lambda-java)
diff --git a/docs/utilities/large_messages.md b/docs/utilities/large_messages.md
index c4947a6e8..c0c1cd599 100644
--- a/docs/utilities/large_messages.md
+++ b/docs/utilities/large_messages.md
@@ -6,12 +6,6 @@ description: Utility
The large message utility handles SQS and SNS messages which have had their payloads
offloaded to S3 if they are larger than the maximum allowed size (256 KB).
-!!! Notice
- The large message utility (available in the `powertools-sqs` module for versions v1.16.1 and earlier) is now deprecated
- and replaced by the `powertools-large-messages` described in this page.
- You can still get the documentation [here](sqs_large_message_handling.md)
- and the migration guide [here](#migration-from-the-sqs-large-message-utility).
-
## Features
- Automatically retrieve the content of S3 objects when SQS or SNS messages have been offloaded to S3.
diff --git a/docs/utilities/sqs_batch.md b/docs/utilities/sqs_batch.md
deleted file mode 100644
index 658f7b085..000000000
--- a/docs/utilities/sqs_batch.md
+++ /dev/null
@@ -1,489 +0,0 @@
----
-title: SQS Batch Processing (Deprecated)
-description: Utility
----
-
-!!! warning
- The SQS batch module is now deprecated and will be removed in v2 of the library. Use the [batch module](batch.md),
- and check out **[migrating to the batch library](#migrating-to-the-batch-library)** for migration instructions.
-
-The SQS batch processing utility provides a way to handle partial failures when processing batches of messages from SQS.
-The utility handles batch processing for both
-[standard](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/standard-queues.html) and
-[FIFO](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/FIFO-queues.html) SQS queues.
-
-**Key Features**
-
-* Prevent successfully processed messages from being returned to SQS
-* A simple interface for individually processing messages from a batch
-
-**Background**
-
-When using SQS as a Lambda event source mapping, Lambda functions can be triggered with a batch of messages from SQS.
-If your function fails to process any message from the batch, the entire batch returns to your SQS queue, and your
-Lambda function will be triggered with the same batch again. With this utility, messages within a batch will be handled individually - only messages that were not successfully processed
-are returned to the queue.
-
-!!! warning
- While this utility lowers the chance of processing messages more than once, it is not guaranteed. We recommend implementing processing logic in an idempotent manner wherever possible.
- More details on how Lambda works with SQS can be found in the [AWS documentation](https://docs.aws.amazon.com/lambda/latest/dg/with-sqs.html)
-
-## Install
-
-Depending on your version of Java (either Java 1.8 or 11+), the configuration slightly changes.
-
-=== "Maven Java 11+"
-
- ```xml hl_lines="3-7 16 18 24-27""
-
- ...
-
- software.amazon.lambda
- powertools-sqs
- {{ powertools.version }}
-
- ...
-
- ...
-
-
-
- ...
-
- dev.aspectj
- aspectj-maven-plugin
- 1.13.1
-
- 11
- 11
- 11
-
-
- software.amazon.lambda
- powertools-sqs
-
-
-
-
-
-
- compile
-
-
-
-
- ...
-
-
- ```
-
-=== "Maven Java 1.8"
-
- ```xml hl_lines="3-7 16 18 24-27"
-
- ...
-
- software.amazon.lambda
- powertools-sqs
- {{ powertools.version }}
-
- ...
-
- ...
-
-
-
- ...
-
- org.codehaus.mojo
- aspectj-maven-plugin
- 1.14.0
-
- 1.8
- 1.8
- 1.8
-
-
- software.amazon.lambda
- powertools-sqs
-
-
-
-
-
-
- compile
-
-
-
-
- ...
-
-
- ```
-
-=== "Gradle Java 11+"
-
- ```groovy hl_lines="3 11"
- plugins {
- id 'java'
- id 'io.freefair.aspectj.post-compile-weaving' version '8.1.0'
- }
-
- repositories {
- mavenCentral()
- }
-
- dependencies {
- aspect 'software.amazon.lambda:powertools-sqs:{{ powertools.version }}'
- }
-
- sourceCompatibility = 11 // or higher
- targetCompatibility = 11 // or higher
- ```
-
-=== "Gradle Java 1.8"
-
- ```groovy hl_lines="3 11"
- plugins {
- id 'java'
- id 'io.freefair.aspectj.post-compile-weaving' version '6.6.3'
- }
-
- repositories {
- mavenCentral()
- }
-
- dependencies {
- aspect 'software.amazon.lambda:powertools-sqs:{{ powertools.version }}'
- }
-
- sourceCompatibility = 1.8
- targetCompatibility = 1.8
- ```
-
-## IAM Permissions
-
-This utility requires additional permissions to work as expected. Lambda functions using this utility require the `sqs:DeleteMessageBatch` permission.
-
-If you are also using [nonRetryableExceptions](#move-non-retryable-messages-to-a-dead-letter-queue) attribute, utility will need additional permission of `sqs:GetQueueAttributes` on source SQS.
-It also needs `sqs:SendMessage` and `sqs:SendMessageBatch` on configured dead letter queue.
-
-If source or dead letter queue is configured to use encryption at rest using [AWS Key Management Service (KMS)](https://aws.amazon.com/kms/), function will need additional permissions of
-`kms:GenerateDataKey` and `kms:Decrypt` on the KMS key being used for encryption. Refer [docs](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-key-management.html#compatibility-with-aws-services) for more details.
-
-Refer [example project](https://github.com/aws-samples/aws-lambda-powertools-examples/blob/main/java/SqsBatchProcessing/template.yaml#L105) for policy details example.
-
-
-## Processing messages from SQS
-
-You can use either **[SqsBatch annotation](#sqsbatch-annotation)**, or **[SqsUtils Utility API](#sqsutils-utility-api)** as a fluent API.
-
-Both have nearly the same behaviour when it comes to processing messages from the batch:
-
-* **Entire batch has been successfully processed**, where your Lambda handler returned successfully, we will let SQS delete the batch to optimize your cost
-* **Entire Batch has been partially processed successfully**, where exceptions were raised within your `SqsMessageHandler` interface implementation, we will:
- - **1)** Delete successfully processed messages from the queue by directly calling `sqs:DeleteMessageBatch`
- - **2)** If a message with a [message group ID](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/using-messagegroupid-property.html) fails,
- the processing of the batch will be stopped and the remainder of the messages will be returned to SQS.
- This behaviour [is required to handle SQS FIFO queues](https://docs.aws.amazon.com/lambda/latest/dg/with-sqs.html#services-sqs-batchfailurereporting).
- - **3)** if non retryable exceptions occur, messages resulting in configured exceptions during processing will be immediately moved to the dead letter queue associated to the source SQS queue or deleted from the source SQS queue if `deleteNonRetryableMessageFromQueue` is set to `true`.
- - **4)** Raise `SQSBatchProcessingException` to ensure failed messages return to your SQS queue
-
-The only difference is that **SqsUtils Utility API** will give you access to return from the processed messages if you need. Exception `SQSBatchProcessingException` thrown from the
-utility will have access to both successful and failed messaged along with failure exceptions.
-
-## Functional Interface SqsMessageHandler
-
-Both [annotation](#sqsbatch-annotation) and [SqsUtils Utility API](#sqsutils-utility-api) requires an implementation of functional interface `SqsMessageHandler`.
-
-This implementation is responsible for processing each individual message from the batch, and to raise an exception if unable to process any of the messages sent.
-
-**Any non-exception/successful return from your record handler function** will instruct utility to queue up each individual message for deletion.
-
-### SqsBatch annotation
-
-When using this annotation, you need provide a class implementation of `SqsMessageHandler` that will process individual messages from the batch - It should raise an exception if it is unable to process the record.
-
-All records in the batch will be passed to this handler for processing, even if exceptions are thrown - Here's the behaviour after completing the batch:
-
-* **Any successfully processed messages**, we will delete them from the queue via `sqs:DeleteMessageBatch`.
-* **if, nonRetryableExceptions attribute is used**, messages resulting in configured exceptions during processing will be immediately moved to the dead letter queue associated to the source SQS queue or deleted from the source SQS queue if `deleteNonRetryableMessageFromQueue` is set to `true`.
-* **Any unprocessed messages detected**, we will raise `SQSBatchProcessingException` to ensure failed messages return to your SQS queue.
-
-!!! warning
- You will not have access to the **processed messages** within the Lambda Handler - all processing logic will and should be performed by the implemented `#!java SqsMessageHandler#process()` function.
-
-=== "AppSqsEvent.java"
-
- ```java hl_lines="7"
- import software.amazon.lambda.powertools.sqs.SqsBatch;
- import software.amazon.lambda.powertools.sqs.SqsMessageHandler;
- import software.amazon.lambda.powertools.sqs.SqsUtils;
-
- public class AppSqsEvent implements RequestHandler {
- @Override
- @SqsBatch(SampleMessageHandler.class)
- public String handleRequest(SQSEvent input, Context context) {
- return "{\"statusCode\": 200}";
- }
-
- public class SampleMessageHandler implements SqsMessageHandler
- */
-public class SQSBatchProcessingException extends RuntimeException {
-
- private final List exceptions;
- private final List failures;
- private final List returnValues;
-
- public SQSBatchProcessingException(final List exceptions,
- final List failures,
- final List successReturns) {
- super(exceptions.stream()
- .map(Throwable::toString)
- .collect(joining("\n")));
-
- this.exceptions = new ArrayList<>(exceptions);
- this.failures = new ArrayList<>(failures);
- this.returnValues = new ArrayList<>(successReturns);
- }
-
- /**
- * Details for exceptions that occurred while processing messages in {@link SqsMessageHandler#process(SQSMessage)}
- *
- * @return List of exceptions that occurred while processing messages
- */
- public List getExceptions() {
- return unmodifiableList(exceptions);
- }
-
- /**
- * List of returns from {@link SqsMessageHandler#process(SQSMessage)} that were successfully processed.
- *
- * @return List of returns from successfully processed messages
- */
- public List successMessageReturnValues() {
- return unmodifiableList(returnValues);
- }
-
- /**
- * Details of {@link SQSMessage} that failed in {@link SqsMessageHandler#process(SQSMessage)}
- *
- * @return List of failed messages
- */
- public List getFailures() {
- return unmodifiableList(failures);
- }
-
- @Override
- public void printStackTrace() {
- for (Exception exception : exceptions) {
- exception.printStackTrace();
- }
- }
-}
diff --git a/powertools-sqs/src/main/java/software/amazon/lambda/powertools/sqs/SqsBatch.java b/powertools-sqs/src/main/java/software/amazon/lambda/powertools/sqs/SqsBatch.java
deleted file mode 100644
index 4378fa707..000000000
--- a/powertools-sqs/src/main/java/software/amazon/lambda/powertools/sqs/SqsBatch.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright 2023 Amazon.com, Inc. or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package software.amazon.lambda.powertools.sqs;
-
-import static com.amazonaws.services.lambda.runtime.events.SQSEvent.SQSMessage;
-
-import com.amazonaws.services.lambda.runtime.events.SQSEvent;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * @deprecated
- * @see software.amazon.lambda.powertools.batch in powertools-batch module.
- * Will be removed in V2.
- *
- * {@link SqsBatch} is used to process batch messages in {@link SQSEvent}
- *
- *
- * When using the annotation, implementation of {@link SqsMessageHandler} is required. Annotation will take care of
- * calling {@link SqsMessageHandler#process(SQSMessage)} method for each {@link SQSMessage} in the received {@link SQSEvent}
- *
- *
- *
- * If any exception is thrown from {@link SqsMessageHandler#process(SQSMessage)} during processing of a messages, Utility
- * will take care of deleting all the successful messages from SQS. When one or more single message fails processing due
- * to exception thrown from {@link SqsMessageHandler#process(SQSMessage)}, Lambda execution will fail
- * with {@link SQSBatchProcessingException}.
- *
- * If all the messages are successfully processes, No SQS messages are deleted explicitly but is rather delegated to
- * Lambda execution context for deletion.
- *
- *
- *
- * If you want to suppress the exception even if any message in batch fails, set
- * {@link SqsBatch#suppressException()} to true. By default its value is false
- *
- *
- *
- * If you want certain exceptions to be treated as permanent failures, i.e. exceptions where the result of retrying will
- * always be a failure and want these can be immediately moved to the dead letter queue associated to the source SQS queue,
- *
- * you can use {@link SqsBatch#nonRetryableExceptions()} to configure such exceptions.
- * Make sure function execution role has sqs:GetQueueAttributes permission on source SQS queue and sqs:SendMessage,
- * sqs:SendMessageBatch permission for configured DLQ.
- *
- * If you want such messages to be deleted instead, set {@link SqsBatch#deleteNonRetryableMessageFromQueue()} to true.
- * By default its value is false.
- *
- * If there is no DLQ configured on source SQS queue and {@link SqsBatch#nonRetryableExceptions()} attribute is set, if
- * nonRetryableExceptions occurs from {@link SqsMessageHandler}, such exceptions will still be treated as temporary
- * exceptions and the message will be moved back to source SQS queue for reprocessing. The same behaviour will occur if
- * for some reason the utility is unable to move the message to the DLQ. An example of this could be because the function
- * is missing the correct permissions.
- *
- *
- * @see Amazon SQS dead-letter queues
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.METHOD)
-@Deprecated
-public @interface SqsBatch {
-
- Class extends SqsMessageHandler> value();
-
- boolean suppressException() default false;
-
- Class extends Exception>[] nonRetryableExceptions() default {};
-
- boolean deleteNonRetryableMessageFromQueue() default false;
-}
diff --git a/powertools-sqs/src/main/java/software/amazon/lambda/powertools/sqs/SqsLargeMessage.java b/powertools-sqs/src/main/java/software/amazon/lambda/powertools/sqs/SqsLargeMessage.java
deleted file mode 100644
index a3a92cea1..000000000
--- a/powertools-sqs/src/main/java/software/amazon/lambda/powertools/sqs/SqsLargeMessage.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright 2023 Amazon.com, Inc. or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package software.amazon.lambda.powertools.sqs;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * @deprecated See software.amazon.lambda.powertools.largemessages.LargeMessage in powertools-large-messages module.
- * Will be removed in version 2.
- *
- *
{@code SqsLargeMessage} is used to signal that the annotated method
- * should be extended to handle large SQS messages which have been offloaded
- * to S3
- *
- *
{@code SqsLargeMessage} automatically retrieves and deletes messages
- * which have been offloaded to S3 using the {@code amazon-sqs-java-extended-client-lib}
- * client library.
- *
- *
This version of the {@code SqsLargeMessage} is compatible with version
- * 1.1.0+ of {@code amazon-sqs-java-extended-client-lib}.
{@code SqsLargeMessage} should be used with the handleRequest method of a class
- * which implements {@code com.amazonaws.services.lambda.runtime.RequestHandler} with
- * {@code com.amazonaws.services.lambda.runtime.events.SQSEvent} as the first parameter.
Using the default S3 Client {@code AmazonS3 amazonS3 = AmazonS3ClientBuilder.defaultClient();}
- * each record received in the SQSEvent {@code SqsLargeMessage} will checked
- * to see if it's body contains a payload which has been offloaded to S3. If it
- * does then {@code getObject(bucket, key)} will be called and the payload
- * retrieved.
- *
- *
Note: Retreiving payloads from S3 will increase the duration of the
- * Lambda function.
- *
- *
If the request handler method returns then each payload will be deleted
- * from S3 using {@code deleteObject(bucket, key)}
- *
- *
To disable deletion of payloads setting the following annotation parameter
- * {@code @SqsLargeMessage(deletePayloads=false)}
- */
-@Deprecated
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.METHOD)
-public @interface SqsLargeMessage {
-
- boolean deletePayloads() default true;
-}
diff --git a/powertools-sqs/src/main/java/software/amazon/lambda/powertools/sqs/SqsMessageHandler.java b/powertools-sqs/src/main/java/software/amazon/lambda/powertools/sqs/SqsMessageHandler.java
deleted file mode 100644
index 0c8f03ee9..000000000
--- a/powertools-sqs/src/main/java/software/amazon/lambda/powertools/sqs/SqsMessageHandler.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright 2023 Amazon.com, Inc. or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package software.amazon.lambda.powertools.sqs;
-
-import static com.amazonaws.services.lambda.runtime.events.SQSEvent.SQSMessage;
-
-import com.amazonaws.services.lambda.runtime.events.SQSEvent;
-
-/**
- *
- * This interface should be implemented for processing {@link SQSMessage} inside {@link SQSEvent} received by lambda
- * function.
- *
- *
- *
- * @param Return value type from {@link SqsMessageHandler#process(SQSMessage)}
- */
-@FunctionalInterface
-public interface SqsMessageHandler {
-
- R process(SQSMessage message);
-}
diff --git a/powertools-sqs/src/main/java/software/amazon/lambda/powertools/sqs/SqsUtils.java b/powertools-sqs/src/main/java/software/amazon/lambda/powertools/sqs/SqsUtils.java
deleted file mode 100644
index d89642780..000000000
--- a/powertools-sqs/src/main/java/software/amazon/lambda/powertools/sqs/SqsUtils.java
+++ /dev/null
@@ -1,653 +0,0 @@
-/*
- * Copyright 2023 Amazon.com, Inc. or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package software.amazon.lambda.powertools.sqs;
-
-import static com.amazonaws.services.lambda.runtime.events.SQSEvent.SQSMessage;
-import static software.amazon.lambda.powertools.sqs.internal.SqsLargeMessageAspect.processMessages;
-
-import com.amazonaws.services.lambda.runtime.events.SQSEvent;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import java.lang.reflect.Constructor;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration;
-import software.amazon.awssdk.core.client.config.SdkAdvancedClientOption;
-import software.amazon.awssdk.services.s3.S3Client;
-import software.amazon.awssdk.services.sqs.SqsClient;
-import software.amazon.lambda.powertools.core.internal.UserAgentConfigurator;
-import software.amazon.lambda.powertools.sqs.exception.SkippedMessageDueToFailedBatchException;
-import software.amazon.lambda.powertools.sqs.internal.BatchContext;
-import software.amazon.lambda.powertools.sqs.internal.SqsLargeMessageAspect;
-import software.amazon.payloadoffloading.PayloadS3Pointer;
-
-/**
- * A class of helper functions to add additional functionality to {@link SQSEvent} processing.
- *
- * @deprecated Batch processing is now handled in powertools-batch and large messages in powertools-large-messages.
- * This class will no longer be available in version 2.
- */
-@Deprecated
-public final class SqsUtils {
-
- public static final String SQS = "sqs";
- private static final Logger LOG = LoggerFactory.getLogger(SqsUtils.class);
- private static final ObjectMapper objectMapper = new ObjectMapper();
- private static final String MESSAGE_GROUP_ID = "MessageGroupId";
- private static SqsClient client;
- private static S3Client s3Client;
-
- private SqsUtils() {
- }
-
- /**
- * This is a utility method when you want to avoid using {@code SqsLargeMessage} annotation.
- * Gives you access to enriched messages from S3 in the SQS event produced via extended client lib.
- * If all the large S3 payload are successfully retrieved, it will delete them from S3 post success.
- *
- * @param sqsEvent Event received from SQS Extended client library
- * @param messageFunction Function to execute you business logic which provides access to enriched messages from S3 when needed.
- * @return Return value from the function.
- */
- public static R enrichedMessageFromS3(final SQSEvent sqsEvent,
- final Function, R> messageFunction) {
- return enrichedMessageFromS3(sqsEvent, true, messageFunction);
- }
-
- /**
- * This is a utility method when you want to avoid using {@code SqsLargeMessage} annotation.
- * Gives you access to enriched messages from S3 in the SQS event produced via extended client lib.
- * if all the large S3 payload are successfully retrieved, Control if it will delete payload from S3 post success.
- *
- * @param sqsEvent Event received from SQS Extended client library
- * @param messageFunction Function to execute you business logic which provides access to enriched messages from S3 when needed.
- * @return Return value from the function.
- */
- public static R enrichedMessageFromS3(final SQSEvent sqsEvent,
- final boolean deleteS3Payload,
- final Function, R> messageFunction) {
-
- List sqsMessages = sqsEvent.getRecords().stream()
- .map(SqsUtils::clonedMessage)
- .collect(Collectors.toList());
-
- List s3Pointers = processMessages(sqsMessages);
-
- R returnValue = messageFunction.apply(sqsMessages);
-
- if (deleteS3Payload) {
- s3Pointers.forEach(SqsLargeMessageAspect::deleteMessage);
- }
-
- return returnValue;
- }
-
- /**
- * Provides ability to set default {@link SqsClient} to be used by utility.
- * If no default configuration is provided, client is instantiated via {@link SqsClient#create()}
- *
- * @param client {@link SqsClient} to be used by utility
- */
- public static void overrideSqsClient(SqsClient client) {
- SqsUtils.client = client;
- }
-
- /**
- * By default, the S3Client is instantiated via {@link S3Client#create()}.
- * This method provides the ability to override the S3Client with your own custom version.
- *
- * @param s3Client {@link S3Client} to be used by utility
- */
- public static void overrideS3Client(S3Client s3Client) {
- SqsUtils.s3Client = s3Client;
- }
-
- /**
- *
- * @deprecated
- * @see software.amazon.lambda.powertools.batch in powertools-batch module.
- * Will be removed in V2.
- *
- * This utility method is used to process each {@link SQSMessage} inside the received {@link SQSEvent}
- *
- *
- * The Utility will call {@link SqsMessageHandler#process(SQSMessage)} method for each {@link SQSMessage}
- * in the received {@link SQSEvent}
- *
- *
- *
- * If any exception is thrown from {@link SqsMessageHandler#process(SQSMessage)} during processing of a message,
- * the utility will take care of deleting all the successful messages from SQS. When one or more single message fails
- * processing due to exception thrown from {@link SqsMessageHandler#process(SQSMessage)}
- * {@link SQSBatchProcessingException} is thrown with all the details of successful and failed messages.
- *
- * If all the messages are successfully processes, No SQS messages are deleted explicitly but is rather delegated to
- * Lambda execution context for deletion.
- *
- *
- *
- * If you dont want the utility to throw {@link SQSBatchProcessingException} in case of failures but rather suppress
- * it, Refer {@link SqsUtils#batchProcessor(SQSEvent, boolean, Class)}
- *
- *
- * @param event {@link SQSEvent} received by lambda function.
- * @param handler Class implementing {@link SqsMessageHandler} which will be called for each message in event.
- * @return List of values returned by {@link SqsMessageHandler#process(SQSMessage)} while processing each message.
- * @throws SQSBatchProcessingException if some messages fail during processing.
- */
- @Deprecated
- public static List batchProcessor(final SQSEvent event,
- final Class extends SqsMessageHandler> handler) {
- return batchProcessor(event, false, handler);
- }
-
- /**
- * @deprecated
- * @see software.amazon.lambda.powertools.batch in powertools-batch module.
- * Will be removed in V2.
- *
- * This utility method is used to process each {@link SQSMessage} inside the received {@link SQSEvent}
- *
- *
- * The Utility will call {@link SqsMessageHandler#process(SQSMessage)} method for each {@link SQSMessage}
- * in the received {@link SQSEvent}
- *
- *
- * If any exception is thrown from {@link SqsMessageHandler#process(SQSMessage)} during processing of a message,
- * the utility will take care of deleting all the successful messages from SQS. When one or more single message fails
- * processing due to exception thrown from {@link SqsMessageHandler#process(SQSMessage)}
- * {@link SQSBatchProcessingException} is thrown with all the details of successful and failed messages.
- *
- *
- *
- *
- * If all the messages are successfully processes, No SQS messages are deleted explicitly but is rather delegated to
- * Lambda execution context for deletion.
- *
- *
- *
- * If you dont want the utility to throw {@link SQSBatchProcessingException} in case of failures but rather suppress
- * it, Refer {@link SqsUtils#batchProcessor(SQSEvent, boolean, Class)}
- *
- *
- *
- * If you want certain exceptions to be treated as permanent failures, i.e. exceptions where the result of retrying will
- * always be a failure and want these can be immediately moved to the dead letter queue associated to the source SQS queue,
- * you can use nonRetryableExceptions parameter to configure such exceptions.
- *
- * Make sure function execution role has sqs:GetQueueAttributes permission on source SQS queue and sqs:SendMessage,
- * sqs:SendMessageBatch permission for configured DLQ.
- *
- * If there is no DLQ configured on source SQS queue and {@link SqsBatch#nonRetryableExceptions()} attribute is set, if
- * nonRetryableExceptions occurs from {@link SqsMessageHandler}, such exceptions will still be treated as temporary
- * exceptions and the message will be moved back to source SQS queue for reprocessing. The same behaviour will occur if
- * for some reason the utility is unable to move the message to the DLQ. An example of this could be because the function
- * is missing the correct permissions.
- *
- *
- * @param event {@link SQSEvent} received by lambda function.
- * @param handler Class implementing {@link SqsMessageHandler} which will be called for each message in event.
- * @param nonRetryableExceptions exception classes that are to be treated as permanent exceptions and to be moved
- * to DLQ.
- * @return List of values returned by {@link SqsMessageHandler#process(SQSMessage)} while processing each message.
- * @throws SQSBatchProcessingException if some messages fail during processing.
- * @see Amazon SQS dead-letter queues
- */
- @SafeVarargs
- @Deprecated
- public static List batchProcessor(final SQSEvent event,
- final Class extends SqsMessageHandler> handler,
- final Class extends Exception>... nonRetryableExceptions) {
- return batchProcessor(event, false, handler, nonRetryableExceptions);
- }
-
- /**
- * @deprecated
- * @see software.amazon.lambda.powertools.batch in powertools-batch module.
- * Will be removed in V2.
- *
- * This utility method is used to process each {@link SQSMessage} inside the received {@link SQSEvent}
- *
- *
- * The Utility will call {@link SqsMessageHandler#process(SQSMessage)} method for each {@link SQSMessage}
- * in the received {@link SQSEvent}
- *
- *
- * If any exception is thrown from {@link SqsMessageHandler#process(SQSMessage)} during processing of a message,
- * the utility will take care of deleting all the successful messages from SQS. When one or more single message fails
- * processing due to exception thrown from {@link SqsMessageHandler#process(SQSMessage)}
- * {@link SQSBatchProcessingException} is thrown with all the details of successful and failed messages.
- *
- * Exception can also be suppressed if desired.
- *
- * If all the messages are successfully processes, No SQS messages are deleted explicitly but is rather delegated to
- * Lambda execution context for deletion.
- *
- *
- * @param event {@link SQSEvent} received by lambda function.
- * @param suppressException if this is set to true, No {@link SQSBatchProcessingException} is thrown even on failed
- * messages.
- * @param handler Class implementing {@link SqsMessageHandler} which will be called for each message in event.
- * @return List of values returned by {@link SqsMessageHandler#process(SQSMessage)} while processing each message.
- * @throws SQSBatchProcessingException if some messages fail during processing and no suppression enabled.
- */
- @Deprecated
- public static List batchProcessor(final SQSEvent event,
- final boolean suppressException,
- final Class extends SqsMessageHandler> handler) {
-
- SqsMessageHandler handlerInstance = instantiatedHandler(handler);
- return batchProcessor(event, suppressException, handlerInstance);
- }
-
- /**
- * @deprecated
- * @see software.amazon.lambda.powertools.batch in powertools-batch module.
- * Will be removed in V2.
- *
- * This utility method is used to process each {@link SQSMessage} inside the received {@link SQSEvent}
- *
- *
- * The Utility will call {@link SqsMessageHandler#process(SQSMessage)} method for each {@link SQSMessage}
- * in the received {@link SQSEvent}
- *
- *
- * If any exception is thrown from {@link SqsMessageHandler#process(SQSMessage)} during processing of a message,
- * the utility will take care of deleting all the successful messages from SQS. When one or more single message fails
- * processing due to exception thrown from {@link SqsMessageHandler#process(SQSMessage)}
- * {@link SQSBatchProcessingException} is thrown with all the details of successful and failed messages.
- *
- *
- *
- *
- * If all the messages are successfully processes, No SQS messages are deleted explicitly but is rather delegated to
- * Lambda execution context for deletion.
- *
- *
- *
- * If you dont want the utility to throw {@link SQSBatchProcessingException} in case of failures but rather suppress
- * it, Refer {@link SqsUtils#batchProcessor(SQSEvent, boolean, Class)}
- *
- *
- *
- * If you want certain exceptions to be treated as permanent failures, i.e. exceptions where the result of retrying will
- * always be a failure and want these can be immediately moved to the dead letter queue associated to the source SQS queue,
- * you can use nonRetryableExceptions parameter to configure such exceptions.
- *
- * Make sure function execution role has sqs:GetQueueAttributes permission on source SQS queue and sqs:SendMessage,
- * sqs:SendMessageBatch permission for configured DLQ.
- *
- * If there is no DLQ configured on source SQS queue and {@link SqsBatch#nonRetryableExceptions()} attribute is set, if
- * nonRetryableExceptions occurs from {@link SqsMessageHandler}, such exceptions will still be treated as temporary
- * exceptions and the message will be moved back to source SQS queue for reprocessing. The same behaviour will occur if
- * for some reason the utility is unable to move the message to the DLQ. An example of this could be because the function
- * is missing the correct permissions.
- *
- *
- * @param event {@link SQSEvent} received by lambda function.
- * @param suppressException if this is set to true, No {@link SQSBatchProcessingException} is thrown even on failed
- * messages.
- * @param handler Class implementing {@link SqsMessageHandler} which will be called for each message in event.
- * @param nonRetryableExceptions exception classes that are to be treated as permanent exceptions and to be moved
- * to DLQ.
- * @return List of values returned by {@link SqsMessageHandler#process(SQSMessage)} while processing each message.
- * @throws SQSBatchProcessingException if some messages fail during processing.
- * @see Amazon SQS dead-letter queues
- */
- @SafeVarargs
- @Deprecated
- public static List batchProcessor(final SQSEvent event,
- final boolean suppressException,
- final Class extends SqsMessageHandler> handler,
- final Class extends Exception>... nonRetryableExceptions) {
-
- SqsMessageHandler handlerInstance = instantiatedHandler(handler);
- return batchProcessor(event, suppressException, handlerInstance, false, nonRetryableExceptions);
- }
-
- /**
- * @deprecated
- * @see software.amazon.lambda.powertools.batch in powertools-batch module.
- * Will be removed in V2.
- *
- * This utility method is used to process each {@link SQSMessage} inside the received {@link SQSEvent}
- *
- *
- * The Utility will call {@link SqsMessageHandler#process(SQSMessage)} method for each {@link SQSMessage}
- * in the received {@link SQSEvent}
- *
- *
- *
- * If any exception is thrown from {@link SqsMessageHandler#process(SQSMessage)} during processing of a message,
- * the utility will take care of deleting all the successful messages from SQS. When one or more single message fails
- * processing due to exception thrown from {@link SqsMessageHandler#process(SQSMessage)}
- * {@link SQSBatchProcessingException} is thrown with all the details of successful and failed messages.
- *
- *
- *
- *
- * If all the messages are successfully processes, No SQS messages are deleted explicitly but is rather delegated to
- * Lambda execution context for deletion.
- *
- *
- *
- * If you dont want the utility to throw {@link SQSBatchProcessingException} in case of failures but rather suppress
- * it, Refer {@link SqsUtils#batchProcessor(SQSEvent, boolean, Class)}
- *
- *
- *
- * If you want certain exceptions to be treated as permanent failures, i.e. exceptions where the result of retrying will
- * always be a failure and want these can be immediately moved to the dead letter queue associated to the source SQS queue,
- * you can use nonRetryableExceptions parameter to configure such exceptions.
- *
- * Make sure function execution role has sqs:GetQueueAttributes permission on source SQS queue and sqs:SendMessage,
- * sqs:SendMessageBatch permission for configured DLQ.
- *
- * If you want such messages to be deleted instead, set deleteNonRetryableMessageFromQueue to true.
- *
- * If there is no DLQ configured on source SQS queue and {@link SqsBatch#nonRetryableExceptions()} attribute is set, if
- * nonRetryableExceptions occurs from {@link SqsMessageHandler}, such exceptions will still be treated as temporary
- * exceptions and the message will be moved back to source SQS queue for reprocessing. The same behaviour will occur if
- * for some reason the utility is unable to move the message to the DLQ. An example of this could be because the function
- * is missing the correct permissions.
- *
- *
- * @param event {@link SQSEvent} received by lambda function.
- * @param suppressException if this is set to true, No {@link SQSBatchProcessingException} is thrown even on failed
- * messages.
- * @param handler Class implementing {@link SqsMessageHandler} which will be called for each message in event.
- * @param deleteNonRetryableMessageFromQueue If messages with nonRetryableExceptions are to be deleted from SQS queue.
- * @param nonRetryableExceptions exception classes that are to be treated as permanent exceptions and to be moved
- * to DLQ.
- * @return List of values returned by {@link SqsMessageHandler#process(SQSMessage)} while processing each message.
- * @throws SQSBatchProcessingException if some messages fail during processing.
- * @see Amazon SQS dead-letter queues
- */
- @SafeVarargs
- @Deprecated
- public static List batchProcessor(final SQSEvent event,
- final boolean suppressException,
- final Class extends SqsMessageHandler> handler,
- final boolean deleteNonRetryableMessageFromQueue,
- final Class extends Exception>... nonRetryableExceptions) {
-
- SqsMessageHandler handlerInstance = instantiatedHandler(handler);
- return batchProcessor(event, suppressException, handlerInstance, deleteNonRetryableMessageFromQueue,
- nonRetryableExceptions);
- }
-
- /**
- * @deprecated
- * @see software.amazon.lambda.powertools.batch in powertools-batch module.
- * Will be removed in V2.
- *
- * This utility method is used to process each {@link SQSMessage} inside the received {@link SQSEvent}
- *
- *
- * The Utility will call {@link SqsMessageHandler#process(SQSMessage)} method for each {@link SQSMessage}
- * in the received {@link SQSEvent}
- *
- *
- *
- * If any exception is thrown from {@link SqsMessageHandler#process(SQSMessage)} during processing of a messages,
- * Utility will take care of deleting all the successful messages from SQS. When one or more single message fails
- * processing due to exception thrown from {@link SqsMessageHandler#process(SQSMessage)}
- * {@link SQSBatchProcessingException} is thrown with all the details of successful and failed messages.
- *
- * If all the messages are successfully processes, No SQS messages are deleted explicitly but is rather delegated to
- * Lambda execution context for deletion.
- *
- *
- *
- * If you dont want the utility to throw {@link SQSBatchProcessingException} in case of failures but rather suppress
- * it, Refer {@link SqsUtils#batchProcessor(SQSEvent, boolean, SqsMessageHandler)}
- *
- *
- * @param event {@link SQSEvent} received by lambda function.
- * @param handler Instance of class implementing {@link SqsMessageHandler} which will be called for each message in event.
- * @return List of values returned by {@link SqsMessageHandler#process(SQSMessage)} while processing each message-
- * @throws SQSBatchProcessingException if some messages fail during processing.
- */
- @Deprecated
- public static List batchProcessor(final SQSEvent event,
- final SqsMessageHandler handler) {
- return batchProcessor(event, false, handler);
- }
-
-
- /**
- * @deprecated
- * @see software.amazon.lambda.powertools.batch in powertools-batch module.
- * Will be removed in V2.
- *
- * This utility method is used to process each {@link SQSMessage} inside the received {@link SQSEvent}
- *
- *
- * The Utility will call {@link SqsMessageHandler#process(SQSMessage)} method for each {@link SQSMessage}
- * in the received {@link SQSEvent}
- *
- *
- *
- * If any exception is thrown from {@link SqsMessageHandler#process(SQSMessage)} during processing of a message,
- * the utility will take care of deleting all the successful messages from SQS. When one or more single message fails
- * processing due to exception thrown from {@link SqsMessageHandler#process(SQSMessage)}
- * {@link SQSBatchProcessingException} is thrown with all the details of successful and failed messages.
- *
- *
- *
- *
- * If all the messages are successfully processes, No SQS messages are deleted explicitly but is rather delegated to
- * Lambda execution context for deletion.
- *
- *
- *
- * If you dont want the utility to throw {@link SQSBatchProcessingException} in case of failures but rather suppress
- * it, Refer {@link SqsUtils#batchProcessor(SQSEvent, boolean, Class)}
- *
- *
- *
- * If you want certain exceptions to be treated as permanent failures, i.e. exceptions where the result of retrying will
- * always be a failure and want these can be immediately moved to the dead letter queue associated to the source SQS queue,
- * you can use nonRetryableExceptions parameter to configure such exceptions.
- *
- * Make sure function execution role has sqs:GetQueueAttributes permission on source SQS queue and sqs:SendMessage,
- * sqs:SendMessageBatch permission for configured DLQ.
- *
- * If there is no DLQ configured on source SQS queue and {@link SqsBatch#nonRetryableExceptions()} attribute is set, if
- * nonRetryableExceptions occurs from {@link SqsMessageHandler}, such exceptions will still be treated as temporary
- * exceptions and the message will be moved back to source SQS queue for reprocessing.The same behaviour will occur if
- * for some reason the utility is unable to moved the message to the DLQ. An example of this could be because the function
- * is missing the correct permissions.
- *
- *
- * @param event {@link SQSEvent} received by lambda function.
- * @param handler Instance of class implementing {@link SqsMessageHandler} which will be called for each message in event.
- * @param nonRetryableExceptions exception classes that are to be treated as permanent exceptions and to be moved
- * to DLQ.
- * @return List of values returned by {@link SqsMessageHandler#process(SQSMessage)} while processing each message.
- * @throws SQSBatchProcessingException if some messages fail during processing.
- * @see Amazon SQS dead-letter queues
- */
- @SafeVarargs
- @Deprecated
- public static List batchProcessor(final SQSEvent event,
- final SqsMessageHandler handler,
- final Class extends Exception>... nonRetryableExceptions) {
- return batchProcessor(event, false, handler, false, nonRetryableExceptions);
- }
-
-
- /**
- * @deprecated
- * @see software.amazon.lambda.powertools.batch in powertools-batch module.
- * Will be removed in V2.
- *
- * This utility method is used to process each {@link SQSMessage} inside the received {@link SQSEvent}
- *
- *
- * The Utility will call {@link SqsMessageHandler#process(SQSMessage)} method for each {@link SQSMessage}
- * in the received {@link SQSEvent}
- *
- *
- *
- * If any exception is thrown from {@link SqsMessageHandler#process(SQSMessage)} during processing of a messages,
- * the utility will take care of deleting all the successful messages from SQS. When one or more single message fails
- * processing due to exception thrown from {@link SqsMessageHandler#process(SQSMessage)}
- * {@link SQSBatchProcessingException} is thrown with all the details of successful and failed messages.
- *
- * Exception can also be suppressed if desired.
- *
- * If all the messages are successfully processes, No SQS messages are deleted explicitly but is rather delegated to
- * Lambda execution context for deletion.
- *
- *
- * @param event {@link SQSEvent} received by lambda function.
- * @param suppressException if this is set to true, No {@link SQSBatchProcessingException} is thrown even on failed
- * messages.
- * @param handler Instance of class implementing {@link SqsMessageHandler} which will be called for each message in event.
- * @return List of values returned by {@link SqsMessageHandler#process(SQSMessage)} while processing each message.
- * @throws SQSBatchProcessingException if some messages fail during processing and no suppression enabled.
- */
- @Deprecated
- public static List batchProcessor(final SQSEvent event,
- final boolean suppressException,
- final SqsMessageHandler handler) {
- return batchProcessor(event, suppressException, handler, false);
-
- }
-
- /**
- * @deprecated
- * @see software.amazon.lambda.powertools.batch in powertools-batch module.
- * Will be removed in V2.
- */
- @SafeVarargs
- @Deprecated
- public static List batchProcessor(final SQSEvent event,
- final boolean suppressException,
- final SqsMessageHandler handler,
- final boolean deleteNonRetryableMessageFromQueue,
- final Class extends Exception>... nonRetryableExceptions) {
- final List handlerReturn = new ArrayList<>();
-
- if (client == null) {
- client = (SqsClient) SqsClient.builder()
- .overrideConfiguration(ClientOverrideConfiguration.builder()
- .putAdvancedOption(SdkAdvancedClientOption.USER_AGENT_SUFFIX,
- UserAgentConfigurator.getUserAgent(SQS))
- .build());
- }
-
- BatchContext batchContext = new BatchContext(client);
- int offset = 0;
- boolean failedBatch = false;
- while (offset < event.getRecords().size() && !failedBatch) {
- // Get the current message and advance to the next. Doing this here
- // makes it easier for us to know where we are up to if we have to
- // break out of here early.
- SQSMessage message = event.getRecords().get(offset);
- offset++;
-
- // If the batch hasn't failed, try process the message
- try {
- handlerReturn.add(handler.process(message));
- batchContext.addSuccess(message);
- } catch (Exception e) {
-
- // Record the failure
- batchContext.addFailure(message, e);
-
- // If we are trying to process a message that has a messageGroupId, we are on a FIFO queue. A failure
- // now stops us from processing the rest of the batch; we break out of the loop leaving unprocessed
- // messages in the queue
- // https://docs.aws.amazon.com/lambda/latest/dg/with-sqs.html#services-sqs-batchfailurereporting
- String messageGroupId = message.getAttributes() != null ?
- message.getAttributes().get(MESSAGE_GROUP_ID) : null;
- if (messageGroupId != null) {
- LOG.info(
- "A message in a message batch with messageGroupId {} and messageId {} failed; failing the rest of the batch too"
- , messageGroupId, message.getMessageId());
- failedBatch = true;
- }
- LOG.error("Encountered issue processing message: {}", message.getMessageId(), e);
- }
- }
-
- // If we have a FIFO batch failure, unprocessed messages will remain on the queue
- // past the failed message. We have to add these to the errors
- if (offset < event.getRecords().size()) {
- event.getRecords()
- .subList(offset, event.getRecords().size())
- .forEach(message ->
- {
- LOG.info("Skipping message {} as another message with a message group failed in this batch",
- message.getMessageId());
- batchContext.addFailure(message, new SkippedMessageDueToFailedBatchException());
- });
- }
-
- batchContext.processSuccessAndHandleFailed(handlerReturn, suppressException, deleteNonRetryableMessageFromQueue,
- nonRetryableExceptions);
- return handlerReturn;
- }
-
- private static SqsMessageHandler instantiatedHandler(final Class extends SqsMessageHandler> handler) {
-
- try {
- if (null == handler.getDeclaringClass()) {
- return handler.getDeclaredConstructor().newInstance();
- }
-
- final Constructor extends SqsMessageHandler> constructor =
- handler.getDeclaredConstructor(handler.getDeclaringClass());
- constructor.setAccessible(true);
- return constructor.newInstance(handler.getDeclaringClass().getDeclaredConstructor().newInstance());
- } catch (Exception e) {
- LOG.error("Failed creating handler instance", e);
- throw new RuntimeException("Unexpected error occurred. Please raise issue at " +
- "https://github.com/aws-powertools/powertools-lambda-java/issues", e);
- }
- }
-
- private static SQSMessage clonedMessage(final SQSMessage sqsMessage) {
- try {
- return objectMapper
- .readValue(objectMapper.writeValueAsString(sqsMessage), SQSMessage.class);
- } catch (JsonProcessingException e) {
- throw new RuntimeException(e);
- }
- }
-
- public static ObjectMapper objectMapper() {
- return objectMapper;
- }
-
- public static S3Client s3Client() {
- if (null == s3Client) {
- s3Client = (S3Client) S3Client.builder()
- .overrideConfiguration(ClientOverrideConfiguration.builder()
- .putAdvancedOption(SdkAdvancedClientOption.USER_AGENT_SUFFIX,
- UserAgentConfigurator.getUserAgent(SQS))
- .build());
- SqsUtils.s3Client = S3Client.create();
- }
-
- return s3Client;
- }
-}
diff --git a/powertools-sqs/src/main/java/software/amazon/lambda/powertools/sqs/exception/SkippedMessageDueToFailedBatchException.java b/powertools-sqs/src/main/java/software/amazon/lambda/powertools/sqs/exception/SkippedMessageDueToFailedBatchException.java
deleted file mode 100644
index fbb4289d8..000000000
--- a/powertools-sqs/src/main/java/software/amazon/lambda/powertools/sqs/exception/SkippedMessageDueToFailedBatchException.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright 2023 Amazon.com, Inc. or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package software.amazon.lambda.powertools.sqs.exception;
-
-/**
- * Indicates that a message has been skipped due to the batch it is
- * within failing.
- */
-public class SkippedMessageDueToFailedBatchException extends Exception {
-
- public SkippedMessageDueToFailedBatchException() {
- }
-
-}
diff --git a/powertools-sqs/src/main/java/software/amazon/lambda/powertools/sqs/internal/BatchContext.java b/powertools-sqs/src/main/java/software/amazon/lambda/powertools/sqs/internal/BatchContext.java
deleted file mode 100644
index 70cf04fb8..000000000
--- a/powertools-sqs/src/main/java/software/amazon/lambda/powertools/sqs/internal/BatchContext.java
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Copyright 2023 Amazon.com, Inc. or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package software.amazon.lambda.powertools.sqs.internal;
-
-import static com.amazonaws.services.lambda.runtime.events.SQSEvent.SQSMessage;
-import static java.lang.String.format;
-import static java.util.Optional.ofNullable;
-import static java.util.stream.Collectors.toList;
-
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.JsonNode;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-import java.util.stream.IntStream;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import software.amazon.awssdk.core.SdkBytes;
-import software.amazon.awssdk.services.sqs.SqsClient;
-import software.amazon.awssdk.services.sqs.model.DeleteMessageBatchRequest;
-import software.amazon.awssdk.services.sqs.model.DeleteMessageBatchRequestEntry;
-import software.amazon.awssdk.services.sqs.model.DeleteMessageBatchResponse;
-import software.amazon.awssdk.services.sqs.model.GetQueueAttributesRequest;
-import software.amazon.awssdk.services.sqs.model.GetQueueAttributesResponse;
-import software.amazon.awssdk.services.sqs.model.MessageAttributeValue;
-import software.amazon.awssdk.services.sqs.model.QueueAttributeName;
-import software.amazon.awssdk.services.sqs.model.SendMessageBatchRequest;
-import software.amazon.awssdk.services.sqs.model.SendMessageBatchRequestEntry;
-import software.amazon.awssdk.services.sqs.model.SendMessageBatchResponse;
-import software.amazon.lambda.powertools.sqs.SQSBatchProcessingException;
-import software.amazon.lambda.powertools.sqs.SqsUtils;
-
-public final class BatchContext {
- private static final Logger LOG = LoggerFactory.getLogger(BatchContext.class);
- private static final Map QUEUE_ARN_TO_DLQ_URL_MAPPING = new HashMap<>();
-
- private final Map messageToException = new HashMap<>();
- private final List success = new ArrayList<>();
-
- private final SqsClient client;
-
- public BatchContext(SqsClient client) {
- this.client = client;
- }
-
- public void addSuccess(SQSMessage event) {
- success.add(event);
- }
-
- public void addFailure(SQSMessage event, Exception e) {
- messageToException.put(event, e);
- }
-
- @SafeVarargs
- public final void processSuccessAndHandleFailed(final List successReturns,
- final boolean suppressException,
- final boolean deleteNonRetryableMessageFromQueue,
- final Class extends Exception>... nonRetryableExceptions) {
- if (hasFailures()) {
-
- List exceptions = new ArrayList<>();
- List failedMessages = new ArrayList<>();
- Map nonRetryableMessageToException = new HashMap<>();
-
- if (nonRetryableExceptions.length == 0) {
- exceptions.addAll(messageToException.values());
- failedMessages.addAll(messageToException.keySet());
- } else {
- messageToException.forEach((sqsMessage, exception) ->
- {
- boolean nonRetryableException = isNonRetryableException(exception, nonRetryableExceptions);
-
- if (nonRetryableException) {
- nonRetryableMessageToException.put(sqsMessage, exception);
- } else {
- exceptions.add(exception);
- failedMessages.add(sqsMessage);
- }
- });
- }
-
- List messagesToBeDeleted = new ArrayList<>(success);
-
- if (!nonRetryableMessageToException.isEmpty() && deleteNonRetryableMessageFromQueue) {
- messagesToBeDeleted.addAll(nonRetryableMessageToException.keySet());
- } else if (!nonRetryableMessageToException.isEmpty()) {
-
- boolean isMovedToDlq = moveNonRetryableMessagesToDlqIfConfigured(nonRetryableMessageToException);
-
- if (!isMovedToDlq) {
- exceptions.addAll(nonRetryableMessageToException.values());
- failedMessages.addAll(nonRetryableMessageToException.keySet());
- }
- }
-
- deleteMessagesFromQueue(messagesToBeDeleted);
-
- processFailedMessages(successReturns, suppressException, exceptions, failedMessages);
- }
- }
-
- private void processFailedMessages(List successReturns,
- boolean suppressException,
- List exceptions,
- List failedMessages) {
- if (failedMessages.isEmpty()) {
- return;
- }
-
- if (suppressException) {
- List messageIds = failedMessages.stream().
- map(SQSMessage::getMessageId)
- .collect(toList());
-
- LOG.debug(format("[%d] records failed processing, but exceptions are suppressed. " +
- "Failed messages %s", failedMessages.size(), messageIds));
- } else {
- throw new SQSBatchProcessingException(exceptions, failedMessages, successReturns);
- }
- }
-
- private boolean isNonRetryableException(Exception exception, Class extends Exception>[] nonRetryableExceptions) {
- return Arrays.stream(nonRetryableExceptions)
- .anyMatch(aClass -> aClass.isInstance(exception));
- }
-
- private boolean moveNonRetryableMessagesToDlqIfConfigured(
- Map nonRetryableMessageToException) {
- Optional dlqUrl = fetchDlqUrl(nonRetryableMessageToException);
-
- if (!dlqUrl.isPresent()) {
- return false;
- }
-
- List dlqMessages = nonRetryableMessageToException.keySet().stream()
- .map(sqsMessage ->
- {
- Map messageAttributesMap = new HashMap<>();
-
- sqsMessage.getMessageAttributes().forEach((s, messageAttribute) ->
- {
- MessageAttributeValue.Builder builder = MessageAttributeValue.builder();
-
- builder
- .dataType(messageAttribute.getDataType())
- .stringValue(messageAttribute.getStringValue());
-
- if (null != messageAttribute.getBinaryValue()) {
- builder.binaryValue(SdkBytes.fromByteBuffer(messageAttribute.getBinaryValue()));
- }
-
- messageAttributesMap.put(s, builder.build());
- });
-
- return SendMessageBatchRequestEntry.builder()
- .messageBody(sqsMessage.getBody())
- .id(sqsMessage.getMessageId())
- .messageAttributes(messageAttributesMap)
- .build();
- })
- .collect(toList());
-
- List sendMessageBatchResponses = batchRequest(dlqMessages, 10, entriesToSend ->
- {
-
- SendMessageBatchResponse sendMessageBatchResponse =
- client.sendMessageBatch(SendMessageBatchRequest.builder()
- .entries(entriesToSend)
- .queueUrl(dlqUrl.get())
- .build());
-
-
- LOG.debug("Response from send batch message to DLQ request {}", sendMessageBatchResponse);
-
- return sendMessageBatchResponse;
- });
-
- return sendMessageBatchResponses.stream()
- .filter(response -> null != response && response.hasFailed())
- .peek(sendMessageBatchResponse -> LOG.error(
- "Failed sending message to the DLQ. Entire batch will be re processed. Check if needed permissions are configured for the function. Response: {}",
- sendMessageBatchResponse))
- .count() == 0;
- }
-
-
- private Optional fetchDlqUrl(Map nonRetryableMessageToException) {
- return nonRetryableMessageToException.keySet().stream()
- .findFirst()
- .map(sqsMessage -> QUEUE_ARN_TO_DLQ_URL_MAPPING.computeIfAbsent(sqsMessage.getEventSourceArn(),
- sourceArn ->
- {
- String queueUrl = url(sourceArn);
-
- GetQueueAttributesResponse queueAttributes =
- client.getQueueAttributes(GetQueueAttributesRequest.builder()
- .attributeNames(QueueAttributeName.REDRIVE_POLICY)
- .queueUrl(queueUrl)
- .build());
-
- return ofNullable(queueAttributes.attributes().get(QueueAttributeName.REDRIVE_POLICY))
- .map(policy ->
- {
- try {
- return SqsUtils.objectMapper().readTree(policy);
- } catch (JsonProcessingException e) {
- LOG.debug(
- "Unable to parse Re drive policy for queue {}. Even if DLQ exists, failed messages will be send back to main queue.",
- queueUrl, e);
- return null;
- }
- })
- .map(node -> node.get("deadLetterTargetArn"))
- .map(JsonNode::asText)
- .map(this::url)
- .orElse(null);
- }));
- }
-
- private boolean hasFailures() {
- return !messageToException.isEmpty();
- }
-
- private void deleteMessagesFromQueue(final List messages) {
- if (!messages.isEmpty()) {
-
- List entries =
- messages.stream().map(m -> DeleteMessageBatchRequestEntry.builder()
- .id(m.getMessageId())
- .receiptHandle(m.getReceiptHandle())
- .build()).collect(toList());
-
- batchRequest(entries, 10, entriesToDelete ->
- {
- DeleteMessageBatchRequest request = DeleteMessageBatchRequest.builder()
- .queueUrl(url(messages.get(0).getEventSourceArn()))
- .entries(entriesToDelete)
- .build();
-
- DeleteMessageBatchResponse deleteMessageBatchResponse = client.deleteMessageBatch(request);
-
- LOG.debug("Response from delete request {}", deleteMessageBatchResponse);
-
- return deleteMessageBatchResponse;
- });
- }
- }
-
- private List batchRequest(final List listOFEntries,
- final int size,
- final Function, R> batchLogic) {
-
- return IntStream.range(0, listOFEntries.size())
- .filter(index -> index % size == 0)
- .mapToObj(index -> listOFEntries.subList(index, Math.min(index + size, listOFEntries.size())))
- .map(batchLogic)
- .collect(Collectors.toList());
- }
-
- private String url(String queueArn) {
- String[] arnArray = queueArn.split(":");
- return String.format("https://sqs.%s.amazonaws.com/%s/%s", arnArray[3], arnArray[4], arnArray[5]);
- }
-}
diff --git a/powertools-sqs/src/main/java/software/amazon/lambda/powertools/sqs/internal/SqsLargeMessageAspect.java b/powertools-sqs/src/main/java/software/amazon/lambda/powertools/sqs/internal/SqsLargeMessageAspect.java
deleted file mode 100644
index e5176e13a..000000000
--- a/powertools-sqs/src/main/java/software/amazon/lambda/powertools/sqs/internal/SqsLargeMessageAspect.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright 2023 Amazon.com, Inc. or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package software.amazon.lambda.powertools.sqs.internal;
-
-import static com.amazonaws.services.lambda.runtime.events.SQSEvent.SQSMessage;
-import static java.lang.String.format;
-import static software.amazon.lambda.powertools.core.internal.LambdaHandlerProcessor.isHandlerMethod;
-import static software.amazon.lambda.powertools.sqs.SqsUtils.s3Client;
-
-import com.amazonaws.services.lambda.runtime.Context;
-import com.amazonaws.services.lambda.runtime.events.SQSEvent;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Optional;
-import java.util.function.Function;
-import org.aspectj.lang.ProceedingJoinPoint;
-import org.aspectj.lang.annotation.Around;
-import org.aspectj.lang.annotation.Aspect;
-import org.aspectj.lang.annotation.Pointcut;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import software.amazon.awssdk.core.ResponseInputStream;
-import software.amazon.awssdk.core.exception.SdkClientException;
-import software.amazon.awssdk.services.s3.model.DeleteObjectRequest;
-import software.amazon.awssdk.services.s3.model.GetObjectRequest;
-import software.amazon.awssdk.services.s3.model.GetObjectResponse;
-import software.amazon.awssdk.services.s3.model.S3Exception;
-import software.amazon.awssdk.utils.IoUtils;
-import software.amazon.lambda.powertools.sqs.SqsLargeMessage;
-import software.amazon.payloadoffloading.PayloadS3Pointer;
-
-@Aspect
-public class SqsLargeMessageAspect {
-
- private static final Logger LOG = LoggerFactory.getLogger(SqsLargeMessageAspect.class);
-
- public static List processMessages(final List records) {
- List s3Pointers = new ArrayList<>();
- for (SQSMessage sqsMessage : records) {
- if (isBodyLargeMessagePointer(sqsMessage.getBody())) {
-
- PayloadS3Pointer s3Pointer = Optional.ofNullable(PayloadS3Pointer.fromJson(sqsMessage.getBody()))
- .orElseThrow(() -> new FailedProcessingLargePayloadException(
- format("Failed processing SQS body to extract S3 details. [ %s ].",
- sqsMessage.getBody())));
-
- ResponseInputStream s3Object = callS3Gracefully(s3Pointer, pointer ->
- {
- ResponseInputStream response =
- s3Client().getObject(GetObjectRequest.builder()
- .bucket(pointer.getS3BucketName())
- .key(pointer.getS3Key())
- .build());
-
- LOG.debug("Object downloaded with key: " + s3Pointer.getS3Key());
- return response;
- });
-
- sqsMessage.setBody(readStringFromS3Object(s3Object, s3Pointer));
- s3Pointers.add(s3Pointer);
- }
- }
-
- return s3Pointers;
- }
-
- private static boolean isBodyLargeMessagePointer(String record) {
- return record.startsWith("[\"software.amazon.payloadoffloading.PayloadS3Pointer\"");
- }
-
- private static String readStringFromS3Object(ResponseInputStream response,
- PayloadS3Pointer s3Pointer) {
- try (ResponseInputStream content = response) {
- return IoUtils.toUtf8String(content);
- } catch (IOException e) {
- LOG.error("Error converting S3 object to String", e);
- throw new FailedProcessingLargePayloadException(
- format("Failed processing S3 record with [Bucket Name: %s Bucket Key: %s]",
- s3Pointer.getS3BucketName(), s3Pointer.getS3Key()), e);
- }
- }
-
- public static void deleteMessage(PayloadS3Pointer s3Pointer) {
- callS3Gracefully(s3Pointer, pointer ->
- {
- s3Client().deleteObject(DeleteObjectRequest.builder()
- .bucket(pointer.getS3BucketName())
- .key(pointer.getS3Key())
- .build());
- LOG.info("Message deleted from S3: " + s3Pointer.toJson());
- return null;
- });
- }
-
- private static R callS3Gracefully(final PayloadS3Pointer pointer,
- final Function function) {
- try {
- return function.apply(pointer);
- } catch (S3Exception e) {
- LOG.error("A service exception", e);
- throw new FailedProcessingLargePayloadException(
- format("Failed processing S3 record with [Bucket Name: %s Bucket Key: %s]",
- pointer.getS3BucketName(), pointer.getS3Key()), e);
- } catch (SdkClientException e) {
- LOG.error("Some sort of client exception", e);
- throw new FailedProcessingLargePayloadException(
- format("Failed processing S3 record with [Bucket Name: %s Bucket Key: %s]",
- pointer.getS3BucketName(), pointer.getS3Key()), e);
- }
- }
-
- public static boolean placedOnSqsEventRequestHandler(ProceedingJoinPoint pjp) {
- return pjp.getArgs().length == 2
- && pjp.getArgs()[0] instanceof SQSEvent
- && pjp.getArgs()[1] instanceof Context;
- }
-
- @SuppressWarnings({"EmptyMethod"})
- @Pointcut("@annotation(sqsLargeMessage)")
- public void callAt(SqsLargeMessage sqsLargeMessage) {
- }
-
- @Around(value = "callAt(sqsLargeMessage) && execution(@SqsLargeMessage * *.*(..))", argNames = "pjp,sqsLargeMessage")
- public Object around(ProceedingJoinPoint pjp,
- SqsLargeMessage sqsLargeMessage) throws Throwable {
- Object[] proceedArgs = pjp.getArgs();
-
- if (isHandlerMethod(pjp)
- && placedOnSqsEventRequestHandler(pjp)) {
- List pointersToDelete = rewriteMessages((SQSEvent) proceedArgs[0]);
-
- Object proceed = pjp.proceed(proceedArgs);
-
- if (sqsLargeMessage.deletePayloads()) {
- pointersToDelete.forEach(SqsLargeMessageAspect::deleteMessage);
- }
- return proceed;
- }
-
- return pjp.proceed(proceedArgs);
- }
-
- private List rewriteMessages(SQSEvent sqsEvent) {
- List records = sqsEvent.getRecords();
- return processMessages(records);
- }
-
- public static class FailedProcessingLargePayloadException extends RuntimeException {
- public FailedProcessingLargePayloadException(String message, Throwable cause) {
- super(message, cause);
- }
-
- public FailedProcessingLargePayloadException(String message) {
- super(message);
- }
- }
-}
diff --git a/powertools-sqs/src/main/java/software/amazon/lambda/powertools/sqs/internal/SqsMessageBatchProcessorAspect.java b/powertools-sqs/src/main/java/software/amazon/lambda/powertools/sqs/internal/SqsMessageBatchProcessorAspect.java
deleted file mode 100644
index ff0b5b014..000000000
--- a/powertools-sqs/src/main/java/software/amazon/lambda/powertools/sqs/internal/SqsMessageBatchProcessorAspect.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2023 Amazon.com, Inc. or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package software.amazon.lambda.powertools.sqs.internal;
-
-import static software.amazon.lambda.powertools.core.internal.LambdaHandlerProcessor.isHandlerMethod;
-import static software.amazon.lambda.powertools.sqs.SqsUtils.batchProcessor;
-import static software.amazon.lambda.powertools.sqs.internal.SqsLargeMessageAspect.placedOnSqsEventRequestHandler;
-
-import com.amazonaws.services.lambda.runtime.events.SQSEvent;
-import org.aspectj.lang.ProceedingJoinPoint;
-import org.aspectj.lang.annotation.Around;
-import org.aspectj.lang.annotation.Aspect;
-import org.aspectj.lang.annotation.Pointcut;
-import software.amazon.lambda.powertools.sqs.SqsBatch;
-
-@Aspect
-public class SqsMessageBatchProcessorAspect {
-
- @SuppressWarnings({"EmptyMethod"})
- @Pointcut("@annotation(sqsBatch)")
- public void callAt(SqsBatch sqsBatch) {
- }
-
- @Around(value = "callAt(sqsBatch) && execution(@SqsBatch * *.*(..))", argNames = "pjp,sqsBatch")
- public Object around(ProceedingJoinPoint pjp,
- SqsBatch sqsBatch) throws Throwable {
- Object[] proceedArgs = pjp.getArgs();
-
- if (isHandlerMethod(pjp)
- && placedOnSqsEventRequestHandler(pjp)) {
-
- SQSEvent sqsEvent = (SQSEvent) proceedArgs[0];
-
- batchProcessor(sqsEvent,
- sqsBatch.suppressException(),
- sqsBatch.value(),
- sqsBatch.deleteNonRetryableMessageFromQueue(),
- sqsBatch.nonRetryableExceptions());
- }
-
- return pjp.proceed(proceedArgs);
- }
-}
diff --git a/powertools-sqs/src/test/java/software/amazon/lambda/powertools/sqs/SampleSqsHandler.java b/powertools-sqs/src/test/java/software/amazon/lambda/powertools/sqs/SampleSqsHandler.java
deleted file mode 100644
index 557aa214d..000000000
--- a/powertools-sqs/src/test/java/software/amazon/lambda/powertools/sqs/SampleSqsHandler.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright 2023 Amazon.com, Inc. or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package software.amazon.lambda.powertools.sqs;
-
-import com.amazonaws.services.lambda.runtime.events.SQSEvent;
-
-public class SampleSqsHandler implements SqsMessageHandler {
- private int counter;
-
- @Override
- public String process(SQSEvent.SQSMessage message) {
- return String.valueOf(counter++);
- }
-}
diff --git a/powertools-sqs/src/test/java/software/amazon/lambda/powertools/sqs/SqsUtilsBatchProcessorTest.java b/powertools-sqs/src/test/java/software/amazon/lambda/powertools/sqs/SqsUtilsBatchProcessorTest.java
deleted file mode 100644
index c0c334e78..000000000
--- a/powertools-sqs/src/test/java/software/amazon/lambda/powertools/sqs/SqsUtilsBatchProcessorTest.java
+++ /dev/null
@@ -1,386 +0,0 @@
-/*
- * Copyright 2023 Amazon.com, Inc. or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package software.amazon.lambda.powertools.sqs;
-
-import static com.amazonaws.services.lambda.runtime.events.SQSEvent.SQSMessage;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoInteractions;
-import static org.mockito.Mockito.when;
-import static software.amazon.lambda.powertools.sqs.SqsUtils.batchProcessor;
-import static software.amazon.lambda.powertools.sqs.SqsUtils.overrideSqsClient;
-
-import com.amazonaws.services.lambda.runtime.events.SQSEvent;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.List;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.ValueSource;
-import org.mockito.ArgumentCaptor;
-import software.amazon.awssdk.services.sqs.SqsClient;
-import software.amazon.awssdk.services.sqs.model.DeleteMessageBatchRequest;
-import software.amazon.awssdk.services.sqs.model.GetQueueAttributesRequest;
-import software.amazon.awssdk.services.sqs.model.GetQueueAttributesResponse;
-import software.amazon.awssdk.services.sqs.model.QueueAttributeName;
-import software.amazon.awssdk.services.sqs.model.SendMessageBatchRequest;
-
-class SqsUtilsBatchProcessorTest {
-
- private static final SqsClient sqsClient = mock(SqsClient.class);
- private static final SqsClient interactionClient = mock(SqsClient.class);
- private static final ObjectMapper MAPPER = new ObjectMapper();
- private SQSEvent event;
-
- @BeforeEach
- void setUp() throws IOException {
- reset(sqsClient, interactionClient);
- event = MAPPER.readValue(this.getClass().getResource("/sampleSqsBatchEvent.json"), SQSEvent.class);
- overrideSqsClient(sqsClient);
- }
-
- @Test
- void shouldBatchProcessAndNotDeleteMessagesWhenAllSuccess() {
- List returnValues = batchProcessor(event, false, (message) ->
- {
- interactionClient.listQueues();
- return "Success";
- });
-
- assertThat(returnValues)
- .hasSize(2)
- .containsExactly("Success", "Success");
-
- verify(interactionClient, times(2)).listQueues();
- verifyNoInteractions(sqsClient);
- }
-
- @ParameterizedTest
- @ValueSource(classes = {SampleInnerSqsHandler.class, SampleSqsHandler.class})
- void shouldBatchProcessViaClassAndNotDeleteMessagesWhenAllSuccess(
- Class extends SqsMessageHandler> handler) {
- List returnValues = batchProcessor(event, handler);
-
- assertThat(returnValues)
- .hasSize(2)
- .containsExactly("0", "1");
-
- verifyNoInteractions(sqsClient);
- }
-
- @Test
- void shouldBatchProcessAndDeleteSuccessMessageOnPartialFailures() {
- String failedId = "2e1424d4-f796-459a-8184-9c92662be6da";
-
- SqsMessageHandler failedHandler = (message) ->
- {
- if (failedId.equals(message.getMessageId())) {
- throw new RuntimeException("Failed processing");
- }
-
- interactionClient.listQueues();
- return "Success";
- };
-
- assertThatExceptionOfType(SQSBatchProcessingException.class)
- .isThrownBy(() -> batchProcessor(event, failedHandler))
- .satisfies(e ->
- {
-
- assertThat(e.successMessageReturnValues())
- .hasSize(1)
- .contains("Success");
-
- assertThat(e.getFailures())
- .hasSize(1)
- .extracting("messageId")
- .contains(failedId);
-
- assertThat(e.getExceptions())
- .hasSize(1)
- .extracting("detailMessage")
- .contains("Failed processing");
- });
-
- verify(interactionClient).listQueues();
-
- ArgumentCaptor captor = ArgumentCaptor.forClass(DeleteMessageBatchRequest.class);
- verify(sqsClient).deleteMessageBatch(captor.capture());
-
- assertThat(captor.getValue())
- .hasFieldOrPropertyWithValue("queueUrl", "https://sqs.us-east-2.amazonaws.com/123456789012/my-queue");
- }
-
- @Test
- void shouldBatchProcessAndFullFailuresInBatch() {
- SqsMessageHandler failedHandler = (message) ->
- {
- throw new RuntimeException(message.getMessageId());
- };
-
- assertThatExceptionOfType(SQSBatchProcessingException.class)
- .isThrownBy(() -> batchProcessor(event, failedHandler))
- .satisfies(e ->
- {
-
- assertThat(e.successMessageReturnValues())
- .isEmpty();
-
- assertThat(e.getFailures())
- .hasSize(2)
- .extracting("messageId")
- .containsExactly("059f36b4-87a3-44ab-83d2-661975830a7d",
- "2e1424d4-f796-459a-8184-9c92662be6da");
-
- assertThat(e.getExceptions())
- .hasSize(2)
- .extracting("detailMessage")
- .containsExactly("059f36b4-87a3-44ab-83d2-661975830a7d",
- "2e1424d4-f796-459a-8184-9c92662be6da");
- });
-
- verifyNoInteractions(sqsClient);
- }
-
- @Test
- void shouldBatchProcessViaClassAndDeleteSuccessMessageOnPartialFailures() {
- assertThatExceptionOfType(SQSBatchProcessingException.class)
- .isThrownBy(() -> batchProcessor(event, FailureSampleInnerSqsHandler.class))
- .satisfies(e ->
- {
-
- assertThat(e.successMessageReturnValues())
- .hasSize(1)
- .contains("Success");
-
- assertThat(e.getFailures())
- .hasSize(1)
- .extracting("messageId")
- .contains("2e1424d4-f796-459a-8184-9c92662be6da");
-
- assertThat(e.getExceptions())
- .hasSize(1)
- .extracting("detailMessage")
- .contains("Failed processing");
- });
-
- verify(sqsClient).deleteMessageBatch(any(DeleteMessageBatchRequest.class));
- }
-
-
- @Test
- void shouldBatchProcessAndSuppressExceptions() {
- String failedId = "2e1424d4-f796-459a-8184-9c92662be6da";
-
- SqsMessageHandler failedHandler = (message) ->
- {
- if (failedId.equals(message.getMessageId())) {
- throw new RuntimeException("Failed processing");
- }
-
- interactionClient.listQueues();
- return "Success";
- };
-
- List returnValues = batchProcessor(event, true, failedHandler);
-
- assertThat(returnValues)
- .hasSize(1)
- .contains("Success");
-
- verify(interactionClient).listQueues();
- verify(sqsClient).deleteMessageBatch(any(DeleteMessageBatchRequest.class));
- }
-
- @Test
- void shouldBatchProcessViaClassAndSuppressExceptions() {
- List returnValues = batchProcessor(event, true, FailureSampleInnerSqsHandler.class);
-
- assertThat(returnValues)
- .hasSize(1)
- .contains("Success");
-
- verify(interactionClient).listQueues();
- verify(sqsClient).deleteMessageBatch(any(DeleteMessageBatchRequest.class));
- }
-
- @Test
- void shouldBatchProcessAndMoveNonRetryableExceptionToDlq() {
- String failedId = "2e1424d4-f796-459a-8184-9c92662be6da";
- HashMap attributes = new HashMap<>();
-
- attributes.put(QueueAttributeName.REDRIVE_POLICY, "{\n" +
- " \"deadLetterTargetArn\": \"arn:aws:sqs:us-east-2:123456789012:retry-queue\",\n" +
- " \"maxReceiveCount\": 2\n" +
- "}");
-
- when(sqsClient.getQueueAttributes(any(GetQueueAttributesRequest.class))).thenReturn(
- GetQueueAttributesResponse.builder()
- .attributes(attributes)
- .build());
-
- List batchProcessor = batchProcessor(event, (message) ->
- {
- if (failedId.equals(message.getMessageId())) {
- throw new IllegalStateException("Failed processing");
- }
-
- interactionClient.listQueues();
- return "Success";
- }, IllegalStateException.class, IllegalArgumentException.class);
-
- assertThat(batchProcessor)
- .hasSize(1);
-
- verify(sqsClient).sendMessageBatch(any(SendMessageBatchRequest.class));
- }
-
- @Test
- void shouldBatchProcessAndDeleteNonRetryableException() {
- String failedId = "2e1424d4-f796-459a-8184-9c92662be6da";
- HashMap attributes = new HashMap<>();
-
- attributes.put(QueueAttributeName.REDRIVE_POLICY, "{\n" +
- " \"deadLetterTargetArn\": \"arn:aws:sqs:us-east-2:123456789012:retry-queue\",\n" +
- " \"maxReceiveCount\": 2\n" +
- "}");
-
- when(sqsClient.getQueueAttributes(any(GetQueueAttributesRequest.class))).thenReturn(
- GetQueueAttributesResponse.builder()
- .attributes(attributes)
- .build());
-
- List batchProcessor = batchProcessor(event, false, (message) ->
- {
- if (failedId.equals(message.getMessageId())) {
- throw new IllegalStateException("Failed processing");
- }
-
- interactionClient.listQueues();
- return "Success";
- }, true, IllegalStateException.class, IllegalArgumentException.class);
-
- assertThat(batchProcessor)
- .hasSize(1);
-
- verify(sqsClient, times(0)).sendMessageBatch(any(SendMessageBatchRequest.class));
- verify(sqsClient).deleteMessageBatch(any(DeleteMessageBatchRequest.class));
- }
-
- @Test
- void shouldDeleteSuccessfulMessageInBatchesOfT10orLess() throws IOException {
- SQSEvent batch25Message =
- MAPPER.readValue(this.getClass().getResource("/sampleSqsBatchEventBatchSize25.json"), SQSEvent.class);
-
- assertThatExceptionOfType(SQSBatchProcessingException.class)
- .isThrownBy(() -> batchProcessor(batch25Message, FailureSampleInnerSqsHandler.class))
- .satisfies(e ->
- {
-
- assertThat(e.successMessageReturnValues())
- .hasSize(24)
- .contains("Success");
-
- assertThat(e.getFailures())
- .hasSize(1)
- .extracting("messageId")
- .contains("2e1424d4-f796-459a-8184-9c92662be6da");
-
- assertThat(e.getExceptions())
- .hasSize(1)
- .extracting("detailMessage")
- .contains("Failed processing");
- });
-
- ArgumentCaptor captor = ArgumentCaptor.forClass(DeleteMessageBatchRequest.class);
-
- verify(sqsClient, times(3)).deleteMessageBatch(captor.capture());
-
- assertThat(captor.getAllValues())
- .hasSize(3)
- .flatMap(DeleteMessageBatchRequest::entries)
- .hasSize(24);
- }
-
- @Test
- void shouldBatchProcessAndMoveNonRetryableExceptionToDlqInBatchesOfT10orLess() throws IOException {
- SQSEvent batch25Message =
- MAPPER.readValue(this.getClass().getResource("/sampleSqsBatchEventBatchSize25.json"), SQSEvent.class);
-
- HashMap attributes = new HashMap<>();
-
- attributes.put(QueueAttributeName.REDRIVE_POLICY, "{\n" +
- " \"deadLetterTargetArn\": \"arn:aws:sqs:us-east-2:123456789012:retry-queue\",\n" +
- " \"maxReceiveCount\": 2\n" +
- "}");
-
- when(sqsClient.getQueueAttributes(any(GetQueueAttributesRequest.class))).thenReturn(
- GetQueueAttributesResponse.builder()
- .attributes(attributes)
- .build());
-
- List batchProcessor = batchProcessor(batch25Message, (message) ->
- {
- if ("2e1424d4-f796-459a-8184-9c92662be6da".equals(message.getMessageId())) {
- interactionClient.listQueues();
- return "Success";
- }
-
- throw new IllegalStateException("Failed processing");
- }, IllegalStateException.class, IllegalArgumentException.class);
-
- assertThat(batchProcessor)
- .hasSize(1);
-
- ArgumentCaptor captor = ArgumentCaptor.forClass(SendMessageBatchRequest.class);
-
-
- verify(sqsClient, times(3)).sendMessageBatch(captor.capture());
-
- assertThat(captor.getAllValues())
- .hasSize(3)
- .flatMap(SendMessageBatchRequest::entries)
- .hasSize(24);
- }
-
- public class SampleInnerSqsHandler implements SqsMessageHandler {
- private int counter;
-
- @Override
- public String process(SQSMessage message) {
- interactionClient.listQueues();
- return String.valueOf(counter++);
- }
- }
-
- public class FailureSampleInnerSqsHandler implements SqsMessageHandler {
- @Override
- public String process(SQSEvent.SQSMessage message) {
- if ("2e1424d4-f796-459a-8184-9c92662be6da".equals(message.getMessageId())) {
- throw new RuntimeException("Failed processing");
- }
-
- interactionClient.listQueues();
- return "Success";
- }
- }
-}
\ No newline at end of file
diff --git a/powertools-sqs/src/test/java/software/amazon/lambda/powertools/sqs/SqsUtilsFifoBatchProcessorTest.java b/powertools-sqs/src/test/java/software/amazon/lambda/powertools/sqs/SqsUtilsFifoBatchProcessorTest.java
deleted file mode 100644
index bfc555405..000000000
--- a/powertools-sqs/src/test/java/software/amazon/lambda/powertools/sqs/SqsUtilsFifoBatchProcessorTest.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Copyright 2023 Amazon.com, Inc. or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package software.amazon.lambda.powertools.sqs;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
-import static software.amazon.lambda.powertools.sqs.SqsUtils.batchProcessor;
-import static software.amazon.lambda.powertools.sqs.SqsUtils.overrideSqsClient;
-
-import com.amazonaws.services.lambda.runtime.events.SQSEvent;
-import com.amazonaws.services.lambda.runtime.tests.EventLoader;
-import java.io.IOException;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.stream.Collectors;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoSession;
-import org.mockito.quality.Strictness;
-import software.amazon.awssdk.services.sqs.SqsClient;
-import software.amazon.awssdk.services.sqs.model.DeleteMessageBatchRequest;
-import software.amazon.awssdk.services.sqs.model.DeleteMessageBatchRequestEntry;
-import software.amazon.awssdk.services.sqs.model.DeleteMessageBatchResponse;
-
-public class SqsUtilsFifoBatchProcessorTest {
-
- private static SQSEvent sqsBatchEvent;
- private MockitoSession session;
-
- @Mock
- private SqsClient sqsClient;
-
- @Captor
- private ArgumentCaptor deleteMessageBatchCaptor;
-
- public SqsUtilsFifoBatchProcessorTest() throws IOException {
- sqsBatchEvent = EventLoader.loadSQSEvent("SqsFifoBatchEvent.json");
- }
-
- @BeforeEach
- public void setup() {
- // Establish a strict mocking session. This means that any
- // calls to a mock that have not been stubbed will throw
- this.session = Mockito.mockitoSession()
- .strictness(Strictness.STRICT_STUBS)
- .initMocks(this)
- .startMocking();
-
- overrideSqsClient(sqsClient);
- }
-
- @AfterEach
- public void tearDown() {
- session.finishMocking();
- }
-
- @Test
- public void processWholeBatch() {
- // Act
- AtomicInteger processedCount = new AtomicInteger();
- List results = batchProcessor(sqsBatchEvent, false, (message) ->
- {
- processedCount.getAndIncrement();
- return true;
- });
-
- // Assert
- assertThat(processedCount.get()).isEqualTo(3);
- assertThat(results.size()).isEqualTo(3);
- }
-
- /**
- * Check that a failure in the middle of the batch:
- * - deletes the successful message explicitly from SQS
- * - marks the failed and subsequent message as failed
- * - does not delete the failed or subsequent message
- */
- @Test
- public void singleFailureInMiddleOfBatch() {
- // Arrange
- Mockito.when(sqsClient.deleteMessageBatch(deleteMessageBatchCaptor.capture()))
- .thenReturn(DeleteMessageBatchResponse
- .builder().build());
-
- // Act
- AtomicInteger processedCount = new AtomicInteger();
- assertThatExceptionOfType(SQSBatchProcessingException.class)
- .isThrownBy(() -> batchProcessor(sqsBatchEvent, false, (message) ->
- {
- int value = processedCount.getAndIncrement();
- if (value == 1) {
- throw new RuntimeException("Whoops");
- }
- return true;
- }))
-
- // Assert
- .isInstanceOf(SQSBatchProcessingException.class)
- .satisfies(e ->
- {
- List failures = ((SQSBatchProcessingException) e).getFailures();
- assertThat(failures.size()).isEqualTo(2);
- List failureIds = failures.stream()
- .map(SQSEvent.SQSMessage::getMessageId)
- .collect(Collectors.toList());
- assertThat(failureIds).contains(sqsBatchEvent.getRecords().get(1).getMessageId());
- assertThat(failureIds).contains(sqsBatchEvent.getRecords().get(2).getMessageId());
- });
-
- DeleteMessageBatchRequest deleteRequest = deleteMessageBatchCaptor.getValue();
- List messageIds = deleteRequest.entries().stream()
- .map(DeleteMessageBatchRequestEntry::id)
- .collect(Collectors.toList());
- assertThat(deleteRequest.entries().size()).isEqualTo(1);
- assertThat(messageIds.contains(sqsBatchEvent.getRecords().get(0).getMessageId())).isTrue();
-
- }
-
- @Test
- public void singleFailureAtEndOfBatch() {
-
- // Arrange
- Mockito.when(sqsClient.deleteMessageBatch(deleteMessageBatchCaptor.capture()))
- .thenReturn(DeleteMessageBatchResponse
- .builder().build());
-
-
- // Act
- AtomicInteger processedCount = new AtomicInteger();
- assertThatExceptionOfType(SQSBatchProcessingException.class)
- .isThrownBy(() -> batchProcessor(sqsBatchEvent, false, (message) ->
- {
- int value = processedCount.getAndIncrement();
- if (value == 2) {
- throw new RuntimeException("Whoops");
- }
- return true;
- }));
-
- // Assert
- DeleteMessageBatchRequest deleteRequest = deleteMessageBatchCaptor.getValue();
- List messageIds = deleteRequest.entries().stream()
- .map(DeleteMessageBatchRequestEntry::id)
- .collect(Collectors.toList());
- assertThat(deleteRequest.entries().size()).isEqualTo(2);
- assertThat(messageIds.contains(sqsBatchEvent.getRecords().get(0).getMessageId())).isTrue();
- assertThat(messageIds.contains(sqsBatchEvent.getRecords().get(1).getMessageId())).isTrue();
- assertThat(messageIds.contains(sqsBatchEvent.getRecords().get(2).getMessageId())).isFalse();
- }
-
- @Test
- public void messageFailureStopsGroupProcessing() {
- String groupToFail = sqsBatchEvent.getRecords().get(0).getAttributes().get("MessageGroupId");
-
- assertThatExceptionOfType(SQSBatchProcessingException.class)
- .isThrownBy(() -> batchProcessor(sqsBatchEvent, (message) ->
- {
- String groupId = message.getAttributes().get("MessageGroupId");
- if (groupId.equals(groupToFail)) {
- throw new RuntimeException("Failed processing");
- }
- return groupId;
- }))
- .satisfies(e ->
- {
- assertThat(e.successMessageReturnValues().size()).isEqualTo(0);
- assertThat(e.successMessageReturnValues().contains(groupToFail)).isFalse();
- });
- }
-
-}
diff --git a/powertools-sqs/src/test/java/software/amazon/lambda/powertools/sqs/SqsUtilsLargeMessageTest.java b/powertools-sqs/src/test/java/software/amazon/lambda/powertools/sqs/SqsUtilsLargeMessageTest.java
deleted file mode 100644
index afc426976..000000000
--- a/powertools-sqs/src/test/java/software/amazon/lambda/powertools/sqs/SqsUtilsLargeMessageTest.java
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Copyright 2023 Amazon.com, Inc. or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package software.amazon.lambda.powertools.sqs;
-
-import static com.amazonaws.services.lambda.runtime.events.SQSEvent.SQSMessage;
-import static java.util.Collections.singletonList;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoInteractions;
-import static org.mockito.Mockito.when;
-import static org.mockito.MockitoAnnotations.openMocks;
-
-import com.amazonaws.services.lambda.runtime.events.SQSEvent;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.function.Consumer;
-import java.util.stream.Stream;
-import org.assertj.core.api.Assertions;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.Arguments;
-import org.junit.jupiter.params.provider.MethodSource;
-import org.junit.jupiter.params.provider.ValueSource;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import software.amazon.awssdk.core.ResponseInputStream;
-import software.amazon.awssdk.core.exception.SdkClientException;
-import software.amazon.awssdk.http.AbortableInputStream;
-import software.amazon.awssdk.services.s3.S3Client;
-import software.amazon.awssdk.services.s3.model.DeleteObjectRequest;
-import software.amazon.awssdk.services.s3.model.GetObjectRequest;
-import software.amazon.awssdk.services.s3.model.GetObjectResponse;
-import software.amazon.awssdk.services.s3.model.S3Exception;
-import software.amazon.awssdk.utils.StringInputStream;
-import software.amazon.lambda.powertools.sqs.internal.SqsLargeMessageAspect;
-
-class SqsUtilsLargeMessageTest {
-
- private static final String BUCKET_NAME = "ms-extended-sqs-client";
- private static final String BUCKET_KEY = "c71eb2ae-37e0-4265-8909-32f4153faddf";
- @Mock
- private S3Client s3Client;
-
- private static Stream exception() {
- return Stream.of(Arguments.of(S3Exception.builder()
- .message("Service Exception")
- .build()),
- Arguments.of(SdkClientException.builder()
- .message("Client Exception")
- .build()));
- }
-
- @BeforeEach
- void setUp() {
- openMocks(this);
- SqsUtils.overrideS3Client(s3Client);
- }
-
- @Test
- public void testLargeMessage() {
- ResponseInputStream s3Response =
- new ResponseInputStream<>(GetObjectResponse.builder().build(),
- AbortableInputStream.create(new ByteArrayInputStream("A big message".getBytes())));
- when(s3Client.getObject(any(GetObjectRequest.class))).thenReturn(s3Response);
-
- SQSEvent sqsEvent = messageWithBody(
- "[\"software.amazon.payloadoffloading.PayloadS3Pointer\",{\"s3BucketName\":\"" + BUCKET_NAME +
- "\",\"s3Key\":\"" + BUCKET_KEY + "\"}]");
-
- Map sqsMessage = SqsUtils.enrichedMessageFromS3(sqsEvent, sqsMessages ->
- {
- Map someBusinessLogic = new HashMap<>();
- someBusinessLogic.put("Message", sqsMessages.get(0).getBody());
- return someBusinessLogic;
- });
-
- assertThat(sqsMessage)
- .hasSize(1)
- .containsEntry("Message", "A big message");
-
- ArgumentCaptor delete = ArgumentCaptor.forClass(DeleteObjectRequest.class);
-
- verify(s3Client).deleteObject(delete.capture());
-
- Assertions.assertThat(delete.getValue())
- .satisfies((Consumer) deleteObjectRequest ->
- {
- assertThat(deleteObjectRequest.bucket())
- .isEqualTo(BUCKET_NAME);
-
- assertThat(deleteObjectRequest.key())
- .isEqualTo(BUCKET_KEY);
- });
- }
-
- @ParameterizedTest
- @ValueSource(booleans = {true, false})
- public void testLargeMessageDeleteFromS3Toggle(boolean deleteS3Payload) {
- ResponseInputStream s3Response =
- new ResponseInputStream<>(GetObjectResponse.builder().build(),
- AbortableInputStream.create(new ByteArrayInputStream("A big message".getBytes())));
-
- when(s3Client.getObject(any(GetObjectRequest.class))).thenReturn(s3Response);
-
- SQSEvent sqsEvent = messageWithBody(
- "[\"software.amazon.payloadoffloading.PayloadS3Pointer\",{\"s3BucketName\":\"" + BUCKET_NAME +
- "\",\"s3Key\":\"" + BUCKET_KEY + "\"}]");
-
- Map sqsMessage = SqsUtils.enrichedMessageFromS3(sqsEvent, deleteS3Payload, sqsMessages ->
- {
- Map someBusinessLogic = new HashMap<>();
- someBusinessLogic.put("Message", sqsMessages.get(0).getBody());
- return someBusinessLogic;
- });
-
- assertThat(sqsMessage)
- .hasSize(1)
- .containsEntry("Message", "A big message");
- if (deleteS3Payload) {
- ArgumentCaptor delete = ArgumentCaptor.forClass(DeleteObjectRequest.class);
-
- verify(s3Client).deleteObject(delete.capture());
-
- Assertions.assertThat(delete.getValue())
- .satisfies((Consumer) deleteObjectRequest ->
- {
- assertThat(deleteObjectRequest.bucket())
- .isEqualTo(BUCKET_NAME);
-
- assertThat(deleteObjectRequest.key())
- .isEqualTo(BUCKET_KEY);
- });
- } else {
- verify(s3Client, never()).deleteObject(any(DeleteObjectRequest.class));
- }
- }
-
- @Test
- public void shouldNotProcessSmallMessageBody() {
- ResponseInputStream s3Response =
- new ResponseInputStream<>(GetObjectResponse.builder().build(),
- AbortableInputStream.create(new ByteArrayInputStream("A big message".getBytes())));
-
- when(s3Client.getObject(any(GetObjectRequest.class))).thenReturn(s3Response);
-
- SQSEvent sqsEvent = messageWithBody("This is small message");
-
- Map sqsMessage = SqsUtils.enrichedMessageFromS3(sqsEvent, sqsMessages ->
- {
- Map someBusinessLogic = new HashMap<>();
- someBusinessLogic.put("Message", sqsMessages.get(0).getBody());
- return someBusinessLogic;
- });
-
- assertThat(sqsMessage)
- .containsEntry("Message", "This is small message");
-
- verifyNoInteractions(s3Client);
- }
-
- @ParameterizedTest
- @MethodSource("exception")
- public void shouldFailEntireBatchIfFailedDownloadingFromS3(RuntimeException exception) {
- when(s3Client.getObject(any(GetObjectRequest.class))).thenThrow(exception);
-
- String messageBody =
- "[\"software.amazon.payloadoffloading.PayloadS3Pointer\",{\"s3BucketName\":\"" + BUCKET_NAME +
- "\",\"s3Key\":\"" + BUCKET_KEY + "\"}]";
- SQSEvent sqsEvent = messageWithBody(messageBody);
-
- assertThatExceptionOfType(SqsLargeMessageAspect.FailedProcessingLargePayloadException.class)
- .isThrownBy(() -> SqsUtils.enrichedMessageFromS3(sqsEvent, sqsMessages -> sqsMessages.get(0).getBody()))
- .withCause(exception);
-
- verify(s3Client, never()).deleteObject(any(DeleteObjectRequest.class));
- }
-
- @Test
- public void shouldFailEntireBatchIfFailedProcessingDownloadMessageFromS3() {
- ResponseInputStream s3Response =
- new ResponseInputStream<>(GetObjectResponse.builder().build(),
- AbortableInputStream.create(new StringInputStream("test") {
- @Override
- public void close() throws IOException {
- throw new IOException("Failed");
- }
- }));
-
- when(s3Client.getObject(any(GetObjectRequest.class))).thenReturn(s3Response);
-
- String messageBody =
- "[\"software.amazon.payloadoffloading.PayloadS3Pointer\",{\"s3BucketName\":\"" + BUCKET_NAME +
- "\",\"s3Key\":\"" + BUCKET_KEY + "\"}]";
- SQSEvent sqsEvent = messageWithBody(messageBody);
-
- assertThatExceptionOfType(SqsLargeMessageAspect.FailedProcessingLargePayloadException.class)
- .isThrownBy(() -> SqsUtils.enrichedMessageFromS3(sqsEvent, sqsMessages -> sqsMessages.get(0).getBody()))
- .withCauseInstanceOf(IOException.class);
-
- verify(s3Client, never()).deleteObject(any(DeleteObjectRequest.class));
- }
-
- private SQSEvent messageWithBody(String messageBody) {
- SQSMessage sqsMessage = new SQSMessage();
- sqsMessage.setBody(messageBody);
- SQSEvent sqsEvent = new SQSEvent();
- sqsEvent.setRecords(singletonList(sqsMessage));
- return sqsEvent;
- }
-}
\ No newline at end of file
diff --git a/powertools-sqs/src/test/java/software/amazon/lambda/powertools/sqs/handlers/LambdaHandlerApiGateway.java b/powertools-sqs/src/test/java/software/amazon/lambda/powertools/sqs/handlers/LambdaHandlerApiGateway.java
deleted file mode 100644
index 3bad9644f..000000000
--- a/powertools-sqs/src/test/java/software/amazon/lambda/powertools/sqs/handlers/LambdaHandlerApiGateway.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright 2023 Amazon.com, Inc. or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package software.amazon.lambda.powertools.sqs.handlers;
-
-import com.amazonaws.services.lambda.runtime.Context;
-import com.amazonaws.services.lambda.runtime.RequestHandler;
-import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
-import software.amazon.lambda.powertools.sqs.SampleSqsHandler;
-import software.amazon.lambda.powertools.sqs.SqsBatch;
-import software.amazon.lambda.powertools.sqs.SqsLargeMessage;
-
-public class LambdaHandlerApiGateway implements RequestHandler {
-
- @Override
- @SqsLargeMessage
- @SqsBatch(value = SampleSqsHandler.class)
- public String handleRequest(APIGatewayProxyRequestEvent sqsEvent, Context context) {
- return sqsEvent.getBody();
- }
-}
diff --git a/powertools-sqs/src/test/java/software/amazon/lambda/powertools/sqs/handlers/PartialBatchFailureSuppressedHandler.java b/powertools-sqs/src/test/java/software/amazon/lambda/powertools/sqs/handlers/PartialBatchFailureSuppressedHandler.java
deleted file mode 100644
index 172179057..000000000
--- a/powertools-sqs/src/test/java/software/amazon/lambda/powertools/sqs/handlers/PartialBatchFailureSuppressedHandler.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2023 Amazon.com, Inc. or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package software.amazon.lambda.powertools.sqs.handlers;
-
-import static com.amazonaws.services.lambda.runtime.events.SQSEvent.SQSMessage;
-import static software.amazon.lambda.powertools.sqs.internal.SqsMessageBatchProcessorAspectTest.interactionClient;
-
-import com.amazonaws.services.lambda.runtime.Context;
-import com.amazonaws.services.lambda.runtime.RequestHandler;
-import com.amazonaws.services.lambda.runtime.events.SQSEvent;
-import software.amazon.lambda.powertools.sqs.SqsBatch;
-import software.amazon.lambda.powertools.sqs.SqsMessageHandler;
-
-public class PartialBatchFailureSuppressedHandler implements RequestHandler {
- @Override
- @SqsBatch(value = InnerMessageHandler.class, suppressException = true)
- public String handleRequest(final SQSEvent sqsEvent,
- final Context context) {
- return "Success";
- }
-
- private class InnerMessageHandler implements SqsMessageHandler {
-
- @Override
- public String process(SQSMessage message) {
- if ("2e1424d4-f796-459a-8184-9c92662be6da".equals(message.getMessageId())) {
- throw new RuntimeException("2e1424d4-f796-459a-8184-9c92662be6da");
- }
-
- interactionClient.listQueues();
- return "Success";
- }
- }
-}
diff --git a/powertools-sqs/src/test/java/software/amazon/lambda/powertools/sqs/handlers/PartialBatchPartialFailureHandler.java b/powertools-sqs/src/test/java/software/amazon/lambda/powertools/sqs/handlers/PartialBatchPartialFailureHandler.java
deleted file mode 100644
index 6e3971269..000000000
--- a/powertools-sqs/src/test/java/software/amazon/lambda/powertools/sqs/handlers/PartialBatchPartialFailureHandler.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2023 Amazon.com, Inc. or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package software.amazon.lambda.powertools.sqs.handlers;
-
-import static com.amazonaws.services.lambda.runtime.events.SQSEvent.SQSMessage;
-import static software.amazon.lambda.powertools.sqs.internal.SqsMessageBatchProcessorAspectTest.interactionClient;
-
-import com.amazonaws.services.lambda.runtime.Context;
-import com.amazonaws.services.lambda.runtime.RequestHandler;
-import com.amazonaws.services.lambda.runtime.events.SQSEvent;
-import software.amazon.lambda.powertools.sqs.SqsBatch;
-import software.amazon.lambda.powertools.sqs.SqsMessageHandler;
-
-public class PartialBatchPartialFailureHandler implements RequestHandler {
- @Override
- @SqsBatch(InnerMessageHandler.class)
- public String handleRequest(final SQSEvent sqsEvent,
- final Context context) {
- return "Success";
- }
-
- private class InnerMessageHandler implements SqsMessageHandler {
-
- @Override
- public String process(SQSMessage message) {
- if ("2e1424d4-f796-459a-8184-9c92662be6da".equals(message.getMessageId())) {
- throw new RuntimeException("2e1424d4-f796-459a-8184-9c92662be6da");
- }
-
- interactionClient.listQueues();
- return "Success";
- }
- }
-}
diff --git a/powertools-sqs/src/test/java/software/amazon/lambda/powertools/sqs/handlers/PartialBatchSuccessHandler.java b/powertools-sqs/src/test/java/software/amazon/lambda/powertools/sqs/handlers/PartialBatchSuccessHandler.java
deleted file mode 100644
index acfcd7109..000000000
--- a/powertools-sqs/src/test/java/software/amazon/lambda/powertools/sqs/handlers/PartialBatchSuccessHandler.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 2023 Amazon.com, Inc. or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package software.amazon.lambda.powertools.sqs.handlers;
-
-import static com.amazonaws.services.lambda.runtime.events.SQSEvent.SQSMessage;
-import static software.amazon.lambda.powertools.sqs.internal.SqsMessageBatchProcessorAspectTest.interactionClient;
-
-import com.amazonaws.services.lambda.runtime.Context;
-import com.amazonaws.services.lambda.runtime.RequestHandler;
-import com.amazonaws.services.lambda.runtime.events.SQSEvent;
-import software.amazon.lambda.powertools.sqs.SqsBatch;
-import software.amazon.lambda.powertools.sqs.SqsMessageHandler;
-
-public class PartialBatchSuccessHandler implements RequestHandler {
- @Override
- @SqsBatch(InnerMessageHandler.class)
- public String handleRequest(final SQSEvent sqsEvent,
- final Context context) {
- return "Success";
- }
-
- private class InnerMessageHandler implements SqsMessageHandler {
-
- @Override
- public String process(SQSMessage message) {
- interactionClient.listQueues();
- return "Success";
- }
- }
-}
diff --git a/powertools-sqs/src/test/java/software/amazon/lambda/powertools/sqs/handlers/SqsMessageHandler.java b/powertools-sqs/src/test/java/software/amazon/lambda/powertools/sqs/handlers/SqsMessageHandler.java
deleted file mode 100644
index de096679f..000000000
--- a/powertools-sqs/src/test/java/software/amazon/lambda/powertools/sqs/handlers/SqsMessageHandler.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright 2023 Amazon.com, Inc. or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package software.amazon.lambda.powertools.sqs.handlers;
-
-import com.amazonaws.services.lambda.runtime.Context;
-import com.amazonaws.services.lambda.runtime.RequestHandler;
-import com.amazonaws.services.lambda.runtime.events.SQSEvent;
-import software.amazon.lambda.powertools.sqs.SqsLargeMessage;
-
-public class SqsMessageHandler implements RequestHandler {
-
- @Override
- @SqsLargeMessage
- public String handleRequest(SQSEvent sqsEvent, Context context) {
- return sqsEvent.getRecords().get(0).getBody();
- }
-}
diff --git a/powertools-sqs/src/test/java/software/amazon/lambda/powertools/sqs/handlers/SqsMessageHandlerWithNonRetryableHandler.java b/powertools-sqs/src/test/java/software/amazon/lambda/powertools/sqs/handlers/SqsMessageHandlerWithNonRetryableHandler.java
deleted file mode 100644
index 74ff02e2c..000000000
--- a/powertools-sqs/src/test/java/software/amazon/lambda/powertools/sqs/handlers/SqsMessageHandlerWithNonRetryableHandler.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright 2023 Amazon.com, Inc. or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package software.amazon.lambda.powertools.sqs.handlers;
-
-import static com.amazonaws.services.lambda.runtime.events.SQSEvent.SQSMessage;
-import static software.amazon.lambda.powertools.sqs.internal.SqsMessageBatchProcessorAspectTest.interactionClient;
-
-import com.amazonaws.services.lambda.runtime.Context;
-import com.amazonaws.services.lambda.runtime.RequestHandler;
-import com.amazonaws.services.lambda.runtime.events.SQSEvent;
-import software.amazon.lambda.powertools.sqs.SqsBatch;
-import software.amazon.lambda.powertools.sqs.SqsMessageHandler;
-
-public class SqsMessageHandlerWithNonRetryableHandler implements RequestHandler {
-
- @Override
- @SqsBatch(value = InnerMessageHandler.class, nonRetryableExceptions = {IllegalStateException.class,
- IllegalArgumentException.class})
- public String handleRequest(final SQSEvent sqsEvent,
- final Context context) {
- return "Success";
- }
-
- private class InnerMessageHandler implements SqsMessageHandler {
-
- @Override
- public String process(SQSMessage message) {
- if (message.getMessageId().isEmpty()) {
- throw new IllegalArgumentException("Invalid message and was moved to DLQ");
- }
-
- if ("2e1424d4-f796-459a-9696-9c92662ba5da".equals(message.getMessageId())) {
- throw new RuntimeException("Invalid message and should be reprocessed");
- }
-
- interactionClient.listQueues();
- return "Success";
- }
- }
-}
diff --git a/powertools-sqs/src/test/java/software/amazon/lambda/powertools/sqs/handlers/SqsMessageHandlerWithNonRetryableHandlerWithDelete.java b/powertools-sqs/src/test/java/software/amazon/lambda/powertools/sqs/handlers/SqsMessageHandlerWithNonRetryableHandlerWithDelete.java
deleted file mode 100644
index 5b341880e..000000000
--- a/powertools-sqs/src/test/java/software/amazon/lambda/powertools/sqs/handlers/SqsMessageHandlerWithNonRetryableHandlerWithDelete.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright 2023 Amazon.com, Inc. or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package software.amazon.lambda.powertools.sqs.handlers;
-
-import static com.amazonaws.services.lambda.runtime.events.SQSEvent.SQSMessage;
-import static software.amazon.lambda.powertools.sqs.internal.SqsMessageBatchProcessorAspectTest.interactionClient;
-
-import com.amazonaws.services.lambda.runtime.Context;
-import com.amazonaws.services.lambda.runtime.RequestHandler;
-import com.amazonaws.services.lambda.runtime.events.SQSEvent;
-import software.amazon.lambda.powertools.sqs.SqsBatch;
-import software.amazon.lambda.powertools.sqs.SqsMessageHandler;
-
-public class SqsMessageHandlerWithNonRetryableHandlerWithDelete implements RequestHandler {
-
- @Override
- @SqsBatch(value = InnerMessageHandler.class,
- nonRetryableExceptions = {IllegalStateException.class, IllegalArgumentException.class},
- deleteNonRetryableMessageFromQueue = true)
- public String handleRequest(final SQSEvent sqsEvent,
- final Context context) {
- return "Success";
- }
-
- private class InnerMessageHandler implements SqsMessageHandler {
-
- @Override
- public String process(SQSMessage message) {
- if (message.getMessageId().isEmpty()) {
- throw new IllegalArgumentException("Invalid message and was moved to DLQ");
- }
-
- if ("2e1424d4-f796-459a-9696-9c92662ba5da".equals(message.getMessageId())) {
- throw new RuntimeException("Invalid message and should be reprocessed");
- }
-
- interactionClient.listQueues();
- return "Success";
- }
- }
-}
diff --git a/powertools-sqs/src/test/java/software/amazon/lambda/powertools/sqs/handlers/SqsNoDeleteMessageHandler.java b/powertools-sqs/src/test/java/software/amazon/lambda/powertools/sqs/handlers/SqsNoDeleteMessageHandler.java
deleted file mode 100644
index e96dc5581..000000000
--- a/powertools-sqs/src/test/java/software/amazon/lambda/powertools/sqs/handlers/SqsNoDeleteMessageHandler.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright 2023 Amazon.com, Inc. or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package software.amazon.lambda.powertools.sqs.handlers;
-
-import com.amazonaws.services.lambda.runtime.Context;
-import com.amazonaws.services.lambda.runtime.RequestHandler;
-import com.amazonaws.services.lambda.runtime.events.SQSEvent;
-import software.amazon.lambda.powertools.sqs.SqsLargeMessage;
-
-public class SqsNoDeleteMessageHandler implements RequestHandler {
-
- @Override
- @SqsLargeMessage(deletePayloads = false)
- public String handleRequest(SQSEvent sqsEvent, Context context) {
- return sqsEvent.getRecords().get(0).getBody();
- }
-}
\ No newline at end of file
diff --git a/powertools-sqs/src/test/java/software/amazon/lambda/powertools/sqs/internal/SqsLargeMessageAspectTest.java b/powertools-sqs/src/test/java/software/amazon/lambda/powertools/sqs/internal/SqsLargeMessageAspectTest.java
deleted file mode 100644
index 535da11c7..000000000
--- a/powertools-sqs/src/test/java/software/amazon/lambda/powertools/sqs/internal/SqsLargeMessageAspectTest.java
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * Copyright 2023 Amazon.com, Inc. or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package software.amazon.lambda.powertools.sqs.internal;
-
-import static com.amazonaws.services.lambda.runtime.events.SQSEvent.SQSMessage;
-import static java.util.Collections.singletonList;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoInteractions;
-import static org.mockito.Mockito.when;
-import static org.mockito.MockitoAnnotations.openMocks;
-import static software.amazon.lambda.powertools.sqs.internal.SqsLargeMessageAspect.FailedProcessingLargePayloadException;
-
-import com.amazonaws.services.lambda.runtime.Context;
-import com.amazonaws.services.lambda.runtime.RequestHandler;
-import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
-import com.amazonaws.services.lambda.runtime.events.SQSEvent;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.util.function.Consumer;
-import java.util.stream.Stream;
-import org.assertj.core.api.Assertions;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.Arguments;
-import org.junit.jupiter.params.provider.MethodSource;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import software.amazon.awssdk.core.ResponseInputStream;
-import software.amazon.awssdk.core.exception.SdkClientException;
-import software.amazon.awssdk.http.AbortableInputStream;
-import software.amazon.awssdk.services.s3.S3Client;
-import software.amazon.awssdk.services.s3.model.DeleteObjectRequest;
-import software.amazon.awssdk.services.s3.model.GetObjectRequest;
-import software.amazon.awssdk.services.s3.model.GetObjectResponse;
-import software.amazon.awssdk.services.s3.model.S3Exception;
-import software.amazon.awssdk.utils.StringInputStream;
-import software.amazon.lambda.powertools.sqs.SqsUtils;
-import software.amazon.lambda.powertools.sqs.handlers.LambdaHandlerApiGateway;
-import software.amazon.lambda.powertools.sqs.handlers.SqsMessageHandler;
-import software.amazon.lambda.powertools.sqs.handlers.SqsNoDeleteMessageHandler;
-
-public class SqsLargeMessageAspectTest {
-
- private static final String BUCKET_NAME = "bucketname";
- private static final String BUCKET_KEY = "c71eb2ae-37e0-4265-8909-32f4153faddf";
- private RequestHandler requestHandler;
- @Mock
- private Context context;
- @Mock
- private S3Client s3Client;
-
- private static Stream exception() {
- return Stream.of(Arguments.of(S3Exception.builder()
- .message("Service Exception")
- .build()),
- Arguments.of(SdkClientException.builder()
- .message("Client Exception")
- .build()));
- }
-
- @BeforeEach
- void setUp() {
- openMocks(this);
- setupContext();
- SqsUtils.overrideS3Client(s3Client);
- requestHandler = new SqsMessageHandler();
- }
-
- @Test
- public void testLargeMessage() {
- when(s3Client.getObject(any(GetObjectRequest.class))).thenReturn(s3ObjectWithLargeMessage());
- SQSEvent sqsEvent = messageWithBody(
- "[\"software.amazon.payloadoffloading.PayloadS3Pointer\",{\"s3BucketName\":\"" + BUCKET_NAME +
- "\",\"s3Key\":\"" + BUCKET_KEY + "\"}]");
-
- String response = requestHandler.handleRequest(sqsEvent, context);
-
- assertThat(response)
- .isEqualTo("A big message");
-
- ArgumentCaptor delete = ArgumentCaptor.forClass(DeleteObjectRequest.class);
-
- verify(s3Client).deleteObject(delete.capture());
-
- Assertions.assertThat(delete.getValue())
- .satisfies((Consumer) deleteObjectRequest ->
- {
- assertThat(deleteObjectRequest.bucket())
- .isEqualTo(BUCKET_NAME);
-
- assertThat(deleteObjectRequest.key())
- .isEqualTo(BUCKET_KEY);
- });
- }
-
- @Test
- public void shouldNotProcessSmallMessageBody() {
- when(s3Client.getObject(any(GetObjectRequest.class))).thenReturn(s3ObjectWithLargeMessage());
-
- SQSEvent sqsEvent = messageWithBody("This is small message");
-
- String response = requestHandler.handleRequest(sqsEvent, context);
-
- assertThat(response)
- .isEqualTo("This is small message");
-
- verifyNoInteractions(s3Client);
- }
-
- @ParameterizedTest
- @MethodSource("exception")
- public void shouldFailEntireBatchIfFailedDownloadingFromS3(RuntimeException exception) {
- when(s3Client.getObject(any(GetObjectRequest.class))).thenThrow(exception);
-
- String messageBody =
- "[\"software.amazon.payloadoffloading.PayloadS3Pointer\",{\"s3BucketName\":\"" + BUCKET_NAME +
- "\",\"s3Key\":\"" + BUCKET_KEY + "\"}]";
- SQSEvent sqsEvent = messageWithBody(messageBody);
-
- assertThatExceptionOfType(FailedProcessingLargePayloadException.class)
- .isThrownBy(() -> requestHandler.handleRequest(sqsEvent, context))
- .withCause(exception);
-
- verify(s3Client, never()).deleteObject(any(DeleteObjectRequest.class));
- }
-
- @Test
- public void testLargeMessageWithDeletionOff() {
- requestHandler = new SqsNoDeleteMessageHandler();
-
- when(s3Client.getObject(any(GetObjectRequest.class))).thenReturn(s3ObjectWithLargeMessage());
- SQSEvent sqsEvent = messageWithBody(
- "[\"software.amazon.payloadoffloading.PayloadS3Pointer\",{\"s3BucketName\":\"" + BUCKET_NAME +
- "\",\"s3Key\":\"" + BUCKET_KEY + "\"}]");
-
- String response = requestHandler.handleRequest(sqsEvent, context);
-
- assertThat(response).isEqualTo("A big message");
-
- verify(s3Client, never()).deleteObject(any(DeleteObjectRequest.class));
- }
-
- @Test
- public void shouldFailEntireBatchIfFailedProcessingDownloadMessageFromS3() {
- ResponseInputStream s3Response =
- new ResponseInputStream<>(GetObjectResponse.builder().build(),
- AbortableInputStream.create(new StringInputStream("test") {
- @Override
- public void close() throws IOException {
- throw new IOException("Failed");
- }
- }));
-
- when(s3Client.getObject(any(GetObjectRequest.class))).thenReturn(s3Response);
-
- String messageBody =
- "[\"software.amazon.payloadoffloading.PayloadS3Pointer\",{\"s3BucketName\":\"" + BUCKET_NAME +
- "\",\"s3Key\":\"" + BUCKET_KEY + "\"}]";
- SQSEvent sqsEvent = messageWithBody(messageBody);
-
- assertThatExceptionOfType(FailedProcessingLargePayloadException.class)
- .isThrownBy(() -> requestHandler.handleRequest(sqsEvent, context))
- .withCauseInstanceOf(IOException.class);
-
- verify(s3Client, never()).deleteObject(any(DeleteObjectRequest.class));
- }
-
- @Test
- public void shouldNotDoAnyProcessingWhenNotSqsEvent() {
- LambdaHandlerApiGateway handler = new LambdaHandlerApiGateway();
-
- String messageBody =
- "[\"software.amazon.payloadoffloading.PayloadS3Pointer\",{\"s3BucketName\":\"" + BUCKET_NAME +
- "\",\"s3Key\":\"" + BUCKET_KEY + "\"}]";
-
- APIGatewayProxyRequestEvent event = new APIGatewayProxyRequestEvent();
- event.setBody(messageBody);
- String response = handler.handleRequest(event, context);
-
- assertThat(response)
- .isEqualTo(messageBody);
-
- verifyNoInteractions(s3Client);
- }
-
- private ResponseInputStream s3ObjectWithLargeMessage() {
- return new ResponseInputStream<>(GetObjectResponse.builder().build(),
- AbortableInputStream.create(new ByteArrayInputStream("A big message".getBytes())));
- }
-
- private SQSEvent messageWithBody(String messageBody) {
- SQSMessage sqsMessage = new SQSMessage();
- sqsMessage.setBody(messageBody);
- SQSEvent sqsEvent = new SQSEvent();
- sqsEvent.setRecords(singletonList(sqsMessage));
- return sqsEvent;
- }
-
- private void setupContext() {
- when(context.getFunctionName()).thenReturn("testFunction");
- when(context.getInvokedFunctionArn()).thenReturn("testArn");
- when(context.getFunctionVersion()).thenReturn("1");
- when(context.getMemoryLimitInMB()).thenReturn(10);
- }
-}
\ No newline at end of file
diff --git a/powertools-sqs/src/test/java/software/amazon/lambda/powertools/sqs/internal/SqsMessageBatchProcessorAspectTest.java b/powertools-sqs/src/test/java/software/amazon/lambda/powertools/sqs/internal/SqsMessageBatchProcessorAspectTest.java
deleted file mode 100644
index c0211cb83..000000000
--- a/powertools-sqs/src/test/java/software/amazon/lambda/powertools/sqs/internal/SqsMessageBatchProcessorAspectTest.java
+++ /dev/null
@@ -1,331 +0,0 @@
-/*
- * Copyright 2023 Amazon.com, Inc. or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package software.amazon.lambda.powertools.sqs.internal;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoInteractions;
-import static org.mockito.Mockito.when;
-import static software.amazon.lambda.powertools.sqs.SqsUtils.overrideSqsClient;
-
-import com.amazonaws.services.lambda.runtime.Context;
-import com.amazonaws.services.lambda.runtime.RequestHandler;
-import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
-import com.amazonaws.services.lambda.runtime.events.SQSEvent;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import java.io.IOException;
-import java.util.HashMap;
-import org.assertj.core.api.Assertions;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.mockito.ArgumentCaptor;
-import software.amazon.awssdk.services.sqs.SqsClient;
-import software.amazon.awssdk.services.sqs.model.BatchResultErrorEntry;
-import software.amazon.awssdk.services.sqs.model.DeleteMessageBatchRequest;
-import software.amazon.awssdk.services.sqs.model.GetQueueAttributesRequest;
-import software.amazon.awssdk.services.sqs.model.GetQueueAttributesResponse;
-import software.amazon.awssdk.services.sqs.model.QueueAttributeName;
-import software.amazon.awssdk.services.sqs.model.SendMessageBatchRequest;
-import software.amazon.awssdk.services.sqs.model.SendMessageBatchResponse;
-import software.amazon.lambda.powertools.sqs.SQSBatchProcessingException;
-import software.amazon.lambda.powertools.sqs.handlers.LambdaHandlerApiGateway;
-import software.amazon.lambda.powertools.sqs.handlers.PartialBatchFailureSuppressedHandler;
-import software.amazon.lambda.powertools.sqs.handlers.PartialBatchPartialFailureHandler;
-import software.amazon.lambda.powertools.sqs.handlers.PartialBatchSuccessHandler;
-import software.amazon.lambda.powertools.sqs.handlers.SqsMessageHandlerWithNonRetryableHandler;
-import software.amazon.lambda.powertools.sqs.handlers.SqsMessageHandlerWithNonRetryableHandlerWithDelete;
-
-public class SqsMessageBatchProcessorAspectTest {
- public static final SqsClient interactionClient = mock(SqsClient.class);
- private static final SqsClient sqsClient = mock(SqsClient.class);
- private static final ObjectMapper MAPPER = new ObjectMapper();
- private final Context context = mock(Context.class);
- private SQSEvent event;
- private RequestHandler requestHandler;
-
- @BeforeEach
- void setUp() throws IOException {
- overrideSqsClient(sqsClient);
- reset(interactionClient);
- reset(sqsClient);
- setupContext();
- event = MAPPER.readValue(this.getClass().getResource("/sampleSqsBatchEvent.json"), SQSEvent.class);
- requestHandler = new PartialBatchSuccessHandler();
- }
-
- @Test
- void shouldBatchProcessAllMessageSuccessfullyAndNotDeleteFromSQS() {
- requestHandler.handleRequest(event, context);
-
- verify(interactionClient, times(2)).listQueues();
- verify(sqsClient, times(0)).deleteMessageBatch(any(DeleteMessageBatchRequest.class));
- }
-
- @Test
- void shouldBatchProcessMessageWithSuccessDeletedOnFailureInBatchFromSQS() {
- requestHandler = new PartialBatchPartialFailureHandler();
-
- assertThatExceptionOfType(SQSBatchProcessingException.class)
- .isThrownBy(() -> requestHandler.handleRequest(event, context))
- .satisfies(e ->
- {
- assertThat(e.getExceptions())
- .hasSize(1)
- .extracting("message")
- .containsExactly("2e1424d4-f796-459a-8184-9c92662be6da");
-
- assertThat(e.getFailures())
- .hasSize(1)
- .extracting("messageId")
- .containsExactly("2e1424d4-f796-459a-8184-9c92662be6da");
-
- assertThat(e.successMessageReturnValues())
- .hasSize(1)
- .contains("Success");
- });
-
- verify(interactionClient).listQueues();
- verify(sqsClient).deleteMessageBatch(any(DeleteMessageBatchRequest.class));
- }
-
- @Test
- void shouldBatchProcessMessageWithSuccessDeletedOnFailureWithSuppressionInBatchFromSQS() {
- requestHandler = new PartialBatchFailureSuppressedHandler();
-
- requestHandler.handleRequest(event, context);
-
- verify(interactionClient).listQueues();
- verify(sqsClient).deleteMessageBatch(any(DeleteMessageBatchRequest.class));
- }
-
- @Test
- void shouldNotTakeEffectOnNonSqsEventHandler() {
- LambdaHandlerApiGateway handlerApiGateway = new LambdaHandlerApiGateway();
-
- handlerApiGateway.handleRequest(mock(APIGatewayProxyRequestEvent.class), context);
-
- verifyNoInteractions(sqsClient);
- }
-
- @Test
- void shouldBatchProcessAndMoveNonRetryableExceptionToDlq() {
- requestHandler = new SqsMessageHandlerWithNonRetryableHandler();
- event.getRecords().get(0).setMessageId("");
-
- HashMap attributes = new HashMap<>();
-
- attributes.put(QueueAttributeName.REDRIVE_POLICY, "{\n" +
- " \"deadLetterTargetArn\": \"arn:aws:sqs:us-east-2:123456789012:retry-queue\",\n" +
- " \"maxReceiveCount\": 2\n" +
- "}");
-
- when(sqsClient.getQueueAttributes(any(GetQueueAttributesRequest.class))).thenReturn(
- GetQueueAttributesResponse.builder()
- .attributes(attributes)
- .build());
-
- requestHandler.handleRequest(event, context);
-
- verify(interactionClient).listQueues();
- verify(sqsClient).deleteMessageBatch(any(DeleteMessageBatchRequest.class));
- verify(sqsClient).sendMessageBatch(any(SendMessageBatchRequest.class));
- }
-
- @Test
- void shouldBatchProcessAndThrowExceptionForNonRetryableExceptionWhenMoveToDlqReturnFailedResponse() {
- requestHandler = new SqsMessageHandlerWithNonRetryableHandler();
- event.getRecords().get(0).setMessageId("");
-
- when(sqsClient.sendMessageBatch(any(SendMessageBatchRequest.class))).thenReturn(
- SendMessageBatchResponse.builder()
- .failed(BatchResultErrorEntry.builder()
- .message("Permission Error")
- .code("KMS.AccessDeniedException")
- .senderFault(true)
- .build())
- .build());
-
- HashMap attributes = new HashMap<>();
-
- attributes.put(QueueAttributeName.REDRIVE_POLICY, "{\n" +
- " \"deadLetterTargetArn\": \"arn:aws:sqs:us-east-2:123456789012:retry-queue\",\n" +
- " \"maxReceiveCount\": 2\n" +
- "}");
-
- when(sqsClient.getQueueAttributes(any(GetQueueAttributesRequest.class))).thenReturn(
- GetQueueAttributesResponse.builder()
- .attributes(attributes)
- .build());
-
- Assertions.assertThatExceptionOfType(SQSBatchProcessingException.class).
- isThrownBy(() -> requestHandler.handleRequest(event, context));
-
- verify(interactionClient).listQueues();
- verify(sqsClient).sendMessageBatch(any(SendMessageBatchRequest.class));
- verify(sqsClient).deleteMessageBatch(any(DeleteMessageBatchRequest.class));
- }
-
- @Test
- void shouldBatchProcessAndDeleteNonRetryableExceptionMessage() {
- requestHandler = new SqsMessageHandlerWithNonRetryableHandlerWithDelete();
- event.getRecords().get(0).setMessageId("");
-
- requestHandler.handleRequest(event, context);
-
- verify(interactionClient).listQueues();
- ArgumentCaptor captor = ArgumentCaptor.forClass(DeleteMessageBatchRequest.class);
- verify(sqsClient).deleteMessageBatch(captor.capture());
- verify(sqsClient, never()).sendMessageBatch(any(SendMessageBatchRequest.class));
- verify(sqsClient, never()).getQueueAttributes(any(GetQueueAttributesRequest.class));
-
- assertThat(captor.getValue())
- .satisfies(deleteMessageBatchRequest -> assertThat(deleteMessageBatchRequest.entries())
- .hasSize(2)
- .extracting("id")
- .contains("", "2e1424d4-f796-459a-8184-9c92662be6da"));
- }
-
- @Test
- void shouldBatchProcessAndFailWithExceptionForNonRetryableExceptionAndNoDlq() {
- requestHandler = new SqsMessageHandlerWithNonRetryableHandler();
-
- event.getRecords().get(0).setMessageId("");
- event.getRecords()
- .forEach(sqsMessage -> sqsMessage.setEventSourceArn(sqsMessage.getEventSourceArn() + "-temp"));
-
- when(sqsClient.getQueueAttributes(any(GetQueueAttributesRequest.class))).thenReturn(
- GetQueueAttributesResponse.builder()
- .build());
-
- assertThatExceptionOfType(SQSBatchProcessingException.class)
- .isThrownBy(() -> requestHandler.handleRequest(event, context))
- .satisfies(e ->
- {
- assertThat(e.getExceptions())
- .hasSize(1)
- .extracting("message")
- .containsExactly("Invalid message and was moved to DLQ");
-
- assertThat(e.getFailures())
- .hasSize(1)
- .extracting("messageId")
- .containsExactly("");
-
- assertThat(e.successMessageReturnValues())
- .hasSize(1)
- .contains("Success");
- });
-
- verify(interactionClient).listQueues();
- verify(sqsClient).deleteMessageBatch(any(DeleteMessageBatchRequest.class));
- verify(sqsClient, never()).sendMessageBatch(any(SendMessageBatchRequest.class));
- }
-
- @Test
- void shouldBatchProcessAndFailWithExceptionForNonRetryableExceptionWhenFailedParsingPolicy() {
- requestHandler = new SqsMessageHandlerWithNonRetryableHandler();
- event.getRecords().get(0).setMessageId("");
- event.getRecords()
- .forEach(sqsMessage -> sqsMessage.setEventSourceArn(sqsMessage.getEventSourceArn() + "-temp-queue"));
-
- HashMap attributes = new HashMap<>();
-
- attributes.put(QueueAttributeName.REDRIVE_POLICY, "MalFormedRedrivePolicy");
-
- when(sqsClient.getQueueAttributes(any(GetQueueAttributesRequest.class))).thenReturn(
- GetQueueAttributesResponse.builder()
- .attributes(attributes)
- .build());
-
- assertThatExceptionOfType(SQSBatchProcessingException.class)
- .isThrownBy(() -> requestHandler.handleRequest(event, context))
- .satisfies(e ->
- {
- assertThat(e.getExceptions())
- .hasSize(1)
- .extracting("message")
- .containsExactly("Invalid message and was moved to DLQ");
-
- assertThat(e.getFailures())
- .hasSize(1)
- .extracting("messageId")
- .containsExactly("");
-
- assertThat(e.successMessageReturnValues())
- .hasSize(1)
- .contains("Success");
- });
-
- verify(interactionClient).listQueues();
- verify(sqsClient).deleteMessageBatch(any(DeleteMessageBatchRequest.class));
- verify(sqsClient, never()).sendMessageBatch(any(SendMessageBatchRequest.class));
- }
-
- @Test
- void shouldBatchProcessAndMoveNonRetryableExceptionToDlqAndThrowException() throws IOException {
- requestHandler = new SqsMessageHandlerWithNonRetryableHandler();
- event = MAPPER.readValue(this.getClass().getResource("/threeMessageSqsBatchEvent.json"), SQSEvent.class);
-
- event.getRecords().get(1).setMessageId("");
-
- HashMap attributes = new HashMap<>();
-
- attributes.put(QueueAttributeName.REDRIVE_POLICY, "{\n" +
- " \"deadLetterTargetArn\": \"arn:aws:sqs:us-east-2:123456789012:retry-queue\",\n" +
- " \"maxReceiveCount\": 2\n" +
- "}");
-
- when(sqsClient.getQueueAttributes(any(GetQueueAttributesRequest.class))).thenReturn(
- GetQueueAttributesResponse.builder()
- .attributes(attributes)
- .build());
-
- assertThatExceptionOfType(SQSBatchProcessingException.class)
- .isThrownBy(() -> requestHandler.handleRequest(event, context))
- .satisfies(e ->
- {
- assertThat(e.getExceptions())
- .hasSize(1)
- .extracting("message")
- .containsExactly("Invalid message and should be reprocessed");
-
- assertThat(e.getFailures())
- .hasSize(1)
- .extracting("messageId")
- .containsExactly("2e1424d4-f796-459a-9696-9c92662ba5da");
-
- assertThat(e.successMessageReturnValues())
- .hasSize(1)
- .contains("Success");
- });
-
- verify(interactionClient).listQueues();
- verify(sqsClient).deleteMessageBatch(any(DeleteMessageBatchRequest.class));
- verify(sqsClient).sendMessageBatch(any(SendMessageBatchRequest.class));
- }
-
- private void setupContext() {
- when(context.getFunctionName()).thenReturn("testFunction");
- when(context.getInvokedFunctionArn()).thenReturn("testArn");
- when(context.getFunctionVersion()).thenReturn("1");
- when(context.getMemoryLimitInMB()).thenReturn(10);
- }
-}
\ No newline at end of file
diff --git a/powertools-sqs/src/test/resources/SqsFifoBatchEvent.json b/powertools-sqs/src/test/resources/SqsFifoBatchEvent.json
deleted file mode 100644
index 726e45ea1..000000000
--- a/powertools-sqs/src/test/resources/SqsFifoBatchEvent.json
+++ /dev/null
@@ -1,73 +0,0 @@
-{
- "Records": [
- {
- "messageId": "059f36b4-87a3-44ab-83d2-661975830a7d",
- "receiptHandle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...",
- "body": "Test message.",
- "attributes": {
- "ApproximateReceiveCount": "1",
- "SentTimestamp": "1545082649183",
- "SenderId": "AIDAIENQZJOLO23YVJ4VO",
- "ApproximateFirstReceiveTimestamp": "1545082649185",
- "MessageGroupId": "Group1"
- },
- "messageAttributes": {},
- "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3",
- "eventSource": "aws:sqs",
- "eventSourceARN": "arn:aws:sqs:us-east-1:906126917321:sqs-lambda-MySqsQueue-4DYWWJIE97N5",
- "awsRegion": "us-east-2"
- },
- {
- "messageId": "2e1424d4-f796-459a-8184-9c92662be6da",
- "receiptHandle": "AQEBzWwaftRI0KuVm4tP+/7q1rGgNqicHq...",
- "body": "Test message.",
- "attributes": {
- "ApproximateReceiveCount": "1",
- "SentTimestamp": "1545082650636",
- "SenderId": "AIDAIENQZJOLO23YVJ4VO",
- "ApproximateFirstReceiveTimestamp": "1545082650649",
- "MessageGroupId": "Group2"
- },
- "messageAttributes": {
- "Attribute3" : {
- "binaryValue" : "MTEwMA==",
- "dataType" : "Binary"
- },
- "Attribute2" : {
- "stringValue" : "123",
- "dataType" : "Number"
- },
- "Attribute1" : {
- "stringValue" : "AttributeValue1",
- "dataType" : "String"
- }
- },
- "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3",
- "eventSource": "aws:sqs",
- "eventSourceARN": "arn:aws:sqs:us-east-1:906126917321:sqs-lambda-MySqsQueue-4DYWWJIE97N5",
- "awsRegion": "us-east-2"
- },
- {
- "messageId": "2e1424d4-f796-459a-9696-9c92662ba5da",
- "receiptHandle": "AQEBzWwaftRI0KuVm4tP+/7q1rGgNqicHq...",
- "body": "Test message.",
- "attributes": {
- "ApproximateReceiveCount": "1",
- "SentTimestamp": "1545082650636",
- "SenderId": "AIDAIENQZJOLO23YVJ4VO",
- "ApproximateFirstReceiveTimestamp": "1545082650649",
- "MessageGroupId": "Group1"
- },
- "messageAttributes": {
- "Attribute2" : {
- "stringValue" : "123",
- "dataType" : "Number"
- }
- },
- "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3",
- "eventSource": "aws:sqs",
- "eventSourceARN": "arn:aws:sqs:us-east-1:906126917321:sqs-lambda-MySqsQueue-4DYWWJIE97N5",
- "awsRegion": "us-east-2"
- }
- ]
-}
\ No newline at end of file
diff --git a/powertools-sqs/src/test/resources/sampleSqsBatchEvent.json b/powertools-sqs/src/test/resources/sampleSqsBatchEvent.json
deleted file mode 100644
index 8a5fbf309..000000000
--- a/powertools-sqs/src/test/resources/sampleSqsBatchEvent.json
+++ /dev/null
@@ -1,36 +0,0 @@
-{
- "records": [
- {
- "messageId": "059f36b4-87a3-44ab-83d2-661975830a7d",
- "receiptHandle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...",
- "body": "Test message.",
- "attributes": {
- "ApproximateReceiveCount": "1",
- "SentTimestamp": "1545082649183",
- "SenderId": "AIDAIENQZJOLO23YVJ4VO",
- "ApproximateFirstReceiveTimestamp": "1545082649185"
- },
- "messageAttributes": {},
- "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3",
- "eventSource": "aws:sqs",
- "eventSourceArn": "arn:aws:sqs:us-east-2:123456789012:my-queue",
- "awsRegion": "us-east-2"
- },
- {
- "messageId": "2e1424d4-f796-459a-8184-9c92662be6da",
- "receiptHandle": "AQEBzWwaftRI0KuVm4tP+/7q1rGgNqicHq...",
- "body": "Test message.",
- "attributes": {
- "ApproximateReceiveCount": "1",
- "SentTimestamp": "1545082650636",
- "SenderId": "AIDAIENQZJOLO23YVJ4VO",
- "ApproximateFirstReceiveTimestamp": "1545082650649"
- },
- "messageAttributes": {},
- "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3",
- "eventSource": "aws:sqs",
- "eventSourceArn": "arn:aws:sqs:us-east-2:123456789012:my-queue",
- "awsRegion": "us-east-2"
- }
- ]
-}
\ No newline at end of file
diff --git a/powertools-sqs/src/test/resources/sampleSqsBatchEventBatchSize25.json b/powertools-sqs/src/test/resources/sampleSqsBatchEventBatchSize25.json
deleted file mode 100644
index 31b8862ad..000000000
--- a/powertools-sqs/src/test/resources/sampleSqsBatchEventBatchSize25.json
+++ /dev/null
@@ -1,404 +0,0 @@
-{
- "records": [
- {
- "messageId": "059f36b4-87a3-44ab-83d2-661975830a7d",
- "receiptHandle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...",
- "body": "Test message.",
- "attributes": {
- "ApproximateReceiveCount": "1",
- "SentTimestamp": "1545082649183",
- "SenderId": "AIDAIENQZJOLO23YVJ4VO",
- "ApproximateFirstReceiveTimestamp": "1545082649185"
- },
- "messageAttributes": {},
- "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3",
- "eventSource": "aws:sqs",
- "eventSourceArn": "arn:aws:sqs:us-east-2:123456789012:my-queue",
- "awsRegion": "us-east-2"
- },
- {
- "messageId": "2e1424d4-f796-459a-8184-9c92662be6da",
- "receiptHandle": "AQEBzWwaftRI0KuVm4tP+/7q1rGgNqicHq...",
- "body": "Test message.",
- "attributes": {
- "ApproximateReceiveCount": "1",
- "SentTimestamp": "1545082650636",
- "SenderId": "AIDAIENQZJOLO23YVJ4VO",
- "ApproximateFirstReceiveTimestamp": "1545082650649"
- },
- "messageAttributes": {},
- "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3",
- "eventSource": "aws:sqs",
- "eventSourceArn": "arn:aws:sqs:us-east-2:123456789012:my-queue",
- "awsRegion": "us-east-2"
- },
- {
- "messageId": "2e1424d4-f796-459a-8184-9c92662be6d3",
- "receiptHandle": "AQEBzWwaftRI0KuVm4tP+/7q1rGgNqicHq...",
- "body": "Test message.",
- "attributes": {
- "ApproximateReceiveCount": "1",
- "SentTimestamp": "1545082650636",
- "SenderId": "AIDAIENQZJOLO23YVJ4VO",
- "ApproximateFirstReceiveTimestamp": "1545082650649"
- },
- "messageAttributes": {},
- "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3",
- "eventSource": "aws:sqs",
- "eventSourceArn": "arn:aws:sqs:us-east-2:123456789012:my-queue",
- "awsRegion": "us-east-2"
- },
- {
- "messageId": "2e1424d4-f796-459a-8184-9c92662be6d4",
- "receiptHandle": "AQEBzWwaftRI0KuVm4tP+/7q1rGgNqicHq...",
- "body": "Test message.",
- "attributes": {
- "ApproximateReceiveCount": "1",
- "SentTimestamp": "1545082650636",
- "SenderId": "AIDAIENQZJOLO23YVJ4VO",
- "ApproximateFirstReceiveTimestamp": "1545082650649"
- },
- "messageAttributes": {},
- "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b5",
- "eventSource": "aws:sqs",
- "eventSourceArn": "arn:aws:sqs:us-east-2:123456789012:my-queue",
- "awsRegion": "us-east-2"
- },
- {
- "messageId": "2e1424d4-f796-459a-8184-9c92662be6d6",
- "receiptHandle": "AQEBzWwaftRI0KuVm4tP+/7q1rGgNqicHq...",
- "body": "Test message.",
- "attributes": {
- "ApproximateReceiveCount": "1",
- "SentTimestamp": "1545082650636",
- "SenderId": "AIDAIENQZJOLO23YVJ4VO",
- "ApproximateFirstReceiveTimestamp": "1545082650649"
- },
- "messageAttributes": {},
- "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b7",
- "eventSource": "aws:sqs",
- "eventSourceArn": "arn:aws:sqs:us-east-2:123456789012:my-queue",
- "awsRegion": "us-east-2"
- },
- {
- "messageId": "2e1424d4-f796-459a-8184-9c92662be6d8",
- "receiptHandle": "AQEBzWwaftRI0KuVm4tP+/7q1rGgNqicHq...",
- "body": "Test message.",
- "attributes": {
- "ApproximateReceiveCount": "1",
- "SentTimestamp": "1545082650636",
- "SenderId": "AIDAIENQZJOLO23YVJ4VO",
- "ApproximateFirstReceiveTimestamp": "1545082650649"
- },
- "messageAttributes": {},
- "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3",
- "eventSource": "aws:sqs",
- "eventSourceArn": "arn:aws:sqs:us-east-2:123456789012:my-queue",
- "awsRegion": "us-east-2"
- },
- {
- "messageId": "2e1424d4-f796-459a-8184-9c92662be6d9",
- "receiptHandle": "AQEBzWwaftRI0KuVm4tP+/7q1rGgNqicHq...",
- "body": "Test message.",
- "attributes": {
- "ApproximateReceiveCount": "1",
- "SentTimestamp": "1545082650636",
- "SenderId": "AIDAIENQZJOLO23YVJ4VO",
- "ApproximateFirstReceiveTimestamp": "1545082650649"
- },
- "messageAttributes": {},
- "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3",
- "eventSource": "aws:sqs",
- "eventSourceArn": "arn:aws:sqs:us-east-2:123456789012:my-queue",
- "awsRegion": "us-east-2"
- },
- {
- "messageId": "2e1424d4-f796-459a-8184-9c92662be6d10",
- "receiptHandle": "AQEBzWwaftRI0KuVm4tP+/7q1rGgNqicHq...",
- "body": "Test message.",
- "attributes": {
- "ApproximateReceiveCount": "1",
- "SentTimestamp": "1545082650636",
- "SenderId": "AIDAIENQZJOLO23YVJ4VO",
- "ApproximateFirstReceiveTimestamp": "1545082650649"
- },
- "messageAttributes": {},
- "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3",
- "eventSource": "aws:sqs",
- "eventSourceArn": "arn:aws:sqs:us-east-2:123456789012:my-queue",
- "awsRegion": "us-east-2"
- },
- {
- "messageId": "2e1424d4-f796-459a-8184-9c92662be6d11",
- "receiptHandle": "AQEBzWwaftRI0KuVm4tP+/7q1rGgNqicHq...",
- "body": "Test message.",
- "attributes": {
- "ApproximateReceiveCount": "1",
- "SentTimestamp": "1545082650636",
- "SenderId": "AIDAIENQZJOLO23YVJ4VO",
- "ApproximateFirstReceiveTimestamp": "1545082650649"
- },
- "messageAttributes": {},
- "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3",
- "eventSource": "aws:sqs",
- "eventSourceArn": "arn:aws:sqs:us-east-2:123456789012:my-queue",
- "awsRegion": "us-east-2"
- },
- {
- "messageId": "2e1424d4-f796-459a-8184-9c92662be6d12",
- "receiptHandle": "AQEBzWwaftRI0KuVm4tP+/7q1rGgNqicHq...",
- "body": "Test message.",
- "attributes": {
- "ApproximateReceiveCount": "1",
- "SentTimestamp": "1545082650636",
- "SenderId": "AIDAIENQZJOLO23YVJ4VO",
- "ApproximateFirstReceiveTimestamp": "1545082650649"
- },
- "messageAttributes": {},
- "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3",
- "eventSource": "aws:sqs",
- "eventSourceArn": "arn:aws:sqs:us-east-2:123456789012:my-queue",
- "awsRegion": "us-east-2"
- },
- {
- "messageId": "2e1424d4-f796-459a-8184-9c92662be6d13",
- "receiptHandle": "AQEBzWwaftRI0KuVm4tP+/7q1rGgNqicHq...",
- "body": "Test message.",
- "attributes": {
- "ApproximateReceiveCount": "1",
- "SentTimestamp": "1545082650636",
- "SenderId": "AIDAIENQZJOLO23YVJ4VO",
- "ApproximateFirstReceiveTimestamp": "1545082650649"
- },
- "messageAttributes": {},
- "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3",
- "eventSource": "aws:sqs",
- "eventSourceArn": "arn:aws:sqs:us-east-2:123456789012:my-queue",
- "awsRegion": "us-east-2"
- },
- {
- "messageId": "2e1424d4-f796-459a-8184-9c92662be6d14",
- "receiptHandle": "AQEBzWwaftRI0KuVm4tP+/7q1rGgNqicHq...",
- "body": "Test message.",
- "attributes": {
- "ApproximateReceiveCount": "1",
- "SentTimestamp": "1545082650636",
- "SenderId": "AIDAIENQZJOLO23YVJ4VO",
- "ApproximateFirstReceiveTimestamp": "1545082650649"
- },
- "messageAttributes": {},
- "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3",
- "eventSource": "aws:sqs",
- "eventSourceArn": "arn:aws:sqs:us-east-2:123456789012:my-queue",
- "awsRegion": "us-east-2"
- },
- {
- "messageId": "2e1424d4-f796-459a-8184-9c92662be6d15",
- "receiptHandle": "AQEBzWwaftRI0KuVm4tP+/7q1rGgNqicHq...",
- "body": "Test message.",
- "attributes": {
- "ApproximateReceiveCount": "1",
- "SentTimestamp": "1545082650636",
- "SenderId": "AIDAIENQZJOLO23YVJ4VO",
- "ApproximateFirstReceiveTimestamp": "1545082650649"
- },
- "messageAttributes": {},
- "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3",
- "eventSource": "aws:sqs",
- "eventSourceArn": "arn:aws:sqs:us-east-2:123456789012:my-queue",
- "awsRegion": "us-east-2"
- },
- {
- "messageId": "2e1424d4-f796-459a-8184-9c92662be6d16",
- "receiptHandle": "AQEBzWwaftRI0KuVm4tP+/7q1rGgNqicHq...",
- "body": "Test message.",
- "attributes": {
- "ApproximateReceiveCount": "1",
- "SentTimestamp": "1545082650636",
- "SenderId": "AIDAIENQZJOLO23YVJ4VO",
- "ApproximateFirstReceiveTimestamp": "1545082650649"
- },
- "messageAttributes": {},
- "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3",
- "eventSource": "aws:sqs",
- "eventSourceArn": "arn:aws:sqs:us-east-2:123456789012:my-queue",
- "awsRegion": "us-east-2"
- },
- {
- "messageId": "2e1424d4-f796-459a-8184-9c92662be6d17",
- "receiptHandle": "AQEBzWwaftRI0KuVm4tP+/7q1rGgNqicHq...",
- "body": "Test message.",
- "attributes": {
- "ApproximateReceiveCount": "1",
- "SentTimestamp": "1545082650636",
- "SenderId": "AIDAIENQZJOLO23YVJ4VO",
- "ApproximateFirstReceiveTimestamp": "1545082650649"
- },
- "messageAttributes": {},
- "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3",
- "eventSource": "aws:sqs",
- "eventSourceArn": "arn:aws:sqs:us-east-2:123456789012:my-queue",
- "awsRegion": "us-east-2"
- },
- {
- "messageId": "2e1424d4-f796-459a-8184-9c92662be6d18",
- "receiptHandle": "AQEBzWwaftRI0KuVm4tP+/7q1rGgNqicHq...",
- "body": "Test message.",
- "attributes": {
- "ApproximateReceiveCount": "1",
- "SentTimestamp": "1545082650636",
- "SenderId": "AIDAIENQZJOLO23YVJ4VO",
- "ApproximateFirstReceiveTimestamp": "1545082650649"
- },
- "messageAttributes": {},
- "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3",
- "eventSource": "aws:sqs",
- "eventSourceArn": "arn:aws:sqs:us-east-2:123456789012:my-queue",
- "awsRegion": "us-east-2"
- },
- {
- "messageId": "2e1424d4-f796-459a-8184-9c92662be6d19",
- "receiptHandle": "AQEBzWwaftRI0KuVm4tP+/7q1rGgNqicHq...",
- "body": "Test message.",
- "attributes": {
- "ApproximateReceiveCount": "1",
- "SentTimestamp": "1545082650636",
- "SenderId": "AIDAIENQZJOLO23YVJ4VO",
- "ApproximateFirstReceiveTimestamp": "1545082650649"
- },
- "messageAttributes": {},
- "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3",
- "eventSource": "aws:sqs",
- "eventSourceArn": "arn:aws:sqs:us-east-2:123456789012:my-queue",
- "awsRegion": "us-east-2"
- },
- {
- "messageId": "2e1424d4-f796-459a-8184-9c92662be6d20",
- "receiptHandle": "AQEBzWwaftRI0KuVm4tP+/7q1rGgNqicHq...",
- "body": "Test message.",
- "attributes": {
- "ApproximateReceiveCount": "1",
- "SentTimestamp": "1545082650636",
- "SenderId": "AIDAIENQZJOLO23YVJ4VO",
- "ApproximateFirstReceiveTimestamp": "1545082650649"
- },
- "messageAttributes": {},
- "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3",
- "eventSource": "aws:sqs",
- "eventSourceArn": "arn:aws:sqs:us-east-2:123456789012:my-queue",
- "awsRegion": "us-east-2"
- },
- {
- "messageId": "2e1424d4-f796-459a-8184-9c92662be6d21",
- "receiptHandle": "AQEBzWwaftRI0KuVm4tP+/7q1rGgNqicHq...",
- "body": "Test message.",
- "attributes": {
- "ApproximateReceiveCount": "1",
- "SentTimestamp": "1545082650636",
- "SenderId": "AIDAIENQZJOLO23YVJ4VO",
- "ApproximateFirstReceiveTimestamp": "1545082650649"
- },
- "messageAttributes": {},
- "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3",
- "eventSource": "aws:sqs",
- "eventSourceArn": "arn:aws:sqs:us-east-2:123456789012:my-queue",
- "awsRegion": "us-east-2"
- },
- {
- "messageId": "2e1424d4-f796-459a-8184-9c92662be6d22",
- "receiptHandle": "AQEBzWwaftRI0KuVm4tP+/7q1rGgNqicHq...",
- "body": "Test message.",
- "attributes": {
- "ApproximateReceiveCount": "1",
- "SentTimestamp": "1545082650636",
- "SenderId": "AIDAIENQZJOLO23YVJ4VO",
- "ApproximateFirstReceiveTimestamp": "1545082650649"
- },
- "messageAttributes": {},
- "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3",
- "eventSource": "aws:sqs",
- "eventSourceArn": "arn:aws:sqs:us-east-2:123456789012:my-queue",
- "awsRegion": "us-east-2"
- },
- {
- "messageId": "2e1424d4-f796-459a-8184-9c92662be6d23",
- "receiptHandle": "AQEBzWwaftRI0KuVm4tP+/7q1rGgNqicHq...",
- "body": "Test message.",
- "attributes": {
- "ApproximateReceiveCount": "1",
- "SentTimestamp": "1545082650636",
- "SenderId": "AIDAIENQZJOLO23YVJ4VO",
- "ApproximateFirstReceiveTimestamp": "1545082650649"
- },
- "messageAttributes": {},
- "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3",
- "eventSource": "aws:sqs",
- "eventSourceArn": "arn:aws:sqs:us-east-2:123456789012:my-queue",
- "awsRegion": "us-east-2"
- },
- {
- "messageId": "2e1424d4-f796-459a-8184-9c92662be6d24",
- "receiptHandle": "AQEBzWwaftRI0KuVm4tP+/7q1rGgNqicHq...",
- "body": "Test message.",
- "attributes": {
- "ApproximateReceiveCount": "1",
- "SentTimestamp": "1545082650636",
- "SenderId": "AIDAIENQZJOLO23YVJ4VO",
- "ApproximateFirstReceiveTimestamp": "1545082650649"
- },
- "messageAttributes": {},
- "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3",
- "eventSource": "aws:sqs",
- "eventSourceArn": "arn:aws:sqs:us-east-2:123456789012:my-queue",
- "awsRegion": "us-east-2"
- },
- {
- "messageId": "2e1424d4-f796-459a-8184-9c92662be6d25",
- "receiptHandle": "AQEBzWwaftRI0KuVm4tP+/7q1rGgNqicHq...",
- "body": "Test message.",
- "attributes": {
- "ApproximateReceiveCount": "1",
- "SentTimestamp": "1545082650636",
- "SenderId": "AIDAIENQZJOLO23YVJ4VO",
- "ApproximateFirstReceiveTimestamp": "1545082650649"
- },
- "messageAttributes": {},
- "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3",
- "eventSource": "aws:sqs",
- "eventSourceArn": "arn:aws:sqs:us-east-2:123456789012:my-queue",
- "awsRegion": "us-east-2"
- },
- {
- "messageId": "2e1424d4-f796-459a-8184-9c92662be6d26",
- "receiptHandle": "AQEBzWwaftRI0KuVm4tP+/7q1rGgNqicHq...",
- "body": "Test message.",
- "attributes": {
- "ApproximateReceiveCount": "1",
- "SentTimestamp": "1545082650636",
- "SenderId": "AIDAIENQZJOLO23YVJ4VO",
- "ApproximateFirstReceiveTimestamp": "1545082650649"
- },
- "messageAttributes": {},
- "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3",
- "eventSource": "aws:sqs",
- "eventSourceArn": "arn:aws:sqs:us-east-2:123456789012:my-queue",
- "awsRegion": "us-east-2"
- },
- {
- "messageId": "2e1424d4-f796-459a-8184-9c92662be6d27",
- "receiptHandle": "AQEBzWwaftRI0KuVm4tP+/7q1rGgNqicHq...",
- "body": "Test message.",
- "attributes": {
- "ApproximateReceiveCount": "1",
- "SentTimestamp": "1545082650636",
- "SenderId": "AIDAIENQZJOLO23YVJ4VO",
- "ApproximateFirstReceiveTimestamp": "1545082650649"
- },
- "messageAttributes": {},
- "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3",
- "eventSource": "aws:sqs",
- "eventSourceArn": "arn:aws:sqs:us-east-2:123456789012:my-queue",
- "awsRegion": "us-east-2"
- }
- ]
-}
\ No newline at end of file
diff --git a/powertools-sqs/src/test/resources/threeMessageSqsBatchEvent.json b/powertools-sqs/src/test/resources/threeMessageSqsBatchEvent.json
deleted file mode 100644
index b3b61da3b..000000000
--- a/powertools-sqs/src/test/resources/threeMessageSqsBatchEvent.json
+++ /dev/null
@@ -1,70 +0,0 @@
-{
- "records": [
- {
- "messageId": "059f36b4-87a3-44ab-83d2-661975830a7d",
- "receiptHandle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...",
- "body": "Test message.",
- "attributes": {
- "ApproximateReceiveCount": "1",
- "SentTimestamp": "1545082649183",
- "SenderId": "AIDAIENQZJOLO23YVJ4VO",
- "ApproximateFirstReceiveTimestamp": "1545082649185"
- },
- "messageAttributes": {},
- "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3",
- "eventSource": "aws:sqs",
- "eventSourceArn": "arn:aws:sqs:us-east-1:906126917321:sqs-lambda-MySqsQueue-4DYWWJIE97N5",
- "awsRegion": "us-east-2"
- },
- {
- "messageId": "2e1424d4-f796-459a-8184-9c92662be6da",
- "receiptHandle": "AQEBzWwaftRI0KuVm4tP+/7q1rGgNqicHq...",
- "body": "Test message.",
- "attributes": {
- "ApproximateReceiveCount": "1",
- "SentTimestamp": "1545082650636",
- "SenderId": "AIDAIENQZJOLO23YVJ4VO",
- "ApproximateFirstReceiveTimestamp": "1545082650649"
- },
- "messageAttributes": {
- "Attribute3" : {
- "binaryValue" : "MTEwMA==",
- "dataType" : "Binary"
- },
- "Attribute2" : {
- "stringValue" : "123",
- "dataType" : "Number"
- },
- "Attribute1" : {
- "stringValue" : "AttributeValue1",
- "dataType" : "String"
- }
- },
- "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3",
- "eventSource": "aws:sqs",
- "eventSourceArn": "arn:aws:sqs:us-east-1:906126917321:sqs-lambda-MySqsQueue-4DYWWJIE97N5",
- "awsRegion": "us-east-2"
- },
- {
- "messageId": "2e1424d4-f796-459a-9696-9c92662ba5da",
- "receiptHandle": "AQEBzWwaftRI0KuVm4tP+/7q1rGgNqicHq...",
- "body": "Test message.",
- "attributes": {
- "ApproximateReceiveCount": "1",
- "SentTimestamp": "1545082650636",
- "SenderId": "AIDAIENQZJOLO23YVJ4VO",
- "ApproximateFirstReceiveTimestamp": "1545082650649"
- },
- "messageAttributes": {
- "Attribute2" : {
- "stringValue" : "123",
- "dataType" : "Number"
- }
- },
- "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3",
- "eventSource": "aws:sqs",
- "eventSourceArn": "arn:aws:sqs:us-east-1:906126917321:sqs-lambda-MySqsQueue-4DYWWJIE97N5",
- "awsRegion": "us-east-2"
- }
- ]
-}
\ No newline at end of file
diff --git a/powertools-test-suite/pom.xml b/powertools-test-suite/pom.xml
deleted file mode 100644
index 4a79d2987..000000000
--- a/powertools-test-suite/pom.xml
+++ /dev/null
@@ -1,164 +0,0 @@
-
-
-
-
- 4.0.0
-
- powertools-test-suite
- jar
-
-
- powertools-parent
- software.amazon.lambda
- 1.17.0-SNAPSHOT
-
-
- Powertools for AWS Lambda (Java) library Test Suite
-
- A suite of tests for interactions between the various Powertools for AWS Lambda (Java) modules.
-
- https://aws.amazon.com/lambda/
-
- GitHub Issues
- https://github.com/aws-powertools/powertools-lambda-java/issues
-
-
- https://github.com/aws-powertools/powertools-lambda-java.git
-
-
-
- Powertools for AWS Lambda team
- Amazon Web Services
- https://aws.amazon.com/
-
-
-
-
- true
-
-
-
-
- ossrh
- https://aws.oss.sonatype.org/content/repositories/snapshots
-
-
-
-
-
- software.amazon.lambda
- powertools-core
-
-
- org.apache.logging.log4j
- log4j-jcl
-
-
- com.amazonaws
- aws-lambda-java-core
-
-
- com.amazonaws
- aws-lambda-java-events
-
-
- software.amazon.lambda
- powertools-logging
-
-
- software.amazon.lambda
- powertools-tracing
-
-
- software.amazon.lambda
- powertools-sqs
-
-
-
-
- org.junit.jupiter
- junit-jupiter-api
- test
-
-
- org.junit.jupiter
- junit-jupiter-engine
- test
-
-
- org.apache.commons
- commons-lang3
- test
-
-
- org.mockito
- mockito-core
- test
-
-
- org.aspectj
- aspectjweaver
- test
-
-
- org.assertj
- assertj-core
- test
-
-
- org.skyscreamer
- jsonassert
- test
-
-
-
-
-
-
- dev.aspectj
- aspectj-maven-plugin
- 1.13.1
-
- ${maven.compiler.source}
- ${maven.compiler.target}
- ${maven.compiler.target}
-
-
- software.amazon.lambda
- powertools-logging
-
-
- software.amazon.lambda
- powertools-tracing
-
-
- software.amazon.lambda
- powertools-sqs
-
-
-
-
-
-
- compile
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/powertools-test-suite/src/test/java/software/amazon/lambda/powertools/testsuite/LoggingOrderTest.java b/powertools-test-suite/src/test/java/software/amazon/lambda/powertools/testsuite/LoggingOrderTest.java
deleted file mode 100644
index 9e9c464a6..000000000
--- a/powertools-test-suite/src/test/java/software/amazon/lambda/powertools/testsuite/LoggingOrderTest.java
+++ /dev/null
@@ -1,193 +0,0 @@
-/*
- * Copyright 2023 Amazon.com, Inc. or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package software.amazon.lambda.powertools.testsuite;
-
-
-import static java.util.Collections.emptyMap;
-import static java.util.Collections.singletonList;
-import static org.apache.commons.lang3.reflect.FieldUtils.writeStaticField;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.fail;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.when;
-import static org.mockito.MockitoAnnotations.openMocks;
-
-import com.amazonaws.services.lambda.runtime.Context;
-import com.amazonaws.services.lambda.runtime.events.SQSEvent;
-import com.amazonaws.services.lambda.runtime.events.models.s3.S3EventNotification;
-import com.amazonaws.xray.AWSXRay;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.nio.channels.FileChannel;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.nio.file.StandardOpenOption;
-import java.util.Map;
-import org.apache.logging.log4j.Level;
-import org.apache.logging.log4j.ThreadContext;
-import org.junit.jupiter.api.AfterEach;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.mockito.Mock;
-import software.amazon.awssdk.core.ResponseInputStream;
-import software.amazon.awssdk.http.AbortableInputStream;
-import software.amazon.awssdk.services.s3.S3Client;
-import software.amazon.awssdk.services.s3.model.GetObjectRequest;
-import software.amazon.awssdk.services.s3.model.GetObjectResponse;
-import software.amazon.lambda.powertools.core.internal.LambdaHandlerProcessor;
-import software.amazon.lambda.powertools.logging.internal.LambdaLoggingAspect;
-import software.amazon.lambda.powertools.sqs.SqsUtils;
-import software.amazon.lambda.powertools.testsuite.handler.LoggingOrderMessageHandler;
-import software.amazon.lambda.powertools.testsuite.handler.TracingLoggingStreamMessageHandler;
-
-public class LoggingOrderTest {
-
- private static final String BUCKET_NAME = "ms-extended-sqs-client";
- private static final String BUCKET_KEY = "c71eb2ae-37e0-4265-8909-32f4153faddf";
-
- @Mock
- private Context context;
-
- @Mock
- private S3Client s3Client;
-
- @BeforeEach
- void setUp() throws IllegalAccessException, IOException, NoSuchMethodException, InvocationTargetException {
- openMocks(this);
- SqsUtils.overrideS3Client(s3Client);
- ThreadContext.clearAll();
- writeStaticField(LambdaHandlerProcessor.class, "IS_COLD_START", null, true);
- setupContext();
- //Make sure file is cleaned up before running full stack logging regression
- FileChannel.open(Paths.get("target/logfile.json"), StandardOpenOption.WRITE).truncate(0).close();
- resetLogLevel(Level.INFO);
- AWSXRay.beginSegment(LoggingOrderTest.class.getName());
- }
-
- @AfterEach
- void tearDown() {
- AWSXRay.endSegment();
- }
-
- /**
- * The SQSEvent payload will be altered by the @SqsLargeMessage annotation. Logging of the event should happen
- * after the event has been altered
- */
- @Test
- public void testThatLoggingAnnotationActsLast() throws IOException {
- ResponseInputStream s3Response =
- new ResponseInputStream<>(GetObjectResponse.builder().build(),
- AbortableInputStream.create(new ByteArrayInputStream("A big message".getBytes())));
-
- when(s3Client.getObject(any(GetObjectRequest.class))).thenReturn(s3Response);
- SQSEvent sqsEvent = messageWithBody(
- "[\"software.amazon.payloadoffloading.PayloadS3Pointer\",{\"s3BucketName\":\"" + BUCKET_NAME +
- "\",\"s3Key\":\"" + BUCKET_KEY + "\"}]");
-
- LoggingOrderMessageHandler requestHandler = new LoggingOrderMessageHandler();
- requestHandler.handleRequest(sqsEvent, context);
-
- assertThat(Files.lines(Paths.get("target/logfile.json")))
- .hasSize(2)
- .satisfies(line ->
- {
- Map actual = parseToMap(line.get(0));
-
- String message = actual.get("message").toString();
-
- assertThat(message)
- .contains("A big message");
- });
- }
-
- @Test
- public void testLoggingAnnotationActsAfterTracingForStreamingHandler() throws IOException {
-
- ByteArrayOutputStream output = new ByteArrayOutputStream();
- S3EventNotification s3EventNotification = s3EventNotification();
-
- TracingLoggingStreamMessageHandler handler = new TracingLoggingStreamMessageHandler();
- handler.handleRequest(new ByteArrayInputStream(new ObjectMapper().writeValueAsBytes(s3EventNotification)),
- output, context);
-
- assertThat(new String(output.toByteArray(), StandardCharsets.UTF_8))
- .isNotEmpty();
- }
-
- private void setupContext() {
- when(context.getFunctionName()).thenReturn("testFunction");
- when(context.getInvokedFunctionArn()).thenReturn("testArn");
- when(context.getFunctionVersion()).thenReturn("1");
- when(context.getMemoryLimitInMB()).thenReturn(10);
- when(context.getAwsRequestId()).thenReturn("RequestId");
- }
-
- private void resetLogLevel(Level level)
- throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
- Method resetLogLevels = LambdaLoggingAspect.class.getDeclaredMethod("resetLogLevels", Level.class);
- resetLogLevels.setAccessible(true);
- resetLogLevels.invoke(null, level);
- writeStaticField(LambdaLoggingAspect.class, "LEVEL_AT_INITIALISATION", level, true);
- }
-
- private Map parseToMap(String stringAsJson) {
- try {
- return new ObjectMapper().readValue(stringAsJson, Map.class);
- } catch (JsonProcessingException e) {
- fail("Failed parsing logger line " + stringAsJson);
- return emptyMap();
- }
- }
-
- private S3EventNotification s3EventNotification() {
- S3EventNotification.S3EventNotificationRecord record =
- new S3EventNotification.S3EventNotificationRecord("us-west-2",
- "ObjectCreated:Put",
- "aws:s3",
- null,
- "2.1",
- new S3EventNotification.RequestParametersEntity("127.0.0.1"),
- new S3EventNotification.ResponseElementsEntity("C3D13FE58DE4C810",
- "FMyUVURIY8/IgAtTv8xRjskZQpcIZ9KG4V5Wp6S7S/JRWeUWerMUE5JgHvANOjpD"),
- new S3EventNotification.S3Entity("testConfigRule",
- new S3EventNotification.S3BucketEntity("mybucket",
- new S3EventNotification.UserIdentityEntity("A3NL1KOZZKExample"),
- "arn:aws:s3:::mybucket"),
- new S3EventNotification.S3ObjectEntity("HappyFace.jpg",
- 1024L,
- "d41d8cd98f00b204e9800998ecf8427e",
- "096fKKXTRTtl3on89fVO.nfljtsv6qko",
- "0055AED6DCD90281E5"),
- "1.0"),
- new S3EventNotification.UserIdentityEntity("AIDAJDPLRKLG7UEXAMPLE")
- );
-
- return new S3EventNotification(singletonList(record));
- }
-
- private SQSEvent messageWithBody(String messageBody) {
- SQSEvent.SQSMessage sqsMessage = new SQSEvent.SQSMessage();
- sqsMessage.setBody(messageBody);
- SQSEvent sqsEvent = new SQSEvent();
- sqsEvent.setRecords(singletonList(sqsMessage));
- return sqsEvent;
- }
-}
\ No newline at end of file
diff --git a/powertools-test-suite/src/test/java/software/amazon/lambda/powertools/testsuite/handler/LoggingOrderMessageHandler.java b/powertools-test-suite/src/test/java/software/amazon/lambda/powertools/testsuite/handler/LoggingOrderMessageHandler.java
deleted file mode 100644
index 5592b1fd3..000000000
--- a/powertools-test-suite/src/test/java/software/amazon/lambda/powertools/testsuite/handler/LoggingOrderMessageHandler.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright 2023 Amazon.com, Inc. or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package software.amazon.lambda.powertools.testsuite.handler;
-
-import com.amazonaws.services.lambda.runtime.Context;
-import com.amazonaws.services.lambda.runtime.RequestHandler;
-import com.amazonaws.services.lambda.runtime.events.SQSEvent;
-import software.amazon.lambda.powertools.logging.Logging;
-import software.amazon.lambda.powertools.sqs.SqsLargeMessage;
-
-public class LoggingOrderMessageHandler implements RequestHandler {
-
- @Override
- @SqsLargeMessage
- @Logging(logEvent = true)
- public String handleRequest(SQSEvent sqsEvent, Context context) {
- return sqsEvent.getRecords().get(0).getBody();
- }
-}
diff --git a/powertools-test-suite/src/test/java/software/amazon/lambda/powertools/testsuite/handler/TracingLoggingStreamMessageHandler.java b/powertools-test-suite/src/test/java/software/amazon/lambda/powertools/testsuite/handler/TracingLoggingStreamMessageHandler.java
deleted file mode 100644
index 4a60d0949..000000000
--- a/powertools-test-suite/src/test/java/software/amazon/lambda/powertools/testsuite/handler/TracingLoggingStreamMessageHandler.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright 2023 Amazon.com, Inc. or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-package software.amazon.lambda.powertools.testsuite.handler;
-
-import com.amazonaws.services.lambda.runtime.Context;
-import com.amazonaws.services.lambda.runtime.RequestStreamHandler;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Map;
-import software.amazon.lambda.powertools.logging.Logging;
-import software.amazon.lambda.powertools.tracing.Tracing;
-
-public class TracingLoggingStreamMessageHandler implements RequestStreamHandler {
-
- @Logging(logEvent = true)
- @Tracing
- @Override
- public void handleRequest(InputStream input, OutputStream output, Context context) throws IOException {
- ObjectMapper mapper = new ObjectMapper();
- mapper.writeValue(output, mapper.readValue(input, Map.class));
- }
-}
diff --git a/powertools-test-suite/src/test/resources/log4j2.xml b/powertools-test-suite/src/test/resources/log4j2.xml
deleted file mode 100644
index 8ac9b34ce..000000000
--- a/powertools-test-suite/src/test/resources/log4j2.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file