Logo Computer scientist,
engineer, and educator
• Software • Utility corner • Apache integration software

amqutil

Version 0.1.0

A simple test client/benchmarking utility for Apache Active MQ.

What is this?

amqutil is a simple Java command-line utility for testing and exercising ActiveMQ destinations as a JMS client. It works with the open-source Apache ActiveMQ, and with Red Hat JBoss Fuse and JBoss A-MQ. It can put messages onto queues or topics, consume from queues, set message header properties, subscribe to topics, list queue contents, and dump individual messages in various formats. Messages can be read from and written to text or binary files, or just generated internally by the utility. amqutil supports transacted batches, durable subscriptions, inter-message delays, persistent and non-persistent production, and both one-way and two-way ('ping') messaging.

amqutil is intended to extend the test client functionality provided by the mq-client.jar utility that is supplied with JBoss A-MQ. Its command-line is similar (but not identical), but amqutil provides a number of features that mq-client.jar does not.

amqutil is supplied as a Java JAR file that embeds the ActiveMQ client runtime, so installation consists of downloading one JAR file and copying it to any convenient directory.

Sample command lines

amqutil is supplied as a Java JAR file (see the Downloads section), and should be invoked like this:
java -jar /path/to/amqutil-0.1.0.jar [command] {options}
However, throughout this document the command amqutil is used as an abbreviation for this longer command line. Of course, it should be possible to create a script or batch file that allows amqutil to be invoked this way (and a sample is included in the source code bundle).
amqutil browse --host mybroker --port 61616 --destination testqueue 
  List messages on destination testqueue, on broker mybroker:61616
  Note that --url can be used instead of --host and --port

amqutil browse --user fred --password secret --destination testqueue 
  List messages on destination testqueue, on default broker localhost:61616,
  using specific connection credentials

amqutil list
  List the destinations on the default broker

amqutil show 23 --destination testqueue 
  Print to the console brief details of message 23 on destination testqueue,
  without consuming the message

amqutil show 23 --destination testqueue --format textonly
  Print to the console the message body of message 23 

amqutil produce 1000 --destination testqueue --batch 10
  Produce 1000 arbitrary 500-character text messages to testqueue
  in transacted batches of 10 messages

amqutil produce 1000 --destination testqueue 
  Produce 1000 arbitrary 500-character text messages to testqueue

amqutil produce --destination testqueue --length 42
 Produce a single arbitrary text message of length 42 characters to testqueue

amqutil --produce --destination testqueue --file data.txt
  Produce text file data.txt to testqueue as a TextMessage

amqutil --produce --destination testqueue --file data.dat --msgtype bytes
  Produce file data.dat to testqueue as a BytesMessage

amqutil consume --destination testqueue --format long
  Consume from the head of testqueue and display all message headers

amqutil consume --destination testqueue --sleep 1000
  Consume from the head of testqueue and display the message ID only,
  pausing for 1000 msec after each message

amqutil consume --destination testqueue --number 1000 --format none --time
  Time how long it takes to consume 1000 messages from testqueue

amqutil subscribe --destination testtopic --format long
  Subscribe to testtopic and display one message in long format
  when it is published

amqutil publish --destination testtopic --file topic.txt
  Publish the text in topic.txt to testtopic

amqutil subscribe --destination testtopic --durable my-client
  Create a durable subscription with client ID my-client

amqutil count --destination testqueue
  Count the messages on the specified destination

amqutil ping 100 --sleep 1000 --destination testqueue
  Puts 100 messages on the destination and then consume them again, at
  one-second intervals

