Working with RabbitMQ and RestApi Using Apache Camel

Reading Time: 2 minutes

Introduction
In this blog, we are going to learn the basic structure and how we can handle the API call and route it to RabbitMQ.We are going to create a maven project in which we will be handling this scenario.

Maven Structure of the Project:

The pom.xml is as follows

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.6.8</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.camel</groupId>
	<artifactId>ApacheCamel</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>ApacheCamel</name>
	<description>Demo project for Spring Boot to consume from rabbit and      publish to kafka</description>
	<properties>
		<java.version>11</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
<!--Camel Dependencies		-->
		<dependency>
			<groupId>org.apache.camel</groupId>
			<artifactId>camel-spring-boot-starter</artifactId>
			<version>2.17.0</version>
		</dependency>

		<dependency>
			<groupId>org.apache.camel</groupId>
			<artifactId>camel-core</artifactId>
			<version>2.17.0</version>
		</dependency>
		<dependency>
			<groupId>org.apache.camel</groupId>
			<artifactId>camel-jackson</artifactId>
			<version>2.17.0</version>
		</dependency>
		<dependency>
			<groupId>org.apache.camel</groupId>
			<artifactId>camel-rabbitmq</artifactId>
			<version>2.17.0</version>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<configuration>
					<excludes>
						<exclude>
							<groupId>org.projectlombok</groupId>
							<artifactId>lombok</artifactId>
						</exclude>
					</excludes>
				</configuration>
			</plugin>
		</plugins>
	</build>

</project>

Create a Model class :
Here I am using Lombok to avoid boilerplate code.

package com.camel.ApacheCamel.model;

import lombok.*;

/**
 * Model class to Process the Library Book details.
 *
 */
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
public class LibraryBookDetail {
    private int serialNo;
    private String bookName;
    private String autherName;
    private double price;
}

Define the Camel Route:

  • We will need to marshal the libraryBookDetail object to JSON. For this, we will make use of Apache Camel JacksonDataFormat.
  • Create the camel route to marshal the employee object and then send it to the rabbitmq queue named libraryQueue. Also, a rabbitmq exchange named libraryQueue.Exchange is created.
package com.camel.ApacheCamel.route;

import com.camel.ApacheCamel.model.LibraryBookDetail;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.jackson.JacksonDataFormat;
import org.springframework.stereotype.Component;

/**
 * This class is use to Route the Data to RabbitMQ
 * which is recieved from Rest call.
 */
@Component
public class LibraryRoute extends RouteBuilder {
    @Override
    public void configure() throws Exception {
        JacksonDataFormat jacksonDataFormat = new JacksonDataFormat(LibraryBookDetail.class);
        from("direct:restPointCall").id("idToRouteRest").marshal(jacksonDataFormat)
                .to("rabbitmq://localhost:5672/librayQueue.exchange?queue=librayQueue&autoDelete=false").end();
    }
}

Create the Controller:

  • Expose GET REST API to take librarybookdetail parameters
  • Using the Camel ProducerTemplate to send librarybookdetail object to RabbitMQ Queue.
package com.camel.ApacheCamel.controller;

import com.camel.ApacheCamel.model.LibraryBookDetail;
import org.apache.camel.Produce;
import org.apache.camel.ProducerTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class LibraryController {

    @Produce(uri = "direct:restPointCall")
    private ProducerTemplate producerTemplate;

    /**
     *
     * @param serialNo
     * @param bookName
     * @param autherName
     * @param price
     * This call receive the Book Detail using rest call and forward it to rabbitMQ queue.
     * @return Simple message "Processed Successfully"
     */
    @GetMapping(value = "/enterbookdetail")
    public String enterBookDetailToLibrary(@RequestParam("serialNo") int serialNo, @RequestParam("bookName") String bookName, @RequestParam("autherName") String autherName, @RequestParam("price") Double price) {
        LibraryBookDetail bookDetail = LibraryBookDetail.builder().serialNo(serialNo)
                .bookName(bookName)
                .autherName(autherName)
                .price(price)
                .build();
        producerTemplate.asyncSendBody(producerTemplate.getDefaultEndpoint(), bookDetail);
        return "Processed Successfully";
    }
}

Finally, create the bootstrap class using the SpringBootApplication annotation.

package com.camel.ApacheCamel;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ApacheCamelApplication {

	public static void main(String[] args) {
		SpringApplication.run(ApacheCamelApplication.class, args);
	}

}

Conclusion:

In this blog, we have learned the simple flow of the restApi call and processed it using Apache Camel, and sent this Rest Call to RabbitMQ so that our internal or external service can use this data.

Leave a Reply