JBoss Community Archive (Read Only)

WildFly 10

Messaging configuration

The JMS server configuration is done through the messaging-activemq subsystem. In this chapter we are going outline the frequently used configuration options. For a more detailed explanation please consult the Artemis user guide (See "Component Reference"). 

Required Extension

The configuration options discussed in this section assume that the the org.wildfly.extension.messaging-activemq extension is present in your configuration. This extension is not included in the standard standalone.xml and standalone-ha.xml configurations included in the WildFly distribution. It is, however, included with the standalone-full.xml and standalone-full-ha.xml configurations.

You can add the extension to a configuration without it either by adding an <extension module="org.wildfly.extension.messaging-activemq"/> element to the xml or by using the following CLI operation:

[standalone@localhost:9990 /]/extension=org.wildfly.extension.messaging-activemq:add

Connectors

There are three kind of connectors that can be used to connect to WildFly JMS Server

  • in-vm-connector can be used by a local client (i.e. one running in the same JVM as the server)

  • remote-connector can be used by a remote client (and uses Netty over TCP for the communication)

  • http-connector can be used by a remote client (and uses Undertow Web Server to upgrade from a HTTP connection)

JMS Connection Factories

There are three kinds of basic JMS connection-factory that depends on the type of connectors that is used.

There is also a pooled-connection-factory which is special in that it is essentially a configuration facade for both the inbound and outbound connectors of the the Artemis JCA Resource Adapter.  An MDB can be configured to use a pooled-connection-factory (e.g. using @ResourceAdapter).  In this context, the MDB leverages the inbound connector of the Artemis JCA RA.  Other kinds of clients can look up the pooled-connection-factory in JNDI (or inject it) and use it to send messages.  In this context, such a client would leverage the outbound connector of the Artemis JCA RA.  A pooled-connection-factory is also special because:

  • It is only available to local clients, although it can be configured to point to a remote server.

  • As the name suggests, it is pooled and therefore provides superior performance to the clients which are able to use it.  The pool size can be configured via the max-pool-size and min-pool-size attributes.

  • It should only be used to send (i.e. produce) messages when looked up in JNDI or injected.

  • It can be configured to use specific security credentials via the user and password attributes.  This is useful if the remote server to which it is pointing is secured.

  • Resources acquired from it will be automatically enlisted any on-going JTA transaction.  If you want to send a message from an EJB using CMT then this is likely the connection factory you want to use so the send operation will be atomically committed along with the rest of the EJB's transaction operations.

To be clear, the inbound connector of the Artemis JCA RA (which is for consuming messages) is only used by MDBs and other JCA-based components.  It is not available to traditional clients.

Both a connection-factory and a pooled-connection-factory reference a connector declaration.  

A remote-connector is associated with a socket-binding which tells the client using the connection-factory where to connect.

  • A connection-factory referencing a remote-connector is suitable to be used by a remote client to send messages to or receive messages from the server (assuming the connection-factory has an appropriately exported entry).  

  • A pooled-connection-factory looked up in JNDI or injected which is referencing a remote-connector is suitable to be used by a local client to send messages to a remote server granted the socket-binding references an outbound-socket-binding pointing to the remote server in question.

  • pooled-connection-factory used by an MDB which is referencing a remote-connector is suitable to consume messages from a remote server granted the socket-binding references an outbound-socket-binding pointing to the remote server in question.

An in-vm-connector is associated with a server-id which tells the client using the connection-factory where to connect (since multiple Artemis servers can run in a single JVM).

  • connection-factory referencing an in-vm-connector is suitable to be used by a local client to either send messages to or receive messages from a local server.  

  • pooled-connection-factory looked up in JNDI or injected which is referencing an in-vm-connector is suitable to be used by a local client only to send messages to a local server.

  • pooled-connection-factory used by an MDB which is referencing an in-vm-connector is suitable only to consume messages from a local server.

A http-connector is associated with the socket-binding that represents the HTTP socket (by default, named http).

  • A connection-factory referencing a http-connector is suitable to be used by a remote client to send messages to or receive messages from the server by connecting to its HTTP port before upgrading to the messaging protocol.

  • A pooled-connection-factory referencing a http-connector is suitable to be used by a local client to send messages to a remote server  granted the socket-binding references an outbound-socket-binding pointing to the remote server in question.

  • pooled-connection-factory used by an MDB which is referencing a http-connector is suitable only to consume messages from a remote server granted the socket-binding references an outbound-socket-binding pointing to the remote server in question.

