18.8. Configuration

18.8.1. Configure the JMS Server

To configure the JMS Server for HornetQ, edit the server configuration file. The server configuration is contained in the EAP_HOME/domain/configuration/domain.xml file for domain servers, or in the EAP_HOME/standalone/configuration/standalone-full.xml file for standalone servers.
The <subsystem xmlns="urn:jboss:domain:messaging:1.4"> element in the server configuration file contains all JMS configuration. Add any JMS ConnectionFactory, Queue, or Topic instances required for the JNDI.
  1. Enable the JMS subsystem in JBoss EAP 6.

    Within the <extensions> element, verify that the following line is present and is not commented out:
    <extension module="org.jboss.as.messaging"/>
  2. Add the basic JMS subsystem.

    If the Messaging subsystem is not present in your configuration file, add it.
    1. Look for the <profile> which corresponds to the profile you use, and locate its <subsystems> tag.
    2. Paste the following XML immediately following the <profile> tag.
      <subsystem xmlns="urn:jboss:domain:messaging:1.4">
          <hornetq-server>
          <!-- ALL XML CONFIGURATION IS ADDED HERE -->
          </hornetq-server>
      </subsystem>
      All further configuration will be added to the empty line above.
  3. Add basic configuration for JMS.

    Add the following XML in the blank line after the <subsystem xmlns="urn:jboss:domain:messaging:1.4"><hornetq-server> tag:
    <journal-min-files>2</journal-min-files>
    <journal-type>NIO</journal-type>
    <persistence-enabled>true</persistence-enabled>
    Customize the values above to meet your needs.

    Warning

    The value of journal-file-size must be higher than or equal to min-large-message-size (100KiB by default), or the server won't be able to store the message.
  4. Add connection factory instances to HornetQ

    The client uses a JMS ConnectionFactory object to make connections to the server. To add a JMS connection factory object to HornetQ, include a single <jms-connection-factories> tag and <connection-factory> element for each connection factory as follows:
      <jms-connection-factories>
        <connection-factory name="InVmConnectionFactory">
            <connectors>
                <connector-ref connector-name="in-vm"/>
            </connectors>
            <entries>
                <entry name="java:/ConnectionFactory"/>
            </entries>
        </connection-factory>
        <connection-factory name="RemoteConnectionFactory">
            <connectors>
                <connector-ref connector-name="netty"/>
            </connectors>
            <entries>
                <entry name="java:jboss/exported/jms/RemoteConnectionFactory"/>
            </entries>
        </connection-factory>
        <pooled-connection-factory name="hornetq-ra">
            <transaction mode="xa"/>
            <connectors>
                <connector-ref connector-name="in-vm"/>
            </connectors>
            <entries>
                <entry name="java:/JmsXA"/>
            </entries>
        </pooled-connection-factory>
    </jms-connection-factories>
    
  5. Configure the netty connectors and acceptors

    This JMS connection factory uses netty acceptors and connectors. These are references to connector and acceptor objects deployed in the server configuration file. The connector object defines the transport and parameters used to connect to the HornetQ server. The acceptor object identifies the type of connections accepted by the HornetQ server.
    To configure the netty connectors, include the following settings:
    <connectors>
        <netty-connector name="netty" socket-binding="messaging"/>
        <netty-connector name="netty-throughput" socket-binding="messaging-throughput">
            <param key="batch-delay" value="50"/>
        </netty-connector>
        <in-vm-connector name="in-vm" server-id="0"/>
    </connectors>
    
    To configure the netty acceptors, include the following settings:
    <acceptors>
        <netty-acceptor name="netty" socket-binding="messaging"/>
        <netty-acceptor name="netty-throughput" socket-binding="messaging-throughput">
            <param key="batch-delay" value="50"/>
            <param key="direct-deliver" value="false"/>
        </netty-acceptor>
        <in-vm-acceptor name="in-vm" server-id="0"/>
    </acceptors>
    
  6. Review the configuration

    If you have followed the previous steps, your messaging subsystem should look like the following:
    <subsystem xmlns="urn:jboss:domain:messaging:1.4">
        <hornetq-server>
            <journal-min-files>2</journal-min-files>
            <journal-type>NIO</journal-type>
            <persistence-enabled>true</persistence-enabled>
            <jms-connection-factories>
                <connection-factory name="InVmConnectionFactory">
                    <connectors>
                        <connector-ref connector-name="in-vm"/>
                    </connectors>
                    <entries>
                        <entry name="java:/ConnectionFactory"/>
                    </entries>
                </connection-factory>
                <connection-factory name="RemoteConnectionFactory">
                    <connectors>
                        <connector-ref connector-name="netty"/>
                    </connectors>
                    <entries>
                        <entry name="java:jboss/exported/jms/RemoteConnectionFactory"/>
                    </entries>
                </connection-factory>
                <pooled-connection-factory name="hornetq-ra">
                    <transaction mode="xa"/>
                    <connectors>
                        <connector-ref connector-name="in-vm"/>
                    </connectors>
                    <entries>
                        <entry name="java:/JmsXA"/>
                    </entries>
                </pooled-connection-factory>
            </jms-connection-factories>
            <connectors>
                <netty-connector name="netty" socket-binding="messaging"/>
                <netty-connector name="netty-throughput" socket-binding="messaging-throughput">
                    <param key="batch-delay" value="50"/>
                </netty-connector>
                <in-vm-connector name="in-vm" server-id="0"/>
            </connectors>	
            <acceptors>
                <netty-acceptor name="netty" socket-binding="messaging"/>
                <netty-acceptor name="netty-throughput" socket-binding="messaging-throughput">
                    <param key="batch-delay" value="50"/>
                    <param key="direct-deliver" value="false"/>
                </netty-acceptor>
                <in-vm-acceptor name="in-vm" server-id="0"/>
            </acceptors>
        </hornetq-server>
    </subsystem>
    
  7. Configure the socket binding groups

    The netty connectors reference the messaging and messaging-throughput socket bindings. The messaging socket binding uses port 5445, and the messaging-throughput socket binding uses port 5455. The <socket-binding-group> tag is in a separate section of the server configuration file. Ensure the following socket bindings are present in the <socket-binding-groups> element:
    <socket-binding-group name="standard-sockets" default-interface="public" port-offset="${jboss.socket.binding.port-offset:0}">
        ...
        <socket-binding name="messaging" port="5445"/>
        <socket-binding name="messaging-throughput" port="5455"/>
        ...
      </socket-binding-group>
    
  8. Add queue instances to HornetQ

    There are 4 ways to setup the queue instances (or JMS destinations) for HornetQ.
    • Use the Management Console
      To use the Management Console, the server must have been started in the Message-Enabled mode. You can do this by using the -c option and forcing the use of the standalone-full.xml (for standalone servers) configuration file. For example, in the standalone mode, the following will start the server in a message enabled mode
      ./standalone.sh -c standalone-full.xml
      Once the server has started, logon to the Management Console and select the Configuration tab. Expand the Subsystems menu, then expand the Messaging menu and click Destinations. Next to Default on the JMS Messaging Provider table, click View, and then click Add to enter details of the JMS destination.
    • Use the Management CLI:
      First, connect to the Management CLI:
       bin/jboss-cli.sh --connect
      Next, change into the messaging subsystem:
      cd /subsystem=messaging/hornetq-server=default
      Finally, execute an add operation, replacing the examples values given below with your own:
      ./jms-queue=testQueue:add(durable=false,entries=["java:jboss/exported/jms/queue/test"])
    • Create a JMS configuration file and add it to the deployments folder
      Start by creating a JMS configuration file: example-jms.xml. Add the following entries to it, replacing the values with your own:
      <?xml version="1.0" encoding="UTF-8"?>				  	  <messaging-deployment xmlns="urn:jboss:messaging-deployment:1.0">
          <hornetq-server>
              <jms-destinations>
                  <jms-queue name="testQueue">
                      <entry name="queue/test"/>
                      <entry name="java:jboss/exported/jms/queue/test"/>
                  </jms-queue>
                  <jms-topic name="testTopic">
                      <entry name="topic/test"/>
                      <entry name="java:jboss/exported/jms/topic/test"/>
                  </jms-topic>
              </jms-destinations>
          </hornetq-server>
      </messaging-deployment>
      Save this file in the deployments folder and do a deployment.
    • Add entries in the JBoss EAP 6 configuration file.
      Queue attributes can be set in one of two ways.
      • Configuration at a JMS level
        The following shows a queue predefined in the standalone.xml or domain.xml configuration file.
        <jms-queue name="selectorQueue">
        	<entry name="/queue/selectorQueue"/>
        	<selector string="color='red'"/>
        	<durable>true</durable>
        </jms-queue>
        This name attribute of queue defines the name of the queue. When we do this at a jms level we follow a naming convention so the actual name of the core queue will be jms.queue.selectorQueue.
        The entry element configures the name that will be used to bind the queue to JNDI. This is a mandatory element and the queue can contain multiple of these to bind the same queue to different names.
        The selector element defines what JMS message selector the predefined queue will have. Only messages that match the selector will be added to the queue. This is an optional element with a default of null when omitted.
        The durable element specifies whether the queue will be persisted. This again is optional and defaults to true if omitted.
      • Configuration at a core level
        A queue can be predefined at a core level in the standalone.xml or domain.xml file. For example:
        <core-queues>
        	<queue name="jms.queue.selectorQueue">
        		<address>jms.queue.selectorQueue</address>
        		<filter string="color='red'"/>
        		<durable>true</durable>
        	</queue>
        </core-queues>
  9. Perform additional configuration

    If you need additional settings, review the DTD in EAP_HOME/docs/schema/jboss-as-messaging_1_4.xsd.

