Search in sources :

Example 1 with Producer

use of com.rabbitmq.stream.Producer in project rabbitmq-stream-java-client by rabbitmq.

the class StreamEnvironmentTest method environmentPublishersConsumersShouldCloseSuccessfullyWhenBrokerIsDown.

@Test
@TestUtils.DisabledIfRabbitMqCtlNotSet
void environmentPublishersConsumersShouldCloseSuccessfullyWhenBrokerIsDown() throws Exception {
    Environment environment = environmentBuilder.recoveryBackOffDelayPolicy(BackOffDelayPolicy.fixed(Duration.ofSeconds(10))).build();
    CountDownLatch consumeLatch = new CountDownLatch(2);
    Consumer consumer = environment.consumerBuilder().stream(stream).messageHandler((context, message) -> consumeLatch.countDown()).build();
    // will be closed by the environment
    environment.consumerBuilder().stream(stream).messageHandler((context, message) -> consumeLatch.countDown()).build();
    Producer producer = environment.producerBuilder().stream(stream).build();
    // will be closed by the environment
    environment.producerBuilder().stream(stream).build();
    producer.send(producer.messageBuilder().addData("".getBytes(StandardCharsets.UTF_8)).build(), confirmationStatus -> {
    });
    latchAssert(consumeLatch).completes();
    try {
        Host.rabbitmqctl("stop_app");
        producer.close();
        consumer.close();
        environment.close();
    } finally {
        Host.rabbitmqctl("start_app");
    }
    waitAtMost(30, () -> {
        Client client = cf.get();
        Map<String, StreamMetadata> metadata = client.metadata(stream);
        return metadata.containsKey(stream) && metadata.get(stream).isResponseOk();
    });
}
Also used : BeforeEach(org.junit.jupiter.api.BeforeEach) SNIHostName(javax.net.ssl.SNIHostName) Message(com.rabbitmq.stream.Message) Assertions.assertThat(org.assertj.core.api.Assertions.assertThat) Random(java.util.Random) TestUtils.streamName(com.rabbitmq.stream.impl.TestUtils.streamName) AuthenticationFailureException(com.rabbitmq.stream.AuthenticationFailureException) AfterAll(org.junit.jupiter.api.AfterAll) StreamException(com.rabbitmq.stream.StreamException) ExtendWith(org.junit.jupiter.api.extension.ExtendWith) BeforeAll(org.junit.jupiter.api.BeforeAll) ConsumerBuilder(com.rabbitmq.stream.ConsumerBuilder) Duration(java.time.Duration) Map(java.util.Map) Host(com.rabbitmq.stream.Host) TestUtils.waitAtMost(com.rabbitmq.stream.impl.TestUtils.waitAtMost) Collection(java.util.Collection) UUID(java.util.UUID) Collectors(java.util.stream.Collectors) NioEventLoopGroup(io.netty.channel.nio.NioEventLoopGroup) StandardCharsets(java.nio.charset.StandardCharsets) TestInfo(org.junit.jupiter.api.TestInfo) BackOffDelayPolicy(com.rabbitmq.stream.BackOffDelayPolicy) Test(org.junit.jupiter.api.Test) CountDownLatch(java.util.concurrent.CountDownLatch) List(java.util.List) StreamCreator(com.rabbitmq.stream.StreamCreator) SslHandler(io.netty.handler.ssl.SslHandler) ProducerBuilder(com.rabbitmq.stream.ProducerBuilder) Constants(com.rabbitmq.stream.Constants) OffsetSpecification(com.rabbitmq.stream.OffsetSpecification) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) IntStream(java.util.stream.IntStream) SSLParameters(javax.net.ssl.SSLParameters) StreamMetadata(com.rabbitmq.stream.impl.Client.StreamMetadata) TestUtils.latchAssert(com.rabbitmq.stream.impl.TestUtils.latchAssert) Address(com.rabbitmq.stream.Address) ConfirmationHandler(com.rabbitmq.stream.ConfirmationHandler) Assertions.assertThatThrownBy(org.assertj.core.api.Assertions.assertThatThrownBy) EnvironmentInfo(com.rabbitmq.stream.impl.MonitoringTestUtils.EnvironmentInfo) ConnectException(java.net.ConnectException) ChannelCustomizer(com.rabbitmq.stream.ChannelCustomizer) ValueSource(org.junit.jupiter.params.provider.ValueSource) EventLoopGroup(io.netty.channel.EventLoopGroup) Environment(com.rabbitmq.stream.Environment) Consumer(com.rabbitmq.stream.Consumer) Producer(com.rabbitmq.stream.Producer) EnvironmentBuilder(com.rabbitmq.stream.EnvironmentBuilder) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) DisabledIfTlsNotEnabled(com.rabbitmq.stream.impl.TestUtils.DisabledIfTlsNotEnabled) Collections(java.util.Collections) SECONDS(java.util.concurrent.TimeUnit.SECONDS) TestUtils.localhost(com.rabbitmq.stream.impl.TestUtils.localhost) TestUtils.localhostTls(com.rabbitmq.stream.impl.TestUtils.localhostTls) StreamMetadata(com.rabbitmq.stream.impl.Client.StreamMetadata) Consumer(com.rabbitmq.stream.Consumer) Producer(com.rabbitmq.stream.Producer) Environment(com.rabbitmq.stream.Environment) CountDownLatch(java.util.concurrent.CountDownLatch) Test(org.junit.jupiter.api.Test) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 2 with Producer

