Book Image

Instant Apache ActiveMQ Messaging Application Development How-to

By : Timothy A. Bish
Book Image

Instant Apache ActiveMQ Messaging Application Development How-to

By: Timothy A. Bish

Overview of this book

Apache ActiveMQ is a powerful and popular open source messaging and Integration Patterns server. ActiveMQ is a fully JMS 1.1 compliant Message Broker and supports many advanced features beyond the JMS specification.Instant ActiveMQ Application Development How-to shows you how to get started with the ActiveMQ Message Broker. You will learn how to develop message-based applications using ActiveMQ and the JMS specification. In this book you will learn all the basic skills you need to start writing Java Messaging applications with a firm grounding in the more advanced features of ActiveMQ, giving you the tools to continue to master application development using ActiveMQ. Starting by applying the messaging features of the JMS specification to write basic messaging applications, you will develop a basic JMS application using topics and queues to broadcast events as well as perform Request and Response operations over the JMS. Once you have mastered the simple tasks you will move onto using the advanced features in ActiveMQ to supercharge your messaging applications. You will get to grips with ActiveMQ's scheduler to delay messages. You will also learn how to leverage ActiveMQ's fault-tolerant capabilities to create robust client applications.
Table of Contents (7 chapters)

Activity monitoring in ActiveMQ (Advanced)


In this recipe we will look at how you can monitor activity in ActiveMQ Broker using the JMS API and the broker's built-in Advisory Message feature. Advisory messages from the broker allow your application to monitor events on the broker such as:

  • Connections, consumers, and producers starting and stopping

  • Temporary destinations being created and destroyed

  • Messages expiring on topics and queues

Getting ready

In this recipe we will use two examples. The first example is named advisory-generator, which will cause the broker to produce some advisory messages. The second one is named advisory-consumer, which demonstrates how we can implement those broker advisories.

How to do it...

To run the sample for this recipe you will need to perform the following steps:

  1. Open a terminal and start a broker.

  2. Open a second terminal, change the path to the directory where advisory-consumer is located, and run it by typing mvn compile exec:java (you can shut it down by pressing Ctrl + C when done or you can allow it to stop on its own after 10 minutes).

  3. Open a third terminal and change the path to the directory where advisory-generator is located and run the example by typing mvn compile exec:java (the sample will shut down on its own after a few minutes).

On the terminal where you started the example named advisory-consumer, you will see output like the following, indicating that the application is receiving advisory messages from the broker:

Starting Advisory Consumer example now...
New Producer Advisory, Producer Count: 1
New Producer Advisory, Producer Count: 5
New Producer Advisory, Producer Count: 5
New Producer Advisory, Producer Count: 5

New Producer Advisory, Producer Count: 2
New Consumer Advisory, Consumer Count: 1
New Producer Advisory, Producer Count: 1
New Consumer Advisory, Consumer Count: 0
New Producer Advisory, Producer Count: 0
Finished running the Advisory Consumer example.

The advisory source application runs without generating much output as it's just used here to create some activity on the broker.

How it works...

ActiveMQ Broker generates advisory messages for a number of different events that occur on the broker. Your client applications can subscribe to special topics where the events are sent in order to monitor activity on the broker. The advisory messages are just simple JMS message objects that can have some message properties set to provide helpful event-related information.

Our advisory-consumer example listens for events (related to MessageProducer and MessageConsumer) being added and removed from the broker for a particular destination; in this example we are watching the queue named MyQueue. Let's take a look at the code for the sample application:

public class AdvisoryConsumerApp implements MessageListener {

    private final String connectionUri = "tcp://localhost:61616";
    private ActiveMQConnectionFactory connectionFactory;
    private Connection connection;
    private Session session;
    private Destination destination;
    private MessageConsumer advisoryConsumer;
    private Destination monitored;

    public void before() throws Exception {
        connectionFactory = new ActiveMQConnectionFactory(connectionUri);
        connection = connectionFactory.createConnection();
        session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        monitored = session.createQueue("MyQueue");
        destination = session.createTopic(
            AdvisorySupport.getConsumerAdvisoryTopic(monitored).getPhysicalName() + "," +
            AdvisorySupport.getProducerAdvisoryTopic(monitored).getPhysicalName());
        advisoryConsumer = session.createConsumer(destination);
        advisoryConsumer.setMessageListener(this);
        connection.start();
    }

    public void onMessage(Message message) {
        try {
            Destination source = message.getJMSDestination();
            if (source.equals(AdvisorySupport.getConsumerAdvisoryTopic(monitored))) {
                int consumerCount = message.getIntProperty("consumerCount");
                System.out.println("New Consumer Advisory, Consumer Count: " + consumerCount);
            } else if (source.equals(AdvisorySupport.getProducerAdvisoryTopic(monitored))) {
                int producerCount = message.getIntProperty("producerCount");
                System.out.println("New Producer Advisory, Producer Count: " + producerCount);
            }
        } catch (JMSException e) {
        }
    }
}

In order to receive advisory messages from the broker, our sample application subscribes to two different topics on the broker. The topics subscribed to are those special advisory topics that were mentioned earlier, and the ActiveMQ client library provides a convenience class named AdvisorySupport for fetching the various advisory topics available.

We use another ActiveMQ feature in this example to save some typing by subscribing to two destinations with one consumer. The destination passed to the createConsumer method is referred to as Composite Destination, which simply means we concatenated two destination names with a comma. We can add even more destinations if we want to.

In our sample application's onMessage callback method, we determine which advisory message we are receiving by examining the JMSDestination message property. Once we know which advisory message we are dealing with, we can find the consumer and producer counts for our monitored destination by accessing the consumerCount property that the broker adds to the advisory message.

There's more...

Advisory messages are enabled by default on the broker, although only a subset of the complete set will be generated by default. The complete list of advisory messages can be found on the ActiveMQ website, http://activemq.apache.org/advisory-message.html, along with information on the specific properties and contents of each advisory message.

Having the advisory messages enabled does generate a small amount of overhead on the network though, so they can be disabled in the broker's XML configuration file. In order to turn off advisory messages, we will add the advisorySupport="false" option to the broker XML element in the configuration file. It will look something like this:

<broker advisorySupport="false">...

Tip

Advisory messages are required for dynamic network broker topologies as network connectors subscribe to advisory messages. In the absence of advisories, a network must be statically configured.