Chapter 30. Configuring Java Message Service bridges
JBoss EAP messaging includes a Java Message Service bridge, which takes messages from a source destination and send them to a target destination, usually on a different server.
A Java Message Service bridge supports destination mapping in which each link consists of a source and a target defined below:
- The source defines the destination from which the Java Message Service bridge receives messages. The source consists of a connection factory for creating connections to a Java Message Service provider and a message source destination in that provider.
- The target defines the destination to which the Java Message Service bridge sends messages received from the source. The target consists of a connection factory for creating connections to a Java Message Service provider and a message target destination in that provider.
If the source destination is a topic, the Java Message Service bridge creates a subscription for it. If the client-id and subscription-name attributes are configured for the Java Message Service bridge, the subscription is durable. This means that no messages are missed if the Java Message Service bridge is stopped and then restarted.
The source and target servers do not have to be in the same cluster, which makes bridging suitable for reliably sending messages from one cluster to another, for instance across a WAN, and where the connection may be unreliable.
Do not confuse a Java Message Service bridge with a core bridge. A Java Message Service bridge can be used to bridge any two Java Message Service-1.1-compliant providers and uses the Java Message Service API. A Configuring core bridges is used to bridge any two JBoss EAP messaging instances and uses the core API. Whenever possible, use a core bridge instead of a Java Message Service bridge.
Example configuration of a JBoss EAP Java Message Service bridge
<subsystem xmlns="urn:jboss:domain:messaging-activemq:17.0">
<server name="default">
...
</server>
<jms-bridge name="my-jms-bridge" module="org.apache.activemq.artemis" max-batch-time="100" max-batch-size="10" max-retries="1" failure-retry-interval="500" quality-of-service="AT_MOST_ONCE">
<source destination="jms/queue/InQueue" connection-factory="ConnectionFactory">
<source-context/>
</source>
<target destination="jms/queue/OutQueue" connection-factory="jms/RemoteConnectionFactory">
<target-context>
<property name="java.naming.factory.initial" value="org.wildfly.naming.client.WildFlyInitialContextFactory"/>
<property name="java.naming.provider.url" value="remote+http://192.168.40.1:8080"/>
</target-context>
</target>
</jms-bridge>
...
</subsystem>
In the above example configuration, the Java Message Service bridge uses the connection-factory attribute for creating the following two connections:
- Source-context, which defines the original destination of the received messages.
- Target-context, which defines the target destination that receives the messages.
You can use the default implementation provided by Apache ActiveMQ Artemis or Red Hat AMQ that searches the connection factory by using Java Naming and Directory Interface (JNDI). For other application servers or Java Message Service providers, you can provide a new implementation by implementing the interface org.apache.activemq.artemis.jms.bridge.ConnectionFactoryFactory.
Adding a Java Message Service bridge using the management CLI A Java Message Service bridge can be added using the following management CLI command. Note that the source and target destinations must already be defined in the configuration. See the table in the appendix for a full list of configurable attributes.
/subsystem=messaging-activemq/jms-bridge=my-jms-bridge:add(quality-of-service=AT_MOST_ONCE,module=org.apache.activemq.artemis,failure-retry-interval=500,max-retries=1,max-batch-size=10,max-batch-time=100,source-connection-factory=ConnectionFactory,source-destination=jms/queue/InQueue,source-context={},target-connection-factory=jms/RemoteConnectionFactory,target-destination=jms/queue/OutQueue,target-context={java.naming.factory.initial=org.wildfly.naming.client.WildFlyInitialContextFactory,java.naming.provider.url=remote+http://192.168.40.1:8080})
You can review the configuration of a Java Message Service bridge using the read-resource command in the management CLI as in the following example.
/subsystem=messaging-activemq/jms-bridge=my-jms-bridge:read-resource
Add configuration to a Java Message Service bridge by using the write-attribute, as done in this example:
/subsystem=messaging-activemq/jms-bridge=my-jms-bridge:write-attribute(name=ATTRIBUTE,value=VALUE)
- Adding a Java Message Service bridge using the management console
- You can also use the management console to add a Java Message Service bridge by following these steps.
Procedure
-
Open the management console in a browser and navigate to Configuration
Subsystems Messaging (ActiveMQ) JMS Bridge. - Click the Add (+) button and provide the required information when prompted.
Click Add when finished.
- Quality of service
-
In JBoss EAP,
quality-of-serviceis a configurable attribute that determines how messages are consumed and acknowledged. The valid values forquality-of-serviceand their descriptions are below. See the table in the appendix for a full list of Java Message Service bridge attributes. - AT_MOST_ONCE
Messages will reach the destination from the source at the most one time. The messages are consumed from the source and acknowledged before sending to the destination. Therefore, there is a possibility that messages could be lost if a failure occurs between their removal from the source and their arrival at the destination. This mode is the default value.
This mode is available for both durable and non-durable messages.
- DUPLICATES_OK
Messages are consumed from the source and then acknowledged after they have been successfully sent to the destination. Therefore, there is a possibility that messages could be sent again if a failure occurs after the initial message was sent but before it is acknowledged.
This mode is available for both durable and non-durable messages.
- ONCE_AND_ONLY_ONCE
Messages will reach the destination from the source once and only once. If both the source and the destination are on the same server instance, this can be achieved by sending and acknowledging the messages in the same local transaction. If the source and destination are on different servers, this is achieved by enlisting the sending and consuming sessions in Jakarta Transactions. The transaction is controlled by a Transaction Manager which will need to be set using the
setTransactionManager()method on the bridge.This mode is only available for durable messages.
WarningWhen shutting down a server that has a deployed Java Message Service bridge with the
quality-of-serviceattribute set toONCE_AND_ONLY_ONCE, be sure to shut the server down with the Java Message Service bridge first to avoid unexpected errors.It may possible to provide once and only once semantics by using the
DUPLICATES_OKmode instead ofONCE_AND_ONLY_ONCEand then checking for duplicates at the destination and discarding them. See Configuring Duplicate Message Detection for more information. However, the cache would only be valid for a certain period of time. This approach therefore is not as watertight as usingONCE_AND_ONLY_ONCE, but it may be a good choice depending on your specific application needs.- Timeouts and the Java Message Service bridge
There is a possibility that the target or source server will not be available at some point in time. If this occurs, the bridge will try to reconnect a number of times equal to the value of
max-retries. The wait between attempts is set byfailure-retry-interval.WarningBecause each Java Message Service bridge has its own
max-retriesparameter, you should use a connection factory that does not set thereconnect-attemptsparameter, or sets it to0. This will avoid a potential collision that may result in longer reconnection times. Also note that any connection factory referenced by a Java Message Service bridge with thequality-of-serviceset toONCE_AND_ONLY_ONCEneeds to have thefactory-typeset toXA_GENERIC,XA_TOPIC, orXA_QUEUE.