Topic Hierarchy Example

ActiveMQ supports topic hierarchies. With a topic hierarchy you can register a subscriber with a wild-card and that subscriber will receive any messages routed to an address that match the wildcard.

ActiveMQ wild-cards can use the character '#' which means "match any number of words", and the character '*' which means "match a single word". Words are delimited by the character "."

For example if I subscribe using the wild-card "news.europe.#", then that would match messages sent to the addresses "news.europe", "news.europe.sport" and "news.europe.entertainment", but it does not match messages sent to the address "news.usa.wrestling"

For more information on the wild-card syntax please consult the user manual.

Example step-by-step

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

In this example we will define a hierarchy of topics in the file activemq-jms.xml

        
   <topic name="news">
      <entry name="/topic/news"/>
   </topic>
   
   <topic name="news.usa">
      <entry name="/topic/news.usa"/>
   </topic>
   
   <topic name="news.usa.wrestling">
      <entry name="/topic/news.wrestling"/>
   </topic>
   
   <topic name="news.europe">
      <entry name="/topic/news.europe"/>
   </topic>
   
   <topic name="news.europe.sport">
      <entry name="/topic/news.europe.sport"/>
   </topic>
   
   <topic name="news.europe.entertainment">
      <entry name="/topic/news.europe.entertainment"/>
   </topic>
        
     

Then we will create a subscriber using the wildcard "news.europe.#".

We will then send three messages: one to the address news.usa.wrestling, one to the address news.europe.sport, and one to the address news.europe.entertainment.

We will verify that the message sent to news.usa.wrestling does not get received since it does not match, but the messages sent to the other two addresses do get received since they match.

  1. Create an initial context to perform the JNDI lookup.
  2.            initialContext = getContext(0);
            
  3. Perform a lookup on the Connection Factory
  4.            ConnectionFactory cf = (ConnectionFactory) initialContext.lookup("/ConnectionFactory");
            
  5. Create a JMS Connection
  6.            connection = cf.createConnection();
            
  7. Create a JMS Session
  8.            Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            
  9. Instantiate a topic representing the wildcard we're going to subscribe to.
  10.            Topic topicSubscribe = ActiveMQJMSClient.createActiveMQTopic("news.europe.#");
            
  11. Create a consumer (topic subscriber) that will consume using that wildcard. The consumer will receive any messages sent to any topic that starts with news.europe
  12.           MessageConsumer messageConsumer = session.createConsumer(topicSubscribe);
           
  13. Create an anonymous producer. The sending address is specified at send time.
  14.            MessageProducer producer = session.createProducer(null);
            
  15. Instantiate some more topic objects corresponding to the individual topics we're going to send messages to. You could look these up from JNDI if you wanted to.
  16.            
             Topic topicNewsUsaWrestling = ActiveMQJMSClient.createActiveMQTopic("news.usa.wrestling");
             
             Topic topicNewsEuropeSport = ActiveMQJMSClient.createActiveMQTopic("news.europe.sport");
             
             Topic topicNewsEuropeEntertainment = ActiveMQJMSClient.createActiveMQTopic("news.europe.entertainment");
            
  17. Send a message destined for the usa wrestling topic.
  18.            
             TextMessage messageWrestlingNews = session.createTextMessage("Hulk Hogan starts ballet classes");
             
             producer.send(topicNewsUsaWrestling, messageWrestlingNews);
               
            
  19. Send a message destined for the europe sport topic.
  20.            
             TextMessage messageEuropeSport = session.createTextMessage("Lewis Hamilton joins European synchronized swimming team");
             
             producer.send(topicNewsEuropeSport, messageEuropeSport);           
               
            
  21. Send a message destined for the europe entertainment topic
  22.            
             TextMessage messageEuropeEntertainment = session.createTextMessage("John Lennon resurrected from dead");
             
             producer.send(topicNewsEuropeEntertainment, messageEuropeEntertainment);
               
            
  23. Start the connection
  24.            
            connection.start();
               
            
  25. We don't receive the usa wrestling message since we subscribed to news.europe.# and that doesn't match news.usa.wrestling. However we do receive the Europe sport message, and the europe entertainment message, since these match the wildcard.
  26.            
            TextMessage messageReceived1 = (TextMessage)messageConsumer.receive(5000);
             
            System.out.println("Received message: " + messageReceived1.getText());
             
            TextMessage messageReceived2 = (TextMessage)messageConsumer.receive(5000);
             
            System.out.println("Received message: " + messageReceived2.getText());
             
            Message message = messageConsumer.receive(1000);
             
            if (message != null)
            {
               return false;
            }
             
            System.out.println("Didn't received any more message: " + message);
               
            
  27. Be sure to close our resources!
  28.            finally
               {
                  if (initialContext != null)
                  {
                    initialContext.close();
                  }
                  if (connection != null)
                  {
                     connection.close();
                  }
               }