How to run RabbitMQ on Docker and connect with Spring Boot

RabbitMQ is a widely used messaging broker. If you don't have any experience in messaging queues it may seem complicated but believe me it is not.

Now we'll focus on how to run RabbitMQ on a Docker container and then connect with a spring boot application.

  • Step 1 - Installation of Docker
  • Step 2 - Running RabbitMQ on Docker
  • Step 3 - Spring Boot application 


 Let's start with the Docker

Step 1 - Installation of Docker

Download the docker --> https://store.docker.com/editions/community/docker-ce-desktop-mac

Double-click the dmg file

Drag&Drop 
That's it! 


Step 2 - Running RabbitMQ on Docker

Create a docker-compose.yml file

Define the base image and define the ports
rabbitmq:
  image: rabbitmq:management
  ports:
    - "5672:5672"
    - "15672:15672"
And then just run the below command in the terminal at the same folder with the file (docker-compose.yml)
docker-compose up
This will download and run the RabbitMQ image on the docker. After the download finishes, we may check the management console
http://localhost:15672/#/
You may login with
guest
guest
If you are seeing something similar to this, it means now you have you rabbitmq running on your docker instance.


That's it!

Step 3 - Spring Boot application with RabbitMQ

Create a Spring Boot application, here is the pom.xml for it 
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.nurettin</groupId>
<artifactId>Spring-RabbitMQ</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Spring-RabbitMQ</name>
<description>project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
<relativePath /> 
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<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>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Application class, here we have listener, binding and our beans
package com.nurettin;



import org.springframework.amqp.core.Binding;

import org.springframework.amqp.core.BindingBuilder;

import org.springframework.amqp.core.Queue;

import org.springframework.amqp.core.TopicExchange;

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.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.context.annotation.Bean;



import com.nurettin.mq.Receiver;



@SpringBootApplication

public class SpringRabbitMqApplication {



 public static final String topicExchangeName = "spring-boot-exchange";



    static final String queueName = "spring-boot";



    @Bean

    Queue queue() {

        return new Queue(queueName, false);

    }



    @Bean

    TopicExchange exchange() {

        return new TopicExchange(topicExchangeName);

    }



    @Bean

    Binding binding(Queue queue, TopicExchange exchange) {

        return BindingBuilder.bind(queue).to(exchange).with("foo.bar.#");

    }



    @Bean

    SimpleMessageListenerContainer container(ConnectionFactory connectionFactory,

            MessageListenerAdapter listenerAdapter) {

        SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();

        container.setConnectionFactory(connectionFactory);

        container.setQueueNames(queueName);

        container.setMessageListener(listenerAdapter);

        return container;

    }



    @Bean

    MessageListenerAdapter listenerAdapter(Receiver receiver) {

        return new MessageListenerAdapter(receiver, "receiveMessage");

    }



 public static void main(String[] args) {

  SpringApplication.run(SpringRabbitMqApplication.class, args);

 }



}


Receiver class
package com.nurettin.mq;



import java.util.concurrent.CountDownLatch;



import org.springframework.stereotype.Component;



@Component

public class Receiver {



    private CountDownLatch latch = new CountDownLatch(1);



    public void receiveMessage(String message) {

        System.out.println("Received <" + message + ">");

        latch.countDown();

    }



    public CountDownLatch getLatch() {

        return latch;

    }



}


Controller 
package com.nurettin.controller;



import java.util.concurrent.TimeUnit;



import javax.validation.Valid;



import org.springframework.amqp.rabbit.core.RabbitTemplate;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.PostMapping;

import org.springframework.web.bind.annotation.RequestBody;

import org.springframework.web.bind.annotation.RestController;



import com.nurettin.SpringRabbitMqApplication;

import com.nurettin.mq.Receiver;



@RestController

public class MessageController {



 @Autowired

 private RabbitTemplate rabbitTemplate;

 @Autowired

 private Receiver receiver;



 @PostMapping("/messages")

 public String sendMessage(@Valid @RequestBody String message) {



  rabbitTemplate.convertAndSend(SpringRabbitMqApplication.topicExchangeName, "foo.bar.baz", message);

  try {

   receiver.getLatch().await(10000, TimeUnit.MILLISECONDS);

  } catch (InterruptedException e) {

   e.printStackTrace();

  }



  return "Message added to the queue : " + message;

 }



}


Config for the Swagger ( Never skip swagger)
package com.nurettin.config;



import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;



import springfox.documentation.builders.PathSelectors;

import springfox.documentation.builders.RequestHandlerSelectors;

import springfox.documentation.spi.DocumentationType;

import springfox.documentation.spring.web.plugins.Docket;

import springfox.documentation.swagger2.annotations.EnableSwagger2;



@Configuration

@EnableSwagger2

public class SwaggerConfig {                                    

    @Bean

    public Docket api() { 

        return new Docket(DocumentationType.SWAGGER_2)  

          .select()                                  

          .apis(RequestHandlerSelectors.any())              

          .paths(PathSelectors.any())                          

          .build();                                           

    }

}

Run your application! 

You may use "postman" or Swagger to try your Rest API 
http://localhost:8080/swagger-ui.html
You may see our message controller. Just expand it, write down your message and try out! 



That's it! 

Congratulations now you are running your spring boot application which is connected to the RabbitMQ ( on Docker). 

No comments: