Skip to content

Commit 144b668

Browse files
jashmoreAtlassianJaidenAshmore
authored andcommitted
refs #73 #54: add dependency information in the README.md
Attempt to help the ConcurrentMessageBrokerIntegrationTest from not being flaky.
1 parent 5ff2a71 commit 144b668

File tree

5 files changed

+168
-219
lines changed

5 files changed

+168
-219
lines changed

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,19 @@ are to be processed and the rate of concurrency for processing messages.
3737

3838
See the [Core Implementations Overview](./doc/core-implementations-overview.md) for more information about the core implementations provided by this library.
3939

40+
### Dependencies
41+
The framework relies on the following dependencies and therefore it is recommended to upgrade the applications dependencies to a point somewhere near these
42+
for compatibility.
43+
- [Core Framework](java-dynamic-sqs-listener-core)
44+
- JDK 1.8 or higher
45+
- [AWS SQS SDK](https://docs.aws.amazon.com/sdk-for-java/v2/developer-guide/welcome.html): 2.2.0
46+
- [Guava](https://github.com/google/guava): 21.0
47+
- [Jackson Databind](https://github.com/FasterXML/jackson-databind): 2.9.8
48+
- [Spring Framework](java-dynamic-sqs-listener-spring)
49+
- All of the core dependencies
50+
- [Spring](https://github.com/spring-projects/spring-framework): 5.0.8.RELEASE
51+
- [Spring Boot](https://github.com/spring-projects/spring-boot): 2.0.2.RELEASE
52+
4053
## Spring Quick Guide
4154
The following provides some examples using the Spring Starter for this library. *Note that this library is not Spring specific as the main implementations are
4255
kept in the [core module](./java-dynamic-sqs-listener-core) which is framework agnostic.*

java-dynamic-sqs-listener-core/src/test/java/it/com/jashmore/sqs/listener/concurrent/ConcurrentMessageBrokerIntegrationTest.java

Lines changed: 13 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import static java.util.concurrent.TimeUnit.MINUTES;
44
import static java.util.concurrent.TimeUnit.SECONDS;
5-
import static org.assertj.core.api.Assertions.assertThat;
65

76
import com.fasterxml.jackson.databind.ObjectMapper;
87
import com.jashmore.sqs.QueueProperties;
@@ -24,104 +23,49 @@
2423
import com.jashmore.sqs.retriever.prefetch.PrefetchingMessageRetriever;
2524
import com.jashmore.sqs.retriever.prefetch.StaticPrefetchingMessageRetrieverProperties;
2625
import com.jashmore.sqs.test.LocalSqsRule;
27-
import it.com.jashmore.sqs.AbstractSqsIntegrationTest;
26+
import it.com.jashmore.sqs.listener.util.SqsIntegrationTestUtils;
2827
import lombok.extern.slf4j.Slf4j;
29-
import org.junit.After;
3028
import org.junit.Before;
3129
import org.junit.Rule;
3230
import org.junit.Test;
3331
import software.amazon.awssdk.services.sqs.SqsAsyncClient;
3432

3533
import java.util.concurrent.CountDownLatch;
3634
import java.util.concurrent.Executors;
37-
import java.util.concurrent.atomic.AtomicInteger;
3835

3936
@Slf4j
40-
public class ConcurrentMessageBrokerIntegrationTest extends AbstractSqsIntegrationTest {
37+
public class ConcurrentMessageBrokerIntegrationTest {
4138
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
4239
private static final PayloadMapper PAYLOAD_MAPPER = new JacksonPayloadMapper(OBJECT_MAPPER);
4340

4441
@Rule
4542
public LocalSqsRule localSqsRule = new LocalSqsRule();
4643

4744
private String queueUrl;
48-
private SqsAsyncClient sqsAsyncClient;
4945
private QueueProperties queueProperties;
5046
private ArgumentResolverService argumentResolverService;
5147

5248
@Before
5349
public void setUp() {
5450
queueUrl = localSqsRule.createRandomQueue();
5551
queueProperties = QueueProperties.builder().queueUrl(queueUrl).build();
56-
sqsAsyncClient = localSqsRule.getLocalAmazonSqsAsync();
57-
argumentResolverService = new CoreArgumentResolverService(PAYLOAD_MAPPER, sqsAsyncClient);
58-
}
59-
60-
@After
61-
public void tearDown() {
62-
// If the thread running the tests is interrupted it will break future tests. This will be fixed in release of JUnit 4.13 but until then
63-
// we use this workaround. See https://github.com/junit-team/junit4/issues/1365
64-
Thread.interrupted();
65-
}
66-
67-
@Test
68-
public void concurrentListenerCanConsumeMultipleMessagesFromQueueAtOnce() throws Exception {
69-
// arrange
70-
final int concurrencyLevel = 5;
71-
final MessageRetriever messageRetriever = new IndividualMessageRetriever(
72-
sqsAsyncClient,
73-
queueProperties,
74-
IndividualMessageRetrieverProperties.builder()
75-
.visibilityTimeoutForMessagesInSeconds(5)
76-
.build()
77-
);
78-
final CountDownLatch concurrentMessagesLatch = new CountDownLatch(concurrencyLevel);
79-
final MessageConsumer messageConsumer = new MessageConsumer(concurrentMessagesLatch);
80-
final MessageResolver messageResolver = new IndividualMessageResolver(queueProperties, sqsAsyncClient);
81-
final MessageProcessor messageProcessor = new DefaultMessageProcessor(
82-
argumentResolverService,
83-
queueProperties,
84-
messageResolver,
85-
MessageConsumer.class.getMethod("consume", String.class),
86-
messageConsumer
87-
);
88-
final ConcurrentMessageBroker messageBroker = new ConcurrentMessageBroker(
89-
messageRetriever,
90-
messageProcessor,
91-
Executors.newCachedThreadPool(),
92-
StaticConcurrentMessageBrokerProperties.builder()
93-
.concurrencyLevel(concurrencyLevel)
94-
.build()
95-
);
96-
sendNumberOfMessages(concurrencyLevel, sqsAsyncClient, queueUrl);
97-
98-
// act
99-
messageBroker.start();
100-
concurrentMessagesLatch.await(60, SECONDS);
101-
102-
// cleanup
103-
messageBroker.stop().get(4, SECONDS);
104-
105-
// assert
106-
assertThat(messageConsumer.numberOfTimesProcessed.get()).isEqualTo(concurrencyLevel);
107-
assertNoMessagesInQueue(sqsAsyncClient, queueUrl);
52+
argumentResolverService = new CoreArgumentResolverService(PAYLOAD_MAPPER, localSqsRule.getLocalAmazonSqsAsync());
10853
}
10954

11055
@Test
11156
public void allMessagesSentIntoQueueAreProcessed() throws Exception {
11257
// arrange
11358
final int concurrencyLevel = 10;
114-
final int numberOfMessages = 300;
115-
final QueueProperties queueProperties = QueueProperties.builder().queueUrl(queueUrl).build();
59+
final int numberOfMessages = 100;
11660
final SqsAsyncClient sqsAsyncClient = localSqsRule.getLocalAmazonSqsAsync();
11761
final MessageRetriever messageRetriever = new IndividualMessageRetriever(
11862
sqsAsyncClient,
11963
queueProperties,
120-
IndividualMessageRetrieverProperties.builder().visibilityTimeoutForMessagesInSeconds(1).build()
64+
IndividualMessageRetrieverProperties.builder()
65+
.visibilityTimeoutForMessagesInSeconds(30)
66+
.build()
12167
);
12268
final CountDownLatch messageReceivedLatch = new CountDownLatch(numberOfMessages);
123-
final PayloadMapper payloadMapper = new JacksonPayloadMapper(OBJECT_MAPPER);
124-
final ArgumentResolverService argumentResolverService = new CoreArgumentResolverService(payloadMapper, sqsAsyncClient);
12569
final MessageConsumer messageConsumer = new MessageConsumer(messageReceivedLatch);
12670
final MessageResolver messageResolver = new IndividualMessageResolver(queueProperties, sqsAsyncClient);
12771
final MessageProcessor messageProcessor = new DefaultMessageProcessor(
@@ -139,42 +83,38 @@ public void allMessagesSentIntoQueueAreProcessed() throws Exception {
13983
.concurrencyLevel(concurrencyLevel)
14084
.build()
14185
);
142-
sendNumberOfMessages(numberOfMessages, sqsAsyncClient, queueUrl);
86+
SqsIntegrationTestUtils.sendNumberOfMessages(numberOfMessages, sqsAsyncClient, queueUrl);
14387

14488
// act
14589
messageBroker.start();
14690

14791
// assert
14892
messageReceivedLatch.await(60, SECONDS);
149-
assertThat(messageConsumer.numberOfTimesProcessed.get()).isEqualTo(numberOfMessages);
15093

15194
// cleanup
15295
messageBroker.stop().get(4, SECONDS);
153-
assertNoMessagesInQueue(sqsAsyncClient, queueUrl);
96+
SqsIntegrationTestUtils.assertNoMessagesInQueue(sqsAsyncClient, queueUrl);
15497
}
15598

15699
@Test
157100
public void usingPrefetchingMessageRetrieverCanConsumeAllMessages() throws Exception {
158101
// arrange
159102
final int concurrencyLevel = 10;
160-
final int numberOfMessages = 300;
161-
final QueueProperties queueProperties = QueueProperties.builder().queueUrl(queueUrl).build();
103+
final int numberOfMessages = 100;
162104
final SqsAsyncClient sqsAsyncClient = localSqsRule.getLocalAmazonSqsAsync();
163105
final AsyncMessageRetriever messageRetriever = new PrefetchingMessageRetriever(
164106
sqsAsyncClient,
165107
queueProperties,
166108
StaticPrefetchingMessageRetrieverProperties
167109
.builder()
168-
.visibilityTimeoutForMessagesInSeconds(1)
110+
.visibilityTimeoutForMessagesInSeconds(60)
169111
.maxWaitTimeInSecondsToObtainMessagesFromServer(1)
170112
.desiredMinPrefetchedMessages(30)
171113
.maxPrefetchedMessages(40)
172114
.build(),
173115
Executors.newCachedThreadPool()
174116
);
175117
final CountDownLatch messageReceivedLatch = new CountDownLatch(numberOfMessages);
176-
final PayloadMapper payloadMapper = new JacksonPayloadMapper(OBJECT_MAPPER);
177-
final ArgumentResolverService argumentResolverService = new CoreArgumentResolverService(payloadMapper, sqsAsyncClient);
178118
final MessageConsumer messageConsumer = new MessageConsumer(messageReceivedLatch);
179119
final MessageResolver messageResolver = new IndividualMessageResolver(queueProperties, sqsAsyncClient);
180120
final MessageProcessor messageProcessor = new DefaultMessageProcessor(
@@ -192,27 +132,25 @@ public void usingPrefetchingMessageRetrieverCanConsumeAllMessages() throws Excep
192132
.concurrencyLevel(concurrencyLevel)
193133
.build()
194134
);
195-
sendNumberOfMessages(numberOfMessages, sqsAsyncClient, queueUrl);
135+
SqsIntegrationTestUtils.sendNumberOfMessages(numberOfMessages, sqsAsyncClient, queueUrl);
196136
messageRetriever.start();
197137

198138
// act
199139
messageBroker.start();
200140

201141
// assert
202142
messageReceivedLatch.await(1, MINUTES);
203-
assertThat(messageConsumer.numberOfTimesProcessed.get()).isEqualTo(numberOfMessages);
204143

205144
// cleanup
206145
messageRetriever.stop().get(5, SECONDS);
207146
log.debug("Stopped message retriever");
208147
messageBroker.stop().get(10, SECONDS);
209-
assertNoMessagesInQueue(sqsAsyncClient, queueUrl);
148+
SqsIntegrationTestUtils.assertNoMessagesInQueue(sqsAsyncClient, queueUrl);
210149
}
211150

212151
@SuppressWarnings("WeakerAccess")
213152
public static class MessageConsumer {
214153
private final CountDownLatch messagesReceivedLatch;
215-
private final AtomicInteger numberOfTimesProcessed = new AtomicInteger(0);
216154

217155
public MessageConsumer(final CountDownLatch messagesReceivedLatch) {
218156
this.messagesReceivedLatch = messagesReceivedLatch;
@@ -221,7 +159,6 @@ public MessageConsumer(final CountDownLatch messagesReceivedLatch) {
221159
@SuppressWarnings("unused")
222160
public void consume(@Payload final String messagePayload) {
223161
log.info("Consuming message: {}", messagePayload);
224-
numberOfTimesProcessed.incrementAndGet();
225162
messagesReceivedLatch.countDown();
226163
}
227164
}

java-dynamic-sqs-listener-core/src/test/java/it/com/jashmore/sqs/listener/individual/SingleThreadedMessageBrokerIntegrationTest.java

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
import com.jashmore.sqs.retriever.individual.IndividualMessageRetriever;
2121
import com.jashmore.sqs.retriever.individual.IndividualMessageRetrieverProperties;
2222
import com.jashmore.sqs.test.LocalSqsRule;
23-
import it.com.jashmore.sqs.AbstractSqsIntegrationTest;
23+
import it.com.jashmore.sqs.listener.util.SqsIntegrationTestUtils;
2424
import org.junit.Before;
2525
import org.junit.Rule;
2626
import org.junit.Test;
@@ -29,7 +29,7 @@
2929
import java.util.concurrent.CountDownLatch;
3030
import java.util.concurrent.atomic.AtomicInteger;
3131

32-
public class SingleThreadedMessageBrokerIntegrationTest extends AbstractSqsIntegrationTest {
32+
public class SingleThreadedMessageBrokerIntegrationTest {
3333
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
3434
@Rule
3535
public final LocalSqsRule localSqsRule = new LocalSqsRule();
@@ -39,10 +39,6 @@ public class SingleThreadedMessageBrokerIntegrationTest extends AbstractSqsInteg
3939
@Before
4040
public void setUp() {
4141
queueUrl = localSqsRule.createRandomQueue();
42-
43-
// If the thread running the tests is interrupted it will break future tests. This will be fixed in release of JUnit 4.13 but until then
44-
// we use this workaround. See https://github.com/junit-team/junit4/issues/1365
45-
Thread.interrupted();
4642
}
4743

4844
@Test
@@ -69,7 +65,7 @@ public void individualMessageListenerCanProcessAllMessagesOnQueue() throws Excep
6965
messageConsumer
7066
);
7167
final MessageBroker container = new SingleThreadedMessageBroker(messageRetriever, messageProcessor);
72-
sendNumberOfMessages(numberOfMessages, sqsAsyncClient, queueUrl);
68+
SqsIntegrationTestUtils.sendNumberOfMessages(numberOfMessages, sqsAsyncClient, queueUrl);
7369

7470
// act
7571
container.start();
@@ -80,9 +76,10 @@ public void individualMessageListenerCanProcessAllMessagesOnQueue() throws Excep
8076

8177
// cleanup
8278
container.stop().get(10, SECONDS);
83-
assertNoMessagesInQueue(sqsAsyncClient, queueUrl);
79+
SqsIntegrationTestUtils.assertNoMessagesInQueue(sqsAsyncClient, queueUrl);
8480
}
8581

82+
@SuppressWarnings({"WeakerAccess", "unused"})
8683
public static class MessageConsumer {
8784
private final CountDownLatch messagesReceivedLatch;
8885
private final CountDownLatch testCompletedLatch;
@@ -93,7 +90,6 @@ public MessageConsumer(final CountDownLatch messagesReceivedLatch, final CountDo
9390
this.testCompletedLatch = testCompletedLatch;
9491
}
9592

96-
@SuppressWarnings("unused")
9793
public void consume(@Payload final String messagePayload) throws InterruptedException {
9894
numberOfTimesProcessed.incrementAndGet();
9995
messagesReceivedLatch.countDown();

java-dynamic-sqs-listener-core/src/test/java/it/com/jashmore/sqs/AbstractSqsIntegrationTest.java renamed to java-dynamic-sqs-listener-core/src/test/java/it/com/jashmore/sqs/listener/util/SqsIntegrationTestUtils.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
package it.com.jashmore.sqs;
1+
package it.com.jashmore.sqs.listener.util;
22

33
import static org.assertj.core.api.Assertions.assertThat;
44
import static software.amazon.awssdk.services.sqs.model.QueueAttributeName.APPROXIMATE_NUMBER_OF_MESSAGES;
55
import static software.amazon.awssdk.services.sqs.model.QueueAttributeName.APPROXIMATE_NUMBER_OF_MESSAGES_NOT_VISIBLE;
66

7+
import lombok.experimental.UtilityClass;
78
import lombok.extern.slf4j.Slf4j;
89
import software.amazon.awssdk.services.sqs.SqsAsyncClient;
910
import software.amazon.awssdk.services.sqs.model.GetQueueAttributesRequest;
@@ -16,12 +17,13 @@
1617
import java.util.stream.IntStream;
1718

1819
@Slf4j
19-
public abstract class AbstractSqsIntegrationTest {
20+
@UtilityClass
21+
public class SqsIntegrationTestUtils {
2022
private static final int MAX_SEND_MESSAGE_BATCH_SIZE = 10;
2123

2224
public static void assertNoMessagesInQueue(final SqsAsyncClient sqsAsyncClient,
2325
final String queueUrl) {
24-
GetQueueAttributesRequest request = GetQueueAttributesRequest
26+
final GetQueueAttributesRequest request = GetQueueAttributesRequest
2527
.builder()
2628
.queueUrl(queueUrl)
2729
.attributeNames(APPROXIMATE_NUMBER_OF_MESSAGES, APPROXIMATE_NUMBER_OF_MESSAGES_NOT_VISIBLE)
@@ -46,8 +48,8 @@ public static void sendNumberOfMessages(int numberOfMessages,
4648
final SendMessageBatchRequest.Builder sendMessageBatchRequestBuilder = SendMessageBatchRequest.builder().queueUrl(queueUrl);
4749
final int batchSize = Math.min(numberOfMessages - numberOfMessagesSent.get(), MAX_SEND_MESSAGE_BATCH_SIZE);
4850
sendMessageBatchRequestBuilder.entries(IntStream.range(0, batchSize)
49-
.map(index -> numberOfMessages + index)
50-
.mapToObj(id -> SendMessageBatchRequestEntry.builder().id("" + id).messageBody("body: " + (numberOfMessagesSent.get() + id)).build())
51+
.map(index -> numberOfMessagesSent.get() + index)
52+
.mapToObj(id -> SendMessageBatchRequestEntry.builder().id("" + id).messageBody("body: " + id).build())
5153
.collect(Collectors.toSet()));
5254
try {
5355
sqsAsyncClient.sendMessageBatch(sendMessageBatchRequestBuilder.build()).get();

0 commit comments

Comments
 (0)