{"id":744,"date":"2022-01-18T16:46:29","date_gmt":"2022-01-18T13:16:29","guid":{"rendered":"https:\/\/m-shaeri.ir\/blog\/?p=744"},"modified":"2022-03-24T17:43:06","modified_gmt":"2022-03-24T13:13:06","slug":"a-simple-real-world-project-with-rabbitmq-python-java-and-php","status":"publish","type":"post","link":"https:\/\/mshaeri.com\/blog\/a-simple-real-world-project-with-rabbitmq-python-java-and-php\/","title":{"rendered":"RabbitMQ + Java + Python + PHP Real-World Example"},"content":{"rendered":"\n<p><strong>RabbitMQ<\/strong> is one of the most popular and easy to deploy message brokers. It receives messages from producers, and delivers them to consumers. It is used to reduce loads and delivery times in applications, and it is widely used in microservice architectures to facilitate asynchronous communication between services. One thing that makes this message broker very popular is that for all  the major programming languages, the client libraries to work with the RabbitMQ are available and easy to use. In this article I am going to build a simple project in which different services with different technology communicate to each other via RabbitMQ.<\/p>\n\n\n\n<h2 class=\"is-style-default has-vivid-cyan-blue-color has-text-color has-medium-font-size wp-block-heading\">Project Description<\/h2>\n\n\n\n<p>We want to build a registration system that sends SMS &amp; email confirmation messages to user after registration. We have 3 tasks to be done in registration process :<strong> <\/strong><span class=\"has-inline-color has-vivid-red-color\">recording user information in database<\/span>, <span class=\"has-inline-color has-vivid-red-color\">sending SMS confirmation<\/span> and <span class=\"has-inline-color has-vivid-red-color\">sending email confirmation<\/span>. <\/p>\n\n\n\n<h2 class=\"is-style-default has-medium-font-size wp-block-heading\"><span class=\"has-inline-color has-vivid-cyan-blue-color\">Monolith approach<\/span><\/h2>\n\n\n\n<p>The simplest approach for implementing this system is to do all tasks in sequence and synchronously as a monolith application. In this way, first we store user information in database, then, after completion of first step we send SMS message to user by calling external 3dparty API and wait for its response, next we call the email function to send confirmation email and wait for the function to return the result, finally we can show the success message to user in the browser. <\/p>\n\n\n\n<div class=\"wp-block-image is-style-default\"><figure class=\"aligncenter size-large is-resized\"><a href=\"https:\/\/m-shaeri.ir\/blog\/wp-content\/uploads\/2022\/01\/sequncial_monolith_approach.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/m-shaeri.ir\/blog\/wp-content\/uploads\/2022\/01\/sequncial_monolith_approach-1024x658.jpg\" alt=\"\" class=\"wp-image-749\" width=\"512\" height=\"329\" srcset=\"https:\/\/mshaeri.com\/blog\/wp-content\/uploads\/2022\/01\/sequncial_monolith_approach-1024x658.jpg 1024w, https:\/\/mshaeri.com\/blog\/wp-content\/uploads\/2022\/01\/sequncial_monolith_approach-300x193.jpg 300w, https:\/\/mshaeri.com\/blog\/wp-content\/uploads\/2022\/01\/sequncial_monolith_approach-768x493.jpg 768w, https:\/\/mshaeri.com\/blog\/wp-content\/uploads\/2022\/01\/sequncial_monolith_approach.jpg 1297w\" sizes=\"(max-width: 512px) 100vw, 512px\" \/><\/a><figcaption>Sequential approach for registration system<\/figcaption><\/figure><\/div>\n\n\n\n<p>One of disadvantages of this approach is that user will face with an unexpected delay in the situation that any of SMS API or email function takes more time to respond. Moreover, if for any reason the system fail just after first step (storing data in database), no SMS and no email message will be sent to user, because all the next tasks depend to completion of first one .<\/p>\n\n\n\n<h2 class=\"is-style-default has-medium-font-size wp-block-heading\"><span class=\"has-inline-color has-vivid-cyan-blue-color\">Separated services with asynchronous inter-communication<\/span><\/h2>\n\n\n\n<p>Separated services allows a system to be divided into a number of smaller, independent and loosely coupled&nbsp;parts. Each part is only responsible for its own tasks , particularly in microservice architecture each service has got exclusive and isolated resources. They work as autonomous processes and communicate with each other through APIs which can be in synchronous or asynchronous way. In this section I focus on asynchronous way of communicating. Each service can be implemented in a different programming language and technology on a different platform.<\/p>\n\n\n\n<p>The Registration System as I described above consists of 3 main parts :  <span class=\"has-inline-color has-vivid-red-color\">recording user information in database<\/span>, <span class=\"has-inline-color has-vivid-red-color\">sending SMS confirmation<\/span> and <span class=\"has-inline-color has-vivid-red-color\">sending email confirmation<\/span>.  We simply assign each task to an individual service with same name.<\/p>\n\n\n\n<div class=\"wp-block-image is-style-default\"><figure class=\"aligncenter size-full is-resized\"><a href=\"https:\/\/m-shaeri.ir\/blog\/wp-content\/uploads\/2022\/01\/services_asynchrounous.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/m-shaeri.ir\/blog\/wp-content\/uploads\/2022\/01\/services_asynchrounous.jpg\" alt=\"\" class=\"wp-image-751\" width=\"499\" height=\"366\" srcset=\"https:\/\/mshaeri.com\/blog\/wp-content\/uploads\/2022\/01\/services_asynchrounous.jpg 997w, https:\/\/mshaeri.com\/blog\/wp-content\/uploads\/2022\/01\/services_asynchrounous-300x220.jpg 300w, https:\/\/mshaeri.com\/blog\/wp-content\/uploads\/2022\/01\/services_asynchrounous-768x563.jpg 768w\" sizes=\"(max-width: 499px) 100vw, 499px\" \/><\/a><figcaption>Turning monolith project into number of Individual Independent Services<\/figcaption><\/figure><\/div>\n\n\n\n<p>As it is crystal clear,<\/p>\n\n\n\n<ul><li> <strong><span class=\"has-inline-color has-vivid-green-cyan-color\">User Service<\/span><\/strong> are in charge of tasks related to users including user registration.<\/li><li> <span class=\"has-inline-color has-vivid-red-color\"><strong>Email Service<\/strong><\/span> is responsible for sending email upon request.<\/li><li>And <span class=\"has-inline-color has-vivid-cyan-blue-color\"><strong>SMS Service<\/strong><\/span>&#8216;s job is to send mobile SMS upon request.<\/li><\/ul>\n\n\n\n<p>Although each service is assigned and responsible to\/for own tasks separately, they are in need of communicating to one another. In this case, the user service needs to send request to two other services to send confirmation messages. As it&#8217;s mentioned earlier we want to experiment the asynchronous approach of communication. One choice in this sort of communication is to use <strong>message queue<\/strong>. The client service send his request as a message to a queue (we call it <span class=\"has-inline-color has-vivid-red-color\">Producer<\/span> service) and the other service which serves the first service, consumes the messages within queue in FIFO order and accomplishes the related tasks (it is called <span class=\"has-inline-color has-vivid-red-color\">Consumer<\/span> service). In this project I use <strong><span class=\"has-inline-color has-vivid-red-color\">RabbitMQ<\/span><\/strong> as message broker which is responsible for receiving messages from producers, and delivers them to consumers. <\/p>\n\n\n\n<h2 class=\"is-style-default has-medium-font-size wp-block-heading\"><span class=\"has-inline-color has-vivid-cyan-blue-color\">RabbitMQ installation and configuration<\/span><\/h2>\n\n\n\n<p>RabbitMQ needs Erlang to work. So first we should download and install the erlang on our system. At the time of this post, the latest version of RabbitMQ is 3.9.12 which is compatible with Erlang 23.2 and later versions. <\/p>\n\n\n\n<p>Erlang 24.1.12  download page : <a href=\"https:\/\/github.com\/rabbitmq\/rabbitmq-server\/releases\/tag\/v3.9.12\" target=\"_blank\" rel=\"noreferrer noopener\">link<\/a><br>RabbitMQ 3.912 download page : <a href=\"https:\/\/erlang.org\/download\/otp_versions_tree.html\" target=\"_blank\" rel=\"noreferrer noopener\">link<\/a><\/p>\n\n\n\n<p>Install RabbitMQ after Erlang. The RabbitMQ service starts after installation is completed.  If it didn&#8217;t start, run it manually from service manager of your operating system. In Windows it&#8217;s better to add <strong>sbin<\/strong> folder of RabbitMQ to system path otherwise you need to run your command under this directory. By default, RabbitMQ listens on&nbsp;<strong>port 5672<\/strong>&nbsp;on all interfaces.<\/p>\n\n\n\n<p>Then we need to enable the RabbitMQ management plugin, it provides an HTTP API for RabbitMQ management, a web based interface and a command line tool. We don&#8217;t need to install it separately,  it is already included in the RabbitMQ installation package , it just needs to be enabled :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">rabbitmq-plugins enable rabbitmq_management<\/code><\/pre>\n\n\n\n<p>The web UI can be accessed at&nbsp;<span class=\"has-inline-color has-vivid-cyan-blue-color\">http:\/\/<em>localhost<\/em>:15672<\/span>. But, we need a username with appropriate permissions to be able to login to management UI. Let&#8217;s create one :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\"><em># create a user<\/em> \nrabbitmqctl add_user rabbitmq_admin 1234@5\n<em># give the user the \"administrator\" privilege (tag)<\/em>\nrabbitmqctl set_user_tags rabbitmq_admin administrator<\/code><\/pre>\n\n\n\n<p>Now, open  &nbsp;<span class=\"has-inline-color has-vivid-cyan-blue-color\">http:\/\/<em>localhost<\/em>:15672<\/span>  in your browser and login with  <strong>rabbitmq_admin<\/strong> and its password <strong>1234@5<\/strong> . After login you will be redirected to Overview page where you can see server related information and statistics. First we need to define a new virtual host for our project from <strong>Admin tab&gt; Virtual Hosts &gt; Add a new virtual host<\/strong> section :<\/p>\n\n\n\n<div class=\"wp-block-image is-style-default\"><figure class=\"aligncenter size-large is-resized\"><a href=\"https:\/\/m-shaeri.ir\/blog\/wp-content\/uploads\/2022\/01\/rabbitmq_ui_virtual_host.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/m-shaeri.ir\/blog\/wp-content\/uploads\/2022\/01\/rabbitmq_ui_virtual_host-1024x412.jpg\" alt=\"Add new virtual host in RabbitMQ for our project\" class=\"wp-image-752\" width=\"1024\" height=\"412\" title=\"Add new virtual host in RabbitMQ for our project\" srcset=\"https:\/\/mshaeri.com\/blog\/wp-content\/uploads\/2022\/01\/rabbitmq_ui_virtual_host-1024x412.jpg 1024w, https:\/\/mshaeri.com\/blog\/wp-content\/uploads\/2022\/01\/rabbitmq_ui_virtual_host-300x121.jpg 300w, https:\/\/mshaeri.com\/blog\/wp-content\/uploads\/2022\/01\/rabbitmq_ui_virtual_host-768x309.jpg 768w, https:\/\/mshaeri.com\/blog\/wp-content\/uploads\/2022\/01\/rabbitmq_ui_virtual_host-1536x619.jpg 1536w, https:\/\/mshaeri.com\/blog\/wp-content\/uploads\/2022\/01\/rabbitmq_ui_virtual_host.jpg 1907w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption>Add new virtual host in RabbitMQ for our project<\/figcaption><\/figure><\/div>\n\n\n\n<p>As you can see in the list, I have already added a virtual host with <strong>shaeri-vc<\/strong> name. Next, go to <strong>Exchange<\/strong> <strong>tab<\/strong>, in <strong>add new exchange<\/strong>, select the virtual host you created in previous step, choose a name for your exchange in the <strong>Name field<\/strong>, I chose &#8220;new_registration&#8221;, it is important because we are going to use it our codes in later steps and select <strong>fanout<\/strong> in the <strong>Type<\/strong> <strong>dropdown<\/strong>, click <strong>Add exchange<\/strong> to create the exchange. We can also create exchange in code that is more common, but here I aim to show you how to work with management web UI.<\/p>\n\n\n\n<div class=\"wp-block-image is-style-default\"><figure class=\"aligncenter size-large\"><a href=\"https:\/\/m-shaeri.ir\/blog\/wp-content\/uploads\/2022\/01\/rabbitmq_new_exchnage.png\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"462\" src=\"https:\/\/m-shaeri.ir\/blog\/wp-content\/uploads\/2022\/01\/rabbitmq_new_exchnage-1024x462.png\" alt=\"\" class=\"wp-image-753\" srcset=\"https:\/\/mshaeri.com\/blog\/wp-content\/uploads\/2022\/01\/rabbitmq_new_exchnage-1024x462.png 1024w, https:\/\/mshaeri.com\/blog\/wp-content\/uploads\/2022\/01\/rabbitmq_new_exchnage-300x135.png 300w, https:\/\/mshaeri.com\/blog\/wp-content\/uploads\/2022\/01\/rabbitmq_new_exchnage-768x347.png 768w, https:\/\/mshaeri.com\/blog\/wp-content\/uploads\/2022\/01\/rabbitmq_new_exchnage-1536x694.png 1536w, https:\/\/mshaeri.com\/blog\/wp-content\/uploads\/2022\/01\/rabbitmq_new_exchnage.png 1860w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/a><figcaption>Add new Fanout Exchange <\/figcaption><\/figure><\/div>\n\n\n\n<p>We need to send message to both SMS queue and Email queue upon every user registration events. I created a Fanout exchange because it routes messages to all bound queues, which is exactly what we want. Now that we have our RabbitMQ server installed, configured and ready to work, we dive into codes.<\/p>\n\n\n\n<h2 class=\"is-style-default has-medium-font-size wp-block-heading\"><span class=\"has-inline-color has-vivid-cyan-blue-color\">User Registration Service<\/span><\/h2>\n\n\n\n<p>Registration service is the entry point of our tiny project. It accepts user&#8217;s basic information including Name, Family, Mobile number and Email address, stores them into database and sends a message containing these data to RabbitMQ, two other services that are listening to the queues which are bound to <strong>new_registration<\/strong> exchange will consume this message and perform appropriate actions. <\/p>\n\n\n\n<div class=\"wp-block-image is-style-default\"><figure class=\"aligncenter size-full is-resized\"><a href=\"https:\/\/m-shaeri.ir\/blog\/wp-content\/uploads\/2022\/01\/rabbitmq_fanout_exchange_queue.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/m-shaeri.ir\/blog\/wp-content\/uploads\/2022\/01\/rabbitmq_fanout_exchange_queue.jpg\" alt=\"RabbitMQ Fanout Exchange\" class=\"wp-image-769\" width=\"748\" height=\"274\" srcset=\"https:\/\/mshaeri.com\/blog\/wp-content\/uploads\/2022\/01\/rabbitmq_fanout_exchange_queue.jpg 997w, https:\/\/mshaeri.com\/blog\/wp-content\/uploads\/2022\/01\/rabbitmq_fanout_exchange_queue-300x110.jpg 300w, https:\/\/mshaeri.com\/blog\/wp-content\/uploads\/2022\/01\/rabbitmq_fanout_exchange_queue-768x281.jpg 768w\" sizes=\"(max-width: 748px) 100vw, 748px\" \/><\/a><figcaption>User service sends a message to fanout exchange, two other services that are listening to the queues which are bound to the exchange consumes the message.<\/figcaption><\/figure><\/div>\n\n\n\n<p>We code the Registration Service in PHP, a simple API that accepts user information in json forma as a HTTP POST request. For communicating with RabbitMQ in PHP we use &nbsp;<a href=\"https:\/\/github.com\/php-amqplib\/php-amqplib\">php-amqplib<\/a>, the most widely used PHP client for RabbitMQ. To communicating with message broker, clients need to pass authentication and authorization. So, before we go to code,  we need to create a user for our Registration service in RabbitMQ (<strong>Admin Tab&gt; Users<\/strong>), click on the user name in the list, and set its  permission to write on <strong>new_registration<\/strong> exchange. Everything is ready to dive into code, we need to send user object to message broker to be delivered to other services, but RabbitMQ has no knowledge on object, messages all are just byte arrays to it. So, we need to serialize objects before sending them to RabbitMQ.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"php\" class=\"language-php line-numbers\">&lt;?php\nrequire_once 'vendor\/autoload.php';\nuse PhpAmqpLib\\Connection\\AMQPStreamConnection;\nuse PhpAmqpLib\\Exchange\\AMQPExchangeType;\nuse PhpAmqpLib\\Message\\AMQPMessage;\n\n\/\/ Request sample payload =&gt; { \"name\": \"Alex\", \"family\": \"Sherif\", \"phone\": \"09205551325\", \"email\" : \"my_email@yahoo.com\"}\n\n\/\/ get request payload\n$inputJSON = file_get_contents('php:\/\/input');\n$user_object= json_decode( $inputJSON );\n\n\/\/ Store the new user information in Database\n$user_id = StoreInDB($user_object);\n\n\/\/ set RabbitMQ client parameters\n$exchange = \"new_registration\";\n$vhost = \"shaeri-vc\";\n$rabbitmq_username = \"register_service\";\n$rabbitmq_password = \"1234\";\n\/\/ create a connection to RabbitMQ\n$connection = new AMQPStreamConnection('localhost', 5672, $rabbitmq_username, $rabbitmq_password, $vhost);\n\n\/\/ Create a Channel on the existing connection\n$channel = $connection-&gt;channel();\n\n\/\/ serialize the user object \n$messageBody = json_encode($user_object);\n\/\/ Prepare the message\n$message = new AMQPMessage($messageBody,\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; array('content_type' =&gt; 'application\/json',\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'delivery_mode' =&gt; AMQPMessage::DELIVERY_MODE_PERSISTENT));\n\/\/ send the message to RabbitMQ\n$channel-&gt;basic_publish($message, $exchange);\n&nbsp;\n\/\/Close the Channel &amp; Connection\n$channel-&gt;close();\n$connection-&gt;close();\n\n\/\/ return result to client\nheader('Content-Type: application\/json; charset=utf-8');\necho \"{'result':'OK', 'userid': $user_id}\";\n\n?&gt;<\/code><\/pre>\n\n\n\n<p>In the line 22, I created a connection to RabbitMQ, then in the line 25, a channel is created upon the connection. Next , in the lines 28-33 the message is prepared and sent to message broker. Then I closed the connection and channel in the lines 36 and 37. <\/p>\n\n\n\n<h2 class=\"is-style-default has-medium-font-size wp-block-heading\"><span class=\"has-inline-color has-vivid-red-color\">Single Active Consumer<\/span><\/h2>\n\n\n\n<p>Before we go to next steps, we should know how we want to deal with messages in queues, how many instance of each service will be listening to a queue at same time, and how to handle fails in services. Here I preferer to use <strong>Single active consumer queue<\/strong> mode. It attachs multiple consumers to a queue, however the queue accepts only one active consumer at a time and ignores other consumers. It switches to another registered consumer in case the active one is cancelled or dies. This feature can be enabled at queue declaration time.<\/p>\n\n\n\n<div class=\"wp-block-image is-style-default\"><figure class=\"aligncenter size-full is-resized\"><a href=\"https:\/\/m-shaeri.ir\/blog\/wp-content\/uploads\/2022\/01\/rabbitmq_single_active_consumer-1.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/m-shaeri.ir\/blog\/wp-content\/uploads\/2022\/01\/rabbitmq_single_active_consumer-1.jpg\" alt=\"rabbitmq single active consumer\" class=\"wp-image-808\" width=\"748\" height=\"274\" srcset=\"https:\/\/mshaeri.com\/blog\/wp-content\/uploads\/2022\/01\/rabbitmq_single_active_consumer-1.jpg 997w, https:\/\/mshaeri.com\/blog\/wp-content\/uploads\/2022\/01\/rabbitmq_single_active_consumer-1-300x110.jpg 300w, https:\/\/mshaeri.com\/blog\/wp-content\/uploads\/2022\/01\/rabbitmq_single_active_consumer-1-768x281.jpg 768w\" sizes=\"(max-width: 748px) 100vw, 748px\" \/><\/a><figcaption>  <strong>Single active consumer<\/strong> <strong>queue<\/strong> accepts only one consumer at a time and ignores other consumers.<\/figcaption><\/figure><\/div>\n\n\n\n<h2 class=\"is-style-default has-medium-font-size wp-block-heading\"><span class=\"has-inline-color has-vivid-cyan-blue-color\">Email service<\/span><\/h2>\n\n\n\n<p>In the Email service which I want to write in Python, we need to create a queue and bind it to <strong>new_registration<\/strong> exchange, then start consuming the message from the queue, and trigger a task on every received message that is sending email.<\/p>\n\n\n\n<p> To communicate with RabbitMQ in Python,  <strong>pika<\/strong> package must be installed using pip :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">pip install pika --upgrade<\/code><\/pre>\n\n\n\n<p>The complete code for Email Service :<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"python\" class=\"language-python line-numbers\">import pika, time, json, smtplib, ssl\n\ndef email_function(msg):\n\n&nbsp; print(\" Email service started\")\n\n&nbsp; #Convert the serialized messaged to Python dictionary\n&nbsp; user_info = json.loads(msg)\n\n&nbsp; print(\" [x] Sending Email to \" + user_info['email'])\n&nbsp; port = 465 &nbsp;# For SSL\n&nbsp; smtp_server = \"smtp.gmail.com\"\n&nbsp; sender_email = \"your_email@gmail.com\" &nbsp;\n&nbsp; receiver_email = user_info['email'] &nbsp;\n&nbsp; password = \"YourEmailPassword\"\n&nbsp; message = \"Welcome to our Application, it is a confirmation email!\"\n&nbsp; context = ssl.create_default_context()\n&nbsp; with smtplib.SMTP_SSL(smtp_server, port, context=context) as server:\n&nbsp; &nbsp; server.login(sender_email, password)\n&nbsp; &nbsp; server.sendmail(sender_email, receiver_email, message)\n\n&nbsp; time.sleep(5) # delays for 5 seconds\n&nbsp; print(\" Email service finished\")\n&nbsp; return\n\n# set credentials parameters\ncredentials = pika.PlainCredentials('email_service', '1234')\nparameters = pika.ConnectionParameters('localhost',\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;5672,\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;'shaeri-vc',\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;credentials)\n\n# create connection\nconnection = pika.BlockingConnection(parameters)\n# create channel\nchannel = connection.channel()\n\n# create single active queue if it is not already created\nchannel.queue_declare(queue='email_queue', arguments = {\"x-single-active-consumer\": True})\n# bind the queue to new_registration exchange\nchannel.queue_bind(exchange='new_registration', queue='email_queue')\n\n# create a function which is called on incoming messages\ndef callback(ch, method, properties, body):\n&nbsp; email_function(body)\n\n# set up subscription on the queue\nchannel.basic_consume('email_queue',\n&nbsp; callback,\n&nbsp; auto_ack=True)\n\n# start listening to the queue (blocks)\nchannel.start_consuming()\nconnection.close()<\/code><\/pre>\n\n\n\n<p>As you can see in the code, from the line 27-36 it is connecting to RabbitMQ and creating a channel. In the line 39, it creates the queue and in line 41 it bind the created queue to &#8220;new_registration&#8221; exchange. Next we need a function to be called on incoming messages, I defined <strong>callback<\/strong> function and set up subscription on the queue with this function in line 48. Finally it starts consuming in line 53, it blocks the thread and listens to incoming message in queue. As I mentioned, RabbitMQ works with byte array and string, we sent serialized object to RabbitMQ in User service, so in line 8, I de-serialize message received from RabbitMQ and convert it to Python dictionary.<\/p>\n\n\n\n<h2 class=\"is-style-default has-medium-font-size wp-block-heading\"><span class=\"has-inline-color has-vivid-cyan-blue-color\">SMS Service<\/span><\/h2>\n\n\n\n<p>Like Email service, this service should listen to the queue bound to &#8220;new_registration&#8221; exchange. Every concepts are same as what I did in last section, except that I want to write it in Java. In order to communicate to broker I am going to use the Java client provided by RabbitMQ, <strong>amqp-client<\/strong> . Although I could use the .jar file of this library, I download it by Maven to have better dependency management. Note that it&#8217;s necessary to import &nbsp;<strong>SLF4J API<\/strong>&nbsp;and&nbsp;<strong>SLF4J Simple<\/strong>, because the  RabbitMQ client depends on these two libraries. You may noticed the <strong>org.json<\/strong>,  <strong>httpclient<\/strong> and  <strong>httpmime<\/strong> in dependencies, don&#8217;t worry, we need the org.json to de-serialize the message body, and the two other library helps us in call 3dParty SMS provider&#8217;s web service:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"xml\" class=\"language-xml\">&lt;dependencies&gt;\n    &lt;dependency&gt;\n        &lt;groupId&gt;org.slf4j&lt;\/groupId&gt;\n        &lt;artifactId&gt;slf4j-api&lt;\/artifactId&gt;\n        &lt;version&gt;1.7.33&lt;\/version&gt;\n    &lt;\/dependency&gt;\n    &lt;dependency&gt;\n        &lt;groupId&gt;org.slf4j&lt;\/groupId&gt;\n        &lt;artifactId&gt;slf4j-simple&lt;\/artifactId&gt;\n        &lt;version&gt;1.7.33&lt;\/version&gt;\n    &lt;\/dependency&gt;\n    &lt;dependency&gt;\n        &lt;groupId&gt;com.rabbitmq&lt;\/groupId&gt;\n        &lt;artifactId&gt;amqp-client&lt;\/artifactId&gt;\n        &lt;version&gt;5.14.1&lt;\/version&gt;\n    &lt;\/dependency&gt;\n    &lt;dependency&gt;\n        &lt;groupId&gt;org.json&lt;\/groupId&gt;\n        &lt;artifactId&gt;json&lt;\/artifactId&gt;\n        &lt;version&gt;20211205&lt;\/version&gt;\n    &lt;\/dependency&gt;\n    &lt;dependency&gt;\n        &lt;groupId&gt;org.apache.httpcomponents&lt;\/groupId&gt;\n        &lt;artifactId&gt;httpclient&lt;\/artifactId&gt;\n        &lt;version&gt;4.5.1&lt;\/version&gt;\n    &lt;\/dependency&gt;\n    &lt;dependency&gt;\n        &lt;groupId&gt;org.apache.httpcomponents&lt;\/groupId&gt;\n        &lt;artifactId&gt;httpmime&lt;\/artifactId&gt;\n        &lt;version&gt;4.5.1&lt;\/version&gt;\n    &lt;\/dependency&gt;\n\n&lt;\/dependencies&gt;<\/code><\/pre>\n\n\n\n<p>And finally the code for SMS service in Java : <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"java\" class=\"language-java\">import com.rabbitmq.client.ConnectionFactory;\nimport com.rabbitmq.client.Connection;\nimport com.rabbitmq.client.Channel;\nimport com.rabbitmq.client.DeliverCallback;\nimport org.apache.http.HttpResponse;\nimport org.apache.http.client.HttpClient;\nimport org.apache.http.client.methods.HttpGet;\nimport org.apache.http.client.methods.HttpUriRequest;\nimport org.apache.http.impl.client.HttpClientBuilder;\nimport org.json.*;\n\nimport java.nio.charset.StandardCharsets;\n\npublic class app {\n    private final static String <em>QUEUE_NAME <\/em>= \"SMS_Queue\";\n    private final static String <em>EXCHANGE_NAME <\/em>= \"new_registration\";\n\n    public static void main(String[] argv) throws Exception {\n\n        \/\/ create connection\n        ConnectionFactory factory = new ConnectionFactory();\n        factory.setUri(\"amqp:\/\/sms_service:1234@localhost:5672\/shaeri-vc\");\n        Connection connection = factory.newConnection();\n        \/\/ create channel\n        Channel channel = connection.createChannel();\n\n        \/\/ enable the single active mode\n        Map&lt;String, Object&gt; arguments = new HashMap&lt;String, Object&gt;();\n        arguments.put(\"x-single-active-consumer\", true);\n        \/\/ create queue if it is not already created\n        channel.queueDeclare(<em>QUEUE_NAME<\/em>, true, false, false, arguments);\n        \/\/ bind the queue to new_registration exchange\n        channel.queueBind(<em>QUEUE_NAME<\/em>, <em>EXCHANGE_NAME<\/em>, \"\");\n\n        \/\/create a callback function to handle incoming messages\n        DeliverCallback deliverCallback = (consumerTag, delivery) -&gt; {\n            String message = new String(delivery.getBody(), StandardCharsets.<em>UTF_8<\/em>);\n            try {\n                JSONObject userObject = new JSONObject(message);\n                System.<em>out<\/em>.println(\" [x] New task received : Sending SMS to \" + userObject.getString(\"phone\") );\n                HttpClient client = HttpClientBuilder.<em>create<\/em>().build();\n                HttpUriRequest httpUriRequest = new HttpGet(\"http:\/\/URL\/to\/sms\/provider\/\");\n                HttpResponse response = client.execute(httpUriRequest);\n                System.<em>out<\/em>.println(response);\n                System.<em>out<\/em>.println(\" [x] SMS sent to : \"  + userObject.getString(\"phone\") );\n            }catch (Exception err){\n                System.<em>out<\/em>.println(\" [x] Error Occurred\" + err.toString() );\n            }\n\n        };\n\n\n        System.<em>out<\/em>.println(\" [*] Waiting for new task\");\n        \/\/ start listening to the queue (it doesn't blocks)\n        channel.basicConsume(<em>QUEUE_NAME<\/em>, true, deliverCallback, consumerTag -&gt; { });\n    }\n}\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>In this article we are going to build a simple real world example in which different services with different technology ( java, python, PHP) communicate to one another via RabbitMQ.<\/p>\n","protected":false},"author":1,"featured_media":803,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[69,94,85,35,41,86,70],"tags":[97,91,95,108,100,106,104,99,98,9,67,89,90,92,88,109,39,101,105,87,102,107,103,96],"_links":{"self":[{"href":"https:\/\/mshaeri.com\/blog\/wp-json\/wp\/v2\/posts\/744"}],"collection":[{"href":"https:\/\/mshaeri.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mshaeri.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mshaeri.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mshaeri.com\/blog\/wp-json\/wp\/v2\/comments?post=744"}],"version-history":[{"count":48,"href":"https:\/\/mshaeri.com\/blog\/wp-json\/wp\/v2\/posts\/744\/revisions"}],"predecessor-version":[{"id":939,"href":"https:\/\/mshaeri.com\/blog\/wp-json\/wp\/v2\/posts\/744\/revisions\/939"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/mshaeri.com\/blog\/wp-json\/wp\/v2\/media\/803"}],"wp:attachment":[{"href":"https:\/\/mshaeri.com\/blog\/wp-json\/wp\/v2\/media?parent=744"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mshaeri.com\/blog\/wp-json\/wp\/v2\/categories?post=744"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mshaeri.com\/blog\/wp-json\/wp\/v2\/tags?post=744"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}