Merge pull request #7476 from pcoates33/BAEL-2688

Bael 2688
This commit is contained in:
rpvilao 2019-08-10 17:59:01 +02:00 committed by GitHub
commit efd0d81ac5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 158 additions and 439 deletions

View File

@ -625,7 +625,6 @@
<module>spring-akka</module>
<module>spring-all</module>
<module>spring-amqp</module>
<module>spring-amqp-simple</module>
<module>spring-aop</module>
<module>spring-apache-camel</module>
<module>spring-batch</module>
@ -1303,7 +1302,6 @@
<module>spring-akka</module>
<module>spring-all</module>
<module>spring-amqp</module>
<module>spring-amqp-simple</module>
<module>spring-aop</module>
<module>spring-apache-camel</module>
<module>spring-batch</module>

View File

@ -1,2 +0,0 @@
### Relevant Articles:
- [RabbitMQ Message Dispatching with Spring AMQP](http://www.baeldung.com/rabbitmq-spring-amqp)

View File

@ -1,28 +0,0 @@
<?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>
<groupId>com.baeldung</groupId>
<artifactId>spring-amqp-simple</artifactId>
<version>1.0.0-SNAPSHOT</version>
<name>spring-amqp-simple</name>
<parent>
<artifactId>parent-boot-2</artifactId>
<groupId>com.baeldung</groupId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../parent-boot-2</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -1,17 +0,0 @@
package com.baeldung.springamqpsimple;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
public class MessageConsumer {
private static final Logger logger = LoggerFactory.getLogger(MessageConsumer.class);
@RabbitListener(queues = {SpringAmqpConfig.queueName})
public void receiveMessage(String message) {
logger.info("Received Message: " + message);
}
}

View File

@ -1,26 +0,0 @@
package com.baeldung.springamqpsimple;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseStatus;
@Controller
public class MessageController {
private final MessageProducer messageProducer;
@Autowired
public MessageController(MessageProducer messageProducer) {
this.messageProducer = messageProducer;
}
@RequestMapping(value="/messages", method= RequestMethod.POST)
@ResponseStatus(value= HttpStatus.CREATED)
public void sendMessage(@RequestBody String message) {
messageProducer.sendMessage(message);
}
}

View File

@ -1,20 +0,0 @@
package com.baeldung.springamqpsimple;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class MessageProducer {
private final RabbitTemplate rabbitTemplate;
@Autowired
public MessageProducer(RabbitTemplate rabbitTemplate) {
this.rabbitTemplate = rabbitTemplate;
}
public void sendMessage(String message) {
rabbitTemplate.convertAndSend(SpringAmqpConfig.queueName, message);
}
}

View File

@ -1,12 +0,0 @@
package com.baeldung.springamqpsimple;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringAmqpApplication {
public static void main(String[] args) throws InterruptedException {
SpringApplication.run(SpringAmqpApplication.class, args);
}
}

View File

@ -1,51 +0,0 @@
package com.baeldung.springamqpsimple;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Exchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
@Configuration
@Profile("!test")
public class SpringAmqpConfig {
public final static String queueName = "com.baeldung.spring-amqp-simple.queue";
public final static String exchangeName = "com.baeldung.spring-amqp-simple.exchange";
@Bean
Queue queue() {
return new Queue(queueName, false);
}
@Bean
Exchange exchange() {
return new DirectExchange(exchangeName);
}
@Bean
Binding binding(Queue queue, DirectExchange exchange) {
return BindingBuilder.bind(queue).to(exchange).with(queueName);
}
@Bean
SimpleMessageListenerContainer springAmqpContainer(ConnectionFactory connectionFactory,
MessageListenerAdapter listenerAdapter) {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
container.setQueueNames(queueName);
container.setMessageListener(listenerAdapter);
return container;
}
@Bean
MessageListenerAdapter listenerAdapter(MessageConsumer messageReceiver) {
return new MessageListenerAdapter(messageReceiver, "receiveMessage");
}
}

View File

@ -1,70 +0,0 @@
package com.baeldung.springamqpsimple.broadcast;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Declarable;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.boot.autoconfigure.amqp.SimpleRabbitListenerContainerFactoryConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import java.util.Arrays;
import java.util.List;
@Configuration
@Profile("!test")
public class BroadcastConfig {
public final static String fanoutQueue1Name = "com.baeldung.spring-amqp-simple.fanout.queue1";
public final static String fanoutQueue2Name = "com.baeldung.spring-amqp-simple.fanout.queue2";
public final static String fanoutExchangeName = "com.baeldung.spring-amqp-simple.fanout.exchange";
public final static String topicQueue1Name = "com.baeldung.spring-amqp-simple.topic.queue1";
public final static String topicQueue2Name = "com.baeldung.spring-amqp-simple.topic.queue2";
public final static String topicExchangeName = "com.baeldung.spring-amql-simple.topic.exchange";
@Bean
public List<Declarable> topicBindings() {
Queue topicQueue1 = new Queue(topicQueue1Name, false);
Queue topicQueue2 = new Queue(topicQueue2Name, false);
TopicExchange topicExchange = new TopicExchange(topicExchangeName);
return Arrays.asList(
topicQueue1,
topicQueue2,
topicExchange,
BindingBuilder.bind(topicQueue1).to(topicExchange).with("*.important.*"),
BindingBuilder.bind(topicQueue2).to(topicExchange).with("user.#")
);
}
@Bean
public List<Declarable> fanoutBindings() {
Queue fanoutQueue1 = new Queue(fanoutQueue1Name, false);
Queue fanoutQueue2 = new Queue(fanoutQueue2Name, false);
FanoutExchange fanoutExchange = new FanoutExchange(fanoutExchangeName);
return Arrays.asList(
fanoutQueue1,
fanoutQueue2,
fanoutExchange,
BindingBuilder.bind(fanoutQueue1).to(fanoutExchange),
BindingBuilder.bind(fanoutQueue2).to(fanoutExchange)
);
}
@Bean
public SimpleRabbitListenerContainerFactory broadcastContainer(ConnectionFactory connectionFactory, SimpleRabbitListenerContainerFactoryConfigurer configurer) {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
configurer.configure(factory, connectionFactory);
return factory;
}
}

View File

@ -1,32 +0,0 @@
package com.baeldung.springamqpsimple.broadcast;
import com.baeldung.springamqpsimple.MessageConsumer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
public class BroadcastMessageConsumers {
private static final Logger logger = LoggerFactory.getLogger(MessageConsumer.class);
@RabbitListener(queues = {BroadcastConfig.fanoutQueue1Name})
public void receiveMessageFromFanout1(String message) {
logger.info("Received fanout 1 message: " + message);
}
@RabbitListener(queues = {BroadcastConfig.fanoutQueue2Name})
public void receiveMessageFromFanout2(String message) {
logger.info("Received fanout 2 message: " + message);
}
@RabbitListener(queues = {BroadcastConfig.topicQueue1Name})
public void receiveMessageFromTopic1(String message) {
logger.info("Received topic 1 message: " + message);
}
@RabbitListener(queues = {BroadcastConfig.topicQueue2Name})
public void receiveMessageFromTopic2(String message) {
logger.info("Received topic 2 message: " + message);
}
}

View File

@ -1,26 +0,0 @@
package com.baeldung.springamqpsimple.broadcast;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseStatus;
@Controller
public class BroadcastMessageController {
private final BroadcastMessageProducer messageProducer;
@Autowired
public BroadcastMessageController(BroadcastMessageProducer messageProducer) {
this.messageProducer = messageProducer;
}
@RequestMapping(value="/broadcast", method= RequestMethod.POST)
@ResponseStatus(value= HttpStatus.CREATED)
public void sendMessage(@RequestBody String message) {
messageProducer.sendMessages(message);
}
}

View File

@ -1,22 +0,0 @@
package com.baeldung.springamqpsimple.broadcast;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class BroadcastMessageProducer {
private final RabbitTemplate rabbitTemplate;
@Autowired
public BroadcastMessageProducer(RabbitTemplate rabbitTemplate) {
this.rabbitTemplate = rabbitTemplate;
}
public void sendMessages(String message) {
rabbitTemplate.convertAndSend(BroadcastConfig.fanoutExchangeName, "", message);
rabbitTemplate.convertAndSend(BroadcastConfig.topicExchangeName, "user.not-important.info", message);
rabbitTemplate.convertAndSend(BroadcastConfig.topicExchangeName, "user.important.error", message);
}
}

View File

@ -1,5 +0,0 @@
spring:
rabbitmq:
username: guest
password: guest
host: 10.10.10.105

View File

@ -1,13 +0,0 @@
<?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>

View File

@ -1,17 +0,0 @@
package org.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.springamqpsimple.SpringAmqpApplication;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringAmqpApplication.class)
public class SpringContextManualTest {
@Test
public void whenSpringContextIsBootstrapped_thenNoExceptions() {
}
}

