<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Rohan Gupta</title>
    <description>The latest articles on DEV Community by Rohan Gupta (@rohan700709).</description>
    <link>https://dev.to/rohan700709</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1321488%2F63bd8bca-5554-4e48-80aa-117f9952a298.jpeg</url>
      <title>DEV Community: Rohan Gupta</title>
      <link>https://dev.to/rohan700709</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rohan700709"/>
    <language>en</language>
    <item>
      <title>Configuring RabbitMQ Server for Asynchronous Messaging</title>
      <dc:creator>Rohan Gupta</dc:creator>
      <pubDate>Sun, 03 Mar 2024 09:16:49 +0000</pubDate>
      <link>https://dev.to/rohan700709/configuring-rabbitmq-server-for-asynchronous-messaging-177o</link>
      <guid>https://dev.to/rohan700709/configuring-rabbitmq-server-for-asynchronous-messaging-177o</guid>
      <description>&lt;h2&gt;
  
  
  Installing RabbitMQ
&lt;/h2&gt;

&lt;p&gt;RabbitMQ can be installed and used in multiple ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Installation on the local machine&lt;/li&gt;
&lt;li&gt;Creating instances of RabbitMQ using Cloud AMQP&lt;/li&gt;
&lt;li&gt;Running a RabbitMQ container using Docker&lt;/li&gt;
&lt;li&gt;The simplest way is to use a Docker container for RabbitMQ.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Start RabbitMQ Server (for Windows Users)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Start Docker Desktop.&lt;/li&gt;
&lt;li&gt;Open the PowerShell in Windows in administrator mode.&lt;/li&gt;
&lt;li&gt;Start the server by running the Docker container using the command.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;docker run -it --rm --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:3.10-management&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Type &lt;a href="http://localhost:15672"&gt;http://localhost:15672&lt;/a&gt; in the browser to log into the RabbitMQ server.&lt;/li&gt;
&lt;li&gt;Use guest/guest as credentials to log into the server console&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo4755gbxp53un71jg0as.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo4755gbxp53un71jg0as.png" alt="Image description" width="800" height="195"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Start RabbitMQ Server (for Linux Users)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Start the server by running the Docker container using the following command:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;docker run -it --rm --name rabbitmq -p 5672:5672 -p 15672:15672 e RABBITMQ SERVER ADDITIONAL ERL ARGS=' –&lt;br&gt;
rabbit loopback_users "none"' rabbitmq:3.10-rc-management&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enter &lt;a href="http://localhost:15672"&gt;http://localhost:15672&lt;/a&gt; in the browser to log into the RabbitMQ server.&lt;/li&gt;
&lt;li&gt;Use guest/guest as credentials to log into the server console.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Implementing Messaging using RabbitMQ
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frrjg0hqo14qzkpzamccp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frrjg0hqo14qzkpzamccp.png" alt="Image description" width="800" height="317"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Pub-Sub Microservices
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The UserMovieService manages all the operations of adding a favorite movie to the user's watch list.&lt;/li&gt;
&lt;li&gt;This will act as the publisher that will send notifications to the user if there are unwatched movies in the user's favourite list.&lt;/li&gt;
&lt;li&gt;The NotificationService will read the messages from the queue and display the notifications to the user.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Publisher Microservice
&lt;/h2&gt;

