Last-Value Queue Example

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 activemq-configuration.xml:

         <address-setting match="jms.queue.lastValueQueue">
                <last-value-queue>true</last-value-queue>
         </address-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 it's properties from the client-jndi.properties
  2.            InitialContext initialContext = getContext();
            
  3. We look up the JMS queue object from JNDI
  4.            Queue queue = (Queue) initialContext.lookup("/queue/lastValueQueue");
            
  5. We look up the JMS connection factory object from JNDI
  6.            ConnectionFactory cf = (ConnectionFactory) initialContext.lookup("/ConnectionFactory");
            
  7. We create a JMS connection, a session and a producer for the queue
  8.             connection = cf.createConnection();
                Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
                MessageProducer producer = session.createProducer(queue);
           
  9. We will create and send a text message with the Last-Value property set to STOCK_NAME
  10.            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"

  11. We will create and send a second text message with the Last-Value property set to STOCK_NAME
  12.            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());
           
  13. We will create and send a third text message with the Last-Value property set to STOCK_NAME
  14.            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.

  15. We will browse the queue. There will be a single message displayed: the 3rd message
  16.             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

  17. We create a JMS message consumer on the queue
  18.             MessageConsumer messageConsumer = session.createConsumer(queue);
            
  19. We start the connection. In order for delivery to occur on any consumers or subscribers on a connection, the connection must be started
  20.            connection.start();
            
  21. We try to receive a message from the queue. It will be the 3rd message
  22.             TextMessage messageReceived = (TextMessage)messageConsumer.receive(5000);
                System.out.format("Received message: %s\n", messageReceived.getText());
            
  23. We will try to receive another message but there is no other on the queue. The receive method will timeout after 5 seconds
  24.             messageReceived = (TextMessage)messageConsumer.receive(5000);
               System.out.format("Received message: %s\n", messageReceived);
            
  25. 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
  26.            finally
               {
                  if (initialContext != null)
                  {
                    initialContext.close();
                  }
                  if (connection != null)
                  {
                     connection.close();
                  }
               }
            

More information