/* * Copyright 2016-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.integration.samples.dsl.kafka; import java.util.Map; import org.apache.kafka.clients.consumer.ConsumerConfig; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.WebApplicationType; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.kafka.KafkaProperties; import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.integration.annotation.Gateway; import org.springframework.integration.annotation.MessagingGateway; import org.springframework.integration.dsl.IntegrationFlow; import org.springframework.integration.dsl.IntegrationFlows; import org.springframework.integration.dsl.context.IntegrationFlowContext; import org.springframework.integration.kafka.dsl.Kafka; import org.springframework.kafka.core.ConsumerFactory; import org.springframework.kafka.core.DefaultKafkaConsumerFactory; import org.springframework.kafka.core.KafkaTemplate; import org.springframework.kafka.support.KafkaHeaders; import org.springframework.messaging.Message; import org.springframework.messaging.handler.annotation.Header; /** * @author Gary Russell * @author Artem Bilan * @since 4.3 */ @SpringBootApplication @EnableConfigurationProperties(KafkaAppProperties.class) public class Application { public static void main(String[] args) throws Exception { ConfigurableApplicationContext context = new SpringApplicationBuilder(Application.class) .web(WebApplicationType.NONE) .run(args); context.getBean(Application.class).runDemo(context); context.close(); } private void runDemo(ConfigurableApplicationContext context) { KafkaGateway kafkaGateway = context.getBean(KafkaGateway.class); System.out.println("Sending 10 messages..."); for (int i = 0; i < 10; i++) { String message = "foo" + i; System.out.println("Send to Kafka: " + message); kafkaGateway.sendToKafka(message, this.properties.getTopic()); } for (int i = 0; i < 10; i++) { Message<?> received = kafkaGateway.receiveFromKafka(); System.out.println(received); } System.out.println("Adding an adapter for a second topic and sending 10 messages..."); addAnotherListenerForTopics(this.properties.getNewTopic()); for (int i = 0; i < 10; i++) { String message = "bar" + i; System.out.println("Send to Kafka: " + message); kafkaGateway.sendToKafka(message, this.properties.getNewTopic()); } for (int i = 0; i < 10; i++) { Message<?> received = kafkaGateway.receiveFromKafka(); System.out.println(received); } context.close(); } @Autowired private KafkaAppProperties properties; @MessagingGateway public interface KafkaGateway { @Gateway(requestChannel = "toKafka.input") void sendToKafka(String payload, @Header(KafkaHeaders.TOPIC) String topic); @Gateway(replyChannel = "fromKafka", replyTimeout = 10000) Message<?> receiveFromKafka(); } @Bean public IntegrationFlow toKafka(KafkaTemplate<?, ?> kafkaTemplate) { return f -> f .handle(Kafka.outboundChannelAdapter(kafkaTemplate) .messageKey(this.properties.getMessageKey())); } @Bean public IntegrationFlow fromKafka(ConsumerFactory<?, ?> consumerFactory) { return IntegrationFlows .from(Kafka.messageDrivenChannelAdapter(consumerFactory, this.properties.getTopic())) .channel(c -> c.queue("fromKafka")) .get(); } @Autowired private IntegrationFlowContext flowContext; @Autowired private KafkaProperties kafkaProperties; public void addAnotherListenerForTopics(String... topics) { Map<String, Object> consumerProperties = kafkaProperties.buildConsumerProperties(); // change the group id so we don't revoke the other partitions. consumerProperties.put(ConsumerConfig.GROUP_ID_CONFIG, consumerProperties.get(ConsumerConfig.GROUP_ID_CONFIG) + "x"); IntegrationFlow flow = IntegrationFlows .from(Kafka.messageDrivenChannelAdapter( new DefaultKafkaConsumerFactory<String, String>(consumerProperties), topics)) .channel("fromKafka") .get(); this.flowContext.registration(flow).register(); } }