[[Messaging_Connect_a_pooled-connection-factory_to_a_Remote_Artemis_Server]]
= Connect a pooled-connection-factory to a Remote Artemis Server

ifdef::env-github[]
:tip-caption: :bulb:
:note-caption: :information_source:
:important-caption: :heavy_exclamation_mark:
:caution-caption: :fire:
:warning-caption: :warning:
endif::[]

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:

. create an outbound-socket-binding pointing to the remote messaging
server:
+
[source,options="nowrap"]
----
/socket-binding-group=standard-sockets/remote-destination-outbound-socket-binding=remote-artemis:add(host=<server host>, port=61616)
----

. create a remote-connector referencing the outbound-socket-binding
created at step (1).
+
[source,options="nowrap"]
----
/subsystem=messaging-activemq/remote-connector=remote-artemis:add(socket-binding=remote-artemis)
----

. create a pooled-connection-factory referencing the remote-connector
created at step (2).
+
[source,options="nowrap"]
----
/subsystem=messaging-activemq/pooled-connection-factory=remote-artemis:add(connectors=[remote-artemis], entries=[java:/jms/remoteCF])
----

In Artemis 1.x topics and queues used had a prefix(jms.topic. and jms.queue.) that were prepended to the destination name.
In Artemis 2.x this is no longer the case, but for compatibility reasons WildFly still prepend those prefixes and tells Artemis to run in compatibility mode.
If you  are connecting to a remote Artemis 2.x, it may not be in compatibility mode and thus the old prefixes may not be used anymore.
If you need to use destinations without those prefixes, you can configure your connection factory not to use them by setting the attribute `enable-amq1-prefix` to false.
[source,options="nowrap"]
----
/subsystem=messaging-activemq/pooled-connection-factory=remote-artemis:write-attribute(name="enable-amq1-prefix", value="false")
----

[[jakarta_messaging_queues_topics_on_remote_artemis_server]]
== Jakarta Messaging Queues and Topics on a remote Artemis Server

You can also add queues and topics defined on a remote Artemis server to be used as if they were local to the server. This means that you can make those remote destinations available via JNDI just like local destinations.
You can also configure destinations not to enable the Artemis 1.x prefixes by setting the attribute `enable-amq1-prefix` to false. Those destinations are defined out-of the server element:

[source,xml]
----
<subsystem xmlns="urn:jboss:domain:messaging-activemq:1.0">
    <external-jms-queue name="testQueue"
               entries="jms/queue/test java:jboss/exported/jms/queue/test" enable-amq1-prefix="false" />
    <external-jms-topic name="testTopic"
               entries="jms/topic/test java:jboss/exported/jms/topic/test" enable-amq1-prefix="false" />
</subsystem>
----

Jakarta Messaging endpoints can easily be created through the CLI:
[source,ruby]
----
[standalone@localhost:9990 /] /subsystem=messaging-activemq/external-jms-queue=myQueue:read-resource
{
    "outcome" => "success",
    "result" => {
        "entries" => ["queues/myQueue"]
    }
}
----
You don't have operations to see or manage attributes of those destinations.

[[configuration-of-a-mdb-using-a-pooled-connection-factory]]
== Configuration of a MDB using a pooled-connection-factory

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`

[source,java,options="nowrap"]
----
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`.

[source,java,options="nowrap"]
----
@Inject
@JMSConnectionFactory("java:/jms/remoteCF")
private JMSContext context;
----

[[configuration-of-the-destination]]
=== Configuration of the destination

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 it will now create those bindings locally. +
It is possible to use the naming subsystem to configure
<<Naming,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 Jakarta Messaging 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 Jakarta Messaging destination without
requiring any JNDI lookup.

[source,java,options="nowrap"]
----
@ResourceAdapter("remote-artemis")
@MessageDriven(name = "MyMDB", activationConfig = {
    @ActivationConfigProperty(propertyName = "useJNDI",         propertyValue = "false"),
    @ActivationConfigProperty(propertyName = "destination",     propertyValue = "myQueue"),
    @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "jakarta.jms.Queue"), 
    @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge")
})
public class MyMDB implements MessageListener {
    ...
}
----

These properties configure the MDB to consume messages from the Jakarta Messaging
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 Jakarta Messaging destinations defined on the remote
server, it must use client-side JNDI by following the
http://http://activemq.apache.org/artemis/docs/2.6.0/using-jms.html#jndi-configuration[Artemis
documentation] or configure external configuration context in the naming
subsystem (which allows to inject the Jakarta Messaging 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.

[source, java]
----
@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="jakarta.jms.Queue",
    destinationName="myQueue2",
        properties = {
            "management-address=my.management.queue",
            "selector=color = 'red'"
       }
)
----

You can also configure destinations not to enable the Artemis 1.x prefixes by adding a property `enable-amq1-prefix` to false to the `@JMSDestinationDefinition`.

[source, java]
----
@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="jakarta.jms.Queue",
    destinationName="myQueue2",
    properties = {
        "enable-amq1-prefix=false"
    }
)
----
