0

I'm trying get the MQTT acceptor in Apache Artemis of the Wildfly 18 server to run.

The server is running, I can even send messages to a defined topic (though it has to be defined).

Initially I had to add the permission create-durable-queue="true" to security, otherwise, as soon as I try to subscribe to that topic, the server would terminate the communication.

That said, I try to figure out how I can create on the JMS side, a subscription to a topic with wildcards, and I can find neither current documentation nor any other information about that.

To give some background to the use case:

I want to use the builtin Artemis server of Wildfly 18, and have a bunch of devices which publish to topics like /device/reader/SOMEID/temperature and similar.

Within my EJBs I want to subscribe to the topic /device/# and get all messages for that topic and all sub topics.

How can I achieve that?

Also when my entry in the config is

<jms-topic name="TestTopic" entries="java:/jms/topic/TestTopic" />

Why is the MQTT topic then jms/topic/TestTopic? I'm not happy about using a prefix there.

Justin Bertram
  • 29,372
  • 4
  • 21
  • 43
Mauli
  • 16,863
  • 27
  • 87
  • 114
  • Did my answer address your question? If so, please mark it as correct to help other users who have this same question in the future. If not, please elaborate as to why. Thanks! – Justin Bertram Nov 07 '19 at 18:25

1 Answers1

2

The server is running, I can even send messages to a defined topic (though it has to be defined).

If you're using true for the auto-create-addresses address-setting then the topic (i.e. the address) should be created for you automatically either when you send a message to it or create a subscription on it.

Initially I had to add the permission create-durable-queue="true" to security, otherwise, as soon as I try to subscribe to that topic, the server would terminate the communication.

This is expected as the create-durable-queue permission is not set by default.

If you want your JMS topic subscriber to get all the messages sent to a certain set of addresses then simply specify the desired wildcard address in your jms-topic definition in the server config or in the code. You can find the latest documentation on this subject for ActiveMQ Artemis here and an example of it being used here.

Why is the MQTT topic then jms/topic/TestTopic? I'm not happy about using a prefix there.

Unfortunately the prefix is not optional in Wildfly for historical backwards compatibility issues. Also, while it is technically possible for the embedded ActiveMQ Artemis instance to service non-JMS clients the embedded broker is really meant to just serve as the JMS implementation as required by Java EE. You'll have more flexibility (i.e. the ability to not use the aforementioned prefix) if you run ActiveMQ Artemis standalone.

Justin Bertram
  • 29,372
  • 4
  • 21
  • 43
  • Thank you, I added `auto-create-jms-queues="true" auto-create-queues="true" auto-create-addresses="true"` to my configuration. And now I get the messages. It was not entirely clear to me what the delimiters were `/` or `.` and if the wildcard was supposed to be `#` or `>`. I now need to find out on which Topic it was actually published. The messages which I get via MQTT are of type `ActiveMQDestination` and not a topic, so how to I get the name? – Mauli Oct 28 '19 at 15:43
  • As noted in the schema `auto-create-jms-queues` is deprecated in favor of `auto-create-queues` and `auto-create-addresses`. I don't understand what you're saying about the messages you get via MQTT are of type `ActiveMQDestination`. The `ActiveMQDestination` class is part of the JMS implementation and has nothing to do with MQTT. This seems like it may be a new/different question which would probably be best on a new post. – Justin Bertram Oct 28 '19 at 16:19
  • I have now an MDB which listens to `TestTopic.#`. That works fine. For test purposes I created a scheduler which posts messages to `TestTopic` and `TestTopic.subtopic`, which is fine. In the message `destination` is of type `Topic`. Thats all fine. When I post on the same topics via MQTT (e.g. `jms/topic/TestTopic`) then the destination is only of type `Destination` (specifically `ActiveMQDestination`), not a `Topic`. And since `Destination` doesn't have a name, how do I get the name of the topic? I want to avoid a call to getName() or getAddress via reflection. – Mauli Oct 28 '19 at 16:37
  • As noted in [the JavaDoc for `Destination`](https://docs.oracle.com/javaee/7/api/javax/jms/Destination.html) it has no methods of it's own and 4 subinterfaces - `Queue`, `TemporaryQueue`, `TemporaryTopic`, `Topic`. No reflection should be necessary to get the name. Simply do `if (destination instanceof Topic) {name = ((Topic)destination).getTopicName();}`. – Justin Bertram Oct 28 '19 at 16:52
  • That's why I said, the message I get via MQTT has in its destination neither a topic nor a queue. When I post within wildfly via JMS, I get as the destination `org.apache.activemq.artemis.jms.client.ActiveMQTopic` - but when it is posted via MQTT I get `org.apache.activemq.artemis.jms.client.ActiveMQDestination` which doesn't implement either of them. – Mauli Oct 28 '19 at 17:06
  • If you have a `Destination` implementation which implements neither `Queue` nor `Topic` then there is no way via the JMS API to retrieve the name. However, you can get the name from an `org.apache.activemq.artemis.jms.client.ActiveMQDestination` via the `getName()` method. – Justin Bertram Oct 28 '19 at 17:17
  • FWIW, [here is the JavaDoc for `org.apache.activemq.artemis.jms.client.ActiveMQDestination`](http://activemq.apache.org/components/artemis/documentation/javadocs/javadoc-latest/org/apache/activemq/artemis/jms/client/ActiveMQDestination.html). – Justin Bertram Oct 28 '19 at 17:22