Search in sources :

Example 16 with TopicMessageFilter

use of com.hedera.mirror.grpc.domain.TopicMessageFilter in project hedera-mirror-node by hashgraph.

the class TopicMessageServiceTest method missingMessages.

@Test
void missingMessages() {
    TopicListener topicListener = Mockito.mock(TopicListener.class);
    EntityRepository entityRepository = Mockito.mock(EntityRepository.class);
    TopicMessageRetriever topicMessageRetriever = Mockito.mock(TopicMessageRetriever.class);
    topicMessageService = new TopicMessageServiceImpl(new GrpcProperties(), topicListener, entityRepository, topicMessageRetriever, new SimpleMeterRegistry());
    TopicMessageFilter filter = TopicMessageFilter.builder().startTime(Instant.EPOCH).topicId(topicId).build();
    TopicMessage beforeMissing = topicMessage(1);
    TopicMessage afterMissing = topicMessage(4);
    Mockito.when(entityRepository.findById(filter.getTopicId().getId())).thenReturn(Optional.of(Entity.builder().type(EntityType.TOPIC).build()));
    Mockito.when(topicMessageRetriever.retrieve(ArgumentMatchers.eq(filter), ArgumentMatchers.eq(true))).thenReturn(Flux.empty());
    Mockito.when(topicListener.listen(filter)).thenReturn(Flux.just(beforeMissing, afterMissing));
    Mockito.when(topicMessageRetriever.retrieve(ArgumentMatchers.argThat(t -> t.getLimit() == 2 && t.getStartTime().equals(beforeMissing.getConsensusTimestampInstant().plusNanos(1)) && t.getEndTime().equals(afterMissing.getConsensusTimestampInstant())), ArgumentMatchers.eq(false))).thenReturn(Flux.just(topicMessage(2), topicMessage(3)));
    topicMessageService.subscribeTopic(filter).map(TopicMessage::getSequenceNumber).as(StepVerifier::create).expectNext(1L, 2L, 3L, 4L).thenCancel().verify(Duration.ofMillis(700));
}
Also used : TopicMessageRetriever(com.hedera.mirror.grpc.retriever.TopicMessageRetriever) BeforeEach(org.junit.jupiter.api.BeforeEach) SimpleMeterRegistry(io.micrometer.core.instrument.simple.SimpleMeterRegistry) ArgumentMatchers(org.mockito.ArgumentMatchers) StepVerifier(reactor.test.StepVerifier) EntityId(com.hedera.mirror.common.domain.entity.EntityId) GrpcIntegrationTest(com.hedera.mirror.grpc.GrpcIntegrationTest) Autowired(org.springframework.beans.factory.annotation.Autowired) EntityType(com.hedera.mirror.common.domain.entity.EntityType) EntityRepository(com.hedera.mirror.grpc.repository.EntityRepository) EntityNotFoundException(com.hedera.mirror.grpc.exception.EntityNotFoundException) TopicMessageRetriever(com.hedera.mirror.grpc.retriever.TopicMessageRetriever) Assertions.assertThatThrownBy(org.assertj.core.api.Assertions.assertThatThrownBy) Duration(java.time.Duration) TopicListener(com.hedera.mirror.grpc.listener.TopicListener) TopicMessageFilter(com.hedera.mirror.grpc.domain.TopicMessageFilter) GrpcProperties(com.hedera.mirror.grpc.GrpcProperties) Resource(javax.annotation.Resource) ListenerProperties(com.hedera.mirror.grpc.listener.ListenerProperties) Instant(java.time.Instant) Test(org.junit.jupiter.api.Test) Mockito(org.mockito.Mockito) Flux(reactor.core.publisher.Flux) AfterEach(org.junit.jupiter.api.AfterEach) RetrieverProperties(com.hedera.mirror.grpc.retriever.RetrieverProperties) ChronoUnit(java.time.temporal.ChronoUnit) ConstraintViolationException(javax.validation.ConstraintViolationException) Entity(com.hedera.mirror.grpc.domain.Entity) Optional(java.util.Optional) TopicMessage(com.hedera.mirror.grpc.domain.TopicMessage) DomainBuilder(com.hedera.mirror.grpc.domain.DomainBuilder) TopicListener(com.hedera.mirror.grpc.listener.TopicListener) GrpcProperties(com.hedera.mirror.grpc.GrpcProperties) TopicMessage(com.hedera.mirror.grpc.domain.TopicMessage) SimpleMeterRegistry(io.micrometer.core.instrument.simple.SimpleMeterRegistry) EntityRepository(com.hedera.mirror.grpc.repository.EntityRepository) TopicMessageFilter(com.hedera.mirror.grpc.domain.TopicMessageFilter) GrpcIntegrationTest(com.hedera.mirror.grpc.GrpcIntegrationTest) Test(org.junit.jupiter.api.Test)

