Showing
7 changed files
with
209 additions
and
0 deletions
@@ -22,6 +22,7 @@ | @@ -22,6 +22,7 @@ | ||
22 | <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | 22 | <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
23 | <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> | 23 | <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> |
24 | <java.version>1.8</java.version> | 24 | <java.version>1.8</java.version> |
25 | + <spring-kafka.version>1.1.2.RELEASE</spring-kafka.version> | ||
25 | </properties> | 26 | </properties> |
26 | 27 | ||
27 | <dependencies> | 28 | <dependencies> |
@@ -31,6 +32,12 @@ | @@ -31,6 +32,12 @@ | ||
31 | </dependency> | 32 | </dependency> |
32 | 33 | ||
33 | <dependency> | 34 | <dependency> |
35 | + <groupId>org.springframework.kafka</groupId> | ||
36 | + <artifactId>spring-kafka</artifactId> | ||
37 | + <version>${spring-kafka.version}</version> | ||
38 | + </dependency> | ||
39 | + | ||
40 | + <dependency> | ||
34 | <groupId>org.springframework.boot</groupId> | 41 | <groupId>org.springframework.boot</groupId> |
35 | <artifactId>spring-boot-starter-test</artifactId> | 42 | <artifactId>spring-boot-starter-test</artifactId> |
36 | <scope>test</scope> | 43 | <scope>test</scope> |
1 | +package com.yoho.ops.kafka; | ||
2 | + | ||
3 | +import java.util.concurrent.CountDownLatch; | ||
4 | + | ||
5 | +import org.slf4j.Logger; | ||
6 | +import org.slf4j.LoggerFactory; | ||
7 | +import org.springframework.kafka.annotation.KafkaListener; | ||
8 | + | ||
9 | +public class Receiver { | ||
10 | + | ||
11 | + private static final Logger LOGGER = LoggerFactory.getLogger(Receiver.class); | ||
12 | + | ||
13 | + private CountDownLatch latch = new CountDownLatch(1); | ||
14 | + | ||
15 | + @KafkaListener(topics = "${kafka.topic.helloworld}") | ||
16 | + public void receive(String message) { | ||
17 | + LOGGER.info("received message='{}'", message); | ||
18 | + latch.countDown(); | ||
19 | + } | ||
20 | + | ||
21 | + public CountDownLatch getLatch() { | ||
22 | + return latch; | ||
23 | + } | ||
24 | +} |
1 | +package com.yoho.ops.kafka; | ||
2 | + | ||
3 | +import java.util.HashMap; | ||
4 | +import java.util.Map; | ||
5 | + | ||
6 | +import org.apache.kafka.clients.consumer.ConsumerConfig; | ||
7 | +import org.apache.kafka.common.serialization.StringDeserializer; | ||
8 | +import org.springframework.beans.factory.annotation.Value; | ||
9 | +import org.springframework.context.annotation.Bean; | ||
10 | +import org.springframework.context.annotation.Configuration; | ||
11 | +import org.springframework.kafka.annotation.EnableKafka; | ||
12 | +import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory; | ||
13 | +import org.springframework.kafka.core.ConsumerFactory; | ||
14 | +import org.springframework.kafka.core.DefaultKafkaConsumerFactory; | ||
15 | + | ||
16 | +@Configuration | ||
17 | +@EnableKafka | ||
18 | +public class ReceiverConfig { | ||
19 | + | ||
20 | + @Value("${kafka.servers.bootstrap}") | ||
21 | + private String bootstrapServers; | ||
22 | + | ||
23 | + @Bean | ||
24 | + public Map<String, Object> consumerConfigs() { | ||
25 | + Map<String, Object> props = new HashMap<>(); | ||
26 | + // list of host:port pairs used for establishing the initial connections | ||
27 | + // to the Kakfa cluster | ||
28 | + props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers); | ||
29 | + props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class); | ||
30 | + props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class); | ||
31 | + // consumer groups allow a pool of processes to divide the work of | ||
32 | + // consuming and processing records | ||
33 | + props.put(ConsumerConfig.GROUP_ID_CONFIG, "helloworld"); | ||
34 | + | ||
35 | + return props; | ||
36 | + } | ||
37 | + | ||
38 | + @Bean | ||
39 | + public ConsumerFactory<String, String> consumerFactory() { | ||
40 | + return new DefaultKafkaConsumerFactory<>(consumerConfigs()); | ||
41 | + } | ||
42 | + | ||
43 | + @Bean | ||
44 | + public ConcurrentKafkaListenerContainerFactory<String, String> kafkaListenerContainerFactory() { | ||
45 | + ConcurrentKafkaListenerContainerFactory<String, String> factory = | ||
46 | + new ConcurrentKafkaListenerContainerFactory<>(); | ||
47 | + factory.setConsumerFactory(consumerFactory()); | ||
48 | + | ||
49 | + return factory; | ||
50 | + } | ||
51 | + | ||
52 | + @Bean | ||
53 | + public Receiver receiver() { | ||
54 | + return new Receiver(); | ||
55 | + } | ||
56 | +} |
src/main/java/com/yoho/ops/kafka/Sender.java
0 → 100644
1 | +package com.yoho.ops.kafka; | ||
2 | + | ||
3 | +import org.slf4j.Logger; | ||
4 | +import org.slf4j.LoggerFactory; | ||
5 | +import org.springframework.beans.factory.annotation.Autowired; | ||
6 | +import org.springframework.kafka.core.KafkaTemplate; | ||
7 | +import org.springframework.kafka.support.SendResult; | ||
8 | +import org.springframework.util.concurrent.ListenableFuture; | ||
9 | +import org.springframework.util.concurrent.ListenableFutureCallback; | ||
10 | + | ||
11 | +public class Sender { | ||
12 | + | ||
13 | + private static final Logger LOGGER = LoggerFactory.getLogger(Sender.class); | ||
14 | + | ||
15 | + @Autowired | ||
16 | + private KafkaTemplate<String, String> kafkaTemplate; | ||
17 | + | ||
18 | + public void send(String topic, String message) { | ||
19 | + // the KafkaTemplate provides asynchronous send methods returning a | ||
20 | + // Future | ||
21 | + ListenableFuture<SendResult<String, String>> future = kafkaTemplate.send(topic, message); | ||
22 | + | ||
23 | + // you can register a callback with the listener to receive the result | ||
24 | + // of the send asynchronously | ||
25 | + future.addCallback(new ListenableFutureCallback<SendResult<String, String>>() { | ||
26 | + | ||
27 | + @Override | ||
28 | + public void onSuccess(SendResult<String, String> result) { | ||
29 | + LOGGER.info("sent message='{}' with offset={}", message, | ||
30 | + result.getRecordMetadata().offset()); | ||
31 | + } | ||
32 | + | ||
33 | + @Override | ||
34 | + public void onFailure(Throwable ex) { | ||
35 | + LOGGER.error("unable to send message='{}'", message, ex); | ||
36 | + } | ||
37 | + }); | ||
38 | + | ||
39 | + // alternatively, to block the sending thread, to await the result, | ||
40 | + // invoke the future's get() method | ||
41 | + } | ||
42 | +} |
1 | +package com.yoho.ops.kafka; | ||
2 | + | ||
3 | +import java.util.HashMap; | ||
4 | +import java.util.Map; | ||
5 | + | ||
6 | +import org.apache.kafka.clients.producer.ProducerConfig; | ||
7 | +import org.apache.kafka.common.serialization.StringSerializer; | ||
8 | +import org.springframework.beans.factory.annotation.Value; | ||
9 | +import org.springframework.context.annotation.Bean; | ||
10 | +import org.springframework.context.annotation.Configuration; | ||
11 | +import org.springframework.kafka.core.DefaultKafkaProducerFactory; | ||
12 | +import org.springframework.kafka.core.KafkaTemplate; | ||
13 | +import org.springframework.kafka.core.ProducerFactory; | ||
14 | + | ||
15 | +@Configuration | ||
16 | +public class SenderConfig { | ||
17 | + | ||
18 | + @Value("${kafka.servers.bootstrap}") | ||
19 | + private String bootstrapServers; | ||
20 | + | ||
21 | + @Bean | ||
22 | + public Map<String, Object> producerConfigs() { | ||
23 | + Map<String, Object> props = new HashMap<>(); | ||
24 | + // list of host:port pairs used for establishing the initial connections | ||
25 | + // to the Kakfa cluster | ||
26 | + props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers); | ||
27 | + props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class); | ||
28 | + props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class); | ||
29 | + // value to block, after which it will throw a TimeoutException | ||
30 | + props.put(ProducerConfig.MAX_BLOCK_MS_CONFIG, 5000); | ||
31 | + | ||
32 | + return props; | ||
33 | + } | ||
34 | + | ||
35 | + @Bean | ||
36 | + public ProducerFactory<String, String> producerFactory() { | ||
37 | + return new DefaultKafkaProducerFactory<>(producerConfigs()); | ||
38 | + } | ||
39 | + | ||
40 | + @Bean | ||
41 | + public KafkaTemplate<String, String> kafkaTemplate() { | ||
42 | + return new KafkaTemplate<>(producerFactory()); | ||
43 | + } | ||
44 | + | ||
45 | + @Bean | ||
46 | + public Sender sender() { | ||
47 | + return new Sender(); | ||
48 | + } | ||
49 | +} |
1 | +package com.yoho.ops.kafka; | ||
2 | + | ||
3 | +import static org.assertj.core.api.Assertions.assertThat; | ||
4 | + | ||
5 | +import java.util.concurrent.TimeUnit; | ||
6 | + | ||
7 | +import org.junit.Test; | ||
8 | +import org.junit.runner.RunWith; | ||
9 | +import org.springframework.beans.factory.annotation.Autowired; | ||
10 | +import org.springframework.boot.test.context.SpringBootTest; | ||
11 | +import org.springframework.test.context.junit4.SpringRunner; | ||
12 | + | ||
13 | +@RunWith(SpringRunner.class) | ||
14 | +@SpringBootTest | ||
15 | +public class SpringKafkaApplicationTests { | ||
16 | + | ||
17 | + @Autowired | ||
18 | + private Sender sender; | ||
19 | + | ||
20 | + @Autowired | ||
21 | + private Receiver receiver; | ||
22 | + | ||
23 | + @Test | ||
24 | + public void testReceive() throws Exception { | ||
25 | + sender.send("helloworld.t", "Hello Spring Kafka!"); | ||
26 | + | ||
27 | + Thread.sleep(100000); | ||
28 | + } | ||
29 | +} |
-
Please register or login to post a comment