use of com.rabbitmq.stream.Producer in project rabbitmq-stream-java-client by rabbitmq.

the class StreamEnvironmentTest method producersAndConsumersShouldBeClosedWhenEnvironmentIsClosed.

@ParameterizedTest
@ValueSource(booleans = { false, true })
void producersAndConsumersShouldBeClosedWhenEnvironmentIsClosed(boolean lazyInit) {
    Environment environment = environmentBuilder.lazyInitialization(lazyInit).build();
    Collection<Producer> producers = IntStream.range(0, 2).mapToObj(i -> environment.producerBuilder().stream(stream).build()).collect(Collectors.toList());
    Collection<Consumer> consumers = IntStream.range(0, 2).mapToObj(i -> environment.consumerBuilder().stream(stream).name(UUID.randomUUID().toString()).messageHandler((offset, message) -> {
    }).build()).collect(Collectors.toList());
    producers.forEach(producer -> assertThat(((StreamProducer) producer).isOpen()).isTrue());
    consumers.forEach(consumer -> assertThat(((StreamConsumer) consumer).isOpen()).isTrue());
    EnvironmentInfo environmentInfo = MonitoringTestUtils.extract(environment);
    assertThat(environmentInfo.getLocator()).isNotNull();
    assertThat(environmentInfo.getProducers()).hasSize(1).element(0).extracting(pool -> pool.getClients()).asList().hasSize(1);
    assertThat(environmentInfo.getProducers().get(0).getClients().get(0).getProducerCount()).isEqualTo(2);
    assertThat(environmentInfo.getProducers().get(0).getClients().get(0).getTrackingConsumerCount()).isEqualTo(2);
    assertThat(environmentInfo.getConsumers()).hasSize(1).element(0).extracting(pool -> pool.getClients()).asList().hasSize(1);
    assertThat(environmentInfo.getConsumers().get(0).getClients().get(0).getConsumerCount()).isEqualTo(2);
    environment.close();
    producers.forEach(producer -> assertThat(((StreamProducer) producer).isOpen()).isFalse());
    consumers.forEach(consumer -> assertThat(((StreamConsumer) consumer).isOpen()).isFalse());
    environmentInfo = MonitoringTestUtils.extract(environment);
    assertThat(environmentInfo.getLocator()).isNull();
    assertThat(environmentInfo.getProducers()).isEmpty();
    assertThat(environmentInfo.getConsumers()).isEmpty();
}
Also used : BeforeEach(org.junit.jupiter.api.BeforeEach) SNIHostName(javax.net.ssl.SNIHostName) Message(com.rabbitmq.stream.Message) Assertions.assertThat(org.assertj.core.api.Assertions.assertThat) Random(java.util.Random) TestUtils.streamName(com.rabbitmq.stream.impl.TestUtils.streamName) AuthenticationFailureException(com.rabbitmq.stream.AuthenticationFailureException) AfterAll(org.junit.jupiter.api.AfterAll) StreamException(com.rabbitmq.stream.StreamException) ExtendWith(org.junit.jupiter.api.extension.ExtendWith) BeforeAll(org.junit.jupiter.api.BeforeAll) ConsumerBuilder(com.rabbitmq.stream.ConsumerBuilder) Duration(java.time.Duration) Map(java.util.Map) Host(com.rabbitmq.stream.Host) TestUtils.waitAtMost(com.rabbitmq.stream.impl.TestUtils.waitAtMost) Collection(java.util.Collection) UUID(java.util.UUID) Collectors(java.util.stream.Collectors) NioEventLoopGroup(io.netty.channel.nio.NioEventLoopGroup) StandardCharsets(java.nio.charset.StandardCharsets) TestInfo(org.junit.jupiter.api.TestInfo) BackOffDelayPolicy(com.rabbitmq.stream.BackOffDelayPolicy) Test(org.junit.jupiter.api.Test) CountDownLatch(java.util.concurrent.CountDownLatch) List(java.util.List) StreamCreator(com.rabbitmq.stream.StreamCreator) SslHandler(io.netty.handler.ssl.SslHandler) ProducerBuilder(com.rabbitmq.stream.ProducerBuilder) Constants(com.rabbitmq.stream.Constants) OffsetSpecification(com.rabbitmq.stream.OffsetSpecification) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) IntStream(java.util.stream.IntStream) SSLParameters(javax.net.ssl.SSLParameters) StreamMetadata(com.rabbitmq.stream.impl.Client.StreamMetadata) TestUtils.latchAssert(com.rabbitmq.stream.impl.TestUtils.latchAssert) Address(com.rabbitmq.stream.Address) ConfirmationHandler(com.rabbitmq.stream.ConfirmationHandler) Assertions.assertThatThrownBy(org.assertj.core.api.Assertions.assertThatThrownBy) EnvironmentInfo(com.rabbitmq.stream.impl.MonitoringTestUtils.EnvironmentInfo) ConnectException(java.net.ConnectException) ChannelCustomizer(com.rabbitmq.stream.ChannelCustomizer) ValueSource(org.junit.jupiter.params.provider.ValueSource) EventLoopGroup(io.netty.channel.EventLoopGroup) Environment(com.rabbitmq.stream.Environment) Consumer(com.rabbitmq.stream.Consumer) Producer(com.rabbitmq.stream.Producer) EnvironmentBuilder(com.rabbitmq.stream.EnvironmentBuilder) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest) DisabledIfTlsNotEnabled(com.rabbitmq.stream.impl.TestUtils.DisabledIfTlsNotEnabled) Collections(java.util.Collections) SECONDS(java.util.concurrent.TimeUnit.SECONDS) TestUtils.localhost(com.rabbitmq.stream.impl.TestUtils.localhost) TestUtils.localhostTls(com.rabbitmq.stream.impl.TestUtils.localhostTls) Producer(com.rabbitmq.stream.Producer) Consumer(com.rabbitmq.stream.Consumer) EnvironmentInfo(com.rabbitmq.stream.impl.MonitoringTestUtils.EnvironmentInfo) Environment(com.rabbitmq.stream.Environment) ValueSource(org.junit.jupiter.params.provider.ValueSource) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 3 with Producer

