Spring Boot and Messaging Queue - [Rabbit MQ] using Docker

Spring Boot and Messaging Queue - [Rabbit MQ] using Docker

RabbitMQ is an open-source message-broker software that originally implemented the Advanced Message Queuing Protocol and has since been extended with a plug-in architecture to support Streaming Text Oriented Messaging Protocol, MQ Telemetry Transport, and other protocols.

JMS[Java Message Service] is a service used to send messages between a subscriber and a publisher. The Publisher adds the message in a queue and a Subscriber[service] can access that message from the queue.

There are different Messaging services such as:-

1) Rabbit MQ
2) Active MQ
3) Feign Client
4) Kafka

We will be using Rabbit MQ for this project.

Docker is required to be installed on the machine.

Installation

1) Clone the Repo from here Click Here & run the following commands.

docker-compose up

Output

Post a request using Postman on:-

localhost:8081/order/taj

Send this in body:-

{
"name" : "Sandwitch",
"qty" : 2,
"price" : 212
}

Usage

MessagingConfig.java

@Configuration
public class MessagingConfig {
    @Bean
    public Queue queue() {
         return new Queue(Constants.QUEUE);
    }
    @Bean
    public TopicExchange exchange() {
        return new TopicExchange(Constants.EXCHANGE); 
    }
    @Bean    
    public Binding binding(Queue queue , TopicExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(Constants.ROUTING_KEY); 
    }

    @Bean
    public MessageConverter converter() {
        return new Jackson2JsonMessageConverter();
    }

    @Bean
    public AmqpTemplate template(ConnectionFactory connectionFactory) {
            final RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
            rabbitTemplate.setMessageConverter(converter());
            return rabbitTemplate;
    }
}

OrderPublisher.java

@RestController 
@RequestMapping("/order")
public class OrderPublisher {

    @Autowired
    private RabbitTemplate rabbitTemplate;

        @PostMapping("/{restaurantName}")
        public String bookOrder(@RequestBody Order order, @PathVariable String restaurantName ) {
            order.setOrderId(UUID.randomUUID().toString());
            OrderStatus orderStatus = new OrderStatus(order, "PROCESS", "Order Successfully Placed"+ restaurantName);

            rabbitTemplate.convertAndSend(Constants.EXCHANGE,Constants.ROUTING_KEY, orderStatus);
            return "success!!"; 
        }
}

User.java (consumer)

@Component
public class User {

    @RabbitListener(queues = Constants.QUEUE )
    public void consumeMessageFromQueue(OrderStatus orderStatus) {
        System.out.println("Message Received from queue: " +orderStatus );
    }
}

Constants.java

Constants are defined in the class.

public class Constants {
    public static final String QUEUE = "rabbit_queue";
    public static final String EXCHANGE = "rabbit_exchange";
    public static final String ROUTING_KEY = "rabbit_routingKey";
}

Configuration

docker-compose.yml

version: '3.3'

services:
    #service 1: definition of mysql database
    rabbitmq:
      image: rabbitmq:3-management
      container_name: rabbitmq  
      restart: always
      ports:
        - "15672:15672"
        - "5672:5672"

    #service 3: definition of your spring-boot app 
    orderservice:                        #it is just a name, which will be used only in this file.
      image: order-service               #name of the image after dockerfile executes
      container_name: order-service-app  #name of the container created from docker image
      build:
        context: .                          #docker file path (. means root directory)
        dockerfile: Dockerfile              #docker file name
      ports:
        - "8081:8080"                       #docker containter port with your os port
      restart: always
      environment:
        - SPRING_RABBITMQ_HOST=rabbitmq  
      depends_on:                           #define dependencies of this app
        - rabbitmq                                #dependency name (which is defined with this name 'db' in this file earlier)

Dockerfile

FROM openjdk:11 as rabbitmq
EXPOSE 8081
WORKDIR /app

# Copy maven executable to the image
COPY mvnw .
COPY .mvn .mvn

# Copy the pom.xml file
COPY pom.xml .

# Copy the project source
COPY ./src ./src
COPY ./pom.xml ./pom.xml

RUN chmod 755 /app/mvnw

RUN ./mvnw package -DskipTests
ENTRYPOINT ["java","-jar","target/springboot-demo-activemq-0.0.1-SNAPSHOT.jar"]

Did you find this article valuable?

Support Atharva Siddhabhatti's Blog by becoming a sponsor. Any amount is appreciated!