Example 17 with TopicMessageFilter

use of com.hedera.mirror.grpc.domain.TopicMessageFilter in project hedera-mirror-node by hashgraph.

the class TopicMessageServiceTest method missingMessagesFromRetrieverAndListener.

@Test
void missingMessagesFromRetrieverAndListener() {
    TopicListener topicListener = Mockito.mock(TopicListener.class);
    EntityRepository entityRepository = Mockito.mock(EntityRepository.class);
    TopicMessageRetriever topicMessageRetriever = Mockito.mock(TopicMessageRetriever.class);
    topicMessageService = new TopicMessageServiceImpl(new GrpcProperties(), topicListener, entityRepository, topicMessageRetriever, new SimpleMeterRegistry());
    TopicMessageFilter retrieverFilter = TopicMessageFilter.builder().startTime(Instant.EPOCH).topicId(topicId).build();
    TopicMessage retrieved1 = topicMessage(1);
    TopicMessage retrieved2 = topicMessage(2);
    TopicMessage beforeMissing1 = topicMessage(3);
    TopicMessage beforeMissing2 = topicMessage(4);
    TopicMessage afterMissing1 = topicMessage(8);
    TopicMessage afterMissing2 = topicMessage(9);
    TopicMessage afterMissing3 = topicMessage(10);
    Mockito.when(entityRepository.findById(retrieverFilter.getTopicId().getId())).thenReturn(Optional.of(Entity.builder().type(EntityType.TOPIC).build()));
    TopicMessageFilter listenerFilter = TopicMessageFilter.builder().startTime(retrieved2.getConsensusTimestampInstant()).build();
    Mockito.when(topicListener.listen(ArgumentMatchers.argThat(l -> l.getStartTime().equals(listenerFilter.getStartTime())))).thenReturn(Flux.just(beforeMissing1, beforeMissing2, afterMissing1, afterMissing2, afterMissing3));
    Mockito.when(topicMessageRetriever.retrieve(ArgumentMatchers.isA(TopicMessageFilter.class), ArgumentMatchers.eq(true))).thenReturn(Flux.just(retrieved1));
    Mockito.when(topicMessageRetriever.retrieve(ArgumentMatchers.isA(TopicMessageFilter.class), ArgumentMatchers.eq(false))).thenReturn(// missing historic
    Flux.just(retrieved2), Flux.just(// missing incoming
    topicMessage(5), topicMessage(6), topicMessage(7)));
    topicMessageService.subscribeTopic(retrieverFilter).map(TopicMessage::getSequenceNumber).as(StepVerifier::create).expectNext(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L).expectComplete().verify(Duration.ofMillis(700));
}
Also used : TopicMessageRetriever(com.hedera.mirror.grpc.retriever.TopicMessageRetriever) BeforeEach(org.junit.jupiter.api.BeforeEach) SimpleMeterRegistry(io.micrometer.core.instrument.simple.SimpleMeterRegistry) ArgumentMatchers(org.mockito.ArgumentMatchers) StepVerifier(reactor.test.StepVerifier) EntityId(com.hedera.mirror.common.domain.entity.EntityId) GrpcIntegrationTest(com.hedera.mirror.grpc.GrpcIntegrationTest) Autowired(org.springframework.beans.factory.annotation.Autowired) EntityType(com.hedera.mirror.common.domain.entity.EntityType) EntityRepository(com.hedera.mirror.grpc.repository.EntityRepository) EntityNotFoundException(com.hedera.mirror.grpc.exception.EntityNotFoundException) TopicMessageRetriever(com.hedera.mirror.grpc.retriever.TopicMessageRetriever) Assertions.assertThatThrownBy(org.assertj.core.api.Assertions.assertThatThrownBy) Duration(java.time.Duration) TopicListener(com.hedera.mirror.grpc.listener.TopicListener) TopicMessageFilter(com.hedera.mirror.grpc.domain.TopicMessageFilter) GrpcProperties(com.hedera.mirror.grpc.GrpcProperties) Resource(javax.annotation.Resource) ListenerProperties(com.hedera.mirror.grpc.listener.ListenerProperties) Instant(java.time.Instant) Test(org.junit.jupiter.api.Test) Mockito(org.mockito.Mockito) Flux(reactor.core.publisher.Flux) AfterEach(org.junit.jupiter.api.AfterEach) RetrieverProperties(com.hedera.mirror.grpc.retriever.RetrieverProperties) ChronoUnit(java.time.temporal.ChronoUnit) ConstraintViolationException(javax.validation.ConstraintViolationException) Entity(com.hedera.mirror.grpc.domain.Entity) Optional(java.util.Optional) TopicMessage(com.hedera.mirror.grpc.domain.TopicMessage) DomainBuilder(com.hedera.mirror.grpc.domain.DomainBuilder) TopicListener(com.hedera.mirror.grpc.listener.TopicListener) GrpcProperties(com.hedera.mirror.grpc.GrpcProperties) TopicMessage(com.hedera.mirror.grpc.domain.TopicMessage) SimpleMeterRegistry(io.micrometer.core.instrument.simple.SimpleMeterRegistry) EntityRepository(com.hedera.mirror.grpc.repository.EntityRepository) TopicMessageFilter(com.hedera.mirror.grpc.domain.TopicMessageFilter) GrpcIntegrationTest(com.hedera.mirror.grpc.GrpcIntegrationTest) Test(org.junit.jupiter.api.Test)

