ActiveMQ Artemis: Virtual Topic and Dead Letter Queue - activemq-artemis

We are migrating from ActiveMQ "Classic" to ActiveMQ Artemis.
On ActiveMQ "Classic" we were using Virtual Topics. They were created with virtualDestinationInterceptor:
<virtualTopic name="VirtualTopic.>" prefix="Consumer.*." selectorAware="false"/>
There is also deadLetterStrategy to automatically create the dead letter queue by appending .Dead at the end of the queue name.
With that setup when a message is undelivered on a Virtual Topic consumers queue it is placed on a queue with the same name suffixed with .Dead.
On ActiveMQ Artemis we have reproduced that by setting the OpenWire parameter virtualTopicConsumerWildcards=Consumer.*.>;2.
The result it that when a consumer is listening on the queue Consumer.CLIENT_ID.VirtualTopic.QUEUE_NAME he receives messages sent to the address VirtualTopic.QUEUE_NAME.
The corresponding FQQN is therefore VirtualTopic.QUEUE_NAME::Consumer.CLIENT_ID.VirtualTopic.QUEUE_NAME.
The dead letter mechanism is reproduced by configuring the broker with auto create dead letter resource and suffixing the created queue with .Dead:
<address-setting match="#">
<dead-letter-address>DLQ</dead-letter-address>
<auto-create-dead-letter-resources>true</auto-create-dead-letter-resources>
<dead-letter-queue-prefix></dead-letter-queue-prefix>
<dead-letter-queue-suffix>.Dead</dead-letter-queue-suffix>
...
</address-setting>
The result is that when a message is not delivered it ends on the DLQ address on a queue with the name of the original address suffixed with .Dead. FQQN: DLQ::VirtualTopic.QUEUE_NAME.Dead.
Question: How can we send the undelivered messages to a dead-letter queue with the same name as the consumed queue: FQQN Consumer.CLIENT_ID.VirtualTopic.QUEUE_NAME::Consumer.CLIENT_ID.VirtualTopic.QUEUE_NAME?
I was hoping that a divert could hook in but that has not effect. The undelivered message is still ending on the DLQ address:
<diverts>
<divert name="virtualTopicDeadDivert">
<address>DLQ</address>
<forwarding-address>Consumer.CLIENT_ID.VirtualTopic.FunctionalTest.Dead</forwarding-address>
<!--filter string="_AMQ_ORIG_QUEUE='Consumer.CLIENT_ID.VirtualTopic.QUEUE_NAME'"/-->
<exclusive>true</exclusive>
</divert>
</diverts>

There is currently no way to send an undelivered message to a dead-letter address with a queue which is automatically created and named according to the queue where the message was originally sent.
This mismatch in behavior is a consequence of the naming convention and the semantics of virtual topics in ActiveMQ "Classic" combined with the semantics of the address model of ActiveMQ Artemis. To be clear, ActiveMQ Artemis is not meant to be a feature-for-feature reimplementation of ActiveMQ "Classic." Rather, it is a new implementation with features and abilities not possible on ActiveMQ "Classic" with equivalent (and sometimes identical) behavior where it makes sense.
Please note that virtual topics in ActiveMQ "Classic" were originally developed to deal with some of the shortcomings of JMS topic subscriptions in JMS 1.1. However, these limitations are already dealt with by the fundamental address model of ActiveMQ Artemis, but more importantly these limitations are already dealt with in JMS 2.0. ActiveMQ "Classic" doesn't yet support JMS 2.0, but ActiveMQ Artemis always has. You might consider moving a way from virtual topics and using JMS 2.0 instead.

Related

ActiveMQ Artemis divert to multiple addresses

I am migrating from ActiveMQ "Classic" to ActiveMQ Artemis. ActiveMQ "Classic" has composite destinations which can forward messages to multiple destinations.
ActiveMQ Artemis uses diverts to forward messages. Can you have one divert to multiple addresses or do you need a separate divert config for each address you wish to forward onto ... for each?
At this point you'll need an individual <divert> for each address where you want to forward the message.
However, in the upcoming ActiveMQ Artemis 2.21.0 you'll be able to forward messages to multiple addresses from a single divert. See ARTEMIS-3670 for more details.

Configure ActiveMQ Artemis message redelivery on the client side

