Skip to content

Messagequeue

Get and put messages on with IBM MQ queues.

User is based on pymqi for communicating with IBM MQ. However pymqi uses native libraries which gevent (used by locust) cannot patch, which causes any calls in pymqi to block the rest of locust. To get around this, the user implementation communicates with a stand-alone process via zmq, which in turn communicates with IBM MQ.

async-messaged starts automagically when a scenario uses MessageQueueUser and pymqi dependencies are installed.

Request methods

Supports the following request methods:

  • send
  • put
  • get
  • receive

Format

Format of host is the following:

mq://<hostname>:<port>/?QueueManager=<queue manager name>&Channel=<channel name>

endpoint in the request is the name of an MQ queue. This can also be combined with an expression, if a specific message is to be retrieved from the queue. The format of endpoint is:

queue:<queue_name>[, expression:<expression>][, max_message_size:<max_message_size>]

Where <expression> can be a XPath or jsonpath expression, depending on the specified content type. See example below. Where <max_message_size> is the maximum number of bytes a message can be for being able to accept it. If not set, the client will reject the message with MQRC_TRUNCATED_MSG_FAILED, adjust the message buffer and try again. If set, and the message is bigger than the specified size, the message will be rejected by the client and will eventually fail.

Examples

Example of how to use it in a scenario:

Given a user of type "MessageQueue" load testing "mq://mq.example.com/?QueueManager=QM01&Channel=SRVCONN01"
Then put request "test/queue-message.j2.json" with name "queue-message" to endpoint "queue:INCOMING.MESSAGES"

Get message

Default behavior is to fail directly if there is no message on the queue. If the request should wait until a message is available, set the time it should wait with message.wait (seconds) context variable.

To keep the connection alive during longer waiting periods, a heartbeat interval can be configured using the connection.heartbeat_interval (seconds) context variable (default 300).

Given a user of type "MessageQueue" load testing "mq://mq.example.com/?QueueManager=QM01&Channel=SRVCONN01"
And set context variable "message.wait" to "5"
Then get request with name "get-queue-message" from endpoint "queue:INCOMING.MESSAGES"

In this example, the request will not fail if there is a message on queue within 5 seconds.

Get message with expression

When specifying an expression, the messages on the queue are first browsed. If any message matches the expression, it is later consumed from the queue. If no matching message was found during browsing, it is repeated again after a slight delay, up until the specified message.wait seconds has elapsed. To use expressions, a content type must be specified for the get request, e.g. application/xml:

Given a user of type "MessageQueue" load testing "mq://mq.example.com/?QueueManager=QM01&Channel=SRVCONN01"
And set context variable "message.wait" to "5"
Then get request with name "get-specific-queue-message" from endpoint "queue:INCOMING.MESSAGES, expression: //document[@id='abc123']"
And set response content type to "application/xml"

Authentication

Username and password

Given a user of type "MessageQueue" load testing "mq://mqm:admin@mq.example.com/?QueueManager=QM01&Channel=SRVCONN01"
And set context variable "auth.username" to "<username>"
And set context variable "auth.password" to "<password>"

With TLS

A key repository (3 files; .kdb, .rdb and .sth) for the user is needed, and is specified with auth.key_file excluding the file extension.

Given a user of type "MessageQueue" load testing "mq://mqm:admin@mq.example.com/?QueueManager=QM01&Channel=SRVCONN01"
And set context variable "auth.username" to "<username>"
And set context variable "auth.password" to "<password>"
And set context variable "auth.key_file" to "<path to key file, excl. file extension>"

Default SSL cipher is ECDHE_RSA_AES_256_GCM_SHA384, change it by setting auth.ssl_cipher context variable.

Default certificate label is set to auth.username, change it by setting auth.cert_label context variable.

Header type

Basic support exist for RFH2, and communicating with MQ using gzip compressed messages. When receiving messages, the RFH2 is automatically detected and (somewhat) supported. If RFH2 should be added when sending messages, with gzip compression, the context variable message.header_type should be set to RFH2:

Given a user of type "MessageQueue" load testing "mq://mq.example.com/?QueueManager=QM01&Channel=SRVCONN01"
And set context variable "message.header_type" to "rfh2"
Then put request "test/queue-message.j2.json" with name "gzipped-message" to endpoint "queue:GZIPPED.MESSAGES"

Default header type is none, i.e. no header is added to the sent messages. To use no header, either set message.header_type to None or omit setting the context variable at all.

To set a user value in the RFH2 header of the message, set metadata after the request, e.g.:

Then put request "test/queue-message.j2.json" with name "gzipped-message" to endpoint "queue:GZIPPED.MESSAGES"
And metadata "filename" is "my_filename"