18.8.2. Configure JMS Address Settings

The JMS subsystem has several configurable options which control aspects of how and when a message is delivered, how many attempts should be made, and when the message expires. These configuration options all exist within the <address-settings> configuration element.
A common feature of address configurations is the syntax for matching multiple addresses, also known as wild cards.
Wildcard Syntax

Address wildcards can be used to match multiple similar addresses with a single statement, similar to how many systems use the asterisk ( *) character to match multiple files or strings with a single search. The following characters have special significance in a wildcard statement.

Table 18.5. JMS Wildcard Syntax

Character Description
. (a single period) Denotes the space between words in a wildcard expression.
# (a pound or hash symbol) Matches any sequence of zero or more words.
* (an asterisk) Matches a single word.

Table 18.6. JMS Wildcard Examples

Example Description
news.europe.#
Matches news.europe, news.europe.sport, news.europe.politic, but not news.usa or europe.
news.*
Matches news.europe but not news.europe.sport.
news.*.sport
Matches news.europe.sport and news.usa.sport, but not news.europe.politics.

Example 18.2. Default Address Setting Configuration

The values in this example are used to illustrate the rest of this topic.
<address-settings>
    <!--default for catch all-->
    <address-setting match="#">
        <dead-letter-address>jms.queue.DLQ</dead-letter-address>
        <expiry-address>jms.queue.ExpiryQueue</expiry-address>
        <redelivery-delay>0</redelivery-delay>
        <max-size-bytes>10485760</max-size-bytes>
        <address-full-policy>BLOCK</address-full-policy>
        <message-counter-history-day-limit>10</message-counter-history-day-limit>
    </address-setting>
