2014-12-11 07:17:29 -05:00
# The JMS Bridge
2014-12-04 10:25:29 -05:00
2015-04-27 17:32:30 -04:00
Apache ActiveMQ Artemis includes a fully functional JMS message bridge.
2014-12-04 10:25:29 -05:00
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.
2015-02-26 22:41:37 -05:00
> *Notice:*
> The JMS Bridge is not intended as a replacement for transformation and more expert systems such as Camel.
2015-04-27 17:32:30 -04:00
> The JMS Bridge may be useful for fast transfers as this chapter covers, but keep in mind that more complex scenarios requiring transformations will require you to use a more advanced transformation system that will play on use cases that will go beyond Apache ActiveMQ Artemis.
2015-02-26 22:41:37 -05:00
2014-12-04 10:25:29 -05:00
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.
2015-04-27 17:32:30 -04:00
A bridge can be deployed as a standalone application, with Apache ActiveMQ Artemis
2014-12-04 10:25:29 -05:00
standalone server or inside a JBoss AS instance. The source and the
target can be located in the same virtual machine or another one.
2015-04-27 17:32:30 -04:00
The bridge can also be used to bridge messages from other non Apache ActiveMQ Artemis
2014-12-04 10:25:29 -05:00
JMS servers, as long as they are JMS 1.1 compliant.
> **Note**
>
> Do not confuse a JMS bridge with a core bridge. A JMS bridge can be
> used to bridge any two JMS 1.1 compliant JMS providers and uses the
2014-12-11 07:17:29 -05:00
> JMS API. A core bridge (described in [Core Bidges](core-bridges.md)) is used to bridge any two
2015-04-27 17:32:30 -04:00
> Apache ActiveMQ Artemis instances and uses the core API. Always use a core bridge if
2014-12-04 10:25:29 -05:00
> you can in preference to a JMS bridge. The core bridge will typically
> provide better performance than a JMS bridge. Also the core bridge can
> provide *once and only once* delivery guarantees without using XA.
The bridge has built-in resilience to failure so if the source or target
server connection 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
Typically, the bridge is deployed by the JBoss Micro Container via a
beans configuration file. This would typically be deployed inside the
JBoss Application Server and the following example shows an example of a
beans file that bridges 2 destinations which are actually on the same
server.
2015-01-21 13:27:19 -05:00
The JMS Bridge is a simple POJO so can be deployed with most frameworks,
2015-04-29 13:20:31 -04:00
simply instantiate the `org.apache.activemq.artemis.api.jms.bridge.impl.JMSBridgeImpl`
2015-01-21 13:27:19 -05:00
class and set the appropriate parameters.
2014-12-04 10:25:29 -05:00
2014-12-11 07:17:29 -05:00
## JMS Bridge Parameters
2014-12-04 10:25:29 -05:00
The main bean deployed is the `JMSBridge` bean. The bean is configurable
by the parameters passed to its constructor.
> **Note**
>
> To let a parameter be unspecified (for example, if the authentication
> is anonymous or no message selector is provided), use `<null
> />` for the unspecified parameter value.
- Source Connection Factory Factory
This injects the `SourceCFF` bean (also defined in the beans file).
This bean is used to create the *source* `ConnectionFactory`
- Target Connection Factory Factory
This injects the `TargetCFF` bean (also defined in the beans file).
This bean is used to create the *target* `ConnectionFactory`
- Source Destination Factory Factory
This injects the `SourceDestinationFactory` bean (also defined in
the beans file). This bean is used to create the *source*
`Destination`
- Target Destination Factory Factory
This injects the `TargetDestinationFactory` bean (also defined in
the beans file). This bean is used to create the *target*
`Destination`
- Source User Name
this parameter is the username for creating the *source* connection
- Source Password
this parameter is the parameter for creating the *source* connection
- Target User Name
this parameter is the username for creating the *target* connection
- Target Password
this parameter is the password for creating the *target* connection
- Selector
This represents 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
The selector expression must follow the [JMS selector
syntax](http://docs.oracle.com/javaee/6/api/javax/jms/Message.html)
- Failure Retry Interval
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
- Max Retries
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'
- Quality Of Service
This parameter represents the desired quality of service mode
Possible values are:
- `AT_MOST_ONCE`
- `DUPLICATES_OK`
- `ONCE_AND_ONLY_ONCE`
2014-12-11 07:17:29 -05:00
See Quality Of Service section for a explanation of these modes.
2014-12-04 10:25:29 -05:00
- Max Batch Size
This represents the maximum number of messages to consume from the
source destination before sending them in a batch to the target
destination. Its value must `>= 1`
- Max Batch Time
This represents the maximum number of milliseconds to wait before
sending a batch to target, even if the number of messages consumed
has not reached `MaxBatchSize` . Its value must be `-1` to represent
'wait forever', or `>= 1` to specify an actual time
- Subscription Name
If the source destination represents a topic, and you want to
consume from the topic using a durable subscription then this
parameter represents the durable subscription name
- Client ID
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
- Add MessageID In Header
If `true` , then the original message's message ID will be appended
in the message sent to the destination in the header
`ACTIVEMQ_BRIDGE_MSG_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
> **Note**
>
> when you receive the message you can send back a response using
> the correlation id of the first message id, so when the original
> sender gets it back it will be able to correlate it.
- MBean Server
To manage the JMS Bridge using JMX, set the MBeanServer where the
JMS Bridge MBean must be registered (e.g. the JVM Platform
MBeanServer or JBoss AS MBeanServer)
- ObjectName
If you set the MBeanServer, you also need to set the ObjectName used
to register the JMS Bridge MBean (must be unique)
The "transactionManager" property points to a JTA transaction manager
2015-01-23 09:28:07 -05:00
implementation and should be set if you need to use the 'ONCE_AND_ONCE_ONLY'
2015-04-27 17:32:30 -04:00
Quality of Service. Apache ActiveMQ Artemis doesn't ship with such an implementation, but
2015-01-23 09:28:07 -05:00
if you are running within an Application Server you can inject the Transaction
Manager that is shipped.
2014-12-04 10:25:29 -05:00
2014-12-11 07:17:29 -05:00
## Source and Target Connection Factories
2014-12-04 10:25:29 -05:00
The source and target connection factory factories are used to create
the connection factory used to create the connection for the source or
target server.
The configuration example above uses the default implementation provided
2015-04-27 17:32:30 -04:00
by Apache ActiveMQ Artemis that looks up the connection factory using JNDI. For other
2014-12-04 10:25:29 -05:00
Application Servers or JMS providers a new implementation may have to be
provided. This can easily be done by implementing the interface
2015-04-29 13:20:31 -04:00
`org.apache.activemq.artemis.jms.bridge.ConnectionFactoryFactory` .
2014-12-04 10:25:29 -05:00
2014-12-11 07:17:29 -05:00
## Source and Target Destination Factories
2014-12-04 10:25:29 -05:00
Again, similarly, these are used to create or lookup up the
destinations.
In the configuration example above, we have used the default provided by
2015-04-27 17:32:30 -04:00
Apache ActiveMQ Artemis that looks up the destination using JNDI.
2014-12-04 10:25:29 -05:00
A new implementation can be provided by implementing
2015-04-29 13:20:31 -04:00
`org.apache.activemq.artemis.jms.bridge.DestinationFactory` interface.
2014-12-04 10:25:29 -05:00
2014-12-11 07:17:29 -05:00
## Quality Of Service
2014-12-04 10:25:29 -05:00
The quality of service modes used by the bridge are described here in
more detail.
2014-12-11 07:17:29 -05:00
### AT_MOST_ONCE
2014-12-04 10:25:29 -05:00
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 available for both durable and non-durable messages.
2014-12-11 07:17:29 -05:00
### DUPLICATES_OK
2014-12-04 10:25:29 -05:00
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 durable and non-durable messages.
2014-12-11 07:17:29 -05:00
### ONCE_AND_ONLY_ONCE
2014-12-04 10:25:29 -05:00
This QoS mode ensures messages will reach the destination from the
source once and only once. (Sometimes this mode is known as "exactly
2015-04-27 17:32:30 -04:00
once"). If both the source and the destination are on the same Apache ActiveMQ Artemis
2014-12-04 10:25:29 -05:00
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
2015-01-23 09:28:07 -05:00
is controlled by a JTA Transaction Manager which will need to be set
via the settransactionManager method on the Bridge.
2014-12-04 10:25:29 -05:00
This mode is only available for durable messages.
> **Note**
>
> For a specific application it may possible to provide once and only
> once semantics without using the ONCE\_AND\_ONLY\_ONCE QoS level. This
> can be done by using the DUPLICATES\_OK mode and then checking for
> duplicates at the destination and discarding them. Some JMS servers
> provide automatic duplicate message detection functionality, or 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 ONCE\_AND\_ONLY\_ONCE but
> may be a good choice depending on your specific application.
2014-12-11 07:17:29 -05:00
### Time outs and the JMS bridge
2014-12-04 10:25:29 -05:00
There is a possibility that the target or source server will not be
available at some point in time. If this occurs then the bridge will try
`Max Retries` to reconnect every `Failure Retry Interval` milliseconds
as specified in the JMS Bridge definition.
However since a third party JNDI is used, in this case the JBoss naming
server, it is possible for the JNDI lookup to hang if the network were
to disappear during the JNDI lookup. To stop this from occurring the
JNDI definition can be configured to time out if this occurs. To do this
set the `jnp.timeout` and the `jnp.sotimeout` on the Initial Context
definition. The first sets the connection timeout for the initial
connection and the second the read timeout for the socket.
> **Note**
>
> Once the initial JNDI connection has succeeded all calls are made
> using RMI. If you want to control the timeouts for the RMI connections
> then this can be done via system properties. JBoss uses Sun's RMI and
> the properties can be found
> [here](http://docs.oracle.com/javase/6/docs/technotes/guides/rmi/sunrmiproperties.html).
> The default connection timeout is 10 seconds and the default read
> timeout is 18 seconds.
If you implement your own factories for looking up JMS resources then
you will have to bear in mind timeout issues.
2014-12-11 07:17:29 -05:00
### Examples
2014-12-04 10:25:29 -05:00
2015-02-25 08:37:19 -05:00
Please see [the examples chapter ](examples.md ) which shows how to configure and use a JMS Bridge with
2014-12-04 10:25:29 -05:00
JBoss AS to send messages to the source destination and consume them
2015-02-25 08:37:19 -05:00
from the target destination and how to configure and use a JMS Bridge between
2015-04-27 17:32:30 -04:00
two standalone Apache ActiveMQ Artemis servers.