140
140
* @author Lukasz Kaminski
141
141
* @author Ray Chuan Tay
142
142
* @author Daniel Gentes
143
+ * @author Soby Chacko
144
+ * @author Wang Zhiyang
145
+ * @author Mikael Carlstedt
143
146
*/
144
147
@ EmbeddedKafka (topics = { KafkaMessageListenerContainerTests .topic1 , KafkaMessageListenerContainerTests .topic2 ,
145
148
KafkaMessageListenerContainerTests .topic3 , KafkaMessageListenerContainerTests .topic4 ,
@@ -3474,25 +3477,33 @@ public void testCooperativeRebalance() throws Exception {
3474
3477
3475
3478
@ Test
3476
3479
void testCommitRebalanceInProgressBatch () throws Exception {
3477
- testCommitRebalanceInProgressGuts (AckMode .BATCH , 2 , commits -> {
3478
- assertThat (commits ).hasSize (3 );
3480
+ testCommitRebalanceInProgressGuts (AckMode .BATCH , 3 , commits -> {
3481
+ assertThat (commits ).hasSize (5 );
3479
3482
assertThat (commits .get (0 )).hasSize (2 ); // assignment
3480
- assertThat (commits .get (1 )).hasSize (2 ); // batch commit
3481
- assertThat (commits .get (2 )).hasSize (2 ); // GH-2489: offsets for both partition should be re-committed before partition 1 is revoked
3483
+ assertThat (commits .get (1 )).hasSize (2 ); // batch commit which should fail due to rebalance in progress
3484
+ assertThat (commits .get (2 )).hasSize (2 ); // commit retry which should fail due to rebalance in progress
3485
+ assertThat (commits .get (3 )).hasSize (1 ); // GH-3186: additional batch commit with only one partition which should be successful
3486
+ assertThat (commits .get (4 )).hasSize (1 ); // GH-2489: offsets for both uncommitted partition should be re-committed before partition 0 is revoked
3487
+ assertThat (commits .get (4 ).get (new TopicPartition ("foo" , 0 )))
3488
+ .isNotNull ()
3489
+ .extracting (OffsetAndMetadata ::offset )
3490
+ .isEqualTo (2L );
3482
3491
});
3483
3492
}
3484
3493
3485
3494
@ Test
3486
3495
void testCommitRebalanceInProgressRecord () throws Exception {
3487
- testCommitRebalanceInProgressGuts (AckMode .RECORD , 5 , commits -> {
3488
- assertThat (commits ).hasSize (6 );
3496
+ testCommitRebalanceInProgressGuts (AckMode .RECORD , 6 , commits -> {
3497
+ assertThat (commits ).hasSize (8 );
3489
3498
assertThat (commits .get (0 )).hasSize (2 ); // assignment
3490
- assertThat (commits .get (1 )).hasSize (1 ); // 4 individual commits
3499
+ assertThat (commits .get (1 )).hasSize (1 ); // 4 individual commits which should fail due to rebalance in progress
3491
3500
assertThat (commits .get (2 )).hasSize (1 );
3492
3501
assertThat (commits .get (3 )).hasSize (1 );
3493
3502
assertThat (commits .get (4 )).hasSize (1 );
3494
- assertThat (commits .get (5 )).hasSize (2 ); // GH-2489: offsets for both partition should be re-committed before partition 1 is revoked
3495
- assertThat (commits .get (5 ).get (new TopicPartition ("foo" , 1 )))
3503
+ assertThat (commits .get (5 )).hasSize (2 ); // commit retry which should fail due to rebalance in progress
3504
+ assertThat (commits .get (6 )).hasSize (1 ); // GH-3186: additional commit which should be successful
3505
+ assertThat (commits .get (7 )).hasSize (1 ); // GH-2489: offsets for both partition should be re-committed before partition 0 is revoked
3506
+ assertThat (commits .get (7 ).get (new TopicPartition ("foo" , 0 )))
3496
3507
.isNotNull ()
3497
3508
.extracting (om -> om .offset ())
3498
3509
.isEqualTo (2L );
@@ -3516,25 +3527,37 @@ private void testCommitRebalanceInProgressGuts(AckMode ackMode, int exceptions,
3516
3527
records .put (new TopicPartition ("foo" , 1 ), Arrays .asList (
3517
3528
new ConsumerRecord <>("foo" , 1 , 0L , 1 , "foo" ),
3518
3529
new ConsumerRecord <>("foo" , 1 , 1L , 1 , "bar" )));
3530
+ final Map <TopicPartition , List <ConsumerRecord <Integer , String >>> additionalRecords = Collections .singletonMap (
3531
+ new TopicPartition ("foo" , 1 ),
3532
+ Collections .singletonList (new ConsumerRecord <>("foo" , 1 , 2L , 1 , "foo" )));
3519
3533
ConsumerRecords <Integer , String > consumerRecords = new ConsumerRecords <>(records );
3534
+ ConsumerRecords <Integer , String > additionalConsumerRecords = new ConsumerRecords <>(additionalRecords );
3520
3535
ConsumerRecords <Integer , String > emptyRecords = new ConsumerRecords <>(Collections .emptyMap ());
3521
- AtomicBoolean first = new AtomicBoolean (true );
3522
- AtomicInteger rebalance = new AtomicInteger ();
3536
+ AtomicInteger pollIteration = new AtomicInteger ();
3523
3537
AtomicReference <ConsumerRebalanceListener > rebal = new AtomicReference <>();
3524
- CountDownLatch latch = new CountDownLatch (2 );
3538
+ CountDownLatch latch = new CountDownLatch (3 );
3525
3539
given (consumer .poll (any (Duration .class ))).willAnswer (i -> {
3526
3540
Thread .sleep (50 );
3527
- int call = rebalance .getAndIncrement ();
3541
+ int call = pollIteration .getAndIncrement ();
3542
+ final ConsumerRecords <Integer , String > result ;
3528
3543
if (call == 0 ) {
3529
3544
rebal .get ().onPartitionsRevoked (Collections .emptyList ());
3530
3545
rebal .get ().onPartitionsAssigned (records .keySet ());
3546
+ result = consumerRecords ;
3531
3547
}
3532
3548
else if (call == 1 ) {
3549
+ result = additionalConsumerRecords ;
3550
+ }
3551
+ else if (call == 2 ) {
3533
3552
rebal .get ().onPartitionsRevoked (Collections .singletonList (topicPartition0 ));
3534
3553
rebal .get ().onPartitionsAssigned (Collections .emptyList ());
3554
+ result = emptyRecords ;
3555
+ }
3556
+ else {
3557
+ result = emptyRecords ;
3535
3558
}
3536
3559
latch .countDown ();
3537
- return first . getAndSet ( false ) ? consumerRecords : emptyRecords ;
3560
+ return result ;
3538
3561
});
3539
3562
willAnswer (invoc -> {
3540
3563
rebal .set (invoc .getArgument (1 ));
0 commit comments