Sun GlassFish Message Queue 4.4 Administration Guide

JMS Bridge Features

To provide flexible, high-performing message transfer between mapped destinations, a JMS bridge offers these features:

Pooled, Shared, and Dedicated Connections

A JMS bridge uses the connection factories configured for link sources, link targets, and DMQs to create connections to the Message Queue broker and the external JMS provider. When making connections, the JMS bridge follows these rules to determine whether to use a pooled connection, a shared connection, or a dedicated connection:

Transactional Message Transfer

Each JMS bridge includes a built-in XA transaction coordinator that enables its links to be configured as "transacted" such that message transfer from the source to the target is done in a XA distributed transaction.

For a link to be configured as transacted, both the link source and link target must specify connection factories of type javax.jms.XAConnectionFactory.

The built-in XA transaction coordinator logs transaction records using the same type of store as the Message Queue broker in which the JMS bridge resides. For file-based transaction logging, the transaction log for a JMS bridge is located at:


IMQ_VARHOME/instances/brokerInstance/bridges/bridgeName/txlog.bridgeNane

For JDBC-based transaction logging, the built-in XA transaction coordinator uses the same JDBC store as the Message Queue broker in which the JMS bridge resides.

Resource Manager Registration and The Built-In XA Transaction Coordinator

When a JMS bridge is started, it registers all its Resource Managers (RMs) with the built-in XA transaction coordinator so that the coordinator can identify specific RMs during recovery.

For connection factories, the JMS bridge only registers the factory as an RM if the factory's multi-rm attribute value is false. A connection factory with a multi-rm attribute value of true should have each of its RMs identified by a connection factory whose multi-rmattribute value of false in order to participate in transactional message transfer. Additionally, the JMS bridge uses a connection factory's ref-name attribute value as part of its RM name when registering RMs with the built-in XA transaction coordinator, so this attribute should not be changed between restarts of the bridge if transaction recovery is desired between restarts.

JMS Bridges in High Availability (HA) Broker Clusters

Message Queue supports JMS bridges in HA broker clusters, but some special constraints apply due to the inherent nature of HA broker clusters:

To ensure that bridges in the cluster have the same configuration across all brokers in the cluster, all bridge-related broker properties except for imq.bridge.activelist should be specified in the centralized cluster properties file defined by the imq.cluster.url broker property.

A table in the cluster's HA store is used to maintain a consistent record of JMS bridge ownership by the brokers in the cluster.

During broker startup, the JMS bridge service compares the broker's imq.bridge.activelist property value to this table's entries before starting any JMS bridges, with the following consequences:

Message Transformation During Message Delivery

A link target or a DMQ can specify a message transformer to process the message before it is delivered to the target destination or DMQ destination. This message transformer must be a Java class that extends the Message Queue bridge com.sun.messaging.bridge.service.MessageTransformer abstract class and has javax.jms.Message as its formal type parameters. To specify a message transformer, set the message-transformer-class attribute of a link target or a DMQ to the fully qualified class name of the Java class.

During message transfer processing, the JMS message to be transferred to a target, plus any property subelements of the link's target element or the dmq element, are passed to the message transformer's MessageTransformer.transform() method, and the returned JMS message is sent to the target destination.

JMSReplyTo Header Processing

In a JMS message, the JMSReplyTo header value is provider dependent. Therefore, unless both the source provider and target provider are Message Queue, the JMS bridge sets an existing JMSReplyTo header to a null value before passing the message to a link target or, if specified, the message transformer for the link target.

This default behavior can be overridden by setting the retain-replyto attribute of the link's target element to true. Overriding the default behavior is useful when:

Dead Message Queue (DMQ) Processing

Each JMS bridge includes a built-in Dead Message Queue (DMQ) named built-in-dmq. This DMQ is a designated Queue destination named imq.bridge.jms.dmq in the broker hosting the JMS bridge. You can also configure additional DMQs for the JMS bridge, in which case the DMQ can use any JMS destination in any configured JMS provider.


Note –

In a production environment, the built-in DMQ, imq.bridge.jms.dmq, should be administratively created and have its access controls set appropriately before starting a broker that uses JMS bridge services.


When a DMQ uses Message Queue as the JMS provider, it can be configured such that messages sent to it will automatically be transferred to the Message Queue broker's DMQ. To do so, set physical destination properties of the JMS bridge's DMQ as follows:


useDMQ=true
limitBehavior=REMOVE_OLDEST
maxNumMsgs=0

When a message is sent to the DMQ, the JMS bridge follows this sequence with the built-in DMQ first:

  1. The bridge creates a new DMQ javax.jms.ObjectMessage object and sets the properties listed in Table 12–1 to the ObjectMessage.

  2. If the DMQ has defined a message transformer, the original message is passed to the transformer's MessageTransformer.transform() method.

  3. The body of the javax.jms.ObjectMessage is set to the transformed message (or original message if no message transformer is defined). If this action fails (usually because the message is not serializable), the body of the ObjectMessage is instead set to the toString() value of the original message.

  4. The javax.jms.ObjectMessage is sent (up to send-attempts times) to the DMQ's destination with a timeToLive value based on the DMQ's time-to-live-in-millis attribute and with the same JMSDeliveryMode and JMSPriority as the original message.

  5. If sending the message fails, the bridge repeats Steps 2 through 4 for each DMQ defined in the bridge's XML configuration file in the order they appear in the file, stopping when a send attempt succeeds, unless it is the built-in DMQ.

  6. If the message can't be sent to any DMQ, a log message is generated, containing the properties and headers of the original message and the properties set in Step 1.

Table 12–1 DMQ Message Propeties

Property 

Type 

Description 

JMS_SUN_JMSBRIDGE_DMQ_BODY_TRUNCATED

String 

If unable to set the original message or the transformed message (if the DMQ has a message transformer) to the body of the DMQ ObjectMessage. In that case the message's toString() is set to the body of the DMQ ObjectMessage.

JMS_SUN_JMSBRIDGE_DMQ_EXCEPTION

String 

The Exception.getMessage() if exception occurred or detailed comments on the failure; null if none.

JMS_SUN_JMSBRIDGE_DMQ_REASON

String 

One of: MESSAGE_EXPIRED, SEND_FAILURE, ACK_FAILURE, TRANSFORM_FAILURE, COMMIT_FAILURE.

JMS_SUN_JMSBRIDGE_DMQ_TIMESTAMP

String 

The timestamp when the JMS bridge sends the message to the DMQ. 

JMS_SUN_JMSBRIDGE_SOURCE_CORRELATIONID

String 

The original message's getJMSCorrelationID().

JMS_SUN_JMSBRIDGE_SOURCE_DESTINATION

String 

The original message's source destination name. 

JMS_SUN_JMSBRIDGE_SOURCE_JMSTYPE

String 

The original message's getJMSType().

JMS_SUN_JMSBRIDGE_SOURCE_MESSAGEID

String 

The orginal message's getJMSMessageID(), or null if not available.

JMS_SUN_JMSBRIDGE_SOURCE_PROVIDER

String 

The ConnectionMetaData.getJMSProviderName of the connection the original message was received on; if not available, the source connection factory's getClass().getName().

JMS_SUN_JMSBRIDGE_SOURCE_TIMESTAMP

Long 

The original message's getJMSTimestamp().

JMS_SUN_JMSBRIDGE_TARGET_DESTINATION

String 

The name of the target destination where the original message was intended to send to. 

JMS_SUN_JMSBRIDGE_TARGET_PROVIDER

String 

The ConnectionMetaData.getJMSProviderName of the connection the original message was intended to send on; if not available, the target connection factory's getClass().getName().