Search in sources :

Example 1 with GenericMessageListenerContainer

use of org.springframework.kafka.listener.GenericMessageListenerContainer in project spring-kafka by spring-projects.

the class ReplyingKafkaTemplateTests method nullDuration.

@SuppressWarnings({ "rawtypes", "unchecked" })
@Test
void nullDuration() throws Exception {
    ProducerFactory pf = mock(ProducerFactory.class);
    Producer producer = mock(Producer.class);
    willAnswer(invocation -> {
        Callback callback = invocation.getArgument(1);
        SettableListenableFuture<Object> future = new SettableListenableFuture<>();
        future.set("done");
        callback.onCompletion(new RecordMetadata(new TopicPartition("foo", 0), 0L, 0, 0L, 0, 0), null);
        return future;
    }).given(producer).send(any(), any());
    given(pf.createProducer()).willReturn(producer);
    GenericMessageListenerContainer container = mock(GenericMessageListenerContainer.class);
    ContainerProperties properties = new ContainerProperties("two");
    given(container.getContainerProperties()).willReturn(properties);
    ReplyingKafkaTemplate template = new ReplyingKafkaTemplate(pf, container);
    template.start();
    Message<?> msg = MessageBuilder.withPayload("foo".getBytes()).setHeader(KafkaHeaders.TOPIC, "foo").build();
    // was NPE here
    template.sendAndReceive(new ProducerRecord("foo", 0, "bar", "baz"), null).getSendFuture().get();
}
Also used : SettableListenableFuture(org.springframework.util.concurrent.SettableListenableFuture) DefaultKafkaProducerFactory(org.springframework.kafka.core.DefaultKafkaProducerFactory) ProducerFactory(org.springframework.kafka.core.ProducerFactory) RecordMetadata(org.apache.kafka.clients.producer.RecordMetadata) Callback(org.apache.kafka.clients.producer.Callback) Producer(org.apache.kafka.clients.producer.Producer) TopicPartition(org.apache.kafka.common.TopicPartition) ContainerProperties(org.springframework.kafka.listener.ContainerProperties) ProducerRecord(org.apache.kafka.clients.producer.ProducerRecord) GenericMessageListenerContainer(org.springframework.kafka.listener.GenericMessageListenerContainer) Test(org.junit.jupiter.api.Test)

Example 2 with GenericMessageListenerContainer

use of org.springframework.kafka.listener.GenericMessageListenerContainer in project spring-kafka by spring-projects.

the class ReplyingKafkaTemplateTests method testAggregateOrphansNotStored.