</address-settings>

Table 18.7. Description of JMS Address Settings

Element Description Default Value Type
address-full-policy
Determines what happens when an address where max-size-bytes is specified becomes full.
PAGE
STRING
dead-letter-address
If a dead letter address is specified, messages are moved to the dead letter address if max-delivery-attempts delivery attempts have failed. Otherwise, these undelivered messages are discarded. Wildcards are allowed.
jms.queue.DLQ
STRING
expiry-address
If the expiry address is present, expired messages are sent to the address or addresses matched by it, instead of being discarded. Wildcards are allowed.
jms.queue.ExpiryQueue
STRING
last-value-queue
Defines whether a queue only uses last values or not.
false
BOOLEAN
max-delivery-attempts
The maximum number of times to attempt to re-deliver a message before it is sent to dead-letter-address or discarded.
10
INT
max-size-bytes
The maximum bytes size.
10485760L
LONG
message-counter-history-day-limit
Day limit for the message counter history.
10
INT
page-max-cache-size
The number of page files to keep in memory to optimize IO during paging navigation.
5
INT
page-size-bytes
The paging size.
5
INT
redelivery-delay
Time to delay between re-delivery attempts of messages, expressed in milliseconds. If set to 0, re-delivery attempts occur indefinitely.
0L
LONG
redistribution-delay
Defines how long to wait when the last consumer is closed on a queue before redistributing any messages.
-1L
LONG
send-to-dla-on-no-route
A parameter for an address that sets the condition of a message not routed to any queues to instead be sent the to the dead letter address (DLA) indicated for that address.
false
BOOLEAN
slow-consumer-threshold
The minimum rate of message consumption allowed before a consumer is considered "slow." Measured in messages-per-second.
-1
INT
slow-consumer-policy
What should happen when a slow consumer is detected. KILL will kill the consumer's connection (which will obviously impact any other client threads using that same connection). NOTIFY will send a CONSUMER_SLOW management notification which an application could receive and take action with.
STRING
slow-consumer-check-period
How often to check for slow consumers on a particular queue. Measured in seconds.
5
INT
  • Configure Address Setting and Pattern Attributes

    Choose either the Management CLI or the Management Console to configure your pattern attributes as required.
    • Configure the Address Settings Using the Management CLI

      Use the Management CLI to configure address settings.
      1. Add a New Pattern

        Use the add operation to create a new address setting if required. You can run this command from the root of the Management CLI session, which in the following examples creates a new pattern titled patternname, with a max-delivery-attempts attribute declared as 5. The examples for both Standalone Server and a Managed Domain editing on the full profile are shown.
        [standalone@localhost:9999 /] /subsystem=messaging/hornetq-server=default/address-setting=patternname/:add(max-delivery-attempts=5)
        [domain@localhost:9999 /] /profile=full/subsystem=messaging/hornetq-server=default/address-setting=patternname/:add(max-delivery-attempts=5)
      2. Edit Pattern Attributes

        Use the write operation to write a new value to an attribute. You can use tab completion to help complete the command string as you type, as well as to expose the available attributes. The following example updates the max-delivery-attempts value to 10
        [standalone@localhost:9999 /] /subsystem=messaging/hornetq-server=default/address-setting=patternname/:write-attribute(name=max-delivery-attempts,value=10)
        [domain@localhost:9999 /] /profile=full/subsystem=messaging/hornetq-server=default/address-setting=patternname/:write-attribute(name=max-delivery-attempts,value=10)
      3. Confirm Pattern Attributes

        Confirm the values are changed by running the read-resource operation with the include-runtime=true parameter to expose all current values active in the server model.
        [standalone@localhost:9999 /] /subsystem=messaging/hornetq-server=default/address-setting=patternname/:read-resource
        [domain@localhost:9999 /] /profile=full/subsystem=messaging/hornetq-server=default/address-setting=patternname/:read-resource
    • Configure the Address Settings Using the Management Console

      Use the Management Console to configure address settings.
      1. Log into the Management Console of your Managed Domain or Standalone Server.
      2. Select the Configuration tab at the top of the screen. For Domain mode, select a profile from the Profile menu at the top left. Only the full and full-ha profiles have the messaging subsystem enabled.
      3. Expand the Messaging menu, and select Destinations.
      4. A list of JMS Providers is shown. In the default configuration, only one provider, called default, is shown. Click View to view the detailed settings for this provider.
      5. Click the Address Settings tab. Either add a new pattern by clicking Add, or select an existing pattern and clickEdit to update the settings.
      6. If you are adding a new pattern, the Pattern field refers to the match parameter of the address-setting element. You can also edit the Dead Letter Address, Expiry Address, Redelivery Delay, and Max Delivery Attempts. Other options need to be configured using the Management CLI.