Example 18 with TopicMessageFilter

use of com.hedera.mirror.grpc.domain.TopicMessageFilter in project hedera-mirror-node by hashgraph.

the class AbstractSharedTopicListenerTest method slowSubscriberOverflowException.

@Test
@DisplayName("slow subscriber receives overflow exception and normal subscriber is not affected")
void slowSubscriberOverflowException() {
    int maxBufferSize = 16;
    Duration interval = Duration.ofMillis(10L);
    int prefetch = 4;
    // step verifier requests 2 messages on subscription, and there are downstream buffers after the backpressure
    // buffer, to ensure overflow, set the number of topic messages to send as follows
    int numMessages = maxBufferSize + prefetch * 2 + 3;
    listenerProperties.setInterval(interval);
    listenerProperties.setMaxBufferSize(maxBufferSize);
    listenerProperties.setPrefetch(prefetch);
    TopicMessageFilter filterFast = TopicMessageFilter.builder().startTime(Instant.EPOCH).topicId(topicId).build();
    // create a fast subscriber to keep the shared flux open. the fast subscriber should receive all messages
    var stepVerifierFast = topicListener.listen(filterFast).map(TopicMessage::getSequenceNumber).as(StepVerifier::create).expectNextSequence(LongStream.range(1, numMessages + 1).boxed().collect(Collectors.toList())).thenCancel().verifyLater();
    TopicMessageFilter filterSlow = TopicMessageFilter.builder().startTime(Instant.EPOCH).topicId(topicId).build();
    // send the messages in two batches and wait 2 * polling interval between. Limit the first batch to
    // maxBufferSize messages so it definitely won't cause overflow with the SharedPollingTopicListener.
    // The wait also gives the subscriber threads chance to consume messages in slow environment.
    Flux<TopicMessage> firstBatch = domainBuilder.topicMessages(maxBufferSize, future);
    Flux<TopicMessage> secondBatch = domainBuilder.topicMessages(numMessages - maxBufferSize, future.plusSeconds(1));
    // the slow subscriber
    topicListener.listen(filterSlow).map(TopicMessage::getSequenceNumber).as(// initial request amount of 1
    p -> StepVerifier.create(p, 1)).thenRequest(// trigger subscription
    1).thenAwait(Duration.ofMillis(10L)).then(() -> publish(firstBatch)).thenAwait(interval.multipliedBy(2)).then(() -> publish(secondBatch)).expectNext(1L, 2L).thenAwait(// stall to overrun backpressure buffer
    Duration.ofMillis(500L)).thenRequest(Long.MAX_VALUE).thenConsumeWhile(n -> n < numMessages).expectErrorMatches(Exceptions::isOverflow).verify(Duration.ofMillis(1000L));
    stepVerifierFast.verify(Duration.ofMillis(1000L));
}
Also used : Test(org.junit.jupiter.api.Test) Flux(reactor.core.publisher.Flux) TopicMessageFilter(com.hedera.mirror.grpc.domain.TopicMessageFilter) LongStream(java.util.stream.LongStream) StepVerifier(reactor.test.StepVerifier) Duration(java.time.Duration) Instant(java.time.Instant) Exceptions(reactor.core.Exceptions) TopicMessage(com.hedera.mirror.grpc.domain.TopicMessage) Collectors(java.util.stream.Collectors) DisplayName(org.junit.jupiter.api.DisplayName) TopicMessage(com.hedera.mirror.grpc.domain.TopicMessage) Duration(java.time.Duration) TopicMessageFilter(com.hedera.mirror.grpc.domain.TopicMessageFilter) Test(org.junit.jupiter.api.Test) DisplayName(org.junit.jupiter.api.DisplayName)

