use of com.rabbitmq.stream.impl.MonitoringTestUtils.ConsumerInfo in project rabbitmq-stream-java-client by rabbitmq.
the class StreamConsumerTest method manualTrackingConsumerShouldRestartWhereItLeftOff.
@Test
void manualTrackingConsumerShouldRestartWhereItLeftOff() throws Exception {
Producer producer = environment.producerBuilder().stream(stream).build();
int messageCountFirstWave = 10_000;
int messageCountSecondWave = 5_000;
int messageCount = messageCountFirstWave + messageCountSecondWave;
CountDownLatch latchConfirmFirstWave = new CountDownLatch(messageCountFirstWave);
CountDownLatch latchConfirmSecondWave = new CountDownLatch(messageCount);
ConfirmationHandler confirmationHandler = confirmationStatus -> {
latchConfirmFirstWave.countDown();
latchConfirmSecondWave.countDown();
};
AtomicLong messageIdSequence = new AtomicLong();
java.util.function.Consumer<Integer> messageSending = messageCountToSend -> {
IntStream.range(0, messageCountToSend).forEach(i -> producer.send(producer.messageBuilder().addData("".getBytes()).properties().messageId(messageIdSequence.getAndIncrement()).messageBuilder().build(), confirmationHandler));
};
messageSending.accept(messageCountFirstWave);
assertThat(latchAssert(latchConfirmFirstWave)).completes();
int storeEvery = 100;
AtomicInteger consumedMessageCount = new AtomicInteger();
AtomicReference<Consumer> consumerReference = new AtomicReference<>();
AtomicLong lastStoredOffset = new AtomicLong(0);
AtomicLong lastProcessedMessage = new AtomicLong(0);
AtomicInteger storeCount = new AtomicInteger(0);
Consumer consumer = environment.consumerBuilder().stream(stream).offset(OffsetSpecification.first()).name("application-1").manualTrackingStrategy().checkInterval(Duration.ZERO).builder().messageHandler((context, message) -> {
consumedMessageCount.incrementAndGet();
lastProcessedMessage.set(message.getProperties().getMessageIdAsLong());
if (consumedMessageCount.get() % storeEvery == 0) {
context.storeOffset();
lastStoredOffset.set(context.offset());
storeCount.incrementAndGet();
}
}).build();
ConsumerInfo consumerInfo = MonitoringTestUtils.extract(consumer);
assertThat(consumerInfo.getId()).isGreaterThanOrEqualTo(0);
assertThat(consumerInfo.getStream()).isEqualTo(stream);
assertThat(consumerInfo.getSubscriptionClient()).contains(" -> localhost:5552");
assertThat(consumerInfo.getTrackingClient()).contains(" -> localhost:5552");
consumerReference.set(consumer);
waitAtMost(10, () -> consumedMessageCount.get() == messageCountFirstWave);
assertThat(lastStoredOffset.get()).isPositive();
consumer.close();
messageSending.accept(messageCountSecondWave);
assertThat(latchAssert(latchConfirmSecondWave)).completes();
AtomicLong firstOffset = new AtomicLong(0);
consumer = environment.consumerBuilder().stream(stream).name("application-1").manualTrackingStrategy().checkInterval(Duration.ZERO).builder().messageHandler((context, message) -> {
firstOffset.compareAndSet(0, context.offset());
if (message.getProperties().getMessageIdAsLong() > lastProcessedMessage.get()) {
consumedMessageCount.incrementAndGet();
}
}).build();
waitAtMost(3, () -> consumedMessageCount.get() == messageCount, () -> "Expected " + consumedMessageCount.get() + " to reach " + messageCount);
// there will be the tracking records after the first wave of messages,
// messages offset won't be contiguous, so it's not an exact match
assertThat(firstOffset.get()).isGreaterThanOrEqualTo(lastStoredOffset.get());
consumer.close();
}
Aggregations