18.8.3. Temporary Queues and Runtime Queues

While designing request-reply scenarios that involve a client sending a request and waiting for a reply, an addressable issue is whether each runtime instance of the client has a dedicated queue for its replies or whether the runtime instances access a shared queue, selecting their specific reply message based on an appropriate attribute. If multiple queues are required, then we need the ability to create a queue dynamically for use by the client, and JMS provides this facility using the concept of temporary queues. The TemporaryQueue is created on request by the QueueSession and exists until it is deleted or for the life of the QueueConnection (i.e. until the QueueConnection is closed). This means that although the TemporaryQueue is created by a specific QueueSession, it can be reused by any other QueueSessions created from the same QueueConnection to create a QueueReceiver.
The tradeoff between having a shared queue for replies or having individual temporary queues is influenced by the potential number of active client instances. With a shared-queue approach, at some provider-specific threshold, contention for access to the queue can become a concern. This has to be contrasted against the additional overhead associated with the provider creating queue storage at runtime and the impact on machine memory of having to host a potentially large number of temporary queues.

Note

The creation of temporary queues is accomplished with the createTemporaryQueue method. Similarly, the creation of temporary topics is accomplished with the createTemporaryTopic method. Both of these methods are for creating the physical queue and physical topic.
If there are messages that have been received but not acknowledged when a QueueSession terminates, these messages will be retained and redelivered when a consumer next accesses the queue. A QueueSession is used for creating Point-to-Point specific objects. In general, use the Session object. The QueueSession is used to support existing code. Using the Session object simplifies the programming model, and allows transactions to be used across the two messaging domains.
A TopicSession is used for creating Pub/Sub specific objects. In general, use the Session object, and use TopicSession only to support existing code. Using the Session object simplifies the programming model, and allows transactions to be used across the two messaging domains.

18.8.4. Last-Value Queues

Last-Value queues are special queues which discard any messages when a newer message with the same value for a well-defined Last-Value property is put in the queue. In other words, a Last-Value queue only retains the last value. A typical example for Last-Value queue is for stock prices, where you are only interested by the latest value for a particular stock.
Configuring Last-Value Queues

Last-value queues are defined in the address-setting configuration:

<address-setting match="jms.queue.lastValueQueue">
	<last-value-queue>true</last-value-queue>
</address-setting>

Using Last-Value Property

The property name used to identify the last value is "_HQ_LVQ_NAME" (or the constant Message.HDR_LAST_VALUE_NAME from the Core API). For example, if two messages with the same value for the Last-Value property are sent to a Last-Value queue, only the latest message will be kept in the queue:

Example 18.3.  Send 1st message with Last-Value property set to STOCK_NAME

TextMessage message = session.createTextMessage("1st message with Last-Value property set");
message.setStringProperty("_HQ_LVQ_NAME", "STOCK_NAME");
producer.send(message);

Example 18.4.  Send 2nd message with Last-Value property set to STOCK_NAME

message = session.createTextMessage("2nd message with Last-Value property set");
message.setStringProperty("_HQ_LVQ_NAME", "STOCK_NAME");
producer.send(message);

Example 18.5.  Only the 2nd message will be received; it is the latest with the Last-Value property set:

TextMessage messageReceived = (TextMessage)messageConsumer.receive(5000);
System.out.format("Received message: %s\n", messageReceived.getText());

18.8.5. Core and JMS Destinations

HornetQ core does not have any concept of a JMS topic. A JMS topic is implemented in core as an address (the topic name) with zero or more queues bound to it. Each queue bound to that address represents a topic subscription. Likewise, a JMS queue is implemented as an address (the JMS queue name) but with one single queue bound to it which represents the JMS queue.
A JMS topic is the channel through which users subscribe to receive specific messages from a producer in the publish-and-subscribe model of JMS messaging.
A JMS queue is a channel through which users "pull" messages they want to receive using the Point-to-point (p2p) model, instead of automatically receiving messages on a particular topic. The producer submits messages to the queue, and recipients can browse the queue and decide which messages they wish to receive. In the p2p model, users can see the contents of the messages held in the queue before deciding whether or not to accept their delivery.
If you want to configure settings for a JMS Queue with the name orders.europe, you need to configure the corresponding core queue jms.queue.orders.europe:
<!-- expired messages in JMS Queue "orders.europe" will be sent to the JMS Queue "expiry.europe" -->
<address-setting match="jms.queue.orders.europe">
	<expiry-address>jms.queue.expiry.europe</expiry-address>
	...
</address-setting>

18.8.6. JMS Message Selectors

