use of com.rabbitmq.stream.Producer in project rabbitmq-stream-java-client by rabbitmq.
the class StreamConsumerTest method useSubscriptionListenerToRestartExactlyWhereDesired.
@Test
@DisabledIfRabbitMqCtlNotSet
void useSubscriptionListenerToRestartExactlyWhereDesired() throws Exception {
AtomicInteger subscriptionListenerCallCount = new AtomicInteger(0);
AtomicInteger receivedMessages = new AtomicInteger(0);
AtomicLong offsetTracking = new AtomicLong(0);
AtomicBoolean started = new AtomicBoolean(false);
int storeEvery = 10_000;
String reference = "ref-1";
CountDownLatch poisonLatch = new CountDownLatch(1);
environment.consumerBuilder().name(reference).stream(stream).offset(OffsetSpecification.first()).subscriptionListener(subscriptionContext -> {
subscriptionListenerCallCount.getAndIncrement();
OffsetSpecification offsetSpecification = started.get() ? OffsetSpecification.offset(offsetTracking.get() + 1) : subscriptionContext.offsetSpecification();
subscriptionContext.offsetSpecification(offsetSpecification);
}).messageHandler((context, message) -> {
receivedMessages.incrementAndGet();
offsetTracking.set(context.offset());
started.set(true);
if ("poison".equals(new String(message.getBodyAsBinary()))) {
poisonLatch.countDown();
}
}).autoTrackingStrategy().flushInterval(// long flush interval
Duration.ofMinutes(60)).messageCountBeforeStorage(storeEvery).builder().build();
AtomicInteger publishedMessages = new AtomicInteger(0);
Producer producer = environment.producerBuilder().stream(stream).build();
IntConsumer publish = messagesToPublish -> {
publishedMessages.addAndGet(messagesToPublish);
IntStream.range(0, messagesToPublish).forEach(i -> producer.send(producer.messageBuilder().addData("".getBytes()).build(), confirmationStatus -> {
}));
};
publish.accept(storeEvery * 2 - 100);
waitAtMost(5, () -> receivedMessages.get() == publishedMessages.get());
Host.killConnection("rabbitmq-stream-consumer-0");
publish.accept(storeEvery * 2);
producer.send(producer.messageBuilder().addData("poison".getBytes()).build(), confirmationStatus -> {
});
latchAssert(poisonLatch).completes();
// no duplicates because the custom offset tracking overrides the stored offset in the
// subscription listener
assertThat(receivedMessages).hasValue(publishedMessages.get() + 1);
}
use of com.rabbitmq.stream.Producer in project rabbitmq-stream-java-client by rabbitmq.
the class StreamConsumerTest method autoTrackingShouldStorePeriodicallyAndAfterInactivity.
@Test
void autoTrackingShouldStorePeriodicallyAndAfterInactivity() throws Exception {
AtomicInteger messageCount = new AtomicInteger(0);
int storeEvery = 10_000;
String reference = "ref-1";
AtomicLong lastReceivedOffset = new AtomicLong(0);
environment.consumerBuilder().name(reference).stream(stream).offset(OffsetSpecification.first()).messageHandler((context, message) -> {
lastReceivedOffset.set(context.offset());
messageCount.incrementAndGet();
}).autoTrackingStrategy().flushInterval(Duration.ofSeconds(1).plusMillis(100)).messageCountBeforeStorage(storeEvery).builder().build();
Producer producer = environment.producerBuilder().stream(stream).build();
IntStream.range(0, storeEvery * 2).forEach(i -> producer.send(producer.messageBuilder().addData("".getBytes()).build(), confirmationStatus -> {
}));
waitAtMost(5, () -> messageCount.get() == storeEvery * 2);
Client client = cf.get();
waitAtMost(5, () -> client.queryOffset(reference, stream).getOffset() == lastReceivedOffset.get());
int extraMessages = storeEvery / 10;
IntStream.range(0, extraMessages).forEach(i -> producer.send(producer.messageBuilder().addData("".getBytes()).build(), confirmationStatus -> {
}));
waitAtMost(5, () -> messageCount.get() == storeEvery * 2 + extraMessages);
waitAtMost(5, () -> client.queryOffset(reference, stream).getOffset() == lastReceivedOffset.get());
}
use of com.rabbitmq.stream.Producer in project rabbitmq-stream-java-client by rabbitmq.
the class StreamConsumerTest method externalOffsetTrackingWithSubscriptionListener.
@Test
@DisabledIfRabbitMqCtlNotSet
void externalOffsetTrackingWithSubscriptionListener() throws Exception {
AtomicInteger subscriptionListenerCallCount = new AtomicInteger(0);
AtomicInteger receivedMessages = new AtomicInteger(0);
AtomicLong offsetTracking = new AtomicLong(0);
AtomicBoolean started = new AtomicBoolean(false);
environment.consumerBuilder().stream(stream).offset(OffsetSpecification.first()).subscriptionListener(subscriptionContext -> {
subscriptionListenerCallCount.incrementAndGet();
OffsetSpecification offsetSpecification = started.get() ? OffsetSpecification.offset(offsetTracking.get() + 1) : subscriptionContext.offsetSpecification();
subscriptionContext.offsetSpecification(offsetSpecification);
}).messageHandler((context, message) -> {
receivedMessages.incrementAndGet();
offsetTracking.set(context.offset());
started.set(true);
}).build();
int messageCount = 10_000;
Producer producer = environment.producerBuilder().stream(stream).build();
Runnable publish = () -> IntStream.range(0, messageCount).forEach(i -> producer.send(producer.messageBuilder().addData("".getBytes()).build(), confirmationStatus -> {
}));
publish.run();
waitAtMost(5, () -> receivedMessages.get() == messageCount);
assertThat(offsetTracking.get()).isGreaterThanOrEqualTo(messageCount - 1);
Host.killConnection("rabbitmq-stream-consumer-0");
waitAtMost(recoveryInitialDelay.multipliedBy(2), () -> subscriptionListenerCallCount.get() == 2);
publish.run();
waitAtMost(5, () -> receivedMessages.get() == messageCount * 2);
assertThat(offsetTracking.get()).isGreaterThanOrEqualTo(messageCount * 2 - 1);
}
use of com.rabbitmq.stream.Producer in project rabbitmq-stream-java-client by rabbitmq.
the class SuperStreamProducerTest method messageIsNackedIfNoRouteFound.
@Test
void messageIsNackedIfNoRouteFound() throws Exception {
routingKeys = new String[] { "amer", "emea", "apac" };
declareSuperStreamTopology(connection, superStream, routingKeys);
Producer producer = environment.producerBuilder().stream(superStream).routing(message -> message.getApplicationProperties().get("region").toString()).key().producerBuilder().build();
AtomicBoolean confirmed = new AtomicBoolean(true);
AtomicInteger code = new AtomicInteger();
CountDownLatch publishLatch = new CountDownLatch(1);
producer.send(producer.messageBuilder().applicationProperties().entry("region", "atlantis").messageBuilder().build(), confirmationStatus -> {
confirmed.set(confirmationStatus.isConfirmed());
code.set(confirmationStatus.getCode());
publishLatch.countDown();
});
assertThat(latchAssert(publishLatch)).completes(5);
assertThat(confirmed).isFalse();
assertThat(code).hasValue(Constants.CODE_NO_ROUTE_FOUND);
}
use of com.rabbitmq.stream.Producer in project rabbitmq-stream-java-client by rabbitmq.
the class SuperStreamTest method allMessagesSentWithRoutingKeyRoutingShouldBeThenConsumed.
@Test
void allMessagesSentWithRoutingKeyRoutingShouldBeThenConsumed() throws Exception {
int messageCount = 10_000 * partitions;
routingKeys = new String[] { "amer", "emea", "apac" };
declareSuperStreamTopology(connection, superStream, routingKeys);
Producer producer = environment.producerBuilder().stream(superStream).routing(message -> message.getApplicationProperties().get("region").toString()).key().producerBuilder().build();
CountDownLatch publishLatch = new CountDownLatch(messageCount);
IntStream.range(0, messageCount).forEach(i -> producer.send(producer.messageBuilder().applicationProperties().entry("region", routingKeys[i % routingKeys.length]).messageBuilder().build(), confirmationStatus -> publishLatch.countDown()));
assertThat(latchAssert(publishLatch)).completes(5);
AtomicInteger totalCount = new AtomicInteger(0);
CountDownLatch consumeLatch = new CountDownLatch(messageCount);
environment.consumerBuilder().superStream(superStream).offset(OffsetSpecification.first()).messageHandler((context, message) -> {
totalCount.incrementAndGet();
consumeLatch.countDown();
}).build();
latchAssert(consumeLatch).completes();
assertThat(totalCount.get()).isEqualTo(messageCount);
}
Aggregations