Init.
This commit is contained in:
131
kafka-consumer/pom.xml
Normal file
131
kafka-consumer/pom.xml
Normal file
@@ -0,0 +1,131 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.ippon.trainning.kafkaintegrationtest</groupId>
|
||||
<artifactId>kafka-integration-test-parent</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>kafka-consumer</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
|
||||
<properties>
|
||||
<java.version>11</java.version>
|
||||
<jupiter.version>5.7.0</jupiter.version>
|
||||
<build-helper-maven-plugin.version>3.2.0</build-helper-maven-plugin.version>
|
||||
<integration-test.source.directory>src/integration-test/java</integration-test.source.directory>
|
||||
<integration-test.resources.directory>src/integration-test/resources</integration-test.resources.directory>
|
||||
<maven-failsafe-plugin.version>2.22.2</maven-failsafe-plugin.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.kafka</groupId>
|
||||
<artifactId>spring-kafka</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.ippon.trainning.kafkaintegrationtest</groupId>
|
||||
<artifactId>kafka-common-test</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.kafka</groupId>
|
||||
<artifactId>spring-kafka-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<version>${jupiter.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<version>${jupiter.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-params</artifactId>
|
||||
<version>${jupiter.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.awaitility</groupId>
|
||||
<artifactId>awaitility</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<!-- Mandatory for executable jar -->
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<classifier>exec</classifier>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<!-- Tests d'intégrations, ajout des dossiers sources + exécution -->
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>build-helper-maven-plugin</artifactId>
|
||||
<version>${build-helper-maven-plugin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>add-integration-test</id>
|
||||
<goals>
|
||||
<goal>add-test-source</goal>
|
||||
<goal>add-test-resource</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<sources>
|
||||
<source>${integration-test.source.directory}</source>
|
||||
</sources>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>${integration-test.resources.directory}</directory>
|
||||
</resource>
|
||||
</resources>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
<version>${maven-failsafe-plugin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>integration-test</goal>
|
||||
<goal>verify</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1,85 @@
|
||||
package com.ippon.trainning.kafkaintegrationtest.kafkaconsumer.consumer;
|
||||
|
||||
import com.ippon.trainning.kafkaintegrationtest.kafkacommontest.extension.EmbeddedKafkaExtension;
|
||||
import com.ippon.trainning.kafkaintegrationtest.kafkaconsumer.service.MessageService;
|
||||
import org.apache.kafka.common.serialization.StringSerializer;
|
||||
import org.awaitility.Durations;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.TestInstance;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.boot.test.context.TestConfiguration;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.kafka.core.DefaultKafkaProducerFactory;
|
||||
import org.springframework.kafka.core.KafkaTemplate;
|
||||
import org.springframework.kafka.core.ProducerFactory;
|
||||
import org.springframework.kafka.test.context.EmbeddedKafka;
|
||||
import org.springframework.test.context.ActiveProfiles;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.apache.kafka.clients.producer.ProducerConfig.*;
|
||||
import static org.awaitility.Awaitility.await;
|
||||
import static org.mockito.BDDMockito.then;
|
||||
|
||||
@ExtendWith({
|
||||
SpringExtension.class,
|
||||
MockitoExtension.class,
|
||||
EmbeddedKafkaExtension.class
|
||||
})
|
||||
@SpringBootTest(classes = {
|
||||
KafkaConsumerIT.KafkaConsumerITConfiguration.class
|
||||
}, properties = "spring.kafka.bootstrap-servers=${spring.embedded.kafka.brokers}")
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
@EmbeddedKafka
|
||||
@ActiveProfiles({"test"})
|
||||
public class KafkaConsumerIT {
|
||||
@TestConfiguration
|
||||
public static class KafkaConsumerITConfiguration {
|
||||
@Bean
|
||||
public DefaultKafkaProducerFactory<String, String> producerFactory(
|
||||
@Value("${server.kafka.bootstrapAddress}") String bootstrapAddress
|
||||
) {
|
||||
Map<String, Object> configProperties = Map.of(
|
||||
BOOTSTRAP_SERVERS_CONFIG, bootstrapAddress,
|
||||
KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class,
|
||||
VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class
|
||||
);
|
||||
|
||||
return new DefaultKafkaProducerFactory<>(configProperties);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public KafkaTemplate<String, String> kafkaTemplate(ProducerFactory<String, String> producerFactory) {
|
||||
return new KafkaTemplate<>(producerFactory);
|
||||
}
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private KafkaTemplate<String, String> kafkaTemplate;
|
||||
@Value("${server.kafka.topic}")
|
||||
private String topic;
|
||||
|
||||
@MockBean
|
||||
private MessageService messageService;
|
||||
|
||||
@Test
|
||||
void should_comsume_a_message_from_kafka_topic() {
|
||||
// given
|
||||
String key = UUID.randomUUID().toString();
|
||||
String message = "A message to consume";
|
||||
|
||||
// when
|
||||
kafkaTemplate.send(topic, key, message);
|
||||
|
||||
// then
|
||||
await().atMost(Durations.FIVE_SECONDS).untilAsserted(() -> then(messageService).should().handleMessage(key, message));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
server:
|
||||
kafka:
|
||||
bootstrapAddress: "${spring.embedded.kafka.brokers:}"
|
||||
topic: topic-test
|
||||
groupId: groupId-test
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.ippon.trainning.kafkaintegrationtest.kafkaconsumer;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class KafkaConsumerApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(KafkaConsumerApplication.class, args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package com.ippon.trainning.kafkaintegrationtest.kafkaconsumer.config;
|
||||
|
||||
import org.apache.kafka.common.serialization.StringDeserializer;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory;
|
||||
import org.springframework.kafka.core.ConsumerFactory;
|
||||
import org.springframework.kafka.core.DefaultKafkaConsumerFactory;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static org.apache.kafka.clients.CommonClientConfigs.BOOTSTRAP_SERVERS_CONFIG;
|
||||
import static org.apache.kafka.clients.CommonClientConfigs.GROUP_ID_CONFIG;
|
||||
import static org.apache.kafka.clients.consumer.ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG;
|
||||
import static org.apache.kafka.clients.consumer.ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG;
|
||||
|
||||
@Configuration
|
||||
public class KafkaConsumerConfiguration {
|
||||
private final String bootstrapAddress;
|
||||
private final String groupId;
|
||||
|
||||
public KafkaConsumerConfiguration(@Value("${server.kafka.bootstrapAddress}") String bootstrapAddress,
|
||||
@Value("${server.kafka.groupId}") String groupId) {
|
||||
this.bootstrapAddress = bootstrapAddress;
|
||||
this.groupId = groupId;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ConsumerFactory<String, String> consumerFactory() {
|
||||
Map<String, Object> props = Map.of(
|
||||
BOOTSTRAP_SERVERS_CONFIG, bootstrapAddress,
|
||||
VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class,
|
||||
KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class,
|
||||
GROUP_ID_CONFIG, groupId
|
||||
);
|
||||
return new DefaultKafkaConsumerFactory<>(props);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ConcurrentKafkaListenerContainerFactory<String, String> containerFactory(ConsumerFactory<String, String> consumerFactory) {
|
||||
ConcurrentKafkaListenerContainerFactory<String, String> factory = new ConcurrentKafkaListenerContainerFactory<>();
|
||||
factory.setConsumerFactory(consumerFactory);
|
||||
return factory;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.ippon.trainning.kafkaintegrationtest.kafkaconsumer.consumer;
|
||||
|
||||
import com.ippon.trainning.kafkaintegrationtest.kafkaconsumer.service.MessageService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.kafka.clients.consumer.ConsumerRecord;
|
||||
import org.springframework.kafka.annotation.KafkaListener;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class KafkaConsumer {
|
||||
private final MessageService messageService;
|
||||
|
||||
public KafkaConsumer(MessageService messageService) {
|
||||
this.messageService = messageService;
|
||||
}
|
||||
|
||||
@KafkaListener(
|
||||
containerFactory = "containerFactory",
|
||||
topics = "${server.kafka.topic}"
|
||||
)
|
||||
public void listenTopic(ConsumerRecord<String, String> record) {
|
||||
messageService.handleMessage(record.key(), record.value());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.ippon.trainning.kafkaintegrationtest.kafkaconsumer.service;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class MessageService {
|
||||
public void handleMessage(String key, String message) {
|
||||
log.info("Message consumed: <{}> - <{}>", key, message);
|
||||
}
|
||||
}
|
||||
6
kafka-consumer/src/main/resources/application.yml
Normal file
6
kafka-consumer/src/main/resources/application.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
server:
|
||||
port: 8081
|
||||
kafka:
|
||||
bootstrapAddress: localhost:9092
|
||||
topic: topic-test
|
||||
groupId: groupId-test
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.ippon.trainning.kafkaintegrationtest.kafkaconsumer;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
@SpringBootTest
|
||||
class KafkaConsumerApplicationTests {
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user