If your messaging application needs to filter the messages it receives, you can use a JMS API message selector, which allows a message consumer to specify the messages it is interested in. Message selectors assign the work of filtering messages to the JMS provider rather than to the application.
You can define your message selector as follows:
@MessageDriven(name = "MDBMessageSelectorExample", activationConfig =
{
   @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
   @ActivationConfigProperty(propertyName = "destination", propertyValue = "queue/testQueue"),
   @ActivationConfigProperty(propertyName = "messageSelector", propertyValue = "color = 'RED'")
})
@TransactionManagement(value= TransactionManagementType.CONTAINER)
@TransactionAttribute(value= TransactionAttributeType.REQUIRED)
public class MDBMessageSelectorExample implements MessageListener
{
   public void onMessage(Message message)....
}

18.8.7. Configure Messaging with HornetQ

The recommended method of configuring messaging in JBoss EAP 6 is in either the Management Console or Management CLI. You can make persistent changes with either of these management tools without needing to manually edit the standalone.xml or domain.xml configuration files. It is useful however to familiarize yourself with the messaging components of the default configuration files, where documentation examples using management tools give configuration file snippets for reference.

18.8.8. Enable Logging for HornetQ

You can enable logging for HornetQ in EAP 6.x using any of the following approaches:
  • Editing server configuration files (standalone-full.xml and standalone-full-ha.xml) manually
  • Editing server configuration files using the CLI

Procedure 18.1. Set HornetQ logging by editing server configuration files manually

  1. Open the server configuration file(s) for editing. For example standalone-full.xml and standalone-full-ha.xml
  2. Navigate to logging subsystem configuration in the file(s). The default configuration looks like this:
    <logger category="com.arjuna">
     <level name="TRACE"/>
    </logger>
    ...
    <logger category="org.apache.tomcat.util.modeler">
     <level name="WARN"/>
    </logger>
    ....
    
  3. Add the org.hornetq logger category along with the desired logging level as shown in the following example:
    <logger category="com.arjuna">
      <level name="TRACE"/>
    </logger>
    ...
    <logger category="org.hornetq">
      <level name="INFO"/>
    </logger>
    ....
    
Result

HornetQ logging is enabled and log messages are processed based on the configured log level.

Set HornetQ logging by editing server configuration files using the CLI

You can also use CLI to add the org.hornetq logger category along with the desired logging level to server configuration file(s). For more information see: Section 12.3.2, “Configure a Log Category in the CLI”

18.8.9. Configuring HornetQ Core Bridge

Example 18.6. Example configuration for HornetQ Core Bridge:

The values in this example are used to illustrate the rest of this topic.
<bridges>
  	<bridge name="myBridge">
        <queue-name>jms.queue.InQueue</queue-name>
        <forwarding-address>jms.queue.OutQueue</forwarding-address>
	<ha>true</ha>
        <reconnect-attempts>-1</reconnect-attempts>
        <use-duplicate-detection>true</use-duplicate-detection>
        <static-connectors>
        	<connector-ref>
                bridge-connector
                </connector-ref>
        </static-connectors>
        </bridge>
</bridges>

Table 18.8. HornetQ Core Bridge Attributes

Attribute Description
name
All bridges must have a unique name on the server.
queue-name
This mandatory parameter is the unique name of the local queue that the bridge consumes from. The queue must already exist by the time the bridge is instantiated at start-up.
forwarding-address
This is the address on the target server that the message will be forwarded to. If a forwarding address is not specified, then the original address of the message will be retained.
ha
This optional parameter determines whether or not this bridge should support high availability. true means it will connect to any available server in a cluster and support failover. The default value is false.
reconnect-attempts
This optional parameter determines the total number of reconnect attempts the bridge should make before giving up and shutting down. A value of -1 signifies an unlimited number of attempts. The default value is -1.
use-duplicate-detection
This optional parameter determines whether the bridge will automatically insert a duplicate id property into each message that it forwards.
static-connectors
The static-connectors is a list of connector-ref elements pointing to connector elements defined elsewhere. A connector encapsulates knowledge of what transport to use (TCP, SSL, HTTP etc) as well as the server connection parameters (host, port etc).

18.8.10. Configuring JMS Bridge

HornetQ includes a fully functional JMS message bridge. The function of this 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 is unreliable.
A bridge can be deployed as a standalone application, with HornetQ standalone server or inside a JBoss AS instance. The source and the target can be located in the same virtual machine or another one.

Example 18.7. Example configuration for JMS Bridge:

The values in this example are used to illustrate the rest of this topic.
<subsystem>
  <subsystem xmlns="urn:jboss:domain:messaging:1.3">
             <hornetq-server>
             ...
             </hornetq-server>

             <jms-bridge name="myBridge">
                <source>
                    <connection-factory name="ConnectionFactory"/>
                    <destination name="jms/queue/InQueue"/>
                </source>
                <target>
                    <connection-factory name="jms/RemoteConnectionFactory"/>
                    <destination name="jms/queue/OutQueue"/>
                    <context>
                        <property key="java.naming.factory.initial" value="org.jboss.naming.remote.client.InitialContextFactory"/>
                        <property key="java.naming.provider.url" value="remote://192.168.40.1:4447"/>
                    </context>
                </target>
                <quality-of-service>AT_MOST_ONCE</quality-of-service>
                <failure-retry-interval>1000</failure-retry-interval>
                <max-retries>-1</max-retries>
                <max-batch-size>10</max-batch-size>
                <max-batch-time>100</max-batch-time>
                <add-messageID-in-header>true</add-messageID-in-header>
            </jms-bridge>