View File

@ -1,5 +0,0 @@
spring:
rabbitmq:
username: guest
password: guest
host: localhost

View File

@ -1,3 +1,4 @@
## Relevant articles:
- [Messaging With Spring AMQP](http://www.baeldung.com/spring-amqp)
- [Messaging With Spring AMQP](https://www.baeldung.com/spring-amqp)
- [RabbitMQ Message Dispatching with Spring AMQP](https://www.baeldung.com/rabbitmq-spring-amqp)

View File

@ -3,37 +3,26 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.baeldung</groupId>
<artifactId>spring-amqp</artifactId>
<version>0.1-SNAPSHOT</version>
<version>1.0.0-SNAPSHOT</version>
<name>spring-amqp</name>
<packaging>jar</packaging>
<description>Introduction to Spring-AMQP</description>
<parent>
<artifactId>parent-boot-2</artifactId>
<groupId>com.baeldung</groupId>
<artifactId>parent-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../parent-boot-2</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit</artifactId>
<version>${spring-rabbit}</version>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
</dependencies>
<build>
<finalName>spring-amqp</finalName>
</build>
<properties>
<spring-rabbit>1.6.6.RELEASE</spring-rabbit>
<start-class>com.baeldung.springamqp.simple.HelloWorldMessageApp</start-class>
</properties>
</project>

View File

@ -0,0 +1,52 @@
package com.baeldung.springamqp.broadcast;
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class BroadcastConfig {
private static final boolean NON_DURABLE = false;
public final static String FANOUT_QUEUE_1_NAME = "com.baeldung.spring-amqp-simple.fanout.queue1";
public final static String FANOUT_QUEUE_2_NAME = "com.baeldung.spring-amqp-simple.fanout.queue2";
public final static String FANOUT_EXCHANGE_NAME = "com.baeldung.spring-amqp-simple.fanout.exchange";
public final static String TOPIC_QUEUE_1_NAME = "com.baeldung.spring-amqp-simple.topic.queue1";
public final static String TOPIC_QUEUE_2_NAME = "com.baeldung.spring-amqp-simple.topic.queue2";
public final static String TOPIC_EXCHANGE_NAME = "com.baeldung.spring-amqp-simple.topic.exchange";
public static final String BINDING_PATTERN_IMPORTANT = "*.important.*";
public static final String BINDING_PATTERN_ERROR = "#.error";
@Bean
public Declarables topicBindings() {
Queue topicQueue1 = new Queue(TOPIC_QUEUE_1_NAME, NON_DURABLE);
Queue topicQueue2 = new Queue(TOPIC_QUEUE_2_NAME, NON_DURABLE);
TopicExchange topicExchange = new TopicExchange(TOPIC_EXCHANGE_NAME, NON_DURABLE, false);
return new Declarables(topicQueue1, topicQueue2, topicExchange, BindingBuilder
.bind(topicQueue1)
.to(topicExchange)
.with(BINDING_PATTERN_IMPORTANT), BindingBuilder
.bind(topicQueue2)
.to(topicExchange)
.with(BINDING_PATTERN_ERROR));
}
@Bean
public Declarables fanoutBindings() {
Queue fanoutQueue1 = new Queue(FANOUT_QUEUE_1_NAME, NON_DURABLE);
Queue fanoutQueue2 = new Queue(FANOUT_QUEUE_2_NAME, NON_DURABLE);
FanoutExchange fanoutExchange = new FanoutExchange(FANOUT_EXCHANGE_NAME, NON_DURABLE, false);
return new Declarables(fanoutQueue1, fanoutQueue2, fanoutExchange, BindingBuilder
.bind(fanoutQueue1)
.to(fanoutExchange), BindingBuilder
.bind(fanoutQueue2)
.to(fanoutExchange));
}
}

View File

@ -0,0 +1,59 @@
package com.baeldung.springamqp.broadcast;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import static com.baeldung.springamqp.broadcast.BroadcastConfig.*;
/**
* Simple test application to send messages to rabbitMQ.
*
*<p>To run this particular application with mvn you use the following command:</p>
* {@code
* mvn spring-boot:run -Dstart-class=com.baeldung.springamqp.broadcast.BroadcastMessageApp
* }
*/
@SpringBootApplication
public class BroadcastMessageApp {
private static String ROUTING_KEY_USER_IMPORTANT_WARN = "user.important.warn";
private static String ROUTING_KEY_USER_IMPORTANT_ERROR = "user.important.error";
public static void main(String[] args) {
SpringApplication.run(BroadcastMessageApp.class, args);
}
@Bean
public ApplicationRunner runner(RabbitTemplate rabbitTemplate) {
String message = " payload is broadcast";
return args -> {
rabbitTemplate.convertAndSend(BroadcastConfig.FANOUT_EXCHANGE_NAME, "", "fanout" + message);
rabbitTemplate.convertAndSend(BroadcastConfig.TOPIC_EXCHANGE_NAME, ROUTING_KEY_USER_IMPORTANT_WARN, "topic important warn" + message);
rabbitTemplate.convertAndSend(BroadcastConfig.TOPIC_EXCHANGE_NAME, ROUTING_KEY_USER_IMPORTANT_ERROR, "topic important error" + message);
};
}
@RabbitListener(queues = { FANOUT_QUEUE_1_NAME })
public void receiveMessageFromFanout1(String message) {
System.out.println("Received fanout 1 message: " + message);
}
@RabbitListener(queues = { FANOUT_QUEUE_2_NAME })
public void receiveMessageFromFanout2(String message) {
System.out.println("Received fanout 2 message: " + message);
}
@RabbitListener(queues = { TOPIC_QUEUE_1_NAME })
public void receiveMessageFromTopic1(String message) {
System.out.println("Received topic 1 (" + BINDING_PATTERN_IMPORTANT + ") message: " + message);
}
@RabbitListener(queues = { TOPIC_QUEUE_2_NAME })
public void receiveMessageFromTopic2(String message) {
System.out.println("Received topic 2 (" + BINDING_PATTERN_ERROR + ") message: " + message);
}
}

View File

@ -1,7 +0,0 @@
package com.baeldung.springamqp.consumer;
public class Consumer {
public void listen(String foo) {
System.out.println(foo);
}
}

View File

@ -1,17 +0,0 @@
package com.baeldung.springamqp.producer;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Producer {
public static void main(String[] args) throws InterruptedException {
AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
AmqpTemplate template = ctx.getBean(RabbitTemplate.class);
template.convertAndSend("Hello, world!");
Thread.sleep(1000);
ctx.destroy();
}
}

View File

@ -0,0 +1,38 @@
package com.baeldung.springamqp.simple;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class HelloWorldMessageApp {
private static final boolean NON_DURABLE = false;
private static final String MY_QUEUE_NAME = "myQueue";
public static void main(String[] args) {
SpringApplication.run(HelloWorldMessageApp.class, args);
}
@Bean
public ApplicationRunner runner(RabbitTemplate template) {
return args -> {
template.convertAndSend("myQueue", "Hello, world!");
};
}
@Bean
public Queue myQueue() {
return new Queue(MY_QUEUE_NAME, NON_DURABLE);
}
@RabbitListener(queues = MY_QUEUE_NAME)
public void listen(String in) {
System.out.println("Message read from myQueue : " + in);
}
}

View File

@ -1,35 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p" xmlns:rabbit="http://www.springframework.org/schema/rabbit"
xmlns:c="http://www.springframework.org/schema/c" xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
http://www.springframework.org/schema/rabbit http://www.springframework.org/schema/rabbit/spring-rabbit-1.4.xsd">
<rabbit:connection-factory id="connectionFactory" host="localhost" username="guest" password="guest" />
<rabbit:template id="amqpTemplate" connection-factory="connectionFactory"
exchange="myExchange" routing-key="foo.bar" />
<rabbit:admin connection-factory="connectionFactory" />
<rabbit:queue name="myQueue" />
<rabbit:topic-exchange name="myExchange">
<rabbit:bindings>
<rabbit:binding queue="myQueue" pattern="foo.*" />
</rabbit:bindings>
</rabbit:topic-exchange>
<rabbit:listener-container
connection-factory="connectionFactory">
<rabbit:listener ref="consumer" method="listen"
queue-names="myQueue" />
</rabbit:listener-container>
<bean id="consumer" class="com.baeldung.springamqp.consumer.Consumer" />
</beans>

View File

@ -1,13 +0,0 @@
<?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>