use of com.rabbitmq.stream.Producer in project rabbitmq-stream-java-client by rabbitmq.

the class StreamEnvironmentTest method locatorShouldReconnectIfConnectionIsLost.

@Test
@TestUtils.DisabledIfRabbitMqCtlNotSet
void locatorShouldReconnectIfConnectionIsLost(TestInfo info) throws Exception {
    try (Environment environment = environmentBuilder.recoveryBackOffDelayPolicy(BackOffDelayPolicy.fixed(Duration.ofSeconds(1))).build()) {
        String s = streamName(info);
        environment.streamCreator().stream(s).create();
        environment.deleteStream(s);
        Host.killConnection("rabbitmq-stream-locator-0");
        environment.streamCreator().stream(s).create();
        try {
            Producer producer = environment.producerBuilder().stream(s).build();
            Consumer consumer = environment.consumerBuilder().stream(s).build();
            producer.close();
            consumer.close();
        } finally {
            environment.deleteStream(s);
        }
    }
}
Also used : Producer(com.rabbitmq.stream.Producer) Consumer(com.rabbitmq.stream.Consumer) Environment(com.rabbitmq.stream.Environment) Test(org.junit.jupiter.api.Test) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Example 4 with Producer

use of com.rabbitmq.stream.Producer 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 5 with Producer

