关于Java:如何测试ConsumerAwareRebalanceListener?

How to test a ConsumerAwareRebalanceListener?

我使用Spring Boot 2.0.6开发了一个@KafkaListener,它也带有ConsumerAwareRebalanceListener接口标记。我实现了onPartitionsAssigned方法,其中将后退偏移固定时间量,例如60秒。

到目前为止一切顺利。

如何使用Spring Kafka给我的工具测试上述用例?我以为我需要启动一个Kafka代理(即EmbeddedKafka),然后停止侦听器,然后再次重新启动它,以测试它是否再次读取了过去60秒内到达的消息。

有人可以帮我吗?我在Google上搜索了一下,但没有找到任何东西。
非常感谢。


1
2
3
4
5
6
7
8
9
10
11
public class MyRebalanceListener implements ConsumerAwareRebalanceListener {

    @Override
    public void onPartitionsAssigned(Consumer<?, ?> consumer, Collection<TopicPartition> partitions) {
        long rewindTo = System.currentTimeMillis() - 60000;
        Map<TopicPartition, OffsetAndTimestamp> offsetsForTimes = consumer.offsetsForTimes(partitions.stream()
                .collect(Collectors.toMap(tp -> tp, tp -> rewindTo)));
        offsetsForTimes.forEach((k, v) -> consumer.seek(k, v.offset()));
    }

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
@RunWith(SpringRunner.class)
@SpringBootTest
public class So52973119ApplicationTests {

    @Test
    public void rebalanceListenerTests() {
        MyRebalanceListener listener = new MyRebalanceListener();
        Consumer<?, ?> consumer = mock(Consumer.class);
        AtomicLong expected = new AtomicLong(System.currentTimeMillis() - 60_000);
        given(consumer.offsetsForTimes(anyMap())).willAnswer(i -> {
            AtomicLong offset = new AtomicLong();
            Map<TopicPartition, OffsetAndTimestamp> offsetsForTimes = new HashMap<>();
            Map<TopicPartition, Long> argument = i.getArgument(0);
            argument.forEach((k, v) -> {
                offsetsForTimes.put(k, new OffsetAndTimestamp(offset.incrementAndGet(), 0L));
                assertThat(v).isBetween(expected.get(), expected.get() + 1_000);
            });
            return offsetsForTimes ;
        });
        TopicPartition t1 = new TopicPartition("foo", 0);
        TopicPartition t2 = new TopicPartition("foo", 1);
        List<TopicPartition> partitions = new ArrayList<>();
        partitions.add(t1);
        partitions.add(t2);
        listener.onPartitionsAssigned(consumer, partitions);
        verify(consumer).seek(t1, 1);
        verify(consumer).seek(t2, 2);
    }

}


@KafkaListener具有一个:

1
2
3
4
5
6
7
/**
 * The unique identifier of the container managing for this endpoint.
 * <p>If none is specified an auto-generated one is provided.
 * @return the {@code id} for the container managing for this endpoint.
 * @see org.springframework.kafka.config.KafkaListenerEndpointRegistry#getListenerContainer(String)
 */

String id() default"";

属性,因此您可以通过提到的KafkaListenerEndpointRegistry访问其MessageListenerContainer,您可以简单地@Autowired进入基于Spring Testing Framework的测试类。然后,您可以在测试方法中真正地stop()start()MessageListenerContainer

还请注意@KafkaListener如何也具有autoStartup()属性。