|
7 | 7 | import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
8 | 8 | import static org.junit.jupiter.api.Assertions.assertNull;
|
9 | 9 | import static org.junit.jupiter.api.Assertions.assertTrue;
|
| 10 | +import static org.junit.jupiter.api.Assertions.fail; |
10 | 11 | import static org.mockito.ArgumentMatchers.any;
|
11 | 12 | import static org.mockito.ArgumentMatchers.eq;
|
12 | 13 | import static org.mockito.ArgumentMatchers.isA;
|
| 14 | +import static org.mockito.Mockito.doThrow; |
13 | 15 | import static org.mockito.Mockito.mock;
|
14 | 16 | import static org.mockito.Mockito.never;
|
15 | 17 | import static org.mockito.Mockito.spy;
|
|
25 | 27 | import java.util.Map;
|
26 | 28 | import java.util.UUID;
|
27 | 29 | import java.util.concurrent.CompletableFuture;
|
| 30 | +import java.util.concurrent.CompletionException; |
28 | 31 | import java.util.stream.Collectors;
|
29 | 32 | import java.util.stream.IntStream;
|
30 | 33 | import org.junit.jupiter.api.BeforeEach;
|
|
35 | 38 | import software.amazon.awssdk.core.ResponseBytes;
|
36 | 39 | import software.amazon.awssdk.core.async.AsyncRequestBody;
|
37 | 40 | import software.amazon.awssdk.core.async.AsyncResponseTransformer;
|
| 41 | +import software.amazon.awssdk.core.exception.SdkException; |
38 | 42 | import software.amazon.awssdk.services.s3.S3AsyncClient;
|
39 | 43 | import software.amazon.awssdk.services.s3.model.DeleteObjectRequest;
|
40 | 44 | import software.amazon.awssdk.services.s3.model.DeleteObjectResponse;
|
41 | 45 | import software.amazon.awssdk.services.s3.model.GetObjectRequest;
|
42 | 46 | import software.amazon.awssdk.services.s3.model.GetObjectResponse;
|
| 47 | +import software.amazon.awssdk.services.s3.model.NoSuchKeyException; |
43 | 48 | import software.amazon.awssdk.services.s3.model.ObjectCannedACL;
|
44 | 49 | import software.amazon.awssdk.services.s3.model.PutObjectRequest;
|
45 | 50 | import software.amazon.awssdk.services.sqs.SqsAsyncClient;
|
| 51 | +import software.amazon.awssdk.services.sqs.SqsClient; |
46 | 52 | import software.amazon.awssdk.services.sqs.model.DeleteMessageBatchRequest;
|
47 | 53 | import software.amazon.awssdk.services.sqs.model.DeleteMessageBatchRequestEntry;
|
48 | 54 | import software.amazon.awssdk.services.sqs.model.DeleteMessageBatchResponse;
|
@@ -640,6 +646,63 @@ private void testReceiveMessage_when_MessageIsLarge(String reservedAttributeName
|
640 | 646 | verify(mockS3, times(1)).getObject(isA(GetObjectRequest.class), isA(AsyncResponseTransformer.class));
|
641 | 647 | }
|
642 | 648 |
|
| 649 | + @Test |
| 650 | + public void testReceiveMessage_when_ignorePayloadNotFound_then_messageWithPayloadNotFoundIsDeletedFromSQS() { |
| 651 | + ExtendedAsyncClientConfiguration extendedAsyncClientConfiguration = new ExtendedAsyncClientConfiguration() |
| 652 | + .withPayloadSupportEnabled(mockS3, S3_BUCKET_NAME) |
| 653 | + .withIgnorePayloadNotFound(true); |
| 654 | + SqsAsyncClient sqsAsyncExtended = spy(new AmazonSQSExtendedAsyncClient(mockSqsBackend, extendedAsyncClientConfiguration)); |
| 655 | + |
| 656 | + String receiptHandle = "receipt-handle"; |
| 657 | + Message message = Message.builder() |
| 658 | + .messageAttributes(ImmutableMap.of(SQSExtendedClientConstants.RESERVED_ATTRIBUTE_NAME, MessageAttributeValue.builder().build())) |
| 659 | + .body(new PayloadS3Pointer(S3_BUCKET_NAME, "S3Key").toJson()) |
| 660 | + .receiptHandle(receiptHandle) |
| 661 | + .build(); |
| 662 | + |
| 663 | + when(mockSqsBackend.receiveMessage(isA(ReceiveMessageRequest.class))).thenReturn( |
| 664 | + CompletableFuture.completedFuture(ReceiveMessageResponse.builder().messages(message).build())); |
| 665 | + doThrow(NoSuchKeyException.class).when(mockS3).getObject((GetObjectRequest) any(), any(AsyncResponseTransformer.class)); |
| 666 | + |
| 667 | + ReceiveMessageRequest messageRequest = ReceiveMessageRequest.builder().queueUrl(SQS_QUEUE_URL).build(); |
| 668 | + ReceiveMessageResponse receiveMessageResponse = sqsAsyncExtended.receiveMessage(messageRequest).join(); |
| 669 | + |
| 670 | + assertTrue(receiveMessageResponse.messages().isEmpty()); |
| 671 | + |
| 672 | + ArgumentCaptor<DeleteMessageRequest> deleteMessageRequestArgumentCaptor = ArgumentCaptor.forClass(DeleteMessageRequest.class); |
| 673 | + verify(mockSqsBackend).deleteMessage(deleteMessageRequestArgumentCaptor.capture()); |
| 674 | + assertEquals(SQS_QUEUE_URL, deleteMessageRequestArgumentCaptor.getValue().queueUrl()); |
| 675 | + assertEquals(receiptHandle, deleteMessageRequestArgumentCaptor.getValue().receiptHandle()); |
| 676 | + } |
| 677 | + |
| 678 | + @Test |
| 679 | + public void testReceiveMessage_when_ignorePayloadNotFoundIsFalse_then_messageWithPayloadNotFoundThrowsException() { |
| 680 | + ExtendedAsyncClientConfiguration extendedAsyncClientConfiguration = new ExtendedAsyncClientConfiguration() |
| 681 | + .withPayloadSupportEnabled(mockS3, S3_BUCKET_NAME) |
| 682 | + .withIgnorePayloadNotFound(false); |
| 683 | + SqsAsyncClient sqsAsyncExtended = spy(new AmazonSQSExtendedAsyncClient(mockSqsBackend, extendedAsyncClientConfiguration)); |
| 684 | + |
| 685 | + String receiptHandle = "receipt-handle"; |
| 686 | + Message message = Message.builder() |
| 687 | + .messageAttributes(ImmutableMap.of(SQSExtendedClientConstants.RESERVED_ATTRIBUTE_NAME, MessageAttributeValue.builder().build())) |
| 688 | + .body(new PayloadS3Pointer(S3_BUCKET_NAME, "S3Key").toJson()) |
| 689 | + .receiptHandle(receiptHandle) |
| 690 | + .build(); |
| 691 | + |
| 692 | + when(mockSqsBackend.receiveMessage(isA(ReceiveMessageRequest.class))).thenReturn( |
| 693 | + CompletableFuture.completedFuture(ReceiveMessageResponse.builder().messages(message).build())); |
| 694 | + doThrow(NoSuchKeyException.class).when(mockS3).getObject((GetObjectRequest) any(), any(AsyncResponseTransformer.class)); |
| 695 | + |
| 696 | + ReceiveMessageRequest messageRequest = ReceiveMessageRequest.builder().build(); |
| 697 | + try { |
| 698 | + sqsAsyncExtended.receiveMessage(messageRequest).join(); |
| 699 | + fail("Expected exception after receiving NoSuchKeyException from S3 was not thrown."); |
| 700 | + } catch (CompletionException e) { |
| 701 | + assertEquals(NoSuchKeyException.class.getName(), e.getCause().getClass().getName()); |
| 702 | + verify(mockSqsBackend, never()).deleteMessage(any(DeleteMessageRequest.class)); |
| 703 | + } |
| 704 | + } |
| 705 | + |
643 | 706 | private DeleteMessageBatchRequest generateLargeDeleteBatchRequest(List<String> originalReceiptHandles) {
|
644 | 707 | List<DeleteMessageBatchRequestEntry> deleteEntries = IntStream.range(0, originalReceiptHandles.size())
|
645 | 708 | .mapToObj(i -> DeleteMessageBatchRequestEntry.builder()
|
|
0 commit comments