use of com.rabbitmq.stream.Producer in project rabbitmq-stream-java-client by rabbitmq.

the class StreamProducerTest method subEntryBatchesSentCompressedShouldBeConsumedProperly.

@Test
void subEntryBatchesSentCompressedShouldBeConsumedProperly() {
    int messagePerProducer = 10000;
    int messageCount = Compression.values().length * messagePerProducer;
    CountDownLatch publishLatch = new CountDownLatch(messageCount);
    ConfirmationHandler confirmationHandler = confirmationStatus -> publishLatch.countDown();
    AtomicInteger messageIndex = new AtomicInteger(0);
    Set<String> publishedBodies = ConcurrentHashMap.newKeySet(messageCount);
    for (Compression compression : Compression.values()) {
        Producer producer = environment.producerBuilder().stream(stream).subEntrySize(100).compression(compression).build();
        IntStream.range(0, messagePerProducer).forEach(i -> {
            String body = "compression " + compression.name() + " message " + messageIndex.getAndIncrement();
            producer.send(producer.messageBuilder().addData(body.getBytes(StandardCharsets.UTF_8)).build(), confirmationHandler);
            publishedBodies.add(body);
        });
    }
    assertThat(latchAssert(publishLatch)).completes();
    Set<String> consumedBodies = ConcurrentHashMap.newKeySet(messageCount);
    CountDownLatch consumeLatch = new CountDownLatch(messageCount);
    environment.consumerBuilder().stream(stream).offset(OffsetSpecification.first()).messageHandler((context, message) -> {
        consumedBodies.add(new String(message.getBodyAsBinary(), StandardCharsets.UTF_8));
        consumeLatch.countDown();
    }).build();
    assertThat(latchAssert(consumeLatch)).completes();
    assertThat(consumedBodies).isNotEmpty().hasSameSizeAs(publishedBodies);
    publishedBodies.forEach(publishBody -> assertThat(consumedBodies.contains(publishBody)).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) Compression(com.rabbitmq.stream.compression.Compression) ConfirmationHandler(com.rabbitmq.stream.ConfirmationHandler) Producer(com.rabbitmq.stream.Producer) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) CountDownLatch(java.util.concurrent.CountDownLatch) Test(org.junit.jupiter.api.Test) ParameterizedTest(org.junit.jupiter.params.ParameterizedTest)

Aggregations

Producer (com.rabbitmq.stream.Producer)51 Environment (com.rabbitmq.stream.Environment)44 CountDownLatch (java.util.concurrent.CountDownLatch)36 Test (org.junit.jupiter.api.Test)36 OffsetSpecification (com.rabbitmq.stream.OffsetSpecification)32 EnvironmentBuilder (com.rabbitmq.stream.EnvironmentBuilder)30 TestUtils.latchAssert (com.rabbitmq.stream.impl.TestUtils.latchAssert)30 Assertions.assertThat (org.assertj.core.api.Assertions.assertThat)30 BeforeEach (org.junit.jupiter.api.BeforeEach)30 ExtendWith (org.junit.jupiter.api.extension.ExtendWith)30 TestUtils.localhost (com.rabbitmq.stream.impl.TestUtils.localhost)29 EventLoopGroup (io.netty.channel.EventLoopGroup)29 IntStream (java.util.stream.IntStream)28 UUID (java.util.UUID)26 AfterEach (org.junit.jupiter.api.AfterEach)26 TestInfo (org.junit.jupiter.api.TestInfo)26 ConfirmationHandler (com.rabbitmq.stream.ConfirmationHandler)25 AtomicLong (java.util.concurrent.atomic.AtomicLong)25 TestUtils.waitAtMost (com.rabbitmq.stream.impl.TestUtils.waitAtMost)24 Duration (java.time.Duration)24