use of com.rabbitmq.stream.StreamException in project rabbitmq-stream-java-client by rabbitmq.
the class StreamProducerTest method producerShouldBeClosedWhenStreamIsDeleted.
@ParameterizedTest
@ValueSource(ints = { 1, 7 })
void producerShouldBeClosedWhenStreamIsDeleted(int subEntrySize, TestInfo info) throws Exception {
Level initialLogLevel = TestUtils.newLoggerLevel(ProducersCoordinator.class, Level.DEBUG);
try {
String s = streamName(info);
environment.streamCreator().stream(s).create();
StreamProducer producer = (StreamProducer) environment.producerBuilder().subEntrySize(subEntrySize).stream(s).build();
AtomicInteger published = new AtomicInteger(0);
AtomicInteger confirmed = new AtomicInteger(0);
AtomicInteger errored = new AtomicInteger(0);
Set<Number> errorCodes = ConcurrentHashMap.newKeySet();
AtomicBoolean continuePublishing = new AtomicBoolean(true);
Thread publishThread = new Thread(() -> {
ConfirmationHandler confirmationHandler = confirmationStatus -> {
if (confirmationStatus.isConfirmed()) {
confirmed.incrementAndGet();
} else {
errored.incrementAndGet();
errorCodes.add(confirmationStatus.getCode());
}
};
while (continuePublishing.get()) {
try {
producer.send(producer.messageBuilder().addData("".getBytes(StandardCharsets.UTF_8)).build(), confirmationHandler);
published.incrementAndGet();
} catch (StreamException e) {
// OK
}
}
});
publishThread.start();
Thread.sleep(1000L);
assertThat(producer.isOpen()).isTrue();
environment.deleteStream(s);
waitAtMost(() -> !producer.isOpen());
continuePublishing.set(false);
waitAtMost(() -> !errorCodes.isEmpty(), () -> "The producer should have received negative publish confirms");
} finally {
TestUtils.newLoggerLevel(ProducersCoordinator.class, initialLogLevel);
}
}
use of com.rabbitmq.stream.StreamException 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.StreamException in project rabbitmq-stream-java-client by rabbitmq.
the class StreamProducerUnitTest method enqueueTimeoutSendingShouldBlockWhenEnqueueTimeoutIsZero.
@ParameterizedTest
@ValueSource(ints = { 1, 7 })
void enqueueTimeoutSendingShouldBlockWhenEnqueueTimeoutIsZero(int subEntrySize) throws Exception {
Duration enqueueTimeout = Duration.ZERO;
StreamProducer producer = new StreamProducer(null, "stream", subEntrySize, 10, Compression.NONE, Duration.ZERO, 2, Duration.ofMinutes(1), enqueueTimeout, env);
AtomicBoolean confirmCalled = new AtomicBoolean(false);
CountDownLatch sendLatch = new CountDownLatch(1);
CountDownLatch interruptedLatch = new CountDownLatch(1);
Thread sendingThread = new Thread(() -> {
try {
producer.send(producer.messageBuilder().addData("".getBytes()).build(), status -> confirmCalled.set(true));
producer.send(producer.messageBuilder().addData("".getBytes()).build(), status -> confirmCalled.set(true));
sendLatch.countDown();
producer.send(producer.messageBuilder().addData("".getBytes()).build(), status -> confirmCalled.set(true));
} catch (StreamException e) {
if (e.getCause() instanceof InterruptedException) {
interruptedLatch.countDown();
}
}
});
sendingThread.start();
assertThat(sendLatch.await(5, TimeUnit.SECONDS)).isTrue();
sendingThread.interrupt();
assertThat(interruptedLatch.await(5, TimeUnit.SECONDS)).isTrue();
assertThat(confirmCalled).isFalse();
}
use of com.rabbitmq.stream.StreamException in project rabbitmq-stream-java-client by rabbitmq.
the class Client method getSaslMechanisms.
private List<String> getSaslMechanisms() {
int length = 2 + 2 + 4;
int correlationId = correlationSequence.incrementAndGet();
try {
ByteBuf bb = allocateNoCheck(length + 4);
bb.writeInt(length);
bb.writeShort(encodeRequestCode(COMMAND_SASL_HANDSHAKE));
bb.writeShort(VERSION_1);
bb.writeInt(correlationId);
OutstandingRequest<List<String>> request = new OutstandingRequest<>(this.rpcTimeout);
outstandingRequests.put(correlationId, request);
channel.writeAndFlush(bb);
request.block();
return request.response.get();
} catch (RuntimeException e) {
outstandingRequests.remove(correlationId);
throw new StreamException(e);
}
}
use of com.rabbitmq.stream.StreamException in project rabbitmq-stream-java-client by rabbitmq.
the class Client method queryOffset.
public QueryOffsetResponse queryOffset(String reference, String stream) {
if (reference == null || reference.isEmpty() || reference.length() > 256) {
throw new IllegalArgumentException("Reference must a non-empty string of less than 256 characters");
}
if (stream == null || stream.isEmpty()) {
throw new IllegalArgumentException("Stream cannot be null or empty");
}
int length = 2 + 2 + 4 + 2 + reference.length() + 2 + stream.length();
int correlationId = correlationSequence.getAndIncrement();
try {
ByteBuf bb = allocate(length + 4);
bb.writeInt(length);
bb.writeShort(encodeRequestCode(COMMAND_QUERY_OFFSET));
bb.writeShort(VERSION_1);
bb.writeInt(correlationId);
bb.writeShort(reference.length());
bb.writeBytes(reference.getBytes(StandardCharsets.UTF_8));
bb.writeShort(stream.length());
bb.writeBytes(stream.getBytes(StandardCharsets.UTF_8));
OutstandingRequest<QueryOffsetResponse> request = new OutstandingRequest<>(this.rpcTimeout);
outstandingRequests.put(correlationId, request);
channel.writeAndFlush(bb);
request.block();
QueryOffsetResponse response = request.response.get();
return response;
} catch (RuntimeException e) {
outstandingRequests.remove(correlationId);
throw new StreamException(e);
}
}
Aggregations