@SuppressWarnings({ "rawtypes", "unchecked" })
@Test
public void testAggregateOrphansNotStored() throws Exception {
    GenericMessageListenerContainer container = mock(GenericMessageListenerContainer.class);
    ContainerProperties properties = new ContainerProperties("two");
    properties.setAckMode(AckMode.MANUAL);
    given(container.getContainerProperties()).willReturn(properties);
    ProducerFactory pf = mock(ProducerFactory.class);
    Producer producer = mock(Producer.class);
    given(pf.createProducer()).willReturn(producer);
    AtomicReference<byte[]> correlation = new AtomicReference<>();
    willAnswer(invocation -> {
        ProducerRecord rec = invocation.getArgument(0);
        correlation.set(rec.headers().lastHeader(KafkaHeaders.CORRELATION_ID).value());
        return new SettableListenableFuture<>();
    }).given(producer).send(any(), any());
    AggregatingReplyingKafkaTemplate template = new AggregatingReplyingKafkaTemplate(pf, container, (list, timeout) -> true);
    template.setDefaultReplyTimeout(Duration.ofSeconds(30));
    template.start();
    List<ConsumerRecord> records = new ArrayList<>();
    ConsumerRecord record = new ConsumerRecord("two", 0, 0L, null, "test1");
    RequestReplyFuture future = template.sendAndReceive(new ProducerRecord("one", null, "test"));
    record.headers().add(new RecordHeader(KafkaHeaders.CORRELATION_ID, correlation.get()));
    records.add(record);
    Consumer consumer = mock(Consumer.class);
    template.onMessage(records, consumer);
    assertThat(future.get(10, TimeUnit.SECONDS)).isNotNull();
    assertThat(KafkaTestUtils.getPropertyValue(template, "pending", Map.class)).hasSize(0);
    Map<TopicPartition, OffsetAndMetadata> offsets = new HashMap<>();
    offsets.put(new TopicPartition("two", 0), new OffsetAndMetadata(1));
    verify(consumer).commitSync(offsets, Duration.ofSeconds(30));
    // simulate redelivery after completion
    template.onMessage(records, consumer);
    assertThat(KafkaTestUtils.getPropertyValue(template, "pending", Map.class)).hasSize(0);
    template.stop();
    template.destroy();
}
Also used : SettableListenableFuture(org.springframework.util.concurrent.SettableListenableFuture) HashMap(java.util.HashMap) DefaultKafkaProducerFactory(org.springframework.kafka.core.DefaultKafkaProducerFactory) ProducerFactory(org.springframework.kafka.core.ProducerFactory) ArrayList(java.util.ArrayList) AtomicReference(java.util.concurrent.atomic.AtomicReference) ConsumerRecord(org.apache.kafka.clients.consumer.ConsumerRecord) Producer(org.apache.kafka.clients.producer.Producer) Consumer(org.apache.kafka.clients.consumer.Consumer) TopicPartition(org.apache.kafka.common.TopicPartition) ContainerProperties(org.springframework.kafka.listener.ContainerProperties) ProducerRecord(org.apache.kafka.clients.producer.ProducerRecord) OffsetAndMetadata(org.apache.kafka.clients.consumer.OffsetAndMetadata) GenericMessageListenerContainer(org.springframework.kafka.listener.GenericMessageListenerContainer) RecordHeader(org.apache.kafka.common.header.internals.RecordHeader) Test(org.junit.jupiter.api.Test)

Example 3 with GenericMessageListenerContainer

use of org.springframework.kafka.listener.GenericMessageListenerContainer in project vividus by vividus-framework.

the class KafkaSteps method startKafkaListener.

/**
 * Starts the Kafka consumer with the provided configuration to listen the specified topics. The consumer must be
 * stopped when it's not needed.
 *
 * @param consumerKey The key of the producer configuration
 * @param topics      The comma-separated set of topics to listen
 */
