Chapter 9. JBoss Messaging Message Bridge Configuration

9.1. Message bridge overview

JBoss Messaging includes a fully functional message bridge.

The function of the bridge is to consume messages from a source queue or topic, and send them to a target queue or topic, typically on a different server.

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.

A bridge is deployed inside a JBoss AS instance. The instance can be the same instance as either the source or target server. Or could be on a third, separate JBoss AS instance.

A bridge is deployed as an MBean inside JBoss AS. Deployment is trivial - just drop the MBean descriptor into the deploy directory of a JBoss configuration which contains JBoss Messaging.

An example in docs/example/bridge demonstrates a simple bridge being deployed in JBoss AS, and moving messages from the source to the target destination

The bridge can also be used to bridge messages from other non JBoss Messaging JMS servers, as long as they are JMS 1.1 compliant.

The bridge has built in resilience to failure so if the source or target server connetion is lost, e.g. due to network failure, the bridge will retry connecting to the source and/or target until they come back online. When it comes back online it will resume operation as normal.

The bridge can be configured with an optional JMS selector, so it will only consume messages matching that JMS selector

It can be configured to consume from a queue or a topic. When it consumes from a topic it can be configured to consume using a non durable or durable subscription

The bridge can be configured to bridge messages with one of three levels of quality of service, they are:

  • QOS_AT_MOST_ONCE

    With this QoS mode messages will reach the destination from the source at most once. The messages are consumed from the source and acknowledged before sending to the destination. Therefore there is a possibility that if failure occurs between removing them from the source and them arriving at the destination they could be lost. Hence delivery will occur at most once. This mode is avilable for both persistent and non persistent messages.

  • QOS_DUPLICATES_OK

    With this QoS mode, the messages are consumed from the source and then acknowledged after they have been successfully sent to the destination. Therefore there is a possibility that if failure occurs after sending to the destination but before acknowledging them, they could be sent again when the system recovers. I.e. the destination might receive duplicates after a failure. This mode is available for both persistent and non persistent messages.

  • QOS_ONCE_AND_ONLY_ONCE

    This QoS mode ensures messages will reach the destination from the source once and only once. (Sometimes this mode is known as "exactly once"). If both the source and the destination are on the same JBoss Messaging server instance then 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 a JTA transaction. The JTA transaction is controlled by JBoss Transactions JTA implementation which is a fully recovering transaction manager, thus providing a very high degree of durability. If JTA is required then both supplied connection factories need to be XAConnectionFactory implementations. This mode is only available for persistent messages. This is likely to be the slowest mode since it requires logging on both the transaction manager and resource side for recovery. If you require this level of QoS, please be sure to enable XA recovery with JBoss Transactions.

    Note

    For a specific application it may possible to provide once and only once semantics without using the QOS_ONCE_AND_ONLY_ONCE QoS level. This can be done by using the QOS_DUPLICATES_OK mode and then checking for duplicates at the destination and discarding them. This may be possible to implement on the application level by maintaining a cache of received message ids on disk and comparing received messages to them. The cache would only be valid for a certain period of time so this approach is not as watertight as using QOS_ONCE_AND_ONLY_ONCE but may be a good choice depending on your specific application.

9.2. Bridge deployment

A message bridge is easily deployed by dropping the MBean descriptor in the deploy directory of your JBoss AS installation which contains JBoss Messaging

9.3. Bridge configuration

In this section we describe how to configure the message bridge

Here is an example of a message bridge configuration, with all the attributes shown. Note that some are commented out for this configuration, since it is not appropriate to specify them all at once. Which ones are specified depends on the configuration you want.

   <mbean code="org.jboss.jms.server.bridge.BridgeService"
          name="jboss.messaging:service=Bridge,name=TestBridge"
          xmbean-dd="xmdesc/Bridge-xmbean.xml">
          
      <!-- The JMS provider loader that is used to lookup the source destination -->   
      <depends optional-attribute-name="SourceProviderLoader">
          jboss.messaging:service=JMSProviderLoader,name=JMSProvider</depends>
      
      <!-- The JMS provider loader that is used to lookup the target destination -->
      <depends optional-attribute-name="TargetProviderLoader">
          jboss.messaging:service=JMSProviderLoader,name=JMSProvider</depends>    
      
      <!-- The JNDI lookup for the source destination -->
      <attribute name="SourceDestinationLookup">/queue/A</attribute> 
      
      <!-- The JNDI lookup for the target destination -->
      <attribute name="TargetDestinationLookup">/queue/B</attribute>
      
      <!-- The username to use for the source connection 
      <attribute name="SourceUsername">bob</attribute>
      -->
      
      <!-- The password to use for the source connection
      <attribute name="SourcePassword">cheesecake</attribute>
      -->
      
      <!-- The username to use for the target connection
      <attribute name="TargetUsername">mary</attribute>
      -->
      
      <!-- The password to use for the target connection
      <attribute name="TargetPassword">hotdog</attribute>
      -->
      
      <!-- Optional: The Quality Of Service mode to use, one of:
           QOS_AT_MOST_ONCE = 0;
           QOS_DUPLICATES_OK = 1;
           QOS_ONCE_AND_ONLY_ONCE = 2; -->
      <attribute name="QualityOfServiceMode">0</attribute>
      
      <!-- JMS selector to use for consuming messages from the source
      <attribute name="Selector">specify jms selector here</attribute>
      -->
      
      <!-- The maximum number of messages to consume from the source
          before sending to the target -->
      <attribute name="MaxBatchSize">5</attribute>     
      
      <!-- The maximum time to wait (in ms) before sending a batch to the target
          even if MaxBatchSize is not exceeded.
           -1 means wait forever -->   
      <attribute name="MaxBatchTime">-1</attribute>
      
      <!-- If consuming from a durable subscription this is the subscription name
      <attribute name="SubName">mysub</attribute>
      -->
      
      <!-- If consuming from a durable subscription this is the client ID to use
      <attribute name="ClientID">myClientID</attribute>
      -->
      
      <!-- The number of ms to wait between connection retrues in the event connections
          to source or target fail -->
      <attribute name="FailureRetryInterval">5000</attribute>      
      
      <!-- The maximum number of connection retries to make in case of failure,
          before giving up -1 means try forever-->
      <attribute name="MaxRetries">-1</attribute>

      <!-- If true then the message id of the message before bridging will be added
          as a header to the message so it is available to the receiver. Can then be
          sent as correlation id to correlate in a distributed request-response -->
      <attribute name="AddMessageIDInHeader">false</attribute>
      
    </mbean>
      

