ActiveMQ Artemis Last-Value Queue Example

# Last-Value Queue Example

    To run the example, simply type mvn verify from this directory,
    or mvn -PnoServer verify if you want to start and create the server manually.

This example shows you how to configure and use last-value queues.

Last-Value queues are special queues which discard any messages when a newer message with the same value for a well-defined Last-Value property is put in the queue. In other words, a Last-Value queue only retains the last value.

A typical example for Last-Value queue is for stock prices, where you are only interested by the latest value for a particular stock.

The example will send 3 messages with the same Last-Value property to a to a Last-Value queue.
We will browse the queue and see that only the last message is in the queue, the first two messages have been discarded.
We will then consume from the queue the last message.

## Example setup

Last-Value queues are defined in the configuration file broker.xml:

             <address-setting match="jms.queue.lastValueQueue">
                    <last-value-queue>true</last-value-queue>
             </address-setting>

## Example step-by-step

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 it's properties from the client-jndi.properties

               InitialContext initialContext = getContext();

2. We look up the JMS queue object from JNDI

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

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

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

4. We create a JMS connection, a session and a producer for the queue

                connection = cf.createConnection();
                Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
                MessageProducer producer = session.createProducer(queue);

5. We will create and send a text message with the Last-Value property set to `STOCK_NAME`

               TextMessage message = session.createTextMessage("1st message with Last-Value property set");
               message.setStringProperty("_AMQ_LVQ_NAME", "STOCK_NAME");
               producer.send(message);
               System.out.format("Sent message: %s\n", message.getText());

The Last-Value key is defined in ActiveMQ's MessageImpl class. Its value is `"_AMQ_LVQ_NAME"`

6. We will create and send a second text message with the Last-Value property set to `STOCK_NAME`

               message = session.createTextMessage("2nd message with Last-Value property set");
               message.setStringProperty("_AMQ_LVQ_NAME", "STOCK_NAME");
               producer.send(message);
               System.out.format("Sent message: %s\n", message.getText());

7. We will create and send a third text message with the Last-Value property set to `STOCK_NAME`

               message = session.createTextMessage("3rd message with Last-Value property set");
               message.setStringProperty("_AMQ_LVQ_NAME", "STOCK_NAME");
               producer.send(message);
               System.out.format("Sent message: %s\n", message.getText());

When the 2nd message was sent to the queue, the 1st message was discarded.
Similarly, when the 3rd message was sent to the queue, the 2nd message was discarded.
Only the 3rd message remains in the queue.

8. We will browse the queue. There will be a single message displayed: the 3rd message

                QueueBrowser browser = session.createBrowser(queue);
                Enumeration enumeration = browser.getEnumeration();
                while (enumeration.hasMoreElements())
                {
                   TextMessage messageInTheQueue = (TextMessage)enumeration.nextElement();
                   System.out.format("Message in the queue: %s\n", messageInTheQueue.getText());
                }
                browser.close();

We will now consume the message on the queue

9. We create a JMS message consumer on the queue

                MessageConsumer messageConsumer = session.createConsumer(queue);

10. We start the connection. In order for delivery to occur on any consumers or subscribers on a connection, the connection must be started

               connection.start();

11. We try to receive a message from the queue. It will be the 3rd message

                TextMessage messageReceived = (TextMessage)messageConsumer.receive(5000);
                System.out.format("Received message: %s\n", messageReceived.getText());

12. We will try to receive another message but there is no other on the queue. The `receive` method will timeout after 5 seconds

                messageReceived = (TextMessage)messageConsumer.receive(5000);
               System.out.format("Received message: %s\n", messageReceived);

13. 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 Last-Value Queues chapter