Click or drag to resize

Messaging using RabbitMQ

The RabbitMQ message broker is used by AskiaPortalCmnAPI and by all modules to send messages between them.

This topic contains the following sections:

Installing RabbitMQ on Windows

RabbitMQ requires a 64-bit supported version of Erlang for Windows to be installed. Erlang releases include a Windows installer.

Important note Important

The Erlang installer must be run using an administrative account otherwise a registry key expected by the RabbitMQ installer will not be present.

Erlang installer can be downloaded here. Once a supported version of Erlang is installed, download the RabbitMQ installer and run it. It installs RabbitMQ as a Windows service and starts it using the default configuration.

All related up do date information can be found on the RabbitMQ website

Using MessageQueue functionality

There are three rows included in the Config table of the AskiaPortal database:

  • MessageBrokerHostName - required, message broker's address, "localhost" by default, must be changed if your message broker is installed on a distant server

  • MessageBrokerUserName - optional, message broker's user name, empty string by default, can be used if you control access to your message broker with login and password

  • MessageBrokerPassword - optional, message broker's password, empty string by default, can be used if you control access to your message broker with login and password

The program that want to use the MessageQueue functionality must import the AskiaPortalCmn.

C#
using AskiaPortalCmn;

To obtain an instance of the MessageQueue object, you have to do the next thing:

C#
var messageQueue = MessageQueueFactory.Get();

If you want to publish (send) a message to the RabbitMQ, each time you have to call the mq.Send(...). Example:

C#
var message = "This is a test message";

var routingArguments = new Dictionary<MatchItemKeys, object> 
{
    { MatchItemKeys.entity, "user" },
    { MatchItemKeys.action, "created" } 
};

messageQueue.Send(context, message, routingArguments);

Where routingArguments is a dictionary that will be present in the message header attribute and will be used by the message broker to route the message.

Examples of some valid key/value pairs in routingArguments variable:

{"entity":"survey","action":"save"}

When you want to receive (consume) a message, you have to call the mq.Listen(...) only once. Example:

C#
var messageQueueFilter = MessageQueueFactory.CreateMessageQueueFilter(
                                    new MatchItem(MatchItemKeys.entity, "survey"),
                                    new MatchItem(MatchItemKeys.action, "publish"),
                                    new MatchItem(MatchItemKeys.source, "design"));

messageQueue.Listen((context, messageContainer) => { /*Do something*/ }, messageQueueFilter);

The Listen() method works as a subscription to some kind of messages. So you do not need to call it each time.

The first argument is a callback, a C# Action that will be executed each time a new message arrrives. It has two parameters: of types AskiaPortalCmn.IContext and AskiaPortalCmn.IMessageContainer.

The second argument AskiaPortalCmn.IMessageQueueFilter gives you a possibility to be selective in what kind of messages you want to receive. In the example you have specified one filter with the key/value pairs: {"entity":"survey","action":"publish","source":"design"}

As you can see the routingArguments parameter used to send the message and this filter parameter used to listen the message are very similar. The message broker uses this information to route the messages.

Let see an exemple:

Sending a message:
So, imagine that you have sent a message from Design Portal Module with a routingArguments parameter containing the items: {"entity":"survey","action":"publish"}

In AskiaPortalCmn side:
AskiaPortalCmn will send this message to the message broker. The message header will contain the already specified routingArguments key/value pairs, but also AskiaPortalCmn will add some other useful items as source and sessionKey.
So the message broker receive a message with a header containing the items:
{"entity":"survey","action":"publish", "source":"design", "sessionKey": "abc"}

Listening the message:
If you have called the Listen method with the filter {"entity":"survey","action":"publish","source":"design"} you will receive the message. But you will also receive the message if your filter was: {"entity":"survey","action":"publish"}.
In both cases all the key/value pairs specified in the filter are present in the message header.

If you are listening with the filter: {"entity":"survey","action":"publish","source":"vista"}, you will not receive the message. The message headers don't match with the criteria "source":"vista".