Search in sources :

Example 1 with StreamException

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);
    }
}
Also used : IntStream(java.util.stream.IntStream) BeforeEach(org.junit.jupiter.api.BeforeEach) SortedSet(java.util.SortedSet) Assertions.assertThat(org.assertj.core.api.Assertions.assertThat) IntConsumer(java.util.function.IntConsumer) TestUtils.latchAssert(com.rabbitmq.stream.impl.TestUtils.latchAssert) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) AtomicReference(java.util.concurrent.atomic.AtomicReference) TestUtils.streamName(com.rabbitmq.stream.impl.TestUtils.streamName) TreeSet(java.util.TreeSet) ConfirmationHandler(com.rabbitmq.stream.ConfirmationHandler) StreamException(com.rabbitmq.stream.StreamException) ExtendWith(org.junit.jupiter.api.extension.ExtendWith) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ProducerInfo(com.rabbitmq.stream.impl.MonitoringTestUtils.ProducerInfo) Duration(java.time.Duration) Map(java.util.Map) ExecutorService(java.util.concurrent.ExecutorService) Host(com.rabbitmq.stream.Host) ValueSource(org.junit.jupiter.params.provider.ValueSource) TestUtils.waitAtMost(com.rabbitmq.stream.impl.TestUtils.waitAtMost) Status(com.rabbitmq.stream.impl.StreamProducer.Status) EventLoopGroup(io.netty.channel.EventLoopGroup) Environment(com.rabbitmq.stream.Environment) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) UUID(java.util.UUID) Compression(com.rabbitmq.stream.compression.Compression) Producer(com.rabbitmq.stream.Producer) Collectors(java.util.stream.Collectors) EnvironmentBuilder(com.rabbitmq.stream.EnvironmentBuilder) StandardCharsets(java.nio.charset.StandardCharsets) Executors(java.util.concurrent.Executors) TestInfo(org.junit.jupiter.api.TestInfo) BackOffDelayPolicy(com.rabbitmq.stream.BackOffDelayPolicy) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) Test(org.junit.jupiter.api.Test) CountDownLatch(java.util.concurrent.CountDownLatch) AtomicLong(java.util.concurrent.atomic.AtomicLong) Level(ch.qos.logback.classic.Level) List(java.util.List) AfterEach(org.junit.jupiter.api.AfterEach) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) ConfirmationStatus(com.rabbitmq.stream.ConfirmationStatus) Constants(com.rabbitmq.stream.Constants) OffsetSpecification(com.rabbitmq.stream.OffsetSpecification) TestUtils.localhost(com.rabbitmq.stream.impl.TestUtils.localhost) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) ConfirmationHandler(com.rabbitmq.stream.ConfirmationHandler) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Level(ch.qos.logback.classic.Level) StreamException(com.rabbitmq.stream.StreamException) ValueSource(org.junit.jupiter.params.provider.ValueSource) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 2 with StreamException

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();
}
Also used : IntStream(java.util.stream.IntStream) BeforeEach(org.junit.jupiter.api.BeforeEach) SortedSet(java.util.SortedSet) Assertions.assertThat(org.assertj.core.api.Assertions.assertThat) IntConsumer(java.util.function.IntConsumer) TestUtils.latchAssert(com.rabbitmq.stream.impl.TestUtils.latchAssert) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) AtomicReference(java.util.concurrent.atomic.AtomicReference) TestUtils.streamName(com.rabbitmq.stream.impl.TestUtils.streamName) TreeSet(java.util.TreeSet) ConfirmationHandler(com.rabbitmq.stream.ConfirmationHandler) StreamException(com.rabbitmq.stream.StreamException) ExtendWith(org.junit.jupiter.api.extension.ExtendWith) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ProducerInfo(com.rabbitmq.stream.impl.MonitoringTestUtils.ProducerInfo) Duration(java.time.Duration) Map(java.util.Map) ExecutorService(java.util.concurrent.ExecutorService) Host(com.rabbitmq.stream.Host) ValueSource(org.junit.jupiter.params.provider.ValueSource) TestUtils.waitAtMost(com.rabbitmq.stream.impl.TestUtils.waitAtMost) Status(com.rabbitmq.stream.impl.StreamProducer.Status) EventLoopGroup(io.netty.channel.EventLoopGroup) Environment(com.rabbitmq.stream.Environment) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) UUID(java.util.UUID) Compression(com.rabbitmq.stream.compression.Compression) Producer(com.rabbitmq.stream.Producer) Collectors(java.util.stream.Collectors) EnvironmentBuilder(com.rabbitmq.stream.EnvironmentBuilder) StandardCharsets(java.nio.charset.StandardCharsets) Executors(java.util.concurrent.Executors) TestInfo(org.junit.jupiter.api.TestInfo) BackOffDelayPolicy(com.rabbitmq.stream.BackOffDelayPolicy) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) Test(org.junit.jupiter.api.Test) CountDownLatch(java.util.concurrent.CountDownLatch) AtomicLong(java.util.concurrent.atomic.AtomicLong) Level(ch.qos.logback.classic.Level) List(java.util.List) AfterEach(org.junit.jupiter.api.AfterEach) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) ConfirmationStatus(com.rabbitmq.stream.ConfirmationStatus) Constants(com.rabbitmq.stream.Constants) OffsetSpecification(com.rabbitmq.stream.OffsetSpecification) TestUtils.localhost(com.rabbitmq.stream.impl.TestUtils.localhost) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Producer(com.rabbitmq.stream.Producer) ConfirmationHandler(com.rabbitmq.stream.ConfirmationHandler) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) CountDownLatch(java.util.concurrent.CountDownLatch) StreamException(com.rabbitmq.stream.StreamException) ValueSource(org.junit.jupiter.params.provider.ValueSource) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 3 with StreamException

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();
}
Also used : AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Duration(java.time.Duration) CountDownLatch(java.util.concurrent.CountDownLatch) StreamException(com.rabbitmq.stream.StreamException) ValueSource(org.junit.jupiter.params.provider.ValueSource) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 4 with StreamException

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);
    }
}
Also used : CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) List(java.util.List) ByteBuf(io.netty.buffer.ByteBuf) StreamException(com.rabbitmq.stream.StreamException)

Example 5 with StreamException

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);
    }
}
Also used : ByteBuf(io.netty.buffer.ByteBuf) StreamException(com.rabbitmq.stream.StreamException)

Aggregations

StreamException (com.rabbitmq.stream.StreamException)29 ByteBuf (io.netty.buffer.ByteBuf)17 Map (java.util.Map)9 List (java.util.List)7 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)7 CountDownLatch (java.util.concurrent.CountDownLatch)6 Duration (java.time.Duration)5 ArrayList (java.util.ArrayList)5 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)5 Constants (com.rabbitmq.stream.Constants)4 OffsetSpecification (com.rabbitmq.stream.OffsetSpecification)4 HashMap (java.util.HashMap)4 CopyOnWriteArrayList (java.util.concurrent.CopyOnWriteArrayList)4 ExecutorService (java.util.concurrent.ExecutorService)4 Executors (java.util.concurrent.Executors)4 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)4 BackOffDelayPolicy (com.rabbitmq.stream.BackOffDelayPolicy)3 ConfirmationHandler (com.rabbitmq.stream.ConfirmationHandler)3 ConfirmationStatus (com.rabbitmq.stream.ConfirmationStatus)3 Environment (com.rabbitmq.stream.Environment)3