activemq-artemis/examples/jms/management-notifications
Thiago Kronig d48b4f4770 ARTEMIS-129 License header should be a normal comment
To reproduce this commit, apply a replace regex rule using:

    search regex: /\*\*\n \* Licensed
    replace: /\*\n \* Licensed

These files had to be changed manually:

    artemis-selector/src/main/javacc/HyphenatedParser.jj
    artemis-selector/src/main/javacc/StrictParser.jj
    artemis-website/src/main/resources/styles/impact/css/pygmentize.css
    artemis-website/src/main/resources/styles/impact/css/site.css
2015-06-03 10:19:45 -04:00
..
src/main ARTEMIS-129 License header should be a normal comment 2015-06-03 10:19:45 -04:00
pom.xml [maven-release-plugin] prepare for next development iteration 2015-05-21 13:47:45 +01:00
readme.html Ensure all references to the project use ActiveMQ Artemis 2015-05-13 11:51:26 +01:00

readme.html

<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
-->

<html>
  <head>
    <title>ActiveMQ Artemis Management Notification Example</title>
    <link rel="stylesheet" type="text/css" href="../common/common.css" />
    <link rel="stylesheet" type="text/css" href="../common/prettify.css" />
    <script type="text/javascript" src="../common/prettify.js"></script>
  </head>
  <body onload="prettyPrint()">
     <h1>Management Notification Example</h1>
     <p>This example shows how to receive management notifications from ActiveMQ Artemis using JMS Messages.</p>
     <p>ActiveMQ Artemis servers emit management notifications when events of interest occur (consumers are created or closed,
         destinations are created or deleted, security authentication fails, etc.).<br />
         These notifications can be received either by using JMX (see <a href="../jmx/readme.html">JMX example</a>) or by receiving JMS Messages
         from a well-known destination.</p>
     <p>This example will setup a JMS MessageListener to receive management notifications. We will also perform normal JMS operations to see the kind
         of notifications they trigger.</p>
     
     <h2>Example configuration</h2>

     <p>ActiveMQ Artemis can configured to send JMS messages when management notifications are emitted on the server.</p>
     <p>By default, the management name is called <code>activemq.notifications</code> but this can be configured in <a href="server0/broker.xml">broker.xml</a>.
        For this example, we will set it to <code>jms.topic.notificationsTopic</code> to be able to receive notifications from a JMS Topic.</p>
      <pre class="prettyprint">
         <code>&lt;management-notification-address&gt;jms.topic.notificationsTopic&lt;/management-notification-address&gt;</code>
     </pre>
     
     <p>Since we want to lookup the notifications topic using JNDI, we also declare it in  <a href="server0/activemq-jms.xml">activemq-jms.xml</a>
     <pre class="prettyprint">
         <code>&lt;topic name="notificationsTopic"&gt;
            &lt;entry name="/topic/notificationsTopic"/&gt;
         &lt;/topic&gt;</code>
     </pre>
     <p>The notification queue requires permission to create/delete temporary queues and consume messages.
         This is also configured in <a href="server0/broker.xml">broker.xml</a></p>
     <pre class="prettyprint">
         <code><!--security for notification topic-->
         &lt;security-setting match="jms.topic.notificationsTopic"&gt;
            &lt;permission type="consume" roles="guest"/&gt;
            &lt;permission type="createNonDurableQueue" roles="guest"/&gt;
            &lt;permission type="deleteNonDurableQueue" roles="guest"/&gt;
         &lt;/security-setting&gt;</code>
     </pre>
     
     <h2>Example step-by-step</h2>
     <p><em>To run the example, simply type <code>mvn verify -Pexample</code> from this directory</em></p>
     <ol>
        <li>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 <a href="server0/client-jndi.properties">client-jndi.properties</a></li>
        <pre class="prettyprint">
            <code>InitialContext initialContext = getContext(0);</code>
        </pre>

        <li>We look up the JMS queue object from JNDI</li>
        <pre class="prettyprint">
            <code>Queue queue = (Queue) initialContext.lookup("/queue/exampleQueue");</code>
        </pre>

        <li>We look up the JMS connection factory object from JNDI</li>
        <pre class="prettyprint">
            <code>ConnectionFactory cf = (ConnectionFactory) initialContext.lookup("/ConnectionFactory");</code>
        </pre>

        <li>We create a JMS connection, a session and a message producer for the example queue</li>
        <pre class="prettyprint">
            <code>connection = cf.createConnection();
            Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            MessageProducer producer = session.createProducer(queue);</code>
        </pre>
        
        <li>We look up the JMS Topic used to receive the notifications from JNDI</li>
        <pre class="prettyprint">
            <code>Topic notificationsTopic = (Topic) initialContext.lookup("/topic/notificationsTopic");</code>
        </pre>

        <li>We create a MessageConsumer for the notification queue and set its MessageListener. When a notification is received, we will simply display all the message properties</li>
        <pre class="prettyprint">
           <code>MessageConsumer notificationConsumer = session.createConsumer(notificationsTopic);
           notificationConsumer.setMessageListener(new MessageListener()
           {
              public void onMessage(Message notif)
              {
                 System.out.println("------------------------");
                 System.out.println("Received notification:");
                 try
                 {
                    Enumeration propertyNames = notif.getPropertyNames();
                    while (propertyNames.hasMoreElements())
                    {
                       String propertyName = (String)propertyNames.nextElement();
                       System.out.format("  %s: %s\n", propertyName, notif.getObjectProperty(propertyName));
                    }
                 }
                 catch (JMSException e)
                 {
                 }
                 System.out.println("------------------------");
              }            
           });</code>
        </pre>
        
        <li>We start the connection to receive messages</li>
        <pre class="prettyprint">
            <code>connection.start();</code>
        </pre>
        
        <p><em>Now that a message listener is setup to receive management notifications, we will perform regular JMS operations to 
            see what kind of notifications are triggered</em></p>
            
        <li>We create a JMS message consumer on the example queue</li>
        <pre class="prettyprint">
            <code>MessageConsumer consumer = session.createConsumer(queue);</code>
        </pre>
        
        <p>This will generate a <code>CONSUMER_CREATED</code> notification:
        <pre class="prettyprint">
            <code>------------------------
            Received notification:
              _AMQ_RoutingName: jms.queue.exampleQueue
              _AMQ_Address: jms.queue.exampleQueue
              ...
              _AMQ_ConsumerCount: 1
              ...
              _AMQ_NotifType: CONSUMER_CREATED
            ------------------------</code>
        </pre>
        <p>The notification tells us that a consumer was created for the JMS queue <code>exampleQueue</code>. When the notification
            was emitted, this consumer was the only one for the queue</p>
            
        <li>We close this consumer</li>
        <pre class="prettyprint">
            <code>consumer.close();</code>
        </pre>

        <p>This will generate a <code>CONSUMER_CLOSED</code> notification:
        <pre class="prettyprint">
            <code>------------------------
            Received notification:
              _AMQ_RoutingName: jms.queue.exampleQueue
              _AMQ_Address: jms.queue.exampleQueue
              ...
              _AMQ_ConsumerCount: 0
              ...
              _AMQ_NotifType: CONSUMER_CLOSED
            ------------------------</code>
        </pre>
        <p>The notification tells us that a consumer was closed for the JMS queue <code>exampleQueue</code>. When the notification
            was emitted, there were no other consumers on the queue</p>

        <li>As a last example, we will create a connection with invalid user credentials</li>
        <pre class="prettyprint">
            <code>try
            {
               cf.createConnection("not.a.valid.user", "not.a.valid.password");
            } catch (JMSException e)
            {            
            }</code>
        </pre>
        
        <p>This will generate a <code>SECURITY_AUTHENTICATION_VIOLATION</code> notification:
        <pre class="prettyprint">
            <code>------------------------
            Received notification:
              _AMQ_User: not.a.valid.user
              ...
              _AMQ_NotifType: SECURITY_AUTHENTICATION_VIOLATION
            ------------------------
            </code>
        </pre>
        <p>The notification tells us that a user named <code>not.a.valid.user</code> failed to authenticate when creating a connection to ActiveMQ Artemis.</p>
        
        <li>And finally, <b>always</b> remember to close your JMS connections and resources after use, in a <code>finally</code> block. Closing a JMS connection will automatically close all of its sessions, consumers, producer and browser objects</li>

        <pre class="prettyprint">
           <code>finally
           {
              if (initialContext != null)
              {
                initialContext.close();
              }
              if (connection != null)
              {
                 connection.close();
              }
           }</code>
        </pre>
     </ol>
     
     <h2>More information</h2>
     
     <ul>
         <li>User Manual's <a href="../../../docs/user-manual/en/html_single/index.html#management.notifications">Management Notifications chapter</a></li>
     </ul>         

  </body>
</html>