@When("I start consuming messages from `$consumerKey` Kafka topics `$topics`")
public void startKafkaListener(String consumerKey, Set<String> topics) {
    stopListener(getListeners().remove(consumerKey), false);
    BlockingQueue<String> messageQueue = new LinkedBlockingDeque<>();
    testContext.get(MESSAGES_KEY, HashMap::new).put(consumerKey, messageQueue);
    ContainerProperties containerProperties = new ContainerProperties(topics.toArray(new String[0]));
    containerProperties.setMessageListener((MessageListener<String, String>) data -> messageQueue.add(data.value()));
    GenericMessageListenerContainer<String, String> container = new KafkaMessageListenerContainer<>(consumerFactories.get(consumerKey), containerProperties);
    container.start();
    getListeners().put(consumerKey, container);
    LOGGER.info("Kafka message listener is started");
}
Also used : GenericMessageListenerContainer(org.springframework.kafka.listener.GenericMessageListenerContainer) VariableContext(org.vividus.context.VariableContext) Collectors.groupingBy(java.util.stream.Collectors.groupingBy) LoggerFactory(org.slf4j.LoggerFactory) TimeoutException(java.util.concurrent.TimeoutException) HashMap(java.util.HashMap) Collectors.collectingAndThen(java.util.stream.Collectors.collectingAndThen) Function(java.util.function.Function) ArrayList(java.util.ArrayList) When(org.jbehave.core.annotations.When) DefaultKafkaProducerFactory(org.springframework.kafka.core.DefaultKafkaProducerFactory) ContainerProperties(org.springframework.kafka.listener.ContainerProperties) StringDeserializer(org.apache.kafka.common.serialization.StringDeserializer) KafkaTemplate(org.springframework.kafka.core.KafkaTemplate) DurationBasedWaiter(org.vividus.util.wait.DurationBasedWaiter) VariableScope(org.vividus.variable.VariableScope) Collectors.mapping(java.util.stream.Collectors.mapping) Duration(java.time.Duration) Map(java.util.Map) ComparisonRule(org.vividus.steps.ComparisonRule) StringSerializer(org.apache.kafka.common.serialization.StringSerializer) Map.entry(java.util.Map.entry) StringUtils.substringAfter(org.apache.commons.lang3.StringUtils.substringAfter) ProducerConfig(org.apache.kafka.clients.producer.ProducerConfig) IPropertyParser(org.vividus.util.property.IPropertyParser) Logger(org.slf4j.Logger) DefaultKafkaConsumerFactory(org.springframework.kafka.core.DefaultKafkaConsumerFactory) AfterStory(org.jbehave.core.annotations.AfterStory) Set(java.util.Set) BlockingQueue(java.util.concurrent.BlockingQueue) ConsumerConfig(org.apache.kafka.clients.consumer.ConsumerConfig) Collectors(java.util.stream.Collectors) MessageListener(org.springframework.kafka.listener.MessageListener) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) List(java.util.List) ConsumerRecord(org.apache.kafka.clients.consumer.ConsumerRecord) Matcher(org.hamcrest.Matcher) LinkedBlockingDeque(java.util.concurrent.LinkedBlockingDeque) SoftAssert(org.vividus.softassert.SoftAssert) StringUtils.substringBefore(org.apache.commons.lang3.StringUtils.substringBefore) TestContext(org.vividus.testcontext.TestContext) KafkaMessageListenerContainer(org.springframework.kafka.listener.KafkaMessageListenerContainer) LinkedBlockingDeque(java.util.concurrent.LinkedBlockingDeque) ContainerProperties(org.springframework.kafka.listener.ContainerProperties) KafkaMessageListenerContainer(org.springframework.kafka.listener.KafkaMessageListenerContainer) When(org.jbehave.core.annotations.When)

Example 4 with GenericMessageListenerContainer

use of org.springframework.kafka.listener.GenericMessageListenerContainer in project vividus by vividus-framework.

the class KafkaStepsTests method shouldStopStartedKafkaListenerIfNewKafkaListenerIsCreated.

@SuppressWarnings({ "rawtypes", "unchecked" })
@Test
void shouldStopStartedKafkaListenerIfNewKafkaListenerIsCreated() {
    try (MockedConstruction<KafkaMessageListenerContainer> construction = Mockito.mockConstruction(KafkaMessageListenerContainer.class, withSettings().extraInterfaces(GenericMessageListenerContainer.class))) {
        String topic = "topic";
        String consumerKey = KEY2;
        Map<String, GenericMessageListenerContainer<String, String>> listeners = new HashMap<>();
        mockListeners(listeners);
        when(testContext.get(eq(ConsumerRecord.class), any(Supplier.class))).thenReturn(new HashMap<>());
        kafkaSteps.startKafkaListener(consumerKey, Set.of(topic));
        KafkaMessageListenerContainer container = construction.constructed().get(0);
        assertThat(listeners.values(), hasSize(1));
        assertEquals(container, listeners.get(consumerKey));
        kafkaSteps.startKafkaListener(consumerKey, Set.of(topic));
        assertThat(listeners.values(), hasSize(1));
        assertEquals(construction.constructed().get(1), listeners.get(consumerKey));
        assertThat(construction.constructed(), hasSize(2));
        String listenerIsStarted = "Kafka message listener is started";
        assertThat(logger.getLoggingEvents(), is(List.of(info(listenerIsStarted), info(LISTENER_IS_STOPPED), info(listenerIsStarted))));
    }
}
Also used : HashMap(java.util.HashMap) KafkaMessageListenerContainer(org.springframework.kafka.listener.KafkaMessageListenerContainer) Supplier(java.util.function.Supplier) GenericMessageListenerContainer(org.springframework.kafka.listener.GenericMessageListenerContainer) ConsumerRecord(org.apache.kafka.clients.consumer.ConsumerRecord) Test(org.junit.jupiter.api.Test)

