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