19
19
import static org .assertj .core .api .Assertions .assertThat ;
20
20
import static org .assertj .core .api .Assertions .assertThatExceptionOfType ;
21
21
import static org .mockito .ArgumentMatchers .any ;
22
+ import static org .mockito .BDDMockito .given ;
23
+ import static org .mockito .BDDMockito .willAnswer ;
22
24
import static org .mockito .Mockito .mock ;
23
25
import static org .mockito .Mockito .times ;
24
26
import static org .mockito .Mockito .verify ;
29
31
import java .util .HashMap ;
30
32
import java .util .List ;
31
33
import java .util .Map ;
34
+ import java .util .concurrent .atomic .AtomicBoolean ;
32
35
33
36
import org .apache .kafka .clients .consumer .Consumer ;
34
37
import org .apache .kafka .clients .consumer .ConsumerRecord ;
35
38
import org .apache .kafka .clients .consumer .ConsumerRecords ;
36
39
import org .apache .kafka .common .TopicPartition ;
37
40
import org .junit .jupiter .api .Test ;
38
41
42
+ import org .springframework .kafka .KafkaException ;
39
43
import org .springframework .util .backoff .FixedBackOff ;
40
44
41
45
/**
@@ -63,6 +67,7 @@ void recover() {
63
67
ConsumerRecords <?, ?> records = new ConsumerRecords <>(map );
64
68
Consumer <?, ?> consumer = mock (Consumer .class );
65
69
MessageListenerContainer container = mock (MessageListenerContainer .class );
70
+ given (container .isRunning ()).willReturn (true );
66
71
eh .handle (new RuntimeException (), records , consumer , container , () -> {
67
72
this .invoked ++;
68
73
throw new RuntimeException ();
@@ -92,6 +97,7 @@ void successOnRetry() {
92
97
ConsumerRecords <?, ?> records = new ConsumerRecords <>(map );
93
98
Consumer <?, ?> consumer = mock (Consumer .class );
94
99
MessageListenerContainer container = mock (MessageListenerContainer .class );
100
+ given (container .isRunning ()).willReturn (true );
95
101
eh .handle (new RuntimeException (), records , consumer , container , () -> this .invoked ++);
96
102
assertThat (this .invoked ).isEqualTo (1 );
97
103
assertThat (recovered ).hasSize (0 );
@@ -119,6 +125,7 @@ void recoveryFails() {
119
125
ConsumerRecords <?, ?> records = new ConsumerRecords <>(map );
120
126
Consumer <?, ?> consumer = mock (Consumer .class );
121
127
MessageListenerContainer container = mock (MessageListenerContainer .class );
128
+ given (container .isRunning ()).willReturn (true );
122
129
assertThatExceptionOfType (RuntimeException .class ).isThrownBy (() ->
123
130
eh .handle (new RuntimeException (), records , consumer , container , () -> {
124
131
this .invoked ++;
@@ -134,4 +141,31 @@ void recoveryFails() {
134
141
verify (consumer ).seek (new TopicPartition ("foo" , 1 ), 0L );
135
142
}
136
143
144
+ @ Test
145
+ void exitOnContainerStop () {
146
+ this .invoked = 0 ;
147
+ List <ConsumerRecord <?, ?>> recovered = new ArrayList <>();
148
+ FallbackBatchErrorHandler eh = new FallbackBatchErrorHandler (new FixedBackOff (0 , 99999 ), (cr , ex ) -> {
149
+ recovered .add (cr );
150
+ });
151
+ Map <TopicPartition , List <ConsumerRecord <Object , Object >>> map = new HashMap <>();
152
+ map .put (new TopicPartition ("foo" , 0 ),
153
+ Collections .singletonList (new ConsumerRecord <>("foo" , 0 , 0L , "foo" , "bar" )));
154
+ map .put (new TopicPartition ("foo" , 1 ),
155
+ Collections .singletonList (new ConsumerRecord <>("foo" , 1 , 0L , "foo" , "bar" )));
156
+ ConsumerRecords <?, ?> records = new ConsumerRecords <>(map );
157
+ Consumer <?, ?> consumer = mock (Consumer .class );
158
+ MessageListenerContainer container = mock (MessageListenerContainer .class );
159
+ AtomicBoolean stopped = new AtomicBoolean (true );
160
+ willAnswer (inv -> stopped .get ()).given (container ).isRunning ();
161
+ assertThatExceptionOfType (KafkaException .class ).isThrownBy (() ->
162
+ eh .handle (new RuntimeException (), records , consumer , container , () -> {
163
+ this .invoked ++;
164
+ stopped .set (false );
165
+ throw new RuntimeException ();
166
+ })
167
+ ).withMessage ("Container stopped during retries" );
168
+ assertThat (this .invoked ).isEqualTo (1 );
169
+ }
170
+
137
171
}
0 commit comments