Search code examples
apache-camelactivemq-artemis

camel-jms: shared durable subscription: parameter subscriptionName escapes dots (.)


  • Apache Artemis: 2.31.2
  • Spring-boot : 2.7.18
  • Apache Camel: 3.22.0

I have a question about Camel shared durable subscription in ActiveMQ Artemis. I have migrated from ActiveMQ Classic VirtualTopics, and I have the following configuration in my broker:

<address name="VirtualTopic.ccncsi.fromEurope">
   <multicast>
      <queue name="Consumer.dispatcher.VirtualTopic.ccncsi.fromEurope"/>
      <queue name="Consumer.ccncsiaudit.VirtualTopic.ccncsi.fromEurope"/>
      <queue name="Consumer.ccncsigateway.VirtualTopic.ccncsi.fromEurope"/>
   </multicast>
</address>

I am trying to use the JMS endpoint to connect to the address VirtualTopic.ccncsi.fromEurope and subscription name Consumer.dispatcher.VirtualTopic.ccncsi.fromEurope with the endpoint jms:topic:VirtualTopic.ccncsi.fromEurope?subscriptionName=Consumer.dispatcher.VirtualTopic.ccncsi.fromEurope&subscriptionDurable=true&subscriptionShared=true inspired by this thread on Stack Overflow.

However, when the route is deployed and given enough rights the endpoint creates a new queue on the address with the dots (.) escaped (i.e. Consumer\.dispatcher\.VirtualTopic\.ccncsi\.fromEurope) next to the existing one (i.e. Consumer.dispatcher.VirtualTopic.ccncsi.fromEurope) defined in broker.xml.

I need to keep this consumer queue name because older clients connect through WebLogic and Openwire protocol using the VirtualTopic mapping.

queues_list

In that configuration I can observe that there is a consumer on the queue Consumer\.dispatcher\.VirtualTopic.ccncsi\.fromEurope but I was expecting my endpoint to consume from the existing queue: Consumer.dispatcher.VirtualTopic.ccncsi.fromEurope

I could not workout if the culprit was Camel or Artemis, but when org.apache.activemq.artemis.core.protocol.core.ServerSessionPacketHandler#session.createSharedQueue(request.toQueueConfiguration()); is called, and the request (org.apache.activemq.artemis.core.protocol.core.Packet) is transformed in a QueueConfiguration, I can see that dots are already escaped.

Is this normal behaviour?


Solution

  • This behavior is expected.

    The first thing to note here is that the name of the subscription queue (i.e. Consumer\.dispatcher\.VirtualTopic\.ccncsi\.fromEurope in this case) is an implementation detail under the broker's control. For unshared, durable subscriptions the broker will compose the subscription queue name with the client ID and the subscription name separated by a dot character (.). Since the dot character is a separator the broker escapes any existing dots in the client ID and subscription name. For shared durable subscriptions the client ID is left out and only the subscription name is used, but the broker still escapes the dots.

    That said, you can still get the behavior you want by using the fully qualified queue name in your Camel route, e.g.:

    jms:queue:VirtualTopic.ccncsi.fromEurope::Consumer.dispatcher.VirtualTopic.ccncsi.fromEurope
    

    I'm not super familiar with Camel so the extra colons in there (i.e. ::) may need to be escaped, but hopefully you get the idea. Using the FQQN will allow you to create a consumer on the queue that will share the messages with the other Virtual Topic consumers in your environment.