use of com.rabbitmq.stream.BackOffDelayPolicy in project rabbitmq-stream-java-client by rabbitmq.
the class ConsumersCoordinatorTest method metadataUpdate_shouldCloseConsumerIfStreamIsDeleted.
@Test
void metadataUpdate_shouldCloseConsumerIfStreamIsDeleted() throws Exception {
BackOffDelayPolicy delayPolicy = fixedWithInitialDelay(ms(50), ms(50));
when(environment.topologyUpdateBackOffDelayPolicy()).thenReturn(delayPolicy);
scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
when(environment.scheduledExecutorService()).thenReturn(scheduledExecutorService);
when(consumer.isOpen()).thenReturn(true);
when(locator.metadata("stream")).thenReturn(metadata(null, replicas())).thenReturn(metadata("stream", null, null, Constants.RESPONSE_CODE_STREAM_DOES_NOT_EXIST));
when(clientFactory.client(any())).thenReturn(client);
when(client.subscribe(subscriptionIdCaptor.capture(), anyString(), any(OffsetSpecification.class), anyInt(), anyMap())).thenReturn(new Client.Response(Constants.RESPONSE_CODE_OK));
AtomicInteger messageHandlerCalls = new AtomicInteger();
coordinator.subscribe(consumer, "stream", OffsetSpecification.first(), null, NO_OP_SUBSCRIPTION_LISTENER, (offset, message) -> messageHandlerCalls.incrementAndGet());
verify(clientFactory, times(1)).client(any());
verify(client, times(1)).subscribe(anyByte(), anyString(), any(OffsetSpecification.class), anyInt(), anyMap());
assertThat(messageHandlerCalls.get()).isEqualTo(0);
messageListener.handle(subscriptionIdCaptor.getValue(), 1, 0, new WrapperMessageBuilder().build());
assertThat(messageHandlerCalls.get()).isEqualTo(1);
metadataListener.handle("stream", Constants.RESPONSE_CODE_STREAM_NOT_AVAILABLE);
Thread.sleep(delayPolicy.delay(0).toMillis() * 5);
verify(consumer, times(1)).closeAfterStreamDeletion();
verify(client, times(1)).subscribe(anyByte(), anyString(), any(OffsetSpecification.class), anyInt(), anyMap());
verify(client, times(0)).unsubscribe(anyByte());
assertThat(coordinator.poolSize()).isZero();
}
use of com.rabbitmq.stream.BackOffDelayPolicy in project rabbitmq-stream-java-client by rabbitmq.
the class ConsumersCoordinatorTest method shouldRetryRedistributionIfMetadataIsNotUpdatedImmediately.
@Test
void shouldRetryRedistributionIfMetadataIsNotUpdatedImmediately() throws Exception {
BackOffDelayPolicy delayPolicy = fixedWithInitialDelay(ms(100), ms(100));
when(environment.topologyUpdateBackOffDelayPolicy()).thenReturn(delayPolicy);
scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
when(environment.scheduledExecutorService()).thenReturn(scheduledExecutorService);
when(consumer.isOpen()).thenReturn(true);
when(locator.metadata("stream")).thenReturn(metadata(null, replicas())).thenReturn(metadata(null, Collections.emptyList())).thenReturn(metadata(null, Collections.emptyList())).thenReturn(metadata(null, replicas()));
when(clientFactory.client(any())).thenReturn(client);
when(client.subscribe(subscriptionIdCaptor.capture(), anyString(), any(OffsetSpecification.class), anyInt(), anyMap())).thenReturn(new Client.Response(Constants.RESPONSE_CODE_OK));
AtomicInteger messageHandlerCalls = new AtomicInteger();
Runnable closingRunnable = coordinator.subscribe(consumer, "stream", OffsetSpecification.first(), null, NO_OP_SUBSCRIPTION_LISTENER, (offset, message) -> messageHandlerCalls.incrementAndGet());
verify(clientFactory, times(1)).client(any());
verify(client, times(1)).subscribe(anyByte(), anyString(), any(OffsetSpecification.class), anyInt(), anyMap());
assertThat(messageHandlerCalls.get()).isEqualTo(0);
messageListener.handle(subscriptionIdCaptor.getValue(), 1, 0, new WrapperMessageBuilder().build());
assertThat(messageHandlerCalls.get()).isEqualTo(1);
metadataListener.handle("stream", Constants.RESPONSE_CODE_STREAM_NOT_AVAILABLE);
Thread.sleep(delayPolicy.delay(0).toMillis() + delayPolicy.delay(1).toMillis() * 5);
verify(client, times(2)).subscribe(anyByte(), anyString(), any(OffsetSpecification.class), anyInt(), anyMap());
assertThat(messageHandlerCalls.get()).isEqualTo(1);
messageListener.handle(subscriptionIdCaptor.getValue(), 0, 0, new WrapperMessageBuilder().build());
assertThat(messageHandlerCalls.get()).isEqualTo(2);
when(client.unsubscribe(subscriptionIdCaptor.getValue())).thenReturn(new Client.Response(Constants.RESPONSE_CODE_OK));
closingRunnable.run();
verify(client, times(1)).unsubscribe(subscriptionIdCaptor.getValue());
messageListener.handle(subscriptionIdCaptor.getValue(), 0, 0, new WrapperMessageBuilder().build());
assertThat(messageHandlerCalls.get()).isEqualTo(2);
assertThat(coordinator.poolSize()).isZero();
}
use of com.rabbitmq.stream.BackOffDelayPolicy in project rabbitmq-stream-java-client by rabbitmq.
the class ConsumersCoordinatorTest method shouldRemoveClientSubscriptionManagerFromPoolIfEmptyAfterMetadataUpdate.
@Test
void shouldRemoveClientSubscriptionManagerFromPoolIfEmptyAfterMetadataUpdate() throws Exception {
BackOffDelayPolicy delayPolicy = fixedWithInitialDelay(ms(50), ms(50));
when(environment.topologyUpdateBackOffDelayPolicy()).thenReturn(delayPolicy);
scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
when(environment.scheduledExecutorService()).thenReturn(scheduledExecutorService);
when(consumer.isOpen()).thenReturn(true);
when(locator.metadata("stream")).thenReturn(metadata(null, replicas().subList(0, 1)));
when(clientFactory.client(any())).thenReturn(client);
when(client.subscribe(subscriptionIdCaptor.capture(), anyString(), any(OffsetSpecification.class), anyInt(), anyMap())).thenReturn(new Client.Response(Constants.RESPONSE_CODE_OK));
int extraSubscriptionCount = ConsumersCoordinator.MAX_SUBSCRIPTIONS_PER_CLIENT / 5;
int subscriptionCount = ConsumersCoordinator.MAX_SUBSCRIPTIONS_PER_CLIENT + extraSubscriptionCount;
IntStream.range(0, subscriptionCount).forEach(i -> {
coordinator.subscribe(consumer, "stream", OffsetSpecification.first(), null, NO_OP_SUBSCRIPTION_LISTENER, (offset, message) -> {
});
});
// the extra is allocated on another client from the same pool
verify(clientFactory, times(2)).client(any());
verify(client, times(subscriptionCount)).subscribe(anyByte(), anyString(), any(OffsetSpecification.class), anyInt(), anyMap());
List<ConsumersPoolInfo> info = MonitoringTestUtils.extract(coordinator);
assertThat(info).hasSize(1).element(0).extracting(pool -> pool.consumerCount()).isEqualTo(subscriptionCount);
// let's kill the first client connection
metadataListeners.get(0).handle("stream", Constants.RESPONSE_CODE_STREAM_NOT_AVAILABLE);
Thread.sleep(delayPolicy.delay(0).toMillis() * 5);
info = MonitoringTestUtils.extract(coordinator);
assertThat(info).hasSize(1).element(0).extracting(pool -> pool.consumerCount()).isEqualTo(subscriptionCount);
// the MAX consumers must have been re-allocated to the existing client and a new one
// let's add a new subscription to make sure we are still using the same pool
coordinator.subscribe(consumer, "stream", OffsetSpecification.first(), null, NO_OP_SUBSCRIPTION_LISTENER, (offset, message) -> {
});
verify(clientFactory, times(2 + 1)).client(any());
verify(client, times(subscriptionCount + ConsumersCoordinator.MAX_SUBSCRIPTIONS_PER_CLIENT + 1)).subscribe(anyByte(), anyString(), any(OffsetSpecification.class), anyInt(), anyMap());
info = MonitoringTestUtils.extract(coordinator);
assertThat(info).hasSize(1).element(0).extracting(pool -> pool.consumerCount()).isEqualTo(subscriptionCount + 1);
}
use of com.rabbitmq.stream.BackOffDelayPolicy in project rabbitmq-stream-java-client by rabbitmq.
the class ConsumersCoordinatorTest method metadataUpdate_shouldCloseConsumerIfRetryTimeoutIsReached.
@Test
void metadataUpdate_shouldCloseConsumerIfRetryTimeoutIsReached() throws Exception {
Duration retryTimeout = Duration.ofMillis(200);
BackOffDelayPolicy delayPolicy = fixedWithInitialDelay(ms(50), ms(50), ms(200));
when(environment.topologyUpdateBackOffDelayPolicy()).thenReturn(delayPolicy);
scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
when(environment.scheduledExecutorService()).thenReturn(scheduledExecutorService);
when(consumer.isOpen()).thenReturn(true);
when(locator.metadata("stream")).thenReturn(metadata(null, replicas())).thenThrow(new IllegalStateException());
when(clientFactory.client(any())).thenReturn(client);
when(client.subscribe(subscriptionIdCaptor.capture(), anyString(), any(OffsetSpecification.class), anyInt(), anyMap())).thenReturn(new Client.Response(Constants.RESPONSE_CODE_OK));
AtomicInteger messageHandlerCalls = new AtomicInteger();
coordinator.subscribe(consumer, "stream", OffsetSpecification.first(), null, NO_OP_SUBSCRIPTION_LISTENER, (offset, message) -> messageHandlerCalls.incrementAndGet());
verify(clientFactory, times(1)).client(any());
verify(client, times(1)).subscribe(anyByte(), anyString(), any(OffsetSpecification.class), anyInt(), anyMap());
assertThat(messageHandlerCalls.get()).isEqualTo(0);
messageListener.handle(subscriptionIdCaptor.getValue(), 1, 0, new WrapperMessageBuilder().build());
assertThat(messageHandlerCalls.get()).isEqualTo(1);
metadataListener.handle("stream", Constants.RESPONSE_CODE_STREAM_NOT_AVAILABLE);
Thread.sleep(delayPolicy.delay(0).toMillis() + retryTimeout.toMillis() * 2);
verify(consumer, times(1)).closeAfterStreamDeletion();
verify(client, times(1)).subscribe(anyByte(), anyString(), any(OffsetSpecification.class), anyInt(), anyMap());
verify(client, times(0)).unsubscribe(anyByte());
assertThat(coordinator.poolSize()).isZero();
}
use of com.rabbitmq.stream.BackOffDelayPolicy in project rabbitmq-stream-java-client by rabbitmq.
the class ConsumersCoordinatorTest method shouldRedistributeConsumerOnMetadataUpdate.
@Test
void shouldRedistributeConsumerOnMetadataUpdate() throws Exception {
BackOffDelayPolicy delayPolicy = fixedWithInitialDelay(ms(100), ms(100));
when(environment.topologyUpdateBackOffDelayPolicy()).thenReturn(delayPolicy);
scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
when(environment.scheduledExecutorService()).thenReturn(scheduledExecutorService);
when(consumer.isOpen()).thenReturn(true);
when(locator.metadata("stream")).thenReturn(metadata(null, replicas()));
when(clientFactory.client(any())).thenReturn(client);
StreamConsumer consumerClosedAfterMetadataUpdate = mock(StreamConsumer.class);
when(consumerClosedAfterMetadataUpdate.isOpen()).thenReturn(false);
when(client.subscribe(subscriptionIdCaptor.capture(), anyString(), any(OffsetSpecification.class), anyInt(), anyMap())).thenReturn(new Client.Response(Constants.RESPONSE_CODE_OK));
AtomicInteger messageHandlerCalls = new AtomicInteger();
Runnable closingRunnable = coordinator.subscribe(consumer, "stream", OffsetSpecification.first(), null, NO_OP_SUBSCRIPTION_LISTENER, (offset, message) -> messageHandlerCalls.incrementAndGet());
verify(clientFactory, times(1)).client(any());
verify(client, times(1)).subscribe(anyByte(), anyString(), any(OffsetSpecification.class), anyInt(), anyMap());
coordinator.subscribe(consumerClosedAfterMetadataUpdate, "stream", OffsetSpecification.first(), null, NO_OP_SUBSCRIPTION_LISTENER, (offset, message) -> {
});
verify(client, times(1 + 1)).subscribe(anyByte(), anyString(), any(OffsetSpecification.class), anyInt(), anyMap());
assertThat(messageHandlerCalls.get()).isEqualTo(0);
firstMessageListener().handle(subscriptionIdCaptor.getAllValues().get(0), 1, 0, new WrapperMessageBuilder().build());
assertThat(messageHandlerCalls.get()).isEqualTo(1);
this.metadataListeners.forEach(ml -> ml.handle("stream", Constants.RESPONSE_CODE_STREAM_NOT_AVAILABLE));
Thread.sleep(delayPolicy.delay(0).toMillis() * 5);
// the second consumer does not re-subscribe because it returns it is not open
verify(client, times(2 + 1)).subscribe(anyByte(), anyString(), any(OffsetSpecification.class), anyInt(), anyMap());
assertThat(messageHandlerCalls.get()).isEqualTo(1);
lastMessageListener().handle(subscriptionIdCaptor.getAllValues().get(0), 0, 0, new WrapperMessageBuilder().build());
assertThat(messageHandlerCalls.get()).isEqualTo(2);
when(client.unsubscribe(subscriptionIdCaptor.getValue())).thenReturn(new Client.Response(Constants.RESPONSE_CODE_OK));
closingRunnable.run();
verify(client, times(1)).unsubscribe(subscriptionIdCaptor.getValue());
lastMessageListener().handle(subscriptionIdCaptor.getValue(), 0, 0, new WrapperMessageBuilder().build());
assertThat(messageHandlerCalls.get()).isEqualTo(2);
assertThat(coordinator.poolSize()).isZero();
}
Aggregations