...
</subsystem>

Warning

It is recommended to use a connection factory that does not set the reconnect-attempts parameter (or sets it to 0), as JMS Bridge has its own max-retries parameter to handle reconnection. This is to avoid a potential collision that may result in longer reconnection times.

Table 18.9. HornetQ Core JMS Attributes

Attribute Description
name
All bridges must have a unique name on the server.
source connection-factory
This injects the SourceCFF bean (also defined in the beans file). This bean creates the source ConnectionFactory.
source destination name
This injects the SourceDestinationFactory bean (also defined in the beans file). This bean creates the source Destination.
target connection-factory
This injects the TargetCFF bean (also defined in the beans file). This bean creates the target ConnectionFactory.
target destination name
This injects the TargetDestinationFactory bean (also defined in the beans file). This bean creates the target Destination.
quality-of-service
This parameter represents the required quality of service mode. The possible values are: AT_MOST_ONCE, DUPLICATES_OK, ONCE_AND_ONLY_ONCE
failure-retry-interval
This represents the amount of time in milliseconds 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 attempts 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'.
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.
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 HORNETQ_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.
When you receive the message you can send a response using the correlation id of the first message id, so when the original sender receives the message, it is easy to correlate.

Note

When shutting down a server that has a deployed JMS bridge with quality-of-service attribute set to ONCE_AND_ONLY_ONCE, shut the server down with the JMS bridge first to avoid unexpected exceptions.
For more complete instructions, see Section 18.13.2, “Create a JMS Bridge” .

18.8.11. Configure Delayed Redelivery

Introduction

Delayed redelivery is defined in the <redelivery-delay> element, which is a child element of the <address-setting> configuration element in the Java Messaging Service (JMS) subsystem configuration.

<!-- delay redelivery of messages for 5s -->
<address-setting match="jms.queue.exampleQueue">
  <redelivery-delay>5000</redelivery-delay>
</address-setting>
If a redelivery delay is specified, the JMS system waits for the duration of this delay before redelivering the messages. If <redelivery-delay> is set to 0, there is no redelivery delay. Address wildcards can be used on the match attribute of <address-match> element to configure the redelivery delay for addresses that match the wildcard.

18.8.12. Configure Dead Letter Addresses

Introduction

A dead letter address is defined in the <address-setting> element of the Java Messaging Service (JMS) subsystem configuration.

<!-- undelivered messages in exampleQueue will be sent to the dead letter address 
deadLetterQueue after 3 unsuccessful delivery attempts
-->
<address-setting match="jms.queue.exampleQueue">
  <dead-letter-address>jms.queue.deadLetterQueue</dead-letter-address>
  <max-delivery-attempts>3</max-delivery-attempts>
</address-setting>
If a <dead-letter-address> is not specified, messages are removed after trying to deliver <max-delivery-attempts> times. By default, messages delivery is attempted 10 times. Setting <max-delivery-attempts> to -1 allows infinite redelivery attempts. For example, a dead letter can be set globally for a set of matching addresses and you can set <max-delivery-attempts> to -1 for a specific address setting to allow infinite redelivery attempts only for this address. Address wildcards can also be used to configure dead letter settings for a set of addresses.

18.8.13. Configure Message Expiry Addresses

Introduction

Message expiry addresses are defined in the address-setting configuration of the Java Messaging Service (JMS). For example:

<!-- expired messages in exampleQueue will be sent to the expiry address expiryQueue -->
<address-setting match="jms.queue.exampleQueue">
  <expiry-address>jms.queue.expiryQueue</expiry-address>
</address-setting>
If messages are expired and no expiry address is specified, messages are simply removed from the queue and dropped. Address wildcards can also be used to configure specific ranges of an expiry address for a set of addresses. See Section 18.8.2, “Configure JMS Address Settings” for the JMX wildcard syntax and examples.

18.8.14. Flow Control