We will now discuss each attribute

9.3.1. SourceProviderLoader

This is the object name of the JMSProviderLoader MBean that the bridge will use to lookup the source connection factory and source destination.

By default JBoss AS ships with one JMSProviderLoader, deployed in the file jms-ds.xml - this is the default local JMSProviderLoader. (This would be in hajndi-jms-ds.xml in a clustered configuration)

If your source destination is on different servers or even correspond to a different, non JBoss JMS provider, then you can deploy another JMSProviderLoader MBean instance which references the remote JMS provider, and reference that from this attribute. The bridge would then use that remote JMS provider to contact the source destination

Note that if you are using a remote non JBoss Messaging source or target and you wish once and only once delivery then that remote JMS provider must provide a fully functional JMS XA resource implementation that works remotely from the server - it is known that some non JBoss JMS providers do not provide such a resource

9.3.2. TargetProviderLoader

This is the object name of the JMSProviderLoader MBean that the bridge will use to lookup the target connection factory and target destination.

By default JBoss AS ships with one JMSProviderLoader, deployed in the file jms-ds.xml - this is the default local JMSProviderLoader. (This would be in hajndi-jms-ds.xml in a clustered configuration)

If your target destination is on a different server or even correspond to a different, non JBoss JMS provider, then you can deploy another JMSProviderLoader MBean instance which references the remote JMS provider, and reference that from this attribute. The bridge would then use that remote JMS provider to contact the target destination

Note that if you are using a remote non JBoss Messaging source or target and you wish once and only once delivery then that remote JMS provider must provide a fully functional JMS XA resource implementation that works remotely from the server - it is known that some non JBoss JMS providers do not provide such a resource

9.3.3. SourceDestinationLookup

This is the full JNDI lookup for the source destination using the SourceProviderLoader

An example would be /queue/mySourceQueue

9.3.4. TargetDestinationLookup

This is the full JNDI lookup for the target destination using the TargetProviderLoader

An example would be /topic/myTargetTopic

9.3.5. SourceUsername

This optional attribute is for when you need to specify the username for creating the source connection

9.3.6. SourcePassword

This optional attribute is for when you need to specify the password for creating the source connection

9.3.7. TargetUsername

This optional attribute is for when you need to specify the username for creating the target connection

9.3.8. TargetPassword

This optional attribute is for when you need to specify the password for creating the target connection

9.3.9. QualityOfServiceMode

This integer represents the desired quality of service mode

Possible values are:

  • QOS_AT_MOST_ONCE = 0
  • QOS_DUPLICATES_OK = 1
  • QOS_ONCE_AND_ONLY_ONCE = 2

Please see Section 9.1, “Message bridge overview” for an explanation of what these mean.

9.3.10. Selector

This optional attribute can contain a JMS selector expression used for consuming messages from the source destination. Only messages that match the selector expression will be bridged from the source to the target destination

Please note it is always more performant to apply selectors on source topic subscriptions to source queue consumers.

The selector expression must follow the JMS selector syntax specified here: http://java.sun.com/j2ee/1.4/docs/api/javax/jms/Message.html

9.3.11. MaxBatchSize

This attribute specifies the maximum number of messages to consume from the source destination before sending them in a batch to the target destination. It's value must >= 1

9.3.12. MaxBatchTime

This attribute specifies the maximum number of milliseconds to wait before sending a batch to target, even if the number of messages consumed has not reached MaxBatchSize. It's value must can be -1 to represent 'wait forever', or >=1 to specify an actual time.

9.3.13. SubName

If the source destination represents a topic, and you want to consume from the topic using a durable subscription then this attribute represents the durable subscription name

9.3.14. ClientID

If the source destination represents a topic, and you want to consume from the topic using a durable subscription then this attribute represents the the JMS client ID to use when creating/looking up the durable subscription

9.3.15. FailureRetryInterval

This represents the amount of time in ms to wait between trying to recreate connections to the source or target servers when the bridge has detected they have failed

9.3.16. MaxRetries

This represents the number of times to attempt to recreate connections to the source or target servers when the bridge has detected they have failed. The bridge will give up after trying this number of times. -1 represents 'try forever'

9.3.17. AddMessageIDInHeader

If true, then the original message's message id will appended in the message sent to the destination in the header JBossMessage.JBOSS_MESSAGING_BRIDGE_MESSAGE_ID_LIST. If the message is bridged more than once each message-id will be appended. This enables a distributed request-response pattern to be used