The entry declaration of a connection-factory or a pooled-connection-factory specifies the JNDI name under which the factory will be exposed.  Only JNDI names bound in the "java:jboss/exported" namespace are available to remote clients.  If a connection-factory has an entry bound in the "java:jboss/exported" namespace a remote client would look-up the connection-factory using the text after "java:jboss/exported".  For example, the "RemoteConnectionFactory" is bound by default to "java:jboss/exported/jms/RemoteConnectionFactory" which means a remote client would look-up this connection-factory using "jms/RemoteConnectionFactory".  A pooled-connection-factory should not have any entry bound in the "java:jboss/exported" namespace because a pooled-connection-factory is not suitable for remote clients.

Since JMS 2.0, a default JMS connection factory is accessible to EE application under the JNDI name java:comp/DefaultJMSConnectionFactory. WildFly messaging subsystem defines a pooled-connection-factory that is used to provide this default connection factory. Any parameter change on this pooled-connection-factory will be take into account by any EE application looking the default JMS provider under the JNDI name java:comp/DefaultJMSConnectionFactory.

<subsystem xmlns="urn:jboss:domain:messaging-activemq:1.0">
    <server name="default">
        [...]
        <http-connector name="http-connector"
                        socket-binding="http"
                        endpoint="http-acceptor" />
        <http-connector name="http-connector-throughput"
                        socket-binding="http"
                        endpoint="http-acceptor-throughput">
            <param name="batch-delay"
                   value="50"/>
        </http-connector>
        <in-vm-connector name="in-vm"
                         server-id="0"/>
      [...]
      <connection-factory name="InVmConnectionFactory"
                            connectors="in-vm"
                            entries="java:/ConnectionFactory" />
      <pooled-connection-factory name="activemq-ra"
                            transaction="xa"
                            connectors="in-vm"
                            entries="java:/JmsXA java:jboss/DefaultJMSConnectionFactory"/>
      [...]
   </server>
</subsystem>

(See standalone/configuration/standalone-full.xml)

JMS Queues and Topics

JMS queues and topics are sub resources of the messaging-activemq subsystem. One can define either a jms-queue or jms-topic.  Each destination must be given a name and contain at least one entry in its entries element (separated by whitespace).

