|
1 | 1 | /* |
2 | | - * Copyright 2016-2020 the original author or authors. |
| 2 | + * Copyright 2016-2021 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. |
@@ -3142,6 +3142,53 @@ void commitAfterHandleManual() throws InterruptedException { |
3142 | 3142 | verify(consumer).commitSync(any(), any()); |
3143 | 3143 | } |
3144 | 3144 |
|
| 3145 | + @Test |
| 3146 | + @SuppressWarnings({ "unchecked", "rawtypes" }) |
| 3147 | + void stopImmediately() throws InterruptedException { |
| 3148 | + ConsumerFactory<Integer, String> cf = mock(ConsumerFactory.class); |
| 3149 | + Consumer<Integer, String> consumer = mock(Consumer.class); |
| 3150 | + given(cf.createConsumer(eq("grp"), eq("clientId"), isNull(), any())).willReturn(consumer); |
| 3151 | + Map<String, Object> cfProps = new HashMap<>(); |
| 3152 | + cfProps.put(ConsumerConfig.DEFAULT_API_TIMEOUT_MS_CONFIG, 45000); // wins |
| 3153 | + given(cf.getConfigurationProperties()).willReturn(cfProps); |
| 3154 | + final Map<TopicPartition, List<ConsumerRecord<Integer, String>>> records = |
| 3155 | + Map.of(new TopicPartition("foo", 0), Arrays.asList(new ConsumerRecord<>("foo", 0, 0L, 1, "foo"), |
| 3156 | + new ConsumerRecord<>("foo", 0, 1L, 1, "bar"))); |
| 3157 | + ConsumerRecords<Integer, String> consumerRecords = new ConsumerRecords<>(records); |
| 3158 | + ConsumerRecords<Integer, String> emptyRecords = new ConsumerRecords<>(Collections.emptyMap()); |
| 3159 | + AtomicBoolean first = new AtomicBoolean(true); |
| 3160 | + given(consumer.poll(any(Duration.class))).willAnswer(i -> { |
| 3161 | + Thread.sleep(50); |
| 3162 | + return first.getAndSet(false) ? consumerRecords : emptyRecords; |
| 3163 | + }); |
| 3164 | + TopicPartitionOffset[] topicPartition = new TopicPartitionOffset[] { |
| 3165 | + new TopicPartitionOffset("foo", 0) }; |
| 3166 | + ContainerProperties containerProps = new ContainerProperties(topicPartition); |
| 3167 | + containerProps.setGroupId("grp"); |
| 3168 | + containerProps.setClientId("clientId"); |
| 3169 | + containerProps.setStopImmediate(true); |
| 3170 | + AtomicInteger delivered = new AtomicInteger(); |
| 3171 | + AtomicReference<KafkaMessageListenerContainer> containerRef = new AtomicReference<>(); |
| 3172 | + containerProps.setMessageListener((MessageListener) r -> { |
| 3173 | + delivered.incrementAndGet(); |
| 3174 | + containerRef.get().stop(() -> { }); |
| 3175 | + }); |
| 3176 | + KafkaMessageListenerContainer<Integer, String> container = |
| 3177 | + new KafkaMessageListenerContainer<>(cf, containerProps); |
| 3178 | + containerRef.set(container); |
| 3179 | + CountDownLatch latch = new CountDownLatch(1); |
| 3180 | + container.setApplicationEventPublisher(event -> { |
| 3181 | + if (event instanceof ConsumerStoppedEvent) { |
| 3182 | + latch.countDown(); |
| 3183 | + } |
| 3184 | + }); |
| 3185 | + container.start(); |
| 3186 | + assertThat(latch.await(10, TimeUnit.SECONDS)).isTrue(); |
| 3187 | + container.stop(); |
| 3188 | + assertThat(delivered.get()).isEqualTo(1); |
| 3189 | + verify(consumer).commitSync(eq(Map.of(new TopicPartition("foo", 0), new OffsetAndMetadata(1L))), any()); |
| 3190 | + } |
| 3191 | + |
3145 | 3192 | private Consumer<?, ?> spyOnConsumer(KafkaMessageListenerContainer<Integer, String> container) { |
3146 | 3193 | Consumer<?, ?> consumer = |
3147 | 3194 | KafkaTestUtils.getPropertyValue(container, "listenerConsumer.consumer", Consumer.class); |
|
0 commit comments