Example 19 with TopicMessageFilter

use of com.hedera.mirror.grpc.domain.TopicMessageFilter in project hedera-mirror-node by hashgraph.

the class AbstractTopicListenerTest method noMessages.

@Test
void noMessages() {
    TopicMessageFilter filter = TopicMessageFilter.builder().startTime(Instant.EPOCH).topicId(topicId).build();
    topicListener.listen(filter).map(TopicMessage::getSequenceNumber).as(StepVerifier::create).expectSubscription().expectTimeout(Duration.ofMillis(500L)).verify();
}
Also used : TopicMessage(com.hedera.mirror.grpc.domain.TopicMessage) TopicMessageFilter(com.hedera.mirror.grpc.domain.TopicMessageFilter) GrpcIntegrationTest(com.hedera.mirror.grpc.GrpcIntegrationTest) Test(org.junit.jupiter.api.Test)

Example 20 with TopicMessageFilter

use of com.hedera.mirror.grpc.domain.TopicMessageFilter in project hedera-mirror-node by hashgraph.

the class AbstractTopicListenerTest method lessThanPageSize.

@Test
void lessThanPageSize() {
    TopicMessageFilter filter = TopicMessageFilter.builder().startTime(Instant.EPOCH).topicId(topicId).build();
    topicListener.listen(filter).map(TopicMessage::getSequenceNumber).as(StepVerifier::create).thenAwait(Duration.ofMillis(50)).then(() -> publish(domainBuilder.topicMessages(2, future))).expectNext(1L, 2L).thenCancel().verify(Duration.ofMillis(500));
}
Also used : TopicMessage(com.hedera.mirror.grpc.domain.TopicMessage) TopicMessageFilter(com.hedera.mirror.grpc.domain.TopicMessageFilter) GrpcIntegrationTest(com.hedera.mirror.grpc.GrpcIntegrationTest) Test(org.junit.jupiter.api.Test)

Aggregations

TopicMessageFilter (com.hedera.mirror.grpc.domain.TopicMessageFilter)62 TopicMessage (com.hedera.mirror.grpc.domain.TopicMessage)52 Test (org.junit.jupiter.api.Test)50 GrpcIntegrationTest (com.hedera.mirror.grpc.GrpcIntegrationTest)47 Instant (java.time.Instant)18 StepVerifier (reactor.test.StepVerifier)15 Duration (java.time.Duration)12 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)12 EntityId (com.hedera.mirror.common.domain.entity.EntityId)11 EntityType (com.hedera.mirror.common.domain.entity.EntityType)11 DomainBuilder (com.hedera.mirror.grpc.domain.DomainBuilder)11 Resource (javax.annotation.Resource)11 ValueSource (org.junit.jupiter.params.provider.ValueSource)11 Autowired (org.springframework.beans.factory.annotation.Autowired)11 Flux (reactor.core.publisher.Flux)11 AfterEach (org.junit.jupiter.api.AfterEach)10 BeforeEach (org.junit.jupiter.api.BeforeEach)10 ConstraintViolationException (javax.validation.ConstraintViolationException)9 GrpcProperties (com.hedera.mirror.grpc.GrpcProperties)6 EntityNotFoundException (com.hedera.mirror.grpc.exception.EntityNotFoundException)6