Flow control is used to limit the flow of data between a client and server, or a server and another server, in order to prevent the client or the server being overloaded with data.
  • Consumer Flow Control - controls the flow of data between the server and the client as the client consumes messages. For performance reasons clients normally buffer messages before delivering to the consumer via the receive() method or asynchronously via a message listener.
    Rate-limited flow control: It is possible to control the rate at which a consumer can consume messages. This is a form of throttling and can be used to ensure that a consumer never consumes messages at a rate faster than the rate specified. The rate must be a positive integer to enable this functionality and is the maximum desired message consumption rate specified in units of messages per second. Setting this to -1 disables rate limited flow control. The default value is -1.

    Example 18.8. Rate limited flow control using JMS

    If JNDI is used to look up the connection factory, the max rate can be configured in standalone.xml or domain.xml:
    <connection-factory name="ConnectionFactory">
    	<connectors>
    		<connector-ref connector-name="netty-connector"/>
    	</connectors>
      <entries>
      	<entry name="ConnectionFactory"/>
      </entries>
      <!-- We limit consumers created on this connection factory to consume messages at a maximum rate of 10 messages per sec -->
    	<consumer-max-rate>10</consumer-max-rate>
    </connection-factory>
    If the connection factory is directly instantiated, the max rate size can be set via the HornetQConnectionFactory.setConsumerMaxRate(int consumerMaxRate) method.
  • Producer flow control - limits the amount of data sent from a client to a server to prevent the server being overwhelmed.
    Window based flow control: HornetQ producers, by default, can only send messages to an address as long as they have sufficient credits to do so. The amount of credits required to send a message is given by the size of the message. As producers run low on credits they request more from the server, when the server sends them more credits they can send more messages. The amount of credits a producer requests in one go is known as the window size.

    Example 18.9. Producer window size flow control using JMS

    If JNDI is used to look up the connection factory, the producer window size can be configured in standalone.xml or domain.xml:
    <connection-factory name="ConnectionFactory">
       <connectors>
          <connector-ref connector-name="netty-connector"/>
       </connectors>
       <entries>
          <entry name="ConnectionFactory"/>
       </entries>
       <producer-window-size>10</producer-window-size>
    </connection-factory>
    If the connection factory is directly instantiated, the producer window size can be set via the HornetQConnectionFactory.setProducerWindowSize(int producerWindowSize) method.

18.8.15. Reference for HornetQ Configuration Attributes

The JBoss EAP 6 implementation of HornetQ exposes the following attributes for configuration. You can use the Management CLI to show the configurable or viewable attributes with the read-resource operation.

Example 18.10. Use read-resource to show attributes

[standalone@localhost:9999 /] /subsystem=messaging/hornetq-server=default:read-resource

Table 18.10. HornetQ Attributes

Attribute Default Value Type Description
allow-failback true BOOLEAN Whether this server will automatically shutdown if the original live server comes back up
async-connection-execution-enabled true BOOLEAN Whether incoming packets on the server must be handed off to a thread from the thread pool for processing
address-setting An address setting defines some attributes that are defined against an address wildcard rather than a specific queue
acceptor An acceptor defines a way in which connections can be made to the HornetQ server
backup-group-name STRING The name of a set of live/backups that must replicate with each other
backup false BOOLEAN Whether this server is a backup server
check-for-live-server false BOOLEAN Whether a replicated live server must check the current cluster to see if there is already a live server with the same node ID
clustered false BOOLEAN [Deprecated] Whether the server is clustered
cluster-password CHANGE ME!! STRING The password used by cluster connections to communicate between the clustered nodes
cluster-user HORNETQ.CLUSTER.ADMIN.USER STRING The user used by cluster connections to communicate between the clustered nodes
cluster-connection Cluster connections group servers into clusters so that messages can be load balanced between the nodes of the cluster
create-bindings-dir true BOOLEAN Whether the server must create the bindings directory on start up
create-journal-dir true BOOLEAN Whether the server must create the journal directory on start up
connection-ttl-override -1L LONG If set, this will override how long (in ms) to keep a connection alive without receiving a ping
connection-factory Defines a connection factory
connector A connector can be used by a client to define how it connects to a server
connector-service
divert A messaging resource that allows you to transparently divert messages routed to one address to some other address, without making any changes to any client application logic
discovery-group Multicast group to listen to receive broadcast from other servers announcing their connectors
failback-delay 5000 LONG How long to wait before failback occurs on live server restart
failover-on-shutdown false BOOLEAN Whether this backup server (if it is a backup server) must come live on a normal server shutdown
grouping-handler Makes decisions about which node in a cluster must handle a message with a group id assigned
id-cache-size 20000 INT The size of the cache for pre-creating message IDs
in-vm-acceptor Defines a way in which in-VM connections can be made to the HornetQ server
in-vm-connector Used by an in-VM client to define how it connects to a server
jmx-domain org.hornetq STRING The JMX domain used to register internal HornetQ MBeans in the MBeanServer
jmx-management-enabled false BOOLEAN Whether HornetQ must expose its internal management API via JMX. This is not recommended, as accessing these MBeans can lead to inconsistent configuration
journal-buffer-size 501760 (490KiB) LONG The size of the internal buffer on the journal
journal-buffer-timeout 500000 (0.5 milliseconds) for ASYNCIO journal and 3333333 (3.33 milliseconds) for NIO journal LONG The timeout (in nanoseconds) used to flush internal buffers on the journal
journal-compact-min-files 10 INT The minimal number of journal data files before we can start compacting
journal-compact-percentage 30 INT The percentage of live data on which we consider compacting the journal
journal-file-size 10485760 LONG The size (in bytes) of each journal file
journal-max-io 1 INT The maximum number of write requests that can be in the AIO queue at any one time. The default value changes to 500 when ASYNCIO journal is used
journal-min-files 2 INT How many journal files to pre-create
journal-sync-non-transactional true BOOLEAN Whether to wait for non transaction data to be synced to the journal before returning a response to the client
journal-sync-transactional true BOOLEAN Whether to wait for transaction data to be synchronized to the journal before returning a response to the client
journal-type ASYNCIO String The type of journal to use. This attribute can take the values "ASYNCIO" or "NIO"
jms-topic Defines a JMS topic
live-connector-ref reference STRING [Deprecated] The name of the connector used to connect to the live connector. If this server is not a backup that uses shared nothing HA, it's value is "undefined"
log-journal-write-rate false BOOLEAN Whether to periodically log the journal's write rate and flush rate
mask-password true BOOLEAN  
management-address jms.queue.hornetq.management STRING Address to send management messages to
management-notification-address hornetq.notifications STRING The name of the address that consumers bind to in order to receive management notifications
max-saved-replicated-journal-size 2 INT The maximum number of backup journals to keep after failback occurs
memory-measure-interval -1 LONG Frequency to sample JVM memory in ms (or -1 to disable memory sampling)
memory-warning-threshold 25 INT Percentage of available memory which if exceeded results in a warning log
message-counter-enabled false BOOLEAN Whether message counters are enabled
message-counter-max-day-history 10 INT How many days to keep message counter history
message-counter-sample-period 10000 LONG The sample period (in ms) to use for message counters
message-expiry-scan-period 30000 LONG How often (in ms) to scan for expired messages
message-expiry-thread-priority 3 INT The priority of the thread expiring messages
page-max-concurrent-io 5 INT The maximum number of concurrent reads allowed on paging
perf-blast-pages -1 INT  
persist-delivery-count-before-delivery false BOOLEAN Whether the delivery count is persisted before delivery. False means that this only happens after a message has been canceled
persist-id-cache true BOOLEAN Whether IDs are persisted to the journal
persistence-enabled true BOOLEAN Whether the server will use the file based journal for persistence
pooled-connection-factory Defines a managed connection factory
remoting-interceptors undefined LIST [Deprecated] The list of interceptor classes used by this server
remoting-incoming-interceptors undefined LIST The list of incoming interceptor classes used by this server
remoting-outgoing-interceptors undefined LIST The list of outgoing interceptor classes used by this server
run-sync-speed-test false BOOLEAN Whether to perform a diagnostic test on how fast your disk can sync on startup. Useful when determining performance issues
replication-clustername STRING The name of the cluster connection to replicate from if more than one cluster connection is configured
runtime-queue A runtime queue
remote-connector Used by a remote client to define how it connects to a server
remote-acceptor Defines a way in which remote connections can be made to the HornetQ server
scheduled-thread-pool-max-size 5 INT The number of threads that the main scheduled thread pool has
security-domain other STRING The security domain to use in order to verify user and role information
security-enabled true BOOLEAN Whether security is enabled
security-setting A security setting allows sets of permissions to be defined against queues based on their address
security-invalidation-interval 10000 LONG How long (in ms) to wait before invalidating the security cache
server-dump-interval -1 LONG How often to dump basic runtime information to the server log. A value less than 1 disables this feature
shared store true BOOLEAN Whether this server is using a shared store for failover
thread-pool-max-size 30 INT The number of threads that the main thread pool has. -1 means no limit
transaction-timeout 300000 LONG How long (in ms) before a transaction can be removed from the resource manager after create time
transaction-timeout-scan-period 1000 LONG How often (in ms) to scan for timeout transactions
wild-card-routing-enabled true BOOLEAN Whether the server supports wild card routing

