|
1 | 1 | /* |
2 | | - * Copyright 2013-2023 the original author or authors. |
| 2 | + * Copyright 2013-2025 the original author or authors. |
3 | 3 | * |
4 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | 5 | * you may not use this file except in compliance with the License. |
|
50 | 50 |
|
51 | 51 | /** |
52 | 52 | * @author Tomaz Fernandes |
| 53 | + * @author Hyunggeol Lee |
53 | 54 | */ |
54 | 55 | @SuppressWarnings("unchecked") |
55 | 56 | class SqsTemplateTests { |
@@ -1218,4 +1219,104 @@ void shouldPropagateTracingAsMessageSystemAttribute() { |
1218 | 1219 | value -> assertThat(value.stringValue()).isEqualTo("abc")); |
1219 | 1220 | } |
1220 | 1221 |
|
| 1222 | + @Test |
| 1223 | + void shouldRemoveFailedQueueAttributesFromCache() { |
| 1224 | + // Given - First attempt will fail |
| 1225 | + String queue = "test-queue"; |
| 1226 | + String payload = "test-payload"; |
| 1227 | + |
| 1228 | + CompletableFuture<GetQueueUrlResponse> failedFuture = new CompletableFuture<>(); |
| 1229 | + failedFuture.completeExceptionally(new RuntimeException("Queue attributes resolution failed")); |
| 1230 | + |
| 1231 | + given(mockClient.getQueueUrl(any(GetQueueUrlRequest.class))).willReturn(failedFuture); |
| 1232 | + |
| 1233 | + SqsOperations template = SqsTemplate.newTemplate(mockClient); |
| 1234 | + |
| 1235 | + // When - First attempt should fail |
| 1236 | + assertThatThrownBy(() -> template.send(queue, payload)).isInstanceOf(MessagingOperationFailedException.class); |
| 1237 | + |
| 1238 | + // Then - Setup successful response for retry |
| 1239 | + GetQueueUrlResponse urlResponse = GetQueueUrlResponse.builder().queueUrl(queue).build(); |
| 1240 | + given(mockClient.getQueueUrl(any(GetQueueUrlRequest.class))) |
| 1241 | + .willReturn(CompletableFuture.completedFuture(urlResponse)); |
| 1242 | + |
| 1243 | + mockQueueAttributes(mockClient, Map.of()); |
| 1244 | + |
| 1245 | + SendMessageResponse sendResponse = SendMessageResponse.builder().messageId(UUID.randomUUID().toString()) |
| 1246 | + .build(); |
| 1247 | + given(mockClient.sendMessage(any(SendMessageRequest.class))) |
| 1248 | + .willReturn(CompletableFuture.completedFuture(sendResponse)); |
| 1249 | + |
| 1250 | + // When - Retry should work (not use cached failure) |
| 1251 | + SendResult<String> result = template.send(queue, payload); |
| 1252 | + |
| 1253 | + // Then - Verify getQueueUrl was called twice (failure was not cached) |
| 1254 | + then(mockClient).should(times(2)).getQueueUrl(any(GetQueueUrlRequest.class)); |
| 1255 | + assertThat(result.endpoint()).isEqualTo(queue); |
| 1256 | + assertThat(result.message().getPayload()).isEqualTo(payload); |
| 1257 | + } |
| 1258 | + |
| 1259 | + @Test |
| 1260 | + void shouldCacheSuccessfulQueueAttributes() { |
| 1261 | + // Given - Setup successful responses |
| 1262 | + String queue = "test-queue"; |
| 1263 | + String payload1 = "test-payload-1"; |
| 1264 | + String payload2 = "test-payload-2"; |
| 1265 | + |
| 1266 | + GetQueueUrlResponse urlResponse = GetQueueUrlResponse.builder().queueUrl(queue).build(); |
| 1267 | + given(mockClient.getQueueUrl(any(GetQueueUrlRequest.class))) |
| 1268 | + .willReturn(CompletableFuture.completedFuture(urlResponse)); |
| 1269 | + |
| 1270 | + SendMessageResponse sendResponse = SendMessageResponse.builder().messageId(UUID.randomUUID().toString()) |
| 1271 | + .build(); |
| 1272 | + given(mockClient.sendMessage(any(SendMessageRequest.class))) |
| 1273 | + .willReturn(CompletableFuture.completedFuture(sendResponse)); |
| 1274 | + |
| 1275 | + SqsOperations template = SqsTemplate.newTemplate(mockClient); |
| 1276 | + |
| 1277 | + // When - Send twice to same queue |
| 1278 | + SendResult<String> result1 = template.send(queue, payload1); |
| 1279 | + SendResult<String> result2 = template.send(queue, payload2); |
| 1280 | + |
| 1281 | + // Then - Queue URL should be cached (only called once) |
| 1282 | + then(mockClient).should(times(1)).getQueueUrl(any(GetQueueUrlRequest.class)); |
| 1283 | + then(mockClient).should(times(2)).sendMessage(any(SendMessageRequest.class)); |
| 1284 | + } |
| 1285 | + |
| 1286 | + @Test |
| 1287 | + void shouldCacheSuccessfulQueueAttributesWithAttributeNames() { |
| 1288 | + // Given - Template with queueAttributeNames configured |
| 1289 | + String queue = "test-queue"; |
| 1290 | + String payload1 = "test-payload-1"; |
| 1291 | + String payload2 = "test-payload-2"; |
| 1292 | + |
| 1293 | + GetQueueUrlResponse urlResponse = GetQueueUrlResponse.builder().queueUrl(queue).build(); |
| 1294 | + given(mockClient.getQueueUrl(any(GetQueueUrlRequest.class))) |
| 1295 | + .willReturn(CompletableFuture.completedFuture(urlResponse)); |
| 1296 | + |
| 1297 | + GetQueueAttributesResponse attributesResponse = GetQueueAttributesResponse.builder() |
| 1298 | + .attributes(Map.of(QueueAttributeName.QUEUE_ARN, "test-arn")).build(); |
| 1299 | + given(mockClient.getQueueAttributes(any(Consumer.class))) |
| 1300 | + .willReturn(CompletableFuture.completedFuture(attributesResponse)); |
| 1301 | + |
| 1302 | + SendMessageResponse sendResponse = SendMessageResponse.builder().messageId(UUID.randomUUID().toString()) |
| 1303 | + .build(); |
| 1304 | + given(mockClient.sendMessage(any(SendMessageRequest.class))) |
| 1305 | + .willReturn(CompletableFuture.completedFuture(sendResponse)); |
| 1306 | + |
| 1307 | + // Create template with queueAttributeNames configured |
| 1308 | + SqsOperations template = SqsTemplate.builder().sqsAsyncClient(mockClient) |
| 1309 | + .configure( |
| 1310 | + options -> options.queueAttributeNames(Collections.singletonList(QueueAttributeName.QUEUE_ARN))) |
| 1311 | + .buildSyncTemplate(); |
| 1312 | + |
| 1313 | + // When - Send twice to same queue |
| 1314 | + template.send(queue, payload1); |
| 1315 | + template.send(queue, payload2); |
| 1316 | + |
| 1317 | + // Then - Queue attributes should be cached (only called once each) |
| 1318 | + then(mockClient).should(times(1)).getQueueUrl(any(GetQueueUrlRequest.class)); |
| 1319 | + then(mockClient).should(times(1)).getQueueAttributes(any(Consumer.class)); |
| 1320 | + then(mockClient).should(times(2)).sendMessage(any(SendMessageRequest.class)); |
| 1321 | + } |
1221 | 1322 | } |
0 commit comments