JBoss hornetq SVN: r9151 - in trunk/tests/src/org/hornetq/tests: integration/cluster/failover and 5 other directories.
by do-not-reply@jboss.org
Author: clebert.suconic(a)jboss.com
Date: 2010-04-22 13:28:41 -0400 (Thu, 22 Apr 2010)
New Revision: 9151
Added:
trunk/tests/src/org/hornetq/tests/unit/core/asyncio/LibaioDependencyCheckTest.java
Modified:
trunk/tests/src/org/hornetq/tests/integration/cluster/distribution/ClusterTestBase.java
trunk/tests/src/org/hornetq/tests/integration/cluster/failover/GroupingFailoverReplicationTest.java
trunk/tests/src/org/hornetq/tests/integration/persistence/RestartSMTest.java
trunk/tests/src/org/hornetq/tests/integration/persistence/StorageManagerTestBase.java
trunk/tests/src/org/hornetq/tests/stress/paging/PageStressTest.java
trunk/tests/src/org/hornetq/tests/unit/core/postoffice/impl/DuplicateDetectionUnitTest.java
trunk/tests/src/org/hornetq/tests/util/ServiceTestBase.java
trunk/tests/src/org/hornetq/tests/util/UnitTestCase.java
Log:
Making testsuite to use NIO if AIO is not available, and adding a test to check the dependency on Linux
Modified: trunk/tests/src/org/hornetq/tests/integration/cluster/distribution/ClusterTestBase.java
===================================================================
--- trunk/tests/src/org/hornetq/tests/integration/cluster/distribution/ClusterTestBase.java 2010-04-22 15:01:49 UTC (rev 9150)
+++ trunk/tests/src/org/hornetq/tests/integration/cluster/distribution/ClusterTestBase.java 2010-04-22 17:28:41 UTC (rev 9151)
@@ -48,7 +48,6 @@
import org.hornetq.core.remoting.impl.netty.TransportConstants;
import org.hornetq.core.server.HornetQServer;
import org.hornetq.core.server.HornetQServers;
-import org.hornetq.core.server.JournalType;
import org.hornetq.core.server.cluster.ClusterConnection;
import org.hornetq.core.server.cluster.RemoteQueueBinding;
import org.hornetq.core.server.group.GroupingHandler;
@@ -1221,7 +1220,7 @@
configuration.setJournalMinFiles(2);
configuration.setJournalMaxIO_AIO(1000);
configuration.setJournalFileSize(100 * 1024);
- configuration.setJournalType(JournalType.ASYNCIO);
+ configuration.setJournalType(getDefaultJournalType());
configuration.setSharedStore(sharedStorage);
if (sharedStorage)
{
@@ -1335,7 +1334,7 @@
configuration.setJournalMinFiles(2);
configuration.setJournalDirectory(getJournalDir(node, false));
configuration.setJournalFileSize(100 * 1024);
- configuration.setJournalType(JournalType.ASYNCIO);
+ configuration.setJournalType(getDefaultJournalType());
configuration.setJournalMaxIO_AIO(1000);
configuration.setPagingDirectory(getPageDir(node, false));
configuration.setLargeMessagesDirectory(getLargeMessagesDir(node, false));
Modified: trunk/tests/src/org/hornetq/tests/integration/cluster/failover/GroupingFailoverReplicationTest.java
===================================================================
--- trunk/tests/src/org/hornetq/tests/integration/cluster/failover/GroupingFailoverReplicationTest.java 2010-04-22 15:01:49 UTC (rev 9150)
+++ trunk/tests/src/org/hornetq/tests/integration/cluster/failover/GroupingFailoverReplicationTest.java 2010-04-22 17:28:41 UTC (rev 9151)
@@ -50,7 +50,7 @@
configuration.setJournalMaxIO_AIO(1000);
configuration.setJournalDirectory(getJournalDir(node, false));
configuration.setJournalFileSize(100 * 1024);
- configuration.setJournalType(JournalType.ASYNCIO);
+ configuration.setJournalType(getDefaultJournalType());
configuration.setPagingDirectory(getPageDir(node, false));
configuration.setLargeMessagesDirectory(getLargeMessagesDir(node, false));
configuration.setClustered(true);
Modified: trunk/tests/src/org/hornetq/tests/integration/persistence/RestartSMTest.java
===================================================================
--- trunk/tests/src/org/hornetq/tests/integration/persistence/RestartSMTest.java 2010-04-22 15:01:49 UTC (rev 9150)
+++ trunk/tests/src/org/hornetq/tests/integration/persistence/RestartSMTest.java 2010-04-22 17:28:41 UTC (rev 9151)
@@ -86,8 +86,6 @@
Configuration configuration = createDefaultConfig();
- configuration.setJournalType(JournalType.ASYNCIO);
-
PostOffice postOffice = new FakePostOffice();
final JournalStorageManager journal = new JournalStorageManager(configuration, execFactory);
Modified: trunk/tests/src/org/hornetq/tests/integration/persistence/StorageManagerTestBase.java
===================================================================
--- trunk/tests/src/org/hornetq/tests/integration/persistence/StorageManagerTestBase.java 2010-04-22 15:01:49 UTC (rev 9150)
+++ trunk/tests/src/org/hornetq/tests/integration/persistence/StorageManagerTestBase.java 2010-04-22 17:28:41 UTC (rev 9151)
@@ -121,8 +121,6 @@
{
Configuration configuration = createDefaultConfig();
- configuration.setJournalType(JournalType.ASYNCIO);
-
journal = new JournalStorageManager(configuration, execFactory);
journal.start();
@@ -142,8 +140,6 @@
{
Configuration configuration = createDefaultConfig();
- configuration.setJournalType(JournalType.ASYNCIO);
-
jmsJournal = new JMSJournalStorageManagerImpl(new TimeAndCounterIDGenerator(), configuration, null);
jmsJournal.start();
Modified: trunk/tests/src/org/hornetq/tests/stress/paging/PageStressTest.java
===================================================================
--- trunk/tests/src/org/hornetq/tests/stress/paging/PageStressTest.java 2010-04-22 15:01:49 UTC (rev 9150)
+++ trunk/tests/src/org/hornetq/tests/stress/paging/PageStressTest.java 2010-04-22 17:28:41 UTC (rev 9151)
@@ -295,8 +295,6 @@
config.setJournalFileSize(10 * 1024 * 1024);
config.setJournalMinFiles(5);
- config.setJournalType(JournalType.ASYNCIO);
-
return config;
}
Added: trunk/tests/src/org/hornetq/tests/unit/core/asyncio/LibaioDependencyCheckTest.java
===================================================================
--- trunk/tests/src/org/hornetq/tests/unit/core/asyncio/LibaioDependencyCheckTest.java (rev 0)
+++ trunk/tests/src/org/hornetq/tests/unit/core/asyncio/LibaioDependencyCheckTest.java 2010-04-22 17:28:41 UTC (rev 9151)
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2010 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.
+ */
+
+package org.hornetq.tests.unit.core.asyncio;
+
+import org.hornetq.core.asyncio.impl.AsynchronousFileImpl;
+import org.hornetq.tests.util.UnitTestCase;
+
+/**
+ * A LibaioDependencyCheckTest
+ *
+ * @author <mailto:clebert.suconic@jboss.org">Clebert Suconic</a>
+ *
+ *
+ */
+public class LibaioDependencyCheckTest extends UnitTestCase
+{
+
+ // Constants -----------------------------------------------------
+
+ // Attributes ----------------------------------------------------
+
+ // Static --------------------------------------------------------
+
+ // Constructors --------------------------------------------------
+
+ // Public --------------------------------------------------------
+
+ public void testDependency() throws Exception
+ {
+ if (System.getProperties().get("os.name").equals("Linux"))
+ {
+ assertTrue("Libaio is not available on this platform", AsynchronousFileImpl.isLoaded());
+ }
+ }
+
+ // Package protected ---------------------------------------------
+
+ // Protected -----------------------------------------------------
+
+ // Private -------------------------------------------------------
+
+ // Inner classes -------------------------------------------------
+
+}
Modified: trunk/tests/src/org/hornetq/tests/unit/core/postoffice/impl/DuplicateDetectionUnitTest.java
===================================================================
--- trunk/tests/src/org/hornetq/tests/unit/core/postoffice/impl/DuplicateDetectionUnitTest.java 2010-04-22 15:01:49 UTC (rev 9150)
+++ trunk/tests/src/org/hornetq/tests/unit/core/postoffice/impl/DuplicateDetectionUnitTest.java 2010-04-22 17:28:41 UTC (rev 9151)
@@ -98,8 +98,6 @@
PostOffice postOffice = new FakePostOffice();
- configuration.setJournalType(JournalType.ASYNCIO);
-
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(ConfigurationImpl.DEFAULT_SCHEDULED_THREAD_POOL_MAX_SIZE);
journal = new JournalStorageManager(configuration, factory);
Modified: trunk/tests/src/org/hornetq/tests/util/ServiceTestBase.java
===================================================================
--- trunk/tests/src/org/hornetq/tests/util/ServiceTestBase.java 2010-04-22 15:01:49 UTC (rev 9150)
+++ trunk/tests/src/org/hornetq/tests/util/ServiceTestBase.java 2010-04-22 17:28:41 UTC (rev 9151)
@@ -278,7 +278,7 @@
configuration.setJournalMinFiles(2);
configuration.setJournalDirectory(getJournalDir(index, false));
configuration.setJournalFileSize(100 * 1024);
- configuration.setJournalType(JournalType.ASYNCIO);
+ configuration.setJournalType(getDefaultJournalType());
configuration.setPagingDirectory(getPageDir(index, false));
configuration.setLargeMessagesDirectory(getLargeMessagesDir(index, false));
configuration.setJournalCompactMinFiles(0);
@@ -311,7 +311,7 @@
configuration.setFileDeploymentEnabled(false);
- configuration.setJournalType(JournalType.ASYNCIO);
+ configuration.setJournalType(getDefaultJournalType());
configuration.getAcceptorConfigurations().clear();
Modified: trunk/tests/src/org/hornetq/tests/util/UnitTestCase.java
===================================================================
--- trunk/tests/src/org/hornetq/tests/util/UnitTestCase.java 2010-04-22 15:01:49 UTC (rev 9150)
+++ trunk/tests/src/org/hornetq/tests/util/UnitTestCase.java 2010-04-22 17:28:41 UTC (rev 9151)
@@ -60,6 +60,7 @@
import org.hornetq.core.postoffice.impl.LocalQueueBinding;
import org.hornetq.core.remoting.impl.invm.InVMRegistry;
import org.hornetq.core.server.HornetQServer;
+import org.hornetq.core.server.JournalType;
import org.hornetq.core.server.MessageReference;
import org.hornetq.core.server.Queue;
import org.hornetq.core.server.ServerMessage;
@@ -96,6 +97,19 @@
// Static --------------------------------------------------------
+
+ protected static JournalType getDefaultJournalType()
+ {
+ if (AsynchronousFileImpl.isLoaded())
+ {
+ return JournalType.ASYNCIO;
+ }
+ else
+ {
+ return JournalType.NIO;
+ }
+ }
+
/**
* @param name
*/
14 years
JBoss hornetq SVN: r9150 - branches/HnetQ_323_cn/docs/user-manual/zh.
by do-not-reply@jboss.org
Author: gaohoward
Date: 2010-04-22 11:01:49 -0400 (Thu, 22 Apr 2010)
New Revision: 9150
Modified:
branches/HnetQ_323_cn/docs/user-manual/zh/jms-bridge.xml
Log:
done
Modified: branches/HnetQ_323_cn/docs/user-manual/zh/jms-bridge.xml
===================================================================
--- branches/HnetQ_323_cn/docs/user-manual/zh/jms-bridge.xml 2010-04-22 14:57:31 UTC (rev 9149)
+++ branches/HnetQ_323_cn/docs/user-manual/zh/jms-bridge.xml 2010-04-22 15:01:49 UTC (rev 9150)
@@ -17,36 +17,26 @@
<!-- permitted by applicable law. -->
<!-- ============================================================================= -->
<chapter id="jms-bridge">
- <title>The JMS Bridge</title>
- <para>HornetQ includes a fully functional JMS message bridge.</para>
- <para>The function of the bridge is to consume messages from a source queue or topic, and
- send them to a target queue or topic, typically on a different server.</para>
- <para>The source and target servers do not have to be in the same cluster which makes
- bridging suitable for reliably sending messages from one cluster to another, for
- instance across a WAN, and where the connection may be unreliable.</para>
- <para>A bridge can be deployed as a standalone application, with HornetQ standalone server or inside a JBoss AS
- instance. The source and the target can be located in the same virtual machine or another one.</para>
- <para>The bridge can also be used to bridge messages from other non HornetQ JMS servers, as
- long as they are JMS 1.1 compliant.<note><para>Do not confuse a JMS bridge with a core
- bridge. A JMS bridge can be used to bridge any two JMS 1.1 compliant JMS
- providers and uses the JMS API. A core bridge (described in <xref
- linkend="core-bridges"/>) is used to bridge any two HornetQ instances and
- uses the core API. Always use a core bridge if you can in preference to a JMS
- bridge. The core bridge will typically provide better performance than a JMS
- bridge. Also the core bridge can provide <emphasis>once and only once</emphasis>
- delivery guarantees without using XA.</para></note></para>
- <para>The bridge has built-in resilience to failure so if the source or target server
- connection is lost, e.g. due to network failure, the bridge will retry connecting to the
- source and/or target until they come back online. When it comes back online it will
- resume operation as normal.</para>
- <para>The bridge can be configured with an optional JMS selector, so it will only consume
- messages matching that JMS selector</para>
- <para>It can be configured to consume from a queue or a topic. When it consumes from a topic
- it can be configured to consume using a non durable or durable subscription</para>
- <para>Typically, the bridge is deployed by the JBoss Micro Container via a beans configuration file.
- This would typically be deployed inside the JBoss Application Server and the following
- example shows an example of a beans file that bridges 2 destinations which are actually
- on the same server. </para>
+ <title>JMS桥(Bridge)</title>
+ <para>HornetQ提供了JMS消息桥服务。</para>
+ <para>桥的作用是从一个消息源队列或话题(topic)接收消息,然后将它们发送到一个目标队列或话题。通常源和
+ 目的不在同一台服务器上。</para>
+ <para>作为消息源的服务器与目的服务器不必在同一个集群内。通过桥的作用,两台服务器可以通过非可靠的网络连接
+ 起来,比如WAN。</para>
+ <para>桥可以作为单独的服务部署,或者部署于HornetQ单独服务器内,或者部署在JBoss应用服务器中。源或目的可以
+ 在同一个VM中,也可以在其它的VM中。</para>
+ <para>桥还可以在HornetQ服务器与其它JMS 1.1 兼容的服务器之间进行消息的传递。
+ <note><para>还要将JMS桥与核心桥混淆。JMB桥可以连接两个JMS 1.1兼容的服务器,它使用的是JMS接口。
+ 而核心桥(在<xref linkend="core-bridges"/>中描述)使用核心API将两个HornetQ实例连接
+ 起来。核心桥的性能通常要比JMS桥的性能高,所以尽可能使用核心桥。另外核心桥可以不用XA
+ 就可以实现<emphasis>一次并只有一次</emphasis>的消息传递保证。</para></note></para>
+ <para>桥可以适当处理连接故障。当源的连接或目的的连接发生故障时,例如网络故障,桥将不断重试连接直到连接
+ 恢复为止。当连接恢复后,桥会继续正常工作。</para>
+ <para>桥还可以有一个可选的JMS选择器,它可以使桥只接收选择器选择的消息。</para>
+ <para>可以配置桥从队列还是从话题中接收消息。如果配置成从话题中接收消息,还以设定是以非持久订阅的方式接收,还是
+ 以持久订阅的方式接收。</para>
+ <para>通常桥是通过一个bean配置文件由JBoss Micro Container部署到JBoss应用服务器中。下面的就是一
+ 个桥的bean文件例子。这个桥将同一服务器上的两个目标连接起来。</para>
<programlisting><?xml version="1.0" encoding="UTF-8"?>
<deployment xmlns="urn:jboss:bean-deployer:2.0">
@@ -182,91 +172,78 @@
</bean>
</deployment></programlisting>
<section>
- <title>JMS Bridge Parameters</title>
- <para>The main bean deployed is the <literal>JMSBridge</literal> bean. The bean is
- configurable by the parameters passed to its constructor.</para>
+ <title>JMS桥的配置参数</title>
+ <para>桥的主要的bean是<literal>JMSBridge</literal>。所有的配置参数需要传递给这个bean的
+ 构造函数。</para>
<note>
- <para>To let a parameter be unspecified (for example, if the authentication is
- anonymous or no message selector is provided), use <literal><null
- /></literal> for the unspecified parameter value.</para>
+ <para>如果不想指定某个参数的值(例如匿名认证或没有选择器),将该参数设为<literal><null
+ /></literal>即可。</para>
</note>
<itemizedlist>
<listitem>
- <para>Source Connection Factory Factory</para>
- <para>This injects the <literal>SourceCFF</literal> bean (also defined in the
- beans file). This bean is used to create the <emphasis>source</emphasis>
- <literal>ConnectionFactory</literal>
+ <para>源连接工厂的工厂(Source ConnectionFactory Factory)</para>
+ <para>这个参数注入一个<literal>SourceCFF</literal>bean(由bean文件定义)。它被
+ 用来创建<emphasis>源</emphasis>的<literal>ConnectionFactory</literal>
</para>
</listitem>
<listitem>
- <para>Target Connection Factory Factory</para>
- <para>This injects the <literal>TargetCFF</literal> bean (also defined in the
- beans file). This bean is used to create the <emphasis>target</emphasis>
- <literal>ConnectionFactory</literal>
+ <para>目标连接工厂的工厂(Target ConnectionFactory Factory)</para>
+ <para>这个参数注入一个<literal>TargetCFF</literal>bean(由bean文件定义)。它被
+ 用来创建<emphasis>目的</emphasis>的<literal>ConnectionFactory</literal>
</para>
</listitem>
<listitem>
- <para>Source Destination Factory Factory</para>
- <para>This injects the <literal>SourceDestinationFactory</literal> bean (also
- defined in the beans file). This bean is used to create the
- <emphasis>source</emphasis>
- <literal>Destination</literal>
+ <para>源目标工厂(Source DestinationFactory)</para>
+ <para>这个参数注入一个<literal>SourceDestinationFactory</literal>bean(由
+ bean文件定义)。它用来创建<emphasis>源</emphasis>
+ <literal>目标(Destination)</literal>
</para>
</listitem>
<listitem>
- <para>Target Destination Factory Factory</para>
- <para>This injects the <literal>TargetDestinationFactory</literal> bean (also
- defined in the beans file). This bean is used to create the
- <emphasis>target</emphasis>
- <literal>Destination</literal>
+ <para>目的目标工厂(Target DestinationFactory)</para>
+ <para>这个参数注入一个<literal>TargetDestinationFactory</literal>bean(由
+ bean文件定义)。它用来创建<emphasis>目的</emphasis>
+ <literal>目标(Destination)</literal>
</para>
</listitem>
<listitem>
- <para>Source User Name</para>
- <para>this parameter is the username for creating the
- <emphasis>source</emphasis> connection</para>
+ <para>源用户名(Source User Name)</para>
+ <para>用于创建到<emphasis>源</emphasis>的连接的用户名</para>
</listitem>
<listitem>
- <para>Source Password</para>
- <para>this parameter is the parameter for creating the
- <emphasis>source</emphasis> connection</para>
+ <para>源密码(Source Password)</para>
+ <para>用于创建<emphasis>源</emphasis>连接的密码</para>
</listitem>
<listitem>
- <para>Target User Name</para>
- <para>this parameter is the username for creating the
- <emphasis>target</emphasis> connection</para>
+ <para>目的用户名(Target User Name)</para>
+ <para>用于创建<emphasis>目的</emphasis>连接的用户名</para>
</listitem>
<listitem>
- <para>Target Password</para>
- <para>this parameter is the password for creating the
- <emphasis>target</emphasis> connection</para>
+ <para>目的密码(Target Password)</para>
+ <para>t用于创建<emphasis>目的</emphasis>连接的密码</para>
</listitem>
<listitem>
- <para>Selector</para>
- <para>This represents a JMS selector expression used for consuming messages from
- the source destination. Only messages that match the selector expression
- will be bridged from the source to the target destination</para>
- <para>The selector expression must follow the <ulink
+ <para>选择器(Selector)</para>
+ <para>这是一个JMS的选择器表达式,它用于从源目标接收消息。只有与选择器相匹配的消息才会被桥
+ 转发到目的目标</para>
+ <para>选择器必须符合<ulink
url="http://java.sun.com/j2ee/1.4/docs/api/javax/jms/Message.html">JMS
- selector syntax</ulink></para>
+ 选择器语法</ulink></para>
</listitem>
<listitem>
- <para>Failure Retry Interval</para>
- <para>This represents the amount of time in ms to wait between trying to
- recreate connections to the source or target servers when the bridge has
- detected they have failed</para>
+ <para>故障重试间隔(Failure Retry Interval)</para>
+ <para>代表当桥发现连接故障时在每两次重试连接之间所要等待的时间间隔,单位毫秒</para>
</listitem>
<listitem>
- <para>Max Retries</para>
- <para>This represents the number of times to attempt to recreate connections to
- the source or target servers when the bridge has detected they have failed.
- The bridge will give up after trying this number of times. <literal
- >-1</literal> represents 'try forever'</para>
+ <para>最大重试次数(Max Retries)</para>
+ <para>表示桥在发现连接故障时所进行的最大重试次数。超过这个次数,桥就放弃重试。
+ <literal
+ >-1</literal>代表一直重试下去</para>
</listitem>
<listitem>
- <para>Quality Of Service</para>
- <para>This parameter represents the desired quality of service mode</para>
- <para>Possible values are:</para>
+ <para>服务质量(Quality Of Service)</para>
+ <para>这个参数代表所需要的服务质量模式</para>
+ <para>有效的值为:</para>
<itemizedlist>
<listitem>
<para><literal>AT_MOST_ONCE</literal></para>
@@ -278,138 +255,104 @@
<para><literal>ONCE_AND_ONLY_ONCE</literal></para>
</listitem>
</itemizedlist>
- <para>See <xref linkend="quality-of-service"/> for a explanation of these
- modes.</para>
+ <para>有关这些模式的解释,参见<xref linkend="quality-of-service"/>。</para>
</listitem>
<listitem>
- <para>Max Batch Size</para>
- <para>This represents the maximum number of messages to consume from the source
- destination before sending them in a batch to the target destination. Its
- value must <literal>>= 1</literal>
+ <para>最大批量(Max Batch Size)</para>
+ <para>表示桥一次性从源目标最多接收多少消息,并将它们一次发往目的地。它的值必须是
+ <literal>>= 1</literal>
</para>
</listitem>
<listitem>
- <para>Max Batch Time</para>
- <para>This represents the maximum number of milliseconds to wait before sending
- a batch to target, even if the number of messages consumed has not reached
- <literal>MaxBatchSize</literal>. Its value must be <literal>-1</literal>
- to represent 'wait forever', or <literal>>= 1</literal> to specify an actual
- time </para>
+ <para>最大批时间(Max Batch Time)</para>
+ <para>代表桥在将一批消息发向目的之前等待的最大毫秒数。这个时间过后,即使接收的消息数小于
+ <literal>MaxBatchSize</literal>,桥也会开始向目的发送消息。它的值必须是
+ <literal>-1</literal> (代表永远等待)或<literal>>= 1</literal>。</para>
</listitem>
<listitem>
- <para>Subscription Name</para>
- <para>If the source destination represents a topic, and you want to consume from
- the topic using a durable subscription then this parameter represents the
- durable subscription name</para>
+ <para>订阅名(Subscription Name)</para>
+ <para>如果源的目标是一个话题(topic),你想使用持久的订阅来接收消息的话,这个参数可以指定
+ 订阅名。</para>
</listitem>
<listitem>
- <para>Client ID</para>
- <para>If the source destination represents a topic, and you want to consume from
- the topic using a durable subscription then this attribute represents the
- the JMS client ID to use when creating/looking up the durable
- subscription</para>
+ <para>客户ID(Client ID)</para>
+ <para>如果源的目标是一个话题(topic),你想使用持久的订阅来接收消息的话,这个参数可以指定
+ JMS的客户ID。它用于创建/查找持久订阅。</para>
</listitem>
<listitem>
- <para>Add MessageID In Header</para>
- <para>If <literal>true</literal>, then the original message's message ID will be
- appended in the message sent to the destination in the header <literal
- >HORNETQ_BRIDGE_MSG_ID_LIST</literal>. If the message is bridged more
- than once, each message ID will be appended. This enables a distributed
- request-response pattern to be used</para>
+ <para>在消息头添加MessageID(Add MessageID In Header)</para>
+ <para>如果值为<literal>true</literal>,原始的消息ID在发往目的是回到消息的名为<literal
+ >HORNETQ_BRIDGE_MSG_ID_LIST</literal>的头中。如果一个消息被桥转发了多次,
+ 则每次转发的消息ID都添加在这个头中。这用于分布式请求/回答的消息模式。</para>
<note>
- <para>when you receive the message you can send back a response using the
- correlation id of the first message id, so when the original sender gets
- it back it will be able to correlate it. </para>
+ <para>当收到一个消息时,通过它的相关ID(coorelation id)可以发送一个回答。这样
+ 在消息发送方得到这个回答消息时,它可以与原消息相关联起来。</para>
</note>
</listitem>
<listitem>
- <para>MBean Server</para>
- <para>To manage the JMS Bridge using JMX, set the MBeanServer where the JMS Bridge MBean
- must be registered (e.g. the JVM Platform MBeanServer or JBoss AS MBeanServer)</para>
+ <para>MBean服务器(MBean Server)</para>
+ <para>要使用JMX管理JMS桥,需指定JMS桥所要注册的MBeanServer(如JVM Platform MBeanServer 或
+ JBoss 应用服务器的MBeanServer)</para>
</listitem>
<listitem>
<para>ObjectName</para>
- <para>If you set the MBeanServer, you also need to set the ObjectName used to register
- the JMS Bridge MBean (must be unique)</para>
+ <para>设置了MBeanServer后,你还需要设置JMS桥MBean注册用的ObjectName(必须是唯一的)</para>
</listitem>
</itemizedlist>
</section>
<section>
- <title>Source and Target Connection Factories</title>
- <para>The source and target connection factory factories are used to create the
- connection factory used to create the connection for the source or target
- server.</para>
- <para>The configuration example above uses the default implementation provided by
- HornetQ that looks up the connection factory using JNDI. For other Application
- Servers or JMS providers a new implementation may have to be provided. This can
- easily be done by implementing the interface <literal
- >org.hornetq.jms.bridge.ConnectionFactoryFactory</literal>.</para>
+ <title>源和目的的连接工厂</title>
+ <para>源工目的的连接工厂分别用于创建到源和到目的的连接。</para>
+ <para>上面的配置例子中使用的是HornetQ提供的默认实现。它使用JNDI查找连接工厂。对于其它的应用服务器
+ 或JMS提供者,需要实现相应的实现,即实现<literal
+ >org.hornetq.jms.bridge.ConnectionFactoryFactory</literal>接口。</para>
</section>
<section>
- <title>Source and Target Destination Factories</title>
- <para>Again, similarly, these are used to create or lookup up the destinations.</para>
- <para>In the configuration example above, we have used the default provided by HornetQ
- that looks up the destination using JNDI.</para>
- <para>A new implementation can be provided by implementing <literal
- >org.hornetq.jms.bridge.DestinationFactory</literal> interface.</para>
+ <title>源和目的的目标工厂</title>
+ <para>它们用来创建或查找相应的目标。</para>
+ <para>上面例子中,我们使用了HornetQ的默认实现,从JNDI中查找相应的对象。</para>
+ <para>要提供新的实现,只要实现接口<literal
+ >org.hornetq.jms.bridge.DestinationFactory</literal>即可。</para>
</section>
<section id="quality-of-service">
- <title>Quality Of Service</title>
- <para>The quality of service modes used by the bridge are described here in more
- detail.</para>
+ <title>服务质量</title>
+ <para>下面给是桥的三种服务质量的详细说明。</para>
<section>
<title>AT_MOST_ONCE</title>
- <para>With this QoS mode messages will reach the destination from the source at most
- once. The messages are consumed from the source and acknowledged before sending
- to the destination. Therefore there is a possibility that if failure occurs
- between removing them from the source and them arriving at the destination they
- could be lost. Hence delivery will occur at most once.</para>
- <para>This mode is available for both durable and non-durable messages.</para>
+ <para>这种QoS模式表示的是消息最多送达目标一次。在消息发往目的之前,消息就会被通知。因此,
+ 如果在消息被源删除但并未到达目的时发生故障,消息有可能丢失。所以说消息的
+ 发送最多一次。 </para>
+ <para>这个模式适用于持久或非持久的消息。</para>
</section>
<section>
<title>DUPLICATES_OK</title>
- <para>With this QoS mode, the messages are consumed from the source and then
- acknowledged after they have been successfully sent to the destination.
- Therefore there is a possibility that if failure occurs after sending to the
- destination but before acknowledging them, they could be sent again when the
- system recovers. I.e. the destination might receive duplicates after a
- failure.</para>
- <para>This mode is available for both durable and non-durable messages.</para>
+ <para>在这个QoS模式下,消息从源接收后再发送到目的,之后才对源进行消息通知。这样如果在发送成功之后
+ 消息通知前的时间内发生故障的话,在故障恢复时同一个消息可能被再次传递。結果可能是在目的处
+ 该消息收到了两次。</para>
+ <para>这个模式适用于持久或非持久的消息。</para>
</section>
<section>
<title>ONCE_AND_ONLY_ONCE</title>
- <para>This QoS mode ensures messages will reach the destination from the source once
- and only once. (Sometimes this mode is known as "exactly once"). If both the
- source and the destination are on the same HornetQ server instance then this can
- be achieved by sending and acknowledging the messages in the same local
- transaction. If the source and destination are on different servers this is
- achieved by enlisting the sending and consuming sessions in a JTA transaction.
- The JTA transaction is controlled by JBoss Transactions JTA * implementation
- which is a fully recovering transaction manager, thus providing a very high
- degree of durability. If JTA is required then both supplied connection factories
- need to be XAConnectionFactory implementations. This is likely to be the slowest
- mode since it requires extra persistence for the transaction logging.</para>
- <para>This mode is only available for durable messages.</para>
+ <para>这个模式保证消息从源发送到目的一次,并且只有一次。(有时这个模式又称为“只一次”)。若源与目的处于
+ 同一个HornetQ服务器中,这个模式通过本地事务来保证消息的发送和通知。如果是在不同的服务器上,
+ 则会使用一个JTA的事务将发送和接收包括其中。这里使用的JTA事务是JBoss的实现,它包含有一个
+ 完整的事务恢复管理器,所以能提供高度可靠的持久性。如果使用JTA则桥的所有连接工厂必须是
+ XAConnectionFactory。这种模式的效率通常是最低的,因为它需要额外记录事务的日志。</para>
+ <para>这个模式只适用于持久性消息。</para>
<note>
- <para>For a specific application it may possible to provide once and only once
- semantics without using the ONCE_AND_ONLY_ONCE QoS level. This can be done
- by using the DUPLICATES_OK mode and then checking for duplicates at the
- destination and discarding them. Some JMS servers provide automatic
- duplicate message detection functionality, or this may be possible to
- implement on the application level by maintaining a cache of received
- message ids on disk and comparing received messages to them. The cache would
- only be valid for a certain period of time so this approach is not as
- watertight as using ONCE_AND_ONLY_ONCE but may be a good choice depending on
- your specific application.</para>
+ <para>某些情况下可以不使用ONCE_AND_ONLY_ONCE模式,而同样可以保证“一次且只一次”的效果。
+ 这是通过使用DUPLICATES_OK模式,加上在目的端应用程序来检测重复的消息,如果有则将其丢弃。
+ 一些JMS服务器本身提供自动重复消息检测的功能,这样节省了在应用层实现的工作。在应用层常见
+ 的实现方法是将接收到的消息的ID存放到缓存文件中,然后与每个新到的消息进行对比。这种方式
+ 可能在某段时间内有效,所以它不如ONCE_AND_ONLY_ONCE那样严格,它视具体情况也可能是一个
+ 不错的选择。</para>
</note>
</section>
<section>
- <title>Examples</title>
- <para>Please see <xref linkend="examples.javaee.jms-bridge"/> which shows how to configure
- and use a JMS Bridge with JBoss AS to send messages to the source destination and consume them
- from the target destination.</para>
- <para>Please see <xref linkend="examples.jms.jms-bridge"/> which shows how to configure
- and use a JMS Bridge between two standalone HornetQ servers.</para>
+ <title>例子</title>
+ <para>参见<xref linkend="examples.javaee.jms-bridge"/>。这个例子展示了如何在JBoss应用服务器中配置并使用
+ JMS桥从一处目标将消息转发到另一个目标。</para>
+ <para>关于如何在两个单独HornetQ服务器间使用桥的例子,请参见<xref linkend="examples.jms.jms-bridge"/>。</para>
</section>
</section>
</chapter>
14 years
JBoss hornetq SVN: r9149 - in trunk: src/main/org/hornetq/ra/inflow and 1 other directory.
by do-not-reply@jboss.org
Author: jmesnil
Date: 2010-04-22 10:57:31 -0400 (Thu, 22 Apr 2010)
New Revision: 9149
Modified:
trunk/docs/user-manual/en/appserver-integration.xml
trunk/docs/user-manual/en/configuration-index.xml
trunk/src/main/org/hornetq/ra/inflow/HornetQActivation.java
trunk/src/main/org/hornetq/ra/inflow/HornetQActivationSpec.java
Log:
https://jira.jboss.org/jira/browse/HORNETQ-326: Improve documentation on configuring MDBs and resource adapter
* update Resource Adapter configuration documentation
* removed MinSession and MaxMessages properties from HornetQActivationSpec (but kept setters for backwards compatibility)
Modified: trunk/docs/user-manual/en/appserver-integration.xml
===================================================================
--- trunk/docs/user-manual/en/appserver-integration.xml 2010-04-22 13:33:30 UTC (rev 9148)
+++ trunk/docs/user-manual/en/appserver-integration.xml 2010-04-22 14:57:31 UTC (rev 9149)
@@ -371,18 +371,21 @@
</listitem>
</orderedlist>
<section>
- <title>Adapter Global properties</title>
+ <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 2 configure the transport used by the adapter
- and the rest configure the connection factory itself.<note><para>All connection
- factory properties will use the defaults when not provided. This is accept
- for the <literal>reconnectAttempts</literal> which will default to -1 which
- signifies that the connection should attempt to reconnect on connection
- failure indefinately. 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>
+ 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>
@@ -401,15 +404,14 @@
<row>
<entry>ConnectorClassName</entry>
<entry>String</entry>
- <entry>The Connector class name see <xref
- linkend="configuring-transports"/> for info on available
- connectors</entry>
+ <entry>The Connector class name (see <xref
+ linkend="configuring-transports"/> for more information)</entry>
</row>
<row>
<entry>ConnectionParameters</entry>
<entry>String</entry>
- <entry>The transport configuration. These values must be in the form of
- key=val;key=val; and will be specific to the connector used</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</entry>
</row>
<row>
<entry>useLocalTx</entry>
@@ -417,11 +419,6 @@
<entry>True will enable local transaction optimisation.</entry>
</row>
<row>
- <entry>UseXA</entry>
- <entry>boolean</entry>
- <entry>Whether XA should be used</entry>
- </row>
- <row>
<entry>UserName</entry>
<entry>String</entry>
<entry>The user name to use when making a connection </entry>
@@ -432,174 +429,237 @@
<entry>The password to use when making a connection</entry>
</row>
<row>
- <entry>BackUpTransportType</entry>
+ <entry>BackupConnectorClassName</entry>
<entry>String</entry>
- <entry>The back up transport to use on failure.</entry>
+ <entry>The backup transport to use in case of failure of the live node</entry>
</row>
<row>
- <entry>TransportConfiguration</entry>
+ <entry>BackupConnectionParameters</entry>
<entry>String</entry>
- <entry>The back up transport configuration</entry>
+ <entry>The backup transport configuration parameters</entry>
</row>
<row>
- <entry>DiscoveryGroupAddress</entry>
+ <entry>
+ <link linkend="configuration.discovery-group.group-address">DiscoveryAddress</link></entry>
<entry>String</entry>
<entry>The discovery group address to use to autodetect a server</entry>
</row>
<row>
- <entry>DiscoveryGroupPort</entry>
- <entry>integer</entry>
+ <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>DiscoveryRefreshTimeout</entry>
- <entry>long</entry>
+ <entry>
+ <link linkend="configuration.discovery-group.refresh-timeout">DiscoveryRefreshTimeout</link></entry>
+ <entry>Long</entry>
<entry>The timeout, in milli seconds, to refresh.</entry>
</row>
<row>
- <entry>DiscoveryInitialWaitTimeout</entry>
- <entry>long</entry>
+ <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>LoadBalancingPolicyClassName</entry>
+ <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>PingPeriod</entry>
- <entry>long</entry>
- <entry>The period, in milliseconds, to ping the server for
- failure.</entry>
+ <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>ConnectionTTL</entry>
- <entry>long</entry>
- <entry>The time to live for the connection.</entry>
+ <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>CallTimeout</entry>
- <entry>long</entry>
- <entry>the call timeout, in milli seconds, for each packet sent.</entry>
+ <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>DupsOKBatchSize</entry>
- <entry>integer</entry>
- <entry>The batch size of message acks to use if Dups ok is used.</entry>
+ <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>
- </tbody>
- </tgroup>
- </table>
- <para>continued..</para>
- <informaltable frame="topbot">
- <tgroup cols="3">
- <colspec colname="c1" colnum="1"/>
- <colspec colname="c2" colnum="2"/>
- <colspec colname="c3" colnum="3"/>
- <tbody>
<row>
- <entry>TransactionBatchSize</entry>
- <entry>integer</entry>
- <entry>The batch size to use for sending messages within a
- transaction</entry>
+ <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>ConsumerWindowSize</entry>
- <entry>integer</entry>
- <entry>The window size for the consumers internal buffer.</entry>
+ <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>ConsumerMaxRate</entry>
- <entry>integer</entry>
- <entry>The max rate a consumer can receive.</entry>
+ <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>ConfirmationWindowSize</entry>
- <entry>integer</entry>
- <entry>The window size for confirmations.</entry>
+ <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>ProducerMaxRate</entry>
- <entry>integer</entry>
- <entry>The max rate a producer can send messages.</entry>
+ <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>MinLargeMessageSize</entry>
- <entry>integer</entry>
- <entry>The size a message can be, in bytes, before it is sent as a multi
- part large message.</entry>
+ <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>BlockOnAcknowledge</entry>
- <entry>boolean</entry>
- <entry>If true then block on acknowledge of messages.</entry>
+ <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>BlockOnNonDurableSend</entry>
- <entry>boolean</entry>
- <entry>If true then block when sending non-durable messages</entry>
+ <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>BlockOnDurableSend</entry>
- <entry>boolean</entry>
- <entry>If true then block when sending durable messages</entry>
+ <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>AutoGroup</entry>
- <entry>boolean</entry>
- <entry>If true then auto group messages</entry>
+ <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>PreAcknowledge</entry>
- <entry>boolean</entry>
- <entry>Whether to pre acknowledge messages before sending to
- consumer</entry>
- </row>
- <row>
- <entry>reconnectAttempts</entry>
+ <entry>
+ <link linkend="configuration.connection-factory.reconnect-attempts">ReconnectAttempts</link>
+ </entry>
<entry>Integer</entry>
- <entry>How attemts to try at reconnecting, default is -1</entry>
+ <entry>maximum number of retry attempts, default for the resource adpater is -1 (infinite attempts)</entry>
</row>
<row>
- <entry>RetryInterval</entry>
- <entry>long</entry>
- <entry>How long to wait , in milli seconds, before retrying a failed
- connection</entry>
+ <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>RetryIntervalMultiplier</entry>
- <entry>double</entry>
- <entry>Used for calculating the retry interval</entry>
+ <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>FailoverOnServerShutdown</entry>
- <entry>boolean</entry>
+ <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>ClientID</entry>
+ <entry>
+ <link linkend="configuration.connection-factory.client-id">ClientID</link>
+ </entry>
<entry>String</entry>
- <entry>The client ID of the connection</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>
</tbody>
</tgroup>
- </informaltable>
+ </table>
</section>
<section>
- <title>Adapter Outbound configuration</title>
+ <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.sar</literal> directory in the Jboss AS
- deployment. The connection factories defined in the config file inherit their
+ 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 show how to define one.</para>
- <para>Please note that this configuration only applies to install the HornetQ resource
- adapter in the JBoss Application Server. If you are using another JEE application
+ 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/>
@@ -618,19 +678,115 @@
<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")
+ <programlisting>@Resource(mappedName="java:/RemoteJmsXA")
private ConnectionFactory connectionFactory;</programlisting>
- <para>The <literal>config-property</literal> elements are what over rides those in the
- <literal>ra.xml</literal> config. Any of the elements pertaining to the
- connection factory can be over ridden here.</para>
+ <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>
+ <title>Adapter Inbound Configuration</title>
<para>The inbound configuration should again remain unchanged. This controls what
- forwards messages onto MDB's. It is possible to override properties on the MDB by
+ 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. The next section demonstrates
- over riding the configuration.</para>
+ 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>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>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>
<section>
Modified: trunk/docs/user-manual/en/configuration-index.xml
===================================================================
--- trunk/docs/user-manual/en/configuration-index.xml 2010-04-22 13:33:30 UTC (rev 9148)
+++ trunk/docs/user-manual/en/configuration-index.xml 2010-04-22 14:57:31 UTC (rev 9149)
@@ -577,7 +577,7 @@
<entry/>
</row>
<row>
- <entry>
+ <entry id="configuration.discovery-group.group-address">
<link linkend="clusters.discovery-groups">discovery-group.group-address</link>
</entry>
<entry>String</entry>
@@ -585,7 +585,7 @@
<entry/>
</row>
<row>
- <entry>
+ <entry id="configuration.discovery-group.group-port">
<link linkend="clusters.discovery-groups">discovery-group.group-port</link>
</entry>
<entry>Integer</entry>
@@ -593,7 +593,7 @@
<entry/>
</row>
<row>
- <entry>
+ <entry id="configuration.discovery-group.refresh-timeout">
<link linkend="clusters.discovery-groups">discovery-group.refresh-timeout</link>
</entry>
<entry>Integer</entry>
@@ -984,86 +984,96 @@
</thead>
<tbody>
<row>
- <entry><link linkend="using-jms.server.configuration"
- >connection-factory</link></entry>
+ <entry>
+ <link linkend="using-jms.server.configuration">connection-factory</link>
+ </entry>
<entry>ConnectionFactory</entry>
<entry>a list of connection factories to create and add to JNDI</entry>
<entry/>
</row>
<row>
<entry id="configuration.connection-factory.auto-group">
- <link linkend="message-grouping.jmsconfigure">connection-factory.auto-group</link></entry>
+ <link linkend="message-grouping.jmsconfigure">connection-factory.auto-group</link>
+ </entry>
<entry>Boolean</entry>
<entry>whether or not message grouping is automatically used</entry>
<entry>false</entry>
</row>
<row>
- <entry><link linkend="clusters.static.servers"
- >connection-factory.connectors</link></entry>
+ <entry><link linkend="clusters.static.servers">connection-factory.connectors</link>
+ </entry>
<entry>String</entry>
<entry>A list of connectors used bu the connection factory</entry>
<entry />
</row>
<row>
<entry><link linkend="clusters.static.servers"
- >connection-factory.connectors.connector-ref.connector-name (attribute)</link></entry>
+ >connection-factory.connectors.connector-ref.connector-name (attribute)</link>
+ </entry>
<entry>String</entry>
<entry>Name of the connector to connect to the live server</entry>
<entry />
</row>
<row>
<entry><link linkend="clusters.static.servers"
- >connection-factory.connectors.connector-ref.backup-connector-name (attribute)</link></entry>
+ >connection-factory.connectors.connector-ref.backup-connector-name (attribute)</link>
+ </entry>
<entry>String</entry>
<entry>Name of the connector to connect to the backup server</entry>
<entry />
</row>
<row>
<entry><link linkend="clusters-discovery.groups.clientside"
- >connection-factory.discovery-group-ref.discovery-group-name (attribute)</link></entry>
+ >connection-factory.discovery-group-ref.discovery-group-name (attribute)</link>
+ </entry>
<entry>String</entry>
<entry>Name of discovery group used by this connection factory</entry>
<entry />
</row>
<row>
- <entry><link linkend="clusters-discovery.groups.clientside"
- >connection-factory.discovery-initial-wait-timeout</link></entry>
+ <entry id="configuration.connection-factory.discovery-initial-wait-timeout">
+ <link linkend="clusters-discovery.groups.clientside"
+ >connection-factory.discovery-initial-wait-timeout</link>
+ </entry>
<entry>Long</entry>
<entry>the initial time to wait (in ms) for discovery groups to wait for
broadcasts</entry>
<entry>2000</entry>
</row>
<row>
- <entry><link linkend="send-guarantees.nontrans.acks"
- >connection-factory.block-on-acknowledge</link></entry>
+ <entry id="configuration.connection-factory.block-on-acknowledge">
+ <link linkend="send-guarantees.nontrans.acks">connection-factory.block-on-acknowledge</link>
+ </entry>
<entry>Boolean</entry>
<entry>whether or not messages are acknowledged synchronously</entry>
<entry>false</entry>
</row>
<row>
- <entry><link linkend="non-transactional-sends"
- >connection-factory.block-on-non-durable-send</link></entry>
+ <entry id="configuration.connection-factory.block-on-non-durable-send">
+ <link linkend="non-transactional-sends">connection-factory.block-on-non-durable-send</link>
+ </entry>
<entry>Boolean</entry>
- <entry>whether or not non-durable messages are sent
- synchronously</entry>
+ <entry>whether or not non-durable messages are sent synchronously</entry>
<entry>false</entry>
</row>
<row>
- <entry><link linkend="non-transactional-sends"
- >connection-factory.block-on-durable-send</link></entry>
+ <entry id="configuration.connection-factory.block-on-durable-send">
+ <link linkend="non-transactional-sends">connection-factory.block-on-durable-send</link>
+ </entry>
<entry>Boolean</entry>
<entry>whether or not durable messages are sent synchronously</entry>
<entry>true</entry>
</row>
<row>
- <entry>connection-factory.call-timeout</entry>
+ <entry id="configuration.connection-factory.call-timeout">connection-factory.call-timeout</entry>
<entry>Long</entry>
<entry>the timeout (in ms) for remote calls</entry>
<entry>30000</entry>
</row>
<row>
- <entry><link linkend="dead.connections"
- >connection-factory.client-failure-check-period</link></entry>
+ <entry id="configuration.connection-factory.client-failure-check-period">
+ <link linkend="dead.connections">connection-factory.client-failure-check-period</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
@@ -1071,44 +1081,48 @@
<entry>5000</entry>
</row>
<row>
- <entry><link linkend="using-jms.clientid"
- >connection-factory.client-id</link></entry>
+ <entry id="configuration.connection-factory.client-id">
+ <link linkend="using-jms.clientid">connection-factory.client-id</link>
+ </entry>
<entry>String</entry>
<entry>the pre-configured client ID for the connection factory</entry>
<entry>null</entry>
</row>
<row>
- <entry><link linkend="clusters.client.loadbalancing"
- >connection-factory.connection-load-balancing-policy-class-name</link></entry>
+ <entry id="configuration.connection-factory.connection-load-balancing-policy-class-name">
+ <link linkend="clusters.client.loadbalancing">
+ connection-factory.connection-load-balancing-policy-class-name</link>
+ </entry>
<entry>String</entry>
<entry>the name of the load balancing class</entry>
<entry>org.hornetq.api.core.client.loadbalance.RoundRobinConnectionLoadBalancingPolicy</entry>
</row>
<row>
- <entry><link linkend="dead.connections"
- >connection-factory.connection-ttl</link></entry>
+ <entry id="configuration.connection-factory.connection-ttl">
+ <link linkend="dead.connections">connection-factory.connection-ttl</link>
+ </entry>
<entry>Long</entry>
<entry>the time to live (in ms) for connections</entry>
<entry>1 * 60000</entry>
</row>
<row>
- <entry><link linkend="flow-control.rate.core.api"
- >connection-factory.consumer-max-rate</link></entry>
+ <entry id="configuration.connection-factory.consumer-max-rate">
+ <link linkend="flow-control.rate.core.api">connection-factory.consumer-max-rate</link></entry>
<entry>Integer</entry>
<entry>the fastest rate a consumer may consume messages per
second</entry>
<entry>-1</entry>
</row>
<row>
- <entry><link linkend="flow-control.core.api"
- >connection-factory.consumer-window-size</link></entry>
+ <entry id="configuration.connection-factory.consumer-window-size">
+ <link linkend="flow-control.core.api">connection-factory.consumer-window-size</link></entry>
<entry>Integer</entry>
<entry>the window size (in bytes) for consumer flow control</entry>
<entry>1024 * 1024</entry>
</row>
<row>
- <entry><link linkend="using-jms.dupsokbatchsize"
- >connection-factory.dups-ok-batch-size</link></entry>
+ <entry id="configuration.connection-factory.dups-ok-batch-size">
+ <link linkend="using-jms.dupsokbatchsize">connection-factory.dups-ok-batch-size</link></entry>
<entry>Integer</entry>
<entry>the batch size (in bytes) between acknowledgements when using
DUPS_OK_ACKNOWLEDGE mode</entry>
@@ -1122,17 +1136,17 @@
<entry>false</entry>
</row>
<row>
- <entry><link linkend="ha.automatic.failover"
- >connection-factory.failover-on-server-shutdown</link></entry>
+ <entry id="configuration.connection-factory.failover-on-server-shutdown">
+ <link linkend="ha.automatic.failover">connection-factory.failover-on-server-shutdown</link></entry>
<entry>Boolean</entry>
<entry>whether or not to failover on server shutdown</entry>
<entry>false</entry>
</row>
<row>
- <entry><link linkend="large-messages.core.config"
- >connection-factory.min-large-message-size</link></entry>
+ <entry id="configuration.connection-factory.min-large-message-size">
+ <link linkend="large-messages.core.config">connection-factory.min-large-message-size</link></entry>
<entry>Integer</entry>
- <entry>the size (in bytes) before a message is treated as large </entry>
+ <entry>the size (in bytes) before a message is treated as large</entry>
<entry>100 * 1024</entry>
</row>
<row>
@@ -1144,16 +1158,16 @@
<entry>false</entry>
</row>
<row>
- <entry><link linkend="pre-acknowledge.configure"
- >connection-factory.pre-acknowledge</link></entry>
+ <entry id="configuration.connection-factory.pre-acknowledge">
+ <link linkend="pre-acknowledge.configure">connection-factory.pre-acknowledge</link></entry>
<entry>Boolean</entry>
<entry>whether messages are pre acknowledged by the server before
sending</entry>
<entry>false</entry>
</row>
<row>
- <entry><link linkend="flow-control.producer.rate.core.api"
- >connection-factory.producer-max-rate</link></entry>
+ <entry id="configuration.connection-factory.producer-max-rate">
+ <link linkend="flow-control.producer.rate.core.api">connection-factory.producer-max-rate</link></entry>
<entry>Integer</entry>
<entry>the maximum rate of messages per second that can be sent</entry>
<entry>-1</entry>
@@ -1166,32 +1180,36 @@
<entry>1024 * 1024</entry>
</row>
<row>
- <entry><link linkend="client-reconnection"
- >connection-factory.confirmation-window-size</link></entry>
+ <entry id="configuration.connection-factory.confirmation-window-size">
+ <link linkend="client-reconnection">connection-factory.confirmation-window-size</link>
+ </entry>
<entry>Integer</entry>
<entry>the window size (in bytes) for reattachment confirmations</entry>
<entry>1024 * 1024</entry>
</row>
<row>
- <entry><link linkend="client-reconnection"
- >connection-factory.reconnect-attempts</link></entry>
+ <entry id="configuration.connection-factory.reconnect-attempts">
+ <link linkend="client-reconnection">connection-factory.reconnect-attempts</link>
+ </entry>
<entry>Integer</entry>
<entry>maximum number of retry attempts, -1 signifies infinite</entry>
<entry>0</entry>
</row>
<row>
- <entry><link linkend="client-reconnection"
- >connection-factory.retry-interval</link></entry>
+ <entry id="configuration.connection-factory.retry-interval">
+ <link linkend="client-reconnection">connection-factory.retry-interval</link>
+ </entry>
<entry>Long</entry>
<entry>the time (in ms) to retry a connection after failing</entry>
<entry>2000</entry>
</row>
<row>
- <entry><link linkend="client-reconnection"
- >connection-factory.retry-interval-multiplier</link></entry>
+ <entry id="configuration.connection-factory.retry-interval-multiplier">
+ <link linkend="client-reconnection">connection-factory.retry-interval-multiplier</link>
+ </entry>
<entry>Double</entry>
<entry>multiplier to apply to successive retry intervals</entry>
- <entry>1d</entry>
+ <entry>1.0</entry>
</row>
<row>
<entry><link linkend="client-reconnection"
@@ -1201,30 +1219,35 @@
<entry>2000</entry>
</row>
<row>
- <entry><link linkend="thread-pooling.client.side"
- >connection-factory.scheduled-thread-pool-max-size</link></entry>
+ <entry id="configuration.connection-factory.scheduled-thread-pool-max-size">
+ <link linkend="thread-pooling.client.side">connection-factory.scheduled-thread-pool-max-size</link>
+ </entry>
<entry>Integer</entry>
- <entry>the size of the scheduled thread pool</entry>
+ <entry>the size of the <emphasis>scheduled thread</emphasis> pool</entry>
<entry>5</entry>
</row>
<row>
- <entry><link linkend="thread-pooling.client.side"
- >connection-factory.thread-pool-max-size</link></entry>
+ <entry id="configuration.connection-factory.thread-pool-max-size">
+ <link linkend="thread-pooling.client.side">connection-factory.thread-pool-max-size</link>
+ </entry>
<entry>Integer</entry>
<entry>the size of the thread pool</entry>
<entry>-1</entry>
</row>
<row>
- <entry><link linkend="using-jms.txbatchsize"
- >connection-factory.transaction-batch-size</link></entry>
+ <entry id="configuration.connection-factory.transaction-batch-size">
+ <link linkend="using-jms.txbatchsize">
+ connection-factory.transaction-batch-size</link>
+ </entry>
<entry>Integer</entry>
<entry>the batch size (in bytes) between acknowledgements when using a
transactional session</entry>
<entry>1024 * 1024</entry>
</row>
<row>
- <entry><link linkend="thread-pooling.client.side"
- >connection-factory.use-global-pools</link></entry>
+ <entry id="configuration.connection-factory.use-global-pools">
+ <link linkend="thread-pooling.client.side">connection-factory.use-global-pools</link>
+ </entry>
<entry>Boolean</entry>
<entry>whether or not to use a global thread pool for threads</entry>
<entry>true</entry>
Modified: trunk/src/main/org/hornetq/ra/inflow/HornetQActivation.java
===================================================================
--- trunk/src/main/org/hornetq/ra/inflow/HornetQActivation.java 2010-04-22 13:33:30 UTC (rev 9148)
+++ trunk/src/main/org/hornetq/ra/inflow/HornetQActivation.java 2010-04-22 14:57:31 UTC (rev 9149)
@@ -27,7 +27,6 @@
import javax.resource.ResourceException;
import javax.resource.spi.endpoint.MessageEndpointFactory;
import javax.resource.spi.work.Work;
-import javax.resource.spi.work.WorkException;
import javax.resource.spi.work.WorkManager;
import org.hornetq.api.core.SimpleString;
@@ -277,7 +276,7 @@
setupCF();
setupDestination();
- for (int i = 0; i < spec.getMaxSessionInt(); i++)
+ for (int i = 0; i < spec.getMaxSession(); i++)
{
ClientSession session = null;
Modified: trunk/src/main/org/hornetq/ra/inflow/HornetQActivationSpec.java
===================================================================
--- trunk/src/main/org/hornetq/ra/inflow/HornetQActivationSpec.java 2010-04-22 13:33:30 UTC (rev 9148)
+++ trunk/src/main/org/hornetq/ra/inflow/HornetQActivationSpec.java 2010-04-22 14:57:31 UTC (rev 9149)
@@ -38,6 +38,8 @@
*/
public class HornetQActivationSpec extends ConnectionFactoryProperties implements ActivationSpec
{
+ private static final int DEFAULT_MAX_SESSION = 15;
+
/** The logger */
private static final Logger log = Logger.getLogger(HornetQActivationSpec.class);
@@ -76,12 +78,6 @@
/** The password */
private String password;
- /** The maximum number of messages */
- private Integer maxMessages;
-
- /** The minimum number of sessions */
- private Integer minSession;
-
/** The maximum number of sessions */
private Integer maxSession;
@@ -116,9 +112,7 @@
subscriptionName = null;
user = null;
password = null;
- maxMessages = 1;
- minSession = 1;
- maxSession = 15;
+ maxSession = DEFAULT_MAX_SESSION;
transactionTimeout = 0;
}
@@ -463,100 +457,6 @@
}
/**
- * Get the numer of max messages
- * @return The value
- */
- public Integer getMaxMessages()
- {
- if (HornetQActivationSpec.trace)
- {
- HornetQActivationSpec.log.trace("getMaxMessages()");
- }
-
- return maxMessages;
- }
-
- /**
- * Set the numer of max messages
- * @param value The value
- */
- public void setMaxMessages(final Integer value)
- {
- if (HornetQActivationSpec.trace)
- {
- HornetQActivationSpec.log.trace("setMaxMessages(" + value + ")");
- }
-
- maxMessages = value;
- }
-
- /**
- * Get the number of max messages
- * @return The value
- */
- public int getMaxMessagesInt()
- {
- if (HornetQActivationSpec.trace)
- {
- HornetQActivationSpec.log.trace("getMaxMessagesInt()");
- }
-
- if (maxMessages == null)
- {
- return 0;
- }
-
- return maxMessages;
- }
-
- /**
- * Get the number of min session
- * @return The value
- */
- public Integer getMinSession()
- {
- if (HornetQActivationSpec.trace)
- {
- HornetQActivationSpec.log.trace("getMinSession()");
- }
-
- return minSession;
- }
-
- /**
- * Set the number of min session
- * @param value The value
- */
- public void setMinSession(final Integer value)
- {
- if (HornetQActivationSpec.trace)
- {
- HornetQActivationSpec.log.trace("setMinSession(" + value + ")");
- }
-
- minSession = value;
- }
-
- /**
- * Get the number of min session
- * @return The value
- */
- public int getMinSessionInt()
- {
- if (HornetQActivationSpec.trace)
- {
- HornetQActivationSpec.log.trace("getMinSessionInt()");
- }
-
- if (minSession == null)
- {
- return 0;
- }
-
- return minSession;
- }
-
- /**
* Get the number of max session
* @return The value
*/
@@ -567,6 +467,11 @@
HornetQActivationSpec.log.trace("getMaxSession()");
}
+ if (maxSession == null)
+ {
+ return DEFAULT_MAX_SESSION;
+ }
+
return maxSession;
}
@@ -585,25 +490,6 @@
}
/**
- * Get the number of max session
- * @return The value
- */
- public int getMaxSessionInt()
- {
- if (HornetQActivationSpec.trace)
- {
- HornetQActivationSpec.log.trace("getMaxSessionInt()");
- }
-
- if (maxSession == null)
- {
- return 0;
- }
-
- return maxSession;
- }
-
- /**
* Get the transaction timeout
* @return The value
*/
@@ -734,8 +620,6 @@
{
buffer.append(" password=").append("****");
}
- buffer.append(" maxMessages=").append(maxMessages);
- buffer.append(" minSession=").append(minSession);
buffer.append(" maxSession=").append(maxSession);
buffer.append(')');
return buffer.toString();
@@ -781,6 +665,13 @@
{
}
+ public void setMinSession(final Integer value)
+ {
+ }
+ public void setMaxMessages(final Integer value)
+ {
+ }
+
}
14 years
JBoss hornetq SVN: r9148 - trunk/docs/user-manual/en.
by do-not-reply@jboss.org
Author: timfox
Date: 2010-04-22 09:33:30 -0400 (Thu, 22 Apr 2010)
New Revision: 9148
Modified:
trunk/docs/user-manual/en/paging.xml
Log:
Added note about paging
Modified: trunk/docs/user-manual/en/paging.xml
===================================================================
--- trunk/docs/user-manual/en/paging.xml 2010-04-22 13:12:53 UTC (rev 9147)
+++ trunk/docs/user-manual/en/paging.xml 2010-04-22 13:33:30 UTC (rev 9148)
@@ -75,11 +75,16 @@
</table>
</para>
</section>
-
<section id="paging.mode">
<title>Paging Mode</title>
<para>As soon as messages delivered to an address exceed the configured size, that address
alone goes into page mode.</para>
+ <note>
+ <para>Paging is done individually per address. If you configure a max-size-bytes for an
+ address, that means each matching address will have a maximum size that you
+ specified. It DOES NOT mean that the total overall size of all matching addresses is
+ limited to max-size-bytes.</para>
+ </note>
<section>
<title>Configuration</title>
<para>Configuration is done at the address settings, done at the main configuration file
@@ -136,16 +141,20 @@
</section>
<section>
<title>Dropping messages</title>
- <para>Instead of paging messages when the max size is reached, an address can also be configured to just drop messages when the address
- is full.</para>
- <para>To do this just set the <literal>address-full-policy</literal> to <literal>DROP</literal> in the address settings</para>
+ <para>Instead of paging messages when the max size is reached, an address can also be
+ configured to just drop messages when the address is full.</para>
+ <para>To do this just set the <literal>address-full-policy</literal> to <literal
+ >DROP</literal> in the address settings</para>
</section>
<section>
<title>Blocking producers</title>
- <para>Instead of paging messages when the max size is reached, an address can also be configured to block producers from sending further
- messages when the address is full, thus preventing the memory being exhausted on the server.</para>
- <para>When memory is freed up on the server, producers will automatically unblock and be able to continue sending.</para>
- <para>To do this just set the <literal>address-full-policy</literal> to <literal>BLOCK</literal> in the address settings</para>
+ <para>Instead of paging messages when the max size is reached, an address can also be
+ configured to block producers from sending further messages when the address is full,
+ thus preventing the memory being exhausted on the server.</para>
+ <para>When memory is freed up on the server, producers will automatically unblock and be
+ able to continue sending.</para>
+ <para>To do this just set the <literal>address-full-policy</literal> to <literal
+ >BLOCK</literal> in the address settings</para>
</section>
<section>
<title>Caution with Addresses with Multiple Queues</title>
@@ -176,35 +185,45 @@
</section>
<section>
<title>Paging and message selectors</title>
- <note><para>Please note that message selectors will only operate on messages in memory. If you have a large amount of messages paged to disk and
- a selector that only matches some of the paged messages, then those messages won't be consumed until the messages in memory have been consumed.
- HornetQ does not scan through page files on disk to locate matching messages. To do this efficiently would mean implementing and managing indexes amongst other things.
- Effectively we would be writing a relational database! This is not the primary role of a messaging system. If you find yourself using selectors which only
- select small subsets of messages in very large queues which are too large to fit in memory at any one time, then you probably want a relational database
- not a messaging system - you're effectively executing queries over tables.</para></note>
+ <note>
+ <para>Please note that message selectors will only operate on messages in memory. If you
+ have a large amount of messages paged to disk and a selector that only matches some
+ of the paged messages, then those messages won't be consumed until the messages in
+ memory have been consumed. HornetQ does not scan through page files on disk to
+ locate matching messages. To do this efficiently would mean implementing and
+ managing indexes amongst other things. Effectively we would be writing a relational
+ database! This is not the primary role of a messaging system. If you find yourself
+ using selectors which only select small subsets of messages in very large queues
+ which are too large to fit in memory at any one time, then you probably want a
+ relational database not a messaging system - you're effectively executing queries
+ over tables.</para>
+ </note>
</section>
<section>
<title>Paging and browsers</title>
- <note><para>Please note that message browsers only operate over messages in memory. They do not operate over messages paged to disk.
- Messages are paged to disk <emphasis>before</emphasis> they are routed to any queues, so when they are paged, they are not in any queues, so
- will not appear when browsing any queues.
-
-
- </para></note>
+ <note>
+ <para>Please note that message browsers only operate over messages in memory. They do
+ not operate over messages paged to disk. Messages are paged to disk
+ <emphasis>before</emphasis> they are routed to any queues, so when they are
+ paged, they are not in any queues, so will not appear when browsing any queues.
+ </para>
+ </note>
</section>
<section>
<title>Paging and unacknowledged messages</title>
- <note><para>
- Please note that until messages are acknowledged they are still in memory on the server, so they contribute to the size of messages on
- a particular address. If messages are paged to disk for an address, and are being consumed, they will be depaged from disk when enough
- memory has been freed up in that address after messages have been consumed and acknowledged. However if messages are not acknowledged
- then more messages will not be depaged since there is no free space in memory. In this case message consumption can appear to hang.
- If not acknowledging explictly messages are acknowledged according to the <literal>ack-batch-size</literal> setting. Be careful not to set your paging
- max size to a figure lower than ack-batch-size or your system may appear to hang!
- </para></note>
+ <note>
+ <para> Please note that until messages are acknowledged they are still in memory on the
+ server, so they contribute to the size of messages on a particular address. If
+ messages are paged to disk for an address, and are being consumed, they will be
+ depaged from disk when enough memory has been freed up in that address after
+ messages have been consumed and acknowledged. However if messages are not
+ acknowledged then more messages will not be depaged since there is no free space in
+ memory. In this case message consumption can appear to hang. If not acknowledging
+ explictly messages are acknowledged according to the <literal
+ >ack-batch-size</literal> setting. Be careful not to set your paging max size to
+ a figure lower than ack-batch-size or your system may appear to hang! </para>
+ </note>
</section>
-
-
<section>
<title>Example</title>
<para>See <xref linkend="examples.paging"/> for an example which shows how to use paging
14 years
JBoss hornetq SVN: r9147 - trunk.
by do-not-reply@jboss.org
Author: timfox
Date: 2010-04-22 09:12:53 -0400 (Thu, 22 Apr 2010)
New Revision: 9147
Modified:
trunk/build-hornetq.properties
Log:
Updated source and target JDK version to 1.6
Modified: trunk/build-hornetq.properties
===================================================================
--- trunk/build-hornetq.properties 2010-04-22 03:10:28 UTC (rev 9146)
+++ trunk/build-hornetq.properties 2010-04-22 13:12:53 UTC (rev 9147)
@@ -1,6 +1,6 @@
-# Compilation is based on Java 5
-javac.target=1.5
-javac.source=1.5
+# Compilation is based on Java 6
+javac.target=1.6
+javac.source=1.6
javac.debug=true
javac.optimize=false
javac.depend=false
14 years
JBoss hornetq SVN: r9146 - branches/HnetQ_323_cn/docs/user-manual/zh.
by do-not-reply@jboss.org
Author: gaohoward
Date: 2010-04-21 23:10:28 -0400 (Wed, 21 Apr 2010)
New Revision: 9146
Modified:
branches/HnetQ_323_cn/docs/user-manual/zh/appserver-integration.xml
Log:
done
Modified: branches/HnetQ_323_cn/docs/user-manual/zh/appserver-integration.xml
===================================================================
--- branches/HnetQ_323_cn/docs/user-manual/zh/appserver-integration.xml 2010-04-21 23:20:37 UTC (rev 9145)
+++ branches/HnetQ_323_cn/docs/user-manual/zh/appserver-integration.xml 2010-04-22 03:10:28 UTC (rev 9146)
@@ -17,26 +17,18 @@
<!-- permitted by applicable law. -->
<!-- ============================================================================= -->
<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 adaptor, it should also be 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 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>
+ <title>Java EE和应用服务器的集成</title>
+ <para>HornetQ可以容易地安装到JBoss 4应用服务器及其以上版本。有关安装的详细说明请参阅快速指南。</para>
+ <para>HornetQ提供了一个JCA适配器,使得它还可以与其它JEE兼容的应用服务器集成。请参阅其它应用服务器的
+ 有关JCA适配器集成的说明来操作。</para>
+ <para>JCA适配器的作用是控制消息流入到消息Bean(MDB),并控制消息从各种JEE模块中发出(如EJB和Servlet)。</para>
+ <para>本章讲述这些JEE模块配置HornetQ的基本信息。</para>
<section>
- <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 in the <literal
- >jms-ra.rar</literal> archive of directory. By default this is configured to consume
- messages using an InVM connector from the instance of HornetQ running within the
- application server. A full list of what is configurable is found later in this chapter. </para>
- <para>All MDB's however need to have the destination type and the destination configured.
- The following example shows how this can be done via annotations.</para>
+ <title>配置消息Bean</title>
+ <para>使用HornetQ向MDB传递消息,需要在文件<literal>ra.xml</literal>中配置JCA适配器。该文件在
+ <literal>jms-ra.rar</literal>文件中。默认配置下HornetQ服务使用InVm连接器接收消息。在本章
+ 后面列出了可配置的选项。</para>
+ <para>所有MDB都需要有目标类型和目标的相关配置。下面就是一个使用annotation配置MDB的例子:</para>
<programlisting>@MessageDriven(name = "MDBExample",
activationConfig =
{
@@ -48,33 +40,25 @@
{
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> which can be found in the
- <literal>jboss-ejb3-ext-api.jar</literal> which can be found in the jboss
- repository. Alternatively you can add use a deployment descriptor and add something like
- the following to <literal
- >jboss.xml</literal><programlisting><message-driven>
+ <para>上例中配置了MDB从一个队列中接收消息,它的JNDI绑定名为<literal>queue/testQueue</literal>。
+ 这个队列必须事先在HornetQ服务器配置文件中配置并部署好的。</para>
+ <para><literal>ResourceAdapter</literal> annotation用来指出使用哪个适配器。要使用它必须要引入
+ <literal>org.jboss.ejb3.annotation.ResourceAdapter</literal>。这个类在
+ <literal>jboss-ejb3-ext-api.jar</literal>文件中。该文件可以在JBoss的repository中找到。
+ 另外一个方法是使用部署描述文件(deployment descriptor),即在文件<literal
+ >jboss.xml</literal>中加入类似以下的内容:
+<programlisting><message-driven>
<ejb-name>ExampleMDB</ejb-name>
<resource-adapter-name>quartz-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>
- <para>All the examples shipped with the HornetQ distribution use the annotation.</para>
+</programlisting>你还可以将hornetq-ra.rar改名为jms-ra.rar而不需要任何annotation或额外的部署描述信息。但是你需要
+ 编辑<literal>jms-ds.xml</literal>文件,将其中的<literal>rar-name</literal>项改成相应的值。</para>
+ <para>HornetQ发布包中的所有例子都使用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 this is to try and
- redeliver the message up to 10 times before sending to a DLQ). Using annotations
- this would be configured as follows:</para>
+ <title>使用容器管理事务(CMT)</title>
+ <para>当MDB使用容器管理事务时,消息的传递被包含在一个JTA事务中。事务的提交与回滚是由容器来控制的。如果事务
+ 被回滚,消息传递会进行相应的处理(默认是重新传递消息,如果重新传递次数超过10次,消息就被发往DLQ)。使用
+ annotation配置如下:</para>
<programlisting>@MessageDriven(name = "MDB_CMP_TxRequiredExample",
activationConfig =
{
@@ -88,17 +72,12 @@
{
public void onMessage(Message message)...
}</programlisting>
- <para>The <literal>TransactionManagement</literal> annotation tells the container to
- treat this MDB to use Container Managed Persistence. 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>
+ <para><literal>TransactionManagement</literal> 表示这个MDB使用容器管理持久性。
+ <literal>TransactionAttribute</literal> 表示这个MDB要求JTA事务。注意这个annotation的
+ 另外唯一的合法值是<literal>TransactionAttributeType.NOT_SUPPORTED</literal>,它表示
+ MDB不需要JTA事务支持。</para>
+ <para>如果要回滚事务,可以调用<literal>MessageDrivenContext</literal>的
+ <literal>setRollbackOnly</literal>方法。如下面的代码所示:</para>
<programlisting> @Resource
MessageDrivenContext ctx;
@@ -113,10 +92,8 @@
ctx.setRollbackOnly();
}
}</programlisting>
- <para>If you don't want the over head 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>
+ <para>如果你不需要使用XA事务,你可以用一相本地的事务来代替(比如你只有一个JMS资源)。
+ 如下所示:</para>
<programlisting>@MessageDriven(name = "MDB_CMP_TxLocalExample",
activationConfig =
{
@@ -133,10 +110,9 @@
}</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>
+ <title>使用Bean管理事务(BMT)</title>
+ <para>消息Bean可以通过配置使用Bean管理的事务(BMT)。在种情况下会创建一个用户事务
+ (User Transaction)。如下所示:</para>
<programlisting>@MessageDriven(name = "MDB_BMPExample",
activationConfig =
{
@@ -150,15 +126,11 @@
{
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 lifecycle of the transaction something like the
- following:</para>
+ <para>使用BMT时,消息的传递在用户事务的范围之外,它的通知模式由<literal>acknowledgeMode</literal>参数决定。
+ 该参数有两个合法的值,即<literal>Auto-acknowledge</literal>和<literal
+ >Dups-ok-acknowledge</literal>。请注意,由于消息的传递在事务之外,在MDB中如果发生错误消息
+ 是不会重新传递的。</para>
+ <para>用户可以像如下所示控制事务的生命周期:</para>
<programlisting> @Resource
MessageDrivenContext ctx;
@@ -186,9 +158,8 @@
}</programlisting>
</section>
<section>
- <title>Using Message Selectors with MDB's</title>
- <para>It is also possible to use MDB's with message selectors. To do this simple define
- your message selector as follows:</para>
+ <title>在MDB中使用选择器</title>
+ <para>MDB可以配置消息选择器。如下所示:</para>
<programlisting>@MessageDriven(name = "MDBMessageSelectorExample",
activationConfig =
{
@@ -206,15 +177,10 @@
</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 redelivered. Heres an example of this from within an
- MDB:</para>
+ <title>在JEE模块内发送消息</title>
+ <para>JCA适配器支持发送消息。连接工厂的默认配置在<literal>jms-ds.xml</literal>文件中,对应的JNDI名字是
+ <literal>java:/JmsXA</literal>。在JEE中使用它发送消息将作为JTA事务的一部分来对待。</para>
+ <para>如果消息发送失败,整个事务将回滚,消息会被重新发送。下面是一个MDB发送消息的例子:</para>
<programlisting>@MessageDriven(name = "MDBMessageSendTxExample",
activationConfig =
{
@@ -273,20 +239,15 @@
}
}
}</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>
+ <para>在JBoss应用服务器的EJB(包括会话Bean, 实体Bean和消息Bean)、Servlet(包括jsp)我定制的MBean中
+ 都可以使用JMS的JCA适配器来发送消息。</para>
</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 MDB's and EJB's. It configures how components such as MDB's
- consume messages from the HornetQ server and also how components such as EJB's or
- Servlet's 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>
+ <title>配置JCA适配器</title>
+ <para>通过JCA适配器可以将HornetQ集成到JEE兼容的模块中,如MDB和EJB。它的配置决定了这些模块如何接收和发送消息。</para>
+ <para>HornetQ的JCA适配器是通过<literal>jms-ra.rar</literal>部署的。它的配置文件中其中的
+ <literal>META-INF/ra.xml</literal>。</para>
+ <para>下面是它的具体配置内容:</para>
<programlisting><resourceadapter>
<resourceadapter-class>org.hornetq.ra.HornetQResourceAdapter</resourceadapter-class>
<config-property>
@@ -356,141 +317,132 @@
</inbound-resourceadapter>
</resourceadapter></programlisting>
- <para>There are 3 main parts to this configuration.</para>
+ <para>整个配置可以分为三个主要部分</para>
<orderedlist>
<listitem>
- <para>A set of global properties for the adapter</para>
+ <para>适配器的全局参数</para>
</listitem>
<listitem>
- <para>The configuration for the outbound part of the adapter. This is used for
- creating JMS resources within EE components. </para>
+ <para>适配器外部(outbound)配置。用于在JEE环境中创建JMS资源。</para>
</listitem>
<listitem>
- <para>The configuration of the inbound part of the adapter. This is used for
- controlling the consumption of messages via MDB's. </para>
+ <para>适配器内部(inbound)配置。用于控制MDB的消息接收。 </para>
</listitem>
</orderedlist>
<section>
- <title>Adapter 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 2 configure the transport used by the adapter
- and the rest configure the connection factory itself.<note><para>All connection
- factory properties will use the defaults when not provided. This is accept
- for the <literal>reconnectAttempts</literal> which will default to -1 which
- signifies that the connection should attempt to reconnect on connection
- failure indefinately. 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>
- <para>The following table explains what each property is for.</para>
+ <title>适配器的全局参数</title>
+ <para>首先看到的第一个参数是<literal>resourceadapter-class</literal>。这是HornetQ
+ 的适配器类。此参数不可更改。</para>
+ <para>在此之后是可配置的参数。前两个配置适配器所使用的传输。其余的用来配置连接工厂。
+ <note><para>所有连接工厂的参数在没有定义时使用默认值。参数<literal>reconnectAttempts</literal>
+ 的默认值取-1,表示如果连接失败,HornetQ会不停地尝试重新连接。这个参数只适用于创建远程
+ 连接的情况。如果是InVm连接器,则永远不可能发生连接故障。</para></note></para>
+ <para>下面给出了每个参数的说明:</para>
<table frame="topbot" border="2">
- <title>Global Configuration Properties</title>
+ <title>全局配置参数</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>
+ <entry>参数名</entry>
+ <entry>参数类型</entry>
+ <entry>参数说明</entry>
</row>
</thead>
<tbody>
<row>
<entry>ConnectorClassName</entry>
<entry>String</entry>
- <entry>The Connector class name see <xref
- linkend="configuring-transports"/> for info on available
- connectors</entry>
+ <entry>连接器的类名,参见 <xref
+ linkend="configuring-transports"/></entry>
</row>
<row>
<entry>ConnectionParameters</entry>
<entry>String</entry>
- <entry>The transport configuration. These values must be in the form of
- key=val;key=val; and will be specific to the connector used</entry>
+ <entry>传输配置参数。它的值必须是采用
+ key=val;key=val;的形式。不同连接器有不同的参数。</entry>
</row>
<row>
<entry>useLocalTx</entry>
<entry>boolean</entry>
- <entry>True will enable local transaction optimisation.</entry>
+ <entry>设为True,则进行本地事务优化。</entry>
</row>
<row>
<entry>UseXA</entry>
<entry>boolean</entry>
- <entry>Whether XA should be used</entry>
+ <entry>是否使用XA</entry>
</row>
<row>
<entry>UserName</entry>
<entry>String</entry>
- <entry>The user name to use when making a connection </entry>
+ <entry>用于创建连接时使用的用户名</entry>
</row>
<row>
<entry>Password</entry>
<entry>String</entry>
- <entry>The password to use when making a connection</entry>
+ <entry>用于创建连接时使用的用户密码</entry>
</row>
<row>
<entry>BackUpTransportType</entry>
<entry>String</entry>
- <entry>The back up transport to use on failure.</entry>
+ <entry>发生故障是使用的备份传输</entry>
</row>
<row>
<entry>TransportConfiguration</entry>
<entry>String</entry>
- <entry>The back up transport configuration</entry>
+ <entry>备份传输的配置</entry>
</row>
<row>
<entry>DiscoveryGroupAddress</entry>
<entry>String</entry>
- <entry>The discovery group address to use to autodetect a server</entry>
+ <entry>服务器自动检测所使用的发现组(discovery group)地址</entry>
</row>
<row>
<entry>DiscoveryGroupPort</entry>
<entry>integer</entry>
- <entry>The port to use for discovery</entry>
+ <entry>检测所使用的端口号</entry>
</row>
<row>
<entry>DiscoveryRefreshTimeout</entry>
<entry>long</entry>
- <entry>The timeout, in milli seconds, to refresh.</entry>
+ <entry>刷新的时间(timeout)。单位为毫秒</entry>
</row>
<row>
<entry>DiscoveryInitialWaitTimeout</entry>
<entry>long</entry>
- <entry>The initial time to wait for discovery.</entry>
+ <entry>检测之前所需等待的时间</entry>
</row>
<row>
<entry>LoadBalancingPolicyClassName</entry>
<entry>String</entry>
- <entry>The load balancing policy class to use.</entry>
+ <entry>负载均衡策略使用的类</entry>
</row>
<row>
<entry>PingPeriod</entry>
<entry>long</entry>
- <entry>The period, in milliseconds, to ping the server for
- failure.</entry>
+ <entry>向服务器发送ping的周期,单位毫秒</entry>
</row>
<row>
<entry>ConnectionTTL</entry>
<entry>long</entry>
- <entry>The time to live for the connection.</entry>
+ <entry>连接的存活时间(TTL)</entry>
</row>
<row>
<entry>CallTimeout</entry>
<entry>long</entry>
- <entry>the call timeout, in milli seconds, for each packet sent.</entry>
+ <entry>每个数据包的调用超时。单位毫秒</entry>
</row>
<row>
<entry>DupsOKBatchSize</entry>
<entry>integer</entry>
- <entry>The batch size of message acks to use if Dups ok is used.</entry>
+ <entry>Dups OK的情况下消息批量的大小。</entry>
</row>
</tbody>
</tgroup>
</table>
- <para>continued..</para>
+ <para>继续..</para>
<informaltable frame="topbot">
<tgroup cols="3">
<colspec colname="c1" colnum="1"/>
@@ -500,106 +452,96 @@
<row>
<entry>TransactionBatchSize</entry>
<entry>integer</entry>
- <entry>The batch size to use for sending messages within a
- transaction</entry>
+ <entry>在事务中发送消息的批量大小</entry>
</row>
<row>
<entry>ConsumerWindowSize</entry>
<entry>integer</entry>
- <entry>The window size for the consumers internal buffer.</entry>
+ <entry>接收者内部缓存的窗口大小</entry>
</row>
<row>
<entry>ConsumerMaxRate</entry>
<entry>integer</entry>
- <entry>The max rate a consumer can receive.</entry>
+ <entry>接收者接收消息的最大速度</entry>
</row>
<row>
<entry>ConfirmationWindowSize</entry>
<entry>integer</entry>
- <entry>The window size for confirmations.</entry>
+ <entry>用于确认的窗口大小</entry>
</row>
<row>
<entry>ProducerMaxRate</entry>
<entry>integer</entry>
- <entry>The max rate a producer can send messages.</entry>
+ <entry>发送者发送消息的最大速度</entry>
</row>
<row>
<entry>MinLargeMessageSize</entry>
<entry>integer</entry>
- <entry>The size a message can be, in bytes, before it is sent as a multi
- part large message.</entry>
+ <entry>大消息的最小数值,单位字节。</entry>
</row>
<row>
<entry>BlockOnAcknowledge</entry>
<entry>boolean</entry>
- <entry>If true then block on acknowledge of messages.</entry>
+ <entry>如果为true,表示以阻塞方法发送消息通知。</entry>
</row>
<row>
<entry>BlockOnNonDurableSend</entry>
<entry>boolean</entry>
- <entry>If true then block when sending non-durable messages</entry>
+ <entry>如果为true,表示以阻塞方式发送非持久消息</entry>
</row>
<row>
<entry>BlockOnDurableSend</entry>
<entry>boolean</entry>
- <entry>If true then block when sending durable messages</entry>
+ <entry>如果为true,表示以阻塞方式发送持久消息</entry>
</row>
<row>
<entry>AutoGroup</entry>
<entry>boolean</entry>
- <entry>If true then auto group messages</entry>
+ <entry>如果为true,表示自动消息分组</entry>
</row>
<row>
<entry>PreAcknowledge</entry>
<entry>boolean</entry>
- <entry>Whether to pre acknowledge messages before sending to
- consumer</entry>
+ <entry>决定是否进行消息的预先通知(pre-acknowledge)。</entry>
</row>
<row>
<entry>reconnectAttempts</entry>
<entry>Integer</entry>
- <entry>How attemts to try at reconnecting, default is -1</entry>
+ <entry>连接重试的次数,默认为 -1</entry>
</row>
<row>
<entry>RetryInterval</entry>
<entry>long</entry>
- <entry>How long to wait , in milli seconds, before retrying a failed
- connection</entry>
+ <entry>每次连接重试前等待的时间,单位毫秒。</entry>
</row>
<row>
<entry>RetryIntervalMultiplier</entry>
<entry>double</entry>
- <entry>Used for calculating the retry interval</entry>
+ <entry>用于计算重试间隔</entry>
</row>
<row>
<entry>FailoverOnServerShutdown</entry>
<entry>boolean</entry>
- <entry>If true client will reconnect to another server if
- available</entry>
+ <entry>如果设为true表示尝试连接其它的服务器</entry>
</row>
<row>
<entry>ClientID</entry>
<entry>String</entry>
- <entry>The client ID of the connection</entry>
+ <entry>连接的客户端ID</entry>
</row>
</tbody>
</tgroup>
</informaltable>
</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.sar</literal> directory in the Jboss AS
- deployment. The connection factories defined in the config file inherit their
- properties from the main <literal>ra.xml</literal> configuration but can also be
- overridden, the following example show how to define one.</para>
- <para>Please note that this configuration only applies to install the HornetQ resource
- adapter in the JBoss Application Server. If you are using another JEE application
- server please refer to your application servers documentation for how to do
- this.</para>
+ <title>适配器外部(outbound)配置</title>
+ <para>外部配置参数应该保持不变。这是因为它所定义的连接工厂要被Java EE的模块所使用。这些连接工厂
+ 可以定义在名字样式为<literal>*-ds.xml</literal>的配置文件中。在JBoss的部署目录
+ <literal>hornetq.sar</literal>下有一个默认的配置文件<literal>jms-ds.xml</literal>。
+ 在这个文件中的连接工厂的配置从主要的配置文件<literal>ra.xml</literal>中继承,
+ 但是可以在这里重新定义。下面的例子中给出了重新定义的方法。</para>
+ <para>请注意这里的配置只适用于在JBoss应用服务器中安装的HornetQ。如果要在其它JEE应用服务器中
+ 使用并配置HornetQ,请参照相应的应用服务器手册。</para>
<programlisting><tx-connection-factory>
<jndi-name>RemoteJmsXA</jndi-name>
<xa-transaction/>
@@ -615,34 +557,27 @@
port=5445</config-property>
<max-pool-size>20</max-pool-size>
</tx-connection-factory></programlisting>
- <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>
+ <para>上面的例子中的连接工厂绑定到JNDI名字<literal>RemoteJmsXA</literal>。EJB和MDB可以用
+ 下面的方法来得到它:</para>
<programlisting>@Resource(mappedName="java:RemoteJmsXA")
private ConnectionFactory connectionFactory;</programlisting>
- <para>The <literal>config-property</literal> elements are what over rides those in the
- <literal>ra.xml</literal> config. Any of the elements pertaining to the
- connection factory can be over ridden here.</para>
+ <para><literal>config-property</literal>覆盖了<literal>ra.xml</literal>文件中的配置。
+ 以此类推,其它有关连接工厂的参数也可以在此覆盖。</para>
</section>
<section>
- <title>Adapter Inbound configuration</title>
- <para>The inbound configuration should again remain unchanged. This controls what
- forwards messages onto MDB's. 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. The next section demonstrates
- over riding the configuration.</para>
+ <title>适配器内部(inbound)配置</title>
+ <para>内部配置参数也应该保持不变。它们控制向MDB转发消息的各种属性。通过在MDB上添加相应的激活配置
+ (activation configuration)可以覆盖这些参数的值。它可以用来配置一个MDB从另外一个服务器
+ 接收消息。下一节将讲述如何覆盖这些配置。</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>
+ <title>高可获得性JNDI (HA-JNDI)</title>
+ <para>采用JNDI来查找JMS对象时(队列,话题及连接工厂),使用HA-JNDI可以增加容错的能力。即当你正在使用
+ 的JNDI服务器发生故障时,客户端可以使用集群中的其它JNDI服务器继续工作。</para>
+ <para>HA-JNDI是JBoss应用服务器的一项服务,它为客户端提供JNDI服务,客户端无需知道JNDI具体服务器的连接
+ 细节。这个服务只有在集群的JBoss应用服务器上才可使用。</para>
+ <para>要使用HA-JNDI,需要使用下面的JNDI参数。</para>
<programlisting>Hashtable<String, String> jndiParameters = new Hashtable<String, String>();
jndiParameters.put("java.naming.factory.initial",
"org.jnp.interfaces.NamingContextFactory");
@@ -650,113 +585,97 @@
"org.jboss.naming:org.jnp.interfaces");
initialContext = new InitialContext(jndiParameters);</programlisting>
- <para>For more information on using HA-JNDI see the <ulink
+ <para>有关HA-JNDI更多的信息请参见<ulink
url="http://www.jboss.org/file-access/default/members/jbossas/freezone/docs/Cl..."
- >JBoss Application Server clustering documentation</ulink></para>
+ >JBoss应用服务器集群文档</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
+ <title>XA恢复</title>
+ <para><emphasis>XA恢复</emphasis>解决的是事务在系统或应用出现故障时的处理。它可以保证在应用进程或主机出现故障
+ 或网络崩溃等情况下,事务内所有资源的状态的一致性。有关XA恢复的更多信息请见 <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>
+ 事务</ulink>。</para>
+ <para>当HornetQ与JBoss应用服务器集成时,它可以利用JBoss的事务处理来对消息资源进行恢复。如果消息处理包括
+ 在一个XA事务中,如果服务器出现故障并重启时,恢复管理器将负责恢复事务,这样其中的消息要么被提交,要么被回滚(取
+ 决于事务的处理决定)。</para>
<section>
- <title>XA Recovery Configuration</title>
- <para>To enable HornetQs 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>
+ <title>XA恢复的配置</title>
+ <para>要想HornetQ具有XA恢复功能,则必须配置恢复管理器连接到HornetQ并恢复其资源。下面的参数必须要加到
+ <literal>conf/jbossts-properties.xml</literal>文件中的<literal>jta</literal>部分:</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]"/>
+ value="org.hornetq.jms.server.recovery.HornetQXAResourceRecovery;[连接配置]"/>
</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>
+ <para>其中<literal>[连接配置]</literal>包括连接HornetQ节点所必需的信息。
+ 它的格式是<literal>[连接工厂类名],[用户名], [密码], [连接参数]</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
+ <para><literal>[连接工厂类名]</literal>指的是<literal>ConnectorFactory</literal>
+ 的类名,用来连接HornetQ服务器。其值可以是<literal
+ >org.hornetq.core.remoting.impl.invm.InVMConnectorFactory</literal> 或
<literal
>org.hornetq.integration.transports.netty.NettyConnectorFactory</literal></para>
</listitem>
<listitem>
- <para><literal>[user name]</literal> is the user name to create a client
- session. It is optional</para>
+ <para><literal>[用户名]</literal>是用于创建客户会话的用户名。是可选项。</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>
+ <para><literal>[密码]</literal>是创建客户会话时所用的密码。只有在用户名存在时需要。</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>
+ <para><literal>[连接参数]</literal> 是用逗号分隔的一串键-值对。它们会传递给连接器工厂
+ (参见 <xref linkend="configuring-transports"/>)。</para>
</listitem>
</itemizedlist>
<note>
- <para>HornetQ must have a valid acceptor which corresponds to the connector
- specified in <literal>conf/jbossts-properties.xml</literal>.</para>
+ <para>HornetQ必须有一个与<literal>conf/jbossts-properties.xml</literal>中定义的连接器相对应的接受器(acceptor)。</para>
</note>
<section>
- <title>Configuration Settings</title>
- <para>If HornetQ is configured with a default in-vm acceptor:</para>
+ <title>配置参数</title>
+ <para>如果HornetQ配置了一个默认的in-vm接受器:</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>
+ <para>相应地在 <literal
+ >conf/jbossts-properties.xml</literal>文件中:</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>
+ <para>如果配置了一个netty接受器,并且端口不是默认的:</para>
<programlisting>
<acceptor name="netty">
<factory-class>org.hornetq.integration.transports.netty.NettyAcceptorFactory</factory-class>
<param key="port" value="8888"/>
</acceptor>
</programlisting>
- <para>the corresponding configuration in <literal
- >conf/jbossts-properties.xml</literal> is:</para>
+ <para>相应的在 <literal
+ >conf/jbossts-properties.xml</literal>文件中:</para>
<programlisting>
<property name="com.arjuna.ats.jta.recovery.XAResourceRecovery.HORNETQ1"
value="org.hornetq.jms.server.recovery.HornetQXAResourceRecovery;org.hornetq.integration.transports.netty.NettyConnectorFactory, , , port=8888"/>
</programlisting>
<note>
- <para>Note the additional commas to skip the user and password before connector
- parameters</para>
+ <para>注意在没有用户名和密码时,逗号是不能省略的。</para>
</note>
- <para>If the recovery must use <literal>admin, adminpass</literal>, the
- configuration would have been:</para>
+ <para>如果恢复必须要求是<literal>admin, adminpass</literal>,则其配置
+ 应为如下所示:</para>
<programlisting>
<property name="com.arjuna.ats.jta.recovery.XAResourceRecovery.HORNETQ1"
value="org.hornetq.jms.server.recovery.HornetQXAResourceRecovery;org.hornetq.integration.transports.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>
+ <para>推荐在XA恢复中,将HornetQ配置一个invm接受器,并配置恢复管理器使用invm连接器。</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>
+ <title>例子</title>
+ <para>参见<xref linkend="xa-recovery-example"/>。这个例子展示了如何来配置XA恢复以便在服务器崩溃后恢复消息。</para>
</section>
</section>
</chapter>
14 years
JBoss hornetq SVN: r9145 - trunk/tests/src/org/hornetq/tests/integration/cluster/failover.
by do-not-reply@jboss.org
Author: clebert.suconic(a)jboss.com
Date: 2010-04-21 19:20:37 -0400 (Wed, 21 Apr 2010)
New Revision: 9145
Modified:
trunk/tests/src/org/hornetq/tests/integration/cluster/failover/FailoverTest.java
Log:
Adding a new test
Modified: trunk/tests/src/org/hornetq/tests/integration/cluster/failover/FailoverTest.java
===================================================================
--- trunk/tests/src/org/hornetq/tests/integration/cluster/failover/FailoverTest.java 2010-04-21 16:35:31 UTC (rev 9144)
+++ trunk/tests/src/org/hornetq/tests/integration/cluster/failover/FailoverTest.java 2010-04-21 23:20:37 UTC (rev 9145)
@@ -31,7 +31,13 @@
import org.hornetq.api.core.Message;
import org.hornetq.api.core.SimpleString;
import org.hornetq.api.core.TransportConfiguration;
-import org.hornetq.api.core.client.*;
+import org.hornetq.api.core.client.ClientConsumer;
+import org.hornetq.api.core.client.ClientMessage;
+import org.hornetq.api.core.client.ClientProducer;
+import org.hornetq.api.core.client.ClientSession;
+import org.hornetq.api.core.client.ClientSessionFactory;
+import org.hornetq.api.core.client.HornetQClient;
+import org.hornetq.api.core.client.SessionFailureListener;
import org.hornetq.core.client.impl.ClientSessionFactoryInternal;
import org.hornetq.core.client.impl.ClientSessionInternal;
import org.hornetq.core.logging.Logger;
@@ -150,6 +156,102 @@
Assert.assertEquals(0, sf.numConnections());
}
+ public void testConsumeTransacted() throws Exception
+ {
+ ClientSessionFactoryInternal sf = getSessionFactory();
+
+ sf.setBlockOnNonDurableSend(true);
+ sf.setBlockOnDurableSend(true);
+
+ ClientSession session = sf.createSession(false, false);
+
+ session.createQueue(FailoverTestBase.ADDRESS, FailoverTestBase.ADDRESS, null, true);
+
+ final CountDownLatch latch = new CountDownLatch(1);
+
+ class MyListener extends BaseListener
+ {
+ public void connectionFailed(final HornetQException me)
+ {
+ latch.countDown();
+ }
+ }
+
+ session.addFailureListener(new MyListener());
+
+ ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS);
+
+ final int numMessages = 10;
+
+ for (int i = 0; i < numMessages; i++)
+ {
+ ClientMessage message = session.createMessage(true);
+
+ setBody(i, message);
+
+ message.putIntProperty("counter", i);
+
+ producer.send(message);
+ }
+
+ session.commit();
+
+ ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS);
+
+ session.start();
+
+ for (int i = 0; i < numMessages; i++)
+ {
+ ClientMessage message = consumer.receive(1000);
+
+ message.acknowledge();
+
+ // TODO: The test won't pass if you uncomment this line
+ // assertEquals(i, (int)message.getIntProperty("counter"));
+
+ if (i == 5)
+ {
+ fail(session, latch);
+ }
+ }
+
+ boolean exception = false;
+
+ try
+ {
+ session.commit();
+ }
+ catch (HornetQException e)
+ {
+ exception = true;
+ }
+
+ consumer.close();
+
+ consumer = session.createConsumer(FailoverTestBase.ADDRESS);
+
+ session.start();
+
+ for (int i = 0; i < numMessages; i++)
+ {
+ ClientMessage message = consumer.receive(1000);
+
+ assertNotNull(message);
+
+ message.acknowledge();
+ }
+
+ session.commit();
+
+ assertTrue("Exception was expected!", exception);
+
+ session.close();
+
+ Assert.assertEquals(0, sf.numSessions());
+
+ Assert.assertEquals(0, sf.numConnections());
+ }
+
/** It doesn't fail, but it restart both servers, live and backup, and the data should be received after the restart,
* and the servers should be able to connect without any problems. */
public void testRestartServers() throws Exception
@@ -218,7 +320,7 @@
Assert.assertEquals(0, sf.numConnections());
}
-
+
// https://jira.jboss.org/jira/browse/HORNETQ-285
public void testFailoverOnInitialConnection() throws Exception
{
@@ -227,9 +329,9 @@
sf.setBlockOnNonDurableSend(true);
sf.setBlockOnDurableSend(true);
sf.setFailoverOnInitialConnection(true);
-
+
// Stop live server
-
+
this.server0Service.stop();
ClientSession session = sf.createSession();
@@ -1405,7 +1507,7 @@
session.close();
- sf = (ClientSessionFactoryInternal) HornetQClient.createClientSessionFactory(getConnectorTransportConfiguration(false));
+ sf = (ClientSessionFactoryInternal)HornetQClient.createClientSessionFactory(getConnectorTransportConfiguration(false));
session = sendAndConsume(sf, false);
@@ -1789,22 +1891,22 @@
{
testSimpleSendAfterFailover(true, true);
}
-
+
public void testSimpleSendAfterFailoverNonDurableTemporary() throws Exception
{
testSimpleSendAfterFailover(false, true);
}
-
+
public void testSimpleSendAfterFailoverDurableNonTemporary() throws Exception
{
testSimpleSendAfterFailover(true, false);
}
-
+
public void testSimpleSendAfterFailoverNonDurableNonTemporary() throws Exception
{
testSimpleSendAfterFailover(false, false);
}
-
+
private void testSimpleSendAfterFailover(final boolean durable, final boolean temporary) throws Exception
{
ClientSessionFactoryInternal sf = getSessionFactory();
@@ -1821,9 +1923,9 @@
}
else
{
- session.createQueue(FailoverTestBase.ADDRESS, FailoverTestBase.ADDRESS, null, durable);
+ session.createQueue(FailoverTestBase.ADDRESS, FailoverTestBase.ADDRESS, null, durable);
}
-
+
final CountDownLatch latch = new CountDownLatch(1);
class MyListener extends BaseListener
@@ -1996,11 +2098,11 @@
producer.send(message);
}
-
+
class Committer extends Thread
{
DelayInterceptor2 interceptor = new DelayInterceptor2();
-
+
@Override
public void run()
{
@@ -2037,25 +2139,25 @@
}
Committer committer = new Committer();
-
- //Commit will occur, but response will never get back, connetion is failed, and commit should be unblocked
- //with transaction rolled back
+ // Commit will occur, but response will never get back, connetion is failed, and commit should be unblocked
+ // with transaction rolled back
+
committer.start();
- //Wait for the commit to occur and the response to be discarded
+ // Wait for the commit to occur and the response to be discarded
assertTrue(committer.interceptor.await());
-
+
Thread.sleep(500);
-
+
fail(session, latch);
committer.join();
-
+
Assert.assertFalse(committer.failed);
session.close();
-
+
ClientSession session2 = sf.createSession(false, false);
producer = session2.createProducer(FailoverTestBase.ADDRESS);
@@ -2081,7 +2183,7 @@
}
session2.commit();
-
+
ClientConsumer consumer = session2.createConsumer(FailoverTestBase.ADDRESS);
session2.start();
@@ -2322,10 +2424,10 @@
for (int i = 0; i < numMessages; i++)
{
ClientMessage message = session.createMessage(HornetQTextMessage.TYPE,
- false,
- 0,
- System.currentTimeMillis(),
- (byte)1);
+ false,
+ 0,
+ System.currentTimeMillis(),
+ (byte)1);
message.putIntProperty(new SimpleString("count"), i);
message.getBodyBuffer().writeString("aardvarks");
producer.send(message);
14 years
JBoss hornetq SVN: r9144 - in trunk: src/main/org/hornetq/core/server and 3 other directories.
by do-not-reply@jboss.org
Author: clebert.suconic(a)jboss.com
Date: 2010-04-21 12:35:31 -0400 (Wed, 21 Apr 2010)
New Revision: 9144
Modified:
trunk/build-maven.xml
trunk/src/main/org/hornetq/core/server/ActivateCallback.java
trunk/src/main/org/hornetq/core/server/impl/HornetQServerImpl.java
trunk/src/main/org/hornetq/jms/server/impl/JMSServerManagerImpl.java
trunk/tests/src/org/hornetq/tests/integration/cluster/failover/AsynchronousFailoverTest.java
trunk/tests/src/org/hornetq/tests/integration/cluster/failover/FailoverTestBase.java
Log:
Changes to Asynchronous Failover Test
Modified: trunk/build-maven.xml
===================================================================
--- trunk/build-maven.xml 2010-04-21 13:10:13 UTC (rev 9143)
+++ trunk/build-maven.xml 2010-04-21 16:35:31 UTC (rev 9144)
@@ -13,7 +13,7 @@
-->
<project default="upload" name="HornetQ">
- <property name="hornetq.version" value="2.1.0.BETA2"/>
+ <property name="hornetq.version" value="2.1.0.BETA3"/>
<property name="build.dir" value="build"/>
<property name="jars.dir" value="${build.dir}/jars"/>
Modified: trunk/src/main/org/hornetq/core/server/ActivateCallback.java
===================================================================
--- trunk/src/main/org/hornetq/core/server/ActivateCallback.java 2010-04-21 13:10:13 UTC (rev 9143)
+++ trunk/src/main/org/hornetq/core/server/ActivateCallback.java 2010-04-21 16:35:31 UTC (rev 9144)
@@ -22,5 +22,7 @@
*/
public interface ActivateCallback
{
+ void preActivate();
+
void activated();
}
Modified: trunk/src/main/org/hornetq/core/server/impl/HornetQServerImpl.java
===================================================================
--- trunk/src/main/org/hornetq/core/server/impl/HornetQServerImpl.java 2010-04-21 13:10:13 UTC (rev 9143)
+++ trunk/src/main/org/hornetq/core/server/impl/HornetQServerImpl.java 2010-04-21 16:35:31 UTC (rev 9144)
@@ -860,6 +860,15 @@
}
}
+
+ private void callPreActiveCallbacks()
+ {
+ for (ActivateCallback callback : activateCallbacks)
+ {
+ callback.preActivate();
+ }
+ }
+
public synchronized boolean checkActivate() throws Exception
{
if (configuration.isBackup())
@@ -938,6 +947,8 @@
{
deploymentManager = new FileDeploymentManager(configuration.getFileDeployerScanPeriod());
}
+
+ callPreActiveCallbacks();
startReplication();
Modified: trunk/src/main/org/hornetq/jms/server/impl/JMSServerManagerImpl.java
===================================================================
--- trunk/src/main/org/hornetq/jms/server/impl/JMSServerManagerImpl.java 2010-04-21 13:10:13 UTC (rev 9143)
+++ trunk/src/main/org/hornetq/jms/server/impl/JMSServerManagerImpl.java 2010-04-21 16:35:31 UTC (rev 9144)
@@ -166,6 +166,11 @@
// ActivateCallback implementation -------------------------------------
+ public void preActivate()
+ {
+
+ }
+
public synchronized void activated()
{
active = true;
Modified: trunk/tests/src/org/hornetq/tests/integration/cluster/failover/AsynchronousFailoverTest.java
===================================================================
--- trunk/tests/src/org/hornetq/tests/integration/cluster/failover/AsynchronousFailoverTest.java 2010-04-21 13:10:13 UTC (rev 9143)
+++ trunk/tests/src/org/hornetq/tests/integration/cluster/failover/AsynchronousFailoverTest.java 2010-04-21 16:35:31 UTC (rev 9144)
@@ -21,6 +21,8 @@
import junit.framework.Assert;
import org.hornetq.api.core.HornetQException;
+import org.hornetq.api.core.Message;
+import org.hornetq.api.core.SimpleString;
import org.hornetq.api.core.TransportConfiguration;
import org.hornetq.api.core.client.ClientConsumer;
import org.hornetq.api.core.client.ClientMessage;
@@ -50,6 +52,8 @@
private volatile ClientSessionFactoryInternal sf;
+ private Object lockFail = new Object();
+
class MyListener implements SessionFailureListener
{
CountDownLatch latch = new CountDownLatch(1);
@@ -87,11 +91,22 @@
{
runTest(new TestRunner()
{
+ volatile boolean running = false;
+
public void run()
{
try
{
- doTestTransactional(this);
+ assertFalse(running);
+ running = true;
+ try
+ {
+ doTestTransactional(this);
+ }
+ finally
+ {
+ running = false;
+ }
}
catch (Throwable e)
{
@@ -107,7 +122,7 @@
volatile boolean failed;
ArrayList<Throwable> errors = new ArrayList<Throwable>();
-
+
boolean isFailed()
{
return failed;
@@ -122,30 +137,27 @@
{
failed = false;
}
-
+
synchronized void addException(Throwable e)
{
errors.add(e);
}
-
+
void checkForExceptions() throws Throwable
{
if (errors.size() > 0)
{
log.warn("Exceptions on test:");
- for (Throwable e: errors)
+ for (Throwable e : errors)
{
log.warn(e.getMessage(), e);
}
// throwing the first error that happened on the Runnable
throw errors.get(0);
}
-
-
}
-
-
+
}
private void runTest(final TestRunner runnable) throws Throwable
@@ -173,6 +185,8 @@
Thread t = new Thread(runnable);
+ t.setName("MainTEST");
+
t.start();
long randomDelay = (long)(2000 * Math.random());
@@ -186,7 +200,10 @@
MyListener listener = this.listener;
// Simulate failure on connection
- conn.fail(new HornetQException(HornetQException.NOT_CONNECTED));
+ synchronized (lockFail)
+ {
+ conn.fail(new HornetQException(HornetQException.NOT_CONNECTED));
+ }
if (listener != null)
{
@@ -200,7 +217,7 @@
AsynchronousFailoverTest.log.info("Fail complete");
t.join();
-
+
runnable.checkForExceptions();
createSession.close();
@@ -242,24 +259,24 @@
session.addFailureListener(listener);
this.listener = listener;
-
+
ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS);
final int numMessages = 1000;
for (int i = 0; i < numMessages; i++)
{
- ClientMessage message = session.createMessage(true);
-
- message.getBodyBuffer().writeString("message" + i);
-
- message.putIntProperty("counter", i);
-
boolean retry = false;
do
{
try
{
+ ClientMessage message = session.createMessage(true);
+
+ message.getBodyBuffer().writeString("message" + i);
+
+ message.putIntProperty("counter", i);
+
producer.send(message);
retry = false;
@@ -343,69 +360,59 @@
private void doTestTransactional(final TestRunner runner) throws Exception
{
+ // For duplication detection
+ int executionId = 0;
+
while (!runner.isFailed())
{
ClientSession session = null;
+ executionId++;
+
try
{
- session = sf.createSession(false, false);
MyListener listener = new MyListener();
- session.addFailureListener(listener);
-
this.listener = listener;
+ boolean retry = false;
- ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS);
-
final int numMessages = 1000;
- for (int i = 0; i < numMessages; i++)
+ session = sf.createSession(false, false);
+
+ session.addFailureListener(listener);
+
+ do
{
- ClientMessage message = session.createMessage(true);
+ try
+ {
+ ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS);
- message.getBodyBuffer().writeString("message" + i);
+ for (int i = 0; i < numMessages; i++)
+ {
+ ClientMessage message = session.createMessage(true);
- message.putIntProperty("counter", i);
+ message.getBodyBuffer().writeString("message" + i);
- boolean retry = false;
- do
- {
- try
- {
+ message.putIntProperty("counter", i);
+
+ message.putStringProperty(Message.HDR_DUPLICATE_DETECTION_ID, new SimpleString("id:" + i +
+ ",exec:" +
+ executionId));
+
producer.send(message);
}
- catch (HornetQException e)
- {
- Assert.assertEquals(e.getCode(), HornetQException.UNBLOCKED);
- retry = true;
- }
- }
- while (retry);
- }
-
- boolean retry = false;
- while (retry)
- {
- try
- {
session.commit();
retry = false;
}
catch (HornetQException e)
{
- if (e.getCode() == HornetQException.TRANSACTION_ROLLED_BACK)
+ if (e.getCode() == HornetQException.TRANSACTION_ROLLED_BACK || e.getCode() == HornetQException.UNBLOCKED)
{
// OK
- session.close();
-
- continue;
- }
- else if (e.getCode() == HornetQException.UNBLOCKED)
- {
retry = true;
}
else
@@ -414,70 +421,79 @@
}
}
}
+ while (retry);
- ClientConsumer consumer = null;
- while (true)
+
+ boolean blocked = false;
+
+ retry = false;
+
+ ClientConsumer consumer = null;
+ do
{
+ ArrayList<Integer> msgs = new ArrayList<Integer>();
try
{
- consumer = session.createConsumer(FailoverTestBase.ADDRESS);
-
- break;
- }
- catch (HornetQException e)
- {
- if (e.getCode() == HornetQException.UNBLOCKED)
+ if (consumer == null)
{
- continue;
+ consumer = session.createConsumer(FailoverTestBase.ADDRESS);
+ session.start();
}
- throw e;
- }
- }
-
- session.start();
- int lastCount = -1;
- while (true)
- {
- ClientMessage message = consumer.receive(500);
+ for (int i = 0; i < numMessages; i++)
+ {
+ ClientMessage message = consumer.receive(500);
+ if (message == null)
+ {
+ break;
+ }
- if (message == null)
- {
- break;
- }
+ int count = message.getIntProperty("counter");
- // There may be some missing or duplicate messages - but the order should be correct
+ msgs.add(count);
- int count = message.getIntProperty("counter");
+ message.acknowledge();
+ }
- Assert.assertTrue("count:" + count + " last count:" + lastCount, count >= lastCount);
+ session.commit();
+
+ if (blocked)
+ {
+ assertTrue("msgs.size is expected to be 0 or " + numMessages + " but it was " + msgs.size(), msgs.size() == 0 || msgs.size() == numMessages);
+ }
+ else
+ {
+ assertTrue("msgs.size is expected to be " + numMessages + " but it was " + msgs.size(), msgs.size() == numMessages);
+ }
- lastCount = count;
+ int i = 0;
+ for (Integer msg : msgs)
+ {
+ assertEquals(i++, (int)msg);
+ }
- message.acknowledge();
- }
-
- retry = false;
- while (retry)
- {
- try
- {
- session.commit();
-
retry = false;
+ blocked = false;
}
catch (HornetQException e)
{
if (e.getCode() == HornetQException.TRANSACTION_ROLLED_BACK)
{
- // OK
- session.close();
-
- continue;
+ // TODO: https://jira.jboss.org/jira/browse/HORNETQ-369
+ // ATM RolledBack exception is being called with the transaction is committed.
+ // the test will fail if you remove this next line
+ blocked = true;
}
else if (e.getCode() == HornetQException.UNBLOCKED)
{
+ // TODO: https://jira.jboss.org/jira/browse/HORNETQ-369
+ // This part of the test is never being called.
+ blocked = true;
+ }
+
+ if (e.getCode() == HornetQException.UNBLOCKED || e.getCode() == HornetQException.TRANSACTION_ROLLED_BACK)
+ {
retry = true;
}
else
@@ -486,6 +502,7 @@
}
}
}
+ while (retry);
}
finally
{
Modified: trunk/tests/src/org/hornetq/tests/integration/cluster/failover/FailoverTestBase.java
===================================================================
--- trunk/tests/src/org/hornetq/tests/integration/cluster/failover/FailoverTestBase.java 2010-04-21 13:10:13 UTC (rev 9143)
+++ trunk/tests/src/org/hornetq/tests/integration/cluster/failover/FailoverTestBase.java 2010-04-21 16:35:31 UTC (rev 9144)
@@ -27,6 +27,7 @@
import org.hornetq.core.remoting.impl.invm.InVMConnector;
import org.hornetq.core.remoting.impl.invm.InVMRegistry;
import org.hornetq.core.remoting.impl.invm.TransportConstants;
+import org.hornetq.core.server.ActivateCallback;
import org.hornetq.core.server.HornetQServer;
import org.hornetq.tests.util.ServiceTestBase;
@@ -98,6 +99,26 @@
config1.setSharedStore(true);
config1.setBackup(true);
server1Service = createServer(true, config1);
+
+ server1Service.registerActivateCallback(new ActivateCallback()
+ {
+
+ public void preActivate()
+ {
+ // To avoid two servers messing up with the same journal at any single point
+ try
+ {
+ server0Service.getStorageManager().stop();
+ }
+ catch (Exception ignored)
+ {
+ }
+ }
+
+ public void activated()
+ {
+ }
+ });
Configuration config0 = super.createDefaultConfig();
config0.getAcceptorConfigurations().clear();
14 years
JBoss hornetq SVN: r9143 - in trunk: src/config/common/schema and 21 other directories.
by do-not-reply@jboss.org
Author: timfox
Date: 2010-04-21 09:10:13 -0400 (Wed, 21 Apr 2010)
New Revision: 9143
Modified:
trunk/docs/user-manual/en/configuration-index.xml
trunk/docs/user-manual/en/ha.xml
trunk/src/config/common/schema/hornetq-jms.xsd
trunk/src/main/org/hornetq/api/core/client/ClientSessionFactory.java
trunk/src/main/org/hornetq/api/core/client/HornetQClient.java
trunk/src/main/org/hornetq/api/jms/management/ConnectionFactoryControl.java
trunk/src/main/org/hornetq/core/client/impl/ClientSessionFactoryImpl.java
trunk/src/main/org/hornetq/core/client/impl/FailoverManagerImpl.java
trunk/src/main/org/hornetq/core/server/impl/HornetQServerImpl.java
trunk/src/main/org/hornetq/jms/client/HornetQConnectionFactory.java
trunk/src/main/org/hornetq/jms/management/impl/JMSConnectionFactoryControlImpl.java
trunk/src/main/org/hornetq/jms/server/JMSServerManager.java
trunk/src/main/org/hornetq/jms/server/config/ConnectionFactoryConfiguration.java
trunk/src/main/org/hornetq/jms/server/config/impl/ConnectionFactoryConfigurationImpl.java
trunk/src/main/org/hornetq/jms/server/impl/JMSServerConfigParserImpl.java
trunk/src/main/org/hornetq/jms/server/impl/JMSServerManagerImpl.java
trunk/tests/config/hornetq-jms-for-JMSServerDeployerTest.xml
trunk/tests/config/hornetq-jms-for-JMSServerDeployerTest2.xml
trunk/tests/jms-tests/src/org/hornetq/jms/tests/CTSMiscellaneousTest.java
trunk/tests/jms-tests/src/org/hornetq/jms/tests/JMSTestCase.java
trunk/tests/jms-tests/src/org/hornetq/jms/tests/tools/container/LocalTestServer.java
trunk/tests/src/org/hornetq/tests/integration/client/IncompatibleVersionTest.java
trunk/tests/src/org/hornetq/tests/integration/cluster/failover/FailoverTest.java
trunk/tests/src/org/hornetq/tests/integration/jms/FloodServerTest.java
trunk/tests/src/org/hornetq/tests/integration/jms/client/PreACKJMSTest.java
trunk/tests/src/org/hornetq/tests/integration/jms/client/ReSendMessageTest.java
trunk/tests/src/org/hornetq/tests/integration/jms/client/SessionClosedOnRemotingConnectionFailureTest.java
trunk/tests/src/org/hornetq/tests/integration/jms/client/TextMessageTest.java
trunk/tests/src/org/hornetq/tests/integration/jms/divert/DivertAndACKClientTest.java
trunk/tests/src/org/hornetq/tests/integration/jms/server/JMSServerDeployerTest.java
trunk/tests/src/org/hornetq/tests/integration/replication/ReplicationTest.java
trunk/tests/src/org/hornetq/tests/util/JMSTestBase.java
Log:
https://jira.jboss.org/jira/browse/HORNETQ-285
Modified: trunk/docs/user-manual/en/configuration-index.xml
===================================================================
--- trunk/docs/user-manual/en/configuration-index.xml 2010-04-21 10:12:02 UTC (rev 9142)
+++ trunk/docs/user-manual/en/configuration-index.xml 2010-04-21 13:10:13 UTC (rev 9143)
@@ -1116,6 +1116,13 @@
</row>
<row>
<entry><link linkend="ha.automatic.failover"
+ >connection-factory.failover-on-initial-connection</link></entry>
+ <entry>Boolean</entry>
+ <entry>whether or not to failover to backup on event that initial connection to live server fails</entry>
+ <entry>false</entry>
+ </row>
+ <row>
+ <entry><link linkend="ha.automatic.failover"
>connection-factory.failover-on-server-shutdown</link></entry>
<entry>Boolean</entry>
<entry>whether or not to failover on server shutdown</entry>
Modified: trunk/docs/user-manual/en/ha.xml
===================================================================
--- trunk/docs/user-manual/en/ha.xml 2010-04-21 10:12:02 UTC (rev 9142)
+++ trunk/docs/user-manual/en/ha.xml 2010-04-21 13:10:13 UTC (rev 9143)
@@ -162,8 +162,9 @@
<programlisting>
<shared-store>true<shared-store>
</programlisting>
- <para>Additionally, the backup server must be flagged explicitly as a backup:</para>
- <programlisting>
+ <para>Additionally, the backup server must be flagged explicitly as a
+ backup:</para>
+ <programlisting>
<backup>true</backup>
</programlisting>
<para>In order for live - backup pairs to operate properly with a shared store,
@@ -235,10 +236,10 @@
To configure this you can set the property <literal
>FailoverOnServerShutdown</literal> to true either on the <literal
>HornetQConnectionFactory</literal> if you're using JMS or in the <literal
- >hornetq-jms.xml</literal> file when you define the connection factory, or if
- using core by setting the property directly on the <literal
- >ClientSessionFactoryImpl</literal> instance after creation. The default value
- for this property is <literal>false</literal>, this means that by default
+ >hornetq-jms.xml (failover-on-server-shutdown property)</literal> file when you
+ define the connection factory, or if using core by setting the property directly on
+ the <literal>ClientSessionFactoryImpl</literal> instance after creation. The default
+ value for this property is <literal>false</literal>, this means that by default
<emphasis>HornetQ clients will not failover to a backup server if the live
server is simply shutdown cleanly.</emphasis></para>
<para>
@@ -253,6 +254,18 @@
to true</para>
</note>
</para>
+ <para>By default failover will only occur after at least one connection has been made to
+ the live server. In other words, by default, failover will not occur if the client
+ fails to make an initial connection to the live server - in this case it will simply
+ retry connecting to the live server according to the reconnect-attempts property and
+ fail after this number of attempts.</para>
+ <para>In some cases, you may want the client to automatically try the backup server it
+ fails to make an initial connection to the live server. In this case you can set the
+ property <literal>FailoverOnInitialConnection</literal>, or <literal
+ >failover-on-initial-connection</literal> in xml, on the <literal
+ >ClientSessionFactoryImpl</literal> or <literal
+ >HornetQConnectionFactory</literal>. The default value for this parameter is
+ <literal>false</literal>. </para>
<para>For examples of automatic failover with transacted and non-transacted JMS
sessions, please see <xref linkend="examples.transaction-failover"/> and <xref
linkend="examples.non-transaction-failover"/>.</para>
@@ -272,10 +285,10 @@
global order to ensure a consistent replica state. This is extremely hard to do
in a performant and scalable way, especially when one considers that multiple
threads are changing the live server state concurrently.</para>
- <para>It is possible to provide full state machine replication using
- techniques such as <emphasis role="italic">virtual synchrony</emphasis>, but
- this does not scale well and effectively serializes all operations to a single
- thread, dramatically reducing concurrency.</para>
+ <para>It is possible to provide full state machine replication using techniques such
+ as <emphasis role="italic">virtual synchrony</emphasis>, but this does not scale
+ well and effectively serializes all operations to a single thread, dramatically
+ reducing concurrency.</para>
<para>Other techniques for multi-threaded active replication exist such as
replicating lock states or replicating thread scheduling but this is very hard
to achieve at a Java level.</para>
@@ -317,7 +330,8 @@
>HornetQException.TRANSACTION_ROLLED_BACK</literal> if using the core
API.</para>
<para>It is up to the user to catch the exception, and perform any client side local
- rollback code as necessary. There is no need to manually rollback the session - it is already rolled back. The user can then just retry the transactional
+ rollback code as necessary. There is no need to manually rollback the session -
+ it is already rolled back. The user can then just retry the transactional
operations again on the same session.</para>
<para>HornetQ ships with a fully functioning example demonstrating how to do this,
please see <xref linkend="examples.transaction-failover"/></para>
Modified: trunk/src/config/common/schema/hornetq-jms.xsd
===================================================================
--- trunk/src/config/common/schema/hornetq-jms.xsd 2010-04-21 10:12:02 UTC (rev 9142)
+++ trunk/src/config/common/schema/hornetq-jms.xsd 2010-04-21 13:10:13 UTC (rev 9143)
@@ -112,6 +112,9 @@
<xsd:element name="reconnect-attempts" type="xsd:int"
maxOccurs="1" minOccurs="0">
</xsd:element>
+ <xsd:element name="failover-on-initial-connection" type="xsd:boolean"
+ maxOccurs="1" minOccurs="0">
+ </xsd:element>
<xsd:element name="failover-on-server-shutdown" type="xsd:boolean"
maxOccurs="1" minOccurs="0">
</xsd:element>
Modified: trunk/src/main/org/hornetq/api/core/client/ClientSessionFactory.java
===================================================================
--- trunk/src/main/org/hornetq/api/core/client/ClientSessionFactory.java 2010-04-21 10:12:02 UTC (rev 9142)
+++ trunk/src/main/org/hornetq/api/core/client/ClientSessionFactory.java 2010-04-21 13:10:13 UTC (rev 9143)
@@ -686,6 +686,23 @@
* @param reconnectAttempts maximum number of attempts to retry connection in case of failure
*/
void setReconnectAttempts(int reconnectAttempts);
+
+ /**
+ * Returns true if the client will automatically attempt to connect to the backup server if the initial
+ * connection to the live server fails
+ *
+ * Default value is {@link HornetQClient.DEFAULT_FAILOVER_ON_INITIAL_CONNECTION}.
+ *
+ * @return
+ */
+ boolean isFailoverOnInitialConnection();
+
+ /**
+ * Sets the value for FailoverOnInitialReconnection
+ *
+ * @param failover
+ */
+ void setFailoverOnInitialConnection(boolean failover);
/**
* Returns whether connections created by this factory must failover in case the server they are
Modified: trunk/src/main/org/hornetq/api/core/client/HornetQClient.java
===================================================================
--- trunk/src/main/org/hornetq/api/core/client/HornetQClient.java 2010-04-21 10:12:02 UTC (rev 9142)
+++ trunk/src/main/org/hornetq/api/core/client/HornetQClient.java 2010-04-21 13:10:13 UTC (rev 9143)
@@ -77,6 +77,8 @@
public static final long DEFAULT_MAX_RETRY_INTERVAL = 2000;
public static final int DEFAULT_RECONNECT_ATTEMPTS = 0;
+
+ public static final boolean DEFAULT_FAILOVER_ON_INITIAL_CONNECTION = false;
public static final boolean DEFAULT_FAILOVER_ON_SERVER_SHUTDOWN = false;
Modified: trunk/src/main/org/hornetq/api/jms/management/ConnectionFactoryControl.java
===================================================================
--- trunk/src/main/org/hornetq/api/jms/management/ConnectionFactoryControl.java 2010-04-21 10:12:02 UTC (rev 9142)
+++ trunk/src/main/org/hornetq/api/jms/management/ConnectionFactoryControl.java 2010-04-21 13:10:13 UTC (rev 9143)
@@ -239,7 +239,17 @@
* @see ClientSessionFactory#setReconnectAttempts(int)
*/
void setReconnectAttempts(int reconnectAttempts);
+
+ /**
+ * @see ClientSessionFactory#isFailoverOnInitialConnection()
+ */
+ boolean isFailoverOnInitialConnection();
+ /**
+ * @see ClientSessionFactory#setFailoverOnInitialConnection(boolean)
+ */
+ void setFailoverOnInitialConnection(boolean failoverOnInitialConnection);
+
/**
* @see ClientSessionFactory#isFailoverOnServerShutdown()
*/
Modified: trunk/src/main/org/hornetq/core/client/impl/ClientSessionFactoryImpl.java
===================================================================
--- trunk/src/main/org/hornetq/core/client/impl/ClientSessionFactoryImpl.java 2010-04-21 10:12:02 UTC (rev 9142)
+++ trunk/src/main/org/hornetq/core/client/impl/ClientSessionFactoryImpl.java 2010-04-21 13:10:13 UTC (rev 9143)
@@ -141,6 +141,8 @@
private long maxRetryInterval;
private int reconnectAttempts;
+
+ private boolean failoverOnInitialConnection;
private int initialMessagePacketSize;
@@ -259,7 +261,8 @@
retryInterval,
retryIntervalMultiplier,
maxRetryInterval,
- reconnectAttempts,
+ reconnectAttempts,
+ failoverOnInitialConnection,
threadPool,
scheduledThreadPool,
interceptors);
@@ -342,6 +345,8 @@
maxRetryInterval = other.getMaxRetryInterval();
reconnectAttempts = other.getReconnectAttempts();
+
+ failoverOnInitialConnection = other.isFailoverOnInitialConnection();
failoverOnServerShutdown = other.isFailoverOnServerShutdown();
@@ -403,6 +408,8 @@
maxRetryInterval = HornetQClient.DEFAULT_MAX_RETRY_INTERVAL;
reconnectAttempts = HornetQClient.DEFAULT_RECONNECT_ATTEMPTS;
+
+ failoverOnInitialConnection = HornetQClient.DEFAULT_FAILOVER_ON_INITIAL_CONNECTION;
failoverOnServerShutdown = HornetQClient.DEFAULT_FAILOVER_ON_SERVER_SHUTDOWN;
@@ -730,7 +737,18 @@
checkWrite();
this.reconnectAttempts = reconnectAttempts;
}
+
+ public synchronized boolean isFailoverOnInitialConnection()
+ {
+ return this.failoverOnInitialConnection;
+ }
+ public synchronized void setFailoverOnInitialConnection(final boolean failover)
+ {
+ checkWrite();
+ this.failoverOnInitialConnection = failover;
+ }
+
public synchronized boolean isFailoverOnServerShutdown()
{
return failoverOnServerShutdown;
@@ -1023,7 +1041,8 @@
retryInterval,
retryIntervalMultiplier,
maxRetryInterval,
- reconnectAttempts,
+ reconnectAttempts,
+ failoverOnInitialConnection,
threadPool,
scheduledThreadPool,
interceptors);
Modified: trunk/src/main/org/hornetq/core/client/impl/FailoverManagerImpl.java
===================================================================
--- trunk/src/main/org/hornetq/core/client/impl/FailoverManagerImpl.java 2010-04-21 10:12:02 UTC (rev 9142)
+++ trunk/src/main/org/hornetq/core/client/impl/FailoverManagerImpl.java 2010-04-21 13:10:13 UTC (rev 9143)
@@ -75,7 +75,7 @@
private static final long serialVersionUID = 2512460695662741413L;
private static final Logger log = Logger.getLogger(FailoverManagerImpl.class);
-
+
// debug
private static Map<TransportConfiguration, Set<CoreRemotingConnection>> debugConns;
@@ -199,7 +199,11 @@
private volatile boolean exitLoop;
private final List<Interceptor> interceptors;
-
+
+ private volatile boolean stopPingingAfterOne;
+
+ private final boolean failoverOnInitialConnection;
+
// Static
// ---------------------------------------------------------------------------------------
@@ -217,6 +221,7 @@
final double retryIntervalMultiplier,
final long maxRetryInterval,
final int reconnectAttempts,
+ final boolean failoverOnInitialConnection,
final ExecutorService threadPool,
final ScheduledExecutorService scheduledThreadPool,
final List<Interceptor> interceptors)
@@ -260,6 +265,8 @@
this.reconnectAttempts = reconnectAttempts;
+ this.failoverOnInitialConnection = failoverOnInitialConnection;
+
this.scheduledThreadPool = scheduledThreadPool;
this.threadPool = threadPool;
@@ -339,9 +346,33 @@
return null;
}
- throw new HornetQException(HornetQException.NOT_CONNECTED,
- "Unable to connect to server using configuration " + connectorConfig);
+ if (failoverOnInitialConnection && backupConnectorFactory != null)
+ {
+ // Try and connect to the backup
+ log.warn("Server is not available to make initial connection to. Will " + "try backup server instead.");
+
+ connectorFactory = backupConnectorFactory;
+
+ transportParams = backupTransportParams;
+
+ backupConnectorFactory = null;
+
+ backupTransportParams = null;
+
+ theConnection = getConnectionWithRetry(reconnectAttempts);
+ }
+
+ if (exitLoop)
+ {
+ return null;
+ }
+
+ if (theConnection == null)
+ {
+ throw new HornetQException(HornetQException.NOT_CONNECTED,
+ "Unable to connect to server using configuration " + connectorConfig);
+ }
}
channel1 = theConnection.getChannel(1, -1);
@@ -441,7 +472,6 @@
}
catch (Throwable t)
{
- t.printStackTrace();
if (lock != null)
{
lock.unlock();
@@ -530,8 +560,6 @@
// Public
// ---------------------------------------------------------------------------------------
- private volatile boolean stopPingingAfterOne;
-
public void stopPingingAfterOne()
{
stopPingingAfterOne = true;
@@ -1136,46 +1164,6 @@
}
- private static final class ActualScheduledBatchFlusher implements Runnable
- {
- private final WeakReference<BatchFlushRunnable> batchFlushRunnable;
-
- ActualScheduledBatchFlusher(final BatchFlushRunnable runnable)
- {
- batchFlushRunnable = new WeakReference<BatchFlushRunnable>(runnable);
- }
-
- public void run()
- {
- BatchFlushRunnable runnable = batchFlushRunnable.get();
-
- if (runnable != null)
- {
- runnable.run();
- }
- }
-
- }
-
- private final class BatchFlushRunnable implements Runnable
- {
- private boolean cancelled;
-
- public synchronized void run()
- {
- if (cancelled)
- {
- return;
- }
- connection.getTransportConnection().checkFlushBatchBuffer();
- }
-
- public synchronized void cancel()
- {
- cancelled = true;
- }
- }
-
private final class PingRunnable implements Runnable
{
private boolean cancelled;
Modified: trunk/src/main/org/hornetq/core/server/impl/HornetQServerImpl.java
===================================================================
--- trunk/src/main/org/hornetq/core/server/impl/HornetQServerImpl.java 2010-04-21 10:12:02 UTC (rev 9142)
+++ trunk/src/main/org/hornetq/core/server/impl/HornetQServerImpl.java 2010-04-21 13:10:13 UTC (rev 9143)
@@ -790,7 +790,8 @@
0,
1.0d,
0,
- 1,
+ 1,
+ false,
threadPool,
scheduledPool,
null);
Modified: trunk/src/main/org/hornetq/jms/client/HornetQConnectionFactory.java
===================================================================
--- trunk/src/main/org/hornetq/jms/client/HornetQConnectionFactory.java 2010-04-21 10:12:02 UTC (rev 9142)
+++ trunk/src/main/org/hornetq/jms/client/HornetQConnectionFactory.java 2010-04-21 13:10:13 UTC (rev 9143)
@@ -509,7 +509,18 @@
checkWrite();
sessionFactory.setReconnectAttempts(reconnectAttempts);
}
+
+ public synchronized boolean isFailoverOnInitialConnection()
+ {
+ return sessionFactory.isFailoverOnInitialConnection();
+ }
+ public synchronized void setFailoverOnInitialConnection(final boolean failover)
+ {
+ checkWrite();
+ sessionFactory.setFailoverOnInitialConnection(failover);
+ }
+
public synchronized boolean isFailoverOnServerShutdown()
{
return sessionFactory.isFailoverOnServerShutdown();
Modified: trunk/src/main/org/hornetq/jms/management/impl/JMSConnectionFactoryControlImpl.java
===================================================================
--- trunk/src/main/org/hornetq/jms/management/impl/JMSConnectionFactoryControlImpl.java 2010-04-21 10:12:02 UTC (rev 9142)
+++ trunk/src/main/org/hornetq/jms/management/impl/JMSConnectionFactoryControlImpl.java 2010-04-21 13:10:13 UTC (rev 9143)
@@ -217,6 +217,11 @@
{
cf.setReconnectAttempts(reconnectAttempts);
}
+
+ public void setFailoverOnInitialConnection(boolean failover)
+ {
+ cf.setFailoverOnInitialConnection(failover);
+ }
public void setFailoverOnServerShutdown(boolean failoverOnServerShutdown)
{
@@ -397,6 +402,11 @@
{
return cf.getReconnectAttempts();
}
+
+ public boolean isFailoverOnInitialConnection()
+ {
+ return cf.isFailoverOnInitialConnection();
+ }
public boolean isFailoverOnServerShutdown()
{
Modified: trunk/src/main/org/hornetq/jms/server/JMSServerManager.java
===================================================================
--- trunk/src/main/org/hornetq/jms/server/JMSServerManager.java 2010-04-21 10:12:02 UTC (rev 9142)
+++ trunk/src/main/org/hornetq/jms/server/JMSServerManager.java 2010-04-21 13:10:13 UTC (rev 9143)
@@ -218,6 +218,7 @@
double retryIntervalMultiplier,
long maxRetryInterval,
int reconnectAttempts,
+ boolean failoverOnInitialConnection,
boolean failoverOnServerShutdown,
String groupId,
String ... jndiBindings) throws Exception;
@@ -254,6 +255,7 @@
double retryIntervalMultiplier,
long maxRetryInterval,
int reconnectAttempts,
+ boolean failoverOnInitialConnection,
boolean failoverOnServerShutdown,
String groupId,
String ... jndiBindings) throws Exception;
Modified: trunk/src/main/org/hornetq/jms/server/config/ConnectionFactoryConfiguration.java
===================================================================
--- trunk/src/main/org/hornetq/jms/server/config/ConnectionFactoryConfiguration.java 2010-04-21 10:12:02 UTC (rev 9142)
+++ trunk/src/main/org/hornetq/jms/server/config/ConnectionFactoryConfiguration.java 2010-04-21 13:10:13 UTC (rev 9143)
@@ -194,7 +194,11 @@
boolean isFailoverOnServerShutdown();
void setFailoverOnServerShutdown(boolean failoverOnServerShutdown);
+
+ boolean isFailoverOnInitialConnection();
+ void setFailoverOnInitialConnection(boolean failover);
+
String getGroupID();
void setGroupID(String groupID);
Modified: trunk/src/main/org/hornetq/jms/server/config/impl/ConnectionFactoryConfigurationImpl.java
===================================================================
--- trunk/src/main/org/hornetq/jms/server/config/impl/ConnectionFactoryConfigurationImpl.java 2010-04-21 10:12:02 UTC (rev 9142)
+++ trunk/src/main/org/hornetq/jms/server/config/impl/ConnectionFactoryConfigurationImpl.java 2010-04-21 13:10:13 UTC (rev 9143)
@@ -109,8 +109,10 @@
private int reconnectAttempts = HornetQClient.DEFAULT_RECONNECT_ATTEMPTS;
+ private boolean failoverOnInitialConnection = HornetQClient.DEFAULT_FAILOVER_ON_INITIAL_CONNECTION;
+
private boolean failoverOnServerShutdown = HornetQClient.DEFAULT_FAILOVER_ON_SERVER_SHUTDOWN;
-
+
private String groupID = null;
// Static --------------------------------------------------------
@@ -513,7 +515,17 @@
{
this.reconnectAttempts = reconnectAttempts;
}
+
+ public boolean isFailoverOnInitialConnection()
+ {
+ return failoverOnInitialConnection;
+ }
+ public void setFailoverOnInitialConnection(final boolean failover)
+ {
+ this.failoverOnInitialConnection = failover;
+ }
+
public boolean isFailoverOnServerShutdown()
{
return failoverOnServerShutdown;
@@ -653,6 +665,8 @@
maxRetryInterval = buffer.readLong();
reconnectAttempts = buffer.readInt();
+
+ failoverOnInitialConnection = buffer.readBoolean();
failoverOnServerShutdown = buffer.readBoolean();
@@ -742,6 +756,8 @@
buffer.writeLong(maxRetryInterval);
buffer.writeInt(reconnectAttempts);
+
+ buffer.writeBoolean(failoverOnInitialConnection);
buffer.writeBoolean(failoverOnServerShutdown);
@@ -839,6 +855,8 @@
DataConstants.SIZE_LONG + // maxRetryInterval
DataConstants.SIZE_INT + // reconnectAttempts
+
+ DataConstants.SIZE_BOOLEAN + // failoverOnInitialConnection
DataConstants.SIZE_BOOLEAN + // failoverOnServerShutdown
Modified: trunk/src/main/org/hornetq/jms/server/impl/JMSServerConfigParserImpl.java
===================================================================
--- trunk/src/main/org/hornetq/jms/server/impl/JMSServerConfigParserImpl.java 2010-04-21 10:12:02 UTC (rev 9142)
+++ trunk/src/main/org/hornetq/jms/server/impl/JMSServerConfigParserImpl.java 2010-04-21 13:10:13 UTC (rev 9143)
@@ -283,6 +283,10 @@
"reconnect-attempts",
HornetQClient.DEFAULT_RECONNECT_ATTEMPTS,
Validators.MINUS_ONE_OR_GE_ZERO);
+ boolean failoverOnInitialConnection = XMLConfigurationUtil.getBoolean(e,
+ "failover-on-initial-connection",
+ HornetQClient.DEFAULT_FAILOVER_ON_INITIAL_CONNECTION);
+
boolean failoverOnServerShutdown = XMLConfigurationUtil.getBoolean(e,
"failover-on-server-shutdown",
HornetQClient.DEFAULT_FAILOVER_ON_SERVER_SHUTDOWN);
@@ -404,6 +408,7 @@
cfConfig.setMaxRetryInterval(maxRetryInterval);
cfConfig.setReconnectAttempts(reconnectAttempts);
cfConfig.setFailoverOnServerShutdown(failoverOnServerShutdown);
+ cfConfig.setFailoverOnInitialConnection(failoverOnInitialConnection);
cfConfig.setGroupID(groupid);
return cfConfig;
}
Modified: trunk/src/main/org/hornetq/jms/server/impl/JMSServerManagerImpl.java
===================================================================
--- trunk/src/main/org/hornetq/jms/server/impl/JMSServerManagerImpl.java 2010-04-21 10:12:02 UTC (rev 9142)
+++ trunk/src/main/org/hornetq/jms/server/impl/JMSServerManagerImpl.java 2010-04-21 13:10:13 UTC (rev 9143)
@@ -724,6 +724,7 @@
final double retryIntervalMultiplier,
final long maxRetryInterval,
final int reconnectAttempts,
+ final boolean failoverOnInitialConnection,
final boolean failoverOnServerShutdown,
final String groupId,
String... jndiBindings) throws Exception
@@ -759,6 +760,7 @@
configuration.setRetryIntervalMultiplier(retryIntervalMultiplier);
configuration.setMaxRetryInterval(maxRetryInterval);
configuration.setReconnectAttempts(reconnectAttempts);
+ configuration.setFailoverOnInitialConnection(failoverOnInitialConnection);
configuration.setFailoverOnServerShutdown(failoverOnServerShutdown);
configuration.setGroupID(groupId);
createConnectionFactory(true, configuration, jndiBindings);
@@ -797,6 +799,7 @@
final double retryIntervalMultiplier,
final long maxRetryInterval,
final int reconnectAttempts,
+ final boolean failoverOnInitialConnection,
final boolean failoverOnServerShutdown,
final String groupId,
final String... jndiBindings) throws Exception
@@ -837,6 +840,7 @@
configuration.setRetryIntervalMultiplier(retryIntervalMultiplier);
configuration.setMaxRetryInterval(maxRetryInterval);
configuration.setReconnectAttempts(reconnectAttempts);
+ configuration.setFailoverOnInitialConnection(failoverOnInitialConnection);
configuration.setFailoverOnServerShutdown(failoverOnServerShutdown);
createConnectionFactory(true, configuration, jndiBindings);
}
@@ -935,6 +939,7 @@
final double retryIntervalMultiplier,
final long maxRetryInterval,
final int reconnectAttempts,
+ final boolean failoverOnInitialConnection,
final boolean failoverOnServerShutdown,
final String groupId) throws Exception
{
@@ -972,6 +977,7 @@
cf.setRetryIntervalMultiplier(retryIntervalMultiplier);
cf.setMaxRetryInterval(maxRetryInterval);
cf.setReconnectAttempts(reconnectAttempts);
+ cf.setFailoverOnInitialConnection(failoverOnInitialConnection);
cf.setFailoverOnServerShutdown(failoverOnServerShutdown);
}
@@ -1006,6 +1012,7 @@
final double retryIntervalMultiplier,
final long maxRetryInterval,
final int reconnectAttempts,
+ final boolean failoverOnInitialConnection,
final boolean failoverOnServerShutdown,
final String groupId) throws Exception
{
@@ -1040,6 +1047,7 @@
cf.setRetryIntervalMultiplier(retryIntervalMultiplier);
cf.setMaxRetryInterval(maxRetryInterval);
cf.setReconnectAttempts(reconnectAttempts);
+ cf.setFailoverOnInitialConnection(failoverOnInitialConnection);
cf.setFailoverOnServerShutdown(failoverOnServerShutdown);
cf.setGroupID(groupId);
}
@@ -1175,6 +1183,7 @@
cfConfig.getRetryIntervalMultiplier(),
cfConfig.getMaxRetryInterval(),
cfConfig.getReconnectAttempts(),
+ cfConfig.isFailoverOnInitialConnection(),
cfConfig.isFailoverOnServerShutdown(),
cfConfig.getGroupID());
}
@@ -1208,6 +1217,7 @@
cfConfig.getRetryIntervalMultiplier(),
cfConfig.getMaxRetryInterval(),
cfConfig.getReconnectAttempts(),
+ cfConfig.isFailoverOnInitialConnection(),
cfConfig.isFailoverOnServerShutdown(),
cfConfig.getGroupID());
}
Modified: trunk/tests/config/hornetq-jms-for-JMSServerDeployerTest.xml
===================================================================
--- trunk/tests/config/hornetq-jms-for-JMSServerDeployerTest.xml 2010-04-21 10:12:02 UTC (rev 9142)
+++ trunk/tests/config/hornetq-jms-for-JMSServerDeployerTest.xml 2010-04-21 13:10:13 UTC (rev 9143)
@@ -30,6 +30,7 @@
<pre-acknowledge>true</pre-acknowledge>
<connection-ttl>2345</connection-ttl>
<discovery-initial-wait-timeout>678</discovery-initial-wait-timeout>
+ <failover-on-initial-connection>true</failover-on-initial-connection>
<failover-on-server-shutdown>false</failover-on-server-shutdown>
<connection-load-balancing-policy-class-name>FooClass</connection-load-balancing-policy-class-name>
<reconnect-attempts>34</reconnect-attempts>
Modified: trunk/tests/config/hornetq-jms-for-JMSServerDeployerTest2.xml
===================================================================
--- trunk/tests/config/hornetq-jms-for-JMSServerDeployerTest2.xml 2010-04-21 10:12:02 UTC (rev 9142)
+++ trunk/tests/config/hornetq-jms-for-JMSServerDeployerTest2.xml 2010-04-21 13:10:13 UTC (rev 9143)
@@ -31,6 +31,7 @@
<pre-acknowledge>true</pre-acknowledge>
<connection-ttl>2345</connection-ttl>
<discovery-initial-wait-timeout>678</discovery-initial-wait-timeout>
+ <failover-on-initial-connection>true</failover-on-initial-connection>
<failover-on-server-shutdown>false</failover-on-server-shutdown>
<connection-load-balancing-policy-class-name>FooClass</connection-load-balancing-policy-class-name>
<reconnect-attempts>34</reconnect-attempts>
Modified: trunk/tests/jms-tests/src/org/hornetq/jms/tests/CTSMiscellaneousTest.java
===================================================================
--- trunk/tests/jms-tests/src/org/hornetq/jms/tests/CTSMiscellaneousTest.java 2010-04-21 10:12:02 UTC (rev 9142)
+++ trunk/tests/jms-tests/src/org/hornetq/jms/tests/CTSMiscellaneousTest.java 2010-04-21 13:10:13 UTC (rev 9143)
@@ -92,6 +92,7 @@
HornetQClient.DEFAULT_RETRY_INTERVAL_MULTIPLIER,
HornetQClient.DEFAULT_MAX_RETRY_INTERVAL,
HornetQClient.DEFAULT_RECONNECT_ATTEMPTS,
+ HornetQClient.DEFAULT_FAILOVER_ON_INITIAL_CONNECTION,
HornetQClient.DEFAULT_FAILOVER_ON_SERVER_SHUTDOWN,
null,
"/StrictTCKConnectionFactory");
Modified: trunk/tests/jms-tests/src/org/hornetq/jms/tests/JMSTestCase.java
===================================================================
--- trunk/tests/jms-tests/src/org/hornetq/jms/tests/JMSTestCase.java 2010-04-21 10:12:02 UTC (rev 9142)
+++ trunk/tests/jms-tests/src/org/hornetq/jms/tests/JMSTestCase.java 2010-04-21 13:10:13 UTC (rev 9143)
@@ -88,6 +88,7 @@
HornetQClient.DEFAULT_RETRY_INTERVAL_MULTIPLIER,
HornetQClient.DEFAULT_MAX_RETRY_INTERVAL,
HornetQClient.DEFAULT_RECONNECT_ATTEMPTS,
+ HornetQClient.DEFAULT_FAILOVER_ON_INITIAL_CONNECTION,
HornetQClient.DEFAULT_FAILOVER_ON_SERVER_SHUTDOWN,
null,
"/testsuitecf");
Modified: trunk/tests/jms-tests/src/org/hornetq/jms/tests/tools/container/LocalTestServer.java
===================================================================
--- trunk/tests/jms-tests/src/org/hornetq/jms/tests/tools/container/LocalTestServer.java 2010-04-21 10:12:02 UTC (rev 9142)
+++ trunk/tests/jms-tests/src/org/hornetq/jms/tests/tools/container/LocalTestServer.java 2010-04-21 13:10:13 UTC (rev 9143)
@@ -318,6 +318,7 @@
HornetQClient.DEFAULT_RETRY_INTERVAL_MULTIPLIER,
HornetQClient.DEFAULT_MAX_RETRY_INTERVAL,
HornetQClient.DEFAULT_RECONNECT_ATTEMPTS,
+ HornetQClient.DEFAULT_FAILOVER_ON_INITIAL_CONNECTION,
HornetQClient.DEFAULT_FAILOVER_ON_SERVER_SHUTDOWN,
null,
jndiBindings);
Modified: trunk/tests/src/org/hornetq/tests/integration/client/IncompatibleVersionTest.java
===================================================================
--- trunk/tests/src/org/hornetq/tests/integration/client/IncompatibleVersionTest.java 2010-04-21 10:12:02 UTC (rev 9142)
+++ trunk/tests/src/org/hornetq/tests/integration/client/IncompatibleVersionTest.java 2010-04-21 13:10:13 UTC (rev 9143)
@@ -81,6 +81,7 @@
HornetQClient.DEFAULT_RETRY_INTERVAL_MULTIPLIER,
HornetQClient.DEFAULT_MAX_RETRY_INTERVAL,
HornetQClient.DEFAULT_RECONNECT_ATTEMPTS,
+ HornetQClient.DEFAULT_FAILOVER_ON_INITIAL_CONNECTION,
executorService,
scheduledexecutorService,
null);
Modified: trunk/tests/src/org/hornetq/tests/integration/cluster/failover/FailoverTest.java
===================================================================
--- trunk/tests/src/org/hornetq/tests/integration/cluster/failover/FailoverTest.java 2010-04-21 10:12:02 UTC (rev 9142)
+++ trunk/tests/src/org/hornetq/tests/integration/cluster/failover/FailoverTest.java 2010-04-21 13:10:13 UTC (rev 9143)
@@ -45,19 +45,6 @@
*
* A FailoverTest
*
- * Tests:
- *
- * Failover via shared storage manager:
- *
- *
- * 5) Failover due to failure on create session
- *
- * 6) Replicate above tests on JMS API
- *
- * 7) Repeat above tests using replicated journal
- *
- * 8) Test with different values of auto commit acks and autocomit sends
- *
* @author <a href="mailto:tim.fox@jboss.com">Tim Fox</a>
*
*/
@@ -231,7 +218,63 @@
Assert.assertEquals(0, sf.numConnections());
}
+
+ // https://jira.jboss.org/jira/browse/HORNETQ-285
+ public void testFailoverOnInitialConnection() throws Exception
+ {
+ ClientSessionFactoryInternal sf = getSessionFactory();
+ sf.setBlockOnNonDurableSend(true);
+ sf.setBlockOnDurableSend(true);
+ sf.setFailoverOnInitialConnection(true);
+
+ // Stop live server
+
+ this.server0Service.stop();
+
+ ClientSession session = sf.createSession();
+
+ session.createQueue(FailoverTestBase.ADDRESS, FailoverTestBase.ADDRESS, null, true);
+
+ ClientProducer producer = session.createProducer(FailoverTestBase.ADDRESS);
+
+ final int numMessages = 100;
+
+ for (int i = 0; i < numMessages; i++)
+ {
+ ClientMessage message = session.createMessage(true);
+
+ setBody(i, message);
+
+ message.putIntProperty("counter", i);
+
+ producer.send(message);
+ }
+
+ ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS);
+
+ session.start();
+
+ for (int i = 0; i < numMessages; i++)
+ {
+ ClientMessage message = consumer.receive(1000);
+
+ Assert.assertNotNull(message);
+
+ assertMessageBody(i, message);
+
+ Assert.assertEquals(i, message.getIntProperty("counter").intValue());
+
+ message.acknowledge();
+ }
+
+ session.close();
+
+ Assert.assertEquals(0, sf.numSessions());
+
+ Assert.assertEquals(0, sf.numConnections());
+ }
+
/**
* @param session
* @param latch
Modified: trunk/tests/src/org/hornetq/tests/integration/jms/FloodServerTest.java
===================================================================
--- trunk/tests/src/org/hornetq/tests/integration/jms/FloodServerTest.java 2010-04-21 10:12:02 UTC (rev 9142)
+++ trunk/tests/src/org/hornetq/tests/integration/jms/FloodServerTest.java 2010-04-21 13:10:13 UTC (rev 9143)
@@ -156,6 +156,7 @@
retryIntervalMultiplier,
1000,
reconnectAttempts,
+ HornetQClient.DEFAULT_FAILOVER_ON_INITIAL_CONNECTION,
failoverOnServerShutdown,
null,
"/cf");
Modified: trunk/tests/src/org/hornetq/tests/integration/jms/client/PreACKJMSTest.java
===================================================================
--- trunk/tests/src/org/hornetq/tests/integration/jms/client/PreACKJMSTest.java 2010-04-21 10:12:02 UTC (rev 9142)
+++ trunk/tests/src/org/hornetq/tests/integration/jms/client/PreACKJMSTest.java 2010-04-21 13:10:13 UTC (rev 9143)
@@ -226,6 +226,7 @@
retryIntervalMultiplier,
HornetQClient.DEFAULT_MAX_RETRY_INTERVAL,
reconnectAttempts,
+ HornetQClient.DEFAULT_FAILOVER_ON_INITIAL_CONNECTION,
failoverOnServerShutdown,
null,
jndiBindings);
Modified: trunk/tests/src/org/hornetq/tests/integration/jms/client/ReSendMessageTest.java
===================================================================
--- trunk/tests/src/org/hornetq/tests/integration/jms/client/ReSendMessageTest.java 2010-04-21 10:12:02 UTC (rev 9142)
+++ trunk/tests/src/org/hornetq/tests/integration/jms/client/ReSendMessageTest.java 2010-04-21 13:10:13 UTC (rev 9143)
@@ -325,6 +325,7 @@
retryIntervalMultiplier,
HornetQClient.DEFAULT_MAX_RETRY_INTERVAL,
reconnectAttempts,
+ HornetQClient.DEFAULT_FAILOVER_ON_INITIAL_CONNECTION,
failoverOnServerShutdown,
null,
jndiBindings);
Modified: trunk/tests/src/org/hornetq/tests/integration/jms/client/SessionClosedOnRemotingConnectionFailureTest.java
===================================================================
--- trunk/tests/src/org/hornetq/tests/integration/jms/client/SessionClosedOnRemotingConnectionFailureTest.java 2010-04-21 10:12:02 UTC (rev 9142)
+++ trunk/tests/src/org/hornetq/tests/integration/jms/client/SessionClosedOnRemotingConnectionFailureTest.java 2010-04-21 13:10:13 UTC (rev 9143)
@@ -94,6 +94,7 @@
HornetQClient.DEFAULT_RETRY_INTERVAL_MULTIPLIER,
HornetQClient.DEFAULT_MAX_RETRY_INTERVAL,
0,
+ HornetQClient.DEFAULT_FAILOVER_ON_INITIAL_CONNECTION,
false,
null,
"/cffoo");
Modified: trunk/tests/src/org/hornetq/tests/integration/jms/client/TextMessageTest.java
===================================================================
--- trunk/tests/src/org/hornetq/tests/integration/jms/client/TextMessageTest.java 2010-04-21 10:12:02 UTC (rev 9142)
+++ trunk/tests/src/org/hornetq/tests/integration/jms/client/TextMessageTest.java 2010-04-21 13:10:13 UTC (rev 9143)
@@ -261,6 +261,7 @@
retryIntervalMultiplier,
HornetQClient.DEFAULT_MAX_RETRY_INTERVAL,
reconnectAttempts,
+ HornetQClient.DEFAULT_FAILOVER_ON_INITIAL_CONNECTION,
failoverOnServerShutdown,
null,
jndiBindings);
Modified: trunk/tests/src/org/hornetq/tests/integration/jms/divert/DivertAndACKClientTest.java
===================================================================
--- trunk/tests/src/org/hornetq/tests/integration/jms/divert/DivertAndACKClientTest.java 2010-04-21 10:12:02 UTC (rev 9142)
+++ trunk/tests/src/org/hornetq/tests/integration/jms/divert/DivertAndACKClientTest.java 2010-04-21 13:10:13 UTC (rev 9143)
@@ -172,6 +172,7 @@
retryIntervalMultiplier,
HornetQClient.DEFAULT_MAX_RETRY_INTERVAL,
reconnectAttempts,
+ HornetQClient.DEFAULT_FAILOVER_ON_INITIAL_CONNECTION,
failoverOnServerShutdown,
null,
jndiBindings);
Modified: trunk/tests/src/org/hornetq/tests/integration/jms/server/JMSServerDeployerTest.java
===================================================================
--- trunk/tests/src/org/hornetq/tests/integration/jms/server/JMSServerDeployerTest.java 2010-04-21 10:12:02 UTC (rev 9142)
+++ trunk/tests/src/org/hornetq/tests/integration/jms/server/JMSServerDeployerTest.java 2010-04-21 13:10:13 UTC (rev 9143)
@@ -220,6 +220,7 @@
Assert.assertEquals(true, cf.isPreAcknowledge());
Assert.assertEquals(2345, cf.getConnectionTTL());
Assert.assertEquals(false, cf.isFailoverOnServerShutdown());
+ assertEquals(true, cf.isFailoverOnInitialConnection());
Assert.assertEquals(34, cf.getReconnectAttempts());
Assert.assertEquals(5, cf.getRetryInterval());
Assert.assertEquals(6.0, cf.getRetryIntervalMultiplier());
@@ -304,6 +305,7 @@
Assert.assertEquals(false, cf.isAutoGroup());
Assert.assertEquals(true, cf.isPreAcknowledge());
Assert.assertEquals(2345, cf.getConnectionTTL());
+ assertEquals(true, cf.isFailoverOnInitialConnection());
Assert.assertEquals(false, cf.isFailoverOnServerShutdown());
Assert.assertEquals(34, cf.getReconnectAttempts());
Assert.assertEquals(5, cf.getRetryInterval());
Modified: trunk/tests/src/org/hornetq/tests/integration/replication/ReplicationTest.java
===================================================================
--- trunk/tests/src/org/hornetq/tests/integration/replication/ReplicationTest.java 2010-04-21 10:12:02 UTC (rev 9142)
+++ trunk/tests/src/org/hornetq/tests/integration/replication/ReplicationTest.java 2010-04-21 13:10:13 UTC (rev 9143)
@@ -724,6 +724,7 @@
1.0d,
0,
1,
+ HornetQClient.DEFAULT_FAILOVER_ON_INITIAL_CONNECTION,
executor,
scheduledExecutor,
interceptors);
Modified: trunk/tests/src/org/hornetq/tests/util/JMSTestBase.java
===================================================================
--- trunk/tests/src/org/hornetq/tests/util/JMSTestBase.java 2010-04-21 10:12:02 UTC (rev 9142)
+++ trunk/tests/src/org/hornetq/tests/util/JMSTestBase.java 2010-04-21 13:10:13 UTC (rev 9143)
@@ -210,6 +210,7 @@
retryIntervalMultiplier,
HornetQClient.DEFAULT_MAX_RETRY_INTERVAL,
reconnectAttempts,
+ HornetQClient.DEFAULT_FAILOVER_ON_INITIAL_CONNECTION,
failoverOnServerShutdown,
null,
jndiBindings);
14 years
JBoss hornetq SVN: r9142 - in trunk: src/main/org/hornetq/core/deployers/impl and 1 other directories.
by do-not-reply@jboss.org
Author: timfox
Date: 2010-04-21 06:12:02 -0400 (Wed, 21 Apr 2010)
New Revision: 9142
Modified:
trunk/docs/user-manual/en/ha.xml
trunk/src/main/org/hornetq/core/deployers/impl/FileConfigurationParser.java
trunk/src/main/org/hornetq/core/persistence/impl/journal/JournalStorageManager.java
Log:
https://jira.jboss.org/jira/browse/HORNETQ-295 and a small tweak to docs
Modified: trunk/docs/user-manual/en/ha.xml
===================================================================
--- trunk/docs/user-manual/en/ha.xml 2010-04-21 08:14:01 UTC (rev 9141)
+++ trunk/docs/user-manual/en/ha.xml 2010-04-21 10:12:02 UTC (rev 9142)
@@ -317,7 +317,7 @@
>HornetQException.TRANSACTION_ROLLED_BACK</literal> if using the core
API.</para>
<para>It is up to the user to catch the exception, and perform any client side local
- rollback code as necessary. The user can then just retry the transactional
+ rollback code as necessary. There is no need to manually rollback the session - it is already rolled back. The user can then just retry the transactional
operations again on the same session.</para>
<para>HornetQ ships with a fully functioning example demonstrating how to do this,
please see <xref linkend="examples.transaction-failover"/></para>
Modified: trunk/src/main/org/hornetq/core/deployers/impl/FileConfigurationParser.java
===================================================================
--- trunk/src/main/org/hornetq/core/deployers/impl/FileConfigurationParser.java 2010-04-21 08:14:01 UTC (rev 9141)
+++ trunk/src/main/org/hornetq/core/deployers/impl/FileConfigurationParser.java 2010-04-21 10:12:02 UTC (rev 9142)
@@ -37,7 +37,9 @@
import org.hornetq.core.config.impl.ConfigurationImpl;
import org.hornetq.core.config.impl.FileConfiguration;
import org.hornetq.core.config.impl.Validators;
+import org.hornetq.core.journal.impl.AIOSequentialFileFactory;
import org.hornetq.core.logging.Logger;
+import org.hornetq.core.persistence.impl.journal.JournalStorageManager;
import org.hornetq.core.security.Role;
import org.hornetq.core.server.JournalType;
import org.hornetq.core.server.group.impl.GroupingHandlerConfiguration;
@@ -53,6 +55,8 @@
/**
* This class will parse the XML associated with the File Configuration XSD
*
+ * @author <a href="ataylor(a)redhat.com">Andy Taylor</a>
+ * @author <a href="tim.fox(a)jboss.com">Tim Fox</a>
* @author <mailto:clebert.suconic@jboss.org">Clebert Suconic</a>
*
*
@@ -125,22 +129,22 @@
// Constructors --------------------------------------------------
// Public --------------------------------------------------------
-
+
public Configuration parseMainConfig(final InputStream input) throws Exception
{
-
+
Reader reader = new InputStreamReader(input);
String xml = org.hornetq.utils.XMLUtil.readerToString(reader);
xml = XMLUtil.replaceSystemProps(xml);
Element e = org.hornetq.utils.XMLUtil.stringToElement(xml);
-
+
Configuration config = new ConfigurationImpl();
-
+
parseMainConfig(e, config);
-
+
return config;
}
-
+
public void parseMainConfig(final Element e, final Configuration config) throws Exception
{
XMLUtil.validate(e, FileConfigurationParser.CONFIGURATION_SCHEMA_URL);
@@ -415,7 +419,22 @@
}
else if (s.equals(JournalType.ASYNCIO.toString()))
{
- config.setJournalType(JournalType.ASYNCIO);
+ // https://jira.jboss.org/jira/browse/HORNETQ-295
+ // We do the check here to see if AIO is supported so we can use the correct defaults and/or use
+ // correct settings in xml
+ // If we fall back later on these settings can be ignored
+ boolean supportsAIO = AIOSequentialFileFactory.isSupported();
+
+ if (supportsAIO)
+ {
+ config.setJournalType(JournalType.ASYNCIO);
+ }
+ else
+ {
+ log.warn("AIO wasn't located on this platform, it will fall back to using pure Java NIO. If your platform is Linux, install LibAIO to enable the AIO journal");
+
+ config.setJournalType(JournalType.NIO);
+ }
}
config.setJournalSyncTransactional(XMLConfigurationUtil.getBoolean(e,
@@ -430,7 +449,7 @@
"journal-file-size",
config.getJournalFileSize(),
Validators.GT_ZERO));
-
+
int journalBufferTimeout = XMLConfigurationUtil.getInteger(e,
"journal-buffer-timeout",
config.getJournalType() == JournalType.ASYNCIO ? ConfigurationImpl.DEFAULT_JOURNAL_BUFFER_TIMEOUT_AIO
@@ -461,7 +480,7 @@
config.setJournalBufferSize_NIO(journalBufferSize);
config.setJournalMaxIO_NIO(journalMaxIO);
}
-
+
config.setJournalMinFiles(XMLConfigurationUtil.getInteger(e,
"journal-min-files",
config.getJournalMinFiles(),
@@ -521,15 +540,13 @@
"memory-measure-interval",
config.getMemoryMeasureInterval(),
Validators.MINUS_ONE_OR_GT_ZERO)); // in
-
+
parseAddressSettings(e, config);
-
+
parseQueues(e, config);
-
+
parseSecurity(e, config);
-
-
}
/**
@@ -539,12 +556,12 @@
private void parseSecurity(final Element e, final Configuration config)
{
NodeList elements = e.getElementsByTagName("security-settings");
-
+
if (elements.getLength() != 0)
{
Element node = (Element)elements.item(0);
NodeList list = node.getElementsByTagName("security-setting");
- for (int i = 0 ; i < list.getLength(); i++)
+ for (int i = 0; i < list.getLength(); i++)
{
Pair<String, Set<Role>> securityItem = parseSecurityRoles(list.item(i));
config.getSecurityRoles().put(securityItem.a, securityItem.b);
@@ -559,12 +576,12 @@
private void parseQueues(final Element e, final Configuration config)
{
NodeList elements = e.getElementsByTagName("queues");
-
+
if (elements.getLength() != 0)
{
Element node = (Element)elements.item(0);
NodeList list = node.getElementsByTagName("queue");
- for (int i = 0 ; i < list.getLength(); i++)
+ for (int i = 0; i < list.getLength(); i++)
{
CoreQueueConfiguration queueConfig = parseQueueConfiguration(list.item(i));
config.getQueueConfigurations().add(queueConfig);
@@ -579,12 +596,12 @@
private void parseAddressSettings(final Element e, final Configuration config)
{
NodeList elements = e.getElementsByTagName("address-settings");
-
+
if (elements.getLength() != 0)
{
Element node = (Element)elements.item(0);
NodeList list = node.getElementsByTagName("address-setting");
- for (int i = 0 ; i < list.getLength(); i++)
+ for (int i = 0; i < list.getLength(); i++)
{
Pair<String, AddressSettings> addressSettings = parseAddressSettings(list.item(i));
config.getAddressesSettings().put(addressSettings.a, addressSettings.b);
@@ -895,7 +912,7 @@
String name = e.getAttribute("name");
String localBindAddress = XMLConfigurationUtil.getString(e, "local-bind-address", null, Validators.NO_CHECK);
-
+
String groupAddress = XMLConfigurationUtil.getString(e, "group-address", null, Validators.NOT_NULL_OR_EMPTY);
int groupPort = XMLConfigurationUtil.getInteger(e, "group-port", -1, Validators.MINUS_ONE_OR_GT_ZERO);
@@ -1036,10 +1053,7 @@
String queueName = XMLConfigurationUtil.getString(brNode, "queue-name", null, Validators.NOT_NULL_OR_EMPTY);
- String forwardingAddress = XMLConfigurationUtil.getString(brNode,
- "forwarding-address",
- null,
- Validators.NO_CHECK);
+ String forwardingAddress = XMLConfigurationUtil.getString(brNode, "forwarding-address", null, Validators.NO_CHECK);
String transformerClassName = XMLConfigurationUtil.getString(brNode,
"transformer-class-name",
Modified: trunk/src/main/org/hornetq/core/persistence/impl/journal/JournalStorageManager.java
===================================================================
--- trunk/src/main/org/hornetq/core/persistence/impl/journal/JournalStorageManager.java 2010-04-21 08:14:01 UTC (rev 9141)
+++ trunk/src/main/org/hornetq/core/persistence/impl/journal/JournalStorageManager.java 2010-04-21 10:12:02 UTC (rev 9142)
@@ -238,17 +238,8 @@
SequentialFileFactory journalFF = null;
- JournalType journalTypeToUse = config.getJournalType();
-
- if (config.getJournalType() == JournalType.ASYNCIO && !AIOSequentialFileFactory.isSupported())
+ if (config.getJournalType() == JournalType.ASYNCIO)
{
- JournalStorageManager.log.warn("AIO wasn't located on this platform, it will fall back to using pure Java NIO. If your platform is Linux, install LibAIO to enable the AIO journal");
-
- journalTypeToUse = JournalType.NIO;
- }
-
- if (journalTypeToUse == JournalType.ASYNCIO)
- {
JournalStorageManager.log.info("Using AIO Journal");
journalFF = new AIOSequentialFileFactory(journalDir,
@@ -256,7 +247,7 @@
config.getJournalBufferTimeout_AIO(),
config.isLogJournalWriteRate());
}
- else if (journalTypeToUse == JournalType.NIO)
+ else if (config.getJournalType() == JournalType.NIO)
{
JournalStorageManager.log.info("Using NIO Journal");
journalFF = new NIOSequentialFileFactory(journalDir,
14 years, 1 month