Integrating RabbitMQ with SpringBoot Application (Reciever Part)

Making your spring API asynchronous adds up to the crucial features of an application. Asynchronous calls to a spring API means less burden on the server as well as no high demand from application to respond instantly.

There are many ways to make your spring API as asynchronous which includes the usage of RabbitMQ, Kafka, and ActiveMQ, etc. RabbitMQ, Kafka, and ActiveMQ are all messaging technologies used to provide asynchronous communication and decouple processes (detaching the sender and receiver of a message). They are called message queues, message brokers, or messaging tools.

Today, we will be using RabbitMQ to make our spring API asynchronous.

RabbitMQ is open-source message-broker software that originally implemented the Advanced Message Queuing Protocol. RabbitMQ is a queue management tool that works on the principle of “FIFO” (First in First out). Rabbit processes all the incoming messages from itself before forwarding it to server or application. In case, application/server is down, Rabbit will store the incoming messages in it unless the application/server is back up and running. For installation purpose, you can refer to https://cmatskas.com/getting-started-with-rabbitmq-on-windows/

We will be focusing just on receiving the messages from the queue. For sending the messages to queue, do refer https://medium.com/@gourshubham1995/integrating-rabbitmq-with-springboot-application-sender-part-9d0dbd79c707


Implementation of RabbitMQ with Java-springBoot application.

The initial requirement for the implementation is 2 sample spring projects out which, one can act as the sender of messages and the other one can act as a receiver. So, go to https://start.spring.io/ and create a maven project with desired dependencies. For convenience, name it receiver. Go ahead and import this in eclipse.

Designing pom.xml

Add the following dependency in the pom.xml file.

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

This jar is required to access features of “Queue”. Ampq dependency helps in the creation of queues and exchanges in Rabbit.

Designing application.properties file

This file resides in the resources folder of the application. In our case it will be at reciever>src>main>resources>application.properties

This file should have the configuration information of RabbitMQ such as HostName, port, username, password, etc. Below is the snapshot of how it will look after configuration.

Application.properties

Host and Port refer to the server Rabbit is running on. Username & Password as name clarifies is the credentials of Rabbit to log on. Exchange, Queue and Routing Key values are also declared. Read more about what is Exchange, Queue and routing key at https://www.rabbitmq.com/tutorials/amqp-concepts.html

Note : Exchange, Queue and Routing Key must be mapped to the queue created by sender or the queue from where the messages are coming from in RabbitMQ.

Configuration file for Rabbit (RabbitMQConfig)

Moving on, we make a configuration file, to configure and use queues and exchanges. Also, this configuration contains a message converter, that converts the message input to a passable format to queue.

Below is the code that will be in the configuration file.

package com.receiver.receiver.config;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RabbitMQConfig {
@Value("${sample.rabbitmq.queue}")
String queueName;
@Value("${sample.rabbitmq.exchange}")
String exchange;
@Value("${sample.rabbitmq.routingkey}")
private String routingkey;
@Bean
Queue queue() {
return new Queue(queueName, false);
}
@Bean
DirectExchange exchange() {
return new DirectExchange(exchange);
}
@Bean
Binding binding(Queue queue, DirectExchange exchange) {
return BindingBuilder.bind(queue).to(exchange).with(routingkey);
}
@Bean
public MessageConverter jsonMessageConverter() {
return new Jackson2JsonMessageConverter();
}
@Bean
public AmqpTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
final RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
rabbitTemplate.setMessageConverter(jsonMessageConverter());
return rabbitTemplate;
}
}
Creating a Listener

You’ll use RabbitTemplate to send messages, and you will register a Receiver with the message listener container to receive messages. The connection factory drives both, allowing them to connect to the RabbitMQ server.

Here we are using a “String incomingMessage”, that will contain the messages in string form, coming from sender of the message. If sender sends some other kind of data or objects, we have liberty to customize out listener to receive those kind of data and process it.

Following code will listen to the messages coming from queue.

package com.receiver.receiver.controller;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component
public class RabbitMQ {

@RabbitListener(queues = "${sample.rabbitmq.queue}")
public void recievedMessage(String incomingMessage) {
System.out.println("Recieved Message From RabbitMQ: " + incomingMessage);

}
}
Lets Test

Lets go a step forward and try receiving some messages from the sender. For this purpose, we will generate some dummy message from sender, store that message in queue when the receiver application is turned off. The on turning the receiver up, we will be printing those messages. So have a look at the following pictures step by step.

  1. Send message to RabbitMQ:
Sending message from postman

2. Check message reached queue (with receiver app shut down):

Message present at queue

3. Start the receiver app and boom ! message is there.

Message reached reciever.

So, this was sample application that receives messages from RabbitMQ and prints it. Such customization can be made, to get rabbitMQ integrated in spring-boot app, thus making it full compatible with asynchronous calls.

NOTE: RabbitMQ has another feature, that allows receiver to send back responses to sender, to confirm the reception of messages that sender sent.