The messaging-activemq
subsystem allows to configure a
pooled-connection-factory
resource to let a local client deployed in
WildFly connect to a remote Artemis server.
The configuration of such a pooled-connection-factory
is done in 3
steps:
\1. create an outbound-socket-binding pointing to the remote messaging server:
/socket-binding-group=standard-sockets/remote-destination-outbound-socket-binding=remote-artemis:add(host=<server host>, port=61616)
\2. create a remote-connector referencing the outbound-socket-binding created at step (1).
/subsystem=messaging-activemq/server=default/remote-connector=remote-artemis:add(socket-binding=remote-artemis)
\3. create a pooled-connection-factory referencing the remote-connector created at step (2).
/subsystem=messaging-activemq/server=default/pooled-connection-factory=remote-artemis:add(connectors=[remote-artemis], entries=[java:/jms/remoteCF])
When a pooled-connection-factory
is configured to connect to a remote
Artemis, it is possible to configure Message-Driven Beans (MDB) to have
them consume messages from this remote server.
The MDB must be annotated with the @ResourceAdapter
annotation using
the name of the pooled-connection-factory resource
import org.jboss.ejb3.annotation.ResourceAdapter;
@ResourceAdapter("remote-artemis")
@MessageDriven(name = "MyMDB", activationConfig = {
...
})
public class MyMDB implements MessageListener {
public void onMessage(Message message) {
...
}
}
If the MDB needs to produce messages to the remote server, it must
inject the pooled-connection-factory
by looking it up in JNDI using
one of its entries
.
@Inject
@JMSConnectionFactory("java:/jms/remoteCF")
private JMSContext context;
A MDB must also specify which destination it will consume messages from.
The standard way is to define a destinationLookup
activation config
property that corresponds to a JNDI lookup on the local server.
When the MDB is consuming from a remote Artemis server, there may not
have such a JNDI binding in the local WildFly.
It is possible to use the naming subsystem to configure
external context federation to have local JNDI
bindings delegating to external bindings.
However there is a simpler solution to configure the destination when
using the Artemis Resource Adapter.
Instead of using JDNI to lookup the JMS Destination resource, you can
just specify the name of the destination (as configured in the remote
Artemis server) using the destination
activation config property and
set the useJNDI
activation config property to false to let the Artemis
Resource Adapter create automatically the JMS destination without
requiring any JNDI lookup.
@ResourceAdapter("remote-artemis")
@MessageDriven(name = "MyMDB", activationConfig = {
@ActivationConfigProperty(propertyName = "useJNDI", propertyValue = "false"),
@ActivationConfigProperty(propertyName = "destination", propertyValue = "myQueue"),
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge")
})
public class MyMDB implements MessageListener {
...
}
These properties configure the MDB to consume messages from the JMS
Queue named myQueue
hosted on the remote Artemis server.
In most cases, such a MDB does not need to lookup other destinations to
process the consumed messages and it can use the JMSReplyTo destination
if it is defined on the message.
If the MDB needs any other JMS destinations defined on the remote
server, it must use client-side JNDI by following the
Artemis
documentation or configure external configuration context in the naming
subsystem (which allows to inject the JMS resources using the
@Resource
annotation).
[[configuration of a remote destination using annotations]] ==== Configuration of a remote destination using annotations
The annotation @JMSDestinationDefinition
can be used to create a destination on a remote Artemis Server. This will work in the same way as for a local server.+
For this it needs to be able to access Artemis management queue. If your remote Artemis Server management queue is not the default one you can pass the management queue address as a property to the @JMSDestinationDefinition
.
Please note that the destination is created remotely but won’t be removed once the deployement is undeployed/removed.
@JMSDestinationDefinition(
// explicitly mention a resourceAdapter corresponding to a pooled-connection-factory resource to the remote server
resourceAdapter = "activemq-ra",
name="java:global/env/myQueue2",
interfaceName="javax.jms.Queue",
destinationName="myQueue2",
properties = {
"management-address=my.management.queue",
"selector=color = 'red'"
}
)