amqutil ping 100000 --url failover:\(tcp://host1,tcp://host2\) --loglevel debug
  Produce and consume a large number of messages rapidly to a pair
  of brokers in failover configuration, perhaps for failover testing

Installing and running amqutil

You will need the compiled binary JAR file (see the Downloads section below) and a recent Java JVM (Java 7 or later.) To run the utility, install the JAR in any convenient directory, and then run it like this:
java -jar /path/to/amqutil-0.1.0.jar {options}
It can be more convenient just to invoke the program as amqutil, so it's helpful to create a script or batch file to allow that. One straightforward approach for Linux/Unix is as follows.

1. Create the directory /usr/share/amqutil
2. Copy amqutil-0.1.0.jar to that directory
3. Create the script /usr/bin/amqutil with the following contents:

#!/bin/bash
java -jar /usr/share/amqutil/amqutil-0.1.0.jar "$@"
4. chmod 755 /usr/bin/amqutil.

The source code bundle includes a script install_linux.sh that automates these steps.

Basic usage

All amqutil invocations takes the following form:
amqutil [command] {options}
The command is mandatory, and specifies the mode of operation. Further options depend on the command. In all cases, a brief description of the available options can be obtained thus:
amqutil [command] --help 
To find out how to get more general information, just run
amqutil help 
The commands (modes of operation) available to amqutil are as follows.

browse

amqutil browse
Display a list of messages on the destination whose name is given by the --destination option. To see individual message contents, use show, passing the index of the message from the output of browse.

commands

amqutil commands 
Show a list of available commands.

consume

amqutil consume {number} {--destination queue} {...}
Consume number messages from the queue destination whose name is given by the --destination option. If the number is omitted, one message will be consumed. The format of the displayed messages is controlled using the --format option; to write consumed messages to a text file, use --file. If asked to consume more messages than are waiting on the destination, amqutil will block until new messages are available.

count

amqutil count {--destination queue} {...} 
Displays the number of messages currently waiting on the specified destination.

help

amqutil help 
Display a summary of command-line options.

list

amqutil list 
List the destinations on the message broker.

manual

amqutil manual 
Dump the whole manual (this file) to standard output in plain text format, formatted for 80 character width.

ping

amqutil ping {number} {--destination queue} {...}
Produce number messages to the queue destination whose name is given by the --destination option, then consume them synchronously. This serves as a basic test of broker health. ping takes all the command-line switches that produce and consume take, so messages can be sent at intervals, and the results formatted in specific ways. ping sets a JMS correlation ID based on a long random number so it should, in principle, be possible to ping a destination that is in use, without amqutil being confused by messages from other sources. However, amqutil can't prevent some other application consuming its test message, so such a technique would have to be used with care.

If you're using ping to test that a broker is alive, then your might need to specify a connection timeout, to ensure that amqutil doesn't just hang indefinitely:

amqutil ping --url tcp://host:61616?connectionTimeout=1000 

produce

amqutil produce {number} {--destination queue} {...}
Produce number messages to the queue destination whose name is given by the --destination option. By default, one message is produced. To pproduce messages from a text file, use --file; otherwise a message of --length characters is generated internally.

publish

amqutil publish {number} {--destination topic} {...}
Publish number messages to the topic destination whose name is given by the --destination option. By default, one message is published. To publish messages from a text file, use --file; otherwise a message of --length characters is generated internally.

show

amqutil show {message_index} {--destination queue} {...}
Displays in detail the message whose index is given by message_index, on the queue whose name is given by --destination. The indices are arbitrary, and correspond to the numbers displayed when using the browse command. However, message zero is always the head of the queue, that is, the message that will be consumed next. If the message is a text message, its contents will be displayed. Note that it isn't an error to use this option with a topic, but no messages will ever be shown.

subscribe

amqutil subscribe {number} {--destination queue} {--durable ID} {...}
Subscribe to the topic destination whose name is given by the --destination option. This operation blocks until number messages are published to the topic. If no number is given, wait for one message. The message read may be displayed, according to the --format option.

version

amqutil version 
Show program version.

Command-line options

Not all command-line options are relevant to a specific command, although --host, --port, --url, --user, and --password are generally applicable. To see which switches are applicable to a specific command, use amqutil [command] --help.

--batch {size}
Produce or consume messages in transacted batches of the specified size. Use --batch 1 to use a transacted session without batching.

-d, --destination {destination_name}
Specifies the queue or topic name for most other operations. If no name is given, the default is "__test_queue". amqutil does not support the notation queue://name: it will actually create a queue with that literal name. It does support queue parameters, however, so you can say --destination test?prefetch=1.

--durable {client-ID}
Used in conjunction with amqutil subscribe, makes subscriptions durable with the specified client ID.

--file {filename}
When publishing or producing messages, read the message body from the specified file, rather than generating it internally. The whole file is read or written, and any --length option is ignored. The default interpretation is that the file contains text in the platorm's default encoding, and the message body will be a TextMessage. If the option --msgtype bytes is given, then the file contains raw bytes that will be inserted without interpretation into a BytesMessage.

There is little purpose in using the --file option to write messages to a file if more than one message is read in a given amqutil invocation — later messages will overwrite earlier ones. Messages do not append to a file because, except in the special case of text messages, the file formats might not be appendable.

--format {none|short|long|text|textonly}
Format for messages that are consumed with consume, subscribe or show. none is useful for benchmarking, because console output is often slower than messaging operations. short displays only the message ID and type; long displays all headers; text displays all headers and also the message body, if possible. If the body is a TextMessage then the text will be dumped as it is. If the body is a BytesMessge then the message will be dumped in hexadecimal, 16 bytes to a line. textonly dumps only the message body (in text or hexadecimal, as above), and no other information. To write a binary (or text) message body to a file, use --file.

--host {hostname}
The hostname or IP of the broker; defaults to localhost.

--length {number}
When generating messages internally, use the specified number of characters or bytes. Note that the number of bytes actually stored will depend on the character encoding used by the JVM and/or the JMS broker, and will typically be larger (rarely smaller) than the given number of characters.

--msgtype text|bytes
When using produce or publish, specifies whether to create a TextMessage (the default) or a BytesMessage. At present, no other data types are supported.

--loglevel {error|warn|info|debug}
Sets the logging level, both of this utility and the ActiveMQ client. In practice, although all these levels are defined, the only ones that the ActiveMQ client uses are 'error' and 'debug.' The default is 'error,' which means silent operation in normal circumstances.

--nonpersistent
Enable non-persistent delivery, when used with produce or publish.

-p. --password {password}
Specifies the password for authentication against the AMQ broker. Default 'admin'.

--percent
Prints percentage completion as an operation is performed; this can be useful when dealing with huge numbers of messages.

--port {number}
Broker's TCP/IP port number; default 61616

--properties {name=value[,name=value]...}
Sets arbitrary string properties to the message header before sending. Properties are specified as name1=value1,name2=value2....

--sleep {msec}
Sleep (wait) for the specified number of milliseconds after dispatching or consuming each message.

--time
Show the time in milliseconds taken to complete whatever operation was specified.

-u, --user {username}
Username for authentication on the broker. Default 'admin'.

--url {broker_url}
Use a URL for connection to the broker, rather than a simple host/port combination. It will be necessary to specify a URL if you want to use transports other than TCP, or work with multiple brokers in a failover group. An example might be --url failover:\(tcp://broker1:61616,tcp://broker2:61616\). Note that the parentheses have to be escaped here to protect them from the shell. If --url is specified, then --host and --port are ignored.

Usage notes

browse, show, and count all rely on the JMS queue browsing API. ActiveMQ can be configured such that not all messages on a destination are available for browsing. In such a case, amqutil will not have access to all the messages on a destination.

When producing a message to a destination, if no message file (--file) is provided, then a string of 500 arbitrary characters or bytes will be produced, or of length set by the --length switch.

If a file is specified when consuming a message, then the message will be written to that file, provided that the message is a TextMessage or a BytesMessage. Any other message type will be silently ignored.

When listing queue contents with browse, no guarantee can be given that the queue contents will not change during the listing — queue browsing operations are not transactional.

When producing a TextMessage from a text file, the file is read in the platform's default character encoding. For a BytesMessage (--msgtype bytes), the file in not interpreted.

It is not actually an error to use the browse command on a topic, but no messages will ever be shown — that is a consequence of the way that publish/subscribe messaging works.

When the consume command is used, and it blocks because there are insufficient messages to consume, then the only way to stop the program is to kill it (e.g., ctrl+C). If the --batch mode is used, and the session is therefore transacted, any messages consumed will be returned to the destination. This is not a bug although it can be confusing — transacted sessions are designed to work that way.

Message delivery is persistent by default. To test non-persistent delivery, use the --nonpersistent switch.

ActiveMQ supports multi-destination production and consumption. To use this feature with amqutil, separate the multiple destinations with commas. For example: --destination d1,d2,d3.

amqutil can monitor broker operation via advisory topics. For example, to monitor connections being opened and closed in real time:

amqutil --subscribe --destination ActiveMQ.Advisory.Connection
However, most advisory topics are not enabled by default, and some administrators are wary of enabling them, because of the additional network and memory load they might create.

The --properties switch can be used to exercise some specific ActiveMQ behavior. For example, setting the JMSXGroupID header should ensure that a single consumer gets all the messages, regardless of the number of consumers attached.

amqutil --properties JMSXGroupID=something --produce ...

Building

You will need to build amqutil from source if, for example, you want to change the version of the A-MQ runtime support which it bundles. amqutil is a Maven project. To build it, obtain and unpack the source code bundle, and then
mvn compile assembly:single
or
mvn package 
This will create a JAR file in the target directory, which contains the amqutil code and all the necessary ActiveMQ client support. To run the utility, no other dependencies should be necessary; just use java -jar:
java -jar target/amqutil-0.0.1-jar-with-dependencies.jar {options}
For Linux users, a script install_linux.sh is provided that will copy the compiled JAR to /usr/share/amqutil and create an executable script /usr/bin/amqutil to run it. Thereafter, you should be able to run simply:
$ amqutil {options}
Note that Maven will automatically download all the dependencies needed to build amqutil — about 10Mb of them. This might take some time on the first build.

amqutil is configured to use version 5.9.0 of the ActiveMQ client library. This can be changed my modifying the dependency in pom.xml.

The latest version of the source can be obtained from github.

Exit status

So far as is possible with a Java application, amqutil returns an exit status of zero if the operation succeeds, and nonzero if it fails.

Revision history

0.1.0, March 2015 Completely re-factored; added support for binary messages, ping mode, and tidied up command-line handling.
0.0.1 First functional release

Author

amqutil is mainted by Kevin Boone (kevin at railwayterrace dot com). It is distributed under the terms of the GNU Public License, version 2.0, in the hope that it will be useful. However, there is no warranty of any kind.

Download

Source code bundle (Maven project)
Precompiled JAR (including A-MQ runtime components)
Copyright © 1994-2015 Kevin Boone. Updated Mar 31 2015