Chapter 6. Configuration

The JMS API specifies how a messaging client interacts with a messaging server. The exact definition and implementation of messaging services, such as message destinations and connection factories, are specific to JMS providers. JBoss Messaging has its own configuration files to configure services. If you are migrating services from JBossMQ (or other JMS provider) to JBoss Messaging, you will need to understand those configuration files.

In this chapter, we discuss how to configure various services inside JBoss Messaging, which work together to provide JMS API level services to client applications.

Starting with the JBoss Messaging 1.0.1 release, the service configuration is spread among several configuration files. (The 1.0.0 release used to have all configuration information lumped together in the SAR's deployment descriptor jboss-messaging.sar/META-INF/jboss-service.xml). Depending on the functionality provided by the services it configures, the configuration data is distributed between messaging-service.xml, remoting-service.xml, xxx-persistence-service.xml, connection-factories-service.xml and destinations-service.xml.

The AOP client-side and server-side interceptor stacks are configured in aop-messaging-client.xml and aop-messaging-server.xml.

6.1. Configuring the Server

The Server Peer is the "heart" of the JBoss Messaging JMS facade. The server's configuration, together with the configuration of several core plug-ins (ThreadPool and the MessageStore), resides in messaging-service.xml configuration file.

An example of a Server Peer configuration is presented below


  <mbean code="org.jboss.jms.server.ServerPeer"
      name="jboss.messaging:service=ServerPeer"
      xmbean-dd="xmdesc/ServerPeer-xmbean.xml">

      <constructor>
         <!-- ServerPeerID -->
         <arg type="java.lang.String" value="server.0"/>
         <!-- DefaultQueueJNDIContext -->
         <arg type="java.lang.String" value="/queue"/>
         <!-- DefaultTopicJNDIContext -->
         <arg type="java.lang.String" value="/topic"/>
      </constructor>

      <depends optional-attribute-name="ThreadPool">jboss.messaging:service=ThreadPool</depends>
      <depends optional-attribute-name="PersistenceManager">jboss.messaging:service=PersistenceManager</depends>
      <depends optional-attribute-name="MessageStore">jboss.messaging:service=MessageStore</depends>
      <depends optional-attribute-name="ChannelMapper">jboss.messaging:service=ChannelMapper</depends>

      <!-- Set to -1 to completely disable client leasing -->
      <attribute name="SecurityDomain">java:/jaas/messaging</attribute>
      <attribute name="DefaultSecurityConfig">
        <security>
            <role name="guest" read="true" write="true" create="true"/>
        </security>
      </attribute>
   </mbean>

     

6.1.1. SecurityDomain

This identifies the JBoss security domain that will be used when JBoss Messaging authenticates and authorises access to JMS destinations for reading, writing or creating.

It should correspond to a entry in login-config.xml where it is configured in exactly the same way as any other security domain in JBoss.

6.1.2. DefaultSecurityConfig

Default security configuration is used when the security configuration for a specific queue or topic has not been overridden in the destination's deployment descriptor. It has exactly the same syntax and semantics as in JBossMQ.

The DefaultSecurityConfig attribute element should contain one <security> element. The <security> element can contain multiple <role> elements. Each <role> element defines the default access for that particular role.

If the read attribute is true then that role will be able to read (create consumers, receive messaages or browse) destinations by default.

If the write attribute is true then that role will be able to write (create producers or send messages) to destinations by default.

If the create attribute is true then that role will be able to create durable subscriptions on topics by default.

6.2. Configuring Persistence

JBoss Messaging interacts with a persistent store via two services: the Persistence Manager and the Channel Mapper. The Persistence Manager is used to handle the message-related functions. The Channel Mapper manages destination-related persistent data.

JBoss Messaging ships with a JDBC Persistence Manager used for handling persistence of message data in a relational database accessed via JDBC. The Persistence Manager implementation is pluggable (the Persistence Manager is a Messaging server plug-in), this making possible to provide other implementations for persisting message data in non relational stores, file stores etc.

The configuration of "persistent" services is grouped in a xxx-persistence-service.xml file, where the actual file prefix is usually inferred from its corresponding database JDBC connection string. By default, Messaging ships with a hsqldb-persistence-service.xml, which configures the Messaging server to use the in-VM Hypersonic database instance that comes by default with any JBossAS instance.

Warning

The default Persistence Manager configuration is works out of the box with Hypersonic, however it must be stressed that Hypersonic should not be used in a production environment mainly due to its limited support for transaction isolation and its propensity to behave erratically under high load.

The Critique of Hypersonic wiki page outlines some of the well-known issues occuring when using this database.

JBoss Messaging also ships with pre-made Persistence Manager configurations for MySQL, Oracle, PostgreSQL and Sybase. The example mysql-persistence-service.xml, oracle-persistence-service.xml, postgres-persistence-service.xml and sybase-persistence-service.xml configuration files are available in the examples/config directory of the release bundle.

Configurations for MSSQL and other popular databases should be available soon. Users are encouraged to contribute their own configuration files. The JDBC Persistence Manager has been designed to use standard SQL for the DML so writing a JDBC Persistence Manager configuration for another database is usually only a fairly simple matter of changing DDL in the configuration which is likely to be different for different databases.

The default Hypersonic persistence configuration file is listed below:

<server>
   <mbean code="org.jboss.messaging.core.plugin.JDBCPersistenceManager"
      name="jboss.messaging:service=PersistenceManager"
      xmbean-dd="xmdesc/JDBCPersistenceManager-xmbean.xml">
      <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
      <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
      <depends optional-attribute-name="ChannelMapper">jboss.messaging:service=ChannelMapper</depends>
      <attribute name="DataSource">java:/DefaultDS</attribute>
      <attribute name="CreateTablesOnStartup">true</attribute>
      <attribute name="UsingBatchUpdates">true</attribute>
   </mbean>

   <mbean code="org.jboss.jms.server.plugin.JDBCChannelMapper"
      name="jboss.messaging:service=ChannelMapper"
      xmbean-dd="xmdesc/JDBCChannelMapper-xmbean.xml">
      <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
      <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
      <attribute name="DataSource">java:/DefaultDS</attribute>
   </mbean>
</server>
     

An example of a Persistence Manager configuration for a MySQL database follows:

<server>
   <mbean code="org.jboss.messaging.core.plugin.JDBCPersistenceManager"
      name="jboss.messaging:service=PersistenceManager"
      xmbean-dd="xmdesc/JDBCPersistenceManager-xmbean.xml">
      <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
      <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
      <depends optional-attribute-name="ChannelMapper">jboss.messaging:service=ChannelMapper</depends>
      <attribute name="DataSource">java:/DefaultDS</attribute>
      <attribute name="CreateTablesOnStartup">true</attribute>
      <attribute name="UsingBatchUpdates">true</attribute>
      <attribute name="SqlProperties"><![CDATA[
CREATE_MESSAGE_REF=CREATE TABLE JMS_MESSAGE_REFERENCE (CHANNELID BIGINT, MESSAGEID BIGINT, TRANSACTIONID BIGINT, STATE CHAR(1), ORD BIGINT, DELIVERYCOUNT INTEGER, RELIABLE CHAR(1), LOADED CHAR(1), PRIMARY KEY(CHANNELID, MESSAGEID))
CREATE_IDX_MESSAGE_REF_TX=CREATE INDEX JMS_MESSAGE_REF_TX ON JMS_MESSAGE_REFERENCE (TRANSACTIONID)
CREATE_IDX_MESSAGE_REF_ORD=CREATE INDEX JMS_MESSAGE_REF_ORD ON JMS_MESSAGE_REFERENCE (ORD)
CREATE_IDX_MESSAGE_REF_MESSAGEID=CREATE INDEX JMS_MESSAGE_REF_MESSAGEID ON JMS_MESSAGE_REFERENCE (MESSAGEID)
CREATE_IDX_MESSAGE_REF_LOADED=CREATE INDEX JMS_MESSAGE_REF_LOADED ON JMS_MESSAGE_REFERENCE (LOADED)
CREATE_IDX_MESSAGE_REF_RELIABLE=CREATE INDEX JMS_MESSAGE_REF_RELIABLE ON JMS_MESSAGE_REFERENCE (RELIABLE)
INSERT_MESSAGE_REF=INSERT INTO JMS_MESSAGE_REFERENCE (CHANNELID, MESSAGEID, TRANSACTIONID, STATE, ORD, DELIVERYCOUNT, RELIABLE, LOADED) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
....      ]]>
      </attribute>
      <attribute name="MaxParams">500</attribute>
   </mbean>

   <mbean code="org.jboss.jms.server.plugin.JDBCChannelMapper"
      name="jboss.messaging:service=ChannelMapper"
      xmbean-dd="xmdesc/JDBCChannelMapper-xmbean.xml">
      <depends>jboss.jca:service=DataSourceBinding,name=DefaultDS</depends>
      <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
      <attribute name="DataSource">java:/DefaultDS</attribute>
      <attribute name="SqlProperties"><![CDATA[
CREATE_USER_TABLE=CREATE TABLE JMS_USER (USERID VARCHAR(32) NOT NULL, PASSWD VARCHAR(32) NOT NULL, CLIENTID VARCHAR(128), PRIMARY KEY(USERID))
CREATE_ROLE_TABLE=CREATE TABLE JMS_ROLE (ROLEID VARCHAR(32) NOT NULL, USERID VARCHAR(32) NOT NULL, PRIMARY KEY(USERID, ROLEID))
SELECT_PRECONF_CLIENTID=SELECT CLIENTID FROM JMS_USER WHERE USERID=?
....
      ]]>
      </attribute>
   </mbean>
</server>
  

6.2.1. Changing the Database

If the database you want to switch to is one of MySQL, Oracle or Postgres, persistence configuration files are already available in the examples/config directory of the release bundle.

In order to enable support for one of these databases, just replace the default hsqldb-persistence-service.xml configuration file with the database-specific configuration file and restart the server.

Also, be aware that by default, the Messaging services relying on a datastore are referencing "java:/DefaultDS" for the datasource. If you are deploying a datasource with a different JNDI name, you need to update all the DataSource attribute in the persistence configuration file.

6.2.2. CreateTablesOnStartup

Set this to true if you wish the Persistence Manager to attempt to create the tables (and indexes) when it starts. If the tables (or indexes) already exist a SQLException will be thrown by the JDBC driver and ignored by the Persistence Manager, allowing it to continue.

By default the value of CreateTablesOnStartup attribute is set to true

6.2.3. UsingBatchUpdates

Set this to true if the database supports JDBC batch updates. The JDBC Persistence Manager will then group multiple database updates in batches to aid performance.

By default the value of UsingBatchUpdates attribute is set to false

6.2.4. SQLProperties

This is where the DDL and DML for the particular database is specified. If a particular DDL or DML statement is not overridden, the default Hypersonic configuration will be used for that statement.

6.3. Configuring Destinations

6.3.1. Pre-configured destinations

JBoss Messaging ships with a default set of pre-configured destinations that will be deployed during the server start up. The file that contains configuration for these destinations is destinations-service.xml. A section of this file is listed below:


<!-- The Dead Letter Queue. This destination is a dependency of an EJB MDB container -->

<mbean code="org.jboss.jms.server.destination.Queue"
       name="jboss.messaging.destination:service=Queue,name=DLQ"
       xmbean-dd="xmdesc/Queue-xmbean.xml">
   <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
</mbean>

....

<mbean code="org.jboss.jms.server.destination.Topic"
       name="jboss.messaging.destination:service=Topic,name=testTopic"
       xmbean-dd="xmdesc/Topic-xmbean.xml">
   <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
   <attribute name="SecurityConfig">
      <security>
         <role name="guest" read="true" write="true"/>
         <role name="publisher" read="true" write="true" create="false"/>
         <role name="durpublisher" read="true" write="true" create="true"/>
      </security>
   </attribute>
</mbean>

....

<mbean code="org.jboss.jms.server.destination.Queue"
       name="jboss.messaging.destination:service=Queue,name=testQueue"
       xmbean-dd="xmdesc/Queue-xmbean.xml">
   <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
   <attribute name="SecurityConfig">
      <security>
         <role name="guest" read="true" write="true"/>
         <role name="publisher" read="true" write="true" create="false"/>
         <role name="noacc" read="false" write="false" create="false"/>
      </security>
   </attribute>
</mbean>

....
        

6.3.2. Destination Configuration Parameters

6.3.2.1. Destination Security Configuration

SecurityConfig - allows you to determine which roles are allowed to read, write and create on the destination. It has exactly the same syntax and semantics as the security configuration in JBossMQ destinations.

The SecurityConfig element should contain one <security> element. The <security> element can contain multiple <role> elements. Each <role> element defines the access for that particular role.

If the read attribute is true then that role will be able to read (create consumers, receive messaages or browse) this destination.

If the write attribute is true then that role will be able to write (create producers or send messages) to this destination.

If the create attribute is true then that role will be able to create durable subscriptions on this destination.

Note that the security configuration for a destination is optional. If a SecurityConfig element is not specifed then the default security configuration from the Server Peer will be used.

6.3.2.2. Destination paging parameters

'Pageable Channels' are a sophisticated new feature available in JBoss Messaging.

If your application needs to support very large queues or subscriptions containing potentially millions of messages, then it's not possible to store them all in memory at once.

JBoss Messaging solves this problem but letting you specify the maximum number of messages that can be stored in memory at any one time, on a queue-by-queue, or topic-by-topic basis. JBoss Messaging then pages messages to and from storage transparently in blocks, allowing queues and subscriptions to grow to very large sizes without any performance degradation as channel size increases.

This has been tested with in excess of 10 million 2K messages on very basic hardware and has the potential to scale to much larger number of messages.

The individual parameters are:

FullSize - this is the maximum number of messages held by the queue or topic subscriptions in memory at any one time. The actual queue or subscription can hold many more messages than this but these are paged to and from storage as necessary as messages are added or consumed.

PageSize - When loading messages from the queue or subscrition this is the maximum number of messages to pre-load in one operation.

DownCacheSize - When paging messages to storage from the queue they first go into a "Down Cache" before being written to storage. This enables the write to occur as a single operation thus aiding performance. This setting determines the max number of messages that the Down Cache will hold before they are flushed to storage.

If no values for FullSize, PageSize, or DownCacheSize are specified they will default to values 75000, 2000, 2000 respectively.

If you want to specify the paging parameters used for temporary queues then you need to specify them on the appropriate connection factory. See connection factory configuration for details.

6.3.3. Deploying a new destination

For a JBoss 4.0.x installation, JBoss Messaging is deployed in its own class loading domain. Because of that you need to deploy a new destinations to use with JBoss Messaging within the same class loading domain.

To deploy a new destination, create a new deployment descriptor named myqueue-service.xml (or anything else that ends in -service.xml) and copy it to the JBoss instance deployment directory $JBOSS_HOME/server/messaging/deploy.

An example of a scoped destination deployment descriptor is listed below:

<?xml version="1.0" encoding="UTF-8"?>
<server>
 <loader-repository>jboss.messaging:loader=ScopedLoaderRepository
 <loader-repository-config>java2ParentDelegation=false</loader-repository-config>
 </loader-repository>
 <mbean code="org.jboss.jms.server.destination.Queue"
           name="jboss.messaging.destination:service=Queue,name=testQueue"
           xmbean-dd="xmdesc/Queue-xmbean.xml">
           <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
           <attribute name="SecurityConfig">
              <security>
                 <role name="guest" read="true" write="true"/>
                 <role name="publisher" read="true" write="true" create="false"/>
                 <role name="noacc" read="false" write="false" create="false"/>
               </security>
           </attribute>
           <attribute name="fullSize">75000</attribute>
           <attribute name="pageSize">2000</attribute>
           <attribute name="downCacheSize">2000</attribute>
 </mbean>
</server>
        

6.4. Configuring Connection Factories

With the default configuration JBoss Messaging binds just one connection factory in JNDI at start-up. This connection factory has no client ID and is bound into the following JNDI contexts: /ConnectionFactory, /XAConnectionFactory, java:/ConnectionFactory, java:/XAConnectionFactory

You may want to configure additional connection factories, for instance if you want to provide a default client id for a connection factory, or if you want to bind it in different places in JNDI, or if you want different connection factories to use different transports. Deploying a new connection factory is equivalent with adding a new ConnectionFactory MBean configuration to connection-factories-service.xml.

It is also possible to create an entirely new service deployment descriptor xxx-service.xml altogether and deploy it in $JBOSS_HOME/server/messaging/deploy.

An example connection factory configuration is presented below:

     <?xml version="1.0" encoding="UTF-8"?>
     <server>
        <loader-repository>jboss.messaging:loader=ScopedLoaderRepository
           <loader-repository-config>java2ParentDelegation=false</loader-repository-config>
        </loader-repository>
        <mbean code="org.jboss.jms.server.connectionfactory.ConnectionFactory"
           name="jboss.messaging.destination:service=ConnectionFactory"
           xmbean-dd="xmdesc/ConnectionFactory-xmbean.xml">
           <constructor>
              <arg type="java.lang.String" value="myClientID"/>
           </constructor>
           <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
           <depends optional-attribute-name="Connector">jboss.messaging:service=Connector,transport=socket</depends>
           <attribute name="PrefetchSize">10</attribute>
           <attribute name="DefaultTempQueueFullSize">1000</attribute>
           <attribute name="DefaultTempQueuePageSize">50</attribute>
           <attribute name="DefaultTempQueueDownCacheSize">50</attribute>
           <attribute name="JNDIBindings">
              <bindings>
                 <binding>/MyConnectionFactory1</binding>
                 <binding>/factories/cf1</binding>>
              </bindings>
           </attribute>
        </mbean>
     </server>

    

The above example would create a connection factory with pre-configured client ID myClientID and bind the connection factory in two places in the JNDI tree: /MyConnectionFactory and /factories/cf. The connection factory will use the default remoting connector. To use a different remoting connector with the connection factory change the Connector attribute to specify the service name of the connector you wish to use.

prefetchSize is an optional attribute that determines how many messages client side message consumers will buffer locally. Pre-fetching messages prevents the client having to go to the server each time a message is consumed to say it is ready to receive another message. This greatly increases throughput. The default value for prefetchSize is 150. You may want to change this to a smaller value if you are dealing with very large messages, so as not to use too much memory on the client.

DefaultTempQueueFullSize, DefaultTempQueuePageSize, DefaultTempQueueDownCacheSize are optional attributes that determine the default paging parameters to be used for any temporary destinations scoped to connections created using this connection factory. See the section on paging channels for more information on what these values mean. They will default to values of 75000, 2000 and 2000 respectively if ommitted.

6.5. Configuring the remoting connector

JBoss Messaging uses JBoss Remoting for all client to server communication. For full details of what JBoss Remoting is capable of and how it is configured please consult the JBoss Remoting documentation.

The default configuration includes a single remoting connector which is used by the single default connection factory. Each connection factory can be configured to use its own connector.

The default connector is configured to use the remoting socket transport.

This transport opens TCP connections from client to server for client to server communications (e.g. sending messages) and TCP connections from server to client for server to client communications (e.g. receiving messages). The transport can be configured to use SSL where a higher level of security is required.

Future releases JBoss Messaging will support a bidirectional socket transport (similar to UIL2 in JBoss MQ) and an HTTP transport, both of which are useful in network environments where TCP connections from server to client are not possible. This means, for example, that you could deploy one connection factory that uses the HTTP transport for all the connections created from it, and another connection factory that uses the socket transport for all connections created from it.

You can look at remoting configuration under:

<JBoss>/server/<YourMessagingServer>/deploy/jboss-messaging.sar/remoting-service.xml

By default JBoss Messaging binds to ${jboss.bind.address} which can be defined by: ./run.sh -c <yourconfig> -b yourIP.

You can change remoting-service.xml if you want for example use a different communication port, or change any other network behavior.

6.6. Configuring the callback

JBoss Messaging uses a callback mechanism from Remoting that needs a Socket for callback operations. These socket properties are passed to the server by a remote call when the connection is being estabilished. As we said before we will support bidirectional protocols in future releases.

By default JBoss Messaging will execute InetAddress.getLocalHost().getHostAddress() to access your local host IP, but in case you need to setup a different IP, you can define a system property in your java arguments:

Use java -Djboss.messaging.callback.bind.address=YourHost - That will determine the callBack host in your client.

The client port will be selected randomly for any non used port. But if you defined -Djboss.messaging.callback.bind.port=NumericPort in your System Properties that number is going to be used for the call back client port.