|
17 | 17 | package org.springframework.kafka.retrytopic;
|
18 | 18 |
|
19 | 19 | import static org.assertj.core.api.Assertions.assertThat;
|
| 20 | +import static org.assertj.core.api.Assertions.assertThatThrownBy; |
20 | 21 | import static org.mockito.ArgumentMatchers.any;
|
21 | 22 | import static org.mockito.ArgumentMatchers.anyLong;
|
22 | 23 | import static org.mockito.ArgumentMatchers.eq;
|
23 | 24 | import static org.mockito.BDDMockito.given;
|
24 | 25 | import static org.mockito.BDDMockito.then;
|
25 | 26 | import static org.mockito.BDDMockito.willReturn;
|
| 27 | +import static org.mockito.Mockito.mock; |
26 | 28 | import static org.mockito.Mockito.never;
|
27 | 29 | import static org.mockito.Mockito.times;
|
28 | 30 |
|
|
59 | 61 | import org.springframework.kafka.listener.adapter.AbstractDelegatingMessageListenerAdapter;
|
60 | 62 | import org.springframework.kafka.listener.adapter.KafkaBackoffAwareMessageListenerAdapter;
|
61 | 63 | import org.springframework.kafka.support.Acknowledgment;
|
| 64 | +import org.springframework.kafka.support.converter.ConversionException; |
| 65 | +import org.springframework.kafka.support.serializer.DeserializationException; |
| 66 | +import org.springframework.util.backoff.BackOff; |
| 67 | +import org.springframework.util.backoff.BackOffExecution; |
| 68 | +import org.springframework.util.backoff.FixedBackOff; |
62 | 69 |
|
63 | 70 | /**
|
64 | 71 | * @author Tomaz Fernandes
|
65 | 72 | * @since 2.7
|
66 | 73 | */
|
67 | 74 | @ExtendWith(MockitoExtension.class)
|
68 |
| -@SuppressWarnings({"unchecked", "rawtypes"}) |
| 75 | +@SuppressWarnings({"unchecked", "rawtypes", "deprecation"}) |
69 | 76 | class ListenerContainerFactoryConfigurerTests {
|
70 | 77 |
|
71 | 78 | @Mock
|
@@ -404,10 +411,63 @@ void shouldDecorateFactory() {
|
404 | 411 | .createContext(anyLong(), listenerIdCaptor.capture(), any(TopicPartition.class), eq(consumer));
|
405 | 412 | assertThat(listenerIdCaptor.getValue()).isEqualTo(testListenerId);
|
406 | 413 | then(listener).should(times(1)).onMessage(data, ack, consumer);
|
407 |
| - |
408 | 414 | then(this.configurerContainerCustomizer).should(times(1)).accept(container);
|
409 | 415 | }
|
410 | 416 |
|
| 417 | + @Test |
| 418 | + void shouldUseGivenBackOffAndExceptions() { |
| 419 | + |
| 420 | + // given |
| 421 | + given(container.getContainerProperties()).willReturn(containerProperties); |
| 422 | + given(deadLetterPublishingRecovererFactory.create()).willReturn(recoverer); |
| 423 | + given(containerProperties.getMessageListener()).willReturn(listener); |
| 424 | + given(configuration.forContainerFactoryConfigurer()).willReturn(lcfcConfiguration); |
| 425 | + willReturn(container).given(containerFactory).createListenerContainer(endpoint); |
| 426 | + BackOff backOffMock = mock(BackOff.class); |
| 427 | + BackOffExecution backOffExecutionMock = mock(BackOffExecution.class); |
| 428 | + given(backOffMock.start()).willReturn(backOffExecutionMock); |
| 429 | + |
| 430 | + ListenerContainerFactoryConfigurer configurer = |
| 431 | + new ListenerContainerFactoryConfigurer(kafkaConsumerBackoffManager, |
| 432 | + deadLetterPublishingRecovererFactory, clock); |
| 433 | + configurer.setBlockingRetriesBackOff(backOffMock); |
| 434 | + configurer.setBlockingRetryableExceptions(IllegalArgumentException.class, IllegalStateException.class); |
| 435 | + |
| 436 | + // when |
| 437 | + KafkaListenerContainerFactory<?> decoratedFactory = |
| 438 | + configurer.decorateFactory(this.containerFactory, configuration.forContainerFactoryConfigurer()); |
| 439 | + decoratedFactory.createListenerContainer(endpoint); |
| 440 | + |
| 441 | + // then |
| 442 | + then(backOffMock).should().start(); |
| 443 | + then(container).should().setCommonErrorHandler(errorHandlerCaptor.capture()); |
| 444 | + CommonErrorHandler errorHandler = errorHandlerCaptor.getValue(); |
| 445 | + assertThat(DefaultErrorHandler.class.isAssignableFrom(errorHandler.getClass())).isTrue(); |
| 446 | + DefaultErrorHandler defaultErrorHandler = (DefaultErrorHandler) errorHandler; |
| 447 | + assertThat(defaultErrorHandler.removeClassification(IllegalArgumentException.class)).isTrue(); |
| 448 | + assertThat(defaultErrorHandler.removeClassification(IllegalStateException.class)).isTrue(); |
| 449 | + assertThat(defaultErrorHandler.removeClassification(ConversionException.class)).isNull(); |
| 450 | + |
| 451 | + } |
| 452 | + |
| 453 | + |
| 454 | + @Test |
| 455 | + void shouldThrowIfBackOffOrRetryablesAlreadySet() { |
| 456 | + // given |
| 457 | + BackOff backOff = new FixedBackOff(); |
| 458 | + ListenerContainerFactoryConfigurer configurer = |
| 459 | + new ListenerContainerFactoryConfigurer(kafkaConsumerBackoffManager, |
| 460 | + deadLetterPublishingRecovererFactory, clock); |
| 461 | + configurer.setBlockingRetriesBackOff(backOff); |
| 462 | + configurer.setBlockingRetryableExceptions(IllegalArgumentException.class, IllegalStateException.class); |
| 463 | + |
| 464 | + // when / then |
| 465 | + assertThatThrownBy(() -> configurer.setBlockingRetriesBackOff(backOff)).isInstanceOf(IllegalStateException.class); |
| 466 | + assertThatThrownBy(() -> configurer.setBlockingRetryableExceptions(ConversionException.class, DeserializationException.class)) |
| 467 | + .isInstanceOf(IllegalStateException.class); |
| 468 | + } |
| 469 | + |
| 470 | + |
411 | 471 | @Test
|
412 | 472 | void shouldCacheFactoryInstances() {
|
413 | 473 |
|
|
0 commit comments