use of com.rabbitmq.stream.Producer in project rabbitmq-stream-java-client by rabbitmq.
the class StreamProducerTest method shouldRecoverAfterConnectionIsKilled.
@ParameterizedTest
@ValueSource(ints = { 1, 10 })
@TestUtils.DisabledIfRabbitMqCtlNotSet
void shouldRecoverAfterConnectionIsKilled(int subEntrySize) throws Exception {
Producer producer = environment.producerBuilder().subEntrySize(subEntrySize).stream(stream).build();
AtomicInteger published = new AtomicInteger(0);
AtomicInteger confirmed = new AtomicInteger(0);
AtomicInteger errored = new AtomicInteger(0);
AtomicBoolean canPublish = new AtomicBoolean(true);
Thread publishThread = new Thread(() -> {
ConfirmationHandler confirmationHandler = confirmationStatus -> {
if (confirmationStatus.isConfirmed()) {
confirmed.incrementAndGet();
} else {
errored.incrementAndGet();
}
};
while (true) {
try {
if (canPublish.get()) {
producer.send(producer.messageBuilder().addData("".getBytes(StandardCharsets.UTF_8)).build(), confirmationHandler);
published.incrementAndGet();
} else {
Thread.sleep(500);
}
} catch (InterruptedException | StreamException e) {
// OK
}
}
});
publishThread.start();
Thread.sleep(1000L);
Host.killConnection("rabbitmq-stream-producer-0");
waitAtMost(10, () -> ((StreamProducer) producer).status() == Status.NOT_AVAILABLE);
canPublish.set(false);
assertThat(confirmed.get()).isPositive();
waitAtMost(5, () -> confirmed.get() + errored.get() == published.get(), () -> String.format("confirmed %d / errored %d / published %d, %d + %d = %d != %d, difference %d", confirmed.get(), errored.get(), published.get(), confirmed.get(), errored.get(), (confirmed.get() + errored.get()), published.get(), (published.get() - (confirmed.get() + errored.get()))));
assertThat(confirmed.get() + errored.get()).isEqualTo(published.get());
waitAtMost(10, () -> ((StreamProducer) producer).status() == StreamProducer.Status.RUNNING);
int confirmedAfterUnavailability = confirmed.get();
int errorAfterUnavailability = errored.get();
canPublish.set(true);
waitAtMost(10, () -> confirmed.get() > confirmedAfterUnavailability * 2);
assertThat(errored.get()).isEqualTo(errorAfterUnavailability);
canPublish.set(false);
publishThread.interrupt();
waitAtMost(10, () -> confirmed.get() + errored.get() == published.get());
CountDownLatch consumeLatch = new CountDownLatch(confirmed.get());
environment.consumerBuilder().stream(stream).offset(OffsetSpecification.first()).messageHandler((offset, message) -> {
consumeLatch.countDown();
}).build();
assertThat(consumeLatch.await(10, TimeUnit.SECONDS)).isTrue();
}
use of com.rabbitmq.stream.Producer in project rabbitmq-stream-java-client by rabbitmq.
the class StreamProducerTest method send.
@Test
void send() throws Exception {
int batchSize = 10;
// don't want a multiple of batch size
int messageCount = 10 * batchSize + 1;
CountDownLatch publishLatch = new CountDownLatch(messageCount);
Producer producer = environment.producerBuilder().stream(stream).batchSize(batchSize).build();
AtomicLong count = new AtomicLong(0);
AtomicLong sequence = new AtomicLong(0);
Set<Long> idsSent = ConcurrentHashMap.newKeySet(messageCount);
Set<Long> idsConfirmed = ConcurrentHashMap.newKeySet(messageCount);
IntStream.range(0, messageCount).forEach(i -> {
long id = sequence.getAndIncrement();
idsSent.add(id);
producer.send(producer.messageBuilder().properties().messageId(id).messageBuilder().addData("".getBytes()).build(), confirmationStatus -> {
idsConfirmed.add(confirmationStatus.getMessage().getProperties().getMessageIdAsLong());
count.incrementAndGet();
publishLatch.countDown();
});
});
boolean completed = publishLatch.await(10, TimeUnit.SECONDS);
assertThat(idsSent).hasSameSizeAs(idsConfirmed);
idsSent.forEach(idSent -> assertThat(idsConfirmed).contains(idSent));
assertThat(completed).isTrue();
ProducerInfo info = MonitoringTestUtils.extract(producer);
assertThat(info.getId()).isGreaterThanOrEqualTo(0);
assertThat(info.getStream()).isEqualTo(stream);
assertThat(info.getPublishingClient()).contains(" -> localhost:5552");
}
use of com.rabbitmq.stream.Producer in project rabbitmq-stream-java-client by rabbitmq.
the class SuperStreamProducerTest method getLastPublishingIdShouldReturnLowestValue.
@Test
void getLastPublishingIdShouldReturnLowestValue() throws Exception {
int messageCount = 10_000;
declareSuperStreamTopology(connection, superStream, partitions);
String producerName = "super-stream-application";
Producer producer = environment.producerBuilder().name(producerName).stream(superStream).routing(message -> message.getProperties().getMessageIdAsString()).producerBuilder().build();
CountDownLatch publishLatch = new CountDownLatch(messageCount);
IntStream.range(0, messageCount).forEach(i -> producer.send(producer.messageBuilder().publishingId(i).properties().messageId(UUID.randomUUID().toString()).messageBuilder().build(), confirmationStatus -> publishLatch.countDown()));
assertThat(latchAssert(publishLatch)).completes(5);
long lastPublishingId = producer.getLastPublishingId();
assertThat(lastPublishingId).isNotZero();
Client client = cf.get();
IntStream.range(0, partitions).mapToObj(i -> superStream + "-" + i).forEach(stream -> {
long publishingId = client.queryPublisherSequence(producerName, stream);
assertThat(publishingId).isGreaterThanOrEqualTo(lastPublishingId);
});
Map<String, AtomicLong> counts = new ConcurrentHashMap<>();
AtomicLong totalCount = new AtomicLong(0);
IntStream.range(0, partitions).mapToObj(i -> superStream + "-" + i).forEach(stream -> {
AtomicLong streamCount = new AtomicLong(0);
counts.put(stream, streamCount);
environment.consumerBuilder().stream(stream).offset(OffsetSpecification.first()).messageHandler((context, message) -> {
streamCount.incrementAndGet();
totalCount.incrementAndGet();
}).build();
});
waitAtMost(10, () -> totalCount.get() == messageCount);
assertThat(counts.values().stream().map(AtomicLong::get)).hasSize(partitions).doesNotContain(0L);
assertThat(counts.values().stream().map(AtomicLong::get).reduce(0L, Long::sum)).isEqualTo(messageCount);
}
use of com.rabbitmq.stream.Producer 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();
}
use of com.rabbitmq.stream.Producer in project rabbitmq-stream-java-client by rabbitmq.
the class StreamConsumerTest method consumerShouldBeClosedWhenStreamGetsDeleted.
@Test
void consumerShouldBeClosedWhenStreamGetsDeleted(TestInfo info) throws Exception {
String s = streamName(info);
environment.streamCreator().stream(s).create();
int messageCount = 10_000;
CountDownLatch publishLatch = new CountDownLatch(messageCount);
Producer producer = environment.producerBuilder().stream(s).build();
IntStream.range(0, messageCount).forEach(i -> producer.send(producer.messageBuilder().addData("".getBytes()).build(), confirmationStatus -> publishLatch.countDown()));
assertThat(publishLatch.await(10, TimeUnit.SECONDS)).isTrue();
CountDownLatch consumeLatch = new CountDownLatch(messageCount);
StreamConsumer consumer = (StreamConsumer) environment.consumerBuilder().stream(s).offset(OffsetSpecification.first()).messageHandler((offset, message) -> consumeLatch.countDown()).build();
assertThat(consumeLatch.await(10, TimeUnit.SECONDS)).isTrue();
assertThat(consumer.isOpen()).isTrue();
environment.deleteStream(s);
TestUtils.waitAtMost(10, () -> !consumer.isOpen());
assertThat(consumer.isOpen()).isFalse();
}
Aggregations