Each entry refers to a JNDI name of the queue or topic. Keep in mind that any jms-queue or jms-topic which needs to be accessed by a remote client needs to have an entry in the "java:jboss/exported" namespace. As with connection factories, if a jms-queue or or jms-topic has an entry bound in the "java:jboss/exported" namespace a remote client would look it up using the text after "java:jboss/exported". For example, the following jms-queue "testQueue" is bound to "java:jboss/exported/jms/queue/test" which means a remote client would look-up this {{kms-queue} using "jms/queue/test". A local client could look it up using "java:jboss/exported/jms/queue/test", "java:jms/queue/test", or more simply "jms/queue/test":

<subsystem xmlns="urn:jboss:domain:messaging-activemq:1.0">
    <server name="default">
    [...]
    <jms-queue name="testQueue"
               entries="jms/queue/test java:jboss/exported/jms/queue/test" />
    <jms-topic name="testTopic"
               entries="jms/topic/test java:jboss/exported/jms/topic/test" />
</subsystem>

(See standalone/configuration/standalone-full.xml)

JMS endpoints can easily be created through the CLI:

[standalone@localhost:9990 /] jms-queue add --queue-address=myQueue --entries=queues/myQueue
[standalone@localhost:9990 /] /subsystem=messaging-activemq/server=default/jms-queue=myQueue:read-resource
{
    "outcome" => "success",
    "result" => {
        "durable" => true,
        "entries" => ["queues/myQueue"],
        "selector" => undefined
    }
}

A number of additional commands to maintain the JMS subsystem are available as well:

[standalone@localhost:9990 /] jms-queue --help --commands
add
...
remove
To read the description of a specific command execute 'jms-queue command_name --help'.

Dead Letter & Redelivery

Some of the settings are applied against an address wild card instead of a specific messaging destination. The dead letter queue and redelivery settings belong into this group:

<subsystem xmlns="urn:jboss:domain:messaging-activemq:1.0">
   <server name="default">
      [...]
      <address-setting name="#"
                       dead-letter-address="jms.queue.DLQ"
                       expiry-address="jms.queue.ExpiryQueue"
                       [...] />

(See standalone/configuration/standalone-full.xml)

Security Settings for Artemis addresses and JMS destinations

Security constraints are matched against an address wildcard, similar to the DLQ and redelivery settings.

<subsystem xmlns="urn:jboss:domain:messaging-activemq:1.0">
   <server name="default">
      [...]
      <security-setting name="#">
          <role name="guest"
                send="true"
                consume="true"
                create-non-durable-queue="true"
                delete-non-durable-queue="true"/>

(See standalone/configuration/standalone-full.xml)

Security Domain for Users

By default, Artemis will use the "other" JAAS security domain. This domain is used to authenticate users making connections to Artemis and then they are authorized to perform specific functions based on their role(s) and the security-settings described above. This domain can be changed by using the security-domain, e.g.:

<subsystem xmlns="urn:jboss:domain:messaging-activemq:1.0">
   <server name="default">
       <security domain="mySecurityDomain" />
      [...]

Cluster Authentication

If the Artemis server is configured to be clustered, it will use the cluster 's user and password attributes to connect to other Artemis nodes in the cluster.

If you do not change the default value of <cluster-password>, Artemis will fail to authenticate with the error:

HQ224018: Failed to create session: HornetQExceptionerrorType=CLUSTER_SECURITY_EXCEPTION message=HQ119099: Unable to authenticate cluster user: HORNETQ.CLUSTER.ADMIN.USER

To prevent this error, you must specify a value for <cluster-password>. It is possible to encrypt this value by following this guide.

Alternatively, you can use the system property jboss.messaging.cluster.password to specify the cluster password from the command line.

Deployment of -jms.xml files

Starting with WildFly 8, you have the ability to deploy a -jms.xml file defining JMS destinations, e.g.:

<?xml version="1.0" encoding="UTF-8"?>
<messaging-deployment xmlns="urn:jboss:messaging-activemq-deployment:1.0">
   <server name="default">
      <jms-destinations>
         <jms-queue name="sample">
            <entry name="jms/queue/sample"/>
            <entry name="java:jboss/exported/jms/queue/sample"/>
         </jms-queue>
      </jms-destinations>
   </server>
</messaging-deployment>

images/author/images/icons/emoticons/warning.gif

This feature is primarily intended for development as destinations deployed this way can not be managed with any of the provided management tools (e.g. console, CLI, etc).

JMS Bridge

The function of a JMS bridge is to consume messages from a source JMS destination, and send them to a target JMS destination. Typically either the source or the target destinations are on different servers.
The bridge can also be used to bridge messages from other non Artemis JMS servers, as long as they are JMS 1.1 compliant.

The JMS Bridge is provided by the Artemis project. For a detailed description of the available configuration properties, please consult the project documentation.

Modules for other messaging brokers

Source and target JMS resources (destination and connection factories) are looked up using JNDI.
If either the source or the target resources are managed by another messaging server than WildFly, the required client classes must be bundled in a module. The name of the module must then be declared when the JMS Bridge is configured.

The use of a JMS bridges with any messaging provider will require to create a module containing the jar of this provider.

Let's suppose we want to use an hypothetical messaging provider named AcmeMQ. We want to bridge messages coming from a source AcmeMQ destination to a target destination on the local WildFly messaging server. To lookup AcmeMQ resources from JNDI, 2 jars are required, acmemq-1.2.3.jar, mylogapi-0.0.1.jar (please note these jars do not exist, this is just for the example purpose). We must not include a JMS jar since it will be provided by a WildFly module directly.

To use these resources in a JMS bridge, we must bundle them in a WildFly module:

in JBOSS_HOME/modules, we create the layout:

modules/
`-- org
    `-- acmemq
        `-- main
            |-- acmemq-1.2.3.jar
            |-- mylogapi-0.0.1.jar
            `-- module.xml

We define the module in module.xml:

<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.1" name="org.acmemq">
    <properties>
        <property name="jboss.api" value="private"/>
    </properties>


    <resources>
        <!-- insert resources required to connect to the source or target   -->
        <!-- messaging brokers if it not another WildFly instance           -->
        <resource-root path="acmemq-1.2.3.jar" />
        <resource-root path="mylogapi-0.0.1.jar" />
    </resources>


    <dependencies>
       <!-- add the dependencies required by JMS Bridge code                -->
       <module name="javax.api" />
       <module name="javax.jms.api" />
       <module name="javax.transaction.api"/>
       <module name="org.jboss.remote-naming"/>
       <!-- we depend on org.apache.activemq.artemis module since we will send messages to  -->
       <!-- the Artemis server embedded in the local WildFly instance       -->
       <module name="org.apache.activemq.artemis" />
    </dependencies>
</module>

Configuration

A JMS bridge is defined inside a jms-bridge section of the `messaging-activemq` subsystem in the XML configuration files.

<subsystem xmlns="urn:jboss:domain:messaging-activemq:1.0">
   <jms-bridge name="myBridge" module="org.acmemq">
      <source connection-factory="ConnectionFactory"
              destination="sourceQ"
              user="user1"
              password="pwd1"
              quality-of-service="AT_MOST_ONCE"
              failure-retry-interval="500"
              max-retries="1"
              max-batch-size="500"
              max-batch-time="500"
              add-messageID-in-header="true">
         <source-context>
            <property name="java.naming.factory.initial"
                      value="org.acmemq.jndi.AcmeMQInitialContextFactory"/>
            <property name="java.naming.provider.url"
                      value="tcp://127.0.0.1:9292"/>
         </source-context>
      </source>
      <target connection-factory"/jms/invmTargetCF"
              destination="/jms/targetQ" />
      </target>
   </jms-bridge>
</subsystem>

The source and target sections contain the name of the JMS resource (connection-factory and destination) that will be looked up in JNDI.
It optionally defines the user and password credentials. If they are set, they will be passed as arguments when creating the JMS connection from the looked up ConnectionFactory.
It is also possible to define JNDI context properties in the source-context and target-context sections. If these sections are absent, the JMS resources will be looked up in the local WildFly instance (as it is the case in the target section in the example above).

Management commands

A JMS Bridge can also be managed using the WildFly command line interface:

[standalone@localhost:9990 /] /subsystem=messaging/jms-bridge=myBridge/:add(module="org.acmemq",      \
      source-destination="sourceQ",                                                                   \
      source-connection-factory="ConnectionFactory",                                                  \
      source-user="user1",                                                                            \
      source-password="pwd1",                                                                         \
      source-context={"java.naming.factory.initial" => "org.acmemq.jndi.AcmeMQInitialContextFactory", \
                      "java.naming.provider.url" => "tcp://127.0.0.1:9292"},                          \
      target-destination="/jms/targetQ",                                                              \
      target-connection-factory="/jms/invmTargetCF",                                                  \
      quality-of-service=AT_MOST_ONCE,                                                                \
      failure-retry-interval=500,                                                                     \
      max-retries=1,                                                                                  \
      max-batch-size=500,                                                                             \
      max-batch-time=500,                                                                             \
      add-messageID-in-header=true)
{"outcome" => "success"}

You can also see the complete JMS Bridge resource description from the CLI:

[standalone@localhost:9990 /] /subsystem=messaging/jms-bridge=*/:read-resource-description
{
    "outcome" => "success",
    "result" => [{
        "address" => [
            ("subsystem" => "messaging"),
            ("jms-bridge" => "*")
        ],
        "outcome" => "success",
        "result" => {
            "description" => "A JMS bridge instance.",
            "attributes" => {
                ...
        }
    }]
}

Component Reference

The messaging-activemq subsystem is provided by the Artemis project. For a detailed description of the available configuration properties, please consult the project documentation.

JBoss.org Content Archive (Read Only), exported from JBoss Community Documentation Editor at 2020-03-13 13:40:29 UTC, last content change 2018-02-22 09:34:05 UTC.