Example 5 with GenericMessageListenerContainer

use of org.springframework.kafka.listener.GenericMessageListenerContainer in project spring-kafka by spring-projects.

the class ReplyingKafkaTemplateTests method requestTimeoutWithMessage.

@SuppressWarnings({ "rawtypes", "unchecked" })
@Test
void requestTimeoutWithMessage() {
    ProducerFactory pf = mock(ProducerFactory.class);
    Producer producer = mock(Producer.class);
    willAnswer(invocation -> {
        return new SettableListenableFuture<>();
    }).given(producer).send(any(), any());
    given(pf.createProducer()).willReturn(producer);
    GenericMessageListenerContainer container = mock(GenericMessageListenerContainer.class);
    ContainerProperties properties = new ContainerProperties("two");
    given(container.getContainerProperties()).willReturn(properties);
    ReplyingKafkaTemplate template = new ReplyingKafkaTemplate(pf, container);
    template.start();
    Message<?> msg = MessageBuilder.withPayload("foo".getBytes()).setHeader(KafkaHeaders.TOPIC, "foo").build();
    long t1 = System.currentTimeMillis();
    RequestReplyTypedMessageFuture<String, String, Foo> future = template.sendAndReceive(msg, Duration.ofMillis(10), new ParameterizedTypeReference<Foo>() {
    });
    try {
        future.get(10, TimeUnit.SECONDS);
    } catch (TimeoutException ex) {
        fail("get timed out");
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        fail("Interrupted");
    } catch (ExecutionException e) {
        assertThat(System.currentTimeMillis() - t1).isLessThan(3000L);
    }
}
Also used : SettableListenableFuture(org.springframework.util.concurrent.SettableListenableFuture) DefaultKafkaProducerFactory(org.springframework.kafka.core.DefaultKafkaProducerFactory) ProducerFactory(org.springframework.kafka.core.ProducerFactory) Producer(org.apache.kafka.clients.producer.Producer) ContainerProperties(org.springframework.kafka.listener.ContainerProperties) ExecutionException(java.util.concurrent.ExecutionException) GenericMessageListenerContainer(org.springframework.kafka.listener.GenericMessageListenerContainer) TimeoutException(java.util.concurrent.TimeoutException) Test(org.junit.jupiter.api.Test)

Aggregations

GenericMessageListenerContainer (org.springframework.kafka.listener.GenericMessageListenerContainer)5 Test (org.junit.jupiter.api.Test)4 DefaultKafkaProducerFactory (org.springframework.kafka.core.DefaultKafkaProducerFactory)4 ContainerProperties (org.springframework.kafka.listener.ContainerProperties)4 HashMap (java.util.HashMap)3 ConsumerRecord (org.apache.kafka.clients.consumer.ConsumerRecord)3 Producer (org.apache.kafka.clients.producer.Producer)3 ProducerFactory (org.springframework.kafka.core.ProducerFactory)3 SettableListenableFuture (org.springframework.util.concurrent.SettableListenableFuture)3 ArrayList (java.util.ArrayList)2 ExecutionException (java.util.concurrent.ExecutionException)2 TimeoutException (java.util.concurrent.TimeoutException)2 ProducerRecord (org.apache.kafka.clients.producer.ProducerRecord)2 TopicPartition (org.apache.kafka.common.TopicPartition)2 KafkaMessageListenerContainer (org.springframework.kafka.listener.KafkaMessageListenerContainer)2 Duration (java.time.Duration)1 List (java.util.List)1 Map (java.util.Map)1 Map.entry (java.util.Map.entry)1 Set (java.util.Set)1