MRG / qpid: usage of QMF protocol
Environment
- MRG Messaging 2.0 or higher
Issue
- How to use QMF protocol for querying or managing objects in qpid broker?
- Are there examples of creating a queue, listing bindings etc.?
Resolution
-
Some general information about QMF (version 2, denoted as QMFv2 later on) is provided at Content from cwiki.apache.org is not included.QPID wiki page
-
In attachments, there are:
qmf_cpp_examples.tar.gz: with some examples of QMFv2 usage (described in detail in Diagnostic Steps), written in C++PurgeQueue.java: one example program fromqmf_cpp_examples.tar.gzrewritten to Java
-
Modifying the provided examples, one can write any application for querying or managing objects in qpid broker
-
To get a complete list of QMF classes and their elements and methods with parameters, see this solution.
management-schema.xmlas structured information for the same for some older broker (such that some methods or arguments might not be up to date) is provided in attachments. -
Some general rules:
-
messages are everytime sent to
"qmf.default.direct/broker"address -
it is worth to set replyTo to get a response to the QMF request
-
message content is a map of:
*"_object_id": that is a map with"_object_name"set to OID of the object whose method we invoke (usually"org.apache.qpid.broker:broker:amqp-broker"or"org.apache.qpid.broker:queue:<queue_name>"for some queue-related stuff)
*"_method_name": name of the method / request frommanagement-schema.xml
*"_arguments": arguments of the method, as described inmanagement-schema.xml -
content type of the messages is
"amqp/map" -
two message properties to be set:
"x-amqp-0-10.app-id"set to"qmf2""qmf.opcode"set to either"_query_request"(for QMF queries asking for some data) or"_method_request"(for QMF methods applying some change)
Diagnostic Steps
- Unpack the attached
qmf_cpp_examples.tar.gzand compile the example programs:
$ tar xzf qmf_cpp_examples.tar.gz
$ cd qmf_cpp_examples
$ make
create_queue.cpp: creates a queue with optional parameters (first is queue name, then durability and then arguments):
$ ./create_queue some_queue
Response: OK
$ ./create_queue another_queue 1 qpid.auto_delete_timeout=1800 auto-delete=true
Response: OK
$ qpid-config queues
Queue Name Attributes
=================================================================
another_queue --durable auto-del --argument qpid.auto_delete_timeout=1800
fd3d65f7-52af-4926-93a8-22df2696c5c4:0.0 auto-del excl
some_queue
$
delete_queue.cpp: deletes a queue of given name:
$ ./delete_queue some_queue
Response: OK
$ qpid-config queues | grep some_queue
$
get_queue_details.cpp: queries qpid for a queue of given name and prints out all its properties:
$ ./create_queue some_queue
Response: OK
$ ./get_queue_details some_queue
{acquires:0, arguments:{}, autoDelete:False, bindingCount:1, bindingCountHigh:1, bindingCountLow:1, byteDepth:0, byteFtdDepth:0, byteFtdDequeues:0, byteFtdEnqueues:0, bytePersistDequeues:0, bytePersistEnqueues:0, byteTotalDequeues:0, byteTotalEnqueues:0, byteTxnDequeues:0, byteTxnEnqueues:0, consumerCount:0, consumerCountHigh:0, consumerCountLow:0, creator:anonymous, discardsLvq:0, discardsOverflow:0, discardsPurge:0, discardsRing:0, discardsSubscriber:0, discardsTtl:0, durable:False, exclusive:False, flowStopped:False, flowStoppedCount:0, messageLatencyAvg:0, messageLatencyCount:0, messageLatencyMax:0, messageLatencyMin:0, msgDepth:0, msgFtdDepth:0, msgFtdDequeues:0, msgFtdEnqueues:0, msgPersistDequeues:0, msgPersistEnqueues:0, msgTotalDequeues:0, msgTotalEnqueues:0, msgTxnDequeues:0, msgTxnEnqueues:0, name:some_queue, redirectPeer:, redirectSource:False, releases:0, reroutes:0, unackedMessages:0, unackedMessagesHigh:0, unackedMessagesLow:0, vhostRef:{_object_name:org.apache.qpid.broker:vhost:org.apache.qpid.broker:broker:amqp-broker,/}}
$
set_log_level.cpp: allows dynamically change logging verbosity of qpid broker without the necessity of its restart:- enabling logging to a file, watch the logfile content in one window while running these commands changing the logging verbosity:
$ ./set_log_level "trace+"
Response: OK
$ ./set_log_level "critical+"
Response: OK
$ ./set_log_level "notice+"
Response: OK
$ ./set_log_level "trace+:management"
Response: OK
$
Syntax of logging levels is described in this solution
purge_queue.cpp: purges given queue (either completely or first N messages):
$ ./spout -c 1000 "testPurgeQueue; {create:always}"
$ qpid-stat -q | grep ueue
Queues
queue dur autoDel excl msg msgIn msgOut bytes bytesIn bytesOut cons bind
testPurgeQueue 1.00k 1.00k 0 0 0 0 0 1
$ # purge first 123 messages from the queue
$ ./purge_queue testPurgeQueue 123
{_arguments:{request:123}, _method_name:purge, _object_id:{_object_name:org.apache.qpid.broker:queue:testPurgeQueue}}
Response: OK
$ qpid-stat -q | grep ueue
Queues
queue dur autoDel excl msg msgIn msgOut bytes bytesIn bytesOut cons bind
testPurgeQueue 877 1.00k 123 0 0 0 0 1
$ # purge the queue completely
$ ./purge_queue testPurgeQueue 0
{_arguments:{request:0}, _method_name:purge, _object_id:{_object_name:org.apache.qpid.broker:queue:testPurgeQueue}}
Response: OK
$ qpid-stat -q | grep ueue
Queues
queue dur autoDel excl msg msgIn msgOut bytes bytesIn bytesOut cons bind
testPurgeQueue 0 1.00k 1.00k 0 0 0 0 1
$
-
watch-bindings.cpp: first it lists all current bindings and then subscribes to a topic to receive updates about new bindings created:- run the watch-bindings command (without parameters) and create a binding later on to see how does it work
-
watch-events.cpp: it prints out all QMF events - some generalized version ofwatch-bindings.cpp
This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.