JBoss hornetq SVN: r9141 - in trunk: tests/src/org/hornetq/tests/integration/jms/bridge and 1 other directory.
by do-not-reply@jboss.org
Author: jmesnil
Date: 2010-04-21 04:14:01 -0400 (Wed, 21 Apr 2010)
New Revision: 9141
Modified:
trunk/src/main/org/hornetq/jms/bridge/impl/JMSBridgeImpl.java
trunk/tests/src/org/hornetq/tests/integration/jms/bridge/JMSBridgeReconnectionTest.java
trunk/tests/src/org/hornetq/tests/integration/jms/bridge/JMSBridgeTest.java
Log:
https://jira.jboss.org/jira/browse/HORNETQ-287: cannot stop JMSBridge which is handling startup failure
* use a 3-sized fixed thread pool to manage JMS Bridge concurrent tasks
Modified: trunk/src/main/org/hornetq/jms/bridge/impl/JMSBridgeImpl.java
===================================================================
--- trunk/src/main/org/hornetq/jms/bridge/impl/JMSBridgeImpl.java 2010-04-20 20:16:45 UTC (rev 9140)
+++ trunk/src/main/org/hornetq/jms/bridge/impl/JMSBridgeImpl.java 2010-04-21 08:14:01 UTC (rev 9141)
@@ -19,6 +19,9 @@
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
@@ -107,6 +110,8 @@
private volatile boolean addMessageIDInHeader;
private boolean started;
+
+ private boolean stopping = false;
private final LinkedList<Message> messages;
@@ -136,10 +141,8 @@
private BatchTimeChecker timeChecker;
- private Thread checkerThread;
-
- private Thread sourceReceiver;
-
+ private ExecutorService executor;
+
private long batchExpiryTime;
private boolean paused;
@@ -170,6 +173,7 @@
public JMSBridgeImpl()
{
messages = new LinkedList<Message>();
+ executor = createExecutor();
}
public JMSBridgeImpl(final ConnectionFactoryFactory sourceCff,
@@ -305,6 +309,8 @@
public synchronized void start() throws Exception
{
+ stopping = false;
+
if (started)
{
JMSBridgeImpl.log.warn("Attempt to start, but is already started");
@@ -316,6 +322,12 @@
JMSBridgeImpl.log.trace("Starting " + this);
}
+ // bridge has been stopped and is restarted
+ if (executor.isShutdown())
+ {
+ executor = createExecutor();
+ }
+
checkParams();
TransactionManager tm = getTm();
@@ -356,20 +368,16 @@
timeChecker = new BatchTimeChecker();
- checkerThread = new Thread(timeChecker, "jmsbridge-checker-thread");
-
+ executor.execute(timeChecker);
batchExpiryTime = System.currentTimeMillis() + maxBatchTime;
- checkerThread.start();
-
if (JMSBridgeImpl.trace)
{
JMSBridgeImpl.log.trace("Started time checker thread");
}
}
- sourceReceiver = new SourceReceiver();
- sourceReceiver.start();
+ executor.execute(new SourceReceiver());
if (JMSBridgeImpl.trace)
{
@@ -386,12 +394,8 @@
public synchronized void stop() throws Exception
{
- if (!started)
- {
- JMSBridgeImpl.log.warn("Attempt to stop, but is already stopped");
- return;
- }
-
+ stopping = true;
+
if (JMSBridgeImpl.trace)
{
JMSBridgeImpl.log.trace("Stopping " + this);
@@ -401,50 +405,16 @@
{
started = false;
- // This must be inside sync block
- if (checkerThread != null)
- {
- checkerThread.interrupt();
- }
-
- if (sourceReceiver != null)
- {
- sourceReceiver.interrupt();
- }
+ executor.shutdownNow();
}
- // This must be outside sync block
- if (checkerThread != null)
+ boolean ok = executor.awaitTermination(60, TimeUnit.SECONDS);
+
+ if(!ok)
{
- if (JMSBridgeImpl.trace)
- {
- JMSBridgeImpl.log.trace("Waiting for checker thread to finish");
- }
-
- checkerThread.join();
-
- if (JMSBridgeImpl.trace)
- {
- JMSBridgeImpl.log.trace("Checker thread has finished");
- }
+ throw new Exception("fail to stop JMS Bridge");
}
- // This must be outside sync block
- if (sourceReceiver != null)
- {
- if (JMSBridgeImpl.trace)
- {
- JMSBridgeImpl.log.trace("Waiting for source receiver thread to finish");
- }
-
- sourceReceiver.join();
-
- if (JMSBridgeImpl.trace)
- {
- JMSBridgeImpl.log.trace("Source receiver thread has finished");
- }
- }
-
if (tx != null)
{
// Terminate any transaction
@@ -1366,7 +1336,7 @@
int count = 0;
- while (true)
+ while (true && !stopping)
{
boolean ok = setupJMSObjects();
@@ -1622,9 +1592,7 @@
// In the case of onMessage we can't close the connection from inside the onMessage method
// since it will block waiting for onMessage to complete. In the case of start we want to return
// from the call before the connections are reestablished so that the caller is not blocked unnecessarily.
- Thread t = new Thread(failureHandler, "jmsbridge-failurehandler-thread");
-
- t.start();
+ executor.execute(failureHandler);
}
private void addMessageIDInHeader(final Message msg) throws Exception
@@ -1702,6 +1670,15 @@
}
}
+ /**
+ * Creates a 3-sized thred pool executor (1 thread for the sourceReceiver, 1 for the timeChecker
+ * and 1 for the eventual failureHandler)
+ */
+ private ExecutorService createExecutor()
+ {
+ return Executors.newFixedThreadPool(3);
+ }
+
// Inner classes ---------------------------------------------------------------
/**
Modified: trunk/tests/src/org/hornetq/tests/integration/jms/bridge/JMSBridgeReconnectionTest.java
===================================================================
--- trunk/tests/src/org/hornetq/tests/integration/jms/bridge/JMSBridgeReconnectionTest.java 2010-04-20 20:16:45 UTC (rev 9140)
+++ trunk/tests/src/org/hornetq/tests/integration/jms/bridge/JMSBridgeReconnectionTest.java 2010-04-21 08:14:01 UTC (rev 9141)
@@ -145,7 +145,7 @@
/**
* https://jira.jboss.org/jira/browse/HORNETQ-287
*/
- public void _testStopBridgeWithFailureWhenStarted() throws Exception
+ public void testStopBridgeWithFailureWhenStarted() throws Exception
{
jmsServer1.stop();
@@ -172,39 +172,17 @@
Assert.assertFalse(bridge.isStarted());
Assert.assertTrue(bridge.isFailed());
- assertEquals(1, numOfThreadsStartingWith("pool-"));
-
bridge.stop();
Assert.assertFalse(bridge.isStarted());
- assertEquals(0, numOfThreadsStartingWith("pool-"));
+ // Thread.sleep(3000);
// we restart and setup the server for the test's tearDown checks
jmsServer1.start();
createQueue("targetQueue", 1);
setUpAdministeredObjects();
-
}
- //TODO is there a better way to check if a thread is still running?
- private int numOfThreadsStartingWith(String prefix)
- {
- int count = 0;
- long[] threadIds = ManagementFactory.getThreadMXBean().getAllThreadIds();
- for (long id : threadIds)
- {
- ThreadInfo threadInfo = ManagementFactory.getThreadMXBean().getThreadInfo(id);
- if (threadInfo != null)
- {
- if (threadInfo.getThreadName().startsWith(prefix))
- {
- count++;
- }
- }
- }
- return count;
- }
-
/*
* Send some messages
* Crash the destination server
Modified: trunk/tests/src/org/hornetq/tests/integration/jms/bridge/JMSBridgeTest.java
===================================================================
--- trunk/tests/src/org/hornetq/tests/integration/jms/bridge/JMSBridgeTest.java 2010-04-20 20:16:45 UTC (rev 9140)
+++ trunk/tests/src/org/hornetq/tests/integration/jms/bridge/JMSBridgeTest.java 2010-04-21 08:14:01 UTC (rev 9141)
@@ -562,6 +562,92 @@
}
}
+ public void testStartStopStart() throws Exception
+ {
+ JMSBridgeImpl bridge = null;
+
+ Connection connSource = null;
+
+ Connection connTarget = null;
+
+ try
+ {
+ final int NUM_MESSAGES = 10;
+
+ bridge = new JMSBridgeImpl(cff0,
+ cff1,
+ sourceQueueFactory,
+ targetQueueFactory,
+ null,
+ null,
+ null,
+ null,
+ null,
+ 5000,
+ 10,
+ QualityOfServiceMode.AT_MOST_ONCE,
+ 1,
+ -1,
+ null,
+ null,
+ false);
+ bridge.setTransactionManager(newTransactionManager());
+
+ bridge.start();
+
+ bridge.stop();
+
+ bridge.start();
+
+ connSource = cf0.createConnection();
+
+ Session sessSend = connSource.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageProducer prod = sessSend.createProducer(sourceQueue);
+
+ for (int i = 0; i < NUM_MESSAGES; i++)
+ {
+ TextMessage tm = sessSend.createTextMessage("message" + i);
+ prod.send(tm);
+ }
+
+ connTarget = cf1.createConnection();
+ Session sessRec = connTarget.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ MessageConsumer cons = sessRec.createConsumer(targetQueue);
+
+ connTarget.start();
+
+ for (int i = 0; i < NUM_MESSAGES; i++)
+ {
+ TextMessage tm = (TextMessage)cons.receive(10000);
+ Assert.assertNotNull(tm);
+ Assert.assertEquals("message" + i, tm.getText());
+ }
+
+ Message m = cons.receiveNoWait();
+ Assert.assertNull(m);
+ }
+ finally
+ {
+ if (connSource != null)
+ {
+ connSource.close();
+ }
+
+ if (connTarget != null)
+ {
+ connTarget.close();
+ }
+
+ if (bridge != null)
+ {
+ bridge.stop();
+ }
+
+ removeAllMessages(sourceQueue.getQueueName(), 0);
+ }
+ }
+
public void testSelector() throws Exception
{
JMSBridgeImpl bridge = null;
15 years, 8 months
JBoss hornetq SVN: r9140 - trunk/docs/user-manual/en.
by do-not-reply@jboss.org
Author: clebert.suconic(a)jboss.com
Date: 2010-04-20 16:16:45 -0400 (Tue, 20 Apr 2010)
New Revision: 9140
Modified:
trunk/docs/user-manual/en/duplicate-detection.xml
Log:
quick fix on typo
Modified: trunk/docs/user-manual/en/duplicate-detection.xml
===================================================================
--- trunk/docs/user-manual/en/duplicate-detection.xml 2010-04-20 15:58:33 UTC (rev 9139)
+++ trunk/docs/user-manual/en/duplicate-detection.xml 2010-04-20 20:16:45 UTC (rev 9140)
@@ -64,7 +64,7 @@
set it once in the transaction. If the server detects a duplicate message for any
message in the transaction, then it will ignore the entire transaction.</para>
<para>The name of the property that you set is given by the value of <literal
- >org.hornetq.core.message.impl.HDR_DUPLICATE_DETECTION_ID</literal>, which
+ >org.hornetq.api.core.HDR_DUPLICATE_DETECTION_ID</literal>, which
is <literal>_HQ_DUPL_ID</literal></para>
<para>The value of the property can be of type <literal>byte[]</literal> or <literal
>SimpleString</literal> if you're using the core API. If you're using JMS it must be
15 years, 8 months
JBoss hornetq SVN: r9139 - trunk/docs/user-manual/en.
by do-not-reply@jboss.org
Author: jmesnil
Date: 2010-04-20 11:58:33 -0400 (Tue, 20 Apr 2010)
New Revision: 9139
Modified:
trunk/docs/user-manual/en/clusters.xml
trunk/docs/user-manual/en/configuration-index.xml
trunk/docs/user-manual/en/configuring-transports.xml
Log:
https://jira.jboss.org/jira/browse/HORNETQ-367: Missing properties in doc configuration index
* added description for <discovery-groups>, <broadcast-groups>, <connectors> & <acceptors> configuration elements
Modified: trunk/docs/user-manual/en/clusters.xml
===================================================================
--- trunk/docs/user-manual/en/clusters.xml 2010-04-20 14:51:34 UTC (rev 9138)
+++ trunk/docs/user-manual/en/clusters.xml 2010-04-20 15:58:33 UTC (rev 9139)
@@ -82,8 +82,7 @@
<para>Let's take a look at an example broadcast group from <literal
>hornetq-configuration.xml</literal>:</para>
<programlisting><broadcast-groups>
- <broadcast-group name="my-broadcast-group"></programlisting>
- <programlisting>
+ <broadcast-group name="my-broadcast-group">
<local-bind-address>172.16.9.3</local-bind-address>
<local-bind-port>5432</local-bind-port>
<group-address>231.7.7.7</group-address>
Modified: trunk/docs/user-manual/en/configuration-index.xml
===================================================================
--- trunk/docs/user-manual/en/configuration-index.xml 2010-04-20 14:51:34 UTC (rev 9138)
+++ trunk/docs/user-manual/en/configuration-index.xml 2010-04-20 15:58:33 UTC (rev 9139)
@@ -391,13 +391,90 @@
<entry>25</entry>
</row>
<row>
- <entry><link linkend="configuring-transports.acceptors"
- >acceptors</link></entry>
+ <entry><link linkend="configuring-transports.connectors"
+ >connectors</link></entry>
+ <entry>Connector</entry>
+ <entry>a list of remoting connectors configurations to create</entry>
+ <entry/>
+ </row>
+ <row>
+ <entry>
+ <link linkend="configuring-transports.acceptors">connector.name (attribute)</link></entry>
+ <entry>String</entry>
+ <entry>Name of the connector - mandatory</entry>
+ <entry/>
+ </row>
+ <row>
+ <entry>
+ <link linkend="configuring-transports.connectors">connector.factory-class</link></entry>
+ <entry>String</entry>
+ <entry>Name of the ConnectorFactory implementation - mandatory</entry>
+ <entry/>
+ </row>
+ <row>
+ <entry>
+ <link linkend="configuring-transports.connectors">connector.param</link></entry>
+ <entry>A connector configuration parameter</entry>
+ <entry>A key-value pair used to configure the connector. A connector can have many param</entry>
+ <entry/>
+ </row>
+ <row>
+ <entry>
+ <link linkend="configuring-transports.connectors">connector.param.key (attribute)</link></entry>
+ <entry>String</entry>
+ <entry>Key of a configuration parameter - mandatory</entry>
+ <entry/>
+ </row>
+ <row>
+ <entry>
+ <link linkend="configuring-transports.connectors">connector.param.value (attribute)</link></entry>
+ <entry>String</entry>
+ <entry>Value of a configuration parameter - mandatory</entry>
+ <entry/>
+ </row>
+ <row>
+ <entry>
+ <link linkend="configuring-transports.acceptors">acceptors</link></entry>
<entry>Acceptor</entry>
<entry>a list of remoting acceptors to create</entry>
<entry/>
</row>
<row>
+ <entry>
+ <link linkend="configuring-transports.acceptors">acceptor.name (attribute)</link></entry>
+ <entry>String</entry>
+ <entry>Name of the acceptor - optional</entry>
+ <entry/>
+ </row>
+ <row>
+ <entry>
+ <link linkend="configuring-transports.acceptors">acceptor.factory-class</link></entry>
+ <entry>String</entry>
+ <entry>Name of the AcceptorFactory implementation - mandatory</entry>
+ <entry/>
+ </row>
+ <row>
+ <entry>
+ <link linkend="configuring-transports.acceptors">acceptor.param</link></entry>
+ <entry>An acceptor configuration parameter</entry>
+ <entry>A key-value pair used to configure the acceptor. An acceptor can have many param</entry>
+ <entry/>
+ </row>
+ <row>
+ <entry>
+ <link linkend="configuring-transports.acceptors">acceptor.param.key (attribute)</link></entry>
+ <entry>String</entry>
+ <entry>Key of a configuration parameter - mandatory</entry>
+ <entry/>
+ </row>
+ <row>
+ <entry>
+ <link linkend="configuring-transports.acceptors">acceptor.param.value (attribute)</link></entry>
+ <entry>String</entry>
+ <entry>Value of a configuration parameter - mandatory</entry>
+ <entry/>
+ </row>
+ <row>
<entry><link linkend="clusters.broadcast-groups"
>broadcast-groups</link></entry>
<entry>BroadcastGroup</entry>
@@ -405,13 +482,79 @@
<entry/>
</row>
<row>
- <entry><link linkend="understanding.connectors"
- >connectors</link></entry>
- <entry>Connector</entry>
- <entry>a list of remoting connectors configurations to create</entry>
+ <entry>
+ <link linkend="clusters.broadcast-groups">broadcast-group.name (attribute)</link>
+ </entry>
+ <entry>String</entry>
+ <entry>a unique name for the broadcast group - mandatory</entry>
<entry/>
</row>
<row>
+ <entry>
+ <link linkend="clusters.broadcast-groups">broadcast-group.local-bind-address</link>
+ </entry>
+ <entry>String</entry>
+ <entry>local bind address that the datagram socket is bound to</entry>
+ <entry>wildcard IP address chosen by the kernel</entry>
+ </row>
+ <row>
+ <entry>
+ <link linkend="clusters.broadcast-groups">broadcast-group.local-bind-port</link>
+ </entry>
+ <entry>Integer</entry>
+ <entry>local port to which the datagram socket is bound to</entry>
+ <entry>-1 (anonymous port)</entry>
+ </row>
+ <row>
+ <entry>
+ <link linkend="clusters.broadcast-groups">broadcast-group.group-address</link>
+ </entry>
+ <entry>String</entry>
+ <entry>multicast address to which the data will be broadcast - mandatory</entry>
+ <entry/>
+ </row>
+ <row>
+ <entry>
+ <link linkend="clusters.broadcast-groups">broadcast-group.group-port</link>
+ </entry>
+ <entry>Integer</entry>
+ <entry>UDP port number used for broadcasting - mandatory</entry>
+ <entry/>
+ </row>
+ <row>
+ <entry>
+ <link linkend="clusters.broadcast-groups">broadcast-group.broadcast-period</link>
+ </entry>
+ <entry>Long</entry>
+ <entry>period in milliseconds between consecutive broadcasts</entry>
+ <entry>1000 (in milliseconds)</entry>
+ </row>
+ <row>
+ <entry>
+ <link linkend="clusters.broadcast-groups">broadcast-group.connector-ref</link>
+ </entry>
+ <entry>A pair of connector</entry>
+ <entry>A pair connector and
+ optional backup connector that will be broadcasted. A broadcast-group can have multiple connector-ref</entry>
+ <entry/>
+ </row>
+ <row>
+ <entry>
+ <link linkend="clusters.broadcast-groups">broadcast-group.connector-ref.connector-name (attribute)</link>
+ </entry>
+ <entry>String</entry>
+ <entry>Name of the live connector - mandatory</entry>
+ <entry/>
+ </row>
+ <row>
+ <entry>
+ <link linkend="clusters.broadcast-groups">broadcast-group.connector-ref.backup-connector-name (attribute)</link>
+ </entry>
+ <entry>String</entry>
+ <entry>Name of the backup connector - optional</entry>
+ <entry/>
+ </row>
+ <row>
<entry><link linkend="clusters.discovery-groups"
>discovery-groups</link></entry>
<entry>DiscoveryGroup</entry>
@@ -419,6 +562,47 @@
<entry/>
</row>
<row>
+ <entry><link linkend="clusters.discovery-groups"
+ >discovery-group.name (attribute)</link></entry>
+ <entry>String</entry>
+ <entry>a unique name for the discovery group - mandatory</entry>
+ <entry/>
+ </row>
+ <row>
+ <entry>
+ <link linkend="clusters.discovery-groups">discovery-group.local-bind-address</link>
+ </entry>
+ <entry>String</entry>
+ <entry>the discovery group will be bound only to this local address</entry>
+ <entry/>
+ </row>
+ <row>
+ <entry>
+ <link linkend="clusters.discovery-groups">discovery-group.group-address</link>
+ </entry>
+ <entry>String</entry>
+ <entry>Multicast IP address of the group to listen on - mandatory</entry>
+ <entry/>
+ </row>
+ <row>
+ <entry>
+ <link linkend="clusters.discovery-groups">discovery-group.group-port</link>
+ </entry>
+ <entry>Integer</entry>
+ <entry>UDP port of the multicast group - mandatory</entry>
+ <entry/>
+ </row>
+ <row>
+ <entry>
+ <link linkend="clusters.discovery-groups">discovery-group.refresh-timeout</link>
+ </entry>
+ <entry>Integer</entry>
+ <entry>Period the discovery group
+ waits after receiving the last broadcast from a particular server before
+ removing that servers connector pair entry from its list.</entry>
+ <entry>10000 (in milliseconds)</entry>
+ </row>
+ <row>
<entry><link linkend="diverts">diverts</link></entry>
<entry>Divert</entry>
<entry>a list of diverts to use</entry>
@@ -807,8 +991,8 @@
<entry/>
</row>
<row>
- <entry><link linkend="message-grouping.jmsconfigure"
- >connection-factory.auto-group</link></entry>
+ <entry id="configuration.connection-factory.auto-group">
+ <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>
Modified: trunk/docs/user-manual/en/configuring-transports.xml
===================================================================
--- trunk/docs/user-manual/en/configuring-transports.xml 2010-04-20 14:51:34 UTC (rev 9138)
+++ trunk/docs/user-manual/en/configuring-transports.xml 2010-04-20 15:58:33 UTC (rev 9139)
@@ -61,7 +61,7 @@
<para>Examples of key-value pairs for a particular transport would be, say, to configure the
IP address to bind to, or the port to listen at.</para>
</section>
- <section id="understanding.connectors">
+ <section id="configuring-transports.connectors">
<title>Understanding Connectors</title>
<para>Whereas acceptors are used on the server to define how we accept connections,
connectors are used by a client to define how it connects to a server.</para>
15 years, 8 months
JBoss hornetq SVN: r9138 - trunk/src/main/org/hornetq/core/client/impl.
by do-not-reply@jboss.org
Author: timfox
Date: 2010-04-20 10:51:34 -0400 (Tue, 20 Apr 2010)
New Revision: 9138
Modified:
trunk/src/main/org/hornetq/core/client/impl/ClientSessionFactoryImpl.java
Log:
test commit
Modified: trunk/src/main/org/hornetq/core/client/impl/ClientSessionFactoryImpl.java
===================================================================
--- trunk/src/main/org/hornetq/core/client/impl/ClientSessionFactoryImpl.java 2010-04-16 16:46:08 UTC (rev 9137)
+++ trunk/src/main/org/hornetq/core/client/impl/ClientSessionFactoryImpl.java 2010-04-20 14:51:34 UTC (rev 9138)
@@ -175,6 +175,7 @@
ThreadFactory factory = new HornetQThreadFactory("HornetQ-client-global-scheduled-threads", true);
ClientSessionFactoryImpl.globalScheduledThreadPool = Executors.newScheduledThreadPool(HornetQClient.DEFAULT_SCHEDULED_THREAD_POOL_MAX_SIZE,
+
factory);
}
15 years, 8 months
JBoss hornetq SVN: r9137 - in trunk: src/main/org/hornetq/core/server/impl and 7 other directories.
by do-not-reply@jboss.org
Author: ataylor
Date: 2010-04-16 12:46:08 -0400 (Fri, 16 Apr 2010)
New Revision: 9137
Modified:
trunk/src/main/org/hornetq/core/client/impl/ClientConsumerImpl.java
trunk/src/main/org/hornetq/core/client/impl/ClientConsumerInternal.java
trunk/src/main/org/hornetq/core/client/impl/ClientSessionImpl.java
trunk/src/main/org/hornetq/core/server/impl/ServerSessionImpl.java
trunk/src/main/org/hornetq/core/transaction/ResourceManager.java
trunk/src/main/org/hornetq/core/transaction/Transaction.java
trunk/src/main/org/hornetq/core/transaction/impl/ResourceManagerImpl.java
trunk/src/main/org/hornetq/core/transaction/impl/TransactionImpl.java
trunk/src/main/org/hornetq/ra/HornetQRAProperties.java
trunk/src/main/org/hornetq/ra/HornetQResourceAdapter.java
trunk/src/main/org/hornetq/ra/inflow/HornetQActivation.java
trunk/src/main/org/hornetq/ra/inflow/HornetQActivationSpec.java
trunk/src/main/org/hornetq/ra/inflow/HornetQMessageHandler.java
trunk/tests/src/org/hornetq/tests/integration/xa/XaTimeoutTest.java
trunk/tests/src/org/hornetq/tests/unit/core/client/impl/LargeMessageBufferTest.java
trunk/tests/src/org/hornetq/tests/unit/core/postoffice/impl/BindingsImplTest.java
Log:
https://jira.jboss.org/jira/browse/HORNETQ-363 - fixed tx timeout and RA
Modified: trunk/src/main/org/hornetq/core/client/impl/ClientConsumerImpl.java
===================================================================
--- trunk/src/main/org/hornetq/core/client/impl/ClientConsumerImpl.java 2010-04-16 14:45:28 UTC (rev 9136)
+++ trunk/src/main/org/hornetq/core/client/impl/ClientConsumerImpl.java 2010-04-16 16:46:08 UTC (rev 9137)
@@ -369,7 +369,7 @@
// if unsetting a previous handler may be in onMessage so wait for completion
else if (handler == null && !noPreviousHandler)
{
- waitForOnMessageToComplete();
+ waitForOnMessageToComplete(true);
}
}
@@ -397,8 +397,13 @@
public void stop() throws HornetQException
{
- waitForOnMessageToComplete();
+ stop(true);
+ }
+ public void stop(final boolean waitForOnMessage) throws HornetQException
+ {
+ waitForOnMessageToComplete(waitForOnMessage);
+
synchronized (this)
{
if (stopped)
@@ -552,7 +557,7 @@
currentLargeMessageBuffer.addPacket(chunk);
}
- public void clear() throws HornetQException
+ public void clear(boolean waitForOnMessage) throws HornetQException
{
synchronized (this)
{
@@ -572,7 +577,7 @@
// Need to send credits for the messages in the buffer
- waitForOnMessageToComplete();
+ waitForOnMessageToComplete(waitForOnMessage);
}
public int getClientWindowSize()
@@ -723,14 +728,14 @@
channel.send(new SessionConsumerFlowCreditMessage(id, credits));
}
- private void waitForOnMessageToComplete()
+ private void waitForOnMessageToComplete(boolean waitForOnMessage)
{
if (handler == null)
{
return;
}
- if (Thread.currentThread() == onMessageThread)
+ if (!waitForOnMessage || Thread.currentThread() == onMessageThread)
{
// If called from inside onMessage then return immediately - otherwise would block
return;
@@ -855,7 +860,7 @@
closing = true;
// Now we wait for any current handler runners to run.
- waitForOnMessageToComplete();
+ waitForOnMessageToComplete(true);
if (currentLargeMessageBuffer != null)
{
Modified: trunk/src/main/org/hornetq/core/client/impl/ClientConsumerInternal.java
===================================================================
--- trunk/src/main/org/hornetq/core/client/impl/ClientConsumerInternal.java 2010-04-16 14:45:28 UTC (rev 9136)
+++ trunk/src/main/org/hornetq/core/client/impl/ClientConsumerInternal.java 2010-04-16 16:46:08 UTC (rev 9137)
@@ -46,7 +46,7 @@
void flowControl(final int messageBytes, final boolean discountSlowConsumer) throws HornetQException;
- void clear() throws HornetQException;
+ void clear(boolean waitForOnMessage) throws HornetQException;
void clearAtFailover();
@@ -62,6 +62,8 @@
void stop() throws HornetQException;
+ void stop(boolean waitForOnMessage) throws HornetQException;
+
void start();
SessionQueueQueryResponseMessage getQueueInfo();
Modified: trunk/src/main/org/hornetq/core/client/impl/ClientSessionImpl.java
===================================================================
--- trunk/src/main/org/hornetq/core/client/impl/ClientSessionImpl.java 2010-04-16 14:45:28 UTC (rev 9136)
+++ trunk/src/main/org/hornetq/core/client/impl/ClientSessionImpl.java 2010-04-16 16:46:08 UTC (rev 9137)
@@ -560,7 +560,7 @@
// We need to make sure we don't get any inflight messages
for (ClientConsumerInternal consumer : consumers.values())
{
- consumer.clear();
+ consumer.clear(true);
}
// Acks must be flushed here *after connection is stopped and all onmessages finished executing
@@ -639,19 +639,7 @@
public void stop() throws HornetQException
{
- checkClosed();
-
- if (started)
- {
- for (ClientConsumerInternal clientConsumerInternal : consumers.values())
- {
- clientConsumerInternal.stop();
- }
-
- channel.sendBlocking(new PacketImpl(PacketImpl.SESS_STOP));
-
- started = false;
- }
+ stop(true);
}
public void addFailureListener(final SessionFailureListener listener)
@@ -1380,13 +1368,13 @@
if (wasStarted)
{
- stop();
+ stop(false);
}
// We need to make sure we don't get any inflight messages
for (ClientConsumerInternal consumer : consumers.values())
{
- consumer.clear();
+ consumer.clear(false);
}
flushAcks();
@@ -1712,6 +1700,23 @@
}
}
+ public void stop(final boolean waitForOnMessage) throws HornetQException
+ {
+ checkClosed();
+
+ if (started)
+ {
+ for (ClientConsumerInternal clientConsumerInternal : consumers.values())
+ {
+ clientConsumerInternal.stop(waitForOnMessage);
+ }
+
+ channel.sendBlocking(new PacketImpl(PacketImpl.SESS_STOP));
+
+ started = false;
+ }
+ }
+
private static class BindingQueryImpl implements BindingQuery
{
Modified: trunk/src/main/org/hornetq/core/server/impl/ServerSessionImpl.java
===================================================================
--- trunk/src/main/org/hornetq/core/server/impl/ServerSessionImpl.java 2010-04-16 14:45:28 UTC (rev 9136)
+++ trunk/src/main/org/hornetq/core/server/impl/ServerSessionImpl.java 2010-04-16 16:46:08 UTC (rev 9137)
@@ -136,6 +136,8 @@
private volatile SimpleString defaultAddress;
+ private volatile int timeoutSeconds;
+
// Constructors ---------------------------------------------------------------------------------
public ServerSessionImpl(final String name,
@@ -180,9 +182,11 @@
this.securityStore = securityStore;
+ timeoutSeconds = resourceManager.getTimeoutSeconds();
+
if (!xa)
{
- tx = new TransactionImpl(storageManager);
+ tx = new TransactionImpl(storageManager, timeoutSeconds);
}
this.xa = xa;
@@ -558,7 +562,7 @@
}
finally
{
- tx = new TransactionImpl(storageManager);
+ tx = new TransactionImpl(storageManager, timeoutSeconds);
}
}
@@ -568,12 +572,12 @@
{
// Might be null if XA
- tx = new TransactionImpl(storageManager);
+ tx = new TransactionImpl(storageManager, timeoutSeconds);
}
doRollback(considerLastMessageAsDelivered, tx);
- tx = new TransactionImpl(storageManager);
+ tx = new TransactionImpl(storageManager, timeoutSeconds);
}
public void xaCommit(final Xid xid, final boolean onePhase) throws Exception
@@ -809,7 +813,7 @@
}
else
{
- tx = new TransactionImpl(xid, storageManager, postOffice);
+ tx = new TransactionImpl(xid, storageManager, timeoutSeconds);
boolean added = resourceManager.putTransaction(xid, tx);
@@ -898,7 +902,11 @@
public void xaSetTimeout(final int timeout)
{
- resourceManager.setTimeoutSeconds(timeout);
+ timeoutSeconds = timeout;
+ if(tx != null)
+ {
+ tx.setTimeout(timeout);
+ }
}
public void start()
Modified: trunk/src/main/org/hornetq/core/transaction/ResourceManager.java
===================================================================
--- trunk/src/main/org/hornetq/core/transaction/ResourceManager.java 2010-04-16 14:45:28 UTC (rev 9136)
+++ trunk/src/main/org/hornetq/core/transaction/ResourceManager.java 2010-04-16 16:46:08 UTC (rev 9137)
@@ -37,8 +37,6 @@
int getTimeoutSeconds();
- boolean setTimeoutSeconds(int timeoutSeconds);
-
List<Xid> getPreparedTransactions();
Map<Xid, Long> getPreparedTransactionsWithCreationTime();
Modified: trunk/src/main/org/hornetq/core/transaction/Transaction.java
===================================================================
--- trunk/src/main/org/hornetq/core/transaction/Transaction.java 2010-04-16 14:45:28 UTC (rev 9136)
+++ trunk/src/main/org/hornetq/core/transaction/Transaction.java 2010-04-16 16:46:08 UTC (rev 9137)
@@ -55,12 +55,16 @@
void removeOperation(TransactionOperation sync);
+ boolean hasTimedOut(long currentTime, int defaultTimeout);
+
void putProperty(int index, Object property);
Object getProperty(int index);
void setContainsPersistent();
+ void setTimeout(int timeout);
+
static enum State
{
ACTIVE, PREPARED, COMMITTED, ROLLEDBACK, SUSPENDED, ROLLBACK_ONLY
Modified: trunk/src/main/org/hornetq/core/transaction/impl/ResourceManagerImpl.java
===================================================================
--- trunk/src/main/org/hornetq/core/transaction/impl/ResourceManagerImpl.java 2010-04-16 14:45:28 UTC (rev 9136)
+++ trunk/src/main/org/hornetq/core/transaction/impl/ResourceManagerImpl.java 2010-04-16 16:46:08 UTC (rev 9137)
@@ -49,8 +49,6 @@
private final int defaultTimeoutSeconds;
- private volatile int timeoutSeconds;
-
private boolean started = false;
private TxTimeoutHandler task;
@@ -64,7 +62,6 @@
final ScheduledExecutorService scheduledThreadPool)
{
this.defaultTimeoutSeconds = defaultTimeoutSeconds;
- timeoutSeconds = defaultTimeoutSeconds;
this.txTimeoutScanPeriod = txTimeoutScanPeriod;
this.scheduledThreadPool = scheduledThreadPool;
}
@@ -125,24 +122,9 @@
public int getTimeoutSeconds()
{
- return timeoutSeconds;
+ return defaultTimeoutSeconds;
}
- public boolean setTimeoutSeconds(final int timeoutSeconds)
- {
- if (timeoutSeconds == 0)
- {
- // reset to default
- this.timeoutSeconds = defaultTimeoutSeconds;
- }
- else
- {
- this.timeoutSeconds = timeoutSeconds;
- }
-
- return true;
- }
-
public List<Xid> getPreparedTransactions()
{
List<Xid> xids = new ArrayList<Xid>();
@@ -231,7 +213,7 @@
for (Transaction tx : transactions.values())
{
- if (tx.getState() != Transaction.State.PREPARED && now > tx.getCreateTime() + timeoutSeconds * 1000)
+ if (tx.hasTimedOut(now, defaultTimeoutSeconds))
{
transactions.remove(tx.getXid());
ResourceManagerImpl.log.warn("transaction with xid " + tx.getXid() + " timed out");
Modified: trunk/src/main/org/hornetq/core/transaction/impl/TransactionImpl.java
===================================================================
--- trunk/src/main/org/hornetq/core/transaction/impl/TransactionImpl.java 2010-04-16 14:45:28 UTC (rev 9136)
+++ trunk/src/main/org/hornetq/core/transaction/impl/TransactionImpl.java 2010-04-16 16:46:08 UTC (rev 9137)
@@ -59,6 +59,21 @@
private volatile boolean containsPersistent;
+ private int timeoutSeconds = -1;
+
+ public TransactionImpl(final StorageManager storageManager, final int timeoutSeconds)
+ {
+ this.storageManager = storageManager;
+
+ xid = null;
+
+ id = storageManager.generateUniqueID();
+
+ createTime = System.currentTimeMillis();
+
+ this.timeoutSeconds = timeoutSeconds;
+ }
+
public TransactionImpl(final StorageManager storageManager)
{
this.storageManager = storageManager;
@@ -70,7 +85,7 @@
createTime = System.currentTimeMillis();
}
- public TransactionImpl(final Xid xid, final StorageManager storageManager, final PostOffice postOffice)
+ public TransactionImpl(final Xid xid, final StorageManager storageManager, final int timeoutSeconds)
{
this.storageManager = storageManager;
@@ -79,6 +94,8 @@
id = storageManager.generateUniqueID();
createTime = System.currentTimeMillis();
+
+ this.timeoutSeconds = timeoutSeconds;
}
public TransactionImpl(final long id, final Xid xid, final StorageManager storageManager)
@@ -100,6 +117,11 @@
containsPersistent = true;
}
+ public void setTimeout(final int timeout)
+ {
+ this.timeoutSeconds = timeout;
+ }
+
public long getID()
{
return id;
@@ -110,6 +132,18 @@
return createTime;
}
+ public boolean hasTimedOut(final long currentTime,final int defaultTimeout)
+ {
+ if(timeoutSeconds == - 1)
+ {
+ return getState() != Transaction.State.PREPARED && currentTime > createTime + defaultTimeout * 1000;
+ }
+ else
+ {
+ return getState() != Transaction.State.PREPARED && currentTime > createTime + timeoutSeconds * 1000;
+ }
+ }
+
public void prepare() throws Exception
{
synchronized (timeoutLock)
Modified: trunk/src/main/org/hornetq/ra/HornetQRAProperties.java
===================================================================
--- trunk/src/main/org/hornetq/ra/HornetQRAProperties.java 2010-04-16 14:45:28 UTC (rev 9136)
+++ trunk/src/main/org/hornetq/ra/HornetQRAProperties.java 2010-04-16 16:46:08 UTC (rev 9137)
@@ -41,9 +41,6 @@
/** The password */
private String password;
- /** Use XA */
- private Boolean useXA;
-
/** Use Local TX instead of XA */
private Boolean localTx = false;
@@ -142,52 +139,12 @@
this.localTx = localTx;
}
- /**
- * Get the use XA flag
- * @return The value
- */
- public Boolean getUseXA()
- {
- if (HornetQRAProperties.trace)
- {
- HornetQRAProperties.log.trace("getUseXA()");
- }
- return useXA;
- }
-
- /**
- * Set the use XA flag
- * @param xa The value
- */
- public void setUseXA(final Boolean xa)
- {
- if (HornetQRAProperties.trace)
- {
- HornetQRAProperties.log.trace("setUseXA(" + xa + ")");
- }
-
- useXA = xa;
- }
-
- /**
- * Use XA for communication
- * @return The value
- */
- public boolean isUseXA()
- {
- if (HornetQRAProperties.trace)
- {
- HornetQRAProperties.log.trace("isUseXA()");
- }
-
- return useXA != null && useXA;
- }
@Override
public String toString()
{
- return "HornetQRAProperties[useXA=" + useXA + ", localTx=" + localTx +
+ return "HornetQRAProperties[localTx=" + localTx +
", userName=" + userName + ", password=" + password + "]";
}
}
Modified: trunk/src/main/org/hornetq/ra/HornetQResourceAdapter.java
===================================================================
--- trunk/src/main/org/hornetq/ra/HornetQResourceAdapter.java 2010-04-16 14:45:28 UTC (rev 9136)
+++ trunk/src/main/org/hornetq/ra/HornetQResourceAdapter.java 2010-04-16 16:46:08 UTC (rev 9137)
@@ -1186,37 +1186,8 @@
raProperties.setUseLocalTx(localTx);
}
- /**
- * Get the use XA flag
- *
- * @return The value
- */
- public Boolean getUseXA()
- {
- if (HornetQResourceAdapter.trace)
- {
- HornetQResourceAdapter.log.trace("getUseXA()");
- }
- return raProperties.getUseXA();
- }
-
/**
- * Set the use XA flag
- *
- * @param xa The value
- */
- public void setUseXA(final Boolean xa)
- {
- if (HornetQResourceAdapter.trace)
- {
- HornetQResourceAdapter.log.trace("setUseXA(" + xa + ")");
- }
-
- raProperties.setUseXA(xa);
- }
-
- /**
* Indicates whether some other object is "equal to" this one.
*
* @param obj Object with which to compare
@@ -1287,7 +1258,8 @@
final Integer dupsOkBatchSize,
final Integer transactionBatchSize,
final boolean deliveryTransacted,
- final boolean useLocalTx) throws Exception
+ final boolean useLocalTx,
+ final Integer txTimeout) throws Exception
{
ClientSession result;
Modified: trunk/src/main/org/hornetq/ra/inflow/HornetQActivation.java
===================================================================
--- trunk/src/main/org/hornetq/ra/inflow/HornetQActivation.java 2010-04-16 14:45:28 UTC (rev 9136)
+++ trunk/src/main/org/hornetq/ra/inflow/HornetQActivation.java 2010-04-16 16:46:08 UTC (rev 9137)
@@ -353,7 +353,8 @@
ra.getDupsOKBatchSize(),
ra.getTransactionBatchSize(),
isDeliveryTransacted,
- spec.isUseLocalTx());
+ spec.isUseLocalTx(),
+ spec.getTransactionTimeout());
HornetQActivation.log.debug("Using queue connection " + result);
Modified: trunk/src/main/org/hornetq/ra/inflow/HornetQActivationSpec.java
===================================================================
--- trunk/src/main/org/hornetq/ra/inflow/HornetQActivationSpec.java 2010-04-16 14:45:28 UTC (rev 9136)
+++ trunk/src/main/org/hornetq/ra/inflow/HornetQActivationSpec.java 2010-04-16 16:46:08 UTC (rev 9137)
@@ -92,6 +92,10 @@
/* use local tx instead of XA*/
private Boolean localTx;
+
+ private String transactionManagerLocatorClass = "org.hornetq.integration.jboss.tm.JBoss5TransactionManagerLocator";
+
+ private String transactionManagerLocatorMethod = "getTm";
/**
* Constructor
@@ -644,6 +648,27 @@
this.localTx = localTx;
}
+
+ public void setTransactionManagerLocatorClass(final String transactionManagerLocatorClass)
+ {
+ this.transactionManagerLocatorClass = transactionManagerLocatorClass;
+ }
+
+ public String getTransactionManagerLocatorClass()
+ {
+ return transactionManagerLocatorClass;
+ }
+
+ public String getTransactionManagerLocatorMethod()
+ {
+ return transactionManagerLocatorMethod;
+ }
+
+ public void setTransactionManagerLocatorMethod(final String transactionManagerLocatorMethod)
+ {
+ this.transactionManagerLocatorMethod = transactionManagerLocatorMethod;
+ }
+
/**
* Validate
* @exception InvalidPropertyException Thrown if a validation exception occurs
@@ -755,6 +780,7 @@
public void setReconnectInterval(long interval)
{
}
-
-
+
+
+
}
Modified: trunk/src/main/org/hornetq/ra/inflow/HornetQMessageHandler.java
===================================================================
--- trunk/src/main/org/hornetq/ra/inflow/HornetQMessageHandler.java 2010-04-16 14:45:28 UTC (rev 9136)
+++ trunk/src/main/org/hornetq/ra/inflow/HornetQMessageHandler.java 2010-04-16 16:46:08 UTC (rev 9137)
@@ -12,6 +12,7 @@
*/
package org.hornetq.ra.inflow;
+import java.lang.reflect.Method;
import java.util.UUID;
import javax.jms.InvalidClientIDException;
@@ -19,6 +20,8 @@
import javax.resource.ResourceException;
import javax.resource.spi.endpoint.MessageEndpoint;
import javax.resource.spi.endpoint.MessageEndpointFactory;
+import javax.transaction.SystemException;
+import javax.transaction.TransactionManager;
import org.hornetq.api.core.HornetQException;
import org.hornetq.api.core.SimpleString;
@@ -69,6 +72,8 @@
private final int sessionNr;
+ private TransactionManager tm;
+
public HornetQMessageHandler(final HornetQActivation activation, final ClientSession session, final int sessionNr)
{
this.activation = activation;
@@ -241,14 +246,27 @@
HornetQMessage msg = HornetQMessage.createMessage(message, session);
boolean beforeDelivery = false;
+
try
{
+ if(activation.getActivationSpec().getTransactionTimeout() > 0)
+ {
+ getTm().setTransactionTimeout(activation.getActivationSpec().getTransactionTimeout());
+ }
endpoint.beforeDelivery(HornetQActivation.ONMESSAGE);
beforeDelivery = true;
msg.doBeforeReceive();
((MessageListener)endpoint).onMessage(msg);
message.acknowledge();
- endpoint.afterDelivery();
+ try
+ {
+ endpoint.afterDelivery();
+ }
+ catch (ResourceException e)
+ {
+ HornetQMessageHandler.log.warn("Unable to call after delivery", e);
+ return;
+ }
if (useLocalTx)
{
session.commit();
@@ -266,7 +284,7 @@
}
catch (ResourceException e1)
{
- HornetQMessageHandler.log.warn("Unable to call after delivery");
+ HornetQMessageHandler.log.warn("Unable to call after delivery", e);
}
}
if (useLocalTx || !activation.isDeliveryTransacted())
@@ -284,4 +302,33 @@
}
+ private TransactionManager getTm()
+ {
+ if (tm == null)
+ {
+ try
+ {
+ ClassLoader loader = Thread.currentThread().getContextClassLoader();
+ Class aClass = loader.loadClass(activation.getActivationSpec().getTransactionManagerLocatorClass());
+ Object o = aClass.newInstance();
+ Method m = aClass.getMethod(activation.getActivationSpec().getTransactionManagerLocatorMethod());
+ tm = (TransactionManager)m.invoke(o);
+ }
+ catch (Exception e)
+ {
+ throw new IllegalStateException("unable to create TransactionManager from " + activation.getActivationSpec().getTransactionManagerLocatorClass() +
+ "." +
+ activation.getActivationSpec().getTransactionManagerLocatorMethod(),
+ e);
+ }
+
+ if (tm == null)
+ {
+ throw new IllegalStateException("Cannot locate a transaction manager");
+ }
+ }
+
+ return tm;
+ }
+
}
Modified: trunk/tests/src/org/hornetq/tests/integration/xa/XaTimeoutTest.java
===================================================================
--- trunk/tests/src/org/hornetq/tests/integration/xa/XaTimeoutTest.java 2010-04-16 14:45:28 UTC (rev 9136)
+++ trunk/tests/src/org/hornetq/tests/integration/xa/XaTimeoutTest.java 2010-04-16 16:46:08 UTC (rev 9137)
@@ -393,11 +393,19 @@
clientProducer.send(m3);
clientProducer.send(m4);
clientSession.end(xid, XAResource.TMSUCCESS);
+
+ clientSession.commit(xid, true);
+
clientSession.setTransactionTimeout(1);
+ clientSession.start(xid, XAResource.TMNOFLAGS);
CountDownLatch latch = new CountDownLatch(1);
messagingService.getResourceManager().getTransaction(xid).addOperation(new RollbackCompleteOperation(latch));
- Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
-
+ clientProducer.send(m1);
+ clientProducer.send(m2);
+ clientProducer.send(m3);
+ clientProducer.send(m4);
+ clientSession.end(xid, XAResource.TMSUCCESS);
+ Assert.assertTrue(latch.await(2600, TimeUnit.MILLISECONDS));
try
{
clientSession.commit(xid, true);
@@ -408,49 +416,15 @@
}
clientSession.start();
ClientMessage m = clientConsumer.receiveImmediate();
- Assert.assertNull(m);
- }
-
- public void testChangingTimeoutGetsPickedUpCommit() throws Exception
- {
- Xid xid = new XidImpl("xa1".getBytes(), 1, UUIDGenerator.getInstance().generateStringUUID().getBytes());
-
- ClientMessage m1 = createTextMessage("m1", clientSession);
- ClientMessage m2 = createTextMessage("m2", clientSession);
- ClientMessage m3 = createTextMessage("m3", clientSession);
- ClientMessage m4 = createTextMessage("m4", clientSession);
- clientSession.setTransactionTimeout(2);
- clientSession.start(xid, XAResource.TMNOFLAGS);
- clientProducer.send(m1);
- clientProducer.send(m2);
- clientProducer.send(m3);
- clientProducer.send(m4);
- clientSession.end(xid, XAResource.TMSUCCESS);
- clientSession.setTransactionTimeout(10000);
- CountDownLatch latch = new CountDownLatch(1);
- messagingService.getResourceManager().getTransaction(xid).addOperation(new RollbackCompleteOperation(latch));
- Assert.assertFalse(latch.await(2600, TimeUnit.MILLISECONDS));
- clientSession.prepare(xid);
- clientSession.commit(xid, false);
- ClientSession clientSession2 = sessionFactory.createSession(false, true, true);
- ClientConsumer consumer = clientSession2.createConsumer(atestq);
- clientSession2.start();
- ClientMessage m = consumer.receive(500);
Assert.assertNotNull(m);
- Assert.assertEquals(m.getBodyBuffer().readString(), "m1");
- m = consumer.receive(500);
+ m = clientConsumer.receiveImmediate();
Assert.assertNotNull(m);
- m.acknowledge();
- Assert.assertEquals(m.getBodyBuffer().readString(), "m2");
- m = consumer.receive(500);
- m.acknowledge();
+ m = clientConsumer.receiveImmediate();
Assert.assertNotNull(m);
- Assert.assertEquals(m.getBodyBuffer().readString(), "m3");
- m = consumer.receive(500);
- m.acknowledge();
+ m = clientConsumer.receiveImmediate();
Assert.assertNotNull(m);
- Assert.assertEquals(m.getBodyBuffer().readString(), "m4");
- clientSession2.close();
+ m = clientConsumer.receiveImmediate();
+ Assert.assertNull(m);
}
public void testMultipleTransactionsTimedOut() throws Exception
@@ -464,6 +438,7 @@
for (int i = 0; i < clientSessions.length; i++)
{
clientSessions[i] = sessionFactory.createSession(true, false, false);
+ clientSessions[i].setTransactionTimeout(i < 50?2:5000);
}
ClientProducer[] clientProducers = new ClientProducer[xids.length];
@@ -478,7 +453,6 @@
{
messages[i] = createTextMessage("m" + i, clientSession);
}
- clientSession.setTransactionTimeout(2);
for (int i = 0; i < clientSessions.length; i++)
{
clientSessions[i].start(xids[i], XAResource.TMNOFLAGS);
@@ -491,13 +465,21 @@
{
clientSessions[i].end(xids[i], XAResource.TMSUCCESS);
}
- CountDownLatch latch = new CountDownLatch(1);
- messagingService.getResourceManager()
- .getTransaction(xids[clientSessions.length - 1])
- .addOperation(new RollbackCompleteOperation(latch));
- Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
- for (int i = 0; i < clientSessions.length; i++)
+ CountDownLatch[] latches = new CountDownLatch[xids.length];
+ for (int i1 = 0; i1 < latches.length; i1++)
{
+ latches[i1] = new CountDownLatch(1);
+ messagingService.getResourceManager()
+ .getTransaction(xids[i1])
+ .addOperation(new RollbackCompleteOperation(latches[i1]));
+ }
+ for (int i1 = 0;i1 < latches.length/2; i1++)
+ {
+ Assert.assertTrue(latches[i1].await(5, TimeUnit.SECONDS));
+ }
+
+ for (int i = 0; i < clientSessions.length/2; i++)
+ {
try
{
clientSessions[i].commit(xids[i], true);
@@ -507,11 +489,20 @@
Assert.assertTrue(e.errorCode == XAException.XAER_NOTA);
}
}
+ for (int i = 50; i < clientSessions.length; i++)
+ {
+ clientSessions[i].commit(xids[i], true);
+ }
for (ClientSession session : clientSessions)
{
session.close();
}
clientSession.start();
+ for(int i = 0; i < clientSessions.length/2; i++)
+ {
+ ClientMessage m = clientConsumer.receiveImmediate();
+ Assert.assertNotNull(m);
+ }
ClientMessage m = clientConsumer.receiveImmediate();
Assert.assertNull(m);
}
Modified: trunk/tests/src/org/hornetq/tests/unit/core/client/impl/LargeMessageBufferTest.java
===================================================================
--- trunk/tests/src/org/hornetq/tests/unit/core/client/impl/LargeMessageBufferTest.java 2010-04-16 14:45:28 UTC (rev 9136)
+++ trunk/tests/src/org/hornetq/tests/unit/core/client/impl/LargeMessageBufferTest.java 2010-04-16 16:46:08 UTC (rev 9137)
@@ -635,7 +635,7 @@
}
- public void clear() throws HornetQException
+ public void clear(boolean waitForOnMessage) throws HornetQException
{
// TODO Auto-generated method stub
@@ -725,6 +725,11 @@
}
+ public void stop(boolean waitForOnMessage) throws HornetQException
+ {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
public SessionQueueQueryResponseMessage getQueueInfo()
{
// TODO Auto-generated method stub
Modified: trunk/tests/src/org/hornetq/tests/unit/core/postoffice/impl/BindingsImplTest.java
===================================================================
--- trunk/tests/src/org/hornetq/tests/unit/core/postoffice/impl/BindingsImplTest.java 2010-04-16 14:45:28 UTC (rev 9136)
+++ trunk/tests/src/org/hornetq/tests/unit/core/postoffice/impl/BindingsImplTest.java 2010-04-16 16:46:08 UTC (rev 9137)
@@ -134,6 +134,11 @@
}
+ public boolean hasTimedOut(long currentTime, int defaultTimeout)
+ {
+ return false;
+ }
+
/* (non-Javadoc)
* @see org.hornetq.core.transaction.Transaction#commit()
*/
@@ -282,6 +287,11 @@
}
+ public void setTimeout(int timeout)
+ {
+
+ }
+
}
class FakeMessage implements ServerMessage
15 years, 8 months
JBoss hornetq SVN: r9136 - branches/HnetQ_323_cn/docs/user-manual/zh.
by do-not-reply@jboss.org
Author: gaohoward
Date: 2010-04-16 10:45:28 -0400 (Fri, 16 Apr 2010)
New Revision: 9136
Modified:
branches/HnetQ_323_cn/docs/user-manual/zh/security.xml
Log:
done
Modified: branches/HnetQ_323_cn/docs/user-manual/zh/security.xml
===================================================================
--- branches/HnetQ_323_cn/docs/user-manual/zh/security.xml 2010-04-16 09:30:02 UTC (rev 9135)
+++ branches/HnetQ_323_cn/docs/user-manual/zh/security.xml 2010-04-16 14:45:28 UTC (rev 9136)
@@ -17,63 +17,46 @@
<!-- permitted by applicable law. -->
<!-- ============================================================================= -->
<chapter id="security">
- <title>Security</title>
- <para>This chapter describes how security works with HornetQ and how you can configure it. To
- disable security completely simply set the <literal>security-enabled</literal> property to
- false in the <literal>hornetq-configuration.xml</literal> file.</para>
- <para>For performance reasons security is cached and invalidated every so long. To change this
- period set the property <literal>security-invalidation-interval</literal>, which is in
- milliseconds. The default is <literal>10000</literal> ms.</para>
+ <title>安全</title>
+ <para>本章讲述HornetQ的安全机制以及如何配置它。要完全关闭安全,只要将<literal>hornetq-configuration.xml</literal>
+ 文件中的<literal>security-enabled</literal>参数设为false即可。</para>
+ <para>出于性能的考虑,安全在HornetQ中被缓存一定的时间。要改变这个时间,需要设置参数
+ <literal>security-invalidation-interval</literal>,单位是毫秒。默认值是
+ <literal>10000</literal>毫秒。</para>
<section id="security.settings.roles">
- <title>Role based security for addresses</title>
- <para>HornetQ contains a flexible role-based security model for applying security to queues,
- based on their addresses.</para>
- <para>As explained in <xref linkend="using-core"/>, HornetQ core consists mainly of sets of
- queues bound to addresses. A message is sent to an address and the server looks up the
- set of queues that are bound to that address, the server then routes the message to
- those set of queues.</para>
- <para>HornetQ allows sets of permissions to be defined against the queues based on their
- address. An exact match on the address can be used or a wildcard match can be used using
- the wildcard characters '<literal>#</literal>' and '<literal>*</literal>'.</para>
- <para>Seven different permissions can be given to the set of queues which match the address.
- Those permissions are:</para>
+ <title>基于角色的地址安全</title>
+ <para>HornetQ采用了基于角色的安全模型来配置地址的安全以及其队列的安全。</para>
+ <para>正如在<xref linkend="using-core"/>解释的那样,HornetQ核心主要由绑定到地址上的队列组成。
+ 消息被发送到地址后,服务器查找与之绑定的队列,并将消息路由到这些队列中。</para>
+ <para>HornetQ可以基于地址来给队列定义权限。在定义权限时可以使用通配符'<literal>#</literal>'和
+ '<literal>*</literal>'。</para>
+ <para>队列的权限有7种,它们是:</para>
<itemizedlist>
<listitem>
- <para><literal>createDurableQueue</literal>. This permission allows the user to
- create a durable queue under matching addresses.</para>
+ <para><literal>createDurableQueue</literal>。允许用户在相应的地址上创建持久的队列。</para>
</listitem>
<listitem>
- <para><literal>deleteDurableQueue</literal>. This permission allows the user to
- delete a durable queue under matching addresses.</para>
+ <para><literal>deleteDurableQueue</literal>。允许用户在相应的地址上删除相应的持久的队列。</para>
</listitem>
<listitem>
- <para><literal>createTempQueue</literal>. This permission allows the user to create
- a temporary queue under matching addresses.</para>
+ <para><literal>createTempQueue</literal>。允许用户在相应地址上创建临时队列。</para>
</listitem>
<listitem>
- <para><literal>deleteTempQueue</literal>. This permission allows the user to delete
- a temporarry queue under matching addresses.</para>
+ <para><literal>deleteTempQueue</literal>。允许用户在相应地址上删除临时队列。</para>
</listitem>
<listitem>
- <para><literal>send</literal>. This permission allows the user to send a message to
- matching addresses.</para>
+ <para><literal>send</literal>。允许用户向相应地址发送消息。</para>
</listitem>
<listitem>
- <para><literal>consume</literal>. This permission allows the user to consume a
- message from a queue bound to matching addresses.</para>
+ <para><literal>consume</literal>。允许用户从相应地址上的队列接收消息。</para>
</listitem>
<listitem>
- <para><literal>manage</literal>. This permission allows the user to invoke
- management operations by sending management messages to the management
- address.</para>
+ <para><literal>manage</literal>。允许用户调用管理操作,即向管理地址发关管理消息。</para>
</listitem>
</itemizedlist>
- <para>For each permission, a list of roles who are granted that permission is specified. If
- the user has any of those roles, he/she will be granted that permission for that set of
- addresses.</para>
- <para>Let's take a simple example, here's a security block from <literal
- >hornetq-configuration.xml</literal> or <literal>hornetq-queues.xml</literal>
- file:</para>
+ <para>每个权限有一个角色表。如果用户的角色在这个表中,那么它将拥有这个权限。</para>
+ <para>让我们看个简单的例子。下面是从<literal>hornetq-configuration.xml</literal>文件或
+ <literal>hornetq-queues.xml</literal>文件中提取的安全设置:</para>
<programlisting>
<security-setting match="globalqueues.europe.#">
<permission type="createDurableQueue" roles="admin"/>
@@ -84,69 +67,50 @@
<permission type="consume" roles="admin, europe-users"/>
</security-setting>
</programlisting>
- <para>The '<literal>#</literal>' character signifies "any sequence of words". Words are
- delimited by the '<literal>.</literal>' character. For a full description of the
- wildcard syntax please see <xref linkend="wildcard-syntax"/>. The above security block
- applies to any address that starts with the string "globalqueues.europe.":</para>
- <para>Only users who have the <literal>admin</literal> role can create or delete durable
- queues bound to an address that starts with the string "globalqueues.europe."</para>
- <para>Only users who have the <literal>admin</literal> role can create or delete durable
- queues bound to an address that starts with the string "globalqueues.europe."</para>
- <para>Any users with the roles <literal>admin</literal>, <literal>guest</literal>, or
- <literal>europe-users</literal> can create or delete temporary queues bound to an
- address that starts with the string "globalqueues.europe."</para>
- <para>Any users with the roles <literal>admin</literal> or <literal>europe-users</literal>
- can send messages to these addresses or consume messages from queues bound to an address
- that starts with the string "globalqueues.europe."</para>
- <para>The mapping between a user and what roles they have is handled by the security
- manager. HornetQ ships with a user manager that reads user credentials from a file on
- disk, and can also plug into JAAS or JBoss Application Server security.</para>
- <para>For more information on configuring the security manager, please see <xref
- linkend="change-security-manager"/>.</para>
- <para>There can be zero or more <literal>security-setting</literal> elements in each xml
- file. Where more than one match applies to a set of addresses the <emphasis>more
- specific</emphasis> match takes precedence.</para>
- <para>Let's look at an example of that, here's another <literal>security-setting</literal>
- block:</para>
+ <para>在配置中字符'<literal>#</literal>'代表"任何单词序列“。单词由'<literal>.</literal>'字符分隔。
+ 有关通配符的语法的完整说明请参见<xref linkend="wildcard-syntax"/>。上面的安全配置对以
+ "globalqueues.europe."开始的地址有效:</para>
+ <para>只有具有<literal>admin</literal>角色的用户才可以创建和删除绑定到以"globalqueues.europe."开始的地址的持久化队列。</para>
+ <para>具有<literal>admin</literal>、<literal>guest</literal>或<literal>europe-users</literal>
+ 角色的用户可以在以开头的地址上创建临时的队列。</para>
+ <para>任何具有<literal>admin</literal>或<literal>europe-users</literal>角色的用户可以向以"globalqueues.europe."开头的地址
+ 发送消息,并从绑定到相同地址上的队列接收消息。</para>
+ <para>安全管理器处理一个用户和它的角色的对应关系。HornetQ本身自带一个用户管理器,能从文件中读取用户的身份信息。
+ 另外HornetQ还可以使用JAAS或JBoss应用服务器的安全管理机制。</para>
+ <para>有关安全管理器的配置信息,请参见<xref linkend="change-security-manager"/>。</para>
+ <para>在每个xml文件中可以有零个或多个 <literal>security-setting</literal>。当一组地址有多个这样的设置时,
+ HornetQ总是选取<emphasis>更具体的</emphasis>匹配。</para>
+ <para>让我们来看一个实例,下面是另一个<literal>security-setting</literal>:</para>
<programlisting>
<security-setting match="globalqueues.europe.orders.#">
<permission type="send" roles="europe-users"/>
<permission type="consume" roles="europe-users"/>
</security-setting>
</programlisting>
- <para>In this <literal>security-setting</literal> block the match
- 'globalqueues.europe.orders.#' is more specific than the previous match
- 'globalqueues.europe.#'. So any addresses which match 'globalqueues.europe.orders.#'
- will take their security settings <emphasis>only</emphasis> from the latter
- security-setting block.</para>
- <para>Note that settings are not inherited from the former block. All the settings will be
- taken from the more specific matching block, so for the address
- 'globalqueues.europe.orders.plastics' the only permissions that exist are <literal
- >send</literal> and <literal>consume</literal> for the role europe-users. The
- permissions <literal>createDurableQueue</literal>, <literal
- >deleteDurableQueue</literal>, <literal>createTempQueue</literal>, <literal
- >deleteTempQueue</literal> are not inherited from the other security-setting
- block.</para>
- <para>By not inheriting permissions, it allows you to effectively deny permissions in more
- specific security-setting blocks by simply not specifying them. Otherwise it would not
- be possible to deny permissions in sub-groups of addresses.</para>
+ <para>在这个<literal>security-setting</literal>块中,字符串
+ 'globalqueues.europe.orders.#' 要比它之前的字符串'globalqueues.europe.#'更具体。
+ 因此当一个地址与'globalqueues.europe.orders.#'匹配时,它<emphasis>只</emphasis>选择这个安全配置。</para>
+ <para>注意安全设置没有继承性。对于像'globalqueues.europe.orders.plastics'的地址,只要上面的设置
+ 能被采用。即角色europe-users有<literal
+ >send</literal>和<literal>consume</literal>权限。权限
+ <literal>createDurableQueue</literal>、 <literal
+ >deleteDurableQueue</literal>、<literal>createTempQueue</literal>、<literal
+ >deleteTempQueue</literal>不会从先前的设置中继承。</para>
+ <para>由于权限的不可继承,如果我们不在更具体的security-setting设置中给出一个权限,这个权限就是没有的,不会因为继承而带来
+ 麻烦。否则就不可能对一组地址中的部分地址进行如此的设置。</para>
</section>
<section>
- <title>Secure Sockets Layer (SSL) Transport</title>
- <para>When messaging clients are connected to servers, or servers are connected to other
- servers (e.g. via bridges) over an untrusted network then HornetQ allows that traffic to
- be encrypted using the Secure Sockets Layer (SSL) transport.</para>
- <para>For more information on configuring the SSL transport, please see <xref
- linkend="configuring-transports"/>.</para>
+ <title>安全套接字层(SSL)传输</title>
+ <para>当消息客户端与服务器端,或服务器之间(比如使用桥的情况)通过一个不信任的网络相互通信时,HornetQ
+ 支持使用加密的安全套接字(SSL)传输数据。</para>
+ <para>关于SSL的详细配置信息,请参见<xref linkend="configuring-transports"/>。</para>
</section>
<section>
- <title>Basic user credentials</title>
- <para>HornetQ ships with a security manager implementation that reads user credentials, i.e.
- user names, passwords and role information from an xml file on the classpath called
- <literal>hornetq-users.xml</literal>. This is the default security manager.</para>
- <para>If you wish to use this security manager, then users, passwords and roles can easily
- be added into this file.</para>
- <para>Let's take a look at an example file:</para>
+ <title>基本用户身份信息(Credentials)</title>
+ <para>HornetQ自带一个安全管理器(security manager)可以从xml文件中读取用户身份信息,即用户名、
+ 密码、角色信息。该xml文件名为<literal>hornetq-users.xml</literal>,它必须要在classpath中。</para>
+ <para>如果你要使用这个安全管理器,就将用户名,密码,角色等信息加入到这个文件中。</para>
+ <para>让我们看一个例子:</para>
<programlisting>
<configuration xmlns="urn:hornetq"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
@@ -172,23 +136,21 @@
</configuration>
</programlisting>
- <para>The first thing to note is the element <literal>defaultuser</literal>. This defines
- what user will be assumed when the client does not specify a username/password when
- creating a session. In this case they will be the user <literal>guest</literal> and have
- the role also called <literal>guest</literal>. Multiple roles can be specified for a
- default user.</para>
- <para>We then have three more users, the user <literal>tim</literal> has the role <literal
- >admin</literal>. The user <literal>andy</literal> has the roles <literal
- >admin</literal> and <literal>guest</literal>, and the user <literal>jeff</literal>
- has the roles <literal>europe-users</literal> and <literal>guest</literal>.</para>
+ <para>首先要注意的是<literal>defaultuser</literal>,它定义的是默认的用户。当客户端创建会话时
+ 没有提供用户名/密码时,就会使用这个用户。根据上述配置,这个默认用户是<literal>guest</literal>
+ 并且他的角色是<literal>guest</literal>。一个默认用户可以有多个角色。</para>
+ <para>另外三个用户中,用户<literal>tim</literal>具有角色<literal
+ >admin</literal>。用户<literal>andy</literal>具有角色<literal
+ >admin</literal>和<literal>guest</literal>,用户<literal>jeff</literal>
+ 具有角色<literal>europe-users</literal>和<literal>guest</literal>。</para>
</section>
<section id="change-security-manager">
- <title>Changing the security manager</title>
- <para>If you do not want to use the default security manager then you can specify a
- different one by editing the file <literal>hornetq-beans.xml</literal> (or <literal
- >hornetq-jboss-beans.xml</literal> if you're running JBoss Application Server) and
- changing the class for the <literal>HornetQSecurityManager</literal> bean.</para>
- <para>Let's take a look at a snippet from the default beans file:</para>
+ <title>更换安全管理器</title>
+ <para>如果你不想用默认的安全管理器,可以通过修改配置文件<literal>hornetq-beans.xml</literal>
+ (或者在运行JBoss应用服务器情况下<literal
+ >hornetq-jboss-beans.xml</literal>文件)来更换。同时要更换
+ <literal>HornetQSecurityManager</literal> bean 的类。</para>
+ <para>让我们看一段默认bean文件的内容:</para>
<programlisting>
<bean name="HornetQSecurityManager"
class="org.hornetq.spi.core.security.HornetQSecurityManagerImpl">
@@ -196,25 +158,21 @@
<stop ignored="true"/>
</bean>
</programlisting>
- <para>The class <literal>org.hornetq.spi.core.security.HornetQSecurityManagerImpl</literal>
- is the default security manager that is used by the standalone server.</para>
- <para>HornetQ ships with two other security manager implementations you can use
- off-the-shelf; one a JAAS security manager and another for integrating with JBoss
- Application Sever security, alternatively you could write your own implementation by
- implementing the <literal>org.hornetq.core.security.SecurityManager</literal> interface,
- and specifying the classname of your implementation in the file <literal
- >hornetq-beans.xml</literal> (or <literal>hornetq-jboss-beans.xml</literal> if
- you're running JBoss Application Server).</para>
- <para>These two implementations are discussed in the next two sections.</para>
+ <para><literal>org.hornetq.spi.core.security.HornetQSecurityManagerImpl</literal>
+ 类就是HornetQ服务器的在独立运行时的默认的安全管理器。</para>
+ <para>HornetQ自带有另外两个安全管理器可供使用。一个是JAAS安全管理器,另一个是用来与JBoss应用服务
+ 器集成的安全管理器。此外,你还可以编写实现你自己的安全管理器。首先要实现
+ <literal>org.hornetq.core.security.SecurityManager</literal>接口,再将你的实现
+ 类定义到<literal>hornetq-beans.xml</literal>文件中即可(或者在JBoss应用服务器中
+ 使用<literal>hornetq-jboss-beans.xml</literal>文件)。</para>
+ <para>以下分别介绍这两咱安全管理器</para>
</section>
<section>
- <title>JAAS Security Manager</title>
- <para>JAAS stands for 'Java Authentication and Authorization Service' and is a standard part
- of the Java platform. It provides a common API for security authentication and
- authorization, allowing you to plugin your pre-built implementations.</para>
- <para>To configure the JAAS security manager to work with your pre-built JAAS infrastructure
- you need to specify the security manager as a <literal>JAASSecurityManager</literal> in
- the beans file. Here's an example:</para>
+ <title>JAAS安全管理器</title>
+ <para>JAAS表示“Java认证与授权服务“。它是Java平台标准的一部分。它提供了进行安全认证与授权的通用接口。
+ 它允许你插入自己的安全管理模块。</para>
+ <para>要配置使用你自己的JAAS安全实现,需要在bean文件中定义<literal>JAASSecurityManager</literal>。
+ 下面是一个例子:</para>
<programlisting><![CDATA[
<bean name="HornetQSecurityManager"
class="org.hornetq.integration.jboss.security.JAASSecurityManager">
@@ -230,43 +188,36 @@
</property>
</bean>
]]></programlisting>
- <para>Note that you need to feed the JAAS security manager with three properties:</para>
+ <para>注意你需要为JAAS安全管理器提供三个参数:</para>
<itemizedlist>
<listitem>
- <para>ConfigurationName: the name of the <literal>LoginModule</literal>
- implementation that JAAS must use</para>
+ <para>ConfigurationName: <literal>LoginModule</literal>的名字。
</listitem>
<listitem>
- <para>Configuration: the <literal>Configuration</literal> implementation used by
- JAAS</para>
+ <para>Configuration: <literal>Configuration</literal>的实现。</para>
</listitem>
<listitem>
- <para>CallbackHandler: the <literal>CallbackHandler</literal> implementation to use
- if user interaction are required</para>
+ <para>CallbackHandler: <literal>CallbackHandler</literal>实现,用于用户交互。</para>
</listitem>
</itemizedlist>
<section>
- <title>Example</title>
- <para>See <xref linkend="examples.jaas"/> for an example which shows how HornetQ can be
- configured to use JAAS.</para>
+ <title>例子</title>
+ <para>参见<xref linkend="examples.jaas"/>。这个例子展示了怎样在HornetQ中配置使用JAAS。</para>
</section>
</section>
<section>
- <title>JBoss AS Security Manager</title>
- <para>The JBoss AS security manager is used when running HornetQ inside the JBoss
- Application server. This allows tight integration with the JBoss Application Server's
- security model.</para>
- <para>The class name of this security manager is <literal
- >org.hornetq.integration.jboss.security.JBossASSecurityManager</literal></para>
- <para>Take a look at one of the default <literal>hornetq-jboss-beans.xml</literal> files for
- JBoss Application Server that are bundled in the distribution for an example of how this
- is configured.</para>
+ <title>JBoss 应用服务器安全管理器</title>
+ <para>JBoss 应用服务器安全管理器适用于当HornetQ运行于JBoss应用服务器内时。它可以与JBoss应用服务器
+ 的安全模型紧密集成。</para>
+ <para>此安全管理器的类是 <literal
+ >org.hornetq.integration.jboss.security.JBossASSecurityManager</literal>。</para>
+ <para>要了解如何配置JBoss安全管理器,可以看一眼HornetQ发布包中相关例子中的
+ <literal>hornetq-jboss-beans.xml</literal>文件。</para>
</section>
<section>
- <title>Changing the username/password for clustering</title>
- <para>In order for cluster connections to work correctly, each node in the cluster must make
- connections to the other nodes. The username/password they use for this should always be
- changed from the installation default to prevent a security risk.</para>
- <para>Please see <xref linkend="management"/> for instructions on how to do this.</para>
+ <title>集群用户名/密码的配置</title>
+ <para>为了使集群连接正常工作,每个节点都必须与其它节点相连接。它们连接所使用的默认用户名和密码在正式使用时
+ 一定要做相应的更改,以防止安全隐患。</para>
+ <para>请参见<xref linkend="management"/>了解怎样去做。</para>
</section>
</chapter>
15 years, 8 months
JBoss hornetq SVN: r9135 - trunk/tests/src/org/hornetq/tests/integration/cluster/failover.
by do-not-reply@jboss.org
Author: timfox
Date: 2010-04-16 05:30:02 -0400 (Fri, 16 Apr 2010)
New Revision: 9135
Modified:
trunk/tests/src/org/hornetq/tests/integration/cluster/failover/AsynchronousFailoverTest.java
Log:
tweak to test
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-16 05:53:35 UTC (rev 9134)
+++ trunk/tests/src/org/hornetq/tests/integration/cluster/failover/AsynchronousFailoverTest.java 2010-04-16 09:30:02 UTC (rev 9135)
@@ -415,8 +415,26 @@
}
}
- ClientConsumer consumer = session.createConsumer(FailoverTestBase.ADDRESS);
-
+ ClientConsumer consumer = null;
+
+ while (true)
+ {
+ try
+ {
+ consumer = session.createConsumer(FailoverTestBase.ADDRESS);
+
+ break;
+ }
+ catch (HornetQException e)
+ {
+ if (e.getCode() == HornetQException.UNBLOCKED)
+ {
+ continue;
+ }
+ throw e;
+ }
+ }
+
session.start();
int lastCount = -1;
15 years, 8 months
JBoss hornetq SVN: r9134 - tags.
by do-not-reply@jboss.org
Author: clebert.suconic(a)jboss.com
Date: 2010-04-16 01:53:35 -0400 (Fri, 16 Apr 2010)
New Revision: 9134
Added:
tags/HornetQ_2_1_0_Beta2/
Log:
2.1.0 Beta2 release
Copied: tags/HornetQ_2_1_0_Beta2 (from rev 9133, trunk)
15 years, 8 months
JBoss hornetq SVN: r9133 - trunk/docs.
by do-not-reply@jboss.org
Author: clebert.suconic(a)jboss.com
Date: 2010-04-16 01:40:43 -0400 (Fri, 16 Apr 2010)
New Revision: 9133
Modified:
trunk/docs/README.html
Log:
Changing on README for the version
Modified: trunk/docs/README.html
===================================================================
--- trunk/docs/README.html 2010-04-16 05:37:00 UTC (rev 9132)
+++ trunk/docs/README.html 2010-04-16 05:40:43 UTC (rev 9133)
@@ -3,20 +3,20 @@
<head>
<meta content="text/html; charset=ISO-8859-1"
http-equiv="content-type">
- <title>HornetQ 2.1.0 BETA1 Release Notes</title>
+ <title>HornetQ 2.1.0 BETA2 Release Notes</title>
</head>
<body>
-<h1>Release Notes - HornetQ - Version 2.1.0 BETA1</h1>
+<h1>Release Notes - HornetQ - Version 2.1.0 BETA2</h1>
<br>
-<h2>1st April 2010</h2>
+<h2>16th April 2010</h2>
-These are the release notes for HornetQ 2.1.0 BETA1<br><br>
+These are the release notes for HornetQ 2.1.0 BETA2<br><br>
For full description of the contents please see the
-<a href="https://jira.jboss.org/jira/secure/ReleaseNote.jspa?version=12313894&styl...">HornetQ project JIRA</a>.<br><br>
+<a href="https://jira.jboss.org/jira/secure/ReleaseNote.jspa?version=12314776&styl...">HornetQ project JIRA</a>.<br><br>
This release is a feature complete release for forthcoming HornetQ 2.1.0<br>
15 years, 8 months
JBoss hornetq SVN: r9132 - trunk/src/config/common.
by do-not-reply@jboss.org
Author: clebert.suconic(a)jboss.com
Date: 2010-04-16 01:37:00 -0400 (Fri, 16 Apr 2010)
New Revision: 9132
Modified:
trunk/src/config/common/hornetq-version.properties
Log:
Version change
Modified: trunk/src/config/common/hornetq-version.properties
===================================================================
--- trunk/src/config/common/hornetq-version.properties 2010-04-16 04:13:49 UTC (rev 9131)
+++ trunk/src/config/common/hornetq-version.properties 2010-04-16 05:37:00 UTC (rev 9132)
@@ -1,8 +1,8 @@
-hornetq.version.versionName=Horny Hornet
+hornetq.version.versionName=Blue Belt Hornet
hornetq.version.majorVersion=2
hornetq.version.minorVersion=1
hornetq.version.microVersion=0
-hornetq.version.incrementingVersion=115
-hornetq.version.versionSuffix=BETA1
-hornetq.version.versionTag=BETA1
+hornetq.version.incrementingVersion=116
+hornetq.version.versionSuffix=BETA2
+hornetq.version.versionTag=BETA2
hornetq.netty.version=(a)NETTY.VERSION@
15 years, 8 months