ActiveMQ Artemis Management Example

# Management Example

This example shows how to manage ActiveMQ Artemis using JMS Messages to invoke management operations on the server.

To manage ActiveMQ Artemis using JMX, see the JMX example.

## Example configuration

ActiveMQ Artemis can be managed by sending JMS messages with specific properties to its management queue.

By default, the management name is called `activemq.management` but this can be configured in broker.xml

             <management-address>activemq.management</management-address>

The management queue requires a "special" user permission `manage` to be able to receive management messages. This is also configured in broker.xml

             <security-setting match="activemq.management">
                <permission type="manage" roles="guest" />
             </security-setting>

## Example step-by-step

To run the example, simply type `mvn verify -Pexample` from this directory

1. First we need to get an initial context so we can look-up the JMS connection factory and destination objects from JNDI. This initial context will get its properties from client-jndi.properties

                InitialContext initialContext = getContext(0);

2. We look up the JMS queue object from JNDI

                Queue queue = (Queue) initialContext.lookup("/queue/exampleQueue");

3. We look up the JMS connection factory object from JNDI

                ConnectionFactory cf = (ConnectionFactory) initialContext.lookup("/ConnectionFactory");

4. We create a JMS connection

                connection = cf.createConnection();

5. We create a JMS session. The session is created as non transacted and will auto acknowledge messages.

                Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

6. We create a JMS message producer on the session. This will be used to send the messages.

                MessageProducer messageProducer = session.createProducer(topic);

7. We create a JMS text message that we are going to send.

                TextMessage message = session.createTextMessage("This is a text message");

8. We send message to the queue

                messageProducer.send(message);

Now that we have a message in the queue, we will manage the queue by retrieving the number of messages in the queue (i.e. 1) and by removing the message which has been sent in step 8.

9. We create the JMS management queue. This is a special queue which is not looked up from JNDI but instantiated directly

                Queue managementQueue = new ActiveMQQueue("activemq.management", "activemq.management");

10. We create a `QueueRequestor` to send messages to the management queue and receive replies (see queue-requestor example)

                QueueRequestor requestor = new QueueRequestor(session, managementQueue);

11. We start the connection to receive replies on the requestor

               connection.start()

12. We create a JMS message which will be used as a management message

                Message m = session.createMessage();

13. a management message has well-defined properties that ActiveMQ Artemis server needs to know to perform management operations.
    We use a helper class `JMSManagementHelper` to fill these properties:
    - The name of the resource to manage `jms.queue.exampleQueue` (i.e. `jms.queue` followed by the name of the queue as defined in activemq-jms.xml)
    - In our case, the name of the attribute to retrieve `MessageCount`

                JMSManagementHelper.putAttribute(m, "jms.queue.exampleQueue", "MessageCount");

14. We send the management message using the requestor and wait for a reply

                Message reply = requestor.request(m);

15. We use a helper class `JMSManagementHelper` to retrieve the result from the reply message:

                    int messageCount = (Integer)JMSManagementHelper.getResult(reply);
                    System.out.println(queue.getQueueName() + " contains " + messageCount + " messages");

16. We create another JMS message to use as a management message

                m = session.createMessage();

17. This time, we fill the management message with properties to invoke a management operation on the queue
    - the name of the resource `jms.queue.exampleQueue`
    - the name of the management operation `removeMessage`
    - any parameters required to invoke the management operations (in our case, the JMS Message ID of the message sent in step 8)

                JMSManagementHelper.putOperationInvocation(m, "jms.queue.exampleQueue", "removeMessage", message.getJMSMessageID());

18. Again, we use the requestor to send the management message and wait for a reply

                reply = requestor.request(m);

19. We use the helper class to check that the operation was successfully invoked on the server

                boolean success = JMSManagementHelper.hasOperationSucceeded(reply);
                System.out.println("operation invocation has succeeded: " + success);

20. We use a helper class `JMSManagementHelper` to retrieve the result from the reply message: (in our case, the `removeMessage` method returns a boolean)

                boolean messageRemoved = (Boolean)JMSManagementHelper.getResult(reply);
                System.out.println("message has been removed: " + messageRemoved);

We will now consume the message from the queue but there will be none: the message sent at step 8 was removed by the management operation

21. We create a JMS message consumer on the queue

                MessageConsumer messageConsumer = session.createConsumer(queue);

22. We try to receive a message from the queue. Since there is none, the call will timeout after 5000ms and messageReceived will be null

                TextMessage messageReceived = (TextMessage) messageConsumer.receive(5000);
                System.out.println("Received message: " + messageReceived);

23. And finally, always remember to close your JMS connections and resources after use, in a `finally` block. Closing a JMS connection will automatically close all of its sessions, consumers, producer and browser objects

               finally
               {
                  if (initialContext != null)
                  {
                    initialContext.close();
                  }
                  if (connection != null)
                  {
                     connection.close();
                  }
               }

## More information

- User Manual's Using Management Via JMS chapter