javaapache-camelactivemq-artemis

Wildcard address with fully-qualified-queue-name


I am using Apache ActiveMQ Artemis 2.39.0 in an application that needs to process messages broadcast on a collection of topics with the same logic. Multiple instances of this application can be running, but only one instance of the application should do the processing. Other applications need to be able to subscribe to the topics so they can't just be queues.

To accomplish this I have created an Apache Camel route which utilizes a wildcard address with a fully-qualified-queue-name. Since all instances should consume from this backing queue only one instance should actually process the message.

The route source is specified in camel using the following URI:

jms:queue:application.event.#::application.process.event

The desired behavior is for the Camel route to consume any message on any topic that begins with application.event, but that is not happening. A message sent to application.event.shutdown is not received in the Camel route. Setting the source URI to instead be jms:queue:application.event.shutdown results in the message being received, so it's not a problem on the publishing side. Using a subscriber queue to subscribe to a single topic also seems to work jms:queue:application.event.shutdown::application.process.event

What could be going wrong here? Is there another way for me to guarantee that a message published to a collection of topics will only be processed by one instance of this application? Am I misconfiguring something?

I have both org:apache.activemq:activemq-client:6.16 and org.apache.activemq:artemis-core-client:2.40.0 on my classpath.


Solution

  • I believe the problem I was having was due to having two ActiveMQ client libraries on the class path, and I was using the wrong one. I have both activemq-client:6.1.6 and artemis-core-client:2.40.0. I wrote the following snippet in the process of debugging.

    
    import jakarta.jms.JMSException;
    import jakarta.jms.Message;
    import jakarta.jms.MessageListener;
    import org.apache.activemq.ActiveMQConnectionFactory;
    import org.apache.activemq.command.ActiveMQTopic;
    
    public static void main(String[] args) throws JMSException {
            var connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616", "admin", "admin");
            var connection = connectionFactory.createConnection();
            var session = connection.createSession();
            var consumer = session.createConsumer(new ActiveMQTopic("application.event.#"));
            consumer.setMessageListener(new MessageListener() {
                @Override
                public void onMessage(Message message) {
                    System.out.println("Here");
                }
            });
            connection.start();
            var producer = session.createProducer(new ActiveMQTopic("application.event.send"));
            producer.send(session.createTextMessage("Hello!"));
        }
    

    I would expect this to print "Here" especially after what Justin posted, proving it worked. However it didn't. I needed to swap to the proper imports

    import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory;
    import org.apache.activemq.artemis.jms.client.ActiveMQTopic;
    

    With only that change, the code executed as expected. I suspect this is the problem in the "real" code as well, but haven't confirmed yet