I wonder if it is possible to configure message redelivery on the client side. I have read the ActiveMQ Artemis docs and have not found any information about this feature. So I made a conclusion that there is no opportunity to configure message redelivery on the client side. The only place to configure message redelivery is the broker.xml file. Am I right about it?
By the way I can configure the connection to ActiveMQ Artemis by using broker URL params or by application.yml since I using Spring Boot 2.x.
ActiveMQ Artemis supports AMQP, STOMP, MQTT, OpenWire, etc. Many clients exist for these protocols written in lots of different languages across all kinds of platforms. Whether or not a given client supports client-side redelivery is really up to the client itself. You don't specify which client you're using so it's impossible to give you a specific yes/no answer.
However, I can say that ActiveMQ Artemis ships a JMS client implementation which uses the core protocol. That client does not support client-side redelivery. However, the OpenWire JMS client shipped with ActiveMQ "Classic" does support client-side redelivery, and it can be used with ActiveMQ Artemis as well.

JBoss AMQ / ActiveMQ Artemis: Pre-configure Durable Subscribers

I have a Red Hat AMQ (which is based on ActiveMQ Artemis) broker and I would like to make use of durable subscription (or equivalent) feature, so that I will have multiple OpenWire JMS subscribers subscribing to the events of our application which will be delivered to them reliably.
I would like to pre-configure subscribers, so to save me trouble in initial application startup. I want to avoid the case for initial application start up where the main application starts running and publishing events before our durable subscribers perform their initial subscription.
I also wants to avoid explicitly ordering start up sequence of my processes.
Is there any way I can pre-configure durable subscribers? In ordinary ActiveMQ (not Artemis), there is feature like Virtual Topics which (kind of) solve the problem.
What is the preferred solution for ActiveMQ Artemis?
It is possible to pre-configure durable subscriptions since the OpenWire implementation creates the queue used for the durable subscription in a deterministic way (i.e. using the format of client-id.subscription-name). For example, if you wanted to configure a durable subscription on the address myAddress with a client-id of myclientid and a subscription name of mysubscription then configure the durable subscription:
<addresses>
<address name="myAddress">
<multicast>
<queue name="myclientid.mysubscription"/>
</multicast>
</address>
</addresses>

Messages delivered twice at same instant to AMQP message consumer (ActiveMQ Artemis)

I recently had to rollback from WF13 to WF11 due to a regression in one of the dependencies.
Now I am trying to get the AMQP protocol to work on WildFly 11's messaging system. I am running a high availability setup with two nodes. Each of the node has a message consumer locally. This message consumer connects through AMQP1. I've added io.netty as a dependency to the org/apache/activemq/artemis/protocol/amqp module and updated org/apache/qpid to get the AMQP protocol to work (see also WFLY-7823). Now my AMQP message consumer works fine, but it seems to receive messages always exactly twice, and it appears to be even in the same frame. This happens on the same node (the other node receives messages through the bridge if the message isn't handled locally in the first place). So on one node and one queue consumer, I receive every message exactly twice, at the very same instant, before I even got to send an ACK/NACK for the first message I received.
I don't remember seeing this issue on WildFly 13.
Are there any known regressions regarding how messages are sent through the remote connectors? Perhaps an issue in the AMQP protocol? Or could it be a compatibility issue with the updated version of qtip?
For what it's worth Wildfly only uses ActiveMQ Artemis to fulfill their need for a JMS implementation (i.e. a traditional part of Java EE). I don't believe Wildfly has any real interest in other protocols or APIs aside from JMS.
My understanding here is that if you need to support multi-protocol message use-cases you should likely be using a standalone broker. I believe this is why none of the other protocols which Artemis supports (e.g. AMQP, STOMP, MQTT, OpenWire) are enabled in Wildfly or have documentation on how to enable them (aside from the occasional forum post).
It's also worth noting that Wildfly 11 has Artemis 1.5.5 in it which is 10 releases or so behind the latest version (i.e. 2.6.2). Much work has been done on the AMQP implementation in those releases so I think you're best served by using a standalone version of Artemis rather than Artemis embedded in Wildfly.

One JMS message copied to two queues

How do I configure activemq such that a JMS message published to a topic is passed on to two JMS queue.
Is this possible in activemq?
Or
Is it better to use a simple topic with two subscribers. Both picking up their own copy of a message.
Instead of trying to configure the Broker to do this you are better off using Apache Camel to create the routing behaviour you are looking for. Camel routes can be embedded in you ActiveMQ instance.