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
45
50
/**
46
51
* @author Gary Russell
52
+ * @author Francois Rosiere
47
53
* @since 3.0.3
48
54
*
49
55
*/
@@ -52,15 +58,6 @@ public class FailedBatchProcessorTests {
52
58
@ SuppressWarnings ({ "rawtypes" , "unchecked" })
53
59
@ Test
54
60
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
61
CommonErrorHandler mockEH = mock (CommonErrorHandler .class );
65
62
willThrow (new IllegalStateException ("fallback" )).given (mockEH ).handleBatch (any (), any (), any (), any (), any ());
66
63
@@ -83,15 +80,6 @@ records, mock(Consumer.class), mock(MessageListenerContainer.class), mock(Runnab
83
80
@ SuppressWarnings ({ "rawtypes" , "unchecked" })
84
81
@ Test
85
82
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
83
CommonErrorHandler mockEH = mock (CommonErrorHandler .class );
96
84
willThrow (new IllegalStateException ("fallback" )).given (mockEH ).handleBatch (any (), any (), any (), any (), any ());
97
85
@@ -114,4 +102,34 @@ records, mock(Consumer.class), mock(MessageListenerContainer.class), mock(Runnab
114
102
assertThat (output ).contains ("Record not found in batch: topic-42@123;" );
115
103
}
116
104
105
+ @ Test
106
+ void testExceptionDuringCommit () {
107
+ CommonErrorHandler mockEH = mock (CommonErrorHandler .class );
108
+ willThrow (new IllegalStateException ("ise" )).given (mockEH ).handleBatch (any (), any (), any (), any (), any ());
109
+
110
+ ConsumerRecord rec1 = new ConsumerRecord ("topic" , 0 , 0L , null , null );
111
+ ConsumerRecord rec2 = new ConsumerRecord ("topic" , 0 , 1L , null , null );
112
+ ConsumerRecord rec3 = new ConsumerRecord ("topic" , 0 , 2L , null , null );
113
+
114
+ ConsumerRecords records = new ConsumerRecords (Map .of (new TopicPartition ("topic" , 0 ), List .of (rec1 , rec2 , rec3 )));
115
+ TestFBP testFBP = new TestFBP ((rec , ex ) -> { }, new FixedBackOff (2L , 2L ), mockEH );
116
+ final Consumer consumer = mock (Consumer .class );
117
+ willThrow (new RebalanceInProgressException ("rebalance in progress" )).given (consumer ).commitSync (anyMap (), any ());
118
+ final MessageListenerContainer mockMLC = mock (MessageListenerContainer .class );
119
+ willReturn (new ContainerProperties ("topic" )).given (mockMLC ).getContainerProperties ();
120
+ assertThatExceptionOfType (KafkaException .class ).isThrownBy (() ->
121
+ testFBP .handle (new BatchListenerFailedException ("topic" , rec2 ),
122
+ records , consumer , mockMLC , mock (Runnable .class ))
123
+ ).withMessage ("Seek to current after exception" );
124
+ }
125
+
126
+ static class TestFBP extends FailedBatchProcessor {
127
+
128
+ TestFBP (BiConsumer <ConsumerRecord <?, ?>, Exception > recoverer , BackOff backOff ,
129
+ CommonErrorHandler fallbackHandler ) {
130
+
131
+ super (recoverer , backOff , fallbackHandler );
132
+ }
133
+
134
+ }
117
135
}
0 commit comments