JAVA-11240 Moved spring-cloud to spring-cloud-modules
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
## Spring Cloud Stream
|
||||
|
||||
This module contains articles about Spring Cloud Stream
|
||||
|
||||
## Relevant Articles
|
||||
- [Introduction to Spring Cloud Stream](http://www.baeldung.com/spring-cloud-stream)
|
||||
- [Integrating Spring with AWS Kinesis](https://www.baeldung.com/spring-aws-kinesis)
|
||||
@@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>spring-cloud-stream</artifactId>
|
||||
<name>spring-cloud-stream</name>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung.spring.cloud</groupId>
|
||||
<artifactId>spring-cloud-modules</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
<module>spring-cloud-stream-kafka</module>
|
||||
<module>spring-cloud-stream-rabbit</module>
|
||||
<module>spring-cloud-stream-kinesis</module>
|
||||
</modules>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-stream-rabbit</artifactId>
|
||||
<version>${spring-cloud-stream.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-stream</artifactId>
|
||||
<version>${spring-cloud-stream.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-stream-test-support</artifactId>
|
||||
<version>${spring-cloud-stream.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,3 @@
|
||||
## Relevant Articles:
|
||||
|
||||
- [Guide to Spring Cloud Stream with Kafka, Apache Avro and Confluent Schema Registry](https://www.baeldung.com/spring-cloud-stream-kafka-avro-confluent)
|
||||
@@ -0,0 +1,101 @@
|
||||
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>spring-cloud-stream-kafka</artifactId>
|
||||
<name>spring-cloud-stream-kafka</name>
|
||||
<packaging>jar</packaging>
|
||||
<description>Simple Spring Cloud Stream</description>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>spring-cloud-stream</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-dependencies</artifactId>
|
||||
<version>${spring-cloud.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-stream-binder-kafka</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-stream-schema</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-stream-test-support</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.confluent</groupId>
|
||||
<artifactId>kafka-avro-serializer</artifactId>
|
||||
<version>${kafka-avro-serializer.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.avro</groupId>
|
||||
<artifactId>avro-compiler</artifactId>
|
||||
<version>${avro.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.avro</groupId>
|
||||
<artifactId>avro-maven-plugin</artifactId>
|
||||
<version>${avro.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.avro</groupId>
|
||||
<artifactId>avro-maven-plugin</artifactId>
|
||||
<version>1.8.2</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>schemas</id>
|
||||
<phase>generate-sources</phase>
|
||||
<goals>
|
||||
<goal>schema</goal>
|
||||
<goal>protocol</goal>
|
||||
<goal>idl-protocol</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<sourceDirectory>${project.basedir}/src/main/resources/</sourceDirectory>
|
||||
<outputDirectory>${project.basedir}/src/main/java/</outputDirectory>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>confluent</id>
|
||||
<url>https://packages.confluent.io/maven/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<properties>
|
||||
<spring-cloud.version>Greenwich.SR1</spring-cloud.version>
|
||||
<kafka-avro-serializer.version>4.0.0</kafka-avro-serializer.version>
|
||||
<avro.version>1.8.2</avro.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package com.baeldung;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.stream.annotation.EnableBinding;
|
||||
import org.springframework.cloud.stream.messaging.Processor;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableBinding(Processor.class)
|
||||
// The @EnableSchemaRegistryClient annotation needs to be uncommented to use the Spring native method.
|
||||
// @EnableSchemaRegistryClient
|
||||
public class AvroKafkaApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(AvroKafkaApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package com.baeldung.config;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.cloud.stream.schema.client.ConfluentSchemaRegistryClient;
|
||||
import org.springframework.cloud.stream.schema.client.SchemaRegistryClient;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
public class SchemRegistryConfig {
|
||||
|
||||
@Bean
|
||||
public SchemaRegistryClient schemaRegistryClient(@Value("${spring.cloud.stream.kafka.binder.producer-properties.schema.registry.url}") String endPoint) {
|
||||
ConfluentSchemaRegistryClient client = new ConfluentSchemaRegistryClient();
|
||||
client.setEndpoint(endPoint);
|
||||
return client;
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package com.baeldung.consumer;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.cloud.stream.annotation.StreamListener;
|
||||
import org.springframework.cloud.stream.messaging.Processor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baeldung.schema.Employee;
|
||||
|
||||
@Service
|
||||
public class AvroConsumer {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(AvroConsumer.class);
|
||||
|
||||
@StreamListener(Processor.INPUT)
|
||||
public void consumeEmployeeDetails(Employee employeeDetails) {
|
||||
LOGGER.info("Let's process employee details: {}", employeeDetails);
|
||||
}
|
||||
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package com.baeldung.controller;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import com.baeldung.producer.AvroProducer;
|
||||
|
||||
@RestController
|
||||
public class AvroController {
|
||||
|
||||
@Autowired
|
||||
private AvroProducer avroProducer;
|
||||
|
||||
@PostMapping("/employees/{id}/{firstName}/{lastName}")
|
||||
public String producerAvroMessage(@PathVariable int id, @PathVariable String firstName, @PathVariable String lastName) {
|
||||
avroProducer.produceEmployeeDetails(id, firstName, lastName);
|
||||
return "Sent employee details to consumer";
|
||||
}
|
||||
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
package com.baeldung.producer;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cloud.stream.messaging.Processor;
|
||||
import org.springframework.kafka.support.KafkaHeaders;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.support.MessageBuilder;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.baeldung.schema.Employee;
|
||||
import com.baeldung.schema.EmployeeKey;
|
||||
|
||||
@Service
|
||||
public class AvroProducer {
|
||||
|
||||
@Autowired
|
||||
private Processor processor;
|
||||
|
||||
public void produceEmployeeDetails(int empId, String firstName, String lastName) {
|
||||
|
||||
// creating employee details
|
||||
Employee employee = new Employee();
|
||||
employee.setId(empId);
|
||||
employee.setFirstName(firstName);
|
||||
employee.setLastName(lastName);
|
||||
employee.setDepartment("IT");
|
||||
employee.setDesignation("Engineer");
|
||||
|
||||
// creating partition key for kafka topic
|
||||
EmployeeKey employeeKey = new EmployeeKey();
|
||||
employeeKey.setId(empId);
|
||||
employeeKey.setDepartmentName("IT");
|
||||
|
||||
Message<Employee> message = MessageBuilder.withPayload(employee)
|
||||
.setHeader(KafkaHeaders.MESSAGE_KEY, employeeKey)
|
||||
.build();
|
||||
|
||||
processor.output()
|
||||
.send(message);
|
||||
}
|
||||
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
spring:
|
||||
cloud:
|
||||
stream:
|
||||
default:
|
||||
producer:
|
||||
useNativeEncoding: true
|
||||
consumer:
|
||||
useNativeEncoding: true
|
||||
bindings:
|
||||
input:
|
||||
destination: employee-details
|
||||
content-type: application/*+avro
|
||||
group: group-1
|
||||
concurrency: 3
|
||||
output:
|
||||
destination: employee-details
|
||||
content-type: application/*+avro
|
||||
kafka:
|
||||
binder:
|
||||
producer-properties:
|
||||
key.serializer: io.confluent.kafka.serializers.KafkaAvroSerializer
|
||||
value.serializer: io.confluent.kafka.serializers.KafkaAvroSerializer
|
||||
schema.registry.url: http://localhost:8081
|
||||
consumer-properties:
|
||||
key.deserializer: io.confluent.kafka.serializers.KafkaAvroDeserializer
|
||||
value.deserializer: io.confluent.kafka.serializers.KafkaAvroDeserializer
|
||||
schema.registry.url: http://localhost:8081
|
||||
specific.avro.reader: true
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"type": "record",
|
||||
"name": "EmployeeKey",
|
||||
"namespace": "com.baeldung.schema",
|
||||
"fields": [
|
||||
{
|
||||
"name": "id",
|
||||
"type": "int"
|
||||
},
|
||||
{
|
||||
"name": "departmentName",
|
||||
"type": "string"
|
||||
}]
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"type": "record",
|
||||
"name": "Employee",
|
||||
"namespace": "com.baeldung.schema",
|
||||
"fields": [
|
||||
{
|
||||
"name": "id",
|
||||
"type": "int"
|
||||
},
|
||||
{
|
||||
"name": "firstName",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "lastName",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"name": "department",
|
||||
"type": "string",
|
||||
"default": "IT "
|
||||
},
|
||||
{
|
||||
"name": "designation",
|
||||
"type": "string",
|
||||
"default": "Software Engineer"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>spring-cloud-stream-kinesis</artifactId>
|
||||
<name>spring-cloud-stream-kinesis</name>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>spring-cloud-stream</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-stream-binder-kinesis</artifactId>
|
||||
<version>${spring-cloud-stream-kinesis-binder.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.amazonaws</groupId>
|
||||
<artifactId>aws-java-sdk-kinesis</artifactId>
|
||||
<version>${aws-sdk.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-stream-test-support</artifactId>
|
||||
<version>${spring-cloud-stream-test.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<aws-sdk.version>1.11.632</aws-sdk.version>
|
||||
<spring-cloud-stream-kinesis-binder.version>2.0.2.RELEASE</spring-cloud-stream-kinesis-binder.version>
|
||||
<spring-cloud-stream-test.version>2.2.1.RELEASE</spring-cloud-stream-test.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package com.baeldung;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.stream.annotation.EnableBinding;
|
||||
import org.springframework.cloud.stream.annotation.StreamListener;
|
||||
import org.springframework.cloud.stream.messaging.Processor;
|
||||
import org.springframework.messaging.support.MessageBuilder;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableBinding(Processor.class)
|
||||
public class KinesisApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(KinesisApplication.class, args);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private Processor processor;
|
||||
|
||||
@StreamListener(Processor.INPUT)
|
||||
public void consume(String val) {
|
||||
System.out.println(val);
|
||||
}
|
||||
|
||||
public void produce(String val) {
|
||||
processor.output().send(MessageBuilder.withPayload(val).build());
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
cloud.aws.credentials.access-key=aws-key
|
||||
cloud.aws.credentials.secret-key=aws-secret
|
||||
cloud.aws.region.static=eu-central-1
|
||||
cloud.aws.stack.auto=false
|
||||
|
||||
spring.cloud.stream.bindings.output.destination=myStream
|
||||
spring.cloud.stream.bindings.output.content-type=text/plain
|
||||
|
||||
spring.cloud.stream.bindings.input.destination=myStream
|
||||
spring.cloud.stream.bindings.input.group=myStream-group
|
||||
spring.cloud.stream.bindings.input.content-type=text/plain
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package com.baeldung;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = KinesisApplication.class)
|
||||
public class KinesisApplicationIntegrationTest {
|
||||
@Test
|
||||
public void whenSpringContextIsBootstrapped_thenNoExceptions() {
|
||||
|
||||
}
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
cloud.aws.region.static=eu-central-1
|
||||
cloud.aws.stack.auto=false
|
||||
@@ -0,0 +1,29 @@
|
||||
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>spring-cloud-stream-rabbit</artifactId>
|
||||
<name>spring-cloud-stream-rabbit</name>
|
||||
<packaging>jar</packaging>
|
||||
<description>Simple Spring Cloud Stream</description>
|
||||
|
||||
<parent>
|
||||
<groupId>com.baeldung</groupId>
|
||||
<artifactId>spring-cloud-stream</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-stream-rabbit</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-stream-test-support</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
package com.baeldung.spring.cloud.stream.rabbit;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.stream.annotation.EnableBinding;
|
||||
import org.springframework.cloud.stream.annotation.StreamListener;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.support.MessageBuilder;
|
||||
|
||||
import com.baeldung.spring.cloud.stream.rabbit.processor.MyProcessor;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableBinding(MyProcessor.class)
|
||||
public class MultipleOutputsServiceApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(MultipleOutputsServiceApplication.class, args);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private MyProcessor processor;
|
||||
|
||||
@StreamListener(MyProcessor.INPUT)
|
||||
public void routeValues(Integer val) {
|
||||
if (val < 10) {
|
||||
processor.anOutput()
|
||||
.send(message(val));
|
||||
} else {
|
||||
processor.anotherOutput()
|
||||
.send(message(val));
|
||||
}
|
||||
}
|
||||
|
||||
private static final <T> Message<T> message(T val) {
|
||||
return MessageBuilder.withPayload(val)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
package com.baeldung.spring.cloud.stream.rabbit;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.stream.annotation.EnableBinding;
|
||||
import org.springframework.cloud.stream.annotation.StreamListener;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.support.MessageBuilder;
|
||||
|
||||
import com.baeldung.spring.cloud.stream.rabbit.processor.MyProcessor;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableBinding(MyProcessor.class)
|
||||
public class MultipleOutputsWithConditionsServiceApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(MultipleOutputsWithConditionsServiceApplication.class, args);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
private MyProcessor processor;
|
||||
|
||||
@StreamListener(target = MyProcessor.INPUT, condition = "payload < 10")
|
||||
public void routeValuesToAnOutput(Integer val) {
|
||||
processor.anOutput()
|
||||
.send(message(val));
|
||||
}
|
||||
|
||||
@StreamListener(target = MyProcessor.INPUT, condition = "payload >= 10")
|
||||
public void routeValuesToAnotherOutput(Integer val) {
|
||||
processor.anotherOutput()
|
||||
.send(message(val));
|
||||
}
|
||||
|
||||
private static final <T> Message<T> message(T val) {
|
||||
return MessageBuilder.withPayload(val)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package com.baeldung.spring.cloud.stream.rabbit;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.cloud.stream.annotation.EnableBinding;
|
||||
import org.springframework.cloud.stream.annotation.StreamListener;
|
||||
import org.springframework.cloud.stream.messaging.Processor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.messaging.converter.MessageConverter;
|
||||
import org.springframework.messaging.handler.annotation.SendTo;
|
||||
|
||||
import com.baeldung.spring.cloud.stream.rabbit.messages.TextPlainMessageConverter;
|
||||
import com.baeldung.spring.cloud.stream.rabbit.model.LogMessage;
|
||||
|
||||
@SpringBootApplication
|
||||
@EnableBinding(Processor.class)
|
||||
public class MyLoggerServiceApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(MyLoggerServiceApplication.class, args);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MessageConverter providesTextPlainMessageConverter() {
|
||||
return new TextPlainMessageConverter();
|
||||
}
|
||||
|
||||
@StreamListener(Processor.INPUT)
|
||||
@SendTo(Processor.OUTPUT)
|
||||
public LogMessage enrichLogMessage(LogMessage log) {
|
||||
return new LogMessage(String.format("[1]: %s", log.getMessage()));
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package com.baeldung.spring.cloud.stream.rabbit.messages;
|
||||
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.converter.AbstractMessageConverter;
|
||||
import org.springframework.util.MimeType;
|
||||
|
||||
import com.baeldung.spring.cloud.stream.rabbit.model.LogMessage;
|
||||
|
||||
public class TextPlainMessageConverter extends AbstractMessageConverter {
|
||||
|
||||
public TextPlainMessageConverter() {
|
||||
super(new MimeType("text", "plain"));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean supports(Class<?> clazz) {
|
||||
return (LogMessage.class == clazz);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object convertFromInternal(Message<?> message, Class<?> targetClass, Object conversionHint) {
|
||||
Object payload = message.getPayload();
|
||||
String text = payload instanceof String ? (String) payload : new String((byte[]) payload);
|
||||
return new LogMessage(text);
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package com.baeldung.spring.cloud.stream.rabbit.model;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class LogMessage implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -5857383701708275796L;
|
||||
|
||||
private String message;
|
||||
|
||||
public LogMessage() {
|
||||
|
||||
}
|
||||
|
||||
public LogMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return message;
|
||||
}
|
||||
|
||||
public void setMessage(String message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return message;
|
||||
}
|
||||
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package com.baeldung.spring.cloud.stream.rabbit.processor;
|
||||
|
||||
import org.springframework.cloud.stream.annotation.Input;
|
||||
import org.springframework.cloud.stream.annotation.Output;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.SubscribableChannel;
|
||||
|
||||
public interface MyProcessor {
|
||||
String INPUT = "myInput";
|
||||
|
||||
@Input
|
||||
SubscribableChannel myInput();
|
||||
|
||||
@Output("myOutput")
|
||||
MessageChannel anOutput();
|
||||
|
||||
@Output
|
||||
MessageChannel anotherOutput();
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
spring:
|
||||
cloud:
|
||||
stream:
|
||||
bindings:
|
||||
input:
|
||||
destination: queue.log.messages
|
||||
binder: local_rabbit
|
||||
group: logMessageConsumers
|
||||
output:
|
||||
destination: queue.pretty.log.messages
|
||||
binder: local_rabbit
|
||||
binders:
|
||||
local_rabbit:
|
||||
type: rabbit
|
||||
environment:
|
||||
spring:
|
||||
rabbitmq:
|
||||
host: localhost
|
||||
port: 5672
|
||||
username: guest
|
||||
password: guest
|
||||
virtual-host: /
|
||||
server:
|
||||
port: 0
|
||||
management:
|
||||
health:
|
||||
binders:
|
||||
enabled: true
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
|
||||
</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
</configuration>
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
package com.baeldung;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
import com.baeldung.spring.cloud.stream.rabbit.MultipleOutputsServiceApplication;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(classes = MultipleOutputsServiceApplication.class)
|
||||
public class SpringContextTest {
|
||||
|
||||
@Test
|
||||
public void whenSpringContextIsBootstrapped_thenNoExceptions() {
|
||||
}
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
package com.baeldung.spring.cloud.stream.rabbit;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cloud.stream.test.binder.MessageCollector;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.support.MessageBuilder;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import com.baeldung.spring.cloud.stream.rabbit.processor.MyProcessor;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = MultipleOutputsServiceApplication.class)
|
||||
@DirtiesContext
|
||||
public class MultipleOutputsServiceApplicationIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private MyProcessor pipe;
|
||||
|
||||
@Autowired
|
||||
private MessageCollector messageCollector;
|
||||
|
||||
@Test
|
||||
public void whenSendMessage_thenResponseIsInAOutput() {
|
||||
whenSendMessage(1);
|
||||
thenPayloadInChannelIs(pipe.anOutput(), "1");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSendMessage_thenResponseIsInAnotherOutput() {
|
||||
whenSendMessage(11);
|
||||
thenPayloadInChannelIs(pipe.anotherOutput(), "11");
|
||||
}
|
||||
|
||||
private void whenSendMessage(Integer val) {
|
||||
pipe.myInput()
|
||||
.send(MessageBuilder.withPayload(val)
|
||||
.build());
|
||||
}
|
||||
|
||||
private void thenPayloadInChannelIs(MessageChannel channel, String expectedValue) {
|
||||
Object payload = messageCollector.forChannel(channel)
|
||||
.poll()
|
||||
.getPayload();
|
||||
assertEquals(expectedValue, payload);
|
||||
}
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
package com.baeldung.spring.cloud.stream.rabbit;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cloud.stream.test.binder.MessageCollector;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.support.MessageBuilder;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import com.baeldung.spring.cloud.stream.rabbit.processor.MyProcessor;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = MultipleOutputsWithConditionsServiceApplication.class)
|
||||
@DirtiesContext
|
||||
public class MultipleOutputsWithConditionsServiceIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private MyProcessor pipe;
|
||||
|
||||
@Autowired
|
||||
private MessageCollector messageCollector;
|
||||
|
||||
@Test
|
||||
public void whenSendMessage_thenResponseIsInAOutput() {
|
||||
whenSendMessage(1);
|
||||
thenPayloadInChannelIs(pipe.anOutput(), "1");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSendMessage_thenResponseIsInAnotherOutput() {
|
||||
whenSendMessage(11);
|
||||
thenPayloadInChannelIs(pipe.anotherOutput(), "11");
|
||||
}
|
||||
|
||||
private void whenSendMessage(Integer val) {
|
||||
pipe.myInput()
|
||||
.send(MessageBuilder.withPayload(val)
|
||||
.build());
|
||||
}
|
||||
|
||||
private void thenPayloadInChannelIs(MessageChannel channel, String expectedValue) {
|
||||
Object payload = messageCollector.forChannel(channel)
|
||||
.poll()
|
||||
.getPayload();
|
||||
assertEquals(expectedValue, payload);
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
package com.baeldung.spring.cloud.stream.rabbit;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cloud.stream.messaging.Processor;
|
||||
import org.springframework.cloud.stream.test.binder.MessageCollector;
|
||||
import org.springframework.messaging.support.MessageBuilder;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import com.baeldung.spring.cloud.stream.rabbit.model.LogMessage;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = MyLoggerServiceApplication.class)
|
||||
@DirtiesContext
|
||||
public class MyLoggerApplicationIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private Processor pipe;
|
||||
|
||||
@Autowired
|
||||
private MessageCollector messageCollector;
|
||||
|
||||
@Test
|
||||
public void whenSendMessage_thenResponseShouldUpdateText() {
|
||||
pipe.input()
|
||||
.send(MessageBuilder.withPayload(new LogMessage("This is my message"))
|
||||
.build());
|
||||
|
||||
Object payload = messageCollector.forChannel(pipe.output())
|
||||
.poll()
|
||||
.getPayload();
|
||||
|
||||
assertEquals("{\"message\":\"[1]: This is my message\"}", payload.toString());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user