Warning

The value of journal-file-size must be higher than the size of message sent to server, or the server will not be able to store the message.

18.8.16. Set Message Expiry

Introduction

Sent messages can be set to expire on server if they're not delivered to consumer after specified amount of time (milliseconds). Using Java Messaging Service (JMS) or HornetQ Core API, the expiration time can be set directly on the message. For example:

// message will expire in 5000ms from now
message.setExpiration(System.currentTimeMillis() + 5000);
JMS MessageProducer includes a TimeToLive parameter which controls message expiry for the messages it sends:
// messages sent by this producer will be retained for 5s (5000ms) before expiration           
producer.setTimeToLive(5000);
Expired messages which are consumed from an expiry address have the following properties:
  • _HQ_ORIG_ADDRESS
A string property containing the original address of the expired message.
  • _HQ_ACTUAL_EXPIRY
A long property containing the actual expiration time of the expired message.
Besides setting the time-to-live parameter on the JMS producer, you can also set it on a per-message basis. You can achieve this by adding TTL parameter to producer's send method when sending the message.
producer.send(message, DeliveryMode.PERSISTENT, 0, 5000)
Where, the last parameter is message specific TTL.
Configuring Expiry Addresses

Expiry address are defined in the address-setting configuration:

<!-- expired messages in exampleQueue will be sent to the expiry address expiryQueue -->
<address-setting match="jms.queue.exampleQueue">
   <expiry-address>jms.queue.expiryQueue</expiry-address>
</address-setting>
If the messages are expired and no expiry address is specified, the messages are removed from the queue and dropped.
Configuring Expiry Reaper Thread

A reaper thread periodically inspects the queues to validate if messages have expired.

  • message-expiry-scan-period
How often the queues will be scanned to detect expired messages (in milliseconds, default is 30000ms, set to -1 to disable the reaper thread).
  • message-expiry-thread-priority
The reaper thread priority. It must be between 0 and 9, 9 being the highest priority, default is 3.