http://git-wip-us.apache.org/repos/asf/activemq-6/blob/8ecd255f/docs/user-manual/en/appserver-integration.xml
----------------------------------------------------------------------
diff --git a/docs/user-manual/en/appserver-integration.xml
b/docs/user-manual/en/appserver-integration.xml
new file mode 100644
index 0000000..6335411
--- /dev/null
+++ b/docs/user-manual/en/appserver-integration.xml
@@ -0,0 +1,1342 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
=============================================================================
-->
+<!-- Copyright © 2009 Red Hat, Inc. and others.
-->
+<!--
-->
+<!-- The text of and illustrations in this document are licensed by Red Hat
under -->
+<!-- a Creative Commons AttributionâShare Alike 3.0 Unported license
("CC-BY-SA"). -->
+<!--
-->
+<!-- An explanation of CC-BY-SA is available at
-->
+<!--
-->
+<!-- http://creativecommons.org/licenses/by-sa/3.0/.
-->
+<!--
-->
+<!-- In accordance with CC-BY-SA, if you distribute this document or an
adaptation -->
+<!-- of it, you must provide the URL for the original version.
-->
+<!--
-->
+<!-- Red Hat, as the licensor of this document, waives the right to enforce,
-->
+<!-- and agrees not to assert, Section 4d of CC-BY-SA to the fullest extent
-->
+<!-- permitted by applicable law.
-->
+<!--
=============================================================================
-->
+
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % BOOK_ENTITIES SYSTEM "HornetQ_User_Manual.ent">
+%BOOK_ENTITIES;
+]>
+<chapter id="appserver-integration">
+ <title>Application Server Integration and Java EE</title>
+ <para>HornetQ can be easily installed in JBoss Application Server 4 or
later. For details on
+ installing HornetQ in the JBoss Application Server please refer to
quick-start guide.</para>
+ <para>Since HornetQ also provides a JCA adapter, it is also possible to
integrate HornetQ
+ as a JMS provider in other JEE compliant app servers. For instructions
on how to integrate a
+ remote JCA adaptor into another application sever, please consult the
other application server's
+ instructions.</para>
+ <para>A JCA Adapter basically controls the inflow of messages to
Message-Driven Beans (MDBs) and the
+ outflow of messages sent from other JEE components, e.g. EJBs and
Servlets.</para>
+ <para>This section explains the basics behind configuring the different
JEE components in the
+ AS.</para>
+ <section id="configuring-mdbs">
+ <title>Configuring Message-Driven Beans</title>
+ <para>The delivery of messages to an MDB using HornetQ is configured
on the JCA Adapter via
+ a configuration file <literal>ra.xml</literal> which can be found
under the <literal
+ >jms-ra.rar</literal> directory. By default this is configured
to consume
+ messages using an InVM connector from the instance of HornetQ
running within the
+ application server. The configuration properties are listed later
in this chapter. </para>
+ <para>All MDBs however need to have the destination type and the
destination configured.
+ The following example shows how this can be done using
annotations:</para>
+ <programlisting>
+@MessageDriven(name = "MDBExample", activationConfig =
+{
+ @ActivationConfigProperty(propertyName = "destinationType", propertyValue =
"javax.jms.Queue"),
+ @ActivationConfigProperty(propertyName = "destination", propertyValue =
"queue/testQueue")
+})
+@ResourceAdapter("hornetq-ra.rar")
+public class MDBExample implements MessageListener
+{
+ public void onMessage(Message message)...
+}</programlisting>
+ <para>In this example you can see that the MDB will consume messages
from a queue that is
+ mapped into JNDI with the binding
<literal>queue/testQueue</literal>. This queue must be
+ preconfigured in the usual way using the HornetQ configuration
files.</para>
+ <para>The <literal>ResourceAdapter</literal> annotation is used to
specify which adaptor
+ should be used. To use this you will need to import <literal
+ >org.jboss.ejb3.annotation.ResourceAdapter</literal> for JBoss
AS 5.X and later version which can be found in the
+ <literal>jboss-ejb3-ext-api.jar</literal> which can be found
in the JBoss
+ repository. For JBoss AS 4.X, the annotation to use is
<literal>org.jboss.annotation.ejb.ResourceAdaptor</literal>.</para>
+ <para>
+ Alternatively you can add use a deployment descriptor and add
something like
+ the following to <literal
+ >jboss.xml</literal><programlisting><message-driven>
+ <ejb-name>ExampleMDB</ejb-name>
+ <resource-adapter-name>hornetq-ra.rar</resource-adapter-name>
+</message-driven>
+</programlisting>You
+ can also rename the hornetq-ra.rar directory to jms-ra.rar and
neither the annotation or
+ the extra descriptor information will be needed. If you do this
you will need to edit
+ the <literal>jms-ds.xml</literal> datasource file and change
<literal>rar-name</literal>
+ element.</para>
+ <note>
+ <para>HornetQ is the default JMS provider for JBoss AS 6. Starting
with this AS version, HornetQ resource
+ adapter is named <literal>jms-ra.rar</literal> and you no longer
need to annotate the MDB for the resource adapter name.</para>
+ </note>
+ <para>All the examples shipped with the HornetQ distribution use the
annotation.</para>
+ <section>
+ <title>Using Container-Managed Transactions</title>
+ <para>When an MDB is using Container-Managed Transactions (CMT),
the delivery of the
+ message is done within the scope of a JTA transaction. The
commit or rollback of
+ this transaction is controlled by the container itself. If the
transaction is rolled
+ back then the message delivery semantics will kick in (by
default, it will try to
+ redeliver the message up to 10 times before sending to a DLQ).
Using annotations
+ this would be configured as follows:</para>
+ <programlisting>
+@MessageDriven(name = "MDB_CMP_TxRequiredExample", activationConfig =
+{
+ @ActivationConfigProperty(propertyName = "destinationType", propertyValue =
"javax.jms.Queue"),
+ @ActivationConfigProperty(propertyName = "destination", propertyValue =
"queue/testQueue")
+})
+@TransactionManagement(value= TransactionManagementType.CONTAINER)
+@TransactionAttribute(value= TransactionAttributeType.REQUIRED)
+@ResourceAdapter("hornetq-ra.rar")
+public class MDB_CMP_TxRequiredExample implements MessageListener
+{
+ public void onMessage(Message message)...
+}</programlisting>
+ <para>The <literal>TransactionManagement</literal> annotation
tells the container to manage the
+ transaction. The <literal>TransactionAttribute</literal>
annotation tells the container that a JTA
+ transaction is required for this MDB. Note that the only other
valid value for this
+ is <literal>TransactionAttributeType.NOT_SUPPORTED</literal>
which tells the
+ container that this MDB does not support JTA transactions and
one should not be
+ created.</para>
+ <para>It is also possible to inform the container that it must
rollback the transaction
+ by calling <literal>setRollbackOnly</literal> on the <literal
+ >MessageDrivenContext</literal>. The code for this would
look something
+ like:</para>
+ <programlisting>
+@Resource
+MessageDrivenContextContext ctx;
+
+public void onMessage(Message message)
+{
+ try
+ {
+ //something here fails
+ }
+ catch (Exception e)
+ {
+ ctx.setRollbackOnly();
+ }
+}</programlisting>
+ <para>If you do not want the overhead of an XA transaction being
created every time but
+ you would still like the message delivered within a
transaction (i.e. you are only
+ using a JMS resource) then you can configure the MDB to use a
local transaction.
+ This would be configured as such:</para>
+ <programlisting>
+@MessageDriven(name = "MDB_CMP_TxLocalExample", activationConfig =
+{
+ @ActivationConfigProperty(propertyName = "destinationType",
propertyValue = "javax.jms.Queue"),
+ @ActivationConfigProperty(propertyName = "destination", propertyValue =
"queue/testQueue"),
+ @ActivationConfigProperty(propertyName = "useLocalTx", propertyValue =
"true")
+})
+@TransactionManagement(value = TransactionManagementType.CONTAINER)
+@TransactionAttribute(value = TransactionAttributeType.NOT_SUPPORTED)
+@ResourceAdapter("hornetq-ra.rar")
+public class MDB_CMP_TxLocalExample implements MessageListener
+{
+ public void onMessage(Message message)...
+}</programlisting>
+ </section>
+ <section>
+ <title>Using Bean-Managed Transactions</title>
+ <para>Message-driven beans can also be configured to use
Bean-Managed Transactions
+ (BMT). In this case a User Transaction is created. This would
be configured as
+ follows:</para>
+ <programlisting>
+@MessageDriven(name = "MDB_BMPExample", activationConfig =
+{
+ @ActivationConfigProperty(propertyName = "destinationType", propertyValue =
"javax.jms.Queue"),
+ @ActivationConfigProperty(propertyName = "destination", propertyValue =
"queue/testQueue"),
+ @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue =
"Dups-ok-acknowledge")
+})
+@TransactionManagement(value= TransactionManagementType.BEAN)
+@ResourceAdapter("hornetq-ra.rar")
+public class MDB_BMPExample implements MessageListener
+{
+ public void onMessage(Message message)
+}</programlisting>
+ <para>When using Bean-Managed Transactions the message delivery to
the MDB will occur
+ outside the scope of the user transaction and use the
acknowledge mode specified by
+ the user with the <literal>acknowledgeMode</literal> property.
There are only 2
+ acceptable values for this <literal>Auto-acknowledge</literal>
and <literal
+ >Dups-ok-acknowledge</literal>. Please note that because
the message delivery is outside
+ the scope of the transaction a failure within the MDB will not
cause the message to
+ be redelivered.</para>
+ <para>A user would control the life-cycle of the transaction
something like the
+ following:</para>
+ <programlisting>
+@Resource
+MessageDrivenContext ctx;
+
+public void onMessage(Message message)
+{
+ UserTransaction tx;
+ try
+ {
+ TextMessage textMessage = (TextMessage)message;
+
+ String text = textMessage.getText();
+
+ UserTransaction tx = ctx.getUserTransaction();
+
+ tx.begin();
+
+ //do some stuff within the transaction
+
+ tx.commit();
+
+ }
+ catch (Exception e)
+ {
+ tx.rollback();
+ }
+}</programlisting>
+ </section>
+ <section>
+ <title>Using Message Selectors with Message-Driven Beans</title>
+ <para>It is also possible to use MDBs with message selectors. To
do this simple define
+ your message selector as follows:</para>
+ <programlisting>
+@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)
+@ResourceAdapter("hornetq-ra.rar")
+public class MDBMessageSelectorExample implements MessageListener
+{
+ public void onMessage(Message message)....
+}</programlisting>
+ </section>
+ </section>
+ <section>
+ <title>Sending Messages from within JEE components</title>
+ <para>The JCA adapter can also be used for sending messages. The
Connection Factory to use
+ is configured by default in the <literal>jms-ds.xml</literal> file
and is mapped to
+ <literal>java:/JmsXA</literal>. Using this from within a JEE
component will mean
+ that the sending of the message will be done as part of the JTA
transaction being used
+ by the component.</para>
+ <para>This means that if the sending of the message fails the overall
transaction would
+ rollback and the message be re-sent. Heres an example of this from
within an
+ MDB:</para>
+ <programlisting>
+@MessageDriven(name = "MDBMessageSendTxExample", activationConfig =
+{
+ @ActivationConfigProperty(propertyName = "destinationType", propertyValue =
"javax.jms.Queue"),
+ @ActivationConfigProperty(propertyName = "destination", propertyValue =
"queue/testQueue")
+})
+@TransactionManagement(value= TransactionManagementType.CONTAINER)
+@TransactionAttribute(value= TransactionAttributeType.REQUIRED)
+@ResourceAdapter("hornetq-ra.rar")
+public class MDBMessageSendTxExample implements MessageListener
+{
+ @Resource(mappedName = "java:/JmsXA")
+ ConnectionFactory connectionFactory;
+
+ @Resource(mappedName = "queue/replyQueue")
+ Queue replyQueue;
+
+ public void onMessage(Message message)
+ {
+ Connection conn = null;
+ try
+ {
+ //Step 9. We know the client is sending a text message so we cast
+ TextMessage textMessage = (TextMessage)message;
+
+ //Step 10. get the text from the message.
+ String text = textMessage.getText();
+
+ System.out.println("message " + text);
+
+ conn = connectionFactory.createConnection();
+
+ Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageProducer producer = sess.createProducer(replyQueue);
+
+ producer.send(sess.createTextMessage("this is a reply"));
+
+ }
+ catch (Exception e)
+ {
+ e.printStackTrace();
+ }
+ finally
+ {
+ if(conn != null)
+ {
+ try
+ {
+ conn.close();
+ }
+ catch (JMSException e)
+ {
+ }
+ }
+ }
+ }
+ }</programlisting>
+ <para>In JBoss Application Server you can use the JMS JCA adapter for
sending messages from
+ EJBs (including Session, Entity and Message-Driven Beans),
Servlets (including jsps) and
+ custom MBeans.</para>
+ </section>
+ <section>
+ <title>MDB and Consumer pool size</title>
+ <para>Most application servers, including JBoss, allow you to configure
how many MDB's there are in a pool. In
+ JBoss this is configured via the <literal>MaxPoolSize</literal>
parameter in the ejb3-interceptors-aop.xml file. Configuring
+ this has no actual effect on how many sessions/consumers there
actually are created. This is because the Resource
+ Adaptor implementation knows nothing about the application servers MDB
implementation. So even if you set the MDB
+ pool size to 1, 15 sessions/consumers will be created (this is the
default). If you want to limit how many
+ sessions/consumers are created then you need to set the
<literal>maxSession</literal> parameter either on the
+ resource adapter itself or via an an Activation Config Property on the
MDB itself</para>
+ <programlisting>
+@MessageDriven(name = "MDBMessageSendTxExample", activationConfig =
+{
+ @ActivationConfigProperty(propertyName = "destinationType", propertyValue =
"javax.jms.Queue"),
+ @ActivationConfigProperty(propertyName = "destination", propertyValue =
"queue/testQueue"),
+ @ActivationConfigProperty(propertyName = "maxSession", propertyValue = "1")
+})
+@TransactionManagement(value= TransactionManagementType.CONTAINER)
+@TransactionAttribute(value= TransactionAttributeType.REQUIRED)
+@ResourceAdapter("hornetq-ra.rar")
+public class MyMDB implements MessageListener
+{ ....}
+ </programlisting>
+ </section>
+ <section>
+ <title>Configuring the JCA Adaptor</title>
+ <para>The Java Connector Architecture (JCA) Adapter is what allows
HornetQ to be integrated
+ with JEE components such as MDBs and EJBs. It configures how
components such as MDBs
+ consume messages from the HornetQ server and also how components
such as EJBs or
+ Servlets can send messages.</para>
+ <para>The HornetQ JCA adapter is deployed via the
<literal>jms-ra.rar</literal> archive. The
+ configuration of the adapter is found in this archive under
<literal
+ >META-INF/ra.xml</literal>.</para>
+ <para>The configuration will look something like the following:</para>
+ <programlisting>
+<resourceadapter>
+
<resourceadapter-class>org.hornetq.ra.HornetQResourceAdapter</resourceadapter-class>
+ <config-property>
+ <description>The transport type. Multiple connectors can be
configured by using a comma separated list,
+ i.e.
org.hornetq.core.remoting.impl.invm.InVMConnectorFactory,org.hornetq.core.remoting.impl.invm.InVMConnectorFactory.</description>
+ <config-property-name>ConnectorClassName</config-property-name>
+ <config-property-type>java.lang.String</config-property-type>
+
<config-property-value>org.hornetq.core.remoting.impl.invm.InVMConnectorFactory</config-property-value>
+ </config-property>
+ <config-property>
+ <description>The transport configuration. These values must be in the
form of key=val;key=val;,
+ if multiple connectors are used then each set must be separated by a
comma i.e. host=host1;port=5445,host=host2;port=5446.
+ Each set of parameters maps to the connector classname
specified.</description>
+ <config-property-name>ConnectionParameters</config-property-name>
+ <config-property-type>java.lang.String</config-property-type>
+ <config-property-value>server-id=0</config-property-value>
+ </config-property>
+
+ <outbound-resourceadapter>
+ <connection-definition>
+
<managedconnectionfactory-class>org.hornetq.ra.HornetQRAManagedConnection
+ Factory</managedconnectionfactory-class>
+
+ <config-property>
+ <description>The default session type</description>
+
<config-property-name>SessionDefaultType</config-property-name>
+ <config-property-type>java.lang.String</config-property-type>
+
<config-property-value>javax.jms.Queue</config-property-value>
+ </config-property>
+ <config-property>
+ <description>Try to obtain a lock within specified number of
seconds; less
+ than or equal to 0 disable this functionality</description>
+ <config-property-name>UseTryLock</config-property-name>
+
<config-property-type>java.lang.Integer</config-property-type>
+ <config-property-value>0</config-property-value>
+ </config-property>
+
+
<connectionfactory-interface>org.hornetq.ra.HornetQRAConnectionFactory
+ </connectionfactory-interface>
+
<connectionfactororg.hornetq.ra.HornetQConnectionFactoryImplonFactoryImpl
+ </connectionfactory-impl-class>
+ <connection-interface>javax.jms.Session</connection-interface>
+ <connection-impl-class>org.hornetq.ra.HornetQRASession
+ </connection-impl-class>
+ </connection-definition>
+ <transaction-support>XATransaction</transaction-support>
+ <authentication-mechanism>
+ <authentication-mechanism-type>BasicPassword
+ </authentication-mechanism-type>
+
<credential-interface>javax.resource.spi.security.PasswordCredential
+ </credential-interface>
+ </authentication-mechanism>
+ <reauthentication-support>false</reauthentication-support>
+ </outbound-resourceadapter>
+
+ <inbound-resourceadapter>
+ <messageadapter>
+ <messagelistener>
+
<messagelistener-type>javax.jms.MessageListener</messagelistener-type>
+ <activationspec>
+
<activationspec-class>org.hornetq.ra.inflow.HornetQActivationSpec
+ </activationspec-class>
+ <required-config-property>
+
<config-property-name>destination</config-property-name>
+ </required-config-property>
+ </activationspec>
+ </messagelistener>
+ </messageadapter>
+ </inbound-resourceadapter>
+</resourceadapter></programlisting>
+ <para>There are three main parts to this configuration.</para>
+ <orderedlist>
+ <listitem>
+ <para>A set of global properties for the adapter</para>
+ </listitem>
+ <listitem>
+ <para>The configuration for the outbound part of the adapter.
This is used for
+ creating JMS resources within EE components. </para>
+ </listitem>
+ <listitem>
+ <para>The configuration of the inbound part of the adapter.
This is used for
+ controlling the consumption of messages via MDBs. </para>
+ </listitem>
+ </orderedlist>
+ <section>
+ <title>Global Properties</title>
+ <para>The first element you see is
<literal>resourceadapter-class</literal> which should
+ be left unchanged. This is the HornetQ resource adapter
class.</para>
+ <para>After that there is a list of configuration properties. This
will be where most of
+ the configuration is done. The first two properties configure
the transport used by the adapter
+ and the rest configure the connection factory itself.
+ </para>
+ <note>
+ <para>All connection factory properties will use the defaults
if they are not provided, except
+ for the <literal>reconnectAttempts</literal> which will
default to -1. This
+ signifies that the connection should attempt to reconnect on
connection
+ failure indefinitely. This is only used when the adapter is
configured to
+ connect to a remote server as an InVM connector can never
fail.
+ </para>
+ </note>
+ <para>The following table explains what each property is
for.</para>
+ <table frame="topbot" border="2">
+ <title>Global Configuration Properties</title>
+ <tgroup cols="3">
+ <colspec colname="c1" colnum="1"/>
+ <colspec colname="c2" colnum="2"/>
+ <colspec colname="c3" colnum="3"/>
+ <thead>
+ <row>
+ <entry>Property Name</entry>
+ <entry>Property Type</entry>
+ <entry>Property Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>ConnectorClassName</entry>
+ <entry>String</entry>
+ <entry>The Connector class name (see <xref
+ linkend="configuring-transports"/> for
more information). If multiple connectors are
+ needed this should be provided as a comma
separated list.</entry>
+ </row>
+ <row>
+ <entry>ConnectionParameters</entry>
+ <entry>String</entry>
+ <entry>The transport configuration. These
parameters must be in the form of
+ <literal>key1=val1;key2=val2;</literal> and
will be specific to the connector used. If
+ multiple connectors are configured then
parameters should be supplied for each connector
+ separated by a comma.
+ </entry>
+ </row>
+ <row>
+ <entry>ha</entry>
+ <entry>boolean</entry>
+ <entry>True if high availability is needed.</entry>
+ </row>
+ <row>
+ <entry>useLocalTx</entry>
+ <entry>boolean</entry>
+ <entry>True will enable local transaction
optimisation.</entry>
+ </row>
+ <row>
+ <entry>UserName</entry>
+ <entry>String</entry>
+ <entry>The user name to use when making a
connection </entry>
+ </row>
+ <row>
+ <entry>Password</entry>
+ <entry>String</entry>
+ <entry>The password to use when making a
connection</entry>
+ </row>
+ <row>
+ <entry>
+ <link
linkend="configuration.discovery-group.group-address">DiscoveryAddress</link></entry>
+ <entry>String</entry>
+ <entry>The discovery group address to use to
auto-detect a server</entry>
+ </row>
+ <row>
+ <entry>
+ <link
linkend="configuration.discovery-group.group-port">DiscoveryPort</link></entry>
+ <entry>Integer</entry>
+ <entry>The port to use for discovery</entry>
+ </row>
+ <row>
+ <entry>
+ <link
linkend="configuration.discovery-group.refresh-timeout">DiscoveryRefreshTimeout</link></entry>
+ <entry>Long</entry>
+ <entry>The timeout, in milliseconds, to
refresh.</entry>
+ </row>
+ <row>
+ <entry>
+ <link
linkend="configuration.connection-factory.discovery-initial-wait-timeout">
+ DiscoveryInitialWaitTimeout
+ </link>
+ </entry>
+ <entry>Long</entry>
+ <entry>The initial time to wait for
discovery.</entry>
+ </row>
+ <row>
+ <entry>
+ <link
linkend="configuration.connection-factory.connection-load-balancing-policy-class-name">
+ ConnectionLoadBalancingPolicyClassName</link>
+ </entry>
+ <entry>String</entry>
+ <entry>The load balancing policy class to
use.</entry>
+ </row>
+ <row>
+ <entry>
+ <link
linkend="configuration.connection-factory.connection-ttl">ConnectionTTL</link>
+ </entry>
+ <entry>Long</entry>
+ <entry>The time to live (in milliseconds) for the
connection.</entry>
+ </row>
+ <row>
+ <entry>
+ <link
linkend="configuration.connection-factory.call-timeout">CallTimeout</link>
+ </entry>
+ <entry>Long</entry>
+ <entry>the call timeout (in milliseconds) for each
packet sent.</entry>
+ </row>
+ <row>
+ <entry>
+ <link
linkend="configuration.connection-factory.dups-ok-batch-size">DupsOKBatchSize</link>
+ </entry>
+ <entry>Integer</entry>
+ <entry>the batch size (in bytes) between
acknowledgements when using
+ DUPS_OK_ACKNOWLEDGE mode</entry>
+ </row>
+ <row>
+ <entry>
+ <link
linkend="configuration.connection-factory.transaction-batch-size">TransactionBatchSize</link>
+ </entry>
+ <entry>Integer</entry>
+ <entry>the batch size (in bytes) between
acknowledgements when using a
+ transactional session</entry>
+ </row>
+ <row>
+ <entry>
+ <link
linkend="configuration.connection-factory.consumer-window-size">ConsumerWindowSize</link>
+ </entry>
+ <entry>Integer</entry>
+ <entry>the window size (in bytes) for consumer
flow control</entry>
+ </row>
+ <row>
+ <entry>
+ <link
linkend="configuration.connection-factory.consumer-max-rate">ConsumerMaxRate</link>
+ </entry>
+ <entry>Integer</entry>
+ <entry>the fastest rate a consumer may consume
messages per second</entry>
+ </row>
+ <row>
+ <entry>
+ <link
linkend="configuration.connection-factory.confirmation-window-size">ConfirmationWindowSize</link>
+ </entry>
+ <entry>Integer</entry>
+ <entry>the window size (in bytes) for reattachment
confirmations</entry>
+ </row>
+ <row>
+ <entry>
+ <link
linkend="configuration.connection-factory.producer-max-rate">ProducerMaxRate</link>
+ </entry>
+ <entry>Integer</entry>
+ <entry>the maximum rate of messages per second
that can be sent</entry>
+ </row>
+ <row>
+ <entry>
+ <link
linkend="configuration.connection-factory.min-large-message-size">MinLargeMessageSize</link>
+ </entry>
+ <entry>Integer</entry>
+ <entry>the size (in bytes) before a message is
treated as large </entry>
+ </row>
+ <row>
+ <entry>
+ <link
linkend="configuration.connection-factory.block-on-acknowledge">BlockOnAcknowledge</link>
+ </entry>
+ <entry>Boolean</entry>
+ <entry>whether or not messages are acknowledged
synchronously</entry>
+ </row>
+ <row>
+ <entry>
+ <link
linkend="configuration.connection-factory.block-on-non-durable-send">BlockOnNonDurableSend</link>
+ </entry>
+ <entry>Boolean</entry>
+ <entry>whether or not non-durable messages are
sent synchronously</entry>
+ </row>
+ <row>
+ <entry>
+ <link
linkend="configuration.connection-factory.block-on-durable-send">BlockOnDurableSend</link>
+ </entry>
+ <entry>Boolean</entry>
+ <entry>whether or not durable messages are sent
synchronously</entry>
+ </row>
+ <row>
+ <entry>
+ <link
linkend="configuration.connection-factory.auto-group">AutoGroup</link>
+ </entry>
+ <entry>Boolean</entry>
+ <entry>whether or not message grouping is
automatically used</entry>
+ </row>
+ <row>
+ <entry>
+ <link
linkend="configuration.connection-factory.pre-acknowledge">PreAcknowledge</link>
+ </entry>
+ <entry>Boolean</entry>
+ <entry>whether messages are pre acknowledged by
the server before
+ sending</entry>
+ </row>
+ <row>
+ <entry>
+ <link
linkend="configuration.connection-factory.reconnect-attempts">ReconnectAttempts</link>
+ </entry>
+ <entry>Integer</entry>
+ <entry>maximum number of retry attempts, default
for the resource adapter is -1 (infinite attempts)</entry>
+ </row>
+ <row>
+ <entry>
+ <link
linkend="configuration.connection-factory.retry-interval">RetryInterval</link>
+ </entry>
+ <entry>Long</entry>
+ <entry>the time (in milliseconds) to retry a
connection after failing</entry>
+ </row>
+ <row>
+ <entry>
+ <link
linkend="configuration.connection-factory.retry-interval-multiplier">RetryIntervalMultiplier</link>
+ </entry>
+ <entry>Double</entry>
+ <entry>multiplier to apply to successive retry
intervals</entry>
+ </row>
+ <row>
+ <entry>
+ <link
linkend="configuration.connection-factory.failover-on-server-shutdown">FailoverOnServerShutdown</link>
+ </entry>
+ <entry>Boolean</entry>
+ <entry>If true client will reconnect to another
server if
+ available</entry>
+ </row>
+ <row>
+ <entry>
+ <link
linkend="configuration.connection-factory.client-id">ClientID</link>
+ </entry>
+ <entry>String</entry>
+ <entry>the pre-configured client ID for the
connection factory</entry>
+ </row>
+ <row>
+ <entry>
+ <link
linkend="configuration.connection-factory.client-failure-check-period">ClientFailureCheckPeriod</link>
+ </entry>
+ <entry>Long</entry>
+ <entry>the period (in ms) after which the client
will consider the
+ connection failed after not receiving packets
from the
+ server</entry>
+ </row>
+ <row>
+ <entry>
+ <link
linkend="configuration.connection-factory.use-global-pools">UseGlobalPools</link>
+ </entry>
+ <entry>Boolean</entry>
+ <entry>whether or not to use a global thread pool
for threads</entry>
+ </row>
+ <row>
+ <entry>
+ <link
linkend="configuration.connection-factory.scheduled-thread-pool-max-size">ScheduledThreadPoolMaxSize</link>
+ </entry>
+ <entry>Integer</entry>
+ <entry>the size of the <emphasis>scheduled
thread</emphasis> pool</entry>
+ </row>
+ <row>
+ <entry>
+ <link
linkend="configuration.connection-factory.thread-pool-max-size">ThreadPoolMaxSize</link>
+ </entry>
+ <entry>Integer</entry>
+ <entry>the size of the thread pool</entry>
+ </row>
+ <row>
+ <entry>SetupAttempts</entry>
+ <entry>Integer</entry>
+ <entry>Number of attempts to setup a JMS
connection (default is 10, -1 means to attempt infinitely). It is possible
+ that the MDB is deployed before the JMS
resources are available. In that case, the resource
+ adapter will try to setup several times until
the resources are available. This applies only for inbound connections</entry>
+ </row>
+ <row>
+ <entry>SetupInterval</entry>
+ <entry>Long</entry>
+ <entry>Interval in milliseconds between
consecutive attempts to setup a JMS connection (default is 2000m). This applies
only for inbound connections</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+ <section>
+ <title>Adapter Outbound Configuration</title>
+ <para>The outbound configuration should remain unchanged as they
define connection
+ factories that are used by Java EE components. These
Connection Factories can be
+ defined inside a configuration file that matches the name
<literal
+ >*-ds.xml</literal>. You'll find a default
<literal>jms-ds.xml</literal>
+ configuration under the <literal>hornetq</literal> directory
in the JBoss AS
+ deployment. The connection factories defined in this file
inherit their
+ properties from the main <literal>ra.xml</literal>
configuration but can also be
+ overridden. The following example shows how to override
them.</para>
+ <note>
+ <para>Please note that this configuration only applies when
HornetQ resource adapter is installed in
+ JBoss Application Server. If you are using another JEE
application
+ server please refer to your application servers documentation
for how to do
+ this.</para>
+ </note>
+ <programlisting>
+<tx-connection-factory>
+ <jndi-name>RemoteJmsXA</jndi-name>
+ <xa-transaction/>
+ <rar-name>jms-ra.rar</rar-name>
+ <connection-definition>org.hornetq.ra.HornetQRAConnectionFactory
+</connection-definition>
+<config-property name="SessionDefaultType"
type="String">javax.jms.Topic</config-property>
+ <config-property name="ConnectorClassName" type="String">
+ org.hornetq.core.remoting.impl.netty.NettyConnectorFactory
+ </config-property>
+ <config-property name="ConnectionParameters" type="String">
+ port=5445</config-property>
+ <max-pool-size>20</max-pool-size>
+</tx-connection-factory></programlisting>
+ <warning>
+ <title>overriding connectors</title>
+ <para>If the connector class name is overridden the all
parameters must also be supplied.</para>
+ </warning>
+ <para>In this example the connection factory will be bound to JNDI
with the name
+ <literal>RemoteJmsXA</literal> and can be looked up in the
usual way using JNDI
+ or defined within the EJB or MDB as such:</para>
+ <programlisting>
+@Resource(mappedName="java:/RemoteJmsXA")
+private ConnectionFactory connectionFactory;</programlisting>
+ <para>The <literal>config-property</literal> elements are what
overrides those in the
+ <literal>ra.xml</literal> configuration file. Any of the
elements pertaining to the
+ connection factory can be overridden here.</para>
+ <para>The outbound configuration also defines additional
properties in addition to the global configuration properties.</para>
+
+ <table frame="topbot" border="2">
+ <title>Outbound Configuration Properties</title>
+ <tgroup cols="3">
+ <colspec colname="c1" colnum="1"/>
+ <colspec colname="c2" colnum="2"/>
+ <colspec colname="c3" colnum="3"/>
+ <thead>
+ <row>
+ <entry>Property Name</entry>
+ <entry>Property Type</entry>
+ <entry>Property Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>SessionDefaultType</entry>
+ <entry>String</entry>
+ <entry>the default session type</entry>
+ </row>
+ <row>
+ <entry>UseTryLock</entry>
+ <entry>Integer</entry>
+ <entry>try to obtain a lock within specified
number of seconds. less
+ than or equal to 0 disable this
functionality</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+ <section>
+ <title>Adapter Inbound Configuration</title>
+ <para>The inbound configuration should again remain unchanged.
This controls what
+ forwards messages onto MDBs. It is possible to override
properties on the MDB by
+ adding an activation configuration to the MDB itself. This
could be used to
+ configure the MDB to consume from a different server.</para>
+ <para>The inbound configuration also defines additional
properties in addition to the global configuration properties.</para>
+
+ <table frame="topbot" border="2">
+ <title>Inbound Configuration Properties</title>
+ <tgroup cols="3">
+ <colspec colname="c1" colnum="1"/>
+ <colspec colname="c2" colnum="2"/>
+ <colspec colname="c3" colnum="3"/>
+ <thead>
+ <row>
+ <entry>Property Name</entry>
+ <entry>Property Type</entry>
+ <entry>Property Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>Destination</entry>
+ <entry>String</entry>
+ <entry>JNDI name of the destination</entry>
+ </row>
+ <row>
+ <entry>DestinationType</entry>
+ <entry>String</entry>
+ <entry>type of the destination, either
<literal>javax.jms.Queue</literal> or <literal>javax.jms.Topic</literal>
+ (default is javax.jms.Queue)</entry>
+ </row>
+ <row>
+ <entry>AcknowledgeMode</entry>
+ <entry>String</entry>
+ <entry>The Acknowledgment mode, either
<literal>Auto-acknowledge</literal> or <literal>Dups-ok-acknowledge</literal>
+ (default is Auto-acknowledge).
<literal>AUTO_ACKNOWLEDGE</literal> and <literal>DUPS_OK_ACKNOWLEDGE</literal>
are acceptable values.</entry>
+ </row>
+ <row>
+ <entry>JndiParams</entry>
+ <entry>String</entry>
+ <entry>A semicolon (';') delimited string of
name=value pairs which represent the properties to be used for the destination
JNDI
+ look up. The properties depends on the JNDI
implementation of the server hosting HornetQ. Typically only be used when the
MDB is
+ configured to consume from a remote
destination and needs to look up a JNDI reference rather than the HornetQ name
of the
+ destination. Only relevant when
<literal>useJNDI</literal> is <literal>true</literal> (default is an empty
string).</entry>
+ </row>
+ <row>
+ <entry>MaxSession</entry>
+ <entry>Integer</entry>
+ <entry>Maximum number of session created by
this inbound configuration (default is 15)</entry>
+ </row>
+ <row>
+ <entry>MessageSelector</entry>
+ <entry>String</entry>
+ <entry>the message selector of the
consumer</entry>
+ </row>
+ <row>
+ <entry>SubscriptionDurability</entry>
+ <entry>String</entry>
+ <entry>Type of the subscription, either
<literal>Durable</literal> or <literal>NonDurable</literal></entry>
+ </row>
+ <row>
+ <entry>ShareSubscriptions</entry>
+ <entry>Boolean</entry>
+ <entry>When true, multiple MDBs can share the
same <literal>Durable</literal> subscription</entry>
+ </row>
+ <row>
+ <entry>SubscriptionName</entry>
+ <entry>String</entry>
+ <entry>Name of the subscription</entry>
+ </row>
+ <row>
+ <entry>TransactionTimeout</entry>
+ <entry>Long</entry>
+ <entry>The transaction timeout in milliseconds
(default is 0, the transaction does not timeout)</entry>
+ </row>
+ <row>
+ <entry>UseJNDI</entry>
+ <entry>Boolean</entry>
+ <entry>Whether or not use JNDI to look up the
destination (default is true)</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+
+ </section>
+ <section>
+ <title>Configuring the adapter to use a standalone HornetQ
Server</title>
+ <para>Sometime you may want your messaging server on a different
machine or separate from the application server.
+ If this is the case you will only need the hornetq client libs
installed. This section explains what config to create
+ and what jar dependencies are needed.</para>
+ <section>
+ <para>There are two configuration files needed to do this, one
for the incoming adapter used for MDB's
+ and one for outgoing connections managed by the JCA managed
connection pool used by outgoing JEE components
+ wanting outgoing connections.</para>
+ <section>
+ <title>Configuring the Incoming Adaptor</title>
+ <para>Firstly you will need to create directory under the
+ <literal>deploy</literal>
+ directory ending in
+ <literal>.rar.</literal>
+ For this example we will name the directory
<literal>hornetq-ra.rar</literal>. This detail is
+ important as
+ the name of directory is referred to by the MDB's and
the outgoing configuration.
+
+ </para>
+ <note>
+ <para>The jboss default for this is
<literal>jms-ra.rar</literal>, If you don't want to have to
+ configure your
+ MDB's you can use this but you may need to remove the
generic adaptor that uses this.
+ </para>
+ </note>
+ <para>Under the
+ <literal>hornetq-ra.rar</literal>
+ directory you will need to create a
+ <literal>META-INF</literal>
+ directory into which you should create an
+ <literal>ra.xml</literal>
+ configuration file. You can find a template
+ for the
+ <literal>ra.xml</literal>
+ under the config directory of the HornetQ distribution.
+ </para>
+ <para>To configure MDB's to consume messages from a remote
HornetQ server you need to edit the
+ <literal>ra.xml</literal>
+ file under
+ <literal>deploy/hornet-ra.rar/META-INF</literal>
+ and change the transport type to
+ use a netty connector (instead of the invm connector that
is defined) and configure its transport
+ parameters.
+ Heres an example of what this would look like:
+ </para>
+ <programlisting>
+<resourceadapter-class>org.hornetq.ra.HornetQResourceAdapter</resourceadapter-class>
+ <config-property>
+ <description>The transport type</description>
+ <config-property-name>ConnectorClassName</config-property-name>
+ <config-property-type>java.lang.String</config-property-type>
+
<config-property-value>org.hornetq.core.remoting.impl.netty.NettyConnectorFactory</config-property-value>
+ </config-property>
+ <config-property>
+ <description>The transport configuration. These values must be in the
form of key=val;key=val;</description>
+ <config-property-name>ConnectionParameters</config-property-name>
+ <config-property-type>java.lang.String</config-property-type>
+
<config-property-value>host=127.0.0.1;port=5446</config-property-value>
+</config-property></programlisting>
+ <para>
+ If you want to provide a list of servers that the adapter
can connect to you can provide a list of
+ connectors, each separated by a comma.
+ </para>
+
+ <programlisting>
+<resourceadapter-class>org.hornetq.ra.HornetQResourceAdapter</resourceadapter-class>
+ <config-property>
+ <description>The transport type</description>
+ <config-property-name>ConnectorClassName</config-property-name>
+ <config-property-type>java.lang.String</config-property-type>
+
<config-property-value>org.hornetq.core.remoting.impl.netty.NettyConnectorFactory,org.hornetq.core.remoting.impl.netty.NettyConnectorFactory</config-property-value>
+ </config-property>
+ <config-property>
+ <description>The transport configuration. These values must be in the
form of key=val;key=val;</description>
+ <config-property-name>ConnectionParameters</config-property-name>
+ <config-property-type>java.lang.String</config-property-type>
+
<config-property-value>host=127.0.0.1;port=5446,host=127.0.0.2;port=5447</config-property-value>
+</config-property></programlisting>
+ <warning>
+ <title>provide all parameters</title>
+ <para>
+ Make sure you provide parameters for each connector
configured. The position of the parameters in the
+ list maps to each connector provided.
+ </para>
+ </warning>
+ <para>This configures the resource adapter to connect to a
server running on localhost listening on port
+ 5446
+ </para>
+ </section>
+
+ <section>
+ <title>Configuring the outgoing adaptor</title>
+ <para>You will also need to configure the outbound connection
by creating a <literal>hornetq-ds.xml</literal>
+ and placing it under any directory that will be deployed
under the <literal>deploy</literal> directory.
+ In a standard HornetQ jboss configuration this would be
under <literal>hornetq</literal> or <literal>hornetq.sar</literal>
+ but you can place it where ever you like. Actually as long
as it ends in <literal>-ds.xml</literal> you can
+ call it anything you like. You can again find a template
for this file under the config directory of the
+ HornetQ distribution but called
<literal>jms-ds.xml</literal> which is the jboss default.
+ </para>
+ <para>The following example shows a sample configuration</para>
+ <programlisting>
+<tx-connection-factory>
+ <jndi-name>RemoteJmsXA</jndi-name>
+ <xa-transaction/>
+ <rar-name>hornetq-ra.rar</rar-name>
+
<connection-definition>org.hornetq.ra.HornetQRAConnectionFactory</connection-definition>
+ <config-property name="SessionDefaultType"
type="java.lang.String">javax.jms.Topic</config-property>
+ <config-property name="ConnectorClassName"
type="java.lang.String">org.hornetq.core.remoting.impl.netty.NettyConnectorFactory</config-property>
+ <config-property name="ConnectionParameters"
type="java.lang.String">host=127.0.0.1;port=5446</config-property>
+ <max-pool-size>20</max-pool-size>
+</tx-connection-factory></programlisting>
+ <para>Again you will see that this uses the netty connector
type and will connect to the HornetQ server
+ running on localhost and listening on port 5446. JEE
components can access this by using JNDI and looking
+ up the connection factory using JNDI using
<literal>java:/RemoteJmsXA</literal>, you can see that this
+ is defined under the<literal>jndi-name</literal> attribute.
You will also note that the outgoing connection
+ will be created by the resource adaptor configured under
the directory <literal>hornetq-ra.rar</literal>
+ as explained in the last section.
+ </para>
+ <para>
+ Also if you want to configure multiple connectors do this
as a comma separated list as in the ra configuration.
+ </para>
+ </section>
+
+ <section>
+ <title>Jar dependencies</title>
+ <para>This is a list of the HornetQ and third party jars
needed</para>
+ <table frame="topbot" border="2">
+ <title>Jar Dependencies</title>
+ <tgroup cols="3">
+ <colspec colname="c1" colnum="1"/>
+ <colspec colname="c2" colnum="2"/>
+ <colspec colname="c3" colnum="3"/>
+ <thead>
+ <row>
+ <entry>Jar Name</entry>
+ <entry>Description</entry>
+ <entry>Location</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>hornetq-ra.jar</entry>
+ <entry>The HornetQ resource adaptor
classes</entry>
+ <entry>deploy/hornetq-ra.rar or
equivalent</entry>
+ </row>
+ <row>
+ <entry>hornetq-core-client.jar</entry>
+ <entry>The HornetQ core client classes</entry>
+ <entry>either in the config lib, i.e.
default/lib or the common lib dir, i.e. $JBOSS_HOME/common lib </entry>
+ </row>
+ <row>
+ <entry>hornetq-jms-client.jar</entry>
+ <entry>The HornetQ JMS classes</entry>
+ <entry>as above</entry>
+ </row>
+ <row>
+ <entry>netty.jar</entry>
+ <entry>The Netty transport classes</entry>
+ <entry>as above</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
+
+ </section>
+ </section>
+ </section>
+ <section>
+ <title>Configuring the JBoss Application Server to connect to Remote
HornetQ Server</title>
+ <para>This is a step by step guide on how to configure a JBoss
application server that doesn't have HornetQ installed
+ to use a remote instance of HornetQ</para>
+ <section>
+ <title>Configuring JBoss 5</title>
+ <para>Firstly download and install JBoss AS 5 as per the JBoss
installation guide and HornetQ as per the
+ HornetQ installation guide. After that the following steps are
required</para>
+ <itemizedlist>
+ <listitem>
+ <para>Copy the following jars from the HornetQ
distribution to the <literal>lib</literal> directory of
+ which ever JBossAs configuration you have chosen, i.e.
<literal>default</literal>.</para>
+ <itemizedlist>
+ <listitem>
+ <para>hornetq-core-client.jar</para>
+ </listitem>
+ <listitem>
+ <para>hornetq-jms-client.jar</para>
+ </listitem>
+ <listitem>
+ <para>hornetq-ra.jar (this can be found inside the
<literal>hornetq-ra.rar</literal> archive)</para>
+ </listitem>
+ <listitem>
+ <para>netty.jar</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ <listitem>
+ <para>create the directories
<literal>hornetq-ra.rar</literal> and <literal>hornetq-ra.rar/META-INF</literal>
+ under the <literal>deploy</literal> directory in your
JBoss config directory</para>
+ </listitem>
+ <listitem>
+ <para>under the <literal>hornetq-ra.rar/META-INF</literal>
create a <literal>ra.xml</literal> file or
+ copy it from the HornetQ distribution (again it can be
found in the <literal>hornetq-ra.rar</literal> archive)
+ and configure it as follows</para>
+ <programlisting>
+<?xml version="1.0" encoding="UTF-8"?>
+
+<connector xmlns="http://java.sun.com/xml/ns/j2ee"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
+ http://java.sun.com/xml/ns/j2ee/connector_1_5.xsd"
+ version="1.5">
+
+ <description>HornetQ 2.0 Resource Adapter Alternate
Configuration</description>
+ <display-name>HornetQ 2.0 Resource Adapter Alternate
Configuration</display-name>
+
+ <vendor-name>Red Hat Middleware LLC</vendor-name>
+ <eis-type>JMS 1.1 Server</eis-type>
+ <resourceadapter-version>1.0</resourceadapter-version>
+
+ <license>
+ <description>
+Copyright 2009 Red Hat, Inc.
+ Red Hat licenses this file to you under the Apache License, version
+ 2.0 (the "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+ </description>
+ <license-required>true</license-required>
+ </license>
+
+ <resourceadapter>
+
<resourceadapter-class>org.hornetq.ra.HornetQResourceAdapter</resourceadapter-class>
+ <config-property>
+ <description>The transport type</description>
+ <config-property-name>ConnectorClassName</config-property-name>
+ <config-property-type>java.lang.String</config-property-type>
+
<config-property-value>org.hornetq.core.remoting.impl.netty.NettyConnectorFactory</config-property-value>
+ </config-property>
+ <config-property>
+ <description>The transport configuration. These values must be in
the form of key=val;key=val;</description>
+
<config-property-name>ConnectionParameters</config-property-name>
+ <config-property-type>java.lang.String</config-property-type>
+ <emphasis role="bold">
<config-property-value>host=127.0.0.1;port=5445</config-property-value></emphasis>
+ </config-property>
+
+ <outbound-resourceadapter>
+ <connection-definition>
+
<managedconnectionfactory-class>org.hornetq.ra.HornetQRAManagedConnectionFactory</managedconnectionfactory-class>
+
+ <config-property>
+ <description>The default session type</description>
+
<config-property-name>SessionDefaultType</config-property-name>
+
<config-property-type>java.lang.String</config-property-type>
+
<config-property-value>javax.jms.Queue</config-property-value>
+ </config-property>
+ <config-property>
+ <description>Try to obtain a lock within specified number of
seconds; less than or equal to 0 disable this functionality</description>
+ <config-property-name>UseTryLock</config-property-name>
+
<config-property-type>java.lang.Integer</config-property-type>
+ <config-property-value>0</config-property-value>
+ </config-property>
+
+
<connectionfactory-interface>org.hornetq.ra.HornetQRAConnectionFactory</connectionfactory-interface>
+
<connectionfactory-impl-class>org.hornetq.ra.HornetQRAConnectionFactoryImpl</connectionfactory-impl-class>
+
<connection-interface>javax.jms.Session</connection-interface>
+
<connection-impl-class>org.hornetq.ra.HornetQRASession</connection-impl-class>
+ </connection-definition>
+ <transaction-support>XATransaction</transaction-support>
+ <authentication-mechanism>
+
<authentication-mechanism-type>BasicPassword</authentication-mechanism-type>
+
<credential-interface>javax.resource.spi.security.PasswordCredential</credential-interface>
+ </authentication-mechanism>
+ <reauthentication-support>false</reauthentication-support>
+ </outbound-resourceadapter>
+
+ <inbound-resourceadapter>
+ <messageadapter>
+ <messagelistener>
+
<messagelistener-type>javax.jms.MessageListener</messagelistener-type>
+ <activationspec>
+
<activationspec-class>org.hornetq.ra.inflow.HornetQActivationSpec</activationspec-class>
+ <required-config-property>
+
<config-property-name>destination</config-property-name>
+ </required-config-property>
+ </activationspec>
+ </messagelistener>
+ </messageadapter>
+ </inbound-resourceadapter>
+
+ </resourceadapter>
+</connector></programlisting>
+ <para>The important part of this configuration is the part
in bold, i.e.
<config-property-value>host=127.0.0.1;port=5445</config-property-value>.
+ This should be configured to the host and port of the
remote HornetQ server.</para>
+ </listitem>
+ </itemizedlist>
+ <para>At this point you should be able to now deploy MDB's that
consume from the remote server. You will however,
+ have to make sure that your MDB's have the annotation
<literal>@ResourceAdapter("hornetq-ra.rar")</literal>
+ added, this is illustrated in the <xref
linkend="configuring-mdbs">Configuring Message-Driven Beans</xref> section.
+ If you don't want to add this annotation then you can delete the
generic resource adapter <literal>jms-ra.rar</literal>
+ and rename the <literal>hornetq-ra.rar</literal> to this.</para>
+ <para>If you also want to use the remote HornetQ server for
outgoing connections, i.e. sending messages, then
+ do the following:</para>
+ <itemizedlist>
+ <listitem>
+ <para>Create a file called
<literal>hornetq-ds.xml</literal> in the <literal>deploy</literal> directory
+ (in fact you can call this anything you want as long as it
ends in <literal>-ds.xml</literal>). Then
+ add the following:</para>
+ <programlisting>
+<connection-factories>
+ <!--
+ JMS XA Resource adapter, use this for outbound JMS connections.
+ Inbound connections are defined at the @MDB activation or at the
resource-adapter properties.
+ -->
+ <tx-connection-factory>
+ <jndi-name>RemoteJmsXA</jndi-name>
+ <xa-transaction/>
+ <rar-name>hornetq-ra.rar</rar-name>
+
<connection-definition>org.hornetq.ra.HornetQRAConnectionFactory</connection-definition>
+ <config-property name="SessionDefaultType"
type="java.lang.String">javax.jms.Topic</config-property>
+ <config-property name="ConnectorClassName"
type="java.lang.String">org.hornetq.core.remoting.impl.netty.NettyConnectorFactory</config-property>
+ <config-property name="ConnectionParameters"
type="java.lang.String">host=127.0.0.1;port=5445</config-property>
+ <max-pool-size>20</max-pool-size>
+ </tx-connection-factory>
+
+
+</connection-factories></programlisting>
+ <para>Again you will see that the host and port are
configured here to match the remote HornetQ servers
+ configuration. The other important attributes
are:</para>
+ <itemizedlist>
+ <listitem>
+ <para>jndi-name - This is the name used to look up
the JMS connection factory from within your JEE client</para>
+ </listitem>
+ <listitem>
+ <para>rar-name - This should match the directory
that you created to hold the Resource Adapter
+ configuration</para>
+ </listitem>
+ </itemizedlist>
+ </listitem>
+ </itemizedlist>
+ <para>Now you should be able to send messages using the JCA JMS
connection pooling within an XA transaction.</para>
+ </section>
+ <section>
+ <title>Configuring JBoss 5</title>
+ <para>The steps to do this are exactly the same as for JBoss 4,
you will have to create a jboss.xml definition
+ file for your MDB with the following entry</para>
+ <programlisting>
+<message-driven>
+ <ejb-name>MyMDB</ejb-name>
+ <resource-adapter-name>jms-ra.rar</resource-adapter-name>
+ </message-driven></programlisting>
+ <para>Also you will need to edit the
<literal>standardjboss.xml</literal> and uncomment the section with the
+ following 'Uncomment to use JMS message inflow from jmsra.rar' and
then comment out the invoker-proxy-binding
+ called 'message-driven-bean'</para>
+ </section>
+ </section>
+ <section>
+ <title>High Availability JNDI (HA-JNDI)</title>
+ <para>If you are using JNDI to look-up JMS queues, topics and
connection factories from a
+ cluster of servers, it is likely you will want to use HA-JNDI so
that your JNDI look-ups
+ will continue to work if one or more of the servers in the cluster
fail.</para>
+ <para>HA-JNDI is a JBoss Application Server service which allows you
to use JNDI from
+ clients without them having to know the exact JNDI connection
details of every server in
+ the cluster. This service is only available if using a cluster of
JBoss Application
+ Server instances.</para>
+ <para>To use it use the following properties when connecting to
JNDI.</para>
+ <programlisting>
+Hashtable<String, String> jndiParameters = new Hashtable<String,
String>();
+jndiParameters.put("java.naming.factory.initial",
"org.jnp.interfaces.NamingContextFactory");
+jndiParameters.put("java.naming.factory.url.pkgs=",
"org.jboss.naming:org.jnp.interfaces");
+
+initialContext = new InitialContext(jndiParameters);</programlisting>
+ <para>For more information on using HA-JNDI see the <ulink
+
url="http://www.jboss.org/file-access/default/members/jbossas/freezone/docs/Clustering_Guide/5/html/clustering-jndi.html"
+ >JBoss Application Server clustering
documentation</ulink></para>
+ </section>
+ <section id="xa-recovery">
+ <title>XA Recovery</title>
+ <para><emphasis>XA recovery</emphasis> deals with system or
application failures to ensure
+ that of a transaction are applied consistently to all resources
affected by the
+ transaction, even if any of the application processes or the
machine hosting them crash
+ or lose network connectivity. For more information on XA
Recovery,please refer to <ulink
+
url="http://www.jboss.org/community/wiki/JBossTransactions">JBoss
+ Transactions</ulink>.</para>
+ <para>When HornetQ is integrated with JBoss AS, it can take advantage
of JBoss Transactions
+ to provide recovery of messaging resources. If messages are
involved in a XA
+ transaction, in the event of a server crash, the recovery manager
will ensure that the
+ transactions are recovered and the messages will either be
committed or rolled back
+ (depending on the transaction outcome) when the server is
restarted.</para>
+ <section>
+ <title>XA Recovery Configuration</title>
+ <para>To enable HornetQ's XA Recovery, the Recovery Manager must
be configured to connect
+ to HornetQ to recover its resources. The following property
must be added to the
+ <literal>jta</literal> section of
<literal>conf/jbossts-properties.xml</literal>
+ of JBoss AS profiles:</para>
+ <programlisting>
+<properties depends="arjuna" name="jta">
+ ...
+
+ <property name="com.arjuna.ats.jta.recovery.XAResourceRecovery.HornetQ1"
+
value="org.hornetq.jms.server.recovery.HornetQXAResourceRecovery;[connection
configuration]"/>
+ <property name="com.arjuna.ats.jta.xaRecoveryNode" value="1"/>
+</properties></programlisting>
+ <para>The <literal>[connection configuration]</literal> contains
all the information
+ required to connect to HornetQ node under the form
<literal>[connector factory class
+ name],[user name], [password], [connector
parameters]</literal>. </para>
+ <itemizedlist>
+ <listitem>
+ <para><literal>[connector factory class name]</literal>
corresponds to the name
+ of the <literal>ConnectorFactory</literal> used to
connect to HornetQ.
+ Values can be <literal
+
>org.hornetq.core.remoting.impl.invm.InVMConnectorFactory</literal> or
+ <literal
+
>org.hornetq.core.remoting.impl.netty.NettyConnectorFactory</literal></para>
+ </listitem>
+ <listitem>
+ <para><literal>[user name]</literal> is the user name to
create a client
+ session. It is optional</para>
+ </listitem>
+ <listitem>
+ <para><literal>[password]</literal> is the password to
create a client session.
+ It is mandatory only if the user name is
specified</para>
+ </listitem>
+ <listitem>
+ <para><literal>[connector parameters]</literal> is a list
of comma-separated
+ key=value pair which are passed to the connector
factory (see <xref
+ linkend="configuring-transports"/> for a list of
the transport
+ parameters).</para>
+ </listitem>
+ </itemizedlist>
+ <para>Also note the
<literal>com.arjuna.ats.jta.xaRecoveryNode</literal> parameter. If you want
recovery
+ enabled then this must be configured to what ever the tx node id
is set to, this is configured in the
+ same file by the
<literal>com.arjuna.ats.arjuna.xa.nodeIdentifier</literal> property.</para>
+ <note>
+ <para>HornetQ must have a valid acceptor which corresponds to
the connector
+ specified in
<literal>conf/jbossts-properties.xml</literal>.</para>
+ </note>
+ <section>
+ <title>Configuration Settings</title>
+ <para>If HornetQ is configured with a default in-vm
acceptor:</para>
+ <programlisting>
+<acceptor name="in-vm">
+
<factory-class>org.hornetq.core.remoting.impl.invm.InVMAcceptorFactory</factory-class>
+</acceptor></programlisting>
+ <para>the corresponding configuration in <literal
+ >conf/jbossts-properties.xml</literal> is:</para>
+ <programlisting>
+<property name="com.arjuna.ats.jta.recovery.XAResourceRecovery.HORNETQ1"
+
value="org.hornetq.jms.server.recovery.HornetQXAResourceRecovery;org.hornetq.core.remoting.impl.invm.InVMConnectorFactory"/></programlisting>
+ <para>If it is now configured with a netty acceptor on a
non-default port:</para>
+ <programlisting>
+<acceptor name="netty">
+
<factory-class>org.hornetq.core.remoting.impl.netty.NettyAcceptorFactory</factory-class>
+ <param key="port" value="8888"/>
+</acceptor></programlisting>
+ <para>the corresponding configuration in <literal
+ >conf/jbossts-properties.xml</literal> is:</para>
+ <programlisting>
+<property name="com.arjuna.ats.jta.recovery.XAResourceRecovery.HORNETQ1"
+
value="org.hornetq.jms.server.recovery.HornetQXAResourceRecovery;org.hornetq.core.remoting.impl.netty.NettyConnectorFactory,
, , port=8888"/></programlisting>
+ <note>
+ <para>Note the additional commas to skip the user and
password before connector
+ parameters</para>
+ </note>
+ <para>If the recovery must use <literal>admin,
adminpass</literal>, the
+ configuration would have been:</para>
+ <programlisting>
+<property name="com.arjuna.ats.jta.recovery.XAResourceRecovery.HORNETQ1"
+
value="org.hornetq.jms.server.recovery.HornetQXAResourceRecovery;org.hornetq.core.remoting.impl.netty.NettyConnectorFactory,
admin, adminpass, port=8888"/></programlisting>
+ <para>Configuring HornetQ with an invm acceptor and
configuring the Recovery Manager
+ with an invm connector is the recommended way to enable XA
Recovery.</para>
+ </section>
+ </section>
+ <section>
+ <title>Example</title>
+ <para>See <xref linkend="xa-recovery-example"/> which shows how to
configure XA Recovery
+ and recover messages after a server crash.</para>
+ </section>
+ </section>
+</chapter>