Bring Erl On: Provisioning RabbitMQ users through Mule

motif

Though a veteran language and platform, Erlang has recently gained a lot of traction, as very visible web sites and open source projects decided to use it in order to leverage its intrinsic support for highly concurrent, fault tolerant and distributed applications. To name a few, let’s mention: Facebook Chat, Mochiwebejabberd, RabbitMQ, riak and CouchDB.

Without opting for as a development platform, companies may still be tempted to leverage an -built middleware: most of them offer public interfaces accessible over generic protocols, like HTTP, and are easy to integrate quickly and efficiently. That said advanced scenarios can require a tighter integration like, for example, creating a module for ejabberd that requires to call custom Java code or reaching server functions on that are not accessible through AMQP.

This is when the Duke meets Erl. And this is when Mule ESB can help, thanks to the new and coming Erlang Transport for Mule 3. Read on for more information about the transport and a walk-through a simple use-case of RabbitMQ integration.

Duke Meets Erlang With Mule

The Mule Erlang Transport is built on top of Erlang’s Jinterface, which provides the low level building blocks necessary to interface Java and Erlang systems. The transport takes care of configuring these building blocks and does extra stuff like supporting threading (so incoming messages are processed in parallel and not sequentially), offering support for inbound and outbound gen_server call semantics (for better integration with OTP applications) and transparent Java ⇔ Erlang message transformations.

So what can we concretely do with this new transport? Here are a few examples:

We’re going to use the latter to implement a simple use case: we want to enable the provisioning of RabbitMQ users, through Mule ESB, via a simple HTTP POST of a JSON object (something that is not feasible over AMQP).

Use case: Provisioning RabbitMQ users through Mule

Rabbit_and_Donkey

The Erlang transport connector declaration is very simple:

This connector will be identified as MuleRabbitMqController amongst all the Erlang nodes that may engage in a cluster. Note that we need to use the same magic cookie (Erlang’s security is delicious) as the one used by RabbitMQ in order to communicate with it.

A user provisioning operation is done with two RabbitMQ commands: create user and set permissions. Therefore we will create two Mule services, one for each operation, chaining them together with an in-memory queue. We will set the permissions only if creating the user was successful. Let’s look at the first service, which does the JSON heavy-lifting for incoming HTTP requests and their responses, and tries to create a user on RabbitMQ:

The important aspect of this service is the outbound RPC call to Erlang. Note how we pass a list of binaries, which are the arguments expected by the rabbit_access_control:add_user/2 function. Also, since we only have one Erlang connector in our configuration, we don’t need to explicitly refer to it in each endpoint. We pass whatever the result to this call was to the next service, listed below:

Following a common Erlang pattern, the user creation service should have returned “ok” in case of success. If that was the case, we proceed with the setting of permissions, calling rabbit_access_control:set_permissions/5 in a similar fashion as we did for the user creation. If the user creation failed, we send whatever error response was returned to a logger service:

With this in place, we can now try to run our Mule configuration. The JSON object to HTTP POST has a very simple form:

Let’s give it a try:

Success! We now have a user ‘mule’ created with all permissions granted on the / virtual host. Let’s run the command again:

Expected failure! Errors are correctly returned from RabbitMQ and reported back to the caller. Note that a failure in permission setting would be directly reported to the caller too.

Thanks to this simple Mule service, any HTTP-capable system or application in your IT landscape is now able to provision users in RabbitMQ.

In the future, if someone mentions Erlang, have no fear and… bring Erl on!


We'd love to hear your opinion on this post


7 Responses to “Bring Erl On: Provisioning RabbitMQ users through Mule”

  1. Hi,

    With RabbitMQ and Spring AMQP, I have to achieve is a faster consumption of each message. The scenario is like this:

    I have to send emails/SMSes to different people after consuming the messages internally. I want to just post a message and consume it faster by having multiple consumers ready. The message should be consumed only by one consumer…

    Should I make a no. of consumers using a shared rabbitmq queue in which each consumer consumes the message posted on the exchange, deletes it from the queue and then after passes that message to a new thread for processing ?

    But having a single queue might hamper the performance.

    Is there any other way which can cater my requirement ? what do you suggest?

  2. Spring AMQP questions are better asked there: http://forum.springsource.org/forumdisplay.php?f=74

    Unless you prove with performance test that a single queue really hampers performances, I suggest you start simple, i.e. a single queue with multiple listeners subscribed on this queue. If performances are not up to par, try tweaking the delivery mode or acking behavior. Then, and only then, if the performances are still not as expected, you may want to start introducing a more complex design.

  3. This is interesting, thanks. Personally I’d have either wrapped the rabbitmq management webapp (as a REST service) or cheated and wrapped around the rabbitmqctl command; but good to see there’s a way to bridge the divide between Erlang and the Java world.

  4. Hi, I am trying to send json object to rabbitmq in mule. I wrote down transformation of json part in java. Here is the code

    package com.echostar.component;

    import java.io.IOException;

    import org.json.JSONObject;

    import com.rabbitmq.client.Connection;
    import com.rabbitmq.client.ConnectionFactory;
    import com.rabbitmq.client.Channel;

    import com.echostar.model.uimetadata.jaxb.UI;

    public class RabbitMQMessageTransferComponent {
    public String getUI(UI ui) throws Exception{

    JSONObject jsonUI = new JSONObject(ui);
    String jsonUIString = jsonUI.toString();
    System.out.println(jsonUI.toString());
    return “Message successfully sent to rabbitmq from UI”;
    }

    }

    Here is xml code and I am struggling on how to send json object to rabbitmq…

    I would be greatly appreciated if you can give me some advice on this.

    Thank you

  5. My xml code was not post so I am put there again.

    Thank you in advance.

  6. Please post your questions in the MuleSoft forums (http://forum.mulesoft.org/), using the proper code syntax markup so XML is preserved.

  7. Would you look at this link?I post my issue there.
    http://forum.mulesoft.org/mulesoft/topics/how_to_connect_amqp_connector_for_rabbitmq_with_muleesb
    Thank you in advance.