|
16 | 16 |
|
17 | 17 | package org.springframework.integration.aws.inbound;
|
18 | 18 |
|
19 |
| -import java.util.concurrent.CompletableFuture; |
| 19 | +import java.util.Map; |
20 | 20 |
|
21 |
| -import org.junit.jupiter.api.Disabled; |
| 21 | +import io.awspring.cloud.sqs.listener.SqsHeaders; |
| 22 | +import org.junit.jupiter.api.BeforeAll; |
22 | 23 | import org.junit.jupiter.api.Test;
|
23 | 24 | import software.amazon.awssdk.services.sqs.SqsAsyncClient;
|
24 |
| -import software.amazon.awssdk.services.sqs.model.GetQueueAttributesRequest; |
25 |
| -import software.amazon.awssdk.services.sqs.model.GetQueueAttributesResponse; |
26 |
| -import software.amazon.awssdk.services.sqs.model.GetQueueUrlRequest; |
27 |
| -import software.amazon.awssdk.services.sqs.model.GetQueueUrlResponse; |
28 |
| -import software.amazon.awssdk.services.sqs.model.Message; |
29 |
| -import software.amazon.awssdk.services.sqs.model.ReceiveMessageRequest; |
30 |
| -import software.amazon.awssdk.services.sqs.model.ReceiveMessageResponse; |
| 25 | +import software.amazon.awssdk.services.sqs.model.MessageAttributeValue; |
| 26 | +import software.amazon.awssdk.services.sqs.model.SendMessageBatchRequestEntry; |
31 | 27 |
|
32 | 28 | import org.springframework.beans.factory.annotation.Autowired;
|
33 | 29 | import org.springframework.context.annotation.Bean;
|
34 | 30 | import org.springframework.context.annotation.Configuration;
|
35 |
| -import org.springframework.integration.annotation.ServiceActivator; |
36 |
| -import org.springframework.integration.aws.support.AwsHeaders; |
| 31 | +import org.springframework.integration.aws.LocalstackContainerTest; |
37 | 32 | import org.springframework.integration.channel.QueueChannel;
|
38 | 33 | import org.springframework.integration.config.EnableIntegration;
|
39 |
| -import org.springframework.integration.config.ExpressionControlBusFactoryBean; |
40 | 34 | import org.springframework.integration.core.MessageProducer;
|
41 |
| -import org.springframework.integration.test.util.TestUtils; |
42 |
| -import org.springframework.messaging.MessageChannel; |
43 | 35 | import org.springframework.messaging.PollableChannel;
|
44 |
| -import org.springframework.messaging.support.GenericMessage; |
45 | 36 | import org.springframework.test.annotation.DirtiesContext;
|
46 | 37 | import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
47 | 38 |
|
48 | 39 | import static org.assertj.core.api.Assertions.assertThat;
|
49 |
| -import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; |
50 |
| -import static org.mockito.ArgumentMatchers.any; |
51 |
| -import static org.mockito.BDDMockito.given; |
52 |
| -import static org.mockito.BDDMockito.mock; |
53 | 40 |
|
54 | 41 | /**
|
55 | 42 | * @author Artem Bilan
|
56 | 43 | */
|
57 |
| -@Disabled("Revise in favor of Local Stack") |
58 | 44 | @SpringJUnitConfig
|
59 | 45 | @DirtiesContext
|
60 |
| -public class SqsMessageDrivenChannelAdapterTests { |
| 46 | +public class SqsMessageDrivenChannelAdapterTests implements LocalstackContainerTest { |
61 | 47 |
|
62 |
| - @Autowired |
63 |
| - private PollableChannel inputChannel; |
| 48 | + private static SqsAsyncClient AMAZON_SQS; |
64 | 49 |
|
65 |
| - @Autowired |
66 |
| - private SqsMessageDrivenChannelAdapter sqsMessageDrivenChannelAdapter; |
| 50 | + private static String testQueueUrl; |
67 | 51 |
|
68 | 52 | @Autowired
|
69 |
| - private MessageChannel controlBusInput; |
| 53 | + private PollableChannel inputChannel; |
70 | 54 |
|
71 |
| - @Autowired |
72 |
| - private PollableChannel controlBusOutput; |
| 55 | + @BeforeAll |
| 56 | + static void setup() { |
| 57 | + AMAZON_SQS = LocalstackContainerTest.sqsClient(); |
| 58 | + testQueueUrl = AMAZON_SQS.createQueue(request -> request.queueName("testQueue")).join().queueUrl(); |
| 59 | + } |
73 | 60 |
|
74 | 61 | @Test
|
75 | 62 | void testSqsMessageDrivenChannelAdapter() {
|
76 |
| - assertThat( |
77 |
| - TestUtils.getPropertyValue(this.sqsMessageDrivenChannelAdapter, "listenerContainer.queueStopTimeout")) |
78 |
| - .isEqualTo(20000L); |
79 |
| - org.springframework.messaging.Message<?> receive = this.inputChannel.receive(1000); |
80 |
| - assertThat(receive).isNotNull(); |
81 |
| - assertThat((String) receive.getPayload()).isIn("messageContent", "messageContent2"); |
82 |
| - assertThat(receive.getHeaders().get(AwsHeaders.RECEIVED_QUEUE)).isEqualTo("testQueue"); |
83 |
| - receive = this.inputChannel.receive(1000); |
| 63 | + Map<String, MessageAttributeValue> attributes = |
| 64 | + Map.of("someAttribute", |
| 65 | + MessageAttributeValue.builder() |
| 66 | + .stringValue("someValue") |
| 67 | + .dataType("String") |
| 68 | + .build()); |
| 69 | + |
| 70 | + AMAZON_SQS.sendMessageBatch(request -> |
| 71 | + request.queueUrl(testQueueUrl) |
| 72 | + .entries(SendMessageBatchRequestEntry.builder() |
| 73 | + .messageBody("messageContent") |
| 74 | + .id("messageContent_id") |
| 75 | + .messageAttributes(attributes) |
| 76 | + .build(), |
| 77 | + SendMessageBatchRequestEntry.builder() |
| 78 | + .messageBody("messageContent2") |
| 79 | + .id("messageContent2_id") |
| 80 | + .messageAttributes(attributes) |
| 81 | + .build())); |
| 82 | + |
| 83 | + org.springframework.messaging.Message<?> receive = this.inputChannel.receive(10000); |
84 | 84 | assertThat(receive).isNotNull();
|
85 | 85 | assertThat((String) receive.getPayload()).isIn("messageContent", "messageContent2");
|
86 |
| - assertThat(receive.getHeaders().get(AwsHeaders.RECEIVED_QUEUE)).isEqualTo("testQueue"); |
87 |
| - |
88 |
| - try { |
89 |
| - this.controlBusInput.send(new GenericMessage<>("@sqsMessageDrivenChannelAdapter.stop('testQueue')")); |
90 |
| - } |
91 |
| - catch (Exception e) { |
92 |
| - // May fail with NPE. See |
93 |
| - // https://github.com/spring-cloud/spring-cloud-aws/issues/232 |
94 |
| - } |
95 |
| - this.controlBusInput.send(new GenericMessage<>("@sqsMessageDrivenChannelAdapter.isRunning('testQueue')")); |
96 |
| - |
97 |
| - receive = this.controlBusOutput.receive(1000); |
98 |
| - assertThat(receive).isNotNull(); |
99 |
| - assertThat((Boolean) receive.getPayload()).isFalse(); |
100 |
| - |
101 |
| - this.controlBusInput.send(new GenericMessage<>("@sqsMessageDrivenChannelAdapter.start('testQueue')")); |
102 |
| - this.controlBusInput.send(new GenericMessage<>("@sqsMessageDrivenChannelAdapter.isRunning('testQueue')")); |
| 86 | + assertThat(receive.getHeaders().get(SqsHeaders.SQS_QUEUE_NAME_HEADER)).isEqualTo("testQueue"); |
| 87 | + assertThat(receive.getHeaders().get("someAttribute")).isEqualTo("someValue"); |
103 | 88 |
|
104 |
| - receive = this.controlBusOutput.receive(1000); |
| 89 | + receive = this.inputChannel.receive(10000); |
105 | 90 | assertThat(receive).isNotNull();
|
106 |
| - assertThat((Boolean) receive.getPayload()).isTrue(); |
107 |
| - |
108 |
| - assertThatThrownBy( |
109 |
| - () -> this.controlBusInput.send(new GenericMessage<>("@sqsMessageDrivenChannelAdapter.start('foo')"))) |
110 |
| - .hasCauseExactlyInstanceOf(IllegalArgumentException.class) |
111 |
| - .hasStackTraceContaining("Queue with name 'foo' does not exist"); |
112 |
| - |
113 |
| - assertThat(this.sqsMessageDrivenChannelAdapter.getQueues()).isEqualTo(new String[] {"testQueue"}); |
| 91 | + assertThat((String) receive.getPayload()).isIn("messageContent", "messageContent2"); |
| 92 | + assertThat(receive.getHeaders().get(SqsHeaders.SQS_QUEUE_NAME_HEADER)).isEqualTo("testQueue"); |
| 93 | + assertThat(receive.getHeaders().get("someAttribute")).isEqualTo("someValue"); |
114 | 94 | }
|
115 | 95 |
|
116 | 96 | @Configuration
|
117 | 97 | @EnableIntegration
|
118 | 98 | public static class ContextConfiguration {
|
119 | 99 |
|
120 |
| - @Bean |
121 |
| - public SqsAsyncClient amazonSqs() { |
122 |
| - SqsAsyncClient sqs = mock(SqsAsyncClient.class); |
123 |
| - given(sqs.getQueueUrl(GetQueueUrlRequest.builder().queueName("testQueue").build())) |
124 |
| - .willReturn(CompletableFuture.completedFuture( |
125 |
| - GetQueueUrlResponse.builder().queueUrl("http://testQueue.amazonaws.com").build())); |
126 |
| - |
127 |
| - given(sqs.receiveMessage( |
128 |
| - ReceiveMessageRequest.builder() |
129 |
| - .queueUrl("http://testQueue.amazonaws.com") |
130 |
| - .maxNumberOfMessages(10) |
131 |
| - .attributeNamesWithStrings("All") |
132 |
| - .messageAttributeNames("All") |
133 |
| - .waitTimeSeconds(20) |
134 |
| - .build())) |
135 |
| - .willReturn( |
136 |
| - CompletableFuture.completedFuture( |
137 |
| - ReceiveMessageResponse.builder() |
138 |
| - .messages(Message.builder().body("messageContent").build(), |
139 |
| - Message.builder().body("messageContent2").build()) |
140 |
| - .build())) |
141 |
| - .willReturn(CompletableFuture.completedFuture(ReceiveMessageResponse.builder().build())); |
142 |
| - |
143 |
| - given(sqs.getQueueAttributes(any(GetQueueAttributesRequest.class))) |
144 |
| - .willReturn(CompletableFuture.completedFuture(GetQueueAttributesResponse.builder().build())); |
145 |
| - |
146 |
| - return sqs; |
147 |
| - } |
148 |
| - |
149 | 100 | @Bean
|
150 | 101 | public PollableChannel inputChannel() {
|
151 | 102 | return new QueueChannel();
|
152 | 103 | }
|
153 | 104 |
|
154 | 105 | @Bean
|
155 | 106 | public MessageProducer sqsMessageDrivenChannelAdapter() {
|
156 |
| - SqsMessageDrivenChannelAdapter adapter = new SqsMessageDrivenChannelAdapter(amazonSqs(), "testQueue"); |
| 107 | + SqsMessageDrivenChannelAdapter adapter = new SqsMessageDrivenChannelAdapter(AMAZON_SQS, "testQueue"); |
157 | 108 | adapter.setOutputChannel(inputChannel());
|
158 | 109 | return adapter;
|
159 | 110 | }
|
160 | 111 |
|
161 |
| - @Bean |
162 |
| - @ServiceActivator(inputChannel = "controlBusInput") |
163 |
| - public ExpressionControlBusFactoryBean controlBus() { |
164 |
| - ExpressionControlBusFactoryBean controlBusFactoryBean = new ExpressionControlBusFactoryBean(); |
165 |
| - controlBusFactoryBean.setOutputChannel(controlBusOutput()); |
166 |
| - return controlBusFactoryBean; |
167 |
| - } |
168 |
| - |
169 |
| - @Bean |
170 |
| - public PollableChannel controlBusOutput() { |
171 |
| - return new QueueChannel(); |
172 |
| - } |
173 |
| - |
174 | 112 | }
|
175 | 113 |
|
176 | 114 | }
|
0 commit comments