&lt;p&gt;Steps to configure a microservice to publish messages onto RabbitMQ:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add the dependencies to the pom.xml of the parent&lt;/li&gt;
&lt;li&gt;Define configurations of exchange, queue, and binding to connect to RabbitMQ.&lt;/li&gt;
&lt;li&gt;Build the domain object, also called as DTO, which will be sent to the queue. &lt;/li&gt;
&lt;li&gt;Write the data on the queue defined.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 1 : Add Dependencies
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Add the dependencies below to the pom.xml of the parent:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;dependency&amp;gt;&lt;br&gt;
&amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;&lt;br&gt;
&amp;lt;artifactId&amp;gt;spring-boot-starter-amqp&amp;lt;/artifactId&amp;gt;&lt;br&gt;
&amp;lt;/dependency&amp;gt;&lt;br&gt;
&amp;lt;dependency&amp;gt;&lt;br&gt;
&amp;lt;groupId&amp;gt;com.googlecode.json-simple&amp;lt;/groupId&amp;gt;&lt;br&gt;
&amp;lt;artifactId&amp;gt;json-simple&amp;lt;/artifactId&amp;gt;&lt;br&gt;
&amp;lt;version&amp;gt;1.1.1&amp;lt;/version&amp;gt;&lt;br&gt;
&amp;lt;/dependency&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The spring-boot-starter-amqp provides all the dependencies required to connect to RabbitMQ and create a queue, send messages to the created queue, and receive messages from the queue.&lt;/li&gt;
&lt;li&gt;The json-simple dependency is used to convert the Java object to JSON so it can be sent to the queue.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 2 : Configurations
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Define configurations for exchange, queue, and binding to connect to RabbitMQ.&lt;/li&gt;
&lt;li&gt;The RabbitTemplate provides the classes necessary to declare a queue and send data to the queue.&lt;/li&gt;
&lt;li&gt;All the data will be converted as JSON.&lt;/li&gt;
&lt;li&gt;All the objects are managed by the Spring container, so it is declared with the &lt;a class="mentioned-user" href="https://dev.to/bean"&gt;@bean&lt;/a&gt; annotation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;@Configuration&lt;br&gt;
public class MessageConfiguration {&lt;br&gt;
  private String exchangeName = "movie-exchange";&lt;br&gt;
  private String registerQueue = "movie.queue";&lt;br&gt;
  @Bean&lt;br&gt;
  public DirectExchange directExchange() {&lt;br&gt;
    return new DirectExchange(exchangeName);&lt;br&gt;
  }&lt;br&gt;
  @Bean&lt;br&gt;
  public Queue registerQueue() {&lt;br&gt;
    return new Queue(registerQueue, durable: true);&lt;br&gt;
  }&lt;br&gt;
  @Bean&lt;br&gt;
  public Jackson2JsonMessageConverter producerJackson2MessageConverter() {&lt;br&gt;
    return new Jackson2JsonMessageConverter();&lt;br&gt;
  }&lt;br&gt;
  @Bean&lt;br&gt;
  public RabbitTemplate rabbitTemplate(final ConnectionFactory connectionFactory) {&lt;br&gt;
    RabbitTemplate rabbitTemp = new RabbitTemplate(connectionFactory);&lt;br&gt;
    rabbitTemp.setMessageConverter(producerJackson2MessageConverter());&lt;br&gt;
    return rabbitTemp;&lt;br&gt;
  }&lt;br&gt;
  @Bean&lt;br&gt;
  Binding bindingUser(DirectExchange exchange, Queue registerQueue) {&lt;br&gt;
    return BindingBuilder.bind(registerQueue()).to(exchange).with(routingKey: "movie-routing");&lt;br&gt;
  }&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3 : Domain - DTO Object
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Build the domain object (also known as DTO), which will be sent to the queue.&lt;br&gt;
&lt;code&gt;import org.json.simple.JSONObject;&lt;br&gt;
public class MovieDTO {&lt;br&gt;
private JSONObject jsonObject;&lt;br&gt;
public MovieDTO() {}&lt;br&gt;
public JSONObject getJsonObject() {&lt;br&gt;
return jsonObject;&lt;br&gt;
}&lt;br&gt;
public void setJsonObject(JSONObject jsonObject) {&lt;br&gt;
this.jsonObject = jsonObject;&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The data with multiple fields can be put into the message queue as a JSON object.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Note that we can also send primitive datatypes to the queue as they are, without the need to build them as a JSON object.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 4 : Write to the Queue
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Publish the DTO object to the message queue.&lt;/li&gt;
&lt;li&gt;This is done using the RabbitTemplate object defined in the configuration as a bean.&lt;/li&gt;
&lt;li&gt;The convertAndSend method pushes the DTO object into the queue using a routing key.&lt;/li&gt;
&lt;li&gt;This is done in the service layer of the UserMovieService.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;public List &amp;lt; Movie &amp;gt; getAllUserMovies(String email) throws UserNotFoundException {&lt;br&gt;
  if (userMovieRepository.findById(email).isEmpty()) {&lt;br&gt;
    throw new UserNotFoundException();&lt;br&gt;
  }&lt;br&gt;
  MovieDTO movieDTO = new MovieDTO();&lt;br&gt;
  List &amp;lt; Movie &amp;gt; movies = userMovieRepository.findById(email).get().getMovieList();&lt;br&gt;
  List &amp;lt; Movie &amp;gt; notWatchedMovies = new ArrayList &amp;lt; &amp;gt; ();&lt;br&gt;
  for (Movie: movies) {&lt;br&gt;
    if (!m.isWatched()) {&lt;br&gt;
      notWatchedMovies.add(m);&lt;br&gt;
    }&lt;br&gt;
  }&lt;br&gt;
  JSONObject jsonObject = new JSONObject();&lt;br&gt;
  jsonObject.put("notWatched Movies", notWatchedMovies);&lt;br&gt;
  movieDTO.setJsonObject(jsonObject);&lt;br&gt;
  rabbitTemplate.convertAndSend(exchange.getName(), "movie-routing", movieDTO);&lt;br&gt;
  return movies;&lt;br&gt;
}&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The RabbitMQ Console
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2sz75l2cx16nm6euoojt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2sz75l2cx16nm6euoojt.png" alt="Image description" width="800" height="363"&gt;&lt;/a&gt;&lt;br&gt;
The message remains in the queue until it is consumed.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Subscriber Microservice
&lt;/h2&gt;

&lt;p&gt;Steps to create the subscriber service:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Define configurations of exchange, queue, and binding to connect to RabbitMQ.&lt;/li&gt;
&lt;li&gt;The subscriber must know which queue to connect to, so we will define them in the configuration class.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;@Configuration&lt;br&gt;
public class MessageConfiguration {&lt;br&gt;
  private String exchangeName = "movie-exchange";&lt;br&gt;
  private String registerQueue = "movie.queue";&lt;br&gt;
  @Bean&lt;br&gt;
  public DirectExchange directExchange() {&lt;br&gt;
    return new DirectExchange(exchangeName);&lt;br&gt;
  }&lt;br&gt;
  @Bean&lt;br&gt;
  public Queue registerQueue() {&lt;br&gt;
    return new Queue(registerQueue, durable true);&lt;br&gt;
  }&lt;br&gt;
  @Bean&lt;br&gt;
  public Jackson2JsonMessageConverter producer {&lt;br&gt;
    Jackson2MessageConverter()&lt;br&gt;
    return new Jackson2JsonMessageConverter();&lt;br&gt;
  }&lt;br&gt;
  @Bean&lt;br&gt;
  Binding bindingUser(DirectExchange exchange, Queue registerQueue) {&lt;br&gt;
    return BindingBuilder.bind(registerQueue()).to(exchange).with("movie-routing");&lt;br&gt;
  }&lt;br&gt;
}&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Domain - DTO Object
&lt;/h3&gt;

&lt;p&gt;Build the domain object, also known as DTO, which will store the information to be received from the queue.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;import org.json.simple.JSONObject;&lt;br&gt;
public class MovieDTO {&lt;br&gt;
  private JSONObject jsonObject;&lt;br&gt;
  public MovieDTO() {}&lt;br&gt;
  public JSONObject getJsonObject() {&lt;br&gt;
    return jsonObject;&lt;br&gt;
  }&lt;br&gt;
  public void setJsonObject(JSONObject jsonObject) {&lt;br&gt;
    this.jsonObject = jsonObject;&lt;br&gt;
  }&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Read the Data From the Queue
&lt;/h3&gt;

&lt;p&gt;In the service layer of the Notification service, save the data read from the queue in the database by setting the data to the Notification object.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;@RabbitListener(queues = "movie.queue")&lt;br&gt;
@Override&lt;br&gt;
public void saveNotifications(MovieDTO movieDTO) {&lt;br&gt;
  Notification notification = new Notification();&lt;br&gt;
  String email = movieDTO.getJsonObject().get("email").toString();&lt;br&gt;
  if (notificationRepository.findById(email).isEmpty()) {&lt;br&gt;
    notification.setEmail(email);&lt;br&gt;
  }&lt;br&gt;
  notification.setNotificationMessage("The list of not watched movies");&lt;br&gt;
  notification.setMovieNames(movieDTO.getJsonObject());&lt;br&gt;
  notificationRepository.save(notification);&lt;br&gt;
}&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Dockerize the Microservices Using Docker Compose
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Write Docker files for each microservice with the necessary configurations.&lt;/li&gt;
&lt;li&gt;Define the docker-compose.yml file with all the services listed.&lt;/li&gt;
&lt;li&gt;The Docker configuration for RabbitMQ in the docker-compose.yml is shown in the image.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fag441ctprf0pdjd8jmh6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fag441ctprf0pdjd8jmh6.png" alt="Image description" width="800" height="603"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Output
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fegehwz7dngjb4lykuhpi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fegehwz7dngjb4lykuhpi.png" alt="Image description" width="800" height="344"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
