Skip to content

Commit 655cbee

Browse files
garyrussellartembilan
authored andcommitted
Embedded Kafka SeekToBeginning if needed
If the initial `poll()` used to force the subscription returns any records, seek those partitions to beginning instead of discarding.
1 parent 74e5956 commit 655cbee

File tree

2 files changed

+46
-2
lines changed

2 files changed

+46
-2
lines changed

spring-kafka-test/src/main/java/org/springframework/kafka/test/rule/KafkaEmbedded.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import org.apache.kafka.clients.admin.NewTopic;
4444
import org.apache.kafka.clients.consumer.Consumer;
4545
import org.apache.kafka.clients.consumer.ConsumerRebalanceListener;
46+
import org.apache.kafka.clients.consumer.ConsumerRecords;
4647
import org.apache.kafka.common.TopicPartition;
4748
import org.apache.kafka.common.utils.Time;
4849
import org.junit.rules.ExternalResource;
@@ -410,7 +411,18 @@ public void onPartitionsAssigned(Collection<TopicPartition> partitions) {
410411
}
411412

412413
});
413-
consumer.poll(0); // force assignment
414+
ConsumerRecords<?, ?> records = consumer.poll(0); // force assignment
415+
if (records.count() > 0) {
416+
if (logger.isDebugEnabled()) {
417+
logger.debug("Records received on initial poll for assignment; re-seeking to beginning; "
418+
+ records.partitions().stream()
419+
.flatMap(p -> records.records(p).stream())
420+
// map to same format as send metadata toString()
421+
.map(r -> r.topic() + "-" + r.partition() + "@" + r.offset())
422+
.collect(Collectors.toList()));
423+
}
424+
consumer.seekToBeginning(records.partitions());
425+
}
414426
assertThat(consumerLatch.await(30, TimeUnit.SECONDS))
415427
.as("Failed to be assigned partitions from the embedded topics")
416428
.isTrue();

spring-kafka-test/src/test/java/org/springframework/kafka/test/rule/AddressableEmbeddedBrokerTests.java

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,23 @@
2020

2121
import java.io.IOException;
2222
import java.net.ServerSocket;
23+
import java.util.Map;
2324

2425
import javax.net.ServerSocketFactory;
2526

27+
import org.apache.kafka.clients.consumer.Consumer;
28+
import org.apache.kafka.clients.consumer.ConsumerConfig;
29+
import org.apache.kafka.clients.consumer.KafkaConsumer;
30+
import org.apache.kafka.clients.producer.KafkaProducer;
31+
import org.apache.kafka.clients.producer.Producer;
32+
import org.apache.kafka.clients.producer.ProducerRecord;
2633
import org.junit.Test;
2734
import org.junit.runner.RunWith;
2835

2936
import org.springframework.beans.factory.annotation.Autowired;
3037
import org.springframework.context.annotation.Bean;
3138
import org.springframework.context.annotation.Configuration;
39+
import org.springframework.kafka.test.utils.KafkaTestUtils;
3240
import org.springframework.test.context.junit4.SpringRunner;
3341

3442
/**
@@ -41,6 +49,8 @@
4149
@RunWith(SpringRunner.class)
4250
public class AddressableEmbeddedBrokerTests {
4351

52+
private static final String TEST_EMBEDDED = "testEmbedded";
53+
4454
@Autowired
4555
private Config config;
4656

@@ -56,14 +66,36 @@ public void testKafkaEmbedded() {
5666
.isEqualTo(System.getProperty(KafkaEmbedded.SPRING_EMBEDDED_ZOOKEEPER_CONNECT));
5767
}
5868

69+
@Test
70+
public void testLateStartedConsumer() throws Exception {
71+
Map<String, Object> consumerProps = KafkaTestUtils.consumerProps(TEST_EMBEDDED, "false", this.broker);
72+
consumerProps.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
73+
Consumer<Integer, String> consumer = new KafkaConsumer<>(consumerProps);
74+
this.broker.consumeFromAnEmbeddedTopic(consumer, TEST_EMBEDDED);
75+
76+
Producer<String, Object> producer = new KafkaProducer<>(KafkaTestUtils.producerProps(this.broker));
77+
producer.send(new ProducerRecord<String, Object>(TEST_EMBEDDED, "foo"));
78+
producer.close();
79+
KafkaTestUtils.getSingleRecord(consumer, TEST_EMBEDDED);
80+
81+
consumerProps = KafkaTestUtils.consumerProps("another" + TEST_EMBEDDED, "false", this.broker);
82+
consumerProps.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
83+
Consumer<Integer, String> consumer2 = new KafkaConsumer<>(consumerProps);
84+
this.broker.consumeFromAnEmbeddedTopic(consumer2, TEST_EMBEDDED);
85+
KafkaTestUtils.getSingleRecord(consumer2, TEST_EMBEDDED);
86+
87+
consumer.close();
88+
consumer2.close();
89+
}
90+
5991
@Configuration
6092
public static class Config {
6193

6294
private int port;
6395

6496
@Bean
6597
public KafkaEmbedded broker() throws IOException {
66-
KafkaEmbedded broker = new KafkaEmbedded(1);
98+
KafkaEmbedded broker = new KafkaEmbedded(1, true, TEST_EMBEDDED);
6799
ServerSocket ss = ServerSocketFactory.getDefault().createServerSocket(0);
68100
this.port = ss.getLocalPort();
69101
ss.close();

0 commit comments

Comments
 (0)