Using the RabbitMQ Messaging API
InterSystems provides an API you can use to publish and consume RabbitMQ messages. Your code acts as a publisher or consumer by creating a client, then calling the client’s methods to perform actions like sending and receiving messages. InterSystems IRIS also provides methods to manage RabbitMQ queues and exchanges, and to set bindings between the two.
The RabbitMQ API is based on the common messaging classes that are shared by other messaging platforms. This page describes platform-specific variations in the work flow which these common classes establish.
In addition to the API described here, InterSystems provides specialized classes that you can use to send messages to RabbitMQ and retrieve messages from RabbitMQ as part of an interoperability production.
The InterSystems RabbitMQ API corresponds with the RabbitMQ implementation of the AMQP 0–9–1 protocol. To send and receive messages with an external messaging service using the AMQP 1.0 protocol, InterSystems recommends connecting to a JMS implementation of the protocol such as Apache Qpid JMSOpens in a new tab. InterSystems provides a JMS API for working with JMS applications.
Connecting to RabbitMQ
To create a connection to RabbitMQ:
-
Create a settings object. To do this create an instance of %External.Messaging.RabbitMQSettingsOpens in a new tab and set its properties as needed:
-
username and password define the client's RabbitMQ credentials. If you do not set the value for these properties, "guest" is provided as the default.
-
host defines the name for the host server. If not defined, "localhost" is the default.
-
port is an integer which defines the port number being used on the host server. The default is 5672.
-
virtualHost optionally defines the name of the virtual host.
For example:
Set settings = ##class(%External.Messaging.RabbitMQSettings).%New() Set settings.username = "ronaldkellogg" Set settings.password = "449!ds%t" Set settings.host = "bazco.com" Set settings.port = 5693
-
-
(Optional.) If you want to connect to RabbitMQ using SSL/TLS, set the enableSSL property for the settings object to 1, and then set the following properties according to your TLS configuration:
-
tlsVersion, a string that specifies the version of the TLS protocol you are using. The default value is "TLSv1.2"
-
enableHostnameVerification, a boolean which determines whether the peer verification process includes a verification that the hostname of the server matches the name on the server certificate
-
clientKeyFile, a string specifying the path to the client’s private key file (if the server is configured to perform peer verification)
-
keyPassword, the password string which is required to access the client key file (if the key file is secured)
-
keyStoreFile, a string specifying the path to the key store file
-
keyStorePassword, the password string which is required to access the key store file (if the key store file is secured)
-
-
Create the messaging client object. To do this, call the CreateClient() method of the generic %External.Messaging.ClientOpens in a new tab class, passing the settings object as the first argument. For example:
Set client = ##class(%External.Messaging.Client).CreateClient(settings, .tSC) If $$$ISERR(tSC) { //handle error scenario }
The method returns a status code by reference as the second argument. Your code should check the status before proceeding.
Because the settings object is an instance of %External.Messaging.RabbitMQSettingsOpens in a new tab, the returned object (client) is an instance of %External.Messaging.RabbitMQClientOpens in a new tab.
RabbitMQ Publishers
InterSystems IRIS can act as a RabbitMQ publisher by calling API methods to create messages and send them. If the application needs to create the exchanges where messages will be sent or the queues where the exchanges will route them, see Working with Exchanges and Queues. The following flow uses the client object to interact with RabbitMQ as a publisher:
To prepare a message to be sent, create a new instance of the %External.Messaging.RabbitMQMessageOpens in a new tab object. Then, define the properties for that message object as needed. For a full description of the available message properties, refer to the RabbitMQ documentationOpens in a new tab. Set the content of the message by invoking the SetEncodedContent() method (for UTF-8) or the SetContent() method (for other values of contentEncoding). For example:
set exchange = "events_handler"
set routingKey = "quick_start"
set deliveryMode = 2
set body = "MyMessage"
set msg = ##class(%External.Messaging.RabbitMQMessage).%New()
set msg.exchange = exchange
set msg.routingKey = routingKey
set msg.deliveryMode = deliveryMode
do msg.SetEncodedContent(body)
After creating a message, you can send it to the topic by executing the SendMessage() method for the RabbitMQ client object. For example:
set tSC = client.SendMessage(msg)
if $$$ISERR(tSC) { //handle error scenario }
RabbitMQ Consumers
InterSystems IRIS can act as a RabbitMQ consumer by calling APIs to retrieve messages from a queue. The following flow uses the client object to interact with RabbitMQ as a consumer:
The RabbitMQ client can use the ReceiveMessage() method to act as a RabbitMQ consumer. This method allows you to specify settings for the message retrieval operation by providing a JSON-formatted string as an optional argument. To do so, create a new instance of the %External.Messaging.RabbitMQReceiveSettingsOpens in a new tab class and set properties as desired. The following properties are available:
-
autoAck, a boolean. If true, the server considers messages acknowledged automatically once they are delivered. If false, the server expects explicit, manual acknowledgements from the consumer. If not set, autoAck defaults to false.
-
ackMultiple, a boolean. If true, a manual acknowledgement acknowledges the batch of all messages up to and including the message corresponding to the delivery tag which the acknowledgement supplies. If false, an acknowledgement only acknowledges the message corresponding to the delivery tag it supplies. If not set, ackMultiple defaults to false.
For example:
Set rset = ##class(%External.Messaging.RabbitMQReceiveSettings).%New()
Set rset.autoAck = 0
To retrieve messages, invoke the ReceiveMessage() method inherited by the RabbitMQ client. This method takes the name of a queue as an argument and returns messages as a %ListOfObjectsOpens in a new tab by reference. If you have specified message retrieval settings as described in the preceding section, provide these settings as a third argument using the ToJSON() method. For example:
#dim messages As %ListOfObjects
Set tSC = client.ReceiveMessage(queue, .messages, rset.ToJSON())
For i=1:1:messages.Size {
Set msg = messages.GetAt(i)
Write "Message: ", msg.ToJSON(), !
}
Working with Exchanges and Queues
InterSystems IRIS provides an API for managing RabbitMQ exchanges and queues. This includes:
This section describes how to use the API to perform these tasks. For a detailed explanation of exchanges and queues, refer to the introduction to the AMQP 0–9–0 protocolOpens in a new tab which is provided in the RabbitMQ documentation.
Create or Delete an Exchange
Per the AMQP 0–9–0 specification, all RabbitMQ messages must be sent to an exchange, which routes them to their destination queue (or queues).
A RabbitMQ client object includes a CreateExchange() method for creating an exchange. CreateExchange() accepts the following arguments, in order:
-
exchangeName, the name you wish to assign to the exchange.
-
exchangeType, a string specifying one of the four AMQP 0–9–1 exchange types: "direct", "fanout", "topic", or "headers".
-
durable, a boolean. If true, the exchange survives after the server restarts. If false, the exchange must be created again.
-
autoDelete, a boolean. If true, the exchange is deleted when all queues are unbound from it. If false, the exchange persists.
For example:
Set exchangeName = "broadcast"
Set exchangeType = "fanout"
Set durable = 1
Set autoDelete = 0
Set tSC = client.CreateExchange(exchangeName, exchangeType, durable, autoDelete)
An application can delete a RabbitMQ exchange by invoking the DeleteExchange() method of the RabbitMQ client object, providing the name of the exchange as an argument.
Set tSC = client.DeleteExchange(exchangeName)
Create or Delete a Queue
A RabbitMQ consumer receives messages when an exchange routes them to a queue to which the consumer is subscribed.
To create a queue, invoke the CreateQueue() method of the RabbitMQ client object. CreateQueue() accepts the following arguments, in order:
-
queueName, the name you wish to assign to the queue.
-
durable, a boolean. If true, the queue persists after the server restarts. If false, the exchange must be created again after a restart.
-
exclusive, a boolean. If true, the queue is used by only one connection and is deleted when the connection closes.
-
autoDelete, a boolean. If true, the queue is deleted when all consumers unsubscribe. If false, the queue persists.
For example:
Set queue = "quick-start-events"
Set durable = 1
Set exclusive = 0
Set autoDelete = 0
Set tSC = client.CreateQueue(queue, durable, exclusive, autoDelete)
As an alterative, you can create the queue with a method that is common to all messaging platforms. When using this alternative, the queue settings are defined in an instance of the %External.Messaging.RabbitMQQueueSettingsOpens in a new tab class and then passed to the method as a JSON object using the ToJSON() method. See %External.Messaging.Client.CreateQueueOrTopic()Opens in a new tab for details.
An application can delete a RabbitMQ queue by invoking the DeleteQueue() method of the RabbitMQ client object, providing the name of the queue as an argument.
Set tSC = client.DeleteQueue(queueName)
As an alterative, you can delete the queue with a method that is common to all messaging platforms. See %External.Messaging.Client.DeleteQueueOrTopic()Opens in a new tab for details.
Bind a Queue to an Exchange
To route messages to a queue, the queue must be bound to an exchange. An application can bind a queue to an exchange by invoking the BindQueue() method of the RabbitMQ client object.
As its arguments, the BindQueue() method accepts the queue name, the exchange name, and a string containing the binding keys separated by commas. A comma which is part of a binding key can be escaped by preceding it with the backslash character (\); backslashes which are part of a binding key can be escaped using a second backslash character.
For example, if the two desired binding keys were "event-log,critical" and "event-log,urgent/important", application code could bind a queue as follows:
Set bindingKeys = "event-log\,critical,event-log\,urgent\\important"
Set tSC = client.BindQueue(queueName, exchangeName, bindingKeys)
Close Client
An InterSystems IRIS application that is done communicating with RabbitMQ should close the client with the Close() method. For example:
Do:client'="" client.Close()