1
1
/*
2
- * Copyright 2023 the original author or authors.
2
+ * Copyright 2023-2024 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
17
17
package org .springframework .kafka .listener ;
18
18
19
19
import static org .assertj .core .api .Assertions .assertThat ;
20
+ import static org .assertj .core .api .Assertions .assertThatExceptionOfType ;
20
21
import static org .assertj .core .api .Assertions .assertThatIllegalStateException ;
21
22
import static org .mockito .ArgumentMatchers .any ;
23
+ import static org .mockito .ArgumentMatchers .anyMap ;
24
+ import static org .mockito .BDDMockito .willReturn ;
22
25
import static org .mockito .BDDMockito .willThrow ;
23
26
import static org .mockito .Mockito .mock ;
24
27
import static org .mockito .Mockito .spy ;
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 ;
40
+ import org .apache .kafka .common .errors .RebalanceInProgressException ;
37
41
import org .junit .jupiter .api .Test ;
38
42
import org .mockito .ArgumentCaptor ;
39
43
40
44
import org .springframework .core .log .LogAccessor ;
41
45
import org .springframework .data .util .DirectFieldAccessFallbackBeanWrapper ;
46
+ import org .springframework .kafka .KafkaException ;
42
47
import org .springframework .util .backoff .BackOff ;
43
48
import org .springframework .util .backoff .FixedBackOff ;
44
49
@@ -52,15 +57,6 @@ public class FailedBatchProcessorTests {
52
57
@ SuppressWarnings ({ "rawtypes" , "unchecked" })
53
58
@ Test
54
59
void indexOutOfBounds () {
55
- class TestFBP extends FailedBatchProcessor {
56
-
57
- TestFBP (BiConsumer <ConsumerRecord <?, ?>, Exception > recoverer , BackOff backOff ,
58
- CommonErrorHandler fallbackHandler ) {
59
-
60
- super (recoverer , backOff , fallbackHandler );
61
- }
62
-
63
- }
64
60
CommonErrorHandler mockEH = mock (CommonErrorHandler .class );
65
61
willThrow (new IllegalStateException ("fallback" )).given (mockEH ).handleBatch (any (), any (), any (), any (), any ());
66
62
@@ -83,15 +79,6 @@ records, mock(Consumer.class), mock(MessageListenerContainer.class), mock(Runnab
83
79
@ SuppressWarnings ({ "rawtypes" , "unchecked" })
84
80
@ Test
85
81
void recordNotPresent () {
86
- class TestFBP extends FailedBatchProcessor {
87
-
88
- TestFBP (BiConsumer <ConsumerRecord <?, ?>, Exception > recoverer , BackOff backOff ,
89
- CommonErrorHandler fallbackHandler ) {
90
-
91
- super (recoverer , backOff , fallbackHandler );
92
- }
93
-
94
- }
95
82
CommonErrorHandler mockEH = mock (CommonErrorHandler .class );
96
83
willThrow (new IllegalStateException ("fallback" )).given (mockEH ).handleBatch (any (), any (), any (), any (), any ());
97
84
@@ -114,4 +101,34 @@ records, mock(Consumer.class), mock(MessageListenerContainer.class), mock(Runnab
114
101
assertThat (output ).contains ("Record not found in batch: topic-42@123;" );
115
102
}
116
103
104
+ @ Test
105
+ void testExceptionDuringCommit () {
106
+ CommonErrorHandler mockEH = mock (CommonErrorHandler .class );
107
+ willThrow (new IllegalStateException ("ise" )).given (mockEH ).handleBatch (any (), any (), any (), any (), any ());
108
+
109
+ ConsumerRecord rec1 = new ConsumerRecord ("topic" , 0 , 0L , null , null );
110
+ ConsumerRecord rec2 = new ConsumerRecord ("topic" , 0 , 1L , null , null );
111
+ ConsumerRecord rec3 = new ConsumerRecord ("topic" , 0 , 2L , null , null );
112
+
113
+ ConsumerRecords records = new ConsumerRecords (Map .of (new TopicPartition ("topic" , 0 ), List .of (rec1 , rec2 , rec3 )));
114
+ TestFBP testFBP = new TestFBP ((rec , ex ) -> { }, new FixedBackOff (2L , 2L ), mockEH );
115
+ final Consumer consumer = mock (Consumer .class );
116
+ willThrow (new RebalanceInProgressException ("rebalance in progress" )).given (consumer ).commitSync (anyMap (), any ());
117
+ final MessageListenerContainer mockMLC = mock (MessageListenerContainer .class );
118
+ willReturn (new ContainerProperties ("topic" )).given (mockMLC ).getContainerProperties ();
119
+ assertThatExceptionOfType (KafkaException .class ).isThrownBy (() ->
120
+ testFBP .handle (new BatchListenerFailedException ("topic" , rec2 ),
121
+ records , consumer , mockMLC , mock (Runnable .class ))
122
+ ).withMessage ("Seek to current after exception" );
123
+ }
124
+
125
+ static class TestFBP extends FailedBatchProcessor {
126
+
127
+ TestFBP (BiConsumer <ConsumerRecord <?, ?>, Exception > recoverer , BackOff backOff ,
128
+ CommonErrorHandler fallbackHandler ) {
129
+
130
+ super (recoverer , backOff , fallbackHandler );
131
+ }
132
+
133
+ }
117
134
}
0 commit comments