[jboss-cvs] JBoss Messaging SVN: r1843 - in trunk: . docs/examples/common/src/org/jboss/example/jms/common docs/examples/common/src/org/jboss/example/jms/common/bean docs/examples/distributed-topic/src/org/jboss/example/jms/distributedtopic docs/examples/ejb3mdb docs/examples/ejb3mdb/src/org/jboss/example/jms/ejb3mdb docs/examples/http/src/org/jboss/example/jms/http docs/examples/mdb/src/org/jboss/example/jms/mdb docs/examples/queue/src/org/jboss/example/jms/queue docs/examples/queue-failover/src/org/jboss/example/jms/failover docs/examples/secure-socket/src/org/jboss/example/jms/securesocket docs/examples/stateless/src/org/jboss/example/jms/stateless/bean docs/examples/stateless/src/org/jboss/example/jms/stateless/client docs/examples/topic/src/org/jboss/example/jms/topic lib lib/jbossts src/etc/server/default/deploy src/main/org/jboss/jms src/main/org/jboss/jms/client/container src/main/org/jboss/jms/client/remoting src/main/org/jboss/jms/client/state src/main/org/jboss/jms/! recovery src/main/org/jboss/jms/server src/main/org/jboss/jms/server/endpoint src/main/org/jboss/jms/tx src/main/org/jboss/messaging/core src/main/org/jboss/messaging/core/memory src/main/org/jboss/messaging/core/plugin src/main/org/jboss/messaging/core/plugin/contract src/main/org/jboss/messaging/core/plugin/postoffice src/main/org/jboss/messaging/core/plugin/postoffice/cluster src/main/org/jboss/messaging/core/tx tests tests/smoke tests/src/org/jboss/test/messaging tests/src/org/jboss/test/messaging/core tests/src/org/jboss/test/messaging/core/local/base tests/src/org/jboss/test/messaging/core/paging tests/src/org/jboss/test/messaging/core/paging/base tests/src/org/jboss/test/messaging/core/plugin tests/src/org/jboss/test/messaging/core/plugin/base tests/src/org/jboss/test/messaging/core/plugin/postoffice tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster tests/src/org/jboss/test/messaging/jms tests/src/org/jboss/test/messaging/jms/clustering tests/src/org/! jboss/test/messaging/jms/message tests/src/org/jboss/test/messaging/jms/stress tests/src/org/jboss/test/messaging/util util
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Thu Dec 21 18:42:29 EST 2006
Author: timfox
Date: 2006-12-21 18:41:19 -0500 (Thu, 21 Dec 2006)
New Revision: 1843
Added:
trunk/lib/jbossts/
trunk/lib/jbossts/jboss-service.xml
trunk/lib/jbossts/jbossjta-properties.xml
trunk/src/main/org/jboss/jms/recovery/
trunk/src/main/org/jboss/jms/recovery/JMSProviderXAResourceRecovery.java
trunk/src/main/org/jboss/jms/recovery/MessagingXAResourceRecovery.java
trunk/src/main/org/jboss/messaging/core/tx/PreparedTxInfo.java
trunk/tests/src/org/jboss/test/messaging/jms/stress/ConcurrentCloseStressTest.java
trunk/tests/src/org/jboss/test/messaging/util/TransactionManagerLocator.java
Removed:
trunk/lib/jbossts/jboss-service.xml
trunk/lib/jbossts/jbossjta-properties.xml
trunk/src/main/org/jboss/jms/recovery/JMSProviderXAResourceRecovery.java
trunk/src/main/org/jboss/jms/recovery/MessagingXAResourceRecovery.java
trunk/src/main/org/jboss/jms/tx/JMSRecoverable.java
Modified:
trunk/.classpath
trunk/build-messaging.xml
trunk/build-thirdparty.xml
trunk/docs/examples/common/src/org/jboss/example/jms/common/ExampleSupport.java
trunk/docs/examples/common/src/org/jboss/example/jms/common/Util.java
trunk/docs/examples/common/src/org/jboss/example/jms/common/bean/Management.java
trunk/docs/examples/common/src/org/jboss/example/jms/common/bean/ManagementBean.java
trunk/docs/examples/common/src/org/jboss/example/jms/common/bean/ManagementHome.java
trunk/docs/examples/distributed-topic/src/org/jboss/example/jms/distributedtopic/DistributedTopicExample.java
trunk/docs/examples/distributed-topic/src/org/jboss/example/jms/distributedtopic/ExampleListener.java
trunk/docs/examples/ejb3mdb/do-not-distribute.properties
trunk/docs/examples/ejb3mdb/src/org/jboss/example/jms/ejb3mdb/EJB3MDBExample.java
trunk/docs/examples/http/src/org/jboss/example/jms/http/HttpExample.java
trunk/docs/examples/mdb/src/org/jboss/example/jms/mdb/MDBExample.java
trunk/docs/examples/mdb/src/org/jboss/example/jms/mdb/Sender.java
trunk/docs/examples/queue-failover/src/org/jboss/example/jms/failover/QueueFailoverExample.java
trunk/docs/examples/queue/src/org/jboss/example/jms/queue/QueueExample.java
trunk/docs/examples/secure-socket/src/org/jboss/example/jms/securesocket/SecureSocketExample.java
trunk/docs/examples/stateless/src/org/jboss/example/jms/stateless/bean/StatelessSessionExample.java
trunk/docs/examples/stateless/src/org/jboss/example/jms/stateless/bean/StatelessSessionExampleBean.java
trunk/docs/examples/stateless/src/org/jboss/example/jms/stateless/bean/StatelessSessionExampleHome.java
trunk/docs/examples/stateless/src/org/jboss/example/jms/stateless/client/Client.java
trunk/docs/examples/topic/src/org/jboss/example/jms/topic/ExampleListener.java
trunk/docs/examples/topic/src/org/jboss/example/jms/topic/TopicExample.java
trunk/src/etc/server/default/deploy/clustered-mysql-persistence-service.xml
trunk/src/etc/server/default/deploy/mysql-persistence-service.xml
trunk/src/main/org/jboss/jms/client/container/ConnectionAspect.java
trunk/src/main/org/jboss/jms/client/container/ExceptionInterceptor.java
trunk/src/main/org/jboss/jms/client/container/HAAspect.java
trunk/src/main/org/jboss/jms/client/container/SessionAspect.java
trunk/src/main/org/jboss/jms/client/remoting/MessageCallbackHandler.java
trunk/src/main/org/jboss/jms/client/state/ConnectionState.java
trunk/src/main/org/jboss/jms/server/ServerPeer.java
trunk/src/main/org/jboss/jms/server/endpoint/ServerConnectionEndpoint.java
trunk/src/main/org/jboss/jms/server/endpoint/ServerConsumerEndpoint.java
trunk/src/main/org/jboss/jms/server/endpoint/ServerSessionEndpoint.java
trunk/src/main/org/jboss/jms/tx/ClientTransaction.java
trunk/src/main/org/jboss/jms/tx/MessagingXAResource.java
trunk/src/main/org/jboss/jms/tx/ResourceManager.java
trunk/src/main/org/jboss/jms/tx/TransactionRequest.java
trunk/src/main/org/jboss/messaging/core/Channel.java
trunk/src/main/org/jboss/messaging/core/ChannelSupport.java
trunk/src/main/org/jboss/messaging/core/PagingChannelSupport.java
trunk/src/main/org/jboss/messaging/core/memory/SimpleMemoryManager.java
trunk/src/main/org/jboss/messaging/core/plugin/JDBCPersistenceManager.java
trunk/src/main/org/jboss/messaging/core/plugin/contract/ClusteredPostOffice.java
trunk/src/main/org/jboss/messaging/core/plugin/contract/PersistenceManager.java
trunk/src/main/org/jboss/messaging/core/plugin/contract/PostOffice.java
trunk/src/main/org/jboss/messaging/core/plugin/postoffice/DefaultPostOffice.java
trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/DefaultClusteredPostOffice.java
trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/RemoteQueueStub.java
trunk/src/main/org/jboss/messaging/core/tx/Transaction.java
trunk/src/main/org/jboss/messaging/core/tx/TransactionRepository.java
trunk/src/main/org/jboss/messaging/core/tx/XidImpl.java
trunk/tests/build.xml
trunk/tests/smoke/build.xml
trunk/tests/src/org/jboss/test/messaging/MessagingTestCase.java
trunk/tests/src/org/jboss/test/messaging/core/SimpleChannel.java
trunk/tests/src/org/jboss/test/messaging/core/SimpleDeliveryTest.java
trunk/tests/src/org/jboss/test/messaging/core/local/base/PagingFilteredQueueTestBase.java
trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_NP_2PCTest.java
trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_NP_NTTest.java
trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_NP_TTest.java
trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_P_2PCTest.java
trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_P_NTTest.java
trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_P_TTest.java
trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_ReloadTest.java
trunk/tests/src/org/jboss/test/messaging/core/paging/base/PagingStateTestBase.java
trunk/tests/src/org/jboss/test/messaging/core/plugin/JDBCPersistenceManagerTest.java
trunk/tests/src/org/jboss/test/messaging/core/plugin/base/PostOfficeTestBase.java
trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/DefaultPostOfficeTest.java
trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/DefaultMessagePullPolicyTest.java
trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/DefaultRouterTest.java
trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/RedistributionWithDefaultMessagePullPolicyTest.java
trunk/tests/src/org/jboss/test/messaging/jms/ConnectionTest.java
trunk/tests/src/org/jboss/test/messaging/jms/JMSTest.java
trunk/tests/src/org/jboss/test/messaging/jms/ManifestTest.java
trunk/tests/src/org/jboss/test/messaging/jms/MessageConsumerTest.java
trunk/tests/src/org/jboss/test/messaging/jms/XARecoveryTest.java
trunk/tests/src/org/jboss/test/messaging/jms/XATest.java
trunk/tests/src/org/jboss/test/messaging/jms/clustering/HATest.java
trunk/tests/src/org/jboss/test/messaging/jms/message/ObjectMessageDeliveryTest.java
trunk/util/do-not-distribute.properties
trunk/util/release-admin.xml
Log:
Merged XARecovery functionality into TRUNK, and reformatted examples
Modified: trunk/.classpath
===================================================================
--- trunk/.classpath 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/.classpath 2006-12-21 23:41:19 UTC (rev 1843)
@@ -1,6 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="output/gen-parsers"/>
+ <classpathentry kind="src" path="docs/examples/queue-failover/src"/>
+ <classpathentry kind="src" path="docs/examples/common/src"/>
+ <classpathentry kind="src" path="docs/examples/distributed-topic/src"/>
+ <classpathentry kind="src" path="docs/examples/ejb3mdb/src"/>
+ <classpathentry kind="src" path="docs/examples/http/src"/>
+ <classpathentry kind="src" path="docs/examples/mdb/src"/>
+ <classpathentry kind="src" path="docs/examples/queue/src"/>
+ <classpathentry kind="src" path="docs/examples/secure-socket/src"/>
+ <classpathentry kind="src" path="docs/examples/stateless/src"/>
+ <classpathentry kind="src" path="docs/examples/topic/src"/>
<classpathentry excluding="**/.svn/**/*" kind="src" path="src/main"/>
<classpathentry excluding="**/.svn/**/*" kind="src" path="tests/src"/>
<classpathentry kind="lib" path="lib/jboss.jar"/>
@@ -50,5 +60,7 @@
<classpathentry kind="lib" path="thirdparty/jboss/common-logging-log4j/lib/jboss-logging-log4j.jar"/>
<classpathentry kind="lib" path="thirdparty/jboss/common-logging-spi/lib/jboss-logging-spi.jar"/>
<classpathentry kind="lib" path="thirdparty/jboss/common-core/lib/jboss-common-core.jar"/>
+ <classpathentry kind="lib" path="thirdparty/jboss/jbossts/lib/jbossjta.jar"/>
+ <classpathentry kind="var" path="ANT_HOME/lib/ant.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>
Modified: trunk/build-messaging.xml
===================================================================
--- trunk/build-messaging.xml 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/build-messaging.xml 2006-12-21 23:41:19 UTC (rev 1843)
@@ -139,6 +139,7 @@
<path refid="javassist.classpath"/>
<path refid="jgroups.jgroups.classpath"/>
<path refid="trove.trove.classpath"/>
+ <path refid="apache.logging.classpath"/>
</path>
<!--
@@ -155,6 +156,7 @@
<path refid="jboss.aop.classpath"/>
<path refid="jboss.remoting.classpath"/>
<path refid="jboss.serialization.classpath"/>
+ <path refid="jboss.jbossts.classpath"/>
</path>
<!--
@@ -193,6 +195,13 @@
<pathelement location="${project.root}/lib/jboss-jmx.jar"/>
</path>
+ <!--
+ This is for compiling the JBossAS JBossTS driven JMS recovery code which uses XAResourceWrapper implementation
+ -->
+ <path id="jboss.classpath">
+ <pathelement location="${project.root}/lib/jboss.jar"/>
+ </path>
+
<property name="jboss.server.lib" value="${project.root}/lib/"/>
<property name="jboss.naming.lib" value="${project.root}/lib/"/>
@@ -206,6 +215,7 @@
<path refid="jboss.jmx.classpath"/>
<path refid="jboss.remoting.classpath"/>
<path refid="jboss.serialization.classpath"/>
+ <path refid="jboss.classpath"/>
</path>
<!--
@@ -400,13 +410,20 @@
<mkdir dir="${build.lib}"/>
<jar jarfile="${build.lib}/jboss-${module.name}.jar" manifest="${build.etc}/default.mf">
- <fileset dir="${build.classes}" includes="**"/>
+ <fileset dir="${build.classes}" includes="**" excludes="org/jboss/jms/recovery/*.class"/>
<fileset dir="${build.jar}">
<exclude name="*-service.xml"/>
<exclude name="*-ds.xml"/>
<exclude name="messaging-*.properties"/>
</fileset>
</jar>
+
+ <!-- JBossTS integration layer for XA recovery -->
+
+ <jar jarfile="${build.lib}/jboss-${module.name}-integration.jar" manifest="${build.etc}/default.mf">
+ <fileset dir="${build.classes}" includes="org/jboss/jms/recovery/*.class"/>
+ </jar>
+
</target>
<target name="scoped-sar" depends="compile, jar, scoped-sar-structure, extract-server-dependencies">
@@ -491,6 +508,7 @@
I also need org.jboss.util.stream.*
-->
<unjar dest="${build.scoped-sar}/tmp" src="${jboss.common.core.lib}/jboss-common-core.jar">
+
<patternset>
<include name="org/jboss/util/stream/**"/>
</patternset>
Modified: trunk/build-thirdparty.xml
===================================================================
--- trunk/build-thirdparty.xml 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/build-thirdparty.xml 2006-12-21 23:41:19 UTC (rev 1843)
@@ -93,6 +93,7 @@
<componentref name="jboss/aop" version="1.5.0.GA"/>
<componentref name="jboss/serialization" version="1.0.3.GA"/>
<componentref name="jboss/remoting" version="2.2.0.Alpha4"/>
+ <componentref name="jboss/jbossts" version="4.2.2.GA"/>
<!-- Need this otherwise project doesn't build in Eclipse -->
<componentref name="apache-logging" version="1.0.4.1jboss"/>
Modified: trunk/docs/examples/common/src/org/jboss/example/jms/common/ExampleSupport.java
===================================================================
--- trunk/docs/examples/common/src/org/jboss/example/jms/common/ExampleSupport.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/docs/examples/common/src/org/jboss/example/jms/common/ExampleSupport.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -6,16 +6,16 @@
*/
package org.jboss.example.jms.common;
+import javax.jms.Connection;
+import javax.jms.ConnectionMetaData;
+import javax.naming.InitialContext;
+
+import org.jboss.example.jms.common.bean.Management;
+import org.jboss.example.jms.common.bean.ManagementHome;
import org.jboss.jms.client.JBossConnection;
import org.jboss.jms.client.delegate.DelegateSupport;
import org.jboss.jms.client.state.ConnectionState;
-import org.jboss.example.jms.common.bean.ManagementHome;
-import org.jboss.example.jms.common.bean.Management;
-import javax.jms.ConnectionMetaData;
-import javax.jms.Connection;
-import javax.naming.InitialContext;
-
/**
* @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
* @version <tt>$Revision$</tt>
@@ -23,74 +23,74 @@
* $Id$
*/
public abstract class ExampleSupport
- {
+{
// Constants -----------------------------------------------------
-
+
public static final String DEFAULT_QUEUE_NAME = "testQueue";
public static final String DEFAULT_TOPIC_NAME = "testTopic";
-
+
// Static --------------------------------------------------------
-
+
public static int getServerID(Connection conn) throws Exception
{
if (!(conn instanceof JBossConnection))
{
throw new Exception("Connection not an instance of JBossConnection");
}
-
+
JBossConnection jbconn = (JBossConnection)conn;
-
+
DelegateSupport del = (DelegateSupport)jbconn.getDelegate();
-
+
ConnectionState state = (ConnectionState)del.getState();
-
+
return state.getServerID();
}
-
+
public static void assertEquals(Object o, Object o2)
{
- if (o == null && o2 == null)
- {
- return;
- }
-
- if (o.equals(o2))
- {
- return;
- }
-
- throw new RuntimeException("Assertion failed, " + o + " != " + o2);
+ if (o == null && o2 == null)
+ {
+ return;
+ }
+
+ if (o.equals(o2))
+ {
+ return;
+ }
+
+ throw new RuntimeException("Assertion failed, " + o + " != " + o2);
}
-
+
public static void assertEquals(int i, int i2)
{
- if (i == i2)
- {
- return;
- }
-
- throw new RuntimeException("Assertion failed, " + i + " != " + i2);
+ if (i == i2)
+ {
+ return;
+ }
+
+ throw new RuntimeException("Assertion failed, " + i + " != " + i2);
}
-
+
public static void assertNotEquals(int i, int i2)
{
- if (i != i2)
- {
- return;
- }
-
- throw new RuntimeException("Assertion failed, " + i + " == " + i2);
+ if (i != i2)
+ {
+ return;
+ }
+
+ throw new RuntimeException("Assertion failed, " + i + " == " + i2);
}
-
-
+
+
public static void killActiveNode() throws Exception
{
// Currently it will always kill the primary node, ignoring nodeID
-
+
try
{
InitialContext ic = new InitialContext();
-
+
ManagementHome home = (ManagementHome)ic.lookup("ejb/Management");
Management bean = home.create();
bean.killAS();
@@ -98,39 +98,37 @@
catch(Exception e)
{
// OK, I expect exceptions following a VM kill
-
- //e.printStackTrace();
}
}
-
-
+
+
// Attributes ----------------------------------------------------
-
+
private boolean failure;
private boolean deployed;
private String jndiDestinationName;
-
+
// Constructors --------------------------------------------------
-
+
protected ExampleSupport()
{
failure = false;
}
-
+
// Public --------------------------------------------------------
-
+
// Package protected ---------------------------------------------
-
+
// Protected -----------------------------------------------------
-
+
protected abstract void example() throws Exception;
protected abstract boolean isQueueExample();
-
+
protected final boolean isTopicExample()
{
return !isQueueExample();
}
-
+
protected void run()
{
try
@@ -144,52 +142,52 @@
t.printStackTrace();
setFailure(true);
}
-
+
reportResultAndExit();
}
-
+
protected void setFailure(boolean b)
{
failure = b;
}
-
+
protected boolean isFailure()
{
return failure;
}
-
+
protected String getDestinationJNDIName()
{
return jndiDestinationName;
}
-
+
protected void log(String s)
{
System.out.println(s);
}
-
+
protected void displayProviderInfo(ConnectionMetaData metaData) throws Exception
{
String info =
- "The example connected to " + metaData.getJMSProviderName() +
- " version " + metaData.getProviderVersion() + " (" +
- metaData.getProviderMajorVersion() + "." + metaData.getProviderMinorVersion() +
- ")";
-
- System.out.println(info);
+ "The example connected to " + metaData.getJMSProviderName() +
+ " version " + metaData.getProviderVersion() + " (" +
+ metaData.getProviderMajorVersion() + "." + metaData.getProviderMinorVersion() +
+ ")";
+
+ System.out.println(info);
}
-
+
// Private -------------------------------------------------------
-
+
protected void setup() throws Exception
{
- setup(null);
+ setup(null);
}
-
+
protected void setup(InitialContext ic) throws Exception
{
String destinationName;
-
+
if (isQueueExample())
{
destinationName = System.getProperty("example.queue.name");
@@ -202,7 +200,7 @@
jndiDestinationName =
"/topic/" + (destinationName == null ? DEFAULT_TOPIC_NAME : destinationName);
}
-
+
if (!Util.doesDestinationExist(jndiDestinationName,ic))
{
System.out.println("Destination " + jndiDestinationName + " does not exist, deploying it");
@@ -210,12 +208,12 @@
deployed = true;
}
}
-
+
protected void tearDown() throws Exception
{
- tearDown(null);
+ tearDown(null);
}
-
+
protected void tearDown(InitialContext ic) throws Exception
{
if (deployed)
@@ -223,7 +221,7 @@
Util.undeployQueue(jndiDestinationName,ic);
}
}
-
+
protected void reportResultAndExit()
{
if (isFailure())
@@ -234,14 +232,14 @@
System.err.println("#####################");
System.exit(1);
}
-
+
System.out.println();
System.out.println("#####################");
System.out.println("### SUCCESS! ###");
System.out.println("#####################");
System.exit(0);
}
-
+
// Inner classes -------------------------------------------------
-
+
}
Modified: trunk/docs/examples/common/src/org/jboss/example/jms/common/Util.java
===================================================================
--- trunk/docs/examples/common/src/org/jboss/example/jms/common/Util.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/docs/examples/common/src/org/jboss/example/jms/common/Util.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -21,10 +21,10 @@
*/
package org.jboss.example.jms.common;
+import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
import javax.naming.InitialContext;
import javax.naming.NameNotFoundException;
-import javax.management.MBeanServerConnection;
-import javax.management.ObjectName;
/**
* @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
Modified: trunk/docs/examples/common/src/org/jboss/example/jms/common/bean/Management.java
===================================================================
--- trunk/docs/examples/common/src/org/jboss/example/jms/common/bean/Management.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/docs/examples/common/src/org/jboss/example/jms/common/bean/Management.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -6,9 +6,10 @@
*/
package org.jboss.example.jms.common.bean;
-import javax.ejb.EJBObject;
import java.rmi.RemoteException;
+import javax.ejb.EJBObject;
+
/**
* @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
* @version <tt>$Revision: 1766 $</tt>
Modified: trunk/docs/examples/common/src/org/jboss/example/jms/common/bean/ManagementBean.java
===================================================================
--- trunk/docs/examples/common/src/org/jboss/example/jms/common/bean/ManagementBean.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/docs/examples/common/src/org/jboss/example/jms/common/bean/ManagementBean.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -6,23 +6,11 @@
*/
package org.jboss.example.jms.common.bean;
+import java.rmi.RemoteException;
+
+import javax.ejb.EJBException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
-import javax.ejb.EJBException;
-import javax.jms.ConnectionFactory;
-import javax.jms.Queue;
-import javax.jms.Session;
-import javax.jms.Connection;
-import javax.jms.MessageConsumer;
-import javax.jms.Message;
-import javax.jms.MessageProducer;
-import javax.jms.TextMessage;
-import javax.jms.QueueBrowser;
-import javax.jms.JMSException;
-import javax.naming.InitialContext;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.rmi.RemoteException;
/**
* @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
@@ -32,8 +20,6 @@
*/
public class ManagementBean implements SessionBean
{
- private SessionContext ctx;
-
public void killAS() throws Exception
{
System.out.println("######");
@@ -51,7 +37,6 @@
public void setSessionContext(SessionContext ctx) throws EJBException, RemoteException
{
- this.ctx = ctx;
}
public void ejbCreate()
Modified: trunk/docs/examples/common/src/org/jboss/example/jms/common/bean/ManagementHome.java
===================================================================
--- trunk/docs/examples/common/src/org/jboss/example/jms/common/bean/ManagementHome.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/docs/examples/common/src/org/jboss/example/jms/common/bean/ManagementHome.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -6,10 +6,11 @@
*/
package org.jboss.example.jms.common.bean;
-import javax.ejb.EJBHome;
-import javax.ejb.CreateException;
import java.rmi.RemoteException;
+import javax.ejb.CreateException;
+import javax.ejb.EJBHome;
+
/**
* @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
* @version <tt>$Revision: 563 $</tt>
Modified: trunk/docs/examples/distributed-topic/src/org/jboss/example/jms/distributedtopic/DistributedTopicExample.java
===================================================================
--- trunk/docs/examples/distributed-topic/src/org/jboss/example/jms/distributedtopic/DistributedTopicExample.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/docs/examples/distributed-topic/src/org/jboss/example/jms/distributedtopic/DistributedTopicExample.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -21,20 +21,18 @@
*/
package org.jboss.example.jms.distributedtopic;
-import javax.naming.InitialContext;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
-import javax.jms.Topic;
-import javax.jms.Session;
-import javax.jms.MessageProducer;
+import javax.jms.JMSException;
import javax.jms.MessageConsumer;
+import javax.jms.MessageProducer;
+import javax.jms.Session;
import javax.jms.TextMessage;
-import javax.jms.JMSException;
+import javax.jms.Topic;
+import javax.naming.InitialContext;
import org.jboss.example.jms.common.ExampleSupport;
-import java.util.Hashtable;
-
/**
* The example sends a message to a distributed topic depolyed on the JMS cluster. The message is
* subsequently received by two different subscribers, connected to two distinct cluster nodes.
@@ -51,13 +49,10 @@
{
public void example() throws Exception
{
-
String destinationName = getDestinationJNDIName();
-
InitialContext ic = null;
-
Connection connection0 = null;
Connection connection1 = null;
@@ -76,7 +71,6 @@
// transparently creating physical connections to different cluster nodes, in a round
// robin fashion ...
-
// ... so this is a connection to a cluster node
connection0 = cf.createConnection();
@@ -86,7 +80,6 @@
// Let's make sure that (this example is also a smoke test)
assertNotEquals(getServerID(connection0), getServerID(connection1));
-
// Create a session, a producer and consumer for the distributed topic, using connection0
Session session0 = connection0.createSession(false, Session.AUTO_ACKNOWLEDGE);
@@ -95,11 +88,9 @@
ExampleListener messageListener0 = new ExampleListener("MessageListener 0");
subscriber0.setMessageListener(messageListener0);
-
MessageProducer publisher = session0.createProducer(distributedTopic);
-
// Create a session and a consumer for the distributed topic, using connection1
Session session1 = connection1.createSession(false, Session.AUTO_ACKNOWLEDGE);
@@ -137,7 +128,7 @@
}
finally
{
- if(ic != null)
+ if (ic != null)
{
try
{
Modified: trunk/docs/examples/distributed-topic/src/org/jboss/example/jms/distributedtopic/ExampleListener.java
===================================================================
--- trunk/docs/examples/distributed-topic/src/org/jboss/example/jms/distributedtopic/ExampleListener.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/docs/examples/distributed-topic/src/org/jboss/example/jms/distributedtopic/ExampleListener.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -6,8 +6,8 @@
*/
package org.jboss.example.jms.distributedtopic;
+import javax.jms.Message;
import javax.jms.MessageListener;
-import javax.jms.Message;
/**
* @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
Modified: trunk/docs/examples/ejb3mdb/do-not-distribute.properties
===================================================================
--- trunk/docs/examples/ejb3mdb/do-not-distribute.properties 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/docs/examples/ejb3mdb/do-not-distribute.properties 2006-12-21 23:41:19 UTC (rev 1843)
@@ -4,5 +4,6 @@
#
messaging.client.jar.path=../../../output/lib
messaging.client.jar.name=jboss-messaging-client.jar
-jboss.configuration=messaging-smoke-test
+jboss.configuration=messaging
jboss.home=C:\\work\\src\\jboss-4.0.5.CR1-src\\build\\output\\jboss-4.0.5.CR1-ejb3
+jboss.home=C:\\work\\src\\jboss-4.0.5.GA-src\\build\\output\\jboss-4.0.5.GA-ejb3
Modified: trunk/docs/examples/ejb3mdb/src/org/jboss/example/jms/ejb3mdb/EJB3MDBExample.java
===================================================================
--- trunk/docs/examples/ejb3mdb/src/org/jboss/example/jms/ejb3mdb/EJB3MDBExample.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/docs/examples/ejb3mdb/src/org/jboss/example/jms/ejb3mdb/EJB3MDBExample.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -30,7 +30,8 @@
@MessageDriven(activationConfig =
{
@ActivationConfigProperty(propertyName="destinationType", propertyValue="javax.jms.Queue"),
- @ActivationConfigProperty(propertyName="destination", propertyValue="queue/testQueue")
+ @ActivationConfigProperty(propertyName="destination", propertyValue="queue/testQueue"),
+ @ActivationConfigProperty(propertyName="DLQMaxResent", propertyValue="10")
})
public class EJB3MDBExample implements MessageListener
{
@@ -39,7 +40,6 @@
businessLogic(m);
}
-
private void businessLogic(Message m)
{
Connection conn = null;
Modified: trunk/docs/examples/http/src/org/jboss/example/jms/http/HttpExample.java
===================================================================
--- trunk/docs/examples/http/src/org/jboss/example/jms/http/HttpExample.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/docs/examples/http/src/org/jboss/example/jms/http/HttpExample.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -1,24 +1,24 @@
/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
package org.jboss.example.jms.http;
import org.jboss.example.jms.common.ExampleSupport;
@@ -50,93 +50,90 @@
*/
public class HttpExample extends ExampleSupport
{
-
+
public void example() throws Exception
{
String destinationName = getDestinationJNDIName();
-
- InitialContext ic = null;
- ConnectionFactory cf = null;
- Connection connection = null;
- Connection connection2 = null;
-
- try
- {
-
- ic = new InitialContext();
-
- cf = (ConnectionFactory)ic.lookup("/HttpConnectionFactory");
- Queue queue = (Queue)ic.lookup(destinationName);
- log("Queue " + destinationName + " exists");
-
- connection = cf.createConnection();
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- MessageProducer sender = session.createProducer(queue);
-
- TextMessage message = session.createTextMessage("Hello!");
- sender.send(message);
- log("The message was successfully sent to the " + queue.getQueueName() + " queue");
-
- connection2 = cf.createConnection();
- Session session2 = connection2.createSession(false, Session.AUTO_ACKNOWLEDGE);
- MessageConsumer consumer = session2.createConsumer(queue);
-
- connection2.start();
-
- message = (TextMessage)consumer.receive(2000);
- log("Received message: " + message.getText());
- assertEquals("Hello!", message.getText());
-
- displayProviderInfo(connection2.getMetaData());
-
- }
- finally
- {
- if(ic != null)
- {
- try
- {
- ic.close();
- }
- catch(Exception e)
- {
- throw e;
- }
- }
-
- //ALWAYS close your connection in a finally block to avoid leaks
- //Closing connection also takes care of closing its related objects e.g. sessions
- closeConnection(connection);
- closeConnection(connection2);
- }
+
+ InitialContext ic = null;
+ ConnectionFactory cf = null;
+ Connection connection = null;
+ Connection connection2 = null;
+
+ try
+ {
+ ic = new InitialContext();
+
+ cf = (ConnectionFactory)ic.lookup("/HttpConnectionFactory");
+ Queue queue = (Queue)ic.lookup(destinationName);
+ log("Queue " + destinationName + " exists");
+
+ connection = cf.createConnection();
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ MessageProducer sender = session.createProducer(queue);
+
+ TextMessage message = session.createTextMessage("Hello!");
+ sender.send(message);
+ log("The message was successfully sent to the " + queue.getQueueName() + " queue");
+
+ connection2 = cf.createConnection();
+ Session session2 = connection2.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ MessageConsumer consumer = session2.createConsumer(queue);
+
+ connection2.start();
+
+ message = (TextMessage)consumer.receive(2000);
+ log("Received message: " + message.getText());
+ assertEquals("Hello!", message.getText());
+
+ displayProviderInfo(connection2.getMetaData());
+
+ }
+ finally
+ {
+ if(ic != null)
+ {
+ try
+ {
+ ic.close();
+ }
+ catch(Exception e)
+ {
+ throw e;
+ }
+ }
+
+ //ALWAYS close your connection in a finally block to avoid leaks
+ //Closing connection also takes care of closing its related objects e.g. sessions
+ closeConnection(connection);
+ closeConnection(connection2);
+ }
}
-
+
private void closeConnection(Connection con) throws JMSException
{
- try
- {
- if (con != null)
- {
- con.close();
- }
-
- }
- catch(JMSException jmse)
- {
- log("Could not close connection " + con +" exception was " +jmse);
- throw jmse;
- }
+ try
+ {
+ if (con != null)
+ {
+ con.close();
+ }
+ }
+ catch(JMSException jmse)
+ {
+ log("Could not close connection " + con +" exception was " +jmse);
+ }
}
-
-
+
+
protected boolean isQueueExample()
{
return true;
}
-
+
public static void main(String[] args)
{
new HttpExample().run();
}
-
+
}
Modified: trunk/docs/examples/mdb/src/org/jboss/example/jms/mdb/MDBExample.java
===================================================================
--- trunk/docs/examples/mdb/src/org/jboss/example/jms/mdb/MDBExample.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/docs/examples/mdb/src/org/jboss/example/jms/mdb/MDBExample.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -6,49 +6,56 @@
*/
package org.jboss.example.jms.mdb;
-import javax.jms.*;
+import javax.ejb.EJBException;
import javax.ejb.MessageDrivenBean;
import javax.ejb.MessageDrivenContext;
-import javax.ejb.EJBException;
+import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
+import javax.jms.Destination;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageListener;
+import javax.jms.MessageProducer;
+import javax.jms.Session;
+import javax.jms.TextMessage;
import javax.naming.InitialContext;
/**
* @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
* @version <tt>$Revision$</tt>
-
+
* $Id$
*/
public class MDBExample implements MessageDrivenBean, MessageListener
{
-
private MessageDrivenContext ctx;
-
+
private ConnectionFactory cf = null;
-
+
public void onMessage(Message m)
{
Session session = null;
Connection conn = null;
-
+
try
{
TextMessage tm = (TextMessage)m;
-
+
String text = tm.getText();
System.out.println("message " + text + " received");
String result = process(text);
System.out.println("message processed, result: " + result);
-
+
conn = getConnection();
session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
+
Destination replyTo = m.getJMSReplyTo();
MessageProducer producer = session.createProducer(replyTo);
TextMessage reply = session.createTextMessage(result);
-
+
producer.send(reply);
producer.close();
-
+
}
catch(Exception e)
{
@@ -60,91 +67,101 @@
{
if (conn != null)
{
- try {
- closeConnection(conn);
- }catch(Exception e){
- System.out.println("Could not close the connection!" +e);
+ try
+ {
+ closeConnection(conn);
}
+ catch(Exception e)
+ {
+ System.out.println("Could not close the connection!" +e);
+ }
}
}
}
-
+
private String process(String text)
{
// flip the string
-
+
String result = "";
-
+
for(int i = 0; i < text.length(); i++)
{
result = text.charAt(i) + result;
}
return result;
}
-
- public Connection getConnection() throws Exception {
-
- Connection connection = null;
-
- try {
- connection = cf.createConnection();
- connection.start();
-
- }catch(Exception e ){
- if(connection != null)
- closeConnection(connection);
- System.out.println("Failed to get connection...exception is " +e);
- throw e;
- }
-
- return connection;
- }
-
- public void closeConnection(Connection con) throws Exception {
-
- try {
- con.close();
-
- }catch(JMSException jmse) {
- System.out.println("Could not close connection " + con +" exception was " +jmse);
- throw jmse;
- }
- }
-
- public void ejbCreate()
- {
- try
- {
- InitialContext ic = new InitialContext();
-
- cf = (ConnectionFactory)ic.lookup("java:/JmsXA");
-
- ic.close();
- }
- catch(Exception e)
- {
- e.printStackTrace();
- throw new EJBException("Failure to get connection factory: " + e.getMessage());
- }
- }
-
- public void ejbRemove() throws EJBException
- {
- try
- {
- if(cf != null)
- cf = null;
- }
- catch(Exception e)
- {
- throw new EJBException("ejbRemove", e);
- }
- }
-
- public void setMessageDrivenContext(MessageDrivenContext ctx)
- {
- this.ctx = ctx;
- }
-
-
+
+ public Connection getConnection() throws Exception
+ {
+ Connection connection = null;
+
+ try
+ {
+ connection = cf.createConnection();
+ connection.start();
+ }
+ catch(Exception e )
+ {
+ if(connection != null)
+ {
+ closeConnection(connection);
+ }
+ System.out.println("Failed to get connection...exception is " + e);
+ throw e;
+ }
+
+ return connection;
+ }
+
+ public void closeConnection(Connection con) throws Exception
+ {
+ try
+ {
+ con.close();
+ }
+ catch(JMSException jmse)
+ {
+ System.out.println("Could not close connection " + con + " exception was " + jmse);
+ }
+ }
+
+ public void ejbCreate()
+ {
+ try
+ {
+ InitialContext ic = new InitialContext();
+
+ cf = (ConnectionFactory)ic.lookup("java:/JmsXA");
+
+ ic.close();
+ }
+ catch(Exception e)
+ {
+ e.printStackTrace();
+ throw new EJBException("Failure to get connection factory: " + e.getMessage());
+ }
+ }
+
+ public void ejbRemove() throws EJBException
+ {
+ try
+ {
+ if(cf != null)
+ {
+ cf = null;
+ }
+ }
+ catch(Exception e)
+ {
+ throw new EJBException("ejbRemove", e);
+ }
+ }
+
+ public void setMessageDrivenContext(MessageDrivenContext ctx)
+ {
+ this.ctx = ctx;
+ }
+
+
}
Modified: trunk/docs/examples/mdb/src/org/jboss/example/jms/mdb/Sender.java
===================================================================
--- trunk/docs/examples/mdb/src/org/jboss/example/jms/mdb/Sender.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/docs/examples/mdb/src/org/jboss/example/jms/mdb/Sender.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -1,37 +1,37 @@
/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
package org.jboss.example.jms.mdb;
-import org.jboss.example.jms.common.ExampleSupport;
-
-import javax.naming.InitialContext;
-import javax.jms.ConnectionFactory;
import javax.jms.Connection;
-import javax.jms.Session;
+import javax.jms.ConnectionFactory;
+import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
-import javax.jms.TextMessage;
import javax.jms.Queue;
-import javax.jms.MessageConsumer;
+import javax.jms.Session;
+import javax.jms.TextMessage;
+import javax.naming.InitialContext;
+import org.jboss.example.jms.common.ExampleSupport;
+
/**
* This example deploys a simple Message Driven Bean that processes messages sent to a test queue.
* Once it receives a message and "processes" it, the MDB sends an acknowledgment message to a
@@ -51,84 +51,64 @@
public void example() throws Exception
{
String destinationName = getDestinationJNDIName();
-
-
-
+
InitialContext ic = new InitialContext();
-
-
+
ConnectionFactory cf = (ConnectionFactory)ic.lookup("/ConnectionFactory");
Queue queue = (Queue)ic.lookup(destinationName);
-
-
-
- log("Queue " + destinationName + " exists");
-
-
-
- Connection connection = cf.createConnection();
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- MessageProducer sender = session.createProducer(queue);
-
-
-
- Queue temporaryQueue = session.createTemporaryQueue();
- MessageConsumer consumer = session.createConsumer(temporaryQueue);
-
-
-
- TextMessage message = session.createTextMessage("Hello!");
- message.setJMSReplyTo(temporaryQueue);
-
-
-
- sender.send(message);
-
-
-
- log("The " + message.getText() + " message was successfully sent to the " + queue.getQueueName() + " queue");
-
-
-
- connection.start();
-
-
-
- message = (TextMessage)consumer.receive(5000);
-
-
- if (message == null)
+
+ log("Queue " + destinationName + " exists");
+
+ Connection connection = null;
+
+ try
{
- throw new Exception("Have not received any reply. The example failed!");
+ connection = cf.createConnection();
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ MessageProducer sender = session.createProducer(queue);
+
+ Queue temporaryQueue = session.createTemporaryQueue();
+ MessageConsumer consumer = session.createConsumer(temporaryQueue);
+
+ TextMessage message = session.createTextMessage("Hello!");
+ message.setJMSReplyTo(temporaryQueue);
+
+ sender.send(message);
+
+ log("The " + message.getText() + " message was successfully sent to the " + queue.getQueueName() + " queue");
+
+ connection.start();
+
+ message = (TextMessage)consumer.receive(5000);
+
+ if (message == null)
+ {
+ throw new Exception("Have not received any reply. The example failed!");
+ }
+
+ log("Received message: " + message.getText());
+
+ assertEquals("!olleH", message.getText());
+
+ displayProviderInfo(connection.getMetaData());
}
-
-
- log("Received message: " + message.getText());
-
-
-
- assertEquals("!olleH", message.getText());
-
-
-
- displayProviderInfo(connection.getMetaData());
-
-
-
- connection.close();
+ finally
+ {
+ if (connection != null)
+ {
+ connection.close();
+ }
+ }
}
-
-
-
-
+
protected boolean isQueueExample()
{
return true;
}
-
+
public static void main(String[] args)
{
new Sender().run();
}
-
+
}
Modified: trunk/docs/examples/queue/src/org/jboss/example/jms/queue/QueueExample.java
===================================================================
--- trunk/docs/examples/queue/src/org/jboss/example/jms/queue/QueueExample.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/docs/examples/queue/src/org/jboss/example/jms/queue/QueueExample.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -1,38 +1,37 @@
/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
package org.jboss.example.jms.queue;
-import org.jboss.example.jms.common.ExampleSupport;
-
-import javax.naming.InitialContext;
-import javax.jms.TextMessage;
-import javax.jms.Session;
+import javax.jms.Connection;
import javax.jms.ConnectionFactory;
+import javax.jms.JMSException;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageProducer;
import javax.jms.Queue;
-import javax.jms.MessageProducer;
-import javax.jms.Connection;
-import javax.jms.MessageConsumer;
-import javax.jms.JMSException;
+import javax.jms.Session;
+import javax.jms.TextMessage;
+import javax.naming.InitialContext;
+import org.jboss.example.jms.common.ExampleSupport;
/**
* The example creates a connection to the default provider and uses the connection to send a
@@ -51,87 +50,91 @@
*/
public class QueueExample extends ExampleSupport
{
-
+
public void example() throws Exception
{
String destinationName = getDestinationJNDIName();
-
- InitialContext ic = null;
- ConnectionFactory cf = null;
- Connection connection = null;
- Connection connection2 = null;
-
- try {
-
- ic = new InitialContext();
-
- cf = (ConnectionFactory)ic.lookup("/ConnectionFactory");
- Queue queue = (Queue)ic.lookup(destinationName);
- log("Queue " + destinationName + " exists");
-
- connection = cf.createConnection();
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- MessageProducer sender = session.createProducer(queue);
-
- TextMessage message = session.createTextMessage("Hello!");
- sender.send(message);
- log("The message was successfully sent to the " + queue.getQueueName() + " queue");
-
- connection2 = cf.createConnection();
- Session session2 = connection2.createSession(false, Session.AUTO_ACKNOWLEDGE);
- MessageConsumer consumer = session2.createConsumer(queue);
-
- connection2.start();
-
- message = (TextMessage)consumer.receive(2000);
- log("Received message: " + message.getText());
- assertEquals("Hello!", message.getText());
-
- displayProviderInfo(connection2.getMetaData());
-
-
- }finally{
-
- if(ic != null) {
- try {
- ic.close();
- }catch(Exception e){
- throw e;
- }
- }
-
- //ALWAYS close your connection in a finally block to avoid leaks
- //Closing connection also takes care of closing its related objects e.g. sessions
- closeConnection(connection);
-
- closeConnection(connection2);
-
- }
-
+
+ InitialContext ic = null;
+ ConnectionFactory cf = null;
+ Connection connection = null;
+ Connection connection2 = null;
+
+ try
+ {
+ ic = new InitialContext();
+
+ cf = (ConnectionFactory)ic.lookup("/ConnectionFactory");
+ Queue queue = (Queue)ic.lookup(destinationName);
+ log("Queue " + destinationName + " exists");
+
+ connection = cf.createConnection();
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ MessageProducer sender = session.createProducer(queue);
+
+ TextMessage message = session.createTextMessage("Hello!");
+ sender.send(message);
+ log("The message was successfully sent to the " + queue.getQueueName() + " queue");
+
+ connection2 = cf.createConnection();
+ Session session2 = connection2.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ MessageConsumer consumer = session2.createConsumer(queue);
+
+ connection2.start();
+
+ message = (TextMessage)consumer.receive(2000);
+ log("Received message: " + message.getText());
+ assertEquals("Hello!", message.getText());
+
+ displayProviderInfo(connection2.getMetaData());
+
+ }
+ finally
+ {
+ if(ic != null)
+ {
+ try
+ {
+ ic.close();
+ }
+ catch(Exception e)
+ {
+ throw e;
+ }
+ }
+
+ //ALWAYS close your connection in a finally block to avoid leaks
+ //Closing connection also takes care of closing its related objects e.g. sessions
+ closeConnection(connection);
+
+ closeConnection(connection2);
+
+ }
}
-
- private void closeConnection(Connection con) throws JMSException {
-
- try {
- if (con != null) {
- con.close();
- }
-
- }catch(JMSException jmse) {
- log("Could not close connection " + con +" exception was " +jmse);
- throw jmse;
- }
+
+ private void closeConnection(Connection con) throws JMSException
+ {
+ try
+ {
+ if (con != null)
+ {
+ con.close();
+ }
+ }
+ catch(JMSException jmse)
+ {
+ log("Could not close connection " + con +" exception was " + jmse);
+ }
}
-
-
+
protected boolean isQueueExample()
{
return true;
}
-
+
public static void main(String[] args)
{
new QueueExample().run();
}
-
+
}
Modified: trunk/docs/examples/queue-failover/src/org/jboss/example/jms/failover/QueueFailoverExample.java
===================================================================
--- trunk/docs/examples/queue-failover/src/org/jboss/example/jms/failover/QueueFailoverExample.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/docs/examples/queue-failover/src/org/jboss/example/jms/failover/QueueFailoverExample.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -21,15 +21,15 @@
*/
package org.jboss.example.jms.failover;
-import javax.naming.InitialContext;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
-import javax.jms.Session;
-import javax.jms.MessageProducer;
-import javax.jms.MessageConsumer;
-import javax.jms.TextMessage;
import javax.jms.JMSException;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageProducer;
import javax.jms.Queue;
+import javax.jms.Session;
+import javax.jms.TextMessage;
+import javax.naming.InitialContext;
import org.jboss.example.jms.common.ExampleSupport;
@@ -51,7 +51,6 @@
{
public void example() throws Exception
{
-
String destinationName = getDestinationJNDIName();
InitialContext ic = null;
@@ -62,7 +61,6 @@
{
// Create a connection to the clustered messaging instance
-
ic = new InitialContext();
ConnectionFactory cf = (ConnectionFactory)ic.lookup("/ConnectionFactory");
@@ -70,7 +68,6 @@
Queue distributedQueue = (Queue)ic.lookup(destinationName);
log("Distributed queue " + destinationName + " exists");
-
// When connecting to a messaging cluster, the ConnectionFactory has the capability of
// transparently creating physical connections to different cluster nodes, in a round
// robin fashion ...
@@ -105,14 +102,11 @@
assertEquals("Hello1!", rm1.getText());
-
// Kill the active node
killActiveNode();
-
Thread.sleep(30000); // TODO not necesare after we install the client valve
-
// receive the second message on the failed over node
TextMessage rm2 = (TextMessage)consumer.receive(2000);
@@ -122,11 +116,10 @@
assertEquals("Hello2!", rm2.getText());
displayProviderInfo(connection.getMetaData());
-
}
finally
{
- if(ic != null)
+ if (ic != null)
{
try
{
@@ -162,5 +155,4 @@
{
new QueueFailoverExample().run();
}
-
}
Modified: trunk/docs/examples/secure-socket/src/org/jboss/example/jms/securesocket/SecureSocketExample.java
===================================================================
--- trunk/docs/examples/secure-socket/src/org/jboss/example/jms/securesocket/SecureSocketExample.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/docs/examples/secure-socket/src/org/jboss/example/jms/securesocket/SecureSocketExample.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -1,24 +1,24 @@
/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
package org.jboss.example.jms.securesocket;
import org.jboss.example.jms.common.ExampleSupport;
@@ -33,7 +33,6 @@
import javax.jms.MessageConsumer;
import javax.jms.JMSException;
-
/**
* The example creates a connection to the default provider and uses the connection to send a
* message to the queue "queue/testQueue". Then, the example creates a second connection to the
@@ -50,96 +49,92 @@
*/
public class SecureSocketExample extends ExampleSupport
{
-
+
public void example() throws Exception
{
String destinationName = getDestinationJNDIName();
-
- InitialContext ic = null;
- ConnectionFactory cf = null;
- Connection connection = null;
- Connection connection2 = null;
-
- try
- {
-
- ic = new InitialContext();
-
- cf = (ConnectionFactory)ic.lookup("/SecureConnectionFactory");
- Queue queue = (Queue)ic.lookup(destinationName);
- log("Queue " + destinationName + " exists");
-
- connection = cf.createConnection();
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
- MessageProducer sender = session.createProducer(queue);
-
- TextMessage message = session.createTextMessage("Hello!");
- sender.send(message);
- log("The message was successfully sent to the " + queue.getQueueName() + " queue");
-
- connection2 = cf.createConnection();
- Session session2 = connection2.createSession(false, Session.AUTO_ACKNOWLEDGE);
- MessageConsumer consumer = session2.createConsumer(queue);
-
- connection2.start();
-
- message = (TextMessage)consumer.receive(2000);
- log("Received message: " + message.getText());
- assertEquals("Hello!", message.getText());
-
- displayProviderInfo(connection2.getMetaData());
-
-
- }
- finally
- {
- if(ic != null)
- {
- try
- {
- ic.close();
- }
- catch(Exception e)
- {
- throw e;
- }
- }
-
- //ALWAYS close your connection in a finally block to avoid leaks
- //Closing connection also takes care of closing its related objects e.g. sessions
- closeConnection(connection);
-
- closeConnection(connection2);
-
- }
-
+
+ InitialContext ic = null;
+ ConnectionFactory cf = null;
+ Connection connection = null;
+ Connection connection2 = null;
+
+ try
+ {
+ ic = new InitialContext();
+
+ cf = (ConnectionFactory)ic.lookup("/SecureConnectionFactory");
+ Queue queue = (Queue)ic.lookup(destinationName);
+ log("Queue " + destinationName + " exists");
+
+ connection = cf.createConnection();
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ MessageProducer sender = session.createProducer(queue);
+
+ TextMessage message = session.createTextMessage("Hello!");
+ sender.send(message);
+ log("The message was successfully sent to the " + queue.getQueueName() + " queue");
+
+ connection2 = cf.createConnection();
+ Session session2 = connection2.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ MessageConsumer consumer = session2.createConsumer(queue);
+
+ connection2.start();
+
+ message = (TextMessage)consumer.receive(2000);
+ log("Received message: " + message.getText());
+ assertEquals("Hello!", message.getText());
+
+ displayProviderInfo(connection2.getMetaData());
+ }
+ finally
+ {
+ if(ic != null)
+ {
+ try
+ {
+ ic.close();
+ }
+ catch(Exception e)
+ {
+ throw e;
+ }
+ }
+
+ //ALWAYS close your connection in a finally block to avoid leaks
+ //Closing connection also takes care of closing its related objects e.g. sessions
+ closeConnection(connection);
+
+ closeConnection(connection2);
+
+ }
+
}
-
+
private void closeConnection(Connection con) throws JMSException
{
- try
- {
- if (con != null)
- {
- con.close();
- }
- }
- catch(JMSException jmse)
- {
- log("Could not close connection " + con +" exception was " +jmse);
- throw jmse;
- }
+ try
+ {
+ if (con != null)
+ {
+ con.close();
+ }
+ }
+ catch(JMSException jmse)
+ {
+ log("Could not close connection " + con +" exception was " +jmse);
+ }
}
-
-
+
+
protected boolean isQueueExample()
{
return true;
}
-
+
public static void main(String[] args)
{
new SecureSocketExample().run();
}
-
+
}
Modified: trunk/docs/examples/stateless/src/org/jboss/example/jms/stateless/bean/StatelessSessionExample.java
===================================================================
--- trunk/docs/examples/stateless/src/org/jboss/example/jms/stateless/bean/StatelessSessionExample.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/docs/examples/stateless/src/org/jboss/example/jms/stateless/bean/StatelessSessionExample.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -7,6 +7,7 @@
package org.jboss.example.jms.stateless.bean;
import java.rmi.RemoteException;
+
import javax.ejb.EJBObject;
/**
@@ -19,7 +20,10 @@
public interface StatelessSessionExample extends EJBObject
{
public void drain(String queueName) throws RemoteException, Exception;
+
public void send(String txt, String queueName) throws RemoteException, Exception;
+
public int browse(String queueName) throws RemoteException, Exception;
+
public String receive(String queueName) throws RemoteException, Exception;
}
Modified: trunk/docs/examples/stateless/src/org/jboss/example/jms/stateless/bean/StatelessSessionExampleBean.java
===================================================================
--- trunk/docs/examples/stateless/src/org/jboss/example/jms/stateless/bean/StatelessSessionExampleBean.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/docs/examples/stateless/src/org/jboss/example/jms/stateless/bean/StatelessSessionExampleBean.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -9,34 +9,41 @@
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.Enumeration;
+
import javax.ejb.EJBException;
import javax.ejb.SessionBean;
import javax.ejb.SessionContext;
-import javax.jms.*;
+import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
+import javax.jms.JMSException;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageProducer;
+import javax.jms.Queue;
+import javax.jms.QueueBrowser;
+import javax.jms.Session;
+import javax.jms.TextMessage;
import javax.naming.InitialContext;
/**
* @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
* @version <tt>$Revision$</tt>
-
+
* $Id$
*/
public class StatelessSessionExampleBean implements SessionBean
-{
-
- private SessionContext ctx;
-
- private ConnectionFactory cf = null;
-
+{
+ private ConnectionFactory cf = null;
+
public void drain(String queueName) throws Exception
{
InitialContext ic = new InitialContext();
Queue queue = (Queue)ic.lookup(queueName);
ic.close();
-
+
Session session = null;
Connection conn = null;
-
+
try
{
conn = getConnection();
@@ -57,28 +64,31 @@
}
}
}
-
+
public void send(String txt, String queueName) throws Exception
{
InitialContext ic = new InitialContext();
+
Queue queue = (Queue)ic.lookup(queueName);
+
ic.close();
-
+
Session session = null;
Connection conn = null;
-
- try
+
+ try
{
conn = getConnection();
+
session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
+
MessageProducer producer = session.createProducer(queue);
-
+
TextMessage tm = session.createTextMessage(txt);
-
+
producer.send(tm);
- System.out.println("message " + txt + " sent to " + queueName);
-
+
+ System.out.println("message " + txt + " sent to " + queueName);
}
finally
{
@@ -88,28 +98,28 @@
}
}
}
-
+
public int browse(String queueName) throws Exception
{
InitialContext ic = new InitialContext();
Queue queue = (Queue)ic.lookup(queueName);
ic.close();
-
+
Session session = null;
Connection conn = null;
-
+
try
{
conn = getConnection();
session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
QueueBrowser browser = session.createBrowser(queue);
-
+
ArrayList list = new ArrayList();
for(Enumeration e = browser.getEnumeration(); e.hasMoreElements(); )
{
list.add(e.nextElement());
}
-
+
return list.size();
}
finally
@@ -120,35 +130,34 @@
}
}
}
-
+
public String receive(String queueName) throws Exception
{
InitialContext ic = new InitialContext();
Queue queue = (Queue)ic.lookup(queueName);
ic.close();
-
+
Session session = null;
Connection conn = null;
-
+
try
{
conn = getConnection();
session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
+
MessageConsumer consumer = session.createConsumer(queue);
-
+
System.out.println("blocking to receive message from queue " + queueName + " ...");
TextMessage tm = (TextMessage)consumer.receive(5000);
-
+
if (tm == null)
{
throw new Exception("No message!");
}
-
+
System.out.println("Message " + tm.getText() + " received");
-
- return tm.getText();
-
+
+ return tm.getText();
}
finally
{
@@ -158,81 +167,86 @@
}
}
}
-
- public Connection getConnection() throws Exception {
-
- Connection connection = null;
-
- try {
- connection = cf.createConnection();
- connection.start();
-
- }catch(Exception e ){
- if(connection != null)
- closeConnection(connection);
- System.out.println("Failed to get connection...exception is " +e);
- throw e;
- }
-
- return connection;
- }
-
- public void closeConnection(Connection con) throws Exception {
-
- try {
- con.close();
-
- }catch(JMSException jmse) {
- System.out.println("Could not close connection " + con +" exception was " +jmse);
- throw jmse;
- }
- }
-
- public void setSessionContext(SessionContext ctx) throws EJBException, RemoteException
+
+ public Connection getConnection() throws Exception
{
- this.ctx = ctx;
+
+ Connection connection = null;
+
+ try
+ {
+ connection = cf.createConnection();
+
+ connection.start();
+ }
+ catch(Exception e )
+ {
+ if(connection != null)
+ {
+ closeConnection(connection);
+ }
+ System.out.println("Failed to get connection...exception is " + e);
+ throw e;
+ }
+
+ return connection;
}
-
-
-
-
- public void ejbCreate()
- {
- try
- {
- InitialContext ic = new InitialContext();
-
- cf = (ConnectionFactory)ic.lookup("java:/JmsXA");
-
- ic.close();
- }
- catch(Exception e)
- {
- e.printStackTrace();
- throw new EJBException("Initalization failure: " + e.getMessage());
- }
- }
-
+
+ public void closeConnection(Connection con) throws Exception
+ {
+ try
+ {
+ con.close();
+ }
+ catch(JMSException jmse)
+ {
+ System.out.println("Could not close connection " + con +" exception was " + jmse);
+ throw jmse;
+ }
+ }
+
+ public void setSessionContext(SessionContext ctx) throws EJBException, RemoteException
+ {
+ }
+
+ public void ejbCreate()
+ {
+ try
+ {
+ InitialContext ic = new InitialContext();
+
+ cf = (ConnectionFactory)ic.lookup("java:/JmsXA");
+
+ ic.close();
+ }
+ catch(Exception e)
+ {
+ e.printStackTrace();
+ throw new EJBException("Initalization failure: " + e.getMessage());
+ }
+ }
+
public void ejbRemove() throws EJBException
{
try
{
- if(cf != null)
- cf = null;
- }
+ if(cf != null)
+ {
+ cf = null;
+ }
+ }
catch(Exception e)
{
throw new EJBException("ejbRemove ", e);
}
}
-
+
public void ejbActivate() throws EJBException, RemoteException
{
}
-
+
public void ejbPassivate() throws EJBException, RemoteException
{
}
-
-
+
}
Modified: trunk/docs/examples/stateless/src/org/jboss/example/jms/stateless/bean/StatelessSessionExampleHome.java
===================================================================
--- trunk/docs/examples/stateless/src/org/jboss/example/jms/stateless/bean/StatelessSessionExampleHome.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/docs/examples/stateless/src/org/jboss/example/jms/stateless/bean/StatelessSessionExampleHome.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -6,9 +6,10 @@
*/
package org.jboss.example.jms.stateless.bean;
-import javax.ejb.EJBHome;
import java.rmi.RemoteException;
+
import javax.ejb.CreateException;
+import javax.ejb.EJBHome;
/**
* @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
* @version <tt>$Revision$</tt>
Modified: trunk/docs/examples/stateless/src/org/jboss/example/jms/stateless/client/Client.java
===================================================================
--- trunk/docs/examples/stateless/src/org/jboss/example/jms/stateless/client/Client.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/docs/examples/stateless/src/org/jboss/example/jms/stateless/client/Client.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -1,24 +1,24 @@
/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
package org.jboss.example.jms.stateless.client;
import javax.naming.InitialContext;
@@ -41,71 +41,43 @@
public class Client extends ExampleSupport
{
public void example() throws Exception
- {
-
-
+ {
InitialContext ic = new InitialContext();
-
-
-
+
StatelessSessionExampleHome home =
- (StatelessSessionExampleHome)ic.lookup("ejb/StatelessSessionExample");
-
-
-
+ (StatelessSessionExampleHome)ic.lookup("ejb/StatelessSessionExample");
+
StatelessSessionExample bean = home.create();
-
-
-
+
String queueName = getDestinationJNDIName();
- String text = "Hello!";
-
-
-
-
+ String text = "Hello!";
+
bean.drain(queueName);
-
-
-
-
+
bean.send("Hello!", queueName);
log("The " + text + " message was successfully sent to the " + queueName + " queue");
-
-
+
int num = bean.browse(queueName);
-
-
-
+
assertEquals(1, num);
-
-
- log("Queue browse result: " + num);
-
-
-
+
+ log("Queue browse result: " + num);
+
String result = bean.receive(queueName);
- log("Received " + result);
-
-
-
- assertEquals("Hello!", result);
-
-
-
+ log("Received " + result);
+
+ assertEquals("Hello!", result);
+
bean.remove();
}
-
-
-
-
+
protected boolean isQueueExample()
{
return true;
}
-
+
public static void main(String[] args)
{
new Client().run();
- }
-
+ }
}
Modified: trunk/docs/examples/topic/src/org/jboss/example/jms/topic/ExampleListener.java
===================================================================
--- trunk/docs/examples/topic/src/org/jboss/example/jms/topic/ExampleListener.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/docs/examples/topic/src/org/jboss/example/jms/topic/ExampleListener.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -6,40 +6,37 @@
*/
package org.jboss.example.jms.topic;
-import javax.jms.MessageListener;
import javax.jms.Message;
+import javax.jms.MessageListener;
/**
* @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
* @version <tt>$Revision$</tt>
-
+
* $Id$
*/
public class ExampleListener implements MessageListener
-{
-
+{
private Message message;
-
-
+
public synchronized void onMessage(Message message)
{
this.message = message;
notifyAll();
}
-
+
public synchronized Message getMessage()
{
return message;
}
-
-
+
protected synchronized void waitForMessage()
{
if (message != null)
{
return;
}
-
+
try
{
wait(5000);
Modified: trunk/docs/examples/topic/src/org/jboss/example/jms/topic/TopicExample.java
===================================================================
--- trunk/docs/examples/topic/src/org/jboss/example/jms/topic/TopicExample.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/docs/examples/topic/src/org/jboss/example/jms/topic/TopicExample.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -1,31 +1,38 @@
/*
-* JBoss, Home of Professional Open Source
-* Copyright 2005, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
package org.jboss.example.jms.topic;
+import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
+import javax.jms.JMSException;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageProducer;
+import javax.jms.Session;
+import javax.jms.TextMessage;
+import javax.jms.Topic;
+import javax.naming.InitialContext;
+
import org.jboss.example.jms.common.ExampleSupport;
-import javax.naming.InitialContext;
-import javax.jms.*;
-
/**
* The example creates a connection to the default provider and uses the connection to send a
* message to the topic "queue/testTopic". The message must be received by a topic subscriber.
@@ -45,45 +52,46 @@
public void example() throws Exception
{
String destinationName = getDestinationJNDIName();
-
+
InitialContext ic = null;
Connection connection = null;
-
- try {
-
+
+ try
+ {
ic = new InitialContext();
-
+
ConnectionFactory cf = (ConnectionFactory)ic.lookup("/ConnectionFactory");
Topic topic = (Topic)ic.lookup(destinationName);
log("Topic " + destinationName + " exists");
-
+
connection = cf.createConnection();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer publisher = session.createProducer(topic);
MessageConsumer subscriber = session.createConsumer(topic);
-
+
ExampleListener messageListener = new ExampleListener();
subscriber.setMessageListener(messageListener);
connection.start();
-
+
TextMessage message = session.createTextMessage("Hello!");
publisher.send(message);
log("The message was successfully published on the topic");
-
+
messageListener.waitForMessage();
-
+
message = (TextMessage)messageListener.getMessage();
log("Received message: " + message.getText());
assertEquals("Hello!", message.getText());
-
+
displayProviderInfo(connection.getMetaData());
-
+
}
finally
{
- if(ic != null)
+ if (ic != null)
{
- try {
+ try
+ {
ic.close();
}
catch(Exception e)
@@ -91,15 +99,16 @@
throw e;
}
}
-
+
// ALWAYS close your connection in a finally block to avoid leaks.
// Closing connection also takes care of closing its related objects e.g. sessions.
closeConnection(connection);
}
}
-
- private void closeConnection(Connection con) throws JMSException {
-
+
+ private void closeConnection(Connection con) throws JMSException
+ {
+
try
{
if (con != null)
@@ -109,19 +118,18 @@
}
catch(JMSException jmse)
{
- log("Could not close connection " + con +" exception was " +jmse);
- throw jmse;
+ log("Could not close connection " + con +" exception was " + jmse);
}
}
-
+
protected boolean isQueueExample()
{
return false;
}
-
+
public static void main(String[] args)
{
new TopicExample().run();
}
-
+
}
Copied: trunk/lib/jbossts (from rev 1823, branches/Branch_1_0/lib/jbossts)
Deleted: trunk/lib/jbossts/jboss-service.xml
===================================================================
--- branches/Branch_1_0/lib/jbossts/jboss-service.xml 2006-12-19 06:51:01 UTC (rev 1823)
+++ trunk/lib/jbossts/jboss-service.xml 2006-12-21 23:41:19 UTC (rev 1843)
@@ -1,535 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<!-- $Id: jboss-service.xml 38992 2005-12-13 15:29:35Z jerrygauth $ -->
-
-<!-- ===================================================================== -->
-<!-- JBoss Server Configuration -->
-<!-- ===================================================================== -->
-
-<server>
-
- <!-- Load all jars from the JBOSS_DIST/server/<config>/lib directory. This
- can be restricted to specific jars by specifying them in the archives
- attribute.
- -->
- <classpath codebase="${jboss.server.lib.url:lib}" archives="*"/>
-
- <!-- ==================================================================== -->
- <!-- JSR-77 Single JBoss Server Management Domain -->
- <!-- ==================================================================== -->
- <mbean code="org.jboss.management.j2ee.LocalJBossServerDomain"
- name="jboss.management.local:j2eeType=J2EEDomain,name=Manager">
- <attribute name="MainDeployer">jboss.system:service=MainDeployer</attribute>
- <attribute name="SARDeployer">jboss.system:service=ServiceDeployer</attribute>
- <attribute name="EARDeployer">jboss.j2ee:service=EARDeployer</attribute>
- <attribute name="EJBDeployer">jboss.ejb:service=EJBDeployer</attribute>
- <attribute name="RARDeployer">jboss.jca:service=RARDeployer</attribute>
- <attribute name="CMDeployer">jboss.jca:service=ConnectionFactoryDeployer</attribute>
- <attribute name="WARDeployer">jboss.web:service=WebServer</attribute>
- <attribute name="CARDeployer">jboss.j2ee:service=ClientDeployer</attribute>
- <attribute name="MailService">jboss:service=Mail</attribute>
- <attribute name="JMSService">jboss.mq:service=DestinationManager</attribute>
- <attribute name="JNDIService">jboss:service=Naming</attribute>
- <attribute name="JTAService">jboss:service=TransactionManager</attribute>
- <attribute name="UserTransactionService">jboss:service=ClientUserTransaction</attribute>
- <attribute name="RMI_IIOPService">jboss:service=CorbaORB</attribute>
- </mbean>
-
- <!-- ==================================================================== -->
- <!-- XMBean Persistence -->
- <!-- ==================================================================== -->
- <mbean code="org.jboss.system.pm.AttributePersistenceService"
- name="jboss:service=AttributePersistenceService"
- xmbean-dd="resource:xmdesc/AttributePersistenceService-xmbean.xml">
- <!-- the AttributePersistenceService is persistent, itself -->
-
- <!--
- <attribute name="AttributePersistenceManagerClass">org.jboss.system.pm.XMLAttributePersistenceManager</attribute>
- <attribute name="AttributePersistenceManagerConfig">
- <data-directory>data/xmbean-attrs</data-directory>
- </attribute>
- <attribute name="ApmDestroyOnServiceStop">false</attribute>
- <attribute name="VersionTag"></attribute>
- -->
- </mbean>
-
- <!-- A Thread pool service -->
- <mbean code="org.jboss.util.threadpool.BasicThreadPool"
- name="jboss.system:service=ThreadPool">
- <attribute name="Name">JBoss System Threads</attribute>
- <attribute name="ThreadGroupName">System Threads</attribute>
- <!-- How long a thread will live without any tasks in MS -->
- <attribute name="KeepAliveTime">60000</attribute>
- <!-- The max number of threads in the pool -->
- <attribute name="MaximumPoolSize">10</attribute>
- <!-- The max number of tasks before the queue is full -->
- <attribute name="MaximumQueueSize">1000</attribute>
- <!-- The behavior of the pool when a task is added and the queue is full.
- abort - a RuntimeException is thrown
- run - the calling thread executes the task
- wait - the calling thread blocks until the queue has room
- discard - the task is silently discarded without being run
- discardOldest - check to see if a task is about to complete and enque
- the new task if possible, else run the task in the calling thread
- -->
- <attribute name="BlockingMode">run</attribute>
- </mbean>
-
- <!-- Preload all custom editors for VMs that don't use the thread
- context class loader when searching for PropertyEditors. Uncomment
- if your JDK 1.3.0 VM fails to find JBoss PropertyEditors.
- <mbean code="org.jboss.varia.property.PropertyEditorManagerService"
- name="jboss:type=Service,name=BootstrapEditors">
- <attribute name="BootstrapEditors">
- java.math.BigDecimal=org.jboss.util.propertyeditor.BigDecimalEditor
- java.lang.Boolean=org.jboss.util.propertyeditor.BooleanEditor
- java.lang.Class=org.jboss.util.propertyeditor.ClassEditor
- java.util.Date=org.jboss.util.propertyeditor.DateEditor
- java.io.File=org.jboss.util.propertyeditor.FileEditor
- java.net.InetAddress=org.jboss.util.propertyeditor.InetAddressEditor
- java.lang.Integer=org.jboss.util.propertyeditor.IntegerEditor
- javax.management.ObjectName=org.jboss.mx.util.propertyeditor.ObjectNameEditor
- java.util.Properties=org.jboss.util.propertyeditor.PropertiesEditor
- [Ljava.lang.String;=org.jboss.util.propertyeditor.StringArrayEditor
- java.net.URL=org.jboss.util.propertyeditor.URLEditor
- </attribute>
- </mbean>
- -->
-
- <!-- ==================================================================== -->
- <!-- Log4j Initialization -->
- <!-- ==================================================================== -->
-
- <mbean code="org.jboss.logging.Log4jService"
- name="jboss.system:type=Log4jService,service=Logging"
- xmbean-dd="resource:xmdesc/Log4jService-xmbean.xml">
- <attribute name="ConfigurationURL">resource:log4j.xml</attribute>
- <!-- Set the org.apache.log4j.helpers.LogLog.setQuiteMode. As of log4j1.2.8
- this needs to be set to avoid a possible deadlock on exception at the
- appender level. See bug#696819.
- -->
- <attribute name="Log4jQuietMode">true</attribute>
- <!-- How frequently in seconds the ConfigurationURL is checked for changes -->
- <attribute name="RefreshPeriod">60</attribute>
- </mbean>
-
- <!-- ==================================================================== -->
- <!-- Active Alarm Table -->
- <!-- ==================================================================== -->
-
- <!--
- | The ActiveAlarmTable service is a simple JMX notification listener
- | that maintains a table with the received notifications (alarms).
- | The alarms can be acknowledged through the jmx or the web console.
- | Modify the SubscriptionList below to subscribe for any notification
- | in the system and treat it as an alarm.
- | The JMXNotificationAppender is a log4j Appender that can be configured
- | in log4j.xml, that trasforms logging events to JMX notification so they
- | can be fed back into the table. By storing the WARN or higher level logging
- | events you can have a quick view of important system faults.
- |
- | The following attributes may be set:
- |
- | MaxTableSize (default 1000)
- | - set an upper limit to the number of stored alarms
- | LogLevel (default DEBUG)
- | - the log level to use for received notification, can be set to NONE
- | ServerId (default jboss)
- | - used to construct unique alarm ids
- | SubscriptionList
- | - subscribe for the notifications to be stored in the table
-
- <mbean code="org.jboss.monitor.services.ActiveAlarmTable"
- name="jboss.monitor:service=ActiveAlarmTable">
- <attribute name="SubscriptionList">
- <subscription-list>
- <mbean name="jboss.monitor:*">
- <notification type="jboss.alarm"/>
- <notification type="JBOSS_MONITOR_NOTIFICATION"/>
- </mbean>
- <mbean name="jboss.system:service=Logging,type=JMXNotificationAppender"/>
- </subscription-list>
- </attribute>
- </mbean>
- -->
-
- <!-- ==================================================================== -->
- <!-- JBoss RMI Classloader - only install when available -->
- <!-- ==================================================================== -->
- <mbean code="org.jboss.util.property.jmx.SystemPropertyClassValue"
- name="jboss.rmi:type=RMIClassLoader">
- <attribute name="Property">java.rmi.server.RMIClassLoaderSpi</attribute>
- <attribute name="ClassName">org.jboss.system.JBossRMIClassLoader</attribute>
- </mbean>
-
- <!-- ==================================================================== -->
- <!-- Service Binding -->
- <!-- ==================================================================== -->
-
- <!-- Automatically activated when generatting the clustering environment -->
- <!-- @TESTSUITE_CLUSTER_CONFIG@ -->
-
- <!--
- | Binding service manager for port/host mapping. This is a sample
- | config that demonstrates a JBoss instances with a server name 'ports-01'
- | loading its bindings from an XML file using the ServicesStoreFactory
- | implementation returned by the XMLServicesStoreFactory.
- |
- | ServerName: The unique name assigned to a JBoss server instance for
- | lookup purposes. This allows a single ServicesStore to handle mulitiple
- | JBoss servers.
- |
- | StoreURL: The URL string passed to org.jboss.services.binding.ServicesStore
- | during initialization that specifies how to connect to the bindings store.
- | StoreFactory: The org.jboss.services.binding.ServicesStoreFactory interface
- | implementation to create to obtain the ServicesStore instance.
-
- <mbean code="org.jboss.services.binding.ServiceBindingManager"
- name="jboss.system:service=ServiceBindingManager">
- <attribute name="ServerName">ports-01</attribute>
- <attribute name="StoreURL">${jboss.home.url}/docs/examples/binding-manager/sample-bindings.xml</attribute>
- <attribute name="StoreFactoryClassName">
- org.jboss.services.binding.XMLServicesStoreFactory
- </attribute>
- </mbean>
- -->
-
- <!-- ==================================================================== -->
- <!-- Class Loading -->
- <!-- ==================================================================== -->
-
- <mbean code="org.jboss.web.WebService"
- name="jboss:service=WebService">
- <attribute name="Port">8083</attribute>
- <!-- Should non-EJB .class files be downloadable -->
- <attribute name="DownloadServerClasses">true</attribute>
- <!-- Should resources other than .class files be downloadable. Both
- DownloadServerClasses and DownloadResources must be true for resources
- to be downloadable. This is false by default because its generally a
- bad idea as server configuration files that container security
- information can be accessed.
- -->
- <attribute name="DownloadResources">false</attribute>
- <attribute name="Host">${jboss.bind.address}</attribute>
- <attribute name="BindAddress">${jboss.bind.address}</attribute>
- <!-- Use the default thread pool for dynamic class loading -->
- <depends optional-attribute-name="ThreadPool"
- proxy-type="attribute">jboss.system:service=ThreadPool</depends>
- </mbean>
-
- <!-- ==================================================================== -->
- <!-- JNDI -->
- <!-- ==================================================================== -->
-
- <mbean code="org.jboss.naming.NamingService"
- name="jboss:service=Naming"
- xmbean-dd="resource:xmdesc/NamingService-xmbean.xml">
- <!-- The call by value mode. true if all lookups are unmarshalled using
- the caller's TCL, false if in VM lookups return the value by reference.
- -->
- <attribute name="CallByValue">false</attribute>
- <!-- The listening port for the bootstrap JNP service. Set this to -1
- to run the NamingService without the JNP invoker listening port.
- -->
- <attribute name="Port">1099</attribute>
- <!-- The bootstrap JNP server bind address. This also sets the default
- RMI service bind address. Empty == all addresses
- -->
- <attribute name="BindAddress">${jboss.bind.address}</attribute>
- <!-- The port of the RMI naming service, 0 == anonymous -->
- <attribute name="RmiPort">1098</attribute>
- <!-- The RMI service bind address. Empty == all addresses
- -->
- <attribute name="RmiBindAddress">${jboss.bind.address}</attribute>
- <!-- The thread pool service used to control the bootstrap lookups -->
- <depends optional-attribute-name="LookupPool"
- proxy-type="attribute">jboss.system:service=ThreadPool</depends>
- </mbean>
-
- <mbean code="org.jboss.naming.JNDIView"
- name="jboss:service=JNDIView"
- xmbean-dd="resource:xmdesc/JNDIView-xmbean.xml">
- <!-- The HANamingService service name -->
- <attribute name="HANamingService">jboss:service=HAJNDI</attribute>
- </mbean>
-
- <!-- ==================================================================== -->
- <!-- Security -->
- <!-- ==================================================================== -->
-
- <mbean code="org.jboss.security.plugins.SecurityConfig"
- name="jboss.security:service=SecurityConfig">
- <attribute name="LoginConfig">jboss.security:service=XMLLoginConfig</attribute>
- </mbean>
- <mbean code="org.jboss.security.auth.login.XMLLoginConfig"
- name="jboss.security:service=XMLLoginConfig">
- <attribute name="ConfigResource">login-config.xml</attribute>
- </mbean>
-
- <!-- JAAS security manager and realm mapping -->
- <mbean code="org.jboss.security.plugins.JaasSecurityManagerService"
- name="jboss.security:service=JaasSecurityManager">
- <!-- A flag which indicates whether the SecurityAssociation server mode
- is set on service creation. This is true by default since the
- SecurityAssociation should be thread local for multi-threaded server
- operation.
- -->
- <attribute name="ServerMode">true</attribute>
- <attribute name="SecurityManagerClassName">org.jboss.security.plugins.JaasSecurityManager</attribute>
- <attribute name="DefaultUnauthenticatedPrincipal">anonymous</attribute>
- <!-- DefaultCacheTimeout: Specifies the default timed cache policy timeout
- in seconds.
- If you want to disable caching of security credentials, set this to 0 to
- force authentication to occur every time. This has no affect if the
- AuthenticationCacheJndiName has been changed from the default value.
- -->
- <attribute name="DefaultCacheTimeout">1800</attribute>
- <!-- DefaultCacheResolution: Specifies the default timed cache policy
- resolution in seconds. This controls the interval at which the cache
- current timestamp is updated and should be less than the DefaultCacheTimeout
- in order for the timeout to be meaningful. This has no affect if the
- AuthenticationCacheJndiName has been changed from the default value.
- -->
- <attribute name="DefaultCacheResolution">60</attribute>
- </mbean>
-
- <!-- ==================================================================== -->
- <!-- Transactions -->
- <!-- ==================================================================== -->
- <!-- The configurable Xid factory. For use with Oracle, set pad to true -->
- <mbean code="org.jboss.tm.XidFactory"
- name="jboss:service=XidFactory">
- <!--attribute name="Pad">true</attribute-->
- </mbean>
-
- <!--
- | The fast in-memory transaction manager.
-
- <mbean code="org.jboss.tm.TransactionManagerService"
- name="jboss:service=TransactionManager"
- xmbean-dd="resource:xmdesc/TransactionManagerService-xmbean.xml">
- <attribute name="TransactionTimeout">300</attribute>
- <!- set to false to disable transaction demarcation over IIOP ->
- <attribute name="GlobalIdsEnabled">true</attribute>
- <depends optional-attribute-name="XidFactory">jboss:service=XidFactory</depends>
-
- <!- Transaction Integrity Checking ->
- <!- Force a rollback if another thread is associated with the transaction at commit ->
- <!-depends optional-attribute-name="TransactionIntegrityFactory"
- proxy-type="org.jboss.tm.integrity.TransactionIntegrityFactory">
- <mbean code="org.jboss.tm.integrity.FailIncompleteTransaction"
- name="jboss:service=TransactionManager,plugin=TransactionIntegrity"/>
- </depends->
- </mbean-->
-
- <mbean code="com.arjuna.ats.jbossatx.jta.TransactionManagerService"
- name="jboss:service=TransactionManager">
- <attribute name="TransactionTimeout">300</attribute>
- </mbean>
-
- <!--
- | UserTransaction support.
- -->
- <mbean code="org.jboss.tm.usertx.server.ClientUserTransactionService"
- name="jboss:service=ClientUserTransaction"
- xmbean-dd="resource:xmdesc/ClientUserTransaction-xmbean.xml">
- <depends>
- <mbean code="org.jboss.invocation.jrmp.server.JRMPProxyFactory"
- name="jboss:service=proxyFactory,target=ClientUserTransactionFactory">
- <attribute name="InvokerName">jboss:service=invoker,type=jrmp</attribute>
- <attribute name="TargetName">jboss:service=ClientUserTransaction</attribute>
- <attribute name="JndiName">UserTransactionSessionFactory</attribute>
- <attribute name="ExportedInterface">org.jboss.tm.usertx.interfaces.UserTransactionSessionFactory</attribute>
- <attribute name="ClientInterceptors">
- <interceptors>
- <interceptor>org.jboss.proxy.ClientMethodInterceptor</interceptor>
- <interceptor>org.jboss.invocation.InvokerInterceptor</interceptor>
- </interceptors>
- </attribute>
- <depends>jboss:service=invoker,type=jrmp</depends>
- </mbean>
- </depends>
- <depends optional-attribute-name="TxProxyName">
- <mbean code="org.jboss.invocation.jrmp.server.JRMPProxyFactory"
- name="jboss:service=proxyFactory,target=ClientUserTransaction">
- <attribute name="InvokerName">jboss:service=invoker,type=jrmp</attribute>
- <attribute name="TargetName">jboss:service=ClientUserTransaction</attribute>
- <attribute name="JndiName"></attribute>
- <attribute name="ExportedInterface">org.jboss.tm.usertx.interfaces.UserTransactionSession</attribute>
- <attribute name="ClientInterceptors">
- <interceptors>
- <interceptor>org.jboss.proxy.ClientMethodInterceptor</interceptor>
- <interceptor>org.jboss.invocation.InvokerInterceptor</interceptor>
- </interceptors>
- </attribute>
- <depends>jboss:service=invoker,type=jrmp</depends>
- </mbean>
- </depends>
- </mbean>
-
- <!-- ==================================================================== -->
- <!-- Invokers to the JMX node -->
- <!-- ==================================================================== -->
-
- <!-- RMI/JRMP invoker -->
- <mbean code="org.jboss.invocation.jrmp.server.JRMPInvoker"
- name="jboss:service=invoker,type=jrmp">
- <attribute name="RMIObjectPort">4444</attribute>
- <attribute name="ServerAddress">${jboss.bind.address}</attribute>
- <!--
- <attribute name="RMIClientSocketFactory">custom</attribute>
- <attribute name="RMIServerSocketFactory">custom</attribute>
- <attribute name="RMIServerSocketAddr">custom</attribute>
- <attribute name="SecurityDomain">ssl-domain-name</attribute>
- -->
- <depends>jboss:service=TransactionManager</depends>
- </mbean>
-
- <mbean code="org.jboss.invocation.local.LocalInvoker"
- name="jboss:service=invoker,type=local">
-
- <depends>jboss:service=TransactionManager</depends>
- </mbean>
-
- <mbean code="org.jboss.invocation.pooled.server.PooledInvoker"
- name="jboss:service=invoker,type=pooled">
- <attribute name="NumAcceptThreads">1</attribute>
- <attribute name="MaxPoolSize">300</attribute>
- <attribute name="ClientMaxPoolSize">300</attribute>
- <attribute name="SocketTimeout">60000</attribute>
- <attribute name="ServerBindAddress">${jboss.bind.address}</attribute>
- <attribute name="ServerBindPort">4445</attribute>
- <attribute name="ClientConnectAddress">${jboss.bind.address}</attribute>
- <attribute name="ClientConnectPort">0</attribute>
- <attribute name="ClientRetryCount">1</attribute>
- <attribute name="EnableTcpNoDelay">false</attribute>
-
- <!-- Customized socket factory attributes
- <attribute name="ClientSocketFactoryName">custom.client.factory</attribute>
- <attribute name="ServerSocketFactoryName">custom.server.factory</attribute>
- <attribute name="SslDomain">java:/jaas/pooledInvoker</attribute>
- -->
- <depends optional-attribute-name="TransactionManagerService">jboss:service=TransactionManager</depends>
- </mbean>
-
- <!-- ==================================================================== -->
- <!-- Monitoring and Management -->
- <!-- ==================================================================== -->
-
- <!-- Uncomment to enable JMX monitoring of the bean cache
- <mbean code="org.jboss.monitor.BeanCacheMonitor"
- name="jboss.monitor:name=BeanCacheMonitor"/>
- -->
-
- <!-- Uncomment to enable JMX monitoring of the entity bean locking
- <mbean code="org.jboss.monitor.EntityLockMonitor"
- name="jboss.monitor:name=EntityLockMonitor"/>
- -->
-
- <!-- ==================================================================== -->
- <!-- An MBean that is a registry for JDBC type-mapping metadata -->
- <!-- ==================================================================== -->
-
- <mbean code="org.jboss.ejb.plugins.cmp.jdbc.metadata.MetaDataLibrary"
- name="jboss.jdbc:service=metadata"/>
-
- <!-- ==================================================================== -->
- <!-- Deployment Scanning -->
- <!-- ==================================================================== -->
-
- <!-- An mbean for hot deployment/undeployment of archives.
- -->
- <mbean code="org.jboss.deployment.scanner.URLDeploymentScanner"
- name="jboss.deployment:type=DeploymentScanner,flavor=URL">
-
- <!-- Uncomment (and comment/remove version below) to enable usage of the
- DeploymentCache
- <depends optional-attribute-name="Deployer">jboss.deployment:type=DeploymentCache</depends>
- -->
- <depends optional-attribute-name="Deployer">jboss.system:service=MainDeployer</depends>
-
- <!-- The URLComparator can be used to specify a deployment ordering
- for deployments found in a scanned directory. The class specified
- must be an implementation of java.util.Comparator, it must be able
- to compare two URL objects, and it must have a no-arg constructor.
- Two deployment comparators are shipped with JBoss:
- - org.jboss.deployment.DeploymentSorter
- Sorts by file extension, as follows:
- "sar", "service.xml", "rar", "jar", "war", "wsr", "ear", "zip",
- "*"
- - org.jboss.deployment.scanner.PrefixDeploymentSorter
- If the name portion of the url begins with 1 or more digits, those
- digits are converted to an int (ignoring leading zeroes), and
- files are deployed in that order. Files that do not start with
- any digits will be deployed first, and they will be sorted by
- extension as above with DeploymentSorter.
- -->
- <attribute name="URLComparator">org.jboss.deployment.DeploymentSorter</attribute>
-
- <!--
- <attribute name="URLComparator">org.jboss.deployment.scanner.PrefixDeploymentSorter</attribute>
- -->
-
- <!-- The FilterInstance specifies a URLLister.URLFilter for scanned
- directories. This DeploymentFilter is initialized with the given
- prefixes, suffixes and matches that define which URLs should be
- ignored.
- -->
- <attribute name="FilterInstance"
- attributeClass="org.jboss.deployment.scanner.DeploymentFilter"
- serialDataType="javaBean">
- <!-- Files starting with theses strings are ignored -->
- <property name="prefixes">#,%,\,,.,_$</property>
- <!-- Files ending with theses strings are ignored -->
- <property name="suffixes">#,$,%,~,\,v,.BAK,.bak,.old,.orig,.tmp,.rej,.sh</property>
- <!-- Files matching with theses strings are ignored -->
- <property name="matches">.make.state,.nse_depinfo,CVS,CVS.admin,RCS,RCSLOG,SCCS,TAGS,core,tags</property>
- </attribute>
-
- <!-- Frequency in milliseconds to rescan the URLs for changes -->
- <attribute name="ScanPeriod">5000</attribute>
-
- <!-- A flag to disable the scans -->
- <attribute name="ScanEnabled">true</attribute>
-
- <!-- URLs are comma separated and resolve relative to the server home URL
- unless the given path is absolute. If the URL ends in "/" it is
- considered a collection and scanned, otherwise it is simply deployed;
- this follows RFC2518 convention and allows discrimination between
- collections and directories that are simply unpacked archives.
-
- URLs may be local (file:) or remote (http:). Scanning is supported
- for remote URLs but unpacked deployment units are not.
-
- Example URLs:
- deploy/
- scans ${jboss.server.url}/deploy/, which is local or remote
- depending on the URL used to boot the server
- ${jboss.server.home}/deploy/
- scans ${jboss.server.home)/deploy, which is always local
- file:/var/opt/myapp.ear
- deploy myapp.ear from a local location
- file:/var/opt/apps/
- scans the specified directory
- http://www.test.com/netboot/myapp.ear
- deploys myapp.ear from a remote location
- http://www.test.com/netboot/apps/
- scans the specified WebDAV location
- -->
- <attribute name="URLs">
- deploy/
- </attribute>
-
- <!-- Indicates if the scanner should recursively scan directories that
- contain no "." in their names. This can be used to group applications
- and services that must be deployed and that have the same
- logical function in the same directory i.e.
- deploy/JMX/
- deploy/JMS/
- ...
- -->
- <attribute name="RecursiveSearch">True</attribute>
-
- </mbean>
-
-</server>
Copied: trunk/lib/jbossts/jboss-service.xml (from rev 1823, branches/Branch_1_0/lib/jbossts/jboss-service.xml)
Deleted: trunk/lib/jbossts/jbossjta-properties.xml
===================================================================
--- branches/Branch_1_0/lib/jbossts/jbossjta-properties.xml 2006-12-19 06:51:01 UTC (rev 1823)
+++ trunk/lib/jbossts/jbossjta-properties.xml 2006-12-21 23:41:19 UTC (rev 1843)
@@ -1,278 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<transaction-service>
- <properties depends="common" name="arjuna">
- <!--
- Transaction Reaper Timeout (default is 120000 microseconds).
- -->
- <property
- name="com.arjuna.ats.arjuna.coordinator.txReaperTimeout" value="120000"/>
- <!--
- Transaction Reaper Mode, can be: NORMAL or DYNAMIC (default is NORMAL).
- -->
- <property name="com.arjuna.ats.arjuna.coordinator.txReaperMode" value="NORMAL"/>
- <!--
- (default is NO)
- -->
- <property name="com.arjuna.ats.arjuna.coordinator.asyncCommit" value="NO"/>
- <!--
- (default is NO)
- -->
- <property name="com.arjuna.ats.arjuna.coordinator.asyncPrepare" value="NO"/>
- <!--
- (default is YES)
- -->
- <property
- name="com.arjuna.ats.arjuna.coordinator.commitOnePhase" value="YES"/>
- <!--
- (default is defaultStore)
- -->
- <property name="com.arjuna.ats.arjuna.objectstore.localOSRoot" value="defaultStore"/>
- <!--
- default is under user.home - must be writeable!)
- -->
- <property
- name="com.arjuna.ats.arjuna.objectstore.objectStoreDir" value="PutObjectStoreDirHere"/>
- <!--
- (default is ON)
- -->
- <property
- name="com.arjuna.ats.arjuna.objectstore.objectStoreSync" value="ON"/>
- <!--
- (default is ShadowNoFileLockStore)
- -->
- <property
- name="com.arjuna.ats.arjuna.objectstore.objectStoreType" value="ShadowNoFileLockStore"/>
- <!--
- (default is 255)
- -->
- <property
- name="com.arjuna.ats.arjuna.objectstore.hashedDirectories" value="255"/>
- <!--
- (default is ON)
- -->
- <property
- name="com.arjuna.ats.arjuna.objectstore.transactionSync" value="ON"/>
- <!--
- (Must be unique across all Arjuna instances.)
- -->
- <property name="com.arjuna.ats.arjuna.xa.nodeIdentifier" value="1"/>
- <!-- property
- name="com.arjuna.ats.arjuna.coordinator.actionStore"
- value="HashedActionStore"
- value="JDBCActionStore"
- -->
- <!-- property
- name="com.arjuna.ats.arjuna.objectstore.jdbcTxDbAccess"
- value="JDBCAccess"
- -->
- <!-- property
- name="com.arjuna.ats.arjuna.objectstore.objectStoreType"
- value="ShadowNoFileLockStore"
- value="JDBCStore"
- -->
- <!-- property
- name="com.arjuna.ats.arjuna.objectstore.jdbcUserDbAccess"
- value="JDBCAccess"
- -->
- <!-- property
- name="com.arjuna.ats.arjuna.objectstore.jdbcPoolSizeInitial"
- value="1"
- -->
- <!-- property
- name="com.arjuna.ats.arjuna.objectstore.jdbcPoolSizeMaximum"
- value="1"
- -->
- <!-- property
- name="com.arjuna.ats.arjuna.objectstore.jdbcPoolPutConnections"
- value="false"
- -->
- <!-- property
- name="com.arjuna.ats.arjuna.internal.arjuna.objectstore.cacheStore.size"
- value=""
- -->
- <!-- property
- name="com.arjuna.ats.arjuna.internal.arjuna.objectstore.cacheStore.period"
- value=""
- -->
- <!--
- The location for creating temporary files, e.g., Uids.
- Default is under user.home.
- IMPORTANT: make sure the directory is lockable, e.g., /tmp on Unix
- may not be!
- -->
- <!--
- <property
- name="com.arjuna.ats.arjuna.common.varDir"
- value="var"/>
- -->
- </properties>
- <properties depends="arjuna" name="recoverymanager">
- <!--
- Properties used only by the RecoveryManager.
- -->
- <!--
- Periodic recovery settings.
- Time values in this section are in seconds.
- -->
- <!--
- Interval in seconds between initiating the periodic recovery modules.
- Default is 120 seconds.
- -->
- <property
- name="com.arjuna.ats.arjuna.recovery.periodicRecoveryPeriod" value="120"/>
- <!--
- Interval in seconds between first and second pass of periodic recovery.
- Default is 10 seconds.
- -->
- <property
- name="com.arjuna.ats.arjuna.recovery.recoveryBackoffPeriod" value="10"/>
-
- <!--
- Expired entry removal
- -->
- <!--
- Expiry scanners to use (order of invocation is random).
- Names must begin with "com.arjuna.ats.arjuna.recovery.expiryScanner"
- -->
- <property
- name="com.arjuna.ats.arjuna.recovery.expiryScannerTransactionStatusManager" value="com.arjuna.ats.internal.arjuna.recovery.ExpiredTransactionStatusManagerScanner"/>
- <!--
- Interval, in hours, between running the expiry scanners.
- This can be quite long. The absolute value determines the interval -
- if the value is negative, the scan will NOT be run until after one
- interval has elapsed. If positive the first scan will be immediately
- after startup. Zero will prevent any scanning.
- Default = 12 = run immediately, then every 12 hours.
- -->
- <property
- name="com.arjuna.ats.arjuna.recovery.expiryScanInterval" value="12"/>
- <!--
- Age, in hours, for removal of transaction status manager item.
- This should be longer than any ts-using process will remain running.
- Zero = Never removed. Default is 12.
- -->
- <property
- name="com.arjuna.ats.arjuna.recovery.transactionStatusManagerExpiryTime" value="12"/>
- <!--
- Use this to fix the port on which the TransactionStatusManager listens,
- The default behaviour is to use any free port.
- -->
- <property
- name="com.arjuna.ats.arjuna.recovery.transactionStatusManagerPort" value="0"/>
- <!--
- Properties used only by the RecoveryManager.
- -->
- <!--
- Periodic recovery settings.
- Time values in this section are in seconds.
- -->
- <!--
- Interval in seconds between initiating the periodic recovery modules.
- Default is 120 seconds.
- -->
- <property
- name="com.arjuna.ats.arjuna.recovery.periodicRecoveryPeriod" value="120"/>
- <!--
- Interval in seconds between first and second pass of periodic recovery.
- Default is 10 seconds.
- -->
- <property
- name="com.arjuna.ats.arjuna.recovery.recoveryBackoffPeriod" value="10"/>
- <!--
- Periodic recovery modules to use. Invoked in sort-order of names.
- -->
- <property
- name="com.arjuna.ats.arjuna.recovery.recoveryExtension1" value="com.arjuna.ats.internal.jta.recovery.arjunacore.XARecoveryModule"/>
- <!--
- Expired entry removal
- -->
- <!--
- Expiry scanners to use (order of invocation is random).
- Names must begin with "com.arjuna.ats.arjuna.recovery.expiryScanner"
- -->
- <property
- name="com.arjuna.ats.arjuna.recovery.expiryScannerTransactionStatusManager" value="com.arjuna.ats.internal.arjuna.recovery.ExpiredTransactionStatusManagerScanner"/>
- <!--
- Interval, in hours, between running the expiry scanners.
- This can be quite long. The absolute value determines the interval -
- if the value is negative, the scan will NOT be run until after one
- interval has elapsed. If positive the first scan will be immediately
- after startup. Zero will prevent any scanning.
- Default = 12 = run immediately, then every 12 hours.
- -->
- <property
- name="com.arjuna.ats.arjuna.recovery.expiryScanInterval" value="12"/>
- <!--
- Age, in hours, for removal of transaction status manager item.
- This should be longer than any ts-using process will remain running.
- Zero = Never removed. Default is 12.
- -->
- <property
- name="com.arjuna.ats.arjuna.recovery.transactionStatusManagerExpiryTime" value="12"/>
- <!--
- Use this to fix the port on which the TransactionStatusManager listens,
- The default behaviour is to use any free port.
- -->
- <property
- name="com.arjuna.ats.arjuna.recovery.transactionStatusManagerPort" value="0"/>
- </properties>
- <properties name="common">
- <!-- CLF 2.0 properties -->
- <property name="com.arjuna.common.util.logging.DebugLevel"
- type="System" value="0x00000000"/>
- <property name="com.arjuna.common.util.logging.FacilityLevel"
- type="System" value="0xffffffff"/>
- <property name="com.arjuna.common.util.logging.VisibilityLevel"
- type="System" value="0xffffffff"/>
- <property name="com.arjuna.common.util.logger" type="System" value="log4j"/>
- </properties>
- <properties depends="arjuna" name="txoj">
- <!--
- (default is LockStore of installation - must be writeable!)
- -->
- <!--
- <property
- name="com.arjuna.ats.txoj.lockstore.lockStoreDir"
- value="LockStore"/>
- -->
- <!--
- (default is BasicLockStore)
- -->
- <property name="com.arjuna.ats.txoj.lockstore.lockStoreType" value="BasicLockStore"/>
- <!--
- (default is NO)
- -->
- <property name="com.arjuna.ats.txoj.lockstore.multipleLockStore" value="NO"/>
- <!--
- (default is YES)
- -->
- <property name="com.arjuna.ats.txoj.lockstore.singleLockStore" value="YES"/>
- <!--
- (default is YES)
- -->
- <property
- name="com.arjuna.ats.txoj.lockstore.allowNestedLocking" value="YES"/>
- </properties>
- <properties depends="arjuna" name="jta">
- <property
- name="com.arjuna.ats.jta.recovery.XAResourceRecovery.JBMESSAGING" value="org.jboss.jms.recovery.JMSProviderXAResourceRecovery"/>
- <!--
- Support subtransactions in the JTA layer?
- Default is NO.
- -->
- <property name="com.arjuna.ats.jta.supportSubtransactions" value="NO"/>
- <property name="com.arjuna.ats.jta.jtaTMImplementation" value="com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionManagerImple"/>
- <!--
- com.arjuna.ats.internal.jta.transaction.jts.TransactionManagerImple
- -->
- <property name="com.arjuna.ats.jta.jtaUTImplementation" value="com.arjuna.ats.internal.jta.transaction.arjunacore.UserTransactionImple"/>
- <!--
- com.arjuna.ats.internal.jta.transaction.jts.UserTransactionImple
- -->
- </properties>
- <properties depends="jta" name="jdbc">
- <!--
- property name="com.arjuna.ats.jdbc.isolationLevel" value="TRANSACTION_SERIALIZABLE"/>
- -->
- </properties>
-</transaction-service>
Copied: trunk/lib/jbossts/jbossjta-properties.xml (from rev 1823, branches/Branch_1_0/lib/jbossts/jbossjta-properties.xml)
Modified: trunk/src/etc/server/default/deploy/clustered-mysql-persistence-service.xml
===================================================================
--- trunk/src/etc/server/default/deploy/clustered-mysql-persistence-service.xml 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/src/etc/server/default/deploy/clustered-mysql-persistence-service.xml 2006-12-21 23:41:19 UTC (rev 1843)
@@ -35,7 +35,7 @@
ROLLBACK_MESSAGE_REF1=DELETE FROM JMS_MESSAGE_REFERENCE WHERE TRANSACTIONID=? AND STATE='+'
ROLLBACK_MESSAGE_REF2=UPDATE JMS_MESSAGE_REFERENCE SET STATE='C', TRANSACTIONID = NULL WHERE TRANSACTIONID=? AND STATE='-'
LOAD_PAGED_REFS=SELECT MESSAGEID, DELIVERYCOUNT, PAGE_ORD, RELIABLE FROM JMS_MESSAGE_REFERENCE WHERE CHANNELID = ? AND PAGE_ORD BETWEEN ? AND ? ORDER BY PAGE_ORD
-LOAD_UNPAGED_REFS=SELECT MESSAGEID, DELIVERYCOUNT, RELIABLE FROM JMS_MESSAGE_REFERENCE WHERE PAGE_ORD IS NULL and CHANNELID = ? ORDER BY ORD
+LOAD_UNPAGED_REFS=SELECT MESSAGEID, DELIVERYCOUNT, RELIABLE FROM JMS_MESSAGE_REFERENCE WHERE STATE = 'C' AND CHANNELID = ? AND PAGE_ORD IS NULL ORDER BY ORD
UPDATE_RELIABLE_REFS_NOT_PAGED=UPDATE JMS_MESSAGE_REFERENCE SET PAGE_ORD = NULL WHERE PAGE_ORD BETWEEN ? AND ? AND CHANNELID=?
SELECT_MIN_MAX_PAGE_ORD=SELECT MIN(PAGE_ORD), MAX(PAGE_ORD) FROM JMS_MESSAGE_REFERENCE WHERE CHANNELID = ?
SELECT_EXISTS_REF=SELECT MESSAGEID FROM JMS_MESSAGE_REFERENCE WHERE CHANNELID = ? AND MESSAGEID = ?
@@ -50,6 +50,8 @@
INSERT_TRANSACTION=INSERT INTO JMS_TRANSACTION (TRANSACTIONID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID) VALUES(?, ?, ?, ?)
DELETE_TRANSACTION=DELETE FROM JMS_TRANSACTION WHERE TRANSACTIONID = ?
SELECT_PREPARED_TRANSACTIONS=SELECT TRANSACTIONID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID FROM JMS_TRANSACTION
+SELECT_MESSAGEID_FOR_REF=SELECT MESSAGEID, CHANNELID FROM JMS_MESSAGE_REFERENCE WHERE TRANSACTIONID = ? AND STATE = '+'
+SELECT_MESSAGEID_FOR_ACK=SELECT MESSAGEID, CHANNELID FROM JMS_MESSAGE_REFERENCE WHERE TRANSACTIONID = ? AND STATE = '-'
UPDATE_COUNTER=UPDATE JMS_COUNTER SET NEXT_ID = ? WHERE NAME=?
SELECT_COUNTER=SELECT NEXT_ID FROM JMS_COUNTER WHERE NAME=? FOR UPDATE
INSERT_COUNTER=INSERT INTO JMS_COUNTER (NAME, NEXT_ID) VALUES (?, ?)
Modified: trunk/src/etc/server/default/deploy/mysql-persistence-service.xml
===================================================================
--- trunk/src/etc/server/default/deploy/mysql-persistence-service.xml 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/src/etc/server/default/deploy/mysql-persistence-service.xml 2006-12-21 23:41:19 UTC (rev 1843)
@@ -35,7 +35,7 @@
ROLLBACK_MESSAGE_REF1=DELETE FROM JMS_MESSAGE_REFERENCE WHERE TRANSACTIONID=? AND STATE='+'
ROLLBACK_MESSAGE_REF2=UPDATE JMS_MESSAGE_REFERENCE SET STATE='C', TRANSACTIONID = NULL WHERE TRANSACTIONID=? AND STATE='-'
LOAD_PAGED_REFS=SELECT MESSAGEID, DELIVERYCOUNT, PAGE_ORD, RELIABLE FROM JMS_MESSAGE_REFERENCE WHERE CHANNELID = ? AND PAGE_ORD BETWEEN ? AND ? ORDER BY PAGE_ORD
- LOAD_UNPAGED_REFS=SELECT MESSAGEID, DELIVERYCOUNT, RELIABLE FROM JMS_MESSAGE_REFERENCE WHERE PAGE_ORD IS NULL and CHANNELID = ? ORDER BY ORD
+ LOAD_UNPAGED_REFS=SELECT MESSAGEID, DELIVERYCOUNT, RELIABLE FROM JMS_MESSAGE_REFERENCE WHERE STATE = 'C' AND CHANNELID = ? AND PAGE_ORD IS NULL ORDER BY ORD
UPDATE_RELIABLE_REFS_NOT_PAGED=UPDATE JMS_MESSAGE_REFERENCE SET PAGE_ORD = NULL WHERE PAGE_ORD BETWEEN ? AND ? AND CHANNELID=?
SELECT_MIN_MAX_PAGE_ORD=SELECT MIN(PAGE_ORD), MAX(PAGE_ORD) FROM JMS_MESSAGE_REFERENCE WHERE CHANNELID = ?
SELECT_EXISTS_REF=SELECT MESSAGEID FROM JMS_MESSAGE_REFERENCE WHERE CHANNELID = ? AND MESSAGEID = ?
@@ -49,7 +49,9 @@
MESSAGE_EXISTS=SELECT MESSAGEID FROM JMS_MESSAGE WHERE MESSAGEID = ? FOR UPDATE
INSERT_TRANSACTION=INSERT INTO JMS_TRANSACTION (TRANSACTIONID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID) VALUES(?, ?, ?, ?)
DELETE_TRANSACTION=DELETE FROM JMS_TRANSACTION WHERE TRANSACTIONID = ?
- SELECT_PREPARED_TRANSACTIONS=SELECT TRANSACTIONID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID FROM JMS_TRANSACTION
+ SELECT_PREPARED_TRANSACTIONS=SELECT TRANSACTIONID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID FROM JMS_TRANSACTION
+ SELECT_MESSAGEID_FOR_REF=SELECT MESSAGEID, CHANNELID FROM JMS_MESSAGE_REFERENCE WHERE TRANSACTIONID = ? AND STATE = '+'
+ SELECT_MESSAGEID_FOR_ACK=SELECT MESSAGEID, CHANNELID FROM JMS_MESSAGE_REFERENCE WHERE TRANSACTIONID = ? AND STATE = '-'
UPDATE_COUNTER=UPDATE JMS_COUNTER SET NEXT_ID = ? WHERE NAME=?
SELECT_COUNTER=SELECT NEXT_ID FROM JMS_COUNTER WHERE NAME=? FOR UPDATE
INSERT_COUNTER=INSERT INTO JMS_COUNTER (NAME, NEXT_ID) VALUES (?, ?)
@@ -71,7 +73,7 @@
CREATE_POSTOFFICE_TABLE=CREATE TABLE JMS_POSTOFFICE (POSTOFFICE_NAME VARCHAR(255), NODE_ID INTEGER, QUEUE_NAME VARCHAR(1023), COND VARCHAR(1023), SELECTOR VARCHAR(1023), CHANNEL_ID BIGINT, IS_FAILED_OVER CHAR(1))
INSERT_BINDING=INSERT INTO JMS_POSTOFFICE (POSTOFFICE_NAME, NODE_ID, QUEUE_NAME, COND, SELECTOR, CHANNEL_ID, IS_FAILED_OVER) VALUES (?, ?, ?, ?, ?, ?, ?)
DELETE_BINDING=DELETE FROM JMS_POSTOFFICE WHERE POSTOFFICE_NAME=? AND NODE_ID=? AND QUEUE_NAME=?
-LOAD_BINDINGS=SELECT NODE_ID, QUEUE_NAME, COND, SELECTOR, CHANNEL_ID FROM JMS_POSTOFFICE WHERE POSTOFFICE_NAME = ?
+LOAD_BINDINGS=SELECT NODE_ID, QUEUE_NAME, COND, SELECTOR, CHANNEL_ID, IS_FAILED_OVER FROM JMS_POSTOFFICE WHERE POSTOFFICE_NAME = ?
]]></attribute>
</mbean>
Modified: trunk/src/main/org/jboss/jms/client/container/ConnectionAspect.java
===================================================================
--- trunk/src/main/org/jboss/jms/client/container/ConnectionAspect.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/src/main/org/jboss/jms/client/container/ConnectionAspect.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -32,6 +32,7 @@
import org.jboss.jms.client.delegate.ClientConnectionDelegate;
import org.jboss.jms.client.state.ConnectionState;
import org.jboss.jms.message.MessageIdGeneratorFactory;
+import org.jboss.jms.tx.ResourceManagerFactory;
import org.jboss.logging.Logger;
import org.jboss.remoting.Client;
@@ -185,6 +186,9 @@
// Remove reference to message ID generator
MessageIdGeneratorFactory.instance.checkInGenerator(state.getServerID());
+
+ // And to resource manager
+ ResourceManagerFactory.instance.checkInResourceManager(state.getServerID());
return ret;
}
Modified: trunk/src/main/org/jboss/jms/client/container/ExceptionInterceptor.java
===================================================================
--- trunk/src/main/org/jboss/jms/client/container/ExceptionInterceptor.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/src/main/org/jboss/jms/client/container/ExceptionInterceptor.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -25,7 +25,6 @@
import org.jboss.aop.advice.Interceptor;
import org.jboss.aop.joinpoint.Invocation;
-import org.jboss.jms.util.MessagingJMSException;
import org.jboss.logging.Logger;
/**
@@ -70,40 +69,19 @@
}
catch(JMSException e)
{
- if (trace) { log.trace("Caught JMSException:" + e); }
- Exception linked = e.getLinkedException();
- if (linked != null)
- {
- log.error("Linked exception is: ", linked);
- }
- logCause(e);
+ // JMSException should not be logged unless trace is on
+ if (trace) { log.trace("Caught JMSException:", e); }
+
throw e;
}
- catch (UnsupportedOperationException e)
+ catch (Throwable t)
{
- //These must be propagated to the client
- throw e;
- }
- catch (RuntimeException e)
- {
- log.error("Caught RuntimeException", e);
- logCause(e);
- JMSException ex = new javax.jms.IllegalStateException(e.getMessage());
- ex.setLinkedException(e);
- throw ex;
- }
- catch (Exception e)
- {
- log.error("Caught Exception: ", e);
- logCause(e);
- throw new MessagingJMSException("Caught exception", e);
- }
- catch (Error e)
- {
- log.error("Caught Error: ", e);
- logCause(e);
- throw e;
- }
+ //We log everything else
+
+ log(t);
+
+ throw t;
+ }
}
// Package protected ---------------------------------------------
@@ -112,13 +90,13 @@
// Private -------------------------------------------------------
- private void logCause(Throwable e)
+ private void log(Throwable e)
{
+ log.error("Caught throwable", e);
Throwable e2 = e.getCause();
if (e2 != null)
{
- log.error("Cause of exception:", e2);
- logCause(e2);
+ log(e2);
}
}
Modified: trunk/src/main/org/jboss/jms/client/container/HAAspect.java
===================================================================
--- trunk/src/main/org/jboss/jms/client/container/HAAspect.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/src/main/org/jboss/jms/client/container/HAAspect.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -24,7 +24,6 @@
import java.util.ArrayList;
import java.util.Collections;
-import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -32,10 +31,10 @@
import javax.jms.JMSException;
import javax.jms.Session;
-import org.jboss.aop.joinpoint.Invocation;
-import org.jboss.aop.joinpoint.MethodInvocation;
import org.jboss.aop.Advised;
import org.jboss.aop.advice.Interceptor;
+import org.jboss.aop.joinpoint.Invocation;
+import org.jboss.aop.joinpoint.MethodInvocation;
import org.jboss.jms.client.delegate.ClientBrowserDelegate;
import org.jboss.jms.client.delegate.ClientConnectionDelegate;
import org.jboss.jms.client.delegate.ClientConnectionFactoryDelegate;
@@ -58,9 +57,10 @@
import org.jboss.jms.server.endpoint.DeliveryInfo;
import org.jboss.jms.server.endpoint.DeliveryRecovery;
import org.jboss.jms.tx.ResourceManager;
+import org.jboss.jms.tx.ResourceManagerFactory;
import org.jboss.logging.Logger;
-import org.jboss.remoting.ConnectionListener;
import org.jboss.remoting.Client;
+import org.jboss.remoting.ConnectionListener;
/**
*
@@ -381,7 +381,7 @@
}
protected void performClientSideFailover(ClientConnectionDelegate failedConnDelegate,
- ClientConnectionDelegate newConnDelegate)
+ ClientConnectionDelegate newConnDelegate)
throws Exception
{
log.debug(this + " performing client side failover");
@@ -401,16 +401,24 @@
// We need to update some of the attributes on the state
failedState.copyState(newState);
+
+ int failedServerId = failedConnDelegate.getServerID();
+
+ int newServerId = newConnDelegate.getServerID();
+
+ if (trace) { log.trace("Failing over from " + failedServerId + " to " + newServerId); }
+
+ // There is one RM per server, so we need to merge the rms if necessary
+ ResourceManagerFactory.instance.handleFailover(failedServerId, newServerId);
+
+ ResourceManager rm = failedState.getResourceManager();
- // Map of old session ID to new session state
- Map oldNewSessionStateMap = new HashMap();
-
for(Iterator i = failedState.getChildren().iterator(); i.hasNext(); )
{
SessionState failedSessionState = (SessionState)i.next();
+
+ int oldSessionId = failedSessionState.getSessionId();
- int oldSessionID = failedSessionState.getSessionId();
-
ClientSessionDelegate failedSessionDelegate =
(ClientSessionDelegate)failedSessionState.getDelegate();
@@ -420,11 +428,11 @@
failedSessionState.isXA());
SessionState newSessionState = (SessionState)newSessionDelegate.getState();
+
+ int newSessionId = newSessionState.getSessionId();
if (trace) { log.trace("new session state has " + newSessionState.getClientAckList().size() + " deliveries"); }
- oldNewSessionStateMap.put(new Integer(oldSessionID), failedSessionState);
-
failedSessionDelegate.copyAttributes(newSessionDelegate);
// We need to update some of the attributes on the state
@@ -448,34 +456,26 @@
handleFailoverOnBrowser((BrowserState)sessionChild, newSessionDelegate);
}
}
- }
-
- // First we must tell the resource manager to substitute old session ID for new session ID.
- // Note we MUST submit the entire mapping in one operation since there may be overlap between
- // old and new session ID, and we don't want to overwrite keys in the map.
-
- failedState.getResourceManager().handleFailover(oldNewSessionStateMap);
-
- for(Iterator i = oldNewSessionStateMap.values().iterator(); i.hasNext(); )
- {
+
+ // We need to failover from one session id to another in the resource manager
+ rm.handleFailover(newServerId, oldSessionId, newSessionId);
+
List ackInfos = Collections.EMPTY_LIST;
- SessionState state = (SessionState)i.next();
-
- if (!state.isTransacted() ||
- (state.isXA() && state.getCurrentTxId() == null))
+ if (!failedSessionState.isTransacted() ||
+ (failedSessionState.isXA() && failedSessionState.getCurrentTxId() == null))
{
// Non transacted session or an XA session with no transaction set (it falls back
// to auto_ack)
- if (trace) { log.trace(state + " is not transacted (or XA with no tx set), retrieving deliveries from session state"); }
+ if (trace) { log.trace(failedSessionState + " is not transacted (or XA with no tx set), retrieving deliveries from session state"); }
// We remove any unacked non-persistent messages - this is because we don't want to ack
// them since the server won't know about them and will get confused
- if (state.getAcknowledgeMode() == Session.CLIENT_ACKNOWLEDGE)
+ if (failedSessionState.getAcknowledgeMode() == Session.CLIENT_ACKNOWLEDGE)
{
- for(Iterator j = state.getClientAckList().iterator(); j.hasNext(); )
+ for(Iterator j = failedSessionState.getClientAckList().iterator(); j.hasNext(); )
{
DeliveryInfo info = (DeliveryInfo)j.next();
if (!info.getMessageProxy().getMessage().isReliable())
@@ -485,17 +485,17 @@
}
}
- ackInfos = state.getClientAckList();
+ ackInfos = failedSessionState.getClientAckList();
}
else
{
- DeliveryInfo autoAck = state.getAutoAckInfo();
+ DeliveryInfo autoAck = failedSessionState.getAutoAckInfo();
if (autoAck != null)
{
if (!autoAck.getMessageProxy().getMessage().isReliable())
{
// unreliable, discard
- state.setAutoAckInfo(null);
+ failedSessionState.setAutoAckInfo(null);
}
else
{
@@ -513,13 +513,12 @@
// Transacted session - we need to get the acks from the resource manager. BTW we have
// kept the old resource manager
- ResourceManager rm = failedState.getResourceManager();
- ackInfos = rm.getDeliveriesForSession(state.getSessionId());
+ ackInfos = rm.getDeliveriesForSession(failedSessionState.getSessionId());
}
if (!ackInfos.isEmpty())
{
- SessionDelegate newDelegate = (SessionDelegate)state.getDelegate();
+ SessionDelegate newDelegate = (SessionDelegate)failedSessionState.getDelegate();
List recoveryInfos = new ArrayList();
@@ -586,17 +585,6 @@
// Update attributes on the old state
failedConsumerState.copyState(newState);
-// if (failedSessionState.isTransacted() || failedSessionState.isXA())
-// {
-// // Replace the old consumer id with the new consumer id
-//
-// ResourceManager rm = failedConnectionState.getResourceManager();
-//
-// todo - we need to replace the sesion id
-//
-// rm.handleFailover(oldConsumerID, failedConsumerState.getConsumerID());
-// }
-
// We need to re-use the existing message callback handler
MessageCallbackHandler oldHandler =
Modified: trunk/src/main/org/jboss/jms/client/container/SessionAspect.java
===================================================================
--- trunk/src/main/org/jboss/jms/client/container/SessionAspect.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/src/main/org/jboss/jms/client/container/SessionAspect.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -23,7 +23,6 @@
import java.util.ArrayList;
import java.util.Iterator;
-import java.util.LinkedList;
import java.util.List;
import javax.jms.IllegalStateException;
@@ -33,14 +32,15 @@
import org.jboss.aop.joinpoint.MethodInvocation;
import org.jboss.jms.client.delegate.DelegateSupport;
import org.jboss.jms.client.remoting.MessageCallbackHandler;
+import org.jboss.jms.client.state.ConnectionState;
import org.jboss.jms.client.state.SessionState;
import org.jboss.jms.delegate.SessionDelegate;
import org.jboss.jms.message.MessageProxy;
import org.jboss.jms.server.endpoint.DefaultCancel;
-import org.jboss.jms.server.endpoint.DefaultAck;
import org.jboss.jms.server.endpoint.DeliveryInfo;
+import org.jboss.jms.tx.ClientTransaction;
+import org.jboss.jms.tx.ResourceManager;
import org.jboss.logging.Logger;
-import org.jboss.messaging.util.Util;
/**
* This aspect handles JMS session related logic
@@ -97,7 +97,33 @@
MethodInvocation mi = (MethodInvocation)invocation;
SessionState state = getState(invocation);
SessionDelegate del = (SessionDelegate)mi.getTargetObject();
-
+
+ if (trace) { log.trace("In handleClosing"); }
+ //Sanity check
+ if (state.isXA())
+ {
+ if (trace) { log.trace("Session is XA"); }
+
+ ConnectionState connState = (ConnectionState)state.getParent();
+
+ ResourceManager rm = connState.getResourceManager();
+
+ //An XASession should never be closed if there is prepared ack work that has not yet
+ //been committed or rolled back.
+ //Imagine if messages had been consumed in the session, and prepared but not committed.
+ //Then the connection was explicitly closed causing the session to close.
+ //Closing the session causes any outstanding delivered but unacked messages to be cancelled to
+ //the server which means they would be available for other consumers to consume.
+ //If another consumer then consumes them, then recover() is called and the original
+ //transaction is committed, then this means the same message has been delivered twice
+ //which breaks the once and only once delivery guarantee
+
+ if (rm.checkForAcksInSession(state.getSessionId()))
+ {
+ throw new java.lang.IllegalStateException("Attempt to close an XASession when there are still uncommitted acknowledgements!");
+ }
+ }
+
int ackMode = state.getAcknowledgeMode();
//We need to either ack (for auto_ack) or cancel (for client_ack)
@@ -361,6 +387,12 @@
*
* So on rollback we do session recovery (local redelivery) in the same as if session.recover()
* was called.
+ *
+ * All cancellation at rollback is driven from the client side - we always attempt to redeliver
+ * messages to their original consumers if they are still open, or then cancel them to the server
+ * if they are not. Cancelling them to the server explicitly allows the delivery count to be updated.
+ *
+ *
*/
public Object handleRedeliver(Invocation invocation) throws Throwable
{
Modified: trunk/src/main/org/jboss/jms/client/remoting/MessageCallbackHandler.java
===================================================================
--- trunk/src/main/org/jboss/jms/client/remoting/MessageCallbackHandler.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/src/main/org/jboss/jms/client/remoting/MessageCallbackHandler.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -210,8 +210,21 @@
*/
public HandleMessageResponse handleMessage(List msgs) throws HandleCallbackException
{
- if (trace) { log.trace(this + " receiving " + msgs.size() + " message(s) from the remoting layer"); }
-
+ if (trace)
+ {
+ StringBuffer sb = new StringBuffer(this + " receiving [");
+ for(int i = 0; i < msgs.size(); i++)
+ {
+ sb.append(((MessageProxy)msgs.get(i)).getMessage().getMessageID());
+ if (i < msgs.size() - 1)
+ {
+ sb.append(",");
+ }
+ }
+ sb.append("] from the remoting layer");
+ log.trace(sb.toString());
+ }
+
synchronized (mainLock)
{
if (closed)
@@ -237,7 +250,7 @@
buffer.addAll(msgs);
- if (trace) { log.trace(this + " added messages to the buffer"); }
+ if (trace) { log.trace(this + " added message(s) to the buffer"); }
boolean full = buffer.size() >= bufferSize;
@@ -348,9 +361,9 @@
{
sessionExecutor.execute(new Closer(result));
- if (trace) { log.trace("blocking wait for Closer execution"); }
+ if (trace) { log.trace(this + " blocking wait for Closer execution"); }
result.getResult();
- if (trace) { log.trace("got Closer result"); }
+ if (trace) { log.trace(this + " got Closer result"); }
}
catch (InterruptedException e)
{
@@ -433,7 +446,7 @@
}
}
- if (trace) { log.trace("received " + m + " after being blocked on buffer"); }
+ if (trace) { log.trace(this + " received " + m + " after being blocked on buffer"); }
// If message is expired we still call pre and post deliver. This makes sure the
// message is acknowledged so it gets removed from the queue/subscription.
@@ -449,14 +462,14 @@
if (!m.getMessage().isExpired())
{
- if (trace) { log.trace("message " + m + " is not expired, pushing it to the caller"); }
+ if (trace) { log.trace(this + ": message " + m + " is not expired, pushing it to the caller"); }
break;
}
if (trace)
{
- log.trace("message expired, discarding");
+ log.trace(this + ": message expired, discarding");
}
// the message expired, so discard the message, adjust timeout and reenter the buffer
Modified: trunk/src/main/org/jboss/jms/client/state/ConnectionState.java
===================================================================
--- trunk/src/main/org/jboss/jms/client/state/ConnectionState.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/src/main/org/jboss/jms/client/state/ConnectionState.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -31,6 +31,7 @@
import org.jboss.jms.message.MessageIdGenerator;
import org.jboss.jms.server.Version;
import org.jboss.jms.tx.ResourceManager;
+import org.jboss.jms.tx.ResourceManagerFactory;
import org.jboss.logging.Logger;
import EDU.oswego.cs.dl.util.concurrent.SyncSet;
@@ -100,7 +101,7 @@
// Each connection has its own resource manager. If we can failover all connections with the
// same server id at the same time then we can maintain one rm per unique server as opposed to
// per connection.
- this.resourceManager = new ResourceManager();
+ this.resourceManager = ResourceManagerFactory.instance.checkOutResourceManager(serverID);
this.idGenerator = gen;
this.serverID = serverID;
Copied: trunk/src/main/org/jboss/jms/recovery (from rev 1823, branches/Branch_1_0/src/main/org/jboss/jms/recovery)
Deleted: trunk/src/main/org/jboss/jms/recovery/JMSProviderXAResourceRecovery.java
===================================================================
--- branches/Branch_1_0/src/main/org/jboss/jms/recovery/JMSProviderXAResourceRecovery.java 2006-12-19 06:51:01 UTC (rev 1823)
+++ trunk/src/main/org/jboss/jms/recovery/JMSProviderXAResourceRecovery.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -1,100 +0,0 @@
-/*
-* JBoss, Home of Professional Open Source
-* Copyright 2006, JBoss Inc., and individual contributors as indicated
-* by the @authors tag. See the copyright.txt in the distribution for a
-* full listing of individual contributors.
-*
-* This is free software; you can redistribute it and/or modify it
-* under the terms of the GNU Lesser General Public License as
-* published by the Free Software Foundation; either version 2.1 of
-* the License, or (at your option) any later version.
-*
-* This software is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public
-* License along with this software; if not, write to the Free
-* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
-* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
-*/
-package org.jboss.jms.recovery;
-
-import javax.transaction.xa.XAResource;
-
-import org.jboss.logging.Logger;
-
-import com.arjuna.ats.jta.recovery.XAResourceRecovery;
-
-/**
- * JMS Provider Adapter based recovery.
- *
- * @author <a href="adrian at jboss.com">Adrian Brock</a>
- * @author <a href="juha at jboss.com">Juha Lindfors</a>
- *
- * @version $Revision: 1.1 $
- */
-public class JMSProviderXAResourceRecovery implements XAResourceRecovery
-{
- private boolean trace = log.isTraceEnabled();
-
- private static final Logger log = Logger.getLogger(JMSProviderXAResourceRecovery.class);
-
- /** The jms provider name */
- private String providerName;
-
- /** The delegate XAResource */
- private XAResourceWrapper wrapper;
-
- /** Whether the XAResource is working */
- private boolean working = false;
-
- public JMSProviderXAResourceRecovery()
- {
- if(trace)
- log.trace("Constructing JMSProviderXAResourceRecovery..");
- }
-
- public boolean initialise(String p)
- {
- if(trace)
- log.trace("Initialising JMSProviderXAResourceRecovery..");
-
- this.providerName = p;
- return true;
- }
-
- public boolean hasMoreResources()
- {
- // If the XAResource is already working
- if (working)
- return false;
-
- // Have we initialized yet?
- if (wrapper == null)
- {
- wrapper = new XAResourceWrapper();
- wrapper.setProviderName(providerName);
- }
-
- // Test the connection
- try
- {
- wrapper.getTransactionTimeout();
- working = true;
- }
- catch (Exception ignored)
- {
- //System.out.println(ignored.getMessage());
- }
-
- // This will return false until we get a successful connection
- return working;
- }
-
- public XAResource getXAResource()
- {
- return wrapper;
- }
-}
Copied: trunk/src/main/org/jboss/jms/recovery/JMSProviderXAResourceRecovery.java (from rev 1823, branches/Branch_1_0/src/main/org/jboss/jms/recovery/JMSProviderXAResourceRecovery.java)
Deleted: trunk/src/main/org/jboss/jms/recovery/MessagingXAResourceRecovery.java
===================================================================
--- branches/Branch_1_0/src/main/org/jboss/jms/recovery/MessagingXAResourceRecovery.java 2006-12-19 06:51:01 UTC (rev 1823)
+++ trunk/src/main/org/jboss/jms/recovery/MessagingXAResourceRecovery.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -1,133 +0,0 @@
-package org.jboss.jms.recovery;
-
-import java.sql.SQLException;
-import javax.jms.XAConnection;
-import javax.jms.XAConnectionFactory;
-import javax.jms.XASession;
-import javax.naming.Context;
-import javax.naming.InitialContext;
-import javax.transaction.xa.XAResource;
-
-import org.jboss.logging.Logger;
-
-import com.arjuna.ats.jta.recovery.XAResourceRecovery;
-
-public class MessagingXAResourceRecovery implements XAResourceRecovery {
-
- private boolean trace = log.isTraceEnabled();
-
- private static final Logger log = Logger.getLogger(MessagingXAResourceRecovery.class);
-
- private boolean working = false;
-
- private XAResource xaRes = null;
-
- private String xaConnFactory = null;
-
- public MessagingXAResourceRecovery() {
- }
-
- public XAResource getXAResource() throws SQLException {
- if(trace)
- log.trace("returning the xaresource "+xaRes);
- return xaRes;
- }
-
- /**
- * This method returns the Messaging XAResource reference.
- * You have to pass the jndi name of the XAConnectionFactory
- * via the JBossTS RecoveryManager's properties
- * @return
- */
- public XAResource initXAResource() {
- if(trace)
- log.trace("Initialising xaresource..");
- try {
- Context ctx = new InitialContext();
-
- XAConnectionFactory cf = (XAConnectionFactory) ctx
- .lookup(xaConnFactory);
-
- XAConnection xaConn = cf.createXAConnection();
-
- XASession session = xaConn.createXASession();
- xaRes = session.getXAResource();
-
- if(trace)
- log.trace("Found the xares: "+xaRes);
-
- } catch (Exception e) {
- // You may get this exception when the messaging server
- // is not fully booted up. Nothing to worry, it'll keep
- // trying until successful.
- log.warn("XAConnectionFactory is not found. \n" +
- "The messaging server is not yet initialized.\n" +
- "we'll try again once server is fully back");
-
- }
-
- return xaRes;
- }
-
- /**
- * This method is used to pass any
- * intialisation parameters to this
- * class
- * @param param
- * @return
- * @throws SQLException
- */
- public boolean initialise(String param) throws SQLException
- {
- if(trace)
- log.trace("Passed in parameter: "+param);
-
- if(param != null)
- {
- // parama is in the form of name=value
- String value = param.substring(param.indexOf("=")+1);
-
- if(trace)
- log.trace("The connection factory is "+value);
-
- xaConnFactory = value;
- }
- else
- {
- log.debug("The XA connection factory parameter is null. " +
- "Using the default 'XAConnectionFactory'");
-
- xaConnFactory = "XAConnectionFactory";
- }
- return true;
- }
-
- /**
- * This method checks whether there's an xa resource available
- *
- * @return
- */
- public boolean hasMoreResources() {
-
- if (working)
- return false;
-
- if (xaRes == null) {
- xaRes = initXAResource();
- }
-
- // test the resource
- try {
-
- xaRes.getTransactionTimeout();
-
- working = true;
-
- } catch (Exception ignored) {
-
- // ignore this exception
- }
-
- return working;
- }
-}
Copied: trunk/src/main/org/jboss/jms/recovery/MessagingXAResourceRecovery.java (from rev 1823, branches/Branch_1_0/src/main/org/jboss/jms/recovery/MessagingXAResourceRecovery.java)
===================================================================
--- branches/Branch_1_0/src/main/org/jboss/jms/recovery/MessagingXAResourceRecovery.java 2006-12-19 06:51:01 UTC (rev 1823)
+++ trunk/src/main/org/jboss/jms/recovery/MessagingXAResourceRecovery.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -0,0 +1,152 @@
+package org.jboss.jms.recovery;
+
+import java.sql.SQLException;
+import javax.jms.XAConnection;
+import javax.jms.XAConnectionFactory;
+import javax.jms.XASession;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.transaction.xa.XAResource;
+
+import org.jboss.logging.Logger;
+
+import com.arjuna.ats.jta.recovery.XAResourceRecovery;
+
+/**
+ *
+ * A MessagingXAResourceRecovery
+ *
+ * @version <tt>$Revision: 1.1 $</tt>
+ *
+ * $Id$
+ *
+ */
+public class MessagingXAResourceRecovery implements XAResourceRecovery
+{
+ private boolean trace = log.isTraceEnabled();
+
+ private static final Logger log = Logger.getLogger(MessagingXAResourceRecovery.class);
+
+ private boolean working = false;
+
+ private XAResource xaRes = null;
+
+ private String xaConnFactory = null;
+
+ public MessagingXAResourceRecovery()
+ {
+ }
+
+ public XAResource getXAResource() throws SQLException
+ {
+ if (trace) { log.trace("returning the xaresource " + xaRes); }
+ return xaRes;
+ }
+
+ /**
+ * This method returns the Messaging XAResource reference.
+ * You have to pass the jndi name of the XAConnectionFactory
+ * via the JBossTS RecoveryManager's properties
+ * @return
+ */
+ public XAResource initXAResource()
+ {
+ if(trace)
+ {
+ log.trace("Initialising xaresource..");
+ }
+ try
+ {
+ Context ctx = new InitialContext();
+
+ XAConnectionFactory cf = (XAConnectionFactory) ctx
+ .lookup(xaConnFactory);
+
+ XAConnection xaConn = cf.createXAConnection();
+
+ XASession session = xaConn.createXASession();
+ xaRes = session.getXAResource();
+
+ if(trace)
+ log.trace("Found the xares: "+xaRes);
+
+ }
+ catch (Exception e)
+ {
+ // You may get this exception when the messaging server
+ // is not fully booted up. Nothing to worry, it'll keep
+ // trying until successful.
+ log.warn("XAConnectionFactory is not found. \n" +
+ "The messaging server is not yet initialized.\n" +
+ "we'll try again once server is fully back");
+
+ }
+
+ return xaRes;
+ }
+
+ /**
+ * This method is used to pass any
+ * intialisation parameters to this
+ * class
+ * @param param
+ * @return
+ * @throws SQLException
+ */
+ public boolean initialise(String param) throws SQLException
+ {
+ if(trace) { log.trace("Passed in parameter: " + param); }
+
+ if (param != null)
+ {
+ // param is in the form of name=value
+ String value = param.substring(param.indexOf("=") + 1);
+
+ if(trace) { log.trace("The connection factory is " + value); }
+
+ xaConnFactory = value;
+ }
+ else
+ {
+ log.debug("The XA connection factory parameter is null. " +
+ "Using the default 'XAConnectionFactory'");
+
+ xaConnFactory = "XAConnectionFactory";
+ }
+ return true;
+ }
+
+ /**
+ * This method checks whether there's an xa resource available
+ *
+ * @return
+ */
+ public boolean hasMoreResources()
+ {
+ if (working)
+ {
+ return false;
+ }
+
+ if (xaRes == null)
+ {
+ xaRes = initXAResource();
+ }
+
+ // test the resource
+ try
+ {
+
+ xaRes.getTransactionTimeout();
+
+ working = true;
+ }
+ catch (Exception ignored)
+ {
+
+ // ignore this exception
+ }
+
+ return working;
+ }
+}
Modified: trunk/src/main/org/jboss/jms/server/ServerPeer.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/ServerPeer.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/src/main/org/jboss/jms/server/ServerPeer.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -73,6 +73,8 @@
*
* @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
* @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @author <a href="mailto:juha at jboss.org">Juha Lindfors</a>
+ *
* @version <tt>$Revision$</tt>
*
* $Id$
@@ -83,8 +85,6 @@
private static final Logger log = Logger.getLogger(ServerPeer.class);
- public static final String RECOVERABLE_CTX_NAME = "jms-recoverables";
-
// The "subsystem" label this ServerPeer uses to register its ServerInvocationHandler with the
// Remoting connector
public static final String REMOTING_JMS_SUBSYSTEM = "JMS";
@@ -220,7 +220,7 @@
connectorManager = new SimpleConnectorManager();
memoryManager = new SimpleMemoryManager();
messageStore = new SimpleMessageStore();
- txRepository = new TransactionRepository(persistenceManager, transactionIDManager);
+ txRepository = new TransactionRepository(persistenceManager, messageStore, transactionIDManager);
// Start the wired components
@@ -235,11 +235,10 @@
messageStore.start();
securityStore.start();
txRepository.start();
-
+ txRepository.loadPreparedTransactions();
+
initializeRemoting(mbeanServer);
- //createRecoverable();
-
started = true;
log.info("JBoss Messaging " + getVersion().getProviderVersion() + " server [" +
@@ -264,8 +263,6 @@
started = false;
- //removeRecoverable();
-
// Stop the wired components
messageIDManager.stop();
@@ -484,8 +481,6 @@
this.failoverCompleteTimeout = timeout;
}
-
-
// JMX Operations ------------------------------------------------
public String createQueue(String name, String jndiName) throws Exception
@@ -698,10 +693,12 @@
if (!postOffice.isLocal())
{
Replicator rep = (Replicator)postOffice;
- connFactoryJNDIMapper.injectReplicator(rep);
+ connFactoryJNDIMapper.injectReplicator(rep);
rep.registerListener(new FailoverListener());
-
}
+
+ //Also need to inject into txRepository
+ this.txRepository.injectPostOffice(postOffice);
}
return postOffice;
}
@@ -850,61 +847,7 @@
// Protected -----------------------------------------------------
// Private -------------------------------------------------------
-
- /**
- * Place a Recoverable instance in the JNDI tree. This can be used by a transaction manager in
- * order to obtain an XAResource so it can perform XA recovery.
- */
-
- //Commented out until XA Recovery is complete
-
-// private void createRecoverable() throws Exception
-// {
-// //Disabled until XA Recovery is complete with Arjuna transaction integration
-//
-// InitialContext ic = new InitialContext();
-//
-// int connFactoryID = connFactoryJNDIMapper.registerConnectionFactory(null, null);
-//
-// XAConnectionFactory xaConnFactory =
-// (XAConnectionFactory)connFactoryJNDIMapper.getConnectionFactory(connFactoryID);
-//
-// JMSRecoverable recoverable = new JMSRecoverable(serverPeerID, xaConnFactory);
-//
-// Context recCtx = null;
-// try
-// {
-// recCtx = (Context)ic.lookup(RECOVERABLE_CTX_NAME);
-// }
-// catch (NamingException e)
-// {
-// //Ignore
-// }
-//
-// if (recCtx == null)
-// {
-// recCtx = ic.createSubcontext(RECOVERABLE_CTX_NAME);
-// }
-//
-// recCtx.rebind(this.serverPeerID, recoverable);
-// }
-//
-// private void removeRecoverable() throws Exception
-// {
-// InitialContext ic = new InitialContext();
-//
-// Context recCtx = null;
-// try
-// {
-// recCtx = (Context)ic.lookup(RECOVERABLE_CTX_NAME);
-// recCtx.unbind(serverPeerID);
-// }
-// catch (NamingException e)
-// {
-// //Ignore
-// }
-// }
-
+
private void initializeRemoting(MBeanServer mbeanServer) throws Exception
{
JMSWireFormat wf = new JMSWireFormat();
Modified: trunk/src/main/org/jboss/jms/server/endpoint/ServerConnectionEndpoint.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/endpoint/ServerConnectionEndpoint.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/src/main/org/jboss/jms/server/endpoint/ServerConnectionEndpoint.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -380,6 +380,9 @@
{
if (trace) { log.trace("Two phase commit rollback request received"); }
+ //For 2pc rollback - we just don't cancel any messages back to the channel
+ //this is driven from the client side
+
Transaction tx = tr.getPreparedTx(request.getXid());
if (trace) { log.trace("Rolling back " + tx); }
tx.rollback();
@@ -402,7 +405,7 @@
{
try
{
- List xids = tr.getPreparedTransactions();
+ List xids = tr.recoverPreparedTransactions();
return (Xid[])xids.toArray(new Xid[xids.size()]);
}
@@ -634,7 +637,7 @@
private void processTransaction(ClientTransaction txState, Transaction tx) throws Throwable
{
- if (trace) { log.trace("processing transaction"); }
+ if (trace) { log.trace(tx + " :processing transaction"); }
synchronized (sessions)
{
@@ -665,7 +668,7 @@
}
}
- if (trace) { log.trace("Processed transaction"); }
+ if (trace) { log.trace(tx + " :Processed transaction"); }
}
// Inner classes -------------------------------------------------
Modified: trunk/src/main/org/jboss/jms/server/endpoint/ServerConsumerEndpoint.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/endpoint/ServerConsumerEndpoint.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/src/main/org/jboss/jms/server/endpoint/ServerConsumerEndpoint.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -630,8 +630,21 @@
try
{
- if (trace) { log.trace(ServerConsumerEndpoint.this + " handing " + list.size() + " message(s) over to the remoting layer"); }
-
+ if (trace)
+ {
+ StringBuffer sb = new StringBuffer(ServerConsumerEndpoint.this + " handing [");
+ for(int i = 0; i < list.size(); i++)
+ {
+ sb.append(((MessageProxy)list.get(i)).getMessage().getMessageID());
+ if (i < list.size() - 1)
+ {
+ sb.append(",");
+ }
+ }
+ sb.append("] over to the remoting layer");
+ log.trace(sb.toString());
+ }
+
synchronized(messagesInTransitLock)
{
connection.getCallbackHandler().handleCallback(callback);
Modified: trunk/src/main/org/jboss/jms/server/endpoint/ServerSessionEndpoint.java
===================================================================
--- trunk/src/main/org/jboss/jms/server/endpoint/ServerSessionEndpoint.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/src/main/org/jboss/jms/server/endpoint/ServerSessionEndpoint.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -484,7 +484,7 @@
Queue queue = binding.getQueue();
- List dels = queue.createDeliveries(ids);
+ List dels = queue.recoverDeliveries(ids);
Iterator iter2 = dels.iterator();
@@ -1343,7 +1343,10 @@
public void afterRollback(boolean onePhase) throws TransactionException
{
- //NOOP
+ //One phase rollbacks never hit the server - they are dealt with locally only
+ //so this would only ever be executed for a two phase rollback.
+
+ //We don't do anything since cancellation is driven from the client.
}
synchronized void addDeliveryId(Long deliveryId)
Modified: trunk/src/main/org/jboss/jms/tx/ClientTransaction.java
===================================================================
--- trunk/src/main/org/jboss/jms/tx/ClientTransaction.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/src/main/org/jboss/jms/tx/ClientTransaction.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -24,18 +24,17 @@
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.Collections;
-import java.util.HashMap;
import java.util.Iterator;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
-import org.jboss.jms.client.state.SessionState;
import org.jboss.jms.message.JBossMessage;
import org.jboss.jms.server.endpoint.Ack;
import org.jboss.jms.server.endpoint.DefaultAck;
import org.jboss.jms.server.endpoint.DeliveryInfo;
+import org.jboss.logging.Logger;
import org.jboss.messaging.core.message.MessageFactory;
/**
@@ -46,6 +45,9 @@
public class ClientTransaction
{
// Constants -----------------------------------------------------
+
+ private static final Logger log = Logger.getLogger(ClientTransaction.class);
+
public final static byte TX_OPEN = 0;
@@ -59,7 +61,7 @@
// Attributes ----------------------------------------------------
- private int state = TX_OPEN;
+ private byte state = TX_OPEN;
//Maintained on the client side
private Map sessionStatesMap;
@@ -80,7 +82,7 @@
// Public --------------------------------------------------------
- public int getState()
+ public byte getState()
{
return state;
}
@@ -113,17 +115,23 @@
{
throw new IllegalStateException("Cannot call this method on the server side");
}
- Iterator iter = sessionStatesMap.values().iterator();
- while (iter.hasNext())
+ if (sessionStatesMap != null)
{
- SessionTxState sessionTxState = (SessionTxState)iter.next();
+ //This can be null if the tx was recreated on the client side due to recovery
- sessionTxState.clearMessages();
+ Iterator iter = sessionStatesMap.values().iterator();
+
+ while (iter.hasNext())
+ {
+ SessionTxState sessionTxState = (SessionTxState)iter.next();
+
+ sessionTxState.clearMessages();
+ }
}
}
- public void setState(int state)
+ public void setState(byte state)
{
if (!clientSide)
{
@@ -132,7 +140,7 @@
this.state = state;
}
- public Collection getSessionStates()
+ public List getSessionStates()
{
if (sessionStatesList != null)
{
@@ -140,14 +148,14 @@
}
else
{
- return sessionStatesMap == null ? Collections.EMPTY_SET : sessionStatesMap.values();
+ return sessionStatesMap == null ? Collections.EMPTY_LIST : new ArrayList(sessionStatesMap.values());
}
}
/*
* Substitute newSessionId for oldSessionId
*/
- public void handleFailover(Map oldNewSessionMap)
+ public void handleFailover(int newServerId, int oldSessionId, int newSessionId)
{
if (!clientSide)
{
@@ -157,33 +165,15 @@
//and we don't want to overwrite keys in the map
if (sessionStatesMap != null)
- {
- Map newMap = new HashMap();
+ {
+ Iterator iter = sessionStatesMap.values().iterator();
- Iterator iter = oldNewSessionMap.entrySet().iterator();
-
while (iter.hasNext())
{
- Map.Entry entry = (Map.Entry)iter.next();
+ SessionTxState state = (SessionTxState)iter.next();
- Integer oldSessionId = (Integer)entry.getKey();
-
- SessionState newSessionState = (SessionState)entry.getValue();
-
- int newSessionId = newSessionState.getSessionId();
-
- SessionTxState state = (SessionTxState)sessionStatesMap.get(oldSessionId);
-
- if (state != null)
- {
- state.handleFailover(newSessionId);
- }
-
- newMap.put(new Integer(newSessionId), state);
-
+ state.handleFailover(newServerId, oldSessionId, newSessionId);
}
-
- sessionStatesMap = newMap;
}
}
@@ -209,7 +199,7 @@
public void write(DataOutputStream out) throws Exception
{
- out.writeInt(state);
+ out.writeByte(state);
if (sessionStatesMap == null)
{
@@ -264,7 +254,7 @@
{
clientSide = false;
- state = in.readInt();
+ state = in.readByte();
int numSessions = in.readInt();
@@ -314,7 +304,7 @@
{
if (sessionStatesMap == null)
{
- sessionStatesMap = new HashMap();
+ sessionStatesMap = new LinkedHashMap();
}
SessionTxState sessionTxState = (SessionTxState)sessionStatesMap.get(new Integer(sessionId));
@@ -328,8 +318,7 @@
return sessionTxState;
}
-
-
+
// Inner Classes -------------------------------------------------
@@ -365,23 +354,29 @@
return sessionId;
}
- void handleFailover(int newSessionId)
+ void handleFailover(int newServerId, int oldSessionId, int newSessionId)
{
- this.sessionId = newSessionId;
-
- //Remove any non persistent acks
-
- Iterator iter = acks.iterator();
-
- while (iter.hasNext())
- {
- DeliveryInfo info = (DeliveryInfo)iter.next();
+ if (this.sessionId == oldSessionId && this.serverId != newServerId)
+ {
+ this.sessionId = newSessionId;
- if (!info.getMessageProxy().getMessage().isReliable())
+ this.serverId = newServerId;
+
+ //Remove any non persistent acks
+
+ Iterator iter = acks.iterator();
+
+ while (iter.hasNext())
{
- iter.remove();
+ DeliveryInfo info = (DeliveryInfo)iter.next();
+
+ if (!info.getMessageProxy().getMessage().isReliable())
+ {
+ iter.remove();
+ }
}
}
+
}
void clearMessages()
@@ -391,6 +386,11 @@
private int sessionId;
+ //we record the server id when doing failover to avoid overwriting the sesion id again
+ //if multiple connections fail on the same resource mamanger but fail onto old values of the session id
+ //this prevents the id being failed over more than once for the same server
+ private int serverId = -1;
+
private List msgs = new ArrayList();
private List acks = new ArrayList();
Deleted: trunk/src/main/org/jboss/jms/tx/JMSRecoverable.java
===================================================================
--- trunk/src/main/org/jboss/jms/tx/JMSRecoverable.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/src/main/org/jboss/jms/tx/JMSRecoverable.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -1,81 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.jms.tx;
-
-import java.io.Serializable;
-
-import javax.jms.JMSException;
-import javax.jms.XAConnection;
-import javax.jms.XAConnectionFactory;
-import javax.jms.XASession;
-import javax.transaction.xa.XAResource;
-
-/**
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- *
- * @version $Revision$
- *
- * $Id$
- */
-public class JMSRecoverable implements Serializable
-{
- private static final long serialVersionUID = -2007160911694821670L;
-
- protected String serverID;
-
- protected XAConnectionFactory cf;
-
- protected XAConnection conn;
-
- public JMSRecoverable(String serverID, XAConnectionFactory cf)
- {
- this.serverID = serverID;
- this.cf = cf;
- }
-
- public String getName()
- {
- return "JBossMessaging-" + serverID;
- }
-
- public XAResource getResource() throws JMSException
- {
- cleanUp();
-
- conn = cf.createXAConnection();
-
- XASession sess = conn.createXASession();
-
- return sess.getXAResource();
- }
-
- public void cleanUp() throws JMSException
- {
- if (conn != null)
- {
- conn.close();
-
- conn = null;
- }
- }
-
-}
Modified: trunk/src/main/org/jboss/jms/tx/MessagingXAResource.java
===================================================================
--- trunk/src/main/org/jboss/jms/tx/MessagingXAResource.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/src/main/org/jboss/jms/tx/MessagingXAResource.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -28,6 +28,7 @@
import org.jboss.jms.client.state.SessionState;
import org.jboss.jms.delegate.ConnectionDelegate;
import org.jboss.logging.Logger;
+import org.jboss.messaging.core.tx.XidImpl;
/**
* An XAResource implementation.
@@ -38,6 +39,10 @@
*
* @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
* @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
+ * @author <a href="mailto:juha at jboss.org">Juha Lindfors</a>
+ *
+ * Parts based on JBoss MQ XAResource implementation by:
+ *
* @author Hiram Chirino (Cojonudo14 at hotmail.com)
* @author <a href="mailto:adrian at jboss.org">Adrian Brock</a>
*
@@ -109,7 +114,12 @@
public void commit(Xid xid, boolean onePhase) throws XAException
{
if (trace) { log.trace(this + " committing " + xid + (onePhase ? " (one phase)" : " (two phase)")); }
-
+
+ // Recreate Xid. See JBMESSAGING-661 [JPL]
+
+ if (!(xid instanceof XidImpl))
+ xid = new XidImpl(xid.getBranchQualifier(), xid.getFormatId(), xid.getGlobalTransactionId());
+
rm.commit(xid, onePhase, connection);
// leave the session in a 'clean' state, the currentTxId will be set when the XAResource will
@@ -122,6 +132,11 @@
{
if (trace) { log.trace(this + " ending " + xid + ", flags: " + flags); }
+ // Recreate Xid. See JBMESSAGING-661 [JPL]
+
+ if (!(xid instanceof XidImpl))
+ xid = new XidImpl(xid.getBranchQualifier(), xid.getFormatId(), xid.getGlobalTransactionId());
+
synchronized (this)
{
switch (flags)
@@ -145,11 +160,22 @@
public void forget(Xid xid) throws XAException
{
if (trace) { log.trace(this + " forgetting " + xid + " (currently an NOOP)"); }
+
+ // Recreate Xid. See JBMESSAGING-661 [JPL]
+
+ if (!(xid instanceof XidImpl))
+ xid = new XidImpl(xid.getBranchQualifier(), xid.getFormatId(), xid.getGlobalTransactionId());
}
public int prepare(Xid xid) throws XAException
{
if (trace) { log.trace(this + " preparing " + xid); }
+
+ // Recreate Xid. See JBMESSAGING-661 [JPL]
+
+ if (!(xid instanceof XidImpl))
+ xid = new XidImpl(xid.getBranchQualifier(), xid.getFormatId(), xid.getGlobalTransactionId());
+
return rm.prepare(xid, connection);
}
@@ -164,9 +190,11 @@
{
if (trace) { log.trace(this + " rolling back " + xid); }
- // TODO on rollback should we also stop and start the consumers to remove any transient
- // messages, like we do on local session rollback??
+ // Recreate Xid. See JBMESSAGING-661 [JPL]
+ if (!(xid instanceof XidImpl))
+ xid = new XidImpl(xid.getBranchQualifier(), xid.getFormatId(), xid.getGlobalTransactionId());
+
rm.rollback(xid, connection);
}
@@ -174,6 +202,11 @@
{
if (trace) { log.trace(this + " starting " + xid + ", flags: " + flags); }
+ // Recreate Xid. See JBMESSAGING-661 [JPL]
+
+ if (!(xid instanceof XidImpl))
+ xid = new XidImpl(xid.getBranchQualifier(), xid.getFormatId(), xid.getGlobalTransactionId());
+
boolean convertTx = false;
if (sessionState.getCurrentTxId() != null)
Modified: trunk/src/main/org/jboss/jms/tx/ResourceManager.java
===================================================================
--- trunk/src/main/org/jboss/jms/tx/ResourceManager.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/src/main/org/jboss/jms/tx/ResourceManager.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -22,7 +22,7 @@
package org.jboss.jms.tx;
import java.util.ArrayList;
-import java.util.Collection;
+import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -52,7 +52,9 @@
* This is one instance of ResourceManager per JMS server. The ResourceManager instances are managed
* by ResourceManagerFactory.
*
- * @author <a href="mailto:tim.fox at jboss.com>Tim Fox</a>
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @author <a href="mailto:Konda.Madhu at uk.mizuho-sc.com">Madhu Konda</a>
+ * @author <a href="mailto:juha at jboss.org">Juha Lindfors</a>
* @author <a href="mailto:Cojonudo14 at hotmail.com">Hiram Chirino</a>
* @author <a href="mailto:adrian at jboss.org">Adrian Brock</a>
* @version $Revision$
@@ -74,9 +76,21 @@
private static final Logger log = Logger.getLogger(ResourceManager.class);
// Constructors --------------------------------------------------
+
+ ResourceManager()
+ {
+ }
// Public --------------------------------------------------------
+ /*
+ * Merge another resource manager into this one - used in failover
+ */
+ public void merge(ResourceManager other)
+ {
+ transactions.putAll(other.transactions);
+ }
+
/**
* Remove a tx
*/
@@ -115,20 +129,17 @@
}
/*
- * Failover session from old session -> new session
- * This basically involves updating the session id
+ * Failover session from old session id -> new session id
*/
- public void handleFailover(Map oldNewSessionMap)
+ public void handleFailover(int newServerId, int oldSessionId, int newSessionId)
{
- //Note we need to replace ids for *all* transactions - this is because, for XA
- //the session might have done work in many transactions
Iterator iter = this.transactions.values().iterator();
while (iter.hasNext())
{
ClientTransaction tx = (ClientTransaction)iter.next();
- tx.handleFailover(oldNewSessionMap);
+ tx.handleFailover(newServerId, oldSessionId, newSessionId);
}
}
@@ -162,8 +173,6 @@
*
* @param xid - The id of the transaction to add the message to
* @param ackInfo Information describing the acknowledgement
- * @param sessionState - the session the ack is in - we need this so on rollback we can tell each session
- * to redeliver it's messages
*/
public void addAck(Object xid, int sessionId, DeliveryInfo ackInfo) throws JMSException
{
@@ -245,6 +254,34 @@
{
return transactions.size();
}
+
+
+ public boolean checkForAcksInSession(int sessionId)
+ {
+ Iterator iter = transactions.entrySet().iterator();
+
+ while (iter.hasNext())
+ {
+ Map.Entry entry = (Map.Entry)iter.next();
+
+ Object xid = entry.getKey();
+
+ ClientTransaction tx = (ClientTransaction)entry.getValue();
+
+ if (tx.getState() == ClientTransaction.TX_PREPARED)
+ {
+ List dels = tx.getDeliveriesForSession(sessionId);
+
+ if (dels != null && !dels.isEmpty())
+ {
+ //There are outstanding prepared acks in this session
+
+ return true;
+ }
+ }
+ }
+ return false;
+ }
// Protected ------------------------------------------------------
@@ -255,6 +292,8 @@
if (trace) { log.trace("commiting xid " + xid + ", onePhase=" + onePhase); }
ClientTransaction tx = removeTxInternal(xid);
+
+ if (trace) { log.trace("Got tx: " + tx + " state " + tx.getState()); }
if (onePhase)
{
@@ -306,40 +345,59 @@
if (trace) { log.trace("rolling back xid " + xid); }
ClientTransaction tx = removeTxInternal(xid);
-
+
+ //It's possible we don't actually have the prepared tx here locally - this
+ //may happen if we have recovered from failure and the transaction manager
+ //is calling rollback on the transaction as part of the recovery process.
+
TransactionRequest request = null;
- // we don't need to send the messages to the server on a rollback
+ //don't need the messages
if (tx != null)
{
- //We don't clear the acks since we need to redeliver locally
tx.clearMessages();
}
-
+
if ((tx == null) || tx.getState() == ClientTransaction.TX_PREPARED)
{
+ //2PC rollback
+
request = new TransactionRequest(TransactionRequest.TWO_PHASE_ROLLBACK_REQUEST, xid, tx);
+ if (trace) { log.trace("Sending rollback to server, tx:" + tx); }
+
sendTransactionXA(request, connection);
}
else
{
+ //For one phase rollback there is nothing to do on the server
+
if (tx == null)
{
throw new MessagingXAException(XAException.XAER_NOTA, "Cannot find transaction with xid:" + xid);
}
-
- //For one phase rollback there is nothing to do on the server
}
+
+ //we redeliver the messages
+ //locally to their original consumers if they are still open or cancel them to the server
+ //if the original consumers have closed
+ if (trace) { log.trace("Redelivering messages, tx:" + tx); }
+
try
{
- redeliverMessages(tx);
+ if (tx != null)
+ {
+ redeliverMessages(tx);
+
+ tx.setState(ClientTransaction.TX_ROLLEDBACK);
+ }
+
}
catch (JMSException e)
{
log.error("Failed to redeliver", e);
- }
+ }
}
void endTx(Xid xid, boolean success) throws XAException
@@ -388,6 +446,8 @@
state.setState(ClientTransaction.TX_PREPARED);
+ if (trace) { log.trace("State is now: " + state.getState()); }
+
return XAResource.XA_OK;
}
@@ -469,6 +529,21 @@
try
{
Xid[] txs = conn.getPreparedTransactions();
+
+ //populate with TxState --MK
+ for (int i = 0; i < txs.length;i++)
+ {
+ //Don't overwrite if it is already there
+ if (!transactions.containsKey(txs[i]))
+ {
+ ClientTransaction tx = new ClientTransaction();
+
+ tx.setState(ClientTransaction.TX_PREPARED);
+
+ transactions.put(txs[i], tx);
+ }
+ }
+
return txs;
}
catch (JMSException e)
@@ -499,11 +574,19 @@
/*
* Rollback has occurred so we need to redeliver any unacked messages corresponding to the acks
* is in the transaction.
+ * NOTE! We only do this for 1PC rollback - for 2PC rollback we MUST rollback on the server
+ * but if we do this we cannot redeliver locally since then we might get the same message
+ * delievered twice. Therefore we must not redeliver locally.
+ *
*/
private void redeliverMessages(ClientTransaction ts) throws JMSException
{
- Collection sessionStates = ts.getSessionStates();
+ List sessionStates = ts.getSessionStates();
+ //Need to do this in reverse order
+
+ Collections.reverse(sessionStates);
+
for (Iterator i = sessionStates.iterator(); i.hasNext();)
{
SessionTxState state = (SessionTxState)i.next();
Modified: trunk/src/main/org/jboss/jms/tx/TransactionRequest.java
===================================================================
--- trunk/src/main/org/jboss/jms/tx/TransactionRequest.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/src/main/org/jboss/jms/tx/TransactionRequest.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -30,7 +30,7 @@
import org.jboss.messaging.util.Streamable;
/**
- * This class contians all the data needed to perform a JMS transaction.
+ * This class contains all the data needed to perform a JMS transaction.
*
* @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
*
Modified: trunk/src/main/org/jboss/messaging/core/Channel.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/Channel.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/src/main/org/jboss/messaging/core/Channel.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -144,7 +144,10 @@
boolean isActive();
- List createDeliveries(List messageIds);
+ List recoverDeliveries(List messageIds);
+
+ //This method will be defunct very soon when we remove the delivery list from inside the channel
+ void addDelivery(Delivery del);
}
Modified: trunk/src/main/org/jboss/messaging/core/ChannelSupport.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/ChannelSupport.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/src/main/org/jboss/messaging/core/ChannelSupport.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -184,14 +184,8 @@
public void cancel(Delivery d) throws Throwable
{
- // TODO We should also consider executing cancels on the event queue
- synchronized (deliveryLock)
- {
- synchronized (refLock)
- {
- cancelInternal(d);
- }
- }
+ // We put the cancellation on the event queue
+ this.executor.execute(new CancelRunnable(d));
}
// Distributor implementation ------------------------------------
@@ -492,22 +486,20 @@
}
}
- public List createDeliveries(List messageIds)
+ //This method will be defunct very soon when we remove the delivery list from inside the channel
+ public void addDelivery(Delivery del)
{
+ synchronized (deliveryLock)
+ {
+ deliveries.add(del);
+ }
+ }
+
+ public List recoverDeliveries(List messageIds)
+ {
//debug
Iterator iter = messageIds.iterator();
-
- log.info("***** createdeliveries:" + messageIds.size());
- while (iter.hasNext())
- {
- Long l = (Long)iter.next();
-
- log.info("Creating delivery for " + l);
- }
- log.info("**** end dump");
-
- iter = messageIds.iterator();
-
+
List dels = new ArrayList();
synchronized (refLock)
@@ -616,6 +608,8 @@
// Reference is not expired
// Attempt to push the ref to a receiver
+
+ if (trace) { log.trace(this + " pushing " + ref); }
Delivery del = router.handle(this, ref, null);
@@ -668,6 +662,8 @@
synchronized (deliveryLock)
{
deliveries.add(del);
+
+ if (trace) { log.trace(this + " starting to track " + del); }
}
}
}
@@ -865,13 +861,17 @@
return callback;
}
-
-
+
protected boolean cancelInternal(Delivery del) throws Exception
{
if (trace) { log.trace(this + " cancelling " + del + " in memory"); }
- boolean removed = deliveries.remove(del);
+ boolean removed;
+
+ synchronized (deliveryLock)
+ {
+ removed = deliveries.remove(del);
+ }
if (!removed)
{
@@ -886,7 +886,10 @@
{
MessageReference ref = del.getReference();
- messageRefs.addFirst(ref, ref.getPriority());
+ synchronized (refLock)
+ {
+ messageRefs.addFirst(ref, ref.getPriority());
+ }
//We may need to update the delivery count in the database
if (ref.isReliable())
@@ -950,10 +953,14 @@
{
if (iter == null)
{
+ if (trace) { log.trace(this + " removing first ref in memory"); }
+
removeFirstInMemory();
}
else
{
+ if (trace) { log.trace(this + " removed current message from iterator"); }
+
iter.remove();
}
}
@@ -1275,7 +1282,29 @@
}
}
}
- }
+ }
+
+ private class CancelRunnable implements Runnable
+ {
+ Delivery del;
+
+ CancelRunnable(Delivery del)
+ {
+ this.del = del;
+ }
+
+ public void run()
+ {
+ try
+ {
+ cancelInternal(del);
+ }
+ catch (Exception e)
+ {
+ log.error("Failed to cancel delivery", e);
+ }
+ }
+ }
protected class HandleRunnable implements Runnable
{
Modified: trunk/src/main/org/jboss/messaging/core/PagingChannelSupport.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/PagingChannelSupport.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/src/main/org/jboss/messaging/core/PagingChannelSupport.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -249,8 +249,6 @@
firstPagingOrder = nextPagingOrder = 0;
}
- log.info("Channel " + this.channelID + " loading " + ili.getRefInfos().size() + " references");
-
Map refMap = processReferences(ili.getRefInfos());
Iterator iter = ili.getRefInfos().iterator();
@@ -373,23 +371,26 @@
{
if (trace) { log.trace(this + " cancelling " + del + " in memory"); }
- boolean removed = super.cancelInternal(del);
-
- if (removed && paging)
- {
- // if paging and the in memory queue is exactly full we need to evict the end reference to storage to
- // preserve the number of refs in the queue
- if (messageRefs.size() == fullSize + 1)
+ synchronized (refLock)
+ {
+ boolean removed = super.cancelInternal(del);
+
+ if (removed && paging)
{
- MessageReference ref = (MessageReference)messageRefs.removeLast();
-
- addToDownCache(ref, true);
+ // if paging and the in memory queue is exactly full we need to evict the end reference to storage to
+ // preserve the number of refs in the queue
+ if (messageRefs.size() == fullSize + 1)
+ {
+ MessageReference ref = (MessageReference)messageRefs.removeLast();
+
+ addToDownCache(ref, true);
+ }
}
+
+ if (trace) { log.trace(this + " added " + del.getReference() + " back into state"); }
+
+ return removed;
}
-
- if (trace) { log.trace(this + " added " + del.getReference() + " back into state"); }
-
- return removed;
}
protected MessageReference removeFirstInMemory() throws Exception
Modified: trunk/src/main/org/jboss/messaging/core/memory/SimpleMemoryManager.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/memory/SimpleMemoryManager.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/src/main/org/jboss/messaging/core/memory/SimpleMemoryManager.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -36,7 +36,7 @@
{
private static final Logger log = Logger.getLogger(SimpleMemoryManager.class);
- private static final long DEFAULT_MEASURE_INTERVAL = 2000;
+ private static final long DEFAULT_MEASURE_INTERVAL = 3000;
private static final int DEFAULT_FREE_MEMORY_PERCENT = 25;
Modified: trunk/src/main/org/jboss/messaging/core/plugin/JDBCPersistenceManager.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/JDBCPersistenceManager.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/src/main/org/jboss/messaging/core/plugin/JDBCPersistenceManager.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -37,11 +37,13 @@
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
+import java.util.Set;
import javax.sql.DataSource;
import javax.transaction.TransactionManager;
@@ -58,6 +60,7 @@
import org.jboss.messaging.core.message.MessageFactory;
import org.jboss.messaging.core.message.MessageSupport;
import org.jboss.messaging.core.plugin.contract.PersistenceManager;
+import org.jboss.messaging.core.tx.PreparedTxInfo;
import org.jboss.messaging.core.tx.Transaction;
import org.jboss.messaging.core.tx.TxCallback;
import org.jboss.messaging.core.tx.XidImpl;
@@ -72,6 +75,7 @@
* @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
* @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
* @author <a href="mailto:adrian at jboss.org">Adrian Brock</a>
+ * @author <a href="mailto:juha at jboss.org">Juha Lindfors</a>
*
* @version <tt>1.1</tt>
*
@@ -95,6 +99,9 @@
private int maxParams;
+ private short orderCount;
+
+
// Constructors --------------------------------------------------
public JDBCPersistenceManager(DataSource ds, TransactionManager tm, Properties sqlProperties,
@@ -146,7 +153,7 @@
//We can't remnove unreliable data since it might introduce holes into the paging order
//removeUnreliableMessageData();
-
+
log.debug(this + " started");
}
@@ -157,6 +164,107 @@
// PersistenceManager implementation -------------------------
+ // Related to XA Recovery
+ // ======================
+
+ public List getMessageChannelPairRefsForTx(long transactionId) throws Exception
+ {
+ String sql = this.getSQLStatement("SELECT_MESSAGEID_FOR_REF");
+ return getMessageChannelPair(sql, transactionId);
+ }
+
+ public List getMessageChannelPairAcksForTx(long transactionId) throws Exception
+ {
+ String sql = this.getSQLStatement("SELECT_MESSAGEID_FOR_ACK");
+ return getMessageChannelPair(sql, transactionId);
+ }
+
+ public List retrievePreparedTransactions() throws Exception
+ {
+ /* Note the API change for 1.0.2 XA Recovery -- List now contains instances of PreparedTxInfo<TxId, Xid>
+ * instead of direct Xids [JPL] */
+
+ Connection conn = null;
+ Statement st = null;
+ ResultSet rs = null;
+ PreparedTxInfo txInfo = null;
+ TransactionWrapper wrap = new TransactionWrapper();
+
+ try
+ {
+ List transactions = new ArrayList();
+
+ conn = ds.getConnection();
+
+ st = conn.createStatement();
+
+ String sql = this.getSQLStatement("SELECT_PREPARED_TRANSACTIONS");
+
+ rs = st.executeQuery(sql);
+
+ while (rs.next())
+ {
+ //get the existing tx id --MK START
+ long txId = rs.getLong(1);
+
+ byte[] branchQual = rs.getBytes(2);
+ int formatId = rs.getInt(3);
+ byte[] globalTxId = rs.getBytes(4);
+ Xid xid = new XidImpl(branchQual, formatId, globalTxId);
+
+ // create a tx info object with the result set detailsdetails
+ txInfo = new PreparedTxInfo(txId, xid);
+ transactions.add(txInfo);
+ }
+
+ return transactions;
+
+ }
+ catch (Exception e)
+ {
+ wrap.exceptionOccurred();
+ throw e;
+ }
+ finally
+ {
+ if (rs != null)
+ {
+ try
+ {
+ rs.close();
+ }
+ catch (Throwable e)
+ {
+ }
+ }
+ if (st != null)
+ {
+ try
+ {
+ st.close();
+ }
+ catch (Throwable e)
+ {
+ }
+ }
+ if (conn != null)
+ {
+ try
+ {
+ conn.close();
+ }
+ catch (Throwable e)
+ {
+ }
+ }
+ wrap.end();
+ }
+ }
+
+
+
+
+
// Related to counters
// ===================
@@ -1181,7 +1289,7 @@
PreparedStatement ps = null;
ResultSet rs = null;
TransactionWrapper wrap = new TransactionWrapper();
-
+
try
{
conn = ds.getConnection();
@@ -1209,6 +1317,12 @@
maxOrdering = null;
}
+ //For unpaged refs we must make sure we only load refs with state='C' - i.e.
+ //they're not part of an XA transactions.
+ //Otherwise we could end up loading message that hadn't be committed
+ //or end up loading refs which are due to be acked by a transaction that's yet
+ //to be recovered.
+
ps = conn.prepareStatement(getSQLStatement("LOAD_UNPAGED_REFS"));
ps.setLong(1, channelID);
@@ -1574,77 +1688,7 @@
}
}
-
- public List retrievePreparedTransactions() throws Exception
- {
- Connection conn = null;
- Statement st = null;
- ResultSet rs = null;
- TransactionWrapper wrap = new TransactionWrapper();
-
- try
- {
- List transactions = new ArrayList();
-
- conn = ds.getConnection();
-
- st = conn.createStatement();
- rs = st.executeQuery(getSQLStatement("SELECT_PREPARED_TRANSACTIONS"));
-
- while (rs.next())
- {
- byte[] branchQual = rs.getBytes(2);
- int formatId = rs.getInt(3);
- byte[] globalTxId = rs.getBytes(4);
- Xid xid = new XidImpl(branchQual, formatId, globalTxId);
-
- transactions.add(xid);
- }
-
- return transactions;
-
- }
- catch (Exception e)
- {
- wrap.exceptionOccurred();
- throw e;
- }
- finally
- {
- if (rs != null)
- {
- try
- {
- rs.close();
- }
- catch (Throwable e)
- {
- }
- }
- if (st != null)
- {
- try
- {
- st.close();
- }
- catch (Throwable e)
- {
- }
- }
- if (conn != null)
- {
- try
- {
- conn.close();
- }
- catch (Throwable e)
- {
- }
- }
- wrap.end();
- }
- }
-
+
public boolean referenceExists(long channelID, long messageID) throws Exception
{
Connection conn = null;
@@ -2811,6 +2855,8 @@
protected void commitPreparedTransaction(Transaction tx, Connection conn) throws Exception
{
PreparedStatement ps = null;
+
+ if (trace) { log.trace(this + " commitPreparedTransaction, tx= " + tx); }
try
{
@@ -2833,7 +2879,7 @@
if (trace)
{
- log.trace(JDBCUtil.statementToString(getSQLStatement("COMMIT_MESSAGE_REF2"), null, new Long(tx.getId())) + " updated " + rows
+ log.trace(JDBCUtil.statementToString(getSQLStatement("COMMIT_MESSAGE_REF2"), new Long(tx.getId())) + " updated " + rows
+ " row(s)");
}
@@ -2880,7 +2926,7 @@
if (trace)
{
- log.trace(JDBCUtil.statementToString(getSQLStatement("ROLLBACK_MESSAGE_REF2"), null, new Long(tx.getId())) + " updated " + rows
+ log.trace(JDBCUtil.statementToString(getSQLStatement("ROLLBACK_MESSAGE_REF2"), new Long(tx.getId())) + " updated " + rows
+ " row(s)");
}
@@ -3248,8 +3294,8 @@
"SELECT MESSAGEID, DELIVERYCOUNT, PAGE_ORD, RELIABLE FROM JMS_MESSAGE_REFERENCE " +
"WHERE CHANNELID = ? AND PAGE_ORD BETWEEN ? AND ? ORDER BY PAGE_ORD");
map.put("LOAD_UNPAGED_REFS",
- "SELECT MESSAGEID, DELIVERYCOUNT, RELIABLE FROM JMS_MESSAGE_REFERENCE " +
- "WHERE PAGE_ORD IS NULL and CHANNELID = ? ORDER BY ORD");
+ "SELECT MESSAGEID, DELIVERYCOUNT, RELIABLE FROM JMS_MESSAGE_REFERENCE WHERE STATE = 'C' " +
+ "AND CHANNELID = ? AND PAGE_ORD IS NULL ORDER BY ORD");
map.put("UPDATE_RELIABLE_REFS_NOT_PAGED", "UPDATE JMS_MESSAGE_REFERENCE SET PAGE_ORD = NULL WHERE PAGE_ORD BETWEEN ? AND ? AND CHANNELID=?");
map.put("SELECT_MIN_MAX_PAGE_ORD", "SELECT MIN(PAGE_ORD), MAX(PAGE_ORD) FROM JMS_MESSAGE_REFERENCE WHERE CHANNELID = ?");
map.put("SELECT_EXISTS_REF", "SELECT MESSAGEID FROM JMS_MESSAGE_REFERENCE WHERE CHANNELID = ? AND MESSAGEID = ?");
@@ -3276,6 +3322,9 @@
"VALUES(?, ?, ?, ?)");
map.put("DELETE_TRANSACTION", "DELETE FROM JMS_TRANSACTION WHERE TRANSACTIONID = ?");
map.put("SELECT_PREPARED_TRANSACTIONS", "SELECT TRANSACTIONID, BRANCH_QUAL, FORMAT_ID, GLOBAL_TXID FROM JMS_TRANSACTION");
+ map.put("SELECT_MESSAGEID_FOR_REF", "SELECT MESSAGEID, CHANNELID FROM JMS_MESSAGE_REFERENCE WHERE TRANSACTIONID = ? AND STATE = '+'");
+ map.put("SELECT_MESSAGEID_FOR_ACK", "SELECT MESSAGEID, CHANNELID FROM JMS_MESSAGE_REFERENCE WHERE TRANSACTIONID = ? AND STATE = '-'");
+
//Counter
map.put("UPDATE_COUNTER", "UPDATE JMS_COUNTER SET NEXT_ID = ? WHERE NAME=?");
map.put("SELECT_COUNTER", "SELECT NEXT_ID FROM JMS_COUNTER WHERE NAME=?");
@@ -3287,7 +3336,132 @@
// Private -------------------------------------------------------
- private short orderCount;
+ private List getMessageChannelPair(String sqlQuery, long transactionId) throws Exception
+ {
+ if (trace) log.trace("loading message and channel ids for tx [" + transactionId + "]");
+
+ Connection conn = null;
+ PreparedStatement ps = null;
+ ResultSet rs = null;
+ TransactionWrapper wrap = new TransactionWrapper();
+
+ try
+ {
+ conn = ds.getConnection();
+
+ ps = conn.prepareStatement(sqlQuery);
+
+ ps.setLong(1, transactionId);
+
+ rs = ps.executeQuery();
+
+ //Don't use a Map. A message could be in multiple channels in a tx, so if you use a map
+ //when you put the same message again it's going to overwrite the previous put!!
+
+ List holders = new ArrayList();
+
+ //Unique set of messages
+ Set msgIds = new HashSet();
+
+ //TODO it would probably have been simpler just to have done all this in a SQL JOIN rather
+ //than do the join in memory.....
+
+ class Holder
+ {
+ long messageId;
+ long channelId;
+ Holder(long messageId, long channelId)
+ {
+ this.messageId = messageId;
+ this.channelId = channelId;
+ }
+ }
+
+ while(rs.next())
+ {
+ long messageId = rs.getLong(1);
+ long channelId = rs.getLong(2);
+
+ Holder holder = new Holder(messageId, channelId);
+
+ holders.add(holder);
+
+ msgIds.add(new Long(messageId));
+
+ if (trace) log.trace("Loaded MsgID: " + messageId + " and ChannelID: " + channelId);
+ }
+
+ Map messageMap = new HashMap();
+
+ List messages = getMessages(new ArrayList(msgIds));
+
+ for (Iterator iter = messages.iterator(); iter.hasNext(); )
+ {
+ Message msg = (Message)iter.next();
+
+ messageMap.put(new Long(msg.getMessageID()), msg);
+ }
+
+ List returnList = new ArrayList();
+
+ for (Iterator iter = holders.iterator(); iter.hasNext(); )
+ {
+ Holder holder = (Holder)iter.next();
+
+ Message msg = (Message)messageMap.get(new Long(holder.messageId));
+
+ if (msg == null)
+ {
+ throw new IllegalStateException("Cannot find message " + holder.messageId);
+ }
+
+ MessageChannelPair pair = new MessageChannelPair(msg, holder.channelId);
+
+ returnList.add(pair);
+ }
+
+ return returnList;
+ }
+ catch (Exception e)
+ {
+ wrap.exceptionOccurred();
+ throw e;
+ }
+ finally
+ {
+ if (rs != null)
+ {
+ try
+ {
+ rs.close();
+ }
+ catch (Throwable e)
+ {
+ }
+ }
+ if (ps != null)
+ {
+ try
+ {
+ ps.close();
+ }
+ catch (Throwable e)
+ {
+ }
+ }
+ if (conn != null)
+ {
+ try
+ {
+ conn.close();
+ }
+ catch (Throwable e)
+ {
+ }
+ }
+ wrap.end();
+ }
+ }
private synchronized long getOrdering()
{
Modified: trunk/src/main/org/jboss/messaging/core/plugin/contract/ClusteredPostOffice.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/contract/ClusteredPostOffice.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/src/main/org/jboss/messaging/core/plugin/contract/ClusteredPostOffice.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -61,7 +61,5 @@
*/
Binding unbindClusteredQueue(String queueName) throws Throwable;
- Collection listAllBindingsForCondition(Condition condition) throws Exception;
-
- Binding getBindingforChannelId(long channelId) throws Exception;
+ Collection listAllBindingsForCondition(Condition condition) throws Exception;
}
Modified: trunk/src/main/org/jboss/messaging/core/plugin/contract/PersistenceManager.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/contract/PersistenceManager.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/src/main/org/jboss/messaging/core/plugin/contract/PersistenceManager.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -22,7 +22,9 @@
package org.jboss.messaging.core.plugin.contract;
import java.util.List;
+import java.util.Map;
+import org.jboss.messaging.core.Message;
import org.jboss.messaging.core.MessageReference;
import org.jboss.messaging.core.tx.Transaction;
@@ -31,6 +33,9 @@
*
* @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
* @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @author <a href="mailto:Konda.Madhu at uk.mizuho-sc.com">Madhu Konda</a>
+ * @author <a href="mailto:juha at jboss.org">Juha Lindfors</a>
+ *
* @version <tt>1.1</tt>
*
* PersistenceManager.java,v 1.1 2006/02/22 17:33:42 timfox Exp
@@ -43,10 +48,14 @@
void updateDeliveryCount(long channelID, MessageReference ref) throws Exception;
-
// XA Recovery functionality
List retrievePreparedTransactions() throws Exception;
+
+ List getMessageChannelPairRefsForTx(long transactionId) throws Exception;
+
+ List getMessageChannelPairAcksForTx(long transactionId) throws Exception;
+
// Paging functionality - TODO we should split this out into its own interface
@@ -75,6 +84,30 @@
// Interface value classes
//---------------------------------------------------------------
+ class MessageChannelPair
+ {
+ private Message message;
+
+ private long channelId;
+
+ public MessageChannelPair(Message message, long channelId)
+ {
+ this.message = message;
+
+ this.channelId = channelId;
+ }
+
+ public Message getMessage()
+ {
+ return message;
+ }
+
+ public long getChannelId()
+ {
+ return channelId;
+ }
+ }
+
class ReferenceInfo
{
private long messageId;
@@ -107,7 +140,6 @@
return reliable;
}
}
-
class InitialLoadInfo
{
private Long minPageOrdering;
Modified: trunk/src/main/org/jboss/messaging/core/plugin/contract/PostOffice.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/contract/PostOffice.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/src/main/org/jboss/messaging/core/plugin/contract/PostOffice.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -89,4 +89,6 @@
* @return true if it is a non clustered post office
*/
boolean isLocal();
+
+ Binding getBindingforChannelId(long channelId) throws Exception;
}
Modified: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/DefaultPostOffice.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/DefaultPostOffice.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/DefaultPostOffice.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -58,7 +58,7 @@
import EDU.oswego.cs.dl.util.concurrent.QueuedExecutor;
import EDU.oswego.cs.dl.util.concurrent.ReadWriteLock;
-import EDU.oswego.cs.dl.util.concurrent.WriterPreferenceReadWriteLock;
+import EDU.oswego.cs.dl.util.concurrent.ReentrantWriterPreferenceReadWriteLock;
/**
*
@@ -117,7 +117,7 @@
{
super (ds, tm, sqlProperties, createTablesOnStartup);
- lock = new WriterPreferenceReadWriteLock();
+ lock = new ReentrantWriterPreferenceReadWriteLock();
nameMaps = new LinkedHashMap();
@@ -386,6 +386,40 @@
{
return true;
}
+
+ public Binding getBindingforChannelId(long channelId) throws Exception
+ {
+ lock.readLock().acquire();
+
+ try
+ {
+ Map nameMap = (Map)nameMaps.get(new Integer(currentNodeId));
+
+ if (nameMap == null)
+ {
+ throw new IllegalStateException("Cannot find name map for current node " + currentNodeId);
+ }
+
+ Binding binding = null;
+
+ for (Iterator iterbindings = nameMap.values().iterator(); iterbindings.hasNext();)
+ {
+ Binding itemBinding = (Binding)iterbindings.next();
+
+ if (itemBinding.getQueue().getChannelID() == channelId)
+ {
+ binding = itemBinding;
+ break;
+ }
+ }
+
+ return binding;
+ }
+ finally
+ {
+ lock.readLock().release();
+ }
+ }
// Protected -----------------------------------------------------
Modified: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/DefaultClusteredPostOffice.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/DefaultClusteredPostOffice.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/DefaultClusteredPostOffice.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -542,25 +542,7 @@
if (binding == null)
{
- //Not found in the failed map - look in the name map
- Map nameMap = (Map)nameMaps.get(new Integer(currentNodeId));
-
- if (nameMap != null)
- {
- for (Iterator iterbindings = nameMap.values().iterator(); iterbindings.hasNext();)
- {
- Binding itemBinding = (Binding)iterbindings.next();
- if (itemBinding.getQueue().getChannelID() == channelId)
- {
- binding = itemBinding;
- break;
- }
- }
- }
- else
- {
- log.info("nameMap is null");
- }
+ binding = super.getBindingforChannelId(channelId);
}
log.info("Returned " + binding);
return binding;
Modified: trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/RemoteQueueStub.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/RemoteQueueStub.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/src/main/org/jboss/messaging/core/plugin/postoffice/cluster/RemoteQueueStub.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -237,7 +237,7 @@
throw new UnsupportedOperationException();
}
- public List createDeliveries(List messageIds)
+ public List recoverDeliveries(List messageIds)
{
throw new UnsupportedOperationException();
}
@@ -288,6 +288,11 @@
return "RemoteQueueStub[" + channelID + "/" + name + " -> " + nodeID + "]";
}
+ public void addDelivery(Delivery del)
+ {
+ throw new UnsupportedOperationException();
+ }
+
// Package protected ---------------------------------------------
// Protected -----------------------------------------------------
Copied: trunk/src/main/org/jboss/messaging/core/tx/PreparedTxInfo.java (from rev 1823, branches/Branch_1_0/src/main/org/jboss/messaging/core/tx/PreparedTxInfo.java)
Modified: trunk/src/main/org/jboss/messaging/core/tx/Transaction.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/tx/Transaction.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/src/main/org/jboss/messaging/core/tx/Transaction.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -52,15 +52,17 @@
private boolean trace = log.isTraceEnabled();
- protected long id;
+ private long id;
- protected int state;
+ private int state;
- protected Xid xid;
+ private Xid xid;
- protected List callbacks;
+ private List callbacks;
- protected Map callbackMap;
+ private Map callbackMap;
+
+ private boolean loadedAtStartup;
/**
@@ -225,7 +227,7 @@
firstCallback = null;
- if (repository !=null)
+ if (repository != null)
{
repository.deleteTransaction(this);
}
@@ -344,6 +346,21 @@
{
return id;
}
+
+ public boolean isLoadedAtStartup()
+ {
+ return this.loadedAtStartup;
+ }
+
+ public void setLoadedAtStartup(boolean loadedAtStartup)
+ {
+ this.loadedAtStartup = loadedAtStartup;
+ }
+
+ public void setState(int state)
+ {
+ this.state = state;
+ }
public String toString()
{
Modified: trunk/src/main/org/jboss/messaging/core/tx/TransactionRepository.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/tx/TransactionRepository.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/src/main/org/jboss/messaging/core/tx/TransactionRepository.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -29,17 +29,27 @@
import javax.transaction.xa.Xid;
import org.jboss.logging.Logger;
+import org.jboss.messaging.core.Delivery;
+import org.jboss.messaging.core.Message;
+import org.jboss.messaging.core.MessageReference;
+import org.jboss.messaging.core.Queue;
+import org.jboss.messaging.core.SimpleDelivery;
import org.jboss.messaging.core.plugin.IDManager;
+import org.jboss.messaging.core.plugin.contract.MessageStore;
import org.jboss.messaging.core.plugin.contract.MessagingComponent;
import org.jboss.messaging.core.plugin.contract.PersistenceManager;
+import org.jboss.messaging.core.plugin.contract.PostOffice;
+import org.jboss.messaging.core.plugin.postoffice.Binding;
import EDU.oswego.cs.dl.util.concurrent.ConcurrentReaderHashMap;
-
/**
* This class maintains JMS Server local transactions.
*
* @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @author <a href="mailto:Konda.Madhu at uk.mizuho-sc.com">Madhu Konda</a>
+ * @author <a href="mailto:juha at jboss.org">Juha Lindfors</a>
+ *
* @version $Revision 1.1 $
*
* $Id$
@@ -57,22 +67,38 @@
private Map globalToLocalMap;
private PersistenceManager persistenceManager;
+
+ protected MessageStore messageStore;
+
+ private IDManager idManager;
- private IDManager idManager;
-
+ private PostOffice postOffice;
+
// Static --------------------------------------------------------
// Constructors --------------------------------------------------
- public TransactionRepository(PersistenceManager persistenceManager, IDManager idManager)
+ public TransactionRepository(PersistenceManager persistenceManager, MessageStore store, IDManager idManager)
{
this.persistenceManager = persistenceManager;
+ this.messageStore = store;
+
this.idManager = idManager;
-
+
globalToLocalMap = new ConcurrentReaderHashMap();
}
+ // Injection ----------------------------------------
+
+ //Unfortunately we have to do this for now, since PostOffice is not started until after this is constructed
+ //We will sort out dependencies properly when we go to the micro container
+ public void injectPostOffice(PostOffice po)
+ {
+ postOffice = po;
+ }
+
+
// MessagingComponent implementation --------------------------------
public void start() throws Exception
@@ -80,6 +106,8 @@
//NOOP
}
+ // Public --------------------------------------------------------
+
public void stop() throws Exception
{
//NOOP
@@ -87,53 +115,94 @@
// Public --------------------------------------------------------
- public List getPreparedTransactions()
+ /**
+ * Attempts to recover existing prepared transactions by redelivering unhandled messages and acknowledgements
+ * on the appropriate channels.
+ *
+ * @return List of Xid instances
+ */
+ public synchronized List recoverPreparedTransactions()
{
+ if (trace) { log.trace(this + " recoverPreparedTransactions()"); }
+
ArrayList prepared = new ArrayList();
-
+
Iterator iter = globalToLocalMap.values().iterator();
-
+
while (iter.hasNext())
{
- Transaction tx = (Transaction)iter.next();
-
- if (tx.xid != null && tx.getState() == Transaction.STATE_PREPARED)
+ Transaction tx = (Transaction) iter.next();
+
+ if (tx.getXid() != null && tx.getState() == Transaction.STATE_PREPARED)
{
+ try
+ {
+ if (trace) log.trace("Loading and handling refs and acks to the Tx "+tx);
+
+ //The transaction might have been created, prepared, without the server crashing
+ //in which case the tx will already have the references and acks in them
+ //in this case we DO NOT want to replay them again, since they will end up in the transaction state
+ //twice
+ //In other words we only want to replay acks and sends if this tx was loaded at startup
+ if (tx.isLoadedAtStartup())
+ {
+ handleReferences(tx);
+ handleAcks(tx);
+
+ tx.setLoadedAtStartup(false);
+ }
+ }
+ catch (Exception e)
+ {
+ log.warn("Failed to replay transaction (XID: " + tx.getXid() + ", LocalID: " + tx.getId() + ") during recovery.", e);
+ }
+
prepared.add(tx.getXid());
}
}
+
return prepared;
}
-
+
/*
- * Load any prepared transactions into the repository so they can be recovered
+ * Load any prepared transactions into the repository so they can be
+ * recovered
*/
public void loadPreparedTransactions() throws Exception
{
+ if (trace) log.trace("load prepared transactions...");
+
List prepared = null;
-
+
prepared = persistenceManager.retrievePreparedTransactions();
-
+
+ if (trace) log.trace ("Found " + prepared.size() + " transactions in prepared state:");
+
if (prepared != null)
- {
+ {
Iterator iter = prepared.iterator();
-
+
while (iter.hasNext())
{
- Xid xid = (Xid)iter.next();
+ PreparedTxInfo txInfo = (PreparedTxInfo) iter.next();
+
+ if (trace) log.trace("Reinstating TX(XID: " + txInfo.getXid() + ", LocalId " + txInfo.getTxId() +")");
- Transaction tx = createTransaction(xid);
+ Transaction tx = createTransaction(txInfo);
- tx.state = Transaction.STATE_PREPARED;
+ tx.setState(Transaction.STATE_PREPARED);
- //Load the references for this transaction
+ tx.setLoadedAtStartup(true);
+
}
}
}
-
+
+
public Transaction getPreparedTx(Xid xid) throws Exception
{
Transaction tx = (Transaction)globalToLocalMap.get(xid);
+
if (tx == null)
{
throw new TransactionException("Cannot find local tx for xid:" + xid);
@@ -159,7 +228,7 @@
{
throw new TransactionException("Transaction with xid " + id + " can't be removed as it's not yet commited or rolledback: (Current state is " + Transaction.stateToString(state));
}
-
+
globalToLocalMap.remove(id);
}
@@ -186,7 +255,7 @@
return tx;
}
-
+
public boolean removeTransaction(Xid xid)
{
return globalToLocalMap.remove(xid) != null;
@@ -203,7 +272,220 @@
// Protected -----------------------------------------------------
// Private -------------------------------------------------------
+
+ /**
+ * Load the references and invoke the channel to handle those refs
+ */
+ private void handleReferences(Transaction tx) throws Exception
+ {
+ if (trace) log.trace("Handle references for TX(XID: " + tx.getXid() + ", LocalID: " + tx.getId()+ "):");
+
+ long txId = tx.getId();
+
+ List pairs = persistenceManager.getMessageChannelPairRefsForTx(txId);
+
+ if (trace) log.trace("Found " + pairs.size() + " unhandled references.");
+
+ for (Iterator iter = pairs.iterator(); iter.hasNext();)
+ {
+ PersistenceManager.MessageChannelPair pair = (PersistenceManager.MessageChannelPair)iter.next();
+
+ Message msg = pair.getMessage();
+
+ long channelID = pair.getChannelId();
+
+ MessageReference ref = null;
+
+ try
+ {
+ ref = messageStore.reference(msg);
+
+ //Need to get the post office reference lazily, cannot pass into constructor
+ Binding binding = postOffice.getBindingforChannelId(channelID);
+
+ if (binding == null)
+ {
+ throw new IllegalStateException("Cannot find binding for channel id " + channelID);
+ }
+
+ Queue queue = binding.getQueue();
+
+ if (trace) log.trace("Destination for message[ID=" + ref.getMessageID() + "] is: " + queue);
+ queue.handle(null, ref, tx);
+ }
+ finally
+ {
+ if (ref != null)
+ {
+ //Need to release reference
+ ref.releaseMemoryReference();
+ }
+ }
+ }
+ }
+
+ /**
+ * Load the acks and acknowledge them
+ */
+ private void handleAcks(Transaction tx) throws Exception
+ {
+ long txId = tx.getId();
+
+ List pairs = persistenceManager.getMessageChannelPairAcksForTx(txId);
+
+ if (trace) log.trace("Found " + pairs.size() + " unhandled acks.");
+
+ List dels = new ArrayList();
+
+ for (Iterator iter = pairs.iterator(); iter.hasNext();)
+ {
+ PersistenceManager.MessageChannelPair pair = (PersistenceManager.MessageChannelPair)iter.next();
+
+ Message msg = pair.getMessage();
+
+ long channelID = pair.getChannelId();
+
+ MessageReference ref = null;
+
+ try
+ {
+ ref = messageStore.reference(msg);
+
+ // Need to get the post office reference lazily, cannot pass into constructor
+ Binding binding = postOffice.getBindingforChannelId(channelID);
+
+ if (binding == null)
+ {
+ throw new IllegalStateException("Cannot find binding for channel id " + channelID);
+ }
+
+ Queue queue = binding.getQueue();
+
+ if (trace) log.trace("Destination for message[ID=" + ref.getMessageID() + "] is: " + queue);
+
+ //Create a new delivery - note that it must have a delivery observer otherwise acknowledge will fail
+ Delivery del = new SimpleDelivery(queue, ref);
+
+ if (trace) log.trace("Acknowledging..");
+
+ try
+ {
+ //At this point there won't be a delivery in the channel for this ref - since
+ //we won't have loaded it when the queue was loaded (since the stat column would have been '-')
+ //so we add it
+
+ queue.addDelivery(del);
+
+ del.acknowledge(tx);
+ }
+ catch (Throwable t)
+ {
+ log.error("Failed to acknowledge " + del + " during recovery", t);
+ }
+
+ dels.add(del);
+ }
+ finally
+ {
+ if (ref != null)
+ {
+ //Need to release reference
+ ref.releaseMemoryReference();
+ }
+ }
+ }
+
+ if (!dels.isEmpty())
+ {
+ //Add a callback so these dels get cancelled on rollback
+ tx.addCallback(new CancelCallback(dels), this);
+ }
+
+ }
+
+ /**
+ * Creates a prepared transaction
+ *
+ * @param txInfo
+ * @return
+ * @throws Exception
+ */
+ private Transaction createTransaction(PreparedTxInfo txInfo) throws Exception
+ {
+ if (globalToLocalMap.containsKey(txInfo.getXid()))
+ {
+ throw new TransactionException(
+ "There is already a local tx for global tx " + txInfo.getXid());
+ }
+
+ // Resurrected tx
+ Transaction tx = new Transaction(txInfo.getTxId(), txInfo.getXid(), this);
+
+ if (trace) {
+ log.trace("created transaction " + tx);
+ }
+
+ globalToLocalMap.put(txInfo.getXid(), tx);
+
+ return tx;
+ }
+
// Inner classes -------------------------------------------------
+ private class CancelCallback implements TxCallback
+ {
+ private List toCancel;
+
+ private CancelCallback(List toCancel)
+ {
+ this.toCancel = toCancel;
+ }
+
+ public void afterCommit(boolean onePhase) throws Exception
+ {
+ }
+
+ public void afterPrepare() throws Exception
+ {
+ }
+
+ public void afterRollback(boolean onePhase) throws Exception
+ {
+ //On rollback we need to cancel the ref back into the channel
+ //We only need to do this if the tx was reloaded since otherwise the
+ //cancel will come from the SCE
+
+ //Need to cancel in reverse
+
+ for (int i = toCancel.size() - 1; i >= 0; i--)
+ {
+ Delivery del = (Delivery)toCancel.get(i);
+
+ try
+ {
+ del.cancel();
+ }
+ catch (Throwable t)
+ {
+ log.error("Failed to cancel delivery", t);
+ throw new TransactionException(t.getMessage(), t);
+ }
+ }
+ }
+
+ public void beforeCommit(boolean onePhase) throws Exception
+ {
+ }
+
+ public void beforePrepare() throws Exception
+ {
+ }
+
+ public void beforeRollback(boolean onePhase) throws Exception
+ {
+ }
+
+ }
+
}
\ No newline at end of file
Modified: trunk/src/main/org/jboss/messaging/core/tx/XidImpl.java
===================================================================
--- trunk/src/main/org/jboss/messaging/core/tx/XidImpl.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/src/main/org/jboss/messaging/core/tx/XidImpl.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -21,6 +21,8 @@
*/
package org.jboss.messaging.core.tx;
+import java.io.Serializable;
+
import javax.transaction.xa.Xid;
/**
@@ -29,11 +31,14 @@
*
* @author <a href="mailto:adrian at jboss.org>Adrian Brock</a>
* @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @author <a href="mailto:juha at jboss.org">Juha Lindfors</a>
*
* @version $Revision 1.1 $
*/
-public class XidImpl implements Xid
+public class XidImpl implements Xid, Serializable
{
+ private static final long serialVersionUID = -1893120702576869245L;
+
protected byte[] branchQualifier;
protected int formatId;
@@ -57,6 +62,11 @@
return globalTransactionId;
}
+ //For serialization
+ public XidImpl()
+ {
+ }
+
public XidImpl(byte[] branchQualifier, int formatId, byte[] globalTransactionId)
{
this.branchQualifier = branchQualifier;
@@ -118,4 +128,11 @@
return true;
}
+ public String toString()
+ {
+ return getClass().getName() + "(GID: " + new String(getGlobalTransactionId()) +
+ ", Branch: " + new String(getBranchQualifier()) +
+ ", Format: " + getFormatId() + ")";
+ }
+
}
Modified: trunk/tests/build.xml
===================================================================
--- trunk/tests/build.xml 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/tests/build.xml 2006-12-21 23:41:19 UTC (rev 1843)
@@ -191,6 +191,7 @@
<path refid="test.compilation.classpath"/>
<path refid="dom4j.dom4j.classpath"/>
<path refid="apache.log4j.classpath"/>
+ <path refid="apache.logging.classpath"/>
<path refid="apache.xerces.classpath"/>
<path refid="jboss.mbeans.classpath"/>
<path refid="jboss.naming.classpath"/>
@@ -410,6 +411,52 @@
</junit>
</target>
+ <target name="local-jms-tests" depends="tests-jar, prepare-testdirs, clear-test-logs"
+ description="Runs all available tests an in-VM configuration">
+
+ <echo message=""/>
+ <echo message="Running invm tests, fork=${junit.fork}, junit.batchtest.fork=${junit.batchtest.fork}"/>
+ <echo message=""/>
+
+ <junit printsummary="${junit.printsummary}"
+ fork="${junit.fork}"
+ includeantruntime="${junit.includeantruntime}"
+ haltonerror="${junit.haltonerror}"
+ haltonfailure="${junit.haltonfailure}"
+ showoutput="${junit.showoutput}"
+ timeout="${junit.timeout}">
+
+ <sysproperty key="remote" value="false"/>
+ <sysproperty key="module.output" value="${tests.output}"/>
+ <sysproperty key="test.bind.address" value="${test.bind.address}"/>
+ <sysproperty key="test.database" value="${functional.tests.database}"/>
+ <sysproperty key="test.serialization" value="${functional.tests.serialization}"/>
+ <sysproperty key="test.logfile.suffix" value="invm"/>
+ <sysproperty key="build.lib" value="${build.lib}"/>
+ <jvmarg value="-Xmx512M"/>
+ <!--
+ <jvmarg line="-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_shmem,server=y,suspend=y,address=antjunit"/>
+ -->
+ <classpath refid="test.execution.classpath"/>
+ <formatter type="xml" usefile="${junit.formatter.usefile}"/>
+ <batchtest fork="${junit.batchtest.fork}"
+ todir="${junit.batchtest.todir}"
+ haltonfailure="${junit.batchtest.haltonfailure}"
+ haltonerror="${junit.batchtest.haltonerror}">
+ <formatter type="plain" usefile="${junit.formatter.usefile}"/>
+ <fileset dir="${build.tests.classes}">
+ <include name="**/messaging/jms/**/*Test.class"/>
+ <exclude name="**/jms/stress/**"/>
+ <exclude name="**/jms/crash/*Test.class"/>
+ <exclude name="**/jms/MemLeakTest.class"/>
+ <exclude name="**/jms/manual/**/*Test.class"/>
+ <exclude name="**/jms/clustering/*Test.class"/>
+ <exclude name="**/jms/RemotingConnectionConfigurationTest.class"/>
+ </fileset>
+ </batchtest>
+ </junit>
+ </target>
+
<target name="memory-leak-tests" depends="tests-jar, prepare-testdirs, clear-test-logs"
description="Runs memory-leak tests using JBossProfiler in-VM configuration">
@@ -772,7 +819,7 @@
<!--
<include name="**/jms/clustering/FailoverTest.class"/>
-->
- <include name="**/jms/clustering/*Test.class"/>
+ <include name="**/jms/clustering/HATest.class"/>
</fileset>
</batchtest>
</junit>
Modified: trunk/tests/smoke/build.xml
===================================================================
--- trunk/tests/smoke/build.xml 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/tests/smoke/build.xml 2006-12-21 23:41:19 UTC (rev 1843)
@@ -77,6 +77,7 @@
<!-- 4.0.0, 4.0.1 NOT SUPPORTED -->
+<<<<<<< .working
<!--
Note on installer versions.
When installing versions to test via the JBoss installer, make sure call by value is *not*
@@ -84,17 +85,51 @@
the arrangement where JBoss is configured for all pass by reference
-->
+=======
+ <!--
+ 4.0.1sp1
+ -->
+
+>>>>>>> .merge-right.r1823
<antcall target="installation-test">
<param name="jboss.home" value="${jboss401sp1.home}"/>
<param name="run.secure-socket.example" value="false"/>
</antcall>
+ <!--
+ 4.0.2
+ -->
+
<antcall target="installation-test">
<param name="jboss.home" value="${jboss402.home}"/>
<param name="run.secure-socket.example" value="false"/>
</antcall>
+<<<<<<< .working
+=======
+<!--
+ <!--
+ 4.0.3
+ -->
<antcall target="installation-test">
+ <param name="jboss.home" value="${jboss403.home}"/>
+ <param name="run.secure-socket.example" value="false"/>
+ </antcall>
+>>>>>>> .merge-right.r1823
+
+ <antcall target="installation-test">
+<<<<<<< .working
+=======
+ <param name="jboss.home" value="${jboss403-installer.home}"/>
+ <param name="run.secure-socket.example" value="false"/>
+ </antcall>
+-->
+ <!--
+ 4.0.3SP1
+ -->
+
+ <antcall target="installation-test">
+>>>>>>> .merge-right.r1823
<param name="jboss.home" value="${jboss403SP1.home}"/>
<param name="run.secure-socket.example" value="false"/>
</antcall>
@@ -112,6 +147,10 @@
<param name="run.secure-socket.example" value="false"/>
</antcall>
+ <!--
+ 4.0.4.GA
+ -->
+
<antcall target="installation-test">
<param name="jboss.home" value="${jboss404GA.home}"/>
</antcall>
@@ -127,12 +166,44 @@
<param name="run.stateless.example" value="false"/>
<param name="run.secure-socket.example" value="false"/>
</antcall>
+<<<<<<< .working
+=======
+<!--
+ <!--
+ 4.0.5.GA
+ -->
<antcall target="installation-test">
<param name="jboss.home" value="${jboss405GA.home}"/>
</antcall>
+>>>>>>> .merge-right.r1823
+ <!--
+ <antcall target="installation-test">
+<<<<<<< .working
+=======
+ <param name="jboss.home" value="${jboss405GA-installer.home}"/>
+ </antcall>
+ -->
+ <antcall target="installation-test">
+ <param name="jboss.home" value="${jboss405GA.home}"/>
+ <param name="release.admin.target" value="standalone"/>
+ <param name="run.mdb.example" value="false"/>
+ <param name="run.stateless.example" value="false"/>
+ <param name="run.secure-socket.example" value="false"/>
+ </antcall>
<antcall target="installation-test">
+ <param name="jboss.home" value="${jboss405GAejb3.home}"/>
+ <param name="no.java4" value="true"/>
+ <param name="run.ejb3mdb.example" value="true"/>
+ </antcall>
+-->
+ <antcall target="installation-test">
+>>>>>>> .merge-right.r1823
+ <param name="jboss.home" value="${jboss405GA.home}"/>
+ </antcall>
+
+ <antcall target="installation-test">
<param name="jboss.home" value="${jboss405GA-installer.home}"/>
</antcall>
Modified: trunk/tests/src/org/jboss/test/messaging/MessagingTestCase.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/MessagingTestCase.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/tests/src/org/jboss/test/messaging/MessagingTestCase.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -21,6 +21,9 @@
*/
package org.jboss.test.messaging;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
@@ -28,11 +31,15 @@
import javax.jms.MessageConsumer;
import javax.jms.Session;
import javax.jms.Topic;
+import javax.naming.InitialContext;
+import javax.sql.DataSource;
+import javax.transaction.TransactionManager;
import junit.framework.TestCase;
import org.jboss.logging.Logger;
import org.jboss.test.messaging.tools.ServerManagement;
+import org.jboss.tm.TransactionManagerService;
/**
* The base case for messaging tests.
@@ -40,6 +47,8 @@
* @author <a href="mailto:adrian at jboss.org">Adrian Brock</a>
* @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
* @author <a href="mailto:tim.fox at jboss.org">Tim Fox</a>
+ * @author <a href="mailto:juha at jboss.org">Juha Lindfors</a>
+ *
* @version <tt>$Revision$</tt>
* $Id$
*/
@@ -47,6 +56,11 @@
{
// Constants -----------------------------------------------------
+ public final static int MAX_TIMEOUT = 1000 * 10 /* seconds */;
+
+ public final static int MIN_TIMEOUT = 1000 * 1 /* seconds */;
+
+
// Static --------------------------------------------------------
// Attributes ----------------------------------------------------
@@ -144,8 +158,118 @@
if (conn!= null) conn.close();
}
}
+
+ protected boolean checkNoBindingData() throws Exception
+ {
+ InitialContext ctx = new InitialContext();
+ TransactionManager mgr = (TransactionManager)ctx.lookup(TransactionManagerService.JNDI_NAME);
+ DataSource ds = (DataSource)ctx.lookup("java:/DefaultDS");
+
+ javax.transaction.Transaction txOld = mgr.suspend();
+ mgr.begin();
+
+ java.sql.Connection conn = null;
+
+ PreparedStatement ps = null;
+
+ ResultSet rs = null;
+ try
+ {
+ conn = ds.getConnection();
+ String sql = "SELECT * FROM JMS_POSTOFFICE";
+ ps = conn.prepareStatement(sql);
+
+ rs = ps.executeQuery();
+
+ return rs.next();
+ }
+ finally
+ {
+ if (rs != null) rs.close();
+
+ if (ps != null) ps.close();
+
+ if (conn != null) conn.close();
+
+ mgr.commit();
+
+ if (txOld != null)
+ {
+ mgr.resume(txOld);
+ }
+
+ }
+ }
+
+ protected boolean checkNoMessageData() throws Exception
+ {
+ //Can't do this remotely
+
+ if (ServerManagement.isRemote())
+ {
+ return false;
+ }
+
+ InitialContext ctx = new InitialContext();
+
+ TransactionManager mgr = (TransactionManager)ctx.lookup(TransactionManagerService.JNDI_NAME);
+ DataSource ds = (DataSource)ctx.lookup("java:/DefaultDS");
+
+ javax.transaction.Transaction txOld = mgr.suspend();
+ mgr.begin();
+
+ java.sql.Connection conn = null;
+
+ PreparedStatement ps = null;
+
+ ResultSet rs = null;
+
+ try
+ {
+ conn = ds.getConnection();
+ String sql = "SELECT * FROM JMS_MESSAGE_REFERENCE";
+ ps = conn.prepareStatement(sql);
+
+ rs = ps.executeQuery();
+
+ boolean exists = rs.next();
+
+ if (!exists)
+ {
+ rs.close();
+
+ ps.close();
+
+ ps = conn.prepareStatement("SELECT * FROM JMS_MESSAGE");
+
+ rs = ps.executeQuery();
+
+ exists = rs.next();
+ }
+
+ return exists;
+ }
+ finally
+ {
+ if (rs != null) rs.close();
+
+ if (ps != null) ps.close();
+
+ if (conn != null) conn.close();
+
+ mgr.commit();
+
+ if (txOld != null)
+ {
+ mgr.resume(txOld);
+ }
+
+ }
+ }
+
+
/**
* @return true if this test is ran in "remote" mode, i.e. the server side of the test runs in a
* different VM than this one (that is running the client side)
Modified: trunk/tests/src/org/jboss/test/messaging/core/SimpleChannel.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/SimpleChannel.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/tests/src/org/jboss/test/messaging/core/SimpleChannel.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -216,11 +216,16 @@
throw new UnsupportedOperationException();
}
- public List createDeliveries(List messageIds)
+ public List recoverDeliveries(List messageIds)
{
throw new UnsupportedOperationException();
}
+ public void addDelivery(Delivery del)
+ {
+ throw new UnsupportedOperationException();
+ }
+
// Package protected ---------------------------------------------
// Protected -----------------------------------------------------
Modified: trunk/tests/src/org/jboss/test/messaging/core/SimpleDeliveryTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/SimpleDeliveryTest.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/tests/src/org/jboss/test/messaging/core/SimpleDeliveryTest.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -26,6 +26,7 @@
import org.jboss.messaging.core.SimpleDelivery;
import org.jboss.messaging.core.plugin.IDManager;
import org.jboss.messaging.core.plugin.JDBCPersistenceManager;
+import org.jboss.messaging.core.plugin.SimpleMessageStore;
import org.jboss.messaging.core.plugin.contract.PersistenceManager;
import org.jboss.messaging.core.tx.Transaction;
import org.jboss.messaging.core.tx.TransactionRepository;
@@ -120,7 +121,7 @@
IDManager idm = new IDManager("TRANSACTION_ID", 10, pm);
idm.start();
- TransactionRepository tr = new TransactionRepository(pm, idm);
+ TransactionRepository tr = new TransactionRepository(pm, new SimpleMessageStore(), idm);
tr.start();
Transaction tx = tr.createTransaction();
Modified: trunk/tests/src/org/jboss/test/messaging/core/local/base/PagingFilteredQueueTestBase.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/local/base/PagingFilteredQueueTestBase.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/tests/src/org/jboss/test/messaging/core/local/base/PagingFilteredQueueTestBase.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -122,11 +122,12 @@
idm = new IDManager("TRANSACTION_ID", 10, pm);
idm.start();
- tr = new TransactionRepository(pm, idm);
+ ms = new SimpleMessageStore();
+ ms.start();
+
+ tr = new TransactionRepository(pm, ms, idm);
tr.start();
- ms = new SimpleMessageStore();
- ms.start();
}
public void tearDown() throws Exception
Modified: trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_NP_2PCTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_NP_2PCTest.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_NP_2PCTest.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -829,6 +829,9 @@
dels[i].cancel();
}
+ //Cancel is asynch, so need to wait a bit
+ Thread.sleep(250);
+
//This should cause the refs corresponding to the deliveries to go the front of the in memory quuee
//and the oldest refs in memory evicted off the end into the down cache
@@ -860,6 +863,9 @@
dels[i].cancel();
}
+// Cancel is asynch, so need to wait a bit
+ Thread.sleep(250);
+
//This should cause the down cache to be flushed
//verify 10 ref in storage
@@ -894,6 +900,9 @@
dels[i].cancel();
}
+ // Cancel is asynch, so need to wait a bit
+ Thread.sleep(250);
+
//This should cause the down cache to be flushed
//verify 20 ref in storage
Modified: trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_NP_NTTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_NP_NTTest.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_NP_NTTest.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -781,6 +781,9 @@
dels[i].cancel();
}
+ // Cancel is asynch, so need to wait a bit
+ Thread.sleep(250);
+
//This should cause the refs corresponding to the deliveries to go the front of the in memory quuee
//and the oldest refs in memory evicted off the end into the down cache
@@ -814,6 +817,9 @@
dels[i].cancel();
}
+ // Cancel is asynch, so need to wait a bit
+ Thread.sleep(250);
+
//This should cause the down cache to be flushed
//verify 10 ref in storage
@@ -847,6 +853,8 @@
{
dels[i].cancel();
}
+ // Cancel is asynch, so need to wait a bit
+ Thread.sleep(250);
//consumeCount += 20;
Modified: trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_NP_TTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_NP_TTest.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_NP_TTest.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -819,6 +819,9 @@
dels[i].cancel();
}
+ // Cancel is asynch, so need to wait a bit
+ Thread.sleep(250);
+
//This should cause the refs corresponding to the deliveries to go the front of the in memory quuee
//and the oldest refs in memory evicted off the end into the down cache
@@ -852,6 +855,9 @@
dels[i].cancel();
}
+ // Cancel is asynch, so need to wait a bit
+ Thread.sleep(250);
+
//This should cause the down cache to be flushed
//verify 10 ref in storage
@@ -887,6 +893,9 @@
}
+ // Cancel is asynch, so need to wait a bit
+ Thread.sleep(250);
+
//This should cause the down cache to be flushed
//verify 20 ref in storage
Modified: trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_P_2PCTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_P_2PCTest.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_P_2PCTest.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -926,6 +926,9 @@
dels[i].cancel();
}
+ // Cancel is asynch, so need to wait a bit
+ Thread.sleep(250);
+
//This should cause the refs corresponding to the deliveries to go the front of the in memory quuee
//and the oldest refs in memory evicted off the end into the down cache
@@ -965,6 +968,9 @@
dels[i].cancel();
}
+ // Cancel is asynch, so need to wait a bit
+ Thread.sleep(250);
+
//This should cause the down cache to be flushed
//verify 10 ref in storage
@@ -1004,6 +1010,9 @@
dels[i].cancel();
}
+ // Cancel is asynch, so need to wait a bit
+ Thread.sleep(250);
+
//consumeCount += 20;
//This should cause the down cache to be flushed
Modified: trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_P_NTTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_P_NTTest.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_P_NTTest.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -880,6 +880,9 @@
dels[i].cancel();
}
+ // Cancel is asynch, so need to wait a bit
+ Thread.sleep(250);
+
//This should cause the refs corresponding to the deliveries to go the front of the in memory quuee
//and the oldest refs in memory evicted off the end into the down cache
@@ -918,6 +921,8 @@
{
dels[i].cancel();
}
+ // Cancel is asynch, so need to wait a bit
+ Thread.sleep(250);
//This should cause the down cache to be flushed
@@ -957,6 +962,9 @@
{
dels[i].cancel();
}
+
+ // Cancel is asynch, so need to wait a bit
+ Thread.sleep(250);
//consumeCount += 20;
Modified: trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_P_TTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_P_TTest.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_P_TTest.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -913,6 +913,9 @@
dels[i].cancel();
}
+ // Cancel is asynch, so need to wait a bit
+ Thread.sleep(250);
+
//This should cause the refs corresponding to the deliveries to go the front of the in memory quuee
//and the oldest refs in memory evicted off the end into the down cache
@@ -952,6 +955,9 @@
dels[i].cancel();
}
+ // Cancel is asynch, so need to wait a bit
+ Thread.sleep(250);
+
//This should cause the down cache to be flushed
//verify 10 ref in storage
@@ -991,6 +997,9 @@
dels[i].cancel();
}
+ // Cancel is asynch, so need to wait a bit
+ Thread.sleep(250);
+
//consumeCount += 20;
//This should cause the down cache to be flushed
Modified: trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_ReloadTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_ReloadTest.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/SingleChannel_ReloadTest.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -23,6 +23,7 @@
import java.util.List;
+import org.jboss.messaging.core.ChannelSupport;
import org.jboss.messaging.core.Message;
import org.jboss.messaging.core.MessageReference;
import org.jboss.messaging.core.local.PagingFilteredQueue;
@@ -40,6 +41,8 @@
* A PagingTest_Reload.
*
* @author <a href="tim.fox at jboss.com">Tim Fox</a>
+ * @author <a href="mailto:juha at jboss.org">Juha Lindfors</a>
+ *
* @version 1.1
*
* SingleChannel_Reload.java,v 1.1 2006/03/22 10:23:35 timfox Exp
@@ -120,14 +123,13 @@
true, true, true, 100);
pm.start();
- tr = new TransactionRepository(pm, idm);
- tr.start();
-
ms = new SimpleMessageStore();
ms.start();
- queue = null;
-
+ tr = new TransactionRepository(pm, ms, idm);
+
+ tr.start();
+
PagingFilteredQueue queue2 = new PagingFilteredQueue("queue1", 1, ms, pm, true, true, new QueuedExecutor(), null, 100, 20, 10);
queue2.deactivate();
queue2.load();
@@ -218,12 +220,12 @@
true, true, true, 100);
pm.start();
- tr = new TransactionRepository(pm, idm);
- tr.start();
-
ms = new SimpleMessageStore();
ms.start();
+ tr = new TransactionRepository(pm, ms, idm);
+ tr.start();
+
PagingFilteredQueue queue2 = new PagingFilteredQueue("queue1", 1, ms, pm, true, true, new QueuedExecutor(), null, 100, 20, 10);
queue2.deactivate();
queue2.load();
Modified: trunk/tests/src/org/jboss/test/messaging/core/paging/base/PagingStateTestBase.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/paging/base/PagingStateTestBase.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/tests/src/org/jboss/test/messaging/core/paging/base/PagingStateTestBase.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -103,11 +103,11 @@
idm = new IDManager("TRANSACTION_ID", 10, pm);
idm.start();
- tr = new TransactionRepository(pm, idm);
- tr.start();
-
ms = new SimpleMessageStore();
ms.start();
+
+ tr = new TransactionRepository(pm, ms, idm);
+ tr.start();
}
Modified: trunk/tests/src/org/jboss/test/messaging/core/plugin/JDBCPersistenceManagerTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/plugin/JDBCPersistenceManagerTest.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/JDBCPersistenceManagerTest.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -1163,7 +1163,7 @@
IDManager idm = new IDManager("TRANSACTION_ID", 10, pm);
idm.start();
- TransactionRepository txRep = new TransactionRepository(pm, idm);
+ TransactionRepository txRep = new TransactionRepository(pm, ms, idm);
txRep.start();
log.debug("transaction log started");
@@ -1274,7 +1274,7 @@
IDManager idm = new IDManager("TRANSACTION_ID", 10, pm);
idm.start();
- TransactionRepository txRep = new TransactionRepository(pm, idm);
+ TransactionRepository txRep = new TransactionRepository(pm, ms, idm);
txRep.start();
Message[] messages = createMessages(10);
Modified: trunk/tests/src/org/jboss/test/messaging/core/plugin/base/PostOfficeTestBase.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/plugin/base/PostOfficeTestBase.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/base/PostOfficeTestBase.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -21,16 +21,9 @@
*/
package org.jboss.test.messaging.core.plugin.base;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
-import javax.naming.InitialContext;
-import javax.sql.DataSource;
-import javax.transaction.TransactionManager;
-
import org.jboss.jms.server.QueuedExecutorPool;
import org.jboss.messaging.core.FilterFactory;
import org.jboss.messaging.core.Message;
@@ -54,7 +47,6 @@
import org.jboss.test.messaging.tools.ServerManagement;
import org.jboss.test.messaging.tools.jmx.ServiceContainer;
import org.jboss.test.messaging.util.CoreMessageFactory;
-import org.jboss.tm.TransactionManagerService;
/**
*
@@ -116,12 +108,12 @@
transactionIDManager = new IDManager("TRANSACTION_ID", 10, pm);
transactionIDManager.start();
- tr = new TransactionRepository(pm, transactionIDManager);
- tr.start();
-
ms = new SimpleMessageStore();
ms.start();
+ tr = new TransactionRepository(pm, ms, transactionIDManager);
+ tr.start();
+
pool = new QueuedExecutorPool(10);
channelIDManager = new IDManager("CHANNEL_ID", 10, pm);
@@ -165,108 +157,7 @@
return postOffice;
}
- protected boolean checkNoBindingData() throws Exception
- {
- InitialContext ctx = new InitialContext();
-
- TransactionManager mgr = (TransactionManager)ctx.lookup(TransactionManagerService.JNDI_NAME);
- DataSource ds = (DataSource)ctx.lookup("java:/DefaultDS");
-
- javax.transaction.Transaction txOld = mgr.suspend();
- mgr.begin();
-
- Connection conn = null;
-
- PreparedStatement ps = null;
-
- ResultSet rs = null;
-
- try
- {
- conn = ds.getConnection();
- String sql = "SELECT * FROM JMS_POSTOFFICE";
- ps = conn.prepareStatement(sql);
-
- rs = ps.executeQuery();
-
- return rs.next();
- }
- finally
- {
- if (rs != null) rs.close();
-
- if (ps != null) ps.close();
-
- if (conn != null) conn.close();
-
- mgr.commit();
-
- if (txOld != null)
- {
- mgr.resume(txOld);
- }
-
- }
- }
- protected boolean checkNoMessageData() throws Exception
- {
- InitialContext ctx = new InitialContext();
-
- TransactionManager mgr = (TransactionManager)ctx.lookup(TransactionManagerService.JNDI_NAME);
- DataSource ds = (DataSource)ctx.lookup("java:/DefaultDS");
-
- javax.transaction.Transaction txOld = mgr.suspend();
- mgr.begin();
-
- Connection conn = null;
-
- PreparedStatement ps = null;
-
- ResultSet rs = null;
-
- try
- {
- conn = ds.getConnection();
- String sql = "SELECT * FROM JMS_MESSAGE_REFERENCE";
- ps = conn.prepareStatement(sql);
-
- rs = ps.executeQuery();
-
- boolean exists = rs.next();
-
- if (!exists)
- {
- rs.close();
-
- ps.close();
-
- ps = conn.prepareStatement("SELECT * FROM JMS_MESSAGE");
-
- rs = ps.executeQuery();
-
- exists = rs.next();
- }
-
- return exists;
- }
- finally
- {
- if (rs != null) rs.close();
-
- if (ps != null) ps.close();
-
- if (conn != null) conn.close();
-
- mgr.commit();
-
- if (txOld != null)
- {
- mgr.resume(txOld);
- }
-
- }
- }
private static long msgCount;
Modified: trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/DefaultPostOfficeTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/DefaultPostOfficeTest.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/DefaultPostOfficeTest.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -1078,7 +1078,7 @@
if (checkNoMessageData())
{
fail("data still in database");
- };
+ }
}
}
Modified: trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/DefaultMessagePullPolicyTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/DefaultMessagePullPolicyTest.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/DefaultMessagePullPolicyTest.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -370,11 +370,17 @@
return false;
}
- public List createDeliveries(List messageIds)
+ public List recoverDeliveries(List messageIds)
{
// TODO Auto-generated method stub
return null;
}
+
+ public void addDelivery(Delivery del)
+ {
+ // TODO Auto-generated method stub
+
+ }
}
Modified: trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/DefaultRouterTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/DefaultRouterTest.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/DefaultRouterTest.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -610,11 +610,17 @@
return false;
}
- public List createDeliveries(List messageIds)
+ public List recoverDeliveries(List messageIds)
{
// TODO Auto-generated method stub
return null;
}
+
+ public void addDelivery(Delivery del)
+ {
+ // TODO Auto-generated method stub
+
+ }
}
Modified: trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/RedistributionWithDefaultMessagePullPolicyTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/RedistributionWithDefaultMessagePullPolicyTest.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/tests/src/org/jboss/test/messaging/core/plugin/postoffice/cluster/RedistributionWithDefaultMessagePullPolicyTest.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -638,7 +638,10 @@
assertTrue(office4.getHoldingTransactions().isEmpty());
assertTrue(office5.getHoldingTransactions().isEmpty());
- checkNoMessageData();
+ if (checkNoMessageData())
+ {
+ fail("Message data still in database");
+ }
}
finally
{
@@ -982,7 +985,10 @@
assertTrue(office4.getHoldingTransactions().isEmpty());
assertTrue(office5.getHoldingTransactions().isEmpty());
- checkNoMessageData();
+ if (checkNoMessageData())
+ {
+ fail("Message data still in database");
+ }
}
finally
{
Modified: trunk/tests/src/org/jboss/test/messaging/jms/ConnectionTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/ConnectionTest.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/tests/src/org/jboss/test/messaging/jms/ConnectionTest.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -44,6 +44,8 @@
import org.jboss.jms.message.MessageIdGenerator;
import org.jboss.jms.message.MessageIdGeneratorFactory;
import org.jboss.jms.server.ServerPeer;
+import org.jboss.jms.tx.ResourceManager;
+import org.jboss.jms.tx.ResourceManagerFactory;
import org.jboss.logging.Logger;
import org.jboss.remoting.InvocationRequest;
import org.jboss.remoting.ServerInvocationHandler;
@@ -112,6 +114,88 @@
// Public --------------------------------------------------------
+ public void testResourceManagersForSameServer() throws Exception
+ {
+ Connection conn1 = cf.createConnection();
+
+ ClientConnectionDelegate del1 = (ClientConnectionDelegate)((JBossConnection)conn1).getDelegate();
+
+ ConnectionState state1 = (ConnectionState)del1.getState();
+
+ ResourceManager rm1 = state1.getResourceManager();
+
+ Connection conn2 = cf.createConnection();
+
+ ClientConnectionDelegate del2 = (ClientConnectionDelegate)((JBossConnection)conn2).getDelegate();
+
+ ConnectionState state2 = (ConnectionState)del2.getState();
+
+ ResourceManager rm2 = state2.getResourceManager();
+
+ //Two connections for same server should share the same resource manager
+
+ assertTrue(rm1 == rm2);
+
+ assertTrue(ResourceManagerFactory.instance.containsResourceManager(state2.getServerID()));
+
+ conn1.close();
+
+ //Check reference counting
+ assertTrue(ResourceManagerFactory.instance.containsResourceManager(state2.getServerID()));
+
+ conn2.close();
+
+ assertFalse(ResourceManagerFactory.instance.containsResourceManager(state2.getServerID()));
+
+ assertEquals(0, ResourceManagerFactory.instance.size());
+ }
+
+ public void testResourceManagerFactory()
+ {
+ ResourceManager rm1 = ResourceManagerFactory.instance.checkOutResourceManager(1);
+
+ ResourceManager rm2 = ResourceManagerFactory.instance.checkOutResourceManager(2);
+
+ ResourceManager rm3 = ResourceManagerFactory.instance.checkOutResourceManager(3);
+
+ ResourceManager rm4 = ResourceManagerFactory.instance.checkOutResourceManager(4);
+
+ assertEquals(4, ResourceManagerFactory.instance.size());
+
+ ResourceManager rm4_2 = ResourceManagerFactory.instance.checkOutResourceManager(4);
+
+ assertEquals(4, ResourceManagerFactory.instance.size());
+
+ ResourceManager rm4_3 = ResourceManagerFactory.instance.checkOutResourceManager(4);
+
+ assertEquals(4, ResourceManagerFactory.instance.size());
+
+ ResourceManagerFactory.instance.checkInResourceManager(4);
+
+ assertEquals(4, ResourceManagerFactory.instance.size());
+
+ ResourceManagerFactory.instance.checkInResourceManager(4);
+
+ assertEquals(4, ResourceManagerFactory.instance.size());
+
+ ResourceManagerFactory.instance.checkInResourceManager(4);
+
+ assertEquals(3, ResourceManagerFactory.instance.size());
+
+ ResourceManagerFactory.instance.checkInResourceManager(3);
+
+ assertEquals(2, ResourceManagerFactory.instance.size());
+
+ ResourceManagerFactory.instance.checkInResourceManager(2);
+
+ assertEquals(1, ResourceManagerFactory.instance.size());
+
+ ResourceManagerFactory.instance.checkInResourceManager(1);
+
+ assertEquals(0, ResourceManagerFactory.instance.size());
+
+ }
+
public void testManyConnections() throws Exception
{
for (int i = 0; i < 1000; i++)
Modified: trunk/tests/src/org/jboss/test/messaging/jms/JMSTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/JMSTest.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/tests/src/org/jboss/test/messaging/jms/JMSTest.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -199,6 +199,45 @@
conn.close();
}
+ public void test_Persistent_Transactional_Send() throws Exception
+ {
+ ConnectionFactory cf = (ConnectionFactory)ic.lookup("/ConnectionFactory");
+
+ Queue queue = (Queue)ic.lookup("/queue/JMSTestQueue");
+
+ Connection conn = cf.createConnection();
+
+ Session session = conn.createSession(true, Session.SESSION_TRANSACTED);
+
+ MessageProducer prod = session.createProducer(queue);
+ prod.setDeliveryMode(DeliveryMode.PERSISTENT);
+
+ TextMessage m = session.createTextMessage("message one");
+ prod.send(m);
+ m = session.createTextMessage("message two");
+ prod.send(m);
+
+ session.commit();
+
+ conn.close();
+
+ conn = cf.createConnection();
+
+ session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageConsumer cons = session.createConsumer(queue);
+
+ conn.start();
+
+ TextMessage rm = (TextMessage)cons.receive();
+ assertEquals("message one", rm.getText());
+ rm = (TextMessage)cons.receive();
+ assertEquals("message two", rm.getText());
+
+ conn.close();
+ }
+
+
public void test_NonPersistent_Transactional_Acknowledgment() throws Exception
{
ConnectionFactory cf = (ConnectionFactory)ic.lookup("/ConnectionFactory");
@@ -232,7 +271,6 @@
conn.close();
}
-
public void test_Asynchronous_to_Client() throws Exception
{
ConnectionFactory cf = (ConnectionFactory)ic.lookup("/ConnectionFactory");
Modified: trunk/tests/src/org/jboss/test/messaging/jms/ManifestTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/ManifestTest.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/tests/src/org/jboss/test/messaging/jms/ManifestTest.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -22,6 +22,7 @@
package org.jboss.test.messaging.jms;
import java.io.File;
+import java.util.Iterator;
import java.util.Properties;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
@@ -89,7 +90,7 @@
// Compare the value from ConnectionMetaData and MANIFEST.MF
Attributes attrs = manifest.getMainAttributes();
- /*
+
System.out.println("META--> " + meta.getJMSMajorVersion());
System.out.println("META--> " + meta.getJMSMinorVersion());
System.out.println("META--> " + meta.getJMSProviderName());
@@ -103,7 +104,7 @@
Object item = itr.next();
System.out.println("MANIFEST--> " + item + " : " + attrs.get(item));
}
- */
+
assertEquals(attrs.getValue("Implementation-Title"), meta.getJMSProviderName());
String ver = attrs.getValue("Implementation-Version");
assertTrue(-1 != ver.indexOf(meta.getProviderVersion()));
Modified: trunk/tests/src/org/jboss/test/messaging/jms/MessageConsumerTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/MessageConsumerTest.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/tests/src/org/jboss/test/messaging/jms/MessageConsumerTest.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -21,17 +21,38 @@
*/
package org.jboss.test.messaging.jms;
-import EDU.oswego.cs.dl.util.concurrent.Latch;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
-import javax.jms.*;
+
+import javax.jms.BytesMessage;
+import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
+import javax.jms.DeliveryMode;
+import javax.jms.InvalidDestinationException;
+import javax.jms.JMSException;
+import javax.jms.MapMessage;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageListener;
+import javax.jms.MessageProducer;
+import javax.jms.ObjectMessage;
+import javax.jms.Queue;
+import javax.jms.QueueReceiver;
+import javax.jms.Session;
+import javax.jms.StreamMessage;
+import javax.jms.TextMessage;
+import javax.jms.Topic;
+import javax.jms.TopicSubscriber;
import javax.naming.InitialContext;
+
import org.jboss.jms.destination.JBossTopic;
import org.jboss.test.messaging.MessagingTestCase;
import org.jboss.test.messaging.tools.ServerManagement;
+import EDU.oswego.cs.dl.util.concurrent.Latch;
+
/**
* @author <a href="mailto:ovidiu at jboss.org">Ovidiu Feodorov</a>
* @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
@@ -886,6 +907,9 @@
cons1.close();
+ //Cancelling is asynch so can take some time
+ Thread.sleep(500);
+
//rollback should cause redelivery of messages
//in this case redelivery occurs to a different receiver
@@ -1000,6 +1024,9 @@
assertEquals("hello1", rm1.getText());
cons1.close();
+
+ //Give time for asynch cancel to happen
+ Thread.sleep(500);
log.debug("sess.recover()");
Modified: trunk/tests/src/org/jboss/test/messaging/jms/XARecoveryTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/XARecoveryTest.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/tests/src/org/jboss/test/messaging/jms/XARecoveryTest.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -21,18 +21,36 @@
*/
package org.jboss.test.messaging.jms;
+import javax.jms.Connection;
import javax.jms.Destination;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.MessageProducer;
+import javax.jms.Session;
+import javax.jms.TextMessage;
+import javax.jms.Topic;
+import javax.jms.XAConnection;
+import javax.jms.XASession;
import javax.naming.InitialContext;
+import javax.transaction.TransactionManager;
+import javax.transaction.xa.XAResource;
+import javax.transaction.xa.Xid;
import org.jboss.jms.client.JBossConnectionFactory;
+import org.jboss.messaging.core.tx.XidImpl;
import org.jboss.test.messaging.MessagingTestCase;
import org.jboss.test.messaging.tools.ServerManagement;
+import org.jboss.tm.TransactionManagerLocator;
+import com.arjuna.ats.arjuna.common.Uid;
+import com.arjuna.ats.jta.xa.XidImple;
+
/**
*
* A XARecoveryTest
-
+ *
* @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @author <a href="mailto:juha at jboss.org">Juha Lindfors</a>
* @version <tt>$Revision: 1.1 $</tt>
*
* $Id$
@@ -49,8 +67,10 @@
protected InitialContext initialContext;
protected JBossConnectionFactory cf;
- protected Destination queue;
+ protected Destination queue, queueA, queueB, queueTX, topicTX;
+ TransactionManager tm;
+
// Constructors --------------------------------------------------
public XARecoveryTest(String name)
@@ -63,139 +83,3252 @@
public void setUp() throws Exception
{
super.setUp();
- ServerManagement.start("all");
+ ServerManagement.start("all");
-
initialContext = new InitialContext(ServerManagement.getJNDIEnvironment());
cf = (JBossConnectionFactory)initialContext.lookup("/ConnectionFactory");
- //if (!ServerManagement.isRemote()) tm = TransactionManagerLocator.getInstance().locate();
+ if (!ServerManagement.isRemote()) tm = TransactionManagerLocator.getInstance().locate();
ServerManagement.undeployQueue("Queue");
ServerManagement.deployQueue("Queue");
- queue = (Destination)initialContext.lookup("/queue/Queue");
+ ServerManagement.undeployQueue("QA");
+ ServerManagement.deployQueue("QA");
+
+ ServerManagement.undeployQueue("QB");
+ ServerManagement.deployQueue("QB");
+
+ ServerManagement.undeployQueue("TXQ");
+ ServerManagement.deployQueue("TXQ");
+
+ ServerManagement.undeployTopic("TXTOPIC");
+ ServerManagement.deployTopic("TXTOPIC");
+
+ queue = (Destination)initialContext.lookup("/queue/Queue");
+ queueA = (Destination)initialContext.lookup("/queue/QA");
+ queueB = (Destination)initialContext.lookup("/queue/QB");
+ queueTX = (Destination)initialContext.lookup("/queue/TXQ");
+
+ topicTX = (Destination)initialContext.lookup("/topic/TXTOPIC");
+
+ drainDestination(cf, queue);
+ drainDestination(cf, queueA);
+ drainDestination(cf, queueB);
+ drainDestination(cf, queueTX);
}
public void tearDown() throws Exception
{
ServerManagement.undeployQueue("Queue");
+ ServerManagement.undeployQueue("QA");
+ ServerManagement.undeployQueue("QB");
+ ServerManagement.undeployQueue("TXQ");
+ ServerManagement.undeployTopic("TXTOPIC");
+
super.tearDown();
}
// Public --------------------------------------------------------
- //TODO Re-enable when we complete XA Recovery
+ /*
+ * In this test, we have two queues, each with four messages already in them.
+ *
+ * We send 4 more messages to each queue, and ack the original 4 in a tx
+ *
+ * Then recover it without restarting the server
+ *
+ */
+ public void testComplexTransactionalRecoveryWithoutRestart() throws Exception
+ {
+ Connection conn1 = null;
+
+ XAConnection conn2 = null;
+
+ XAConnection conn3 = null;
+
+ try
+ {
+ conn1 = cf.createConnection();
+
+ Session sess1 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageProducer prod1 = sess1.createProducer(queueA);
+
+ MessageProducer prod2 = sess1.createProducer(queueB);
+
+ TextMessage tm1 = sess1.createTextMessage("tm1");
+ TextMessage tm2 = sess1.createTextMessage("tm2");
+ TextMessage tm3 = sess1.createTextMessage("tm3");
+ TextMessage tm4 = sess1.createTextMessage("tm4");
+ TextMessage tm5 = sess1.createTextMessage("tm5");
+ TextMessage tm6 = sess1.createTextMessage("tm6");
+ TextMessage tm7 = sess1.createTextMessage("tm7");
+ TextMessage tm8 = sess1.createTextMessage("tm8");
+
+ prod1.send(tm1);
+ prod1.send(tm2);
+ prod1.send(tm3);
+ prod1.send(tm4);
+
+ prod2.send(tm5);
+ prod2.send(tm6);
+ prod2.send(tm7);
+ prod2.send(tm8);
+
+ conn1.close();
+
+ conn2 = cf.createXAConnection();
+
+ conn2.start();
+
+ XASession sess2 = conn2.createXASession();
+
+ XAResource res = sess2.getXAResource();
+
+ Xid xid1 = new XidImpl("bq1".getBytes(), 42, "eemeli".getBytes());
+
+ res.start(xid1, XAResource.TMNOFLAGS);
+
+ MessageProducer prod3 = sess2.createProducer(queueA);
+
+ TextMessage tm9 = sess2.createTextMessage("tm9");
+ TextMessage tm10 = sess2.createTextMessage("tm10");
+ TextMessage tm11 = sess2.createTextMessage("tm11");
+ TextMessage tm12 = sess2.createTextMessage("tm12");
+
+ prod3.send(tm9);
+ prod3.send(tm10);
+ prod3.send(tm11);
+ prod3.send(tm12);
+
+ MessageProducer prod4 = sess2.createProducer(queueB);
+
+ TextMessage tm13 = sess2.createTextMessage("tm13");
+ TextMessage tm14 = sess2.createTextMessage("tm14");
+ TextMessage tm15 = sess2.createTextMessage("tm15");
+ TextMessage tm16 = sess2.createTextMessage("tm16");
+
+ prod4.send(tm13);
+ prod4.send(tm14);
+ prod4.send(tm15);
+ prod4.send(tm16);
+
+ MessageConsumer cons1 = sess2.createConsumer(queueA);
+
+ TextMessage rm1 = (TextMessage)cons1.receive(1000);
+ assertNotNull(rm1);
+ assertEquals(tm1.getText(), rm1.getText());
+
+ TextMessage rm2 = (TextMessage)cons1.receive(1000);
+ assertNotNull(rm2);
+ assertEquals(tm2.getText(), rm2.getText());
+
+ TextMessage rm3 = (TextMessage)cons1.receive(1000);
+ assertNotNull(rm3);
+ assertEquals(tm3.getText(), rm3.getText());
+
+ TextMessage rm4 = (TextMessage)cons1.receive(1000);
+ assertNotNull(rm4);
+ assertEquals(tm4.getText(), rm4.getText());
+
+ Message m = cons1.receive(1000);
+
+ assertNull(m);
+
+ MessageConsumer cons2 = sess2.createConsumer(queueB);
+
+ TextMessage rm5 = (TextMessage)cons2.receive(1000);
+ assertNotNull(rm5);
+ assertEquals(tm5.getText(), rm5.getText());
+
+ TextMessage rm6 = (TextMessage)cons2.receive(1000);
+ assertNotNull(rm6);
+ assertEquals(tm6.getText(), rm6.getText());
+
+ TextMessage rm7 = (TextMessage)cons2.receive(1000);
+ assertNotNull(rm7);
+ assertEquals(tm7.getText(), rm7.getText());
+
+ TextMessage rm8 = (TextMessage)cons2.receive(1000);
+ assertNotNull(rm8);
+ assertEquals(tm8.getText(), rm8.getText());
+
+ m = cons2.receive(1000);
+
+ assertNull(m);
+
+ res.end(xid1, XAResource.TMSUCCESS);
+
+ //prepare it
+
+ log.trace("Preparing xid " + xid1);
+ res.prepare(xid1);
+ log.trace("Prepared xid " + xid1);
+
+ conn3 = cf.createXAConnection();
+
+ XASession sess3 = conn3.createXASession();
+
+ XAResource res3 = sess3.getXAResource();
+
+ Xid[] xids = res3.recover(XAResource.TMSTARTRSCAN);
+ assertEquals(1, xids.length);
+
+ Xid[] xids2 = res3.recover(XAResource.TMENDRSCAN);
+ assertEquals(0, xids2.length);
+
+ assertEquals(xid1, xids[0]);
+
+ log.trace("Committing the tx");
+
+ //Commit
+ res3.commit(xids[0], false);
+
+ log.trace("committed the tx");
+
+ conn1.close();
+
+ conn2.close();
+
+ conn1 = cf.createConnection();
+
+ conn1.start();
+
+ sess1 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ log.trace("creating a consumer");
+
+ cons1 = sess1.createConsumer(queueA);
+
+ log.trace("created a consumer");
+
+ TextMessage rm9 = (TextMessage)cons1.receive(1000);
+ assertNotNull(rm9);
+ assertEquals(tm9.getText(), rm9.getText());
+
+ TextMessage rm10 = (TextMessage)cons1.receive(1000);
+ assertNotNull(rm10);
+ assertEquals(tm10.getText(), rm10.getText());
+
+ TextMessage rm11 = (TextMessage)cons1.receive(1000);
+ assertNotNull(rm11);
+ assertEquals(tm11.getText(), rm11.getText());
+
+ TextMessage rm12 = (TextMessage)cons1.receive(1000);
+ assertNotNull(rm12);
+ assertEquals(tm12.getText(), rm12.getText());
+
+ m = cons1.receive(1000);
+
+ assertNull(m);
+
+ cons2 = sess1.createConsumer(queueB);
+
+ TextMessage rm13 = (TextMessage)cons2.receive(1000);
+ assertNotNull(rm13);
+ assertEquals(tm13.getText(), rm13.getText());
+
+ TextMessage rm14 = (TextMessage)cons2.receive(1000);
+ assertNotNull(rm14);
+ assertEquals(tm14.getText(), rm14.getText());
+
+ TextMessage rm15 = (TextMessage)cons2.receive(1000);
+ assertNotNull(rm15);
+ assertEquals(tm15.getText(), rm15.getText());
+
+ TextMessage rm16 = (TextMessage)cons2.receive(1000);
+ assertNotNull(rm16);
+ assertEquals(tm16.getText(), rm16.getText());
+
+ m = cons2.receive(1000);
+
+ assertNull(m);
+
+ if (checkNoMessageData())
+ {
+ fail("Data remains in database");
+ }
+
+ }
+ finally
+ {
+ if (conn1 != null)
+ {
+ conn1.close();
+ }
+
+ if (conn2 != null)
+ {
+ conn2.close();
+ }
+
+ if (conn3 != null)
+ {
+ conn3.close();
+ }
+ }
+ }
- public void testNoop()
+ /*
+ * In this test, we have two queues, each with four messages already in them.
+ *
+ * We send 4 more messages to each queue, and ack the original 4 in a tx
+ *
+ * Then recover it without restarting the server, then rollback
+ *
+ */
+ public void testComplexTransactionalRecoveryWithoutRestartRollback() throws Exception
{
+ Connection conn1 = null;
+ XAConnection conn2 = null;
+
+ XAConnection conn3 = null;
+
+ try
+ {
+ conn1 = cf.createConnection();
+
+ Session sess1 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageProducer prod1 = sess1.createProducer(queueA);
+
+ MessageProducer prod2 = sess1.createProducer(queueB);
+
+ TextMessage tm1 = sess1.createTextMessage("tm1");
+ TextMessage tm2 = sess1.createTextMessage("tm2");
+ TextMessage tm3 = sess1.createTextMessage("tm3");
+ TextMessage tm4 = sess1.createTextMessage("tm4");
+ TextMessage tm5 = sess1.createTextMessage("tm5");
+ TextMessage tm6 = sess1.createTextMessage("tm6");
+ TextMessage tm7 = sess1.createTextMessage("tm7");
+ TextMessage tm8 = sess1.createTextMessage("tm8");
+
+ prod1.send(tm1);
+ prod1.send(tm2);
+ prod1.send(tm3);
+ prod1.send(tm4);
+
+ prod2.send(tm5);
+ prod2.send(tm6);
+ prod2.send(tm7);
+ prod2.send(tm8);
+
+ conn2 = cf.createXAConnection();
+
+ conn2.start();
+
+ XASession sess2 = conn2.createXASession();
+
+ XAResource res = sess2.getXAResource();
+
+ Xid xid1 = new XidImpl("bq1".getBytes(), 42, "eemeli".getBytes());
+
+ res.start(xid1, XAResource.TMNOFLAGS);
+
+ MessageProducer prod3 = sess2.createProducer(queueA);
+
+ TextMessage tm9 = sess2.createTextMessage("tm9");
+ TextMessage tm10 = sess2.createTextMessage("tm10");
+ TextMessage tm11 = sess2.createTextMessage("tm11");
+ TextMessage tm12 = sess2.createTextMessage("tm12");
+
+ prod3.send(tm9);
+ prod3.send(tm10);
+ prod3.send(tm11);
+ prod3.send(tm12);
+
+ MessageProducer prod4 = sess2.createProducer(queueB);
+
+ TextMessage tm13 = sess2.createTextMessage("tm13");
+ TextMessage tm14 = sess2.createTextMessage("tm14");
+ TextMessage tm15 = sess2.createTextMessage("tm15");
+ TextMessage tm16 = sess2.createTextMessage("tm16");
+
+ prod4.send(tm13);
+ prod4.send(tm14);
+ prod4.send(tm15);
+ prod4.send(tm16);
+
+ MessageConsumer cons1 = sess2.createConsumer(queueA);
+
+ TextMessage rm1 = (TextMessage)cons1.receive(1000);
+ assertNotNull(rm1);
+ assertEquals(tm1.getText(), rm1.getText());
+
+ TextMessage rm2 = (TextMessage)cons1.receive(1000);
+ assertNotNull(rm2);
+ assertEquals(tm2.getText(), rm2.getText());
+
+ TextMessage rm3 = (TextMessage)cons1.receive(1000);
+ assertNotNull(rm3);
+ assertEquals(tm3.getText(), rm3.getText());
+
+ TextMessage rm4 = (TextMessage)cons1.receive(1000);
+ assertNotNull(rm4);
+ assertEquals(tm4.getText(), rm4.getText());
+
+ Message m = cons1.receive(1000);
+
+ assertNull(m);
+
+ MessageConsumer cons2 = sess2.createConsumer(queueB);
+
+ TextMessage rm5 = (TextMessage)cons2.receive(1000);
+ assertNotNull(rm5);
+ assertEquals(tm5.getText(), rm5.getText());
+
+ TextMessage rm6 = (TextMessage)cons2.receive(1000);
+ assertNotNull(rm6);
+ assertEquals(tm6.getText(), rm6.getText());
+
+ TextMessage rm7 = (TextMessage)cons2.receive(1000);
+ assertNotNull(rm7);
+ assertEquals(tm7.getText(), rm7.getText());
+
+ TextMessage rm8 = (TextMessage)cons2.receive(1000);
+ assertNotNull(rm8);
+ assertEquals(tm8.getText(), rm8.getText());
+
+ m = cons2.receive(1000);
+
+ assertNull(m);
+
+ res.end(xid1, XAResource.TMSUCCESS);
+
+ //prepare it
+
+ res.prepare(xid1);
+
+ conn3 = cf.createXAConnection();
+
+ XASession sess3 = conn3.createXASession();
+
+ XAResource res3 = sess3.getXAResource();
+
+ Xid[] xids = res3.recover(XAResource.TMSTARTRSCAN);
+ assertEquals(1, xids.length);
+
+ Xid[] xids2 = res3.recover(XAResource.TMENDRSCAN);
+ assertEquals(0, xids2.length);
+
+ assertEquals(xid1, xids[0]);
+
+ log.trace("rolling back the tx");
+
+ //rollback
+ res3.rollback(xids[0]);
+
+ log.trace("rolledb back the tx");
+
+ Thread.sleep(1000);
+
+ conn1.close();
+
+ conn2.close();
+
+
+ conn1 = cf.createConnection();
+
+ conn1.start();
+
+ sess1 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ log.trace("creating a consumer");
+
+ cons1 = sess1.createConsumer(queueA);
+
+ log.trace("created a consumer");
+
+ TextMessage rm9 = (TextMessage)cons1.receive(1000);
+ assertNotNull(rm9);
+ assertEquals(tm1.getText(), rm9.getText());
+
+ TextMessage rm10 = (TextMessage)cons1.receive(1000);
+ assertNotNull(rm10);
+ assertEquals(tm2.getText(), rm10.getText());
+
+ TextMessage rm11 = (TextMessage)cons1.receive(1000);
+ assertNotNull(rm11);
+ assertEquals(tm3.getText(), rm11.getText());
+
+ TextMessage rm12 = (TextMessage)cons1.receive(1000);
+ assertNotNull(rm12);
+ assertEquals(tm4.getText(), rm12.getText());
+
+ m = cons1.receive(1000);
+
+ assertNull(m);
+
+ cons2 = sess1.createConsumer(queueB);
+
+ TextMessage rm13 = (TextMessage)cons2.receive(1000);
+ assertNotNull(rm13);
+ assertEquals(tm5.getText(), rm13.getText());
+
+ TextMessage rm14 = (TextMessage)cons2.receive(1000);
+ assertNotNull(rm14);
+ assertEquals(tm6.getText(), rm14.getText());
+
+ TextMessage rm15 = (TextMessage)cons2.receive(1000);
+ assertNotNull(rm15);
+ assertEquals(tm7.getText(), rm15.getText());
+
+ TextMessage rm16 = (TextMessage)cons2.receive(1000);
+ assertNotNull(rm16);
+ assertEquals(tm8.getText(), rm16.getText());
+
+ m = cons2.receive(1000);
+
+ assertNull(m);
+
+ if (checkNoMessageData())
+ {
+ fail("Data remains in database");
+ }
+
+ }
+ finally
+ {
+ if (conn1 != null)
+ {
+ try
+ {
+ conn1.close();
+ }
+ catch (Exception e)
+ {
+ //Ignore
+ }
+ }
+
+ if (conn2 != null)
+ {
+ try
+ {
+ conn2.close();
+ }
+ catch (Exception e)
+ {
+ //Ignore
+ }
+ }
+
+ if (conn3 != null)
+ {
+ try
+ {
+ conn3.close();
+ }
+ catch (Exception e)
+ {
+ //Ignore
+ }
+ }
+ }
}
-//
-// public void test1() throws Exception
-// {
-//
-// XAConnection conn1 = cf.createXAConnection();
-//
-// XAConnection conn2 = cf.createXAConnection();
-//
-// XASession sess1 = conn1.createXASession();
-//
-// XASession sess2 = conn2.createXASession();
-//
-// XAResource res1 = sess1.getXAResource();
-//
-// XAResource res2 = sess2.getXAResource();
-//
-// //Pretend to be a transaction manager by interacting through the XAResources
-// Xid xid1 = new XidImpl("bq1".getBytes(), 123, "gbtxid1".getBytes());
-// Xid xid2 = new XidImpl("bq2".getBytes(), 124, "gbtxid2".getBytes());
-//
-//
-//// Send a message in each tx
-//
-//
-// res1.start(xid1, XAResource.TMNOFLAGS);
-//
-// MessageProducer prod1 = sess1.createProducer(queue);
-//
-// TextMessage tm1 = sess1.createTextMessage("testing1");
-//
-// prod1.send(tm1);
-//
-// res1.end(xid1, XAResource.TMSUCCESS);
-//
-//
-//
-//
-// res2.start(xid2, XAResource.TMNOFLAGS);
-//
-// MessageProducer prod2 = sess2.createProducer(queue);
-//
-// TextMessage tm2 = sess2.createTextMessage("testing2");
-//
-// prod2.send(tm2);
-//
-// res2.end(xid2, XAResource.TMSUCCESS);
-//
-// //prepare both txs
-//
-//
-// res1.prepare(xid1);
-// res2.prepare(xid2);
-//
-// //Now "crash" the server
-//
-// ServerManagement.stopServerPeer();
-//
-// ServerManagement.startServerPeer();
-//
-// //Now lookup the recoverable in JNDI
-// InitialContext ic = new InitialContext();
-// JMSRecoverable recoverable = (JMSRecoverable)ic.lookup("/" +
-// ServerPeer.RECOVERABLE_CTX_NAME + "/"+ ServerManagement.getServerPeer().getServerPeerID());
-//
-// XAResource res = recoverable.getResource();
-//
-// Xid[] xids = res.recover(XAResource.TMSTARTRSCAN);
-// assertEquals(2, xids.length);
-//
-// Xid[] xids2 = res.recover(XAResource.TMENDRSCAN);
-// assertEquals(0, xids2.length);
-//
-// assertTrue(xids[0].equals(xid1) || xids[1].equals(xid1));
-// assertTrue(xids[0].equals(xid2) || xids[1].equals(xid2));
-//
-// res.commit(xid1, false);
-//
-// res.commit(xid2, false);
-//
-// recoverable.cleanUp();
-//
-// ServerManagement.deployQueue("Queue");
-//
-// Connection conn3 = cf.createConnection();
-//
-// Session sessRec = conn3.createSession(false, Session.AUTO_ACKNOWLEDGE);
-// MessageConsumer cons = sessRec.createConsumer(queue);
-// conn3.start();
-//
-// TextMessage m2 = (TextMessage)cons.receiveNoWait();
-// assertNotNull(m2);
-// assertEquals("testing1", m2.getText());
-//
-//
-// TextMessage m3 = (TextMessage)cons.receiveNoWait();
-// assertNotNull(m3);
-// assertEquals("testing2", m3.getText());
-//
-// conn3.close();
-//
-// }
-
+ /*
+ * In this test, we have two queues, each with four messages already in them.
+ *
+ * We send 4 more messages to each queue, and ack the original 4 in a tx
+ *
+ * Then recover it after restarting the server
+ *
+ */
+ public void testComplexTransactionalRecoveryWithRestart() throws Exception
+ {
+ Connection conn1 = null;
+
+ XAConnection conn2 = null;
+
+ XAConnection conn3 = null;
+
+ try
+ {
+ conn1 = cf.createConnection();
+
+ Session sess1 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageProducer prod1 = sess1.createProducer(queueA);
+
+ MessageProducer prod2 = sess1.createProducer(queueB);
+
+ TextMessage tm1 = sess1.createTextMessage("tm1");
+ TextMessage tm2 = sess1.createTextMessage("tm2");
+ TextMessage tm3 = sess1.createTextMessage("tm3");
+ TextMessage tm4 = sess1.createTextMessage("tm4");
+ TextMessage tm5 = sess1.createTextMessage("tm5");
+ TextMessage tm6 = sess1.createTextMessage("tm6");
+ TextMessage tm7 = sess1.createTextMessage("tm7");
+ TextMessage tm8 = sess1.createTextMessage("tm8");
+
+ prod1.send(tm1);
+ prod1.send(tm2);
+ prod1.send(tm3);
+ prod1.send(tm4);
+
+ prod2.send(tm5);
+ prod2.send(tm6);
+ prod2.send(tm7);
+ prod2.send(tm8);
+
+ conn2 = cf.createXAConnection();
+
+ conn2.start();
+
+ XASession sess2 = conn2.createXASession();
+
+ XAResource res = sess2.getXAResource();
+
+ Xid xid1 = new XidImpl("bq1".getBytes(), 42, "eemeli".getBytes());
+
+ res.start(xid1, XAResource.TMNOFLAGS);
+
+ MessageProducer prod3 = sess2.createProducer(queueA);
+
+ TextMessage tm9 = sess2.createTextMessage("tm9");
+ TextMessage tm10 = sess2.createTextMessage("tm10");
+ TextMessage tm11 = sess2.createTextMessage("tm11");
+ TextMessage tm12 = sess2.createTextMessage("tm12");
+
+ prod3.send(tm9);
+ prod3.send(tm10);
+ prod3.send(tm11);
+ prod3.send(tm12);
+
+ MessageProducer prod4 = sess2.createProducer(queueB);
+
+ TextMessage tm13 = sess2.createTextMessage("tm13");
+ TextMessage tm14 = sess2.createTextMessage("tm14");
+ TextMessage tm15 = sess2.createTextMessage("tm15");
+ TextMessage tm16 = sess2.createTextMessage("tm16");
+
+ prod4.send(tm13);
+ prod4.send(tm14);
+ prod4.send(tm15);
+ prod4.send(tm16);
+
+ MessageConsumer cons1 = sess2.createConsumer(queueA);
+
+ TextMessage rm1 = (TextMessage)cons1.receive(1000);
+ assertNotNull(rm1);
+ assertEquals(tm1.getText(), rm1.getText());
+
+ TextMessage rm2 = (TextMessage)cons1.receive(1000);
+ assertNotNull(rm2);
+ assertEquals(tm2.getText(), rm2.getText());
+
+ TextMessage rm3 = (TextMessage)cons1.receive(1000);
+ assertNotNull(rm3);
+ assertEquals(tm3.getText(), rm3.getText());
+
+ TextMessage rm4 = (TextMessage)cons1.receive(1000);
+ assertNotNull(rm4);
+ assertEquals(tm4.getText(), rm4.getText());
+
+ Message m = cons1.receive(1000);
+
+ assertNull(m);
+
+ MessageConsumer cons2 = sess2.createConsumer(queueB);
+
+ TextMessage rm5 = (TextMessage)cons2.receive(1000);
+ assertNotNull(rm5);
+ assertEquals(tm5.getText(), rm5.getText());
+
+ TextMessage rm6 = (TextMessage)cons2.receive(1000);
+ assertNotNull(rm6);
+ assertEquals(tm6.getText(), rm6.getText());
+
+ TextMessage rm7 = (TextMessage)cons2.receive(1000);
+ assertNotNull(rm7);
+ assertEquals(tm7.getText(), rm7.getText());
+
+ TextMessage rm8 = (TextMessage)cons2.receive(1000);
+ assertNotNull(rm8);
+ assertEquals(tm8.getText(), rm8.getText());
+
+ m = cons2.receive(1000);
+
+ assertNull(m);
+
+ res.end(xid1, XAResource.TMSUCCESS);
+
+ //prepare it
+
+ res.prepare(xid1);
+
+ conn1 = null;
+
+ conn2 = null;
+
+ // Now "crash" the server
+
+ ServerManagement.stopServerPeer();
+
+ ServerManagement.startServerPeer();
+
+ ServerManagement.deployQueue("QA");
+
+ ServerManagement.deployQueue("QB");
+
+ conn3 = cf.createXAConnection();
+
+ XASession sess3 = conn3.createXASession();
+
+ XAResource res3 = sess3.getXAResource();
+
+ Xid[] xids = res3.recover(XAResource.TMSTARTRSCAN);
+ assertEquals(1, xids.length);
+
+ Xid[] xids2 = res3.recover(XAResource.TMENDRSCAN);
+ assertEquals(0, xids2.length);
+
+ assertEquals(xid1, xids[0]);
+
+ log.trace("Committing the tx");
+
+ //Commit
+ res3.commit(xids[0], false);
+
+ log.trace("committed the tx");
+
+ conn1 = cf.createConnection();
+
+ conn1.start();
+
+ sess1 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ log.trace("creating a consumer");
+
+ cons1 = sess1.createConsumer(queueA);
+
+ log.trace("created a consumer");
+
+ TextMessage rm9 = (TextMessage)cons1.receive(1000);
+ assertNotNull(rm9);
+ assertEquals(tm9.getText(), rm9.getText());
+
+ TextMessage rm10 = (TextMessage)cons1.receive(1000);
+ assertNotNull(rm10);
+ assertEquals(tm10.getText(), rm10.getText());
+
+ TextMessage rm11 = (TextMessage)cons1.receive(1000);
+ assertNotNull(rm11);
+ assertEquals(tm11.getText(), rm11.getText());
+
+ TextMessage rm12 = (TextMessage)cons1.receive(1000);
+ assertNotNull(rm12);
+ assertEquals(tm12.getText(), rm12.getText());
+
+ m = cons1.receive(1000);
+
+ assertNull(m);
+
+ cons2 = sess1.createConsumer(queueB);
+
+ TextMessage rm13 = (TextMessage)cons2.receive(1000);
+ assertNotNull(rm13);
+ assertEquals(tm13.getText(), rm13.getText());
+
+ TextMessage rm14 = (TextMessage)cons2.receive(1000);
+ assertNotNull(rm14);
+ assertEquals(tm14.getText(), rm14.getText());
+
+ TextMessage rm15 = (TextMessage)cons2.receive(1000);
+ assertNotNull(rm15);
+ assertEquals(tm15.getText(), rm15.getText());
+
+ TextMessage rm16 = (TextMessage)cons2.receive(1000);
+ assertNotNull(rm16);
+ assertEquals(tm16.getText(), rm16.getText());
+
+ m = cons2.receive(1000);
+
+ assertNull(m);
+
+ if (checkNoMessageData())
+ {
+ fail("Data remains in database");
+ }
+
+ }
+ finally
+ {
+ if (conn1 != null)
+ {
+ try
+ {
+ conn1.close();
+ }
+ catch (Exception e)
+ {
+ //Ignore
+ }
+ }
+
+ if (conn2 != null)
+ {
+ try
+ {
+ conn2.close();
+ }
+ catch (Exception e)
+ {
+ //Ignore
+ }
+ }
+
+ if (conn3 != null)
+ {
+ try
+ {
+ conn3.close();
+ }
+ catch (Exception e)
+ {
+ //Ignore
+ }
+ }
+ }
+ }
+
+
+
+ /*
+ * In this test, we have two queues, each with four messages already in them.
+ *
+ * We send 4 more messages to each queue, and ack the original 4 in a tx
+ *
+ * Then recover it after restarting the server, then rollback
+ *
+ */
+ public void testComplexTransactionalRecoveryWithRestartRollback() throws Exception
+ {
+ Connection conn1 = null;
+
+ XAConnection conn2 = null;
+
+ XAConnection conn3 = null;
+
+ try
+ {
+ conn1 = cf.createConnection();
+
+ Session sess1 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageProducer prod1 = sess1.createProducer(queueA);
+
+ MessageProducer prod2 = sess1.createProducer(queueB);
+
+ TextMessage tm1 = sess1.createTextMessage("tm1");
+ TextMessage tm2 = sess1.createTextMessage("tm2");
+ TextMessage tm3 = sess1.createTextMessage("tm3");
+ TextMessage tm4 = sess1.createTextMessage("tm4");
+ TextMessage tm5 = sess1.createTextMessage("tm5");
+ TextMessage tm6 = sess1.createTextMessage("tm6");
+ TextMessage tm7 = sess1.createTextMessage("tm7");
+ TextMessage tm8 = sess1.createTextMessage("tm8");
+
+ prod1.send(tm1);
+ prod1.send(tm2);
+ prod1.send(tm3);
+ prod1.send(tm4);
+
+ prod2.send(tm5);
+ prod2.send(tm6);
+ prod2.send(tm7);
+ prod2.send(tm8);
+
+ conn2 = cf.createXAConnection();
+
+ conn2.start();
+
+ XASession sess2 = conn2.createXASession();
+
+ XAResource res = sess2.getXAResource();
+
+ Xid xid1 = new XidImpl("bq1".getBytes(), 42, "eemeli".getBytes());
+
+ res.start(xid1, XAResource.TMNOFLAGS);
+
+ MessageProducer prod3 = sess2.createProducer(queueA);
+
+ TextMessage tm9 = sess2.createTextMessage("tm9");
+ TextMessage tm10 = sess2.createTextMessage("tm10");
+ TextMessage tm11 = sess2.createTextMessage("tm11");
+ TextMessage tm12 = sess2.createTextMessage("tm12");
+
+ prod3.send(tm9);
+ prod3.send(tm10);
+ prod3.send(tm11);
+ prod3.send(tm12);
+
+ MessageProducer prod4 = sess2.createProducer(queueB);
+
+ TextMessage tm13 = sess2.createTextMessage("tm13");
+ TextMessage tm14 = sess2.createTextMessage("tm14");
+ TextMessage tm15 = sess2.createTextMessage("tm15");
+ TextMessage tm16 = sess2.createTextMessage("tm16");
+
+ prod4.send(tm13);
+ prod4.send(tm14);
+ prod4.send(tm15);
+ prod4.send(tm16);
+
+ MessageConsumer cons1 = sess2.createConsumer(queueA);
+
+ TextMessage rm1 = (TextMessage)cons1.receive(1000);
+ assertNotNull(rm1);
+ assertEquals(tm1.getText(), rm1.getText());
+
+ TextMessage rm2 = (TextMessage)cons1.receive(1000);
+ assertNotNull(rm2);
+ assertEquals(tm2.getText(), rm2.getText());
+
+ TextMessage rm3 = (TextMessage)cons1.receive(1000);
+ assertNotNull(rm3);
+ assertEquals(tm3.getText(), rm3.getText());
+
+ TextMessage rm4 = (TextMessage)cons1.receive(1000);
+ assertNotNull(rm4);
+ assertEquals(tm4.getText(), rm4.getText());
+
+ Message m = cons1.receive(1000);
+
+ assertNull(m);
+
+ MessageConsumer cons2 = sess2.createConsumer(queueB);
+
+ TextMessage rm5 = (TextMessage)cons2.receive(1000);
+ assertNotNull(rm5);
+ assertEquals(tm5.getText(), rm5.getText());
+
+ TextMessage rm6 = (TextMessage)cons2.receive(1000);
+ assertNotNull(rm6);
+ assertEquals(tm6.getText(), rm6.getText());
+
+ TextMessage rm7 = (TextMessage)cons2.receive(1000);
+ assertNotNull(rm7);
+ assertEquals(tm7.getText(), rm7.getText());
+
+ TextMessage rm8 = (TextMessage)cons2.receive(1000);
+ assertNotNull(rm8);
+ assertEquals(tm8.getText(), rm8.getText());
+
+ m = cons2.receive(1000);
+
+ assertNull(m);
+
+ res.end(xid1, XAResource.TMSUCCESS);
+
+ //prepare it
+
+ res.prepare(xid1);
+
+ conn1 = null;
+
+ conn2 = null;
+
+ // Now "crash" the server
+
+ ServerManagement.stopServerPeer();
+
+ ServerManagement.startServerPeer();
+
+ ServerManagement.deployQueue("QA");
+
+ ServerManagement.deployQueue("QB");
+
+ conn3 = cf.createXAConnection();
+
+ XASession sess3 = conn3.createXASession();
+
+ XAResource res3 = sess3.getXAResource();
+
+ Xid[] xids = res3.recover(XAResource.TMSTARTRSCAN);
+ assertEquals(1, xids.length);
+
+ Xid[] xids2 = res3.recover(XAResource.TMENDRSCAN);
+ assertEquals(0, xids2.length);
+
+ assertEquals(xid1, xids[0]);
+
+ log.trace("rolling back the tx");
+
+ //rollback
+ res3.rollback(xids[0]);
+
+ log.trace("rolled back the tx");
+
+ Thread.sleep(1000);
+
+ conn1 = cf.createConnection();
+
+ conn1.start();
+
+ sess1 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ log.trace("creating a consumer");
+
+ cons1 = sess1.createConsumer(queueA);
+
+ log.trace("created a consumer");
+
+ TextMessage rm9 = (TextMessage)cons1.receive(1000);
+ assertNotNull(rm9);
+ assertEquals(tm1.getText(), rm9.getText());
+
+ TextMessage rm10 = (TextMessage)cons1.receive(1000);
+ assertNotNull(rm10);
+ assertEquals(tm2.getText(), rm10.getText());
+
+ TextMessage rm11 = (TextMessage)cons1.receive(1000);
+ assertNotNull(rm11);
+ assertEquals(tm3.getText(), rm11.getText());
+
+ TextMessage rm12 = (TextMessage)cons1.receive(1000);
+ assertNotNull(rm12);
+ assertEquals(tm4.getText(), rm12.getText());
+
+ m = cons1.receive(1000);
+
+ assertNull(m);
+
+ cons2 = sess1.createConsumer(queueB);
+
+ TextMessage rm13 = (TextMessage)cons2.receive(1000);
+ assertNotNull(rm13);
+ assertEquals(tm5.getText(), rm13.getText());
+
+ TextMessage rm14 = (TextMessage)cons2.receive(1000);
+ assertNotNull(rm14);
+ assertEquals(tm6.getText(), rm14.getText());
+
+ TextMessage rm15 = (TextMessage)cons2.receive(1000);
+ assertNotNull(rm15);
+ assertEquals(tm7.getText(), rm15.getText());
+
+ TextMessage rm16 = (TextMessage)cons2.receive(1000);
+ assertNotNull(rm16);
+ assertEquals(tm8.getText(), rm16.getText());
+
+ m = cons2.receive(1000);
+
+ assertNull(m);
+
+ cons1.close();
+
+ if (checkNoMessageData())
+ {
+ fail("Data remains in database");
+ }
+
+ }
+ finally
+ {
+ if (conn1 != null)
+ {
+ try
+ {
+ conn1.close();
+ }
+ catch (Exception e)
+ {
+ //Ignore
+ }
+ }
+
+ if (conn2 != null)
+ {
+ try
+ {
+ conn2.close();
+ }
+ catch (Exception e)
+ {
+ //Ignore
+ }
+ }
+
+ if (conn3 != null)
+ {
+ try
+ {
+ conn3.close();
+ }
+ catch (Exception e)
+ {
+ //Ignore
+ }
+ }
+ }
+ }
+
+ /* Not really necessary - but it does no harm */
+ public void testComplexTransactional() throws Exception
+ {
+ Connection conn1 = null;
+
+ XAConnection conn2 = null;
+
+ XAConnection conn3 = null;
+
+ try
+ {
+ conn1 = cf.createConnection();
+
+ Session sess1 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageProducer prod1 = sess1.createProducer(queueA);
+
+ MessageProducer prod2 = sess1.createProducer(queueB);
+
+ TextMessage tm1 = sess1.createTextMessage("tm1");
+ TextMessage tm2 = sess1.createTextMessage("tm2");
+ TextMessage tm3 = sess1.createTextMessage("tm3");
+ TextMessage tm4 = sess1.createTextMessage("tm4");
+ TextMessage tm5 = sess1.createTextMessage("tm5");
+ TextMessage tm6 = sess1.createTextMessage("tm6");
+ TextMessage tm7 = sess1.createTextMessage("tm7");
+ TextMessage tm8 = sess1.createTextMessage("tm8");
+
+ prod1.send(tm1);
+ prod1.send(tm2);
+ prod1.send(tm3);
+ prod1.send(tm4);
+
+ prod2.send(tm5);
+ prod2.send(tm6);
+ prod2.send(tm7);
+ prod2.send(tm8);
+
+ conn2 = cf.createXAConnection();
+
+ conn2.start();
+
+ XASession sess2 = conn2.createXASession();
+
+ XAResource res = sess2.getXAResource();
+
+ Xid xid1 = new XidImpl("bq1".getBytes(), 42, "eemeli".getBytes());
+
+ res.start(xid1, XAResource.TMNOFLAGS);
+
+ MessageProducer prod3 = sess2.createProducer(queueA);
+
+ TextMessage tm9 = sess2.createTextMessage("tm9");
+ TextMessage tm10 = sess2.createTextMessage("tm10");
+ TextMessage tm11 = sess2.createTextMessage("tm11");
+ TextMessage tm12 = sess2.createTextMessage("tm12");
+
+ prod3.send(tm9);
+ prod3.send(tm10);
+ prod3.send(tm11);
+ prod3.send(tm12);
+
+ MessageProducer prod4 = sess2.createProducer(queueB);
+
+ TextMessage tm13 = sess2.createTextMessage("tm13");
+ TextMessage tm14 = sess2.createTextMessage("tm14");
+ TextMessage tm15 = sess2.createTextMessage("tm15");
+ TextMessage tm16 = sess2.createTextMessage("tm16");
+
+ prod4.send(tm13);
+ prod4.send(tm14);
+ prod4.send(tm15);
+ prod4.send(tm16);
+
+ MessageConsumer cons1 = sess2.createConsumer(queueA);
+
+ TextMessage rm1 = (TextMessage)cons1.receive(1000);
+ assertNotNull(rm1);
+ assertEquals(tm1.getText(), rm1.getText());
+
+ TextMessage rm2 = (TextMessage)cons1.receive(1000);
+ assertNotNull(rm2);
+ assertEquals(tm2.getText(), rm2.getText());
+
+ TextMessage rm3 = (TextMessage)cons1.receive(1000);
+ assertNotNull(rm3);
+ assertEquals(tm3.getText(), rm3.getText());
+
+ TextMessage rm4 = (TextMessage)cons1.receive(1000);
+ assertNotNull(rm4);
+ assertEquals(tm4.getText(), rm4.getText());
+
+ Message m = cons1.receive(1000);
+
+ assertNull(m);
+
+ MessageConsumer cons2 = sess2.createConsumer(queueB);
+
+ TextMessage rm5 = (TextMessage)cons2.receive(1000);
+ assertNotNull(rm5);
+ assertEquals(tm5.getText(), rm5.getText());
+
+ TextMessage rm6 = (TextMessage)cons2.receive(1000);
+ assertNotNull(rm6);
+ assertEquals(tm6.getText(), rm6.getText());
+
+ TextMessage rm7 = (TextMessage)cons2.receive(1000);
+ assertNotNull(rm7);
+ assertEquals(tm7.getText(), rm7.getText());
+
+ TextMessage rm8 = (TextMessage)cons2.receive(1000);
+ assertNotNull(rm8);
+ assertEquals(tm8.getText(), rm8.getText());
+
+ m = cons2.receive(1000);
+
+ assertNull(m);
+
+ res.end(xid1, XAResource.TMSUCCESS);
+
+ //prepare it
+
+ res.prepare(xid1);
+
+ res.commit(xid1, false);
+
+ conn1.close();
+
+ conn2.close();
+
+
+
+ conn1 = cf.createConnection();
+
+ conn1.start();
+
+ sess1 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ cons1 = sess1.createConsumer(queueA);
+
+ TextMessage rm9 = (TextMessage)cons1.receive(1000);
+ assertNotNull(rm9);
+ assertEquals(tm9.getText(), rm9.getText());
+
+ TextMessage rm10 = (TextMessage)cons1.receive(1000);
+ assertNotNull(rm10);
+ assertEquals(tm10.getText(), rm10.getText());
+
+ TextMessage rm11 = (TextMessage)cons1.receive(1000);
+ assertNotNull(rm11);
+ assertEquals(tm11.getText(), rm11.getText());
+
+ TextMessage rm12 = (TextMessage)cons1.receive(1000);
+ assertNotNull(rm12);
+ assertEquals(tm12.getText(), rm12.getText());
+
+ m = cons1.receive(1000);
+
+ assertNull(m);
+
+ cons2 = sess1.createConsumer(queueB);
+
+ TextMessage rm13 = (TextMessage)cons2.receive(1000);
+ assertNotNull(rm13);
+ assertEquals(tm13.getText(), rm13.getText());
+
+ TextMessage rm14 = (TextMessage)cons2.receive(1000);
+ assertNotNull(rm14);
+ assertEquals(tm14.getText(), rm14.getText());
+
+ TextMessage rm15 = (TextMessage)cons2.receive(1000);
+ assertNotNull(rm15);
+ assertEquals(tm15.getText(), rm15.getText());
+
+ TextMessage rm16 = (TextMessage)cons2.receive(1000);
+ assertNotNull(rm16);
+ assertEquals(tm16.getText(), rm16.getText());
+
+ m = cons2.receive(1000);
+
+ assertNull(m);
+
+ if (checkNoMessageData())
+ {
+ fail("Data remains in database");
+ }
+
+ }
+ finally
+ {
+ if (conn1 != null)
+ {
+ try
+ {
+ conn1.close();
+ }
+ catch (Exception e)
+ {
+ //Ignore
+ }
+ }
+
+ if (conn2 != null)
+ {
+ try
+ {
+ conn2.close();
+ }
+ catch (Exception e)
+ {
+ //Ignore
+ }
+ }
+
+ if (conn3 != null)
+ {
+ try
+ {
+ conn3.close();
+ }
+ catch (Exception e)
+ {
+ //Ignore
+ }
+ }
+ }
+ }
+
+
+ /* A simple send in a transaction - recovered without restarting the server */
+ public void testSimpleTransactionalSendRecoveryWithoutRestart() throws Exception
+ {
+ log.trace("starting testSimpleTransactionalDeliveryRecoveryWithoutRestart");
+
+ XAConnection conn1 = null;
+
+ Connection conn2 = null;
+
+ XAConnection conn3 = null;
+
+ try
+ {
+ conn1 = cf.createXAConnection();
+
+ XASession sess1 = conn1.createXASession();
+
+ XAResource res1 = sess1.getXAResource();
+
+ //Pretend to be a transaction manager by interacting through the XAResources
+ Xid xid1 = new XidImpl("bq1".getBytes(), 42, "eemeli".getBytes());
+
+ log.trace("Sending message");
+
+ //Send message in tx
+
+ res1.start(xid1, XAResource.TMNOFLAGS);
+
+ MessageProducer prod1 = sess1.createProducer(queueTX);
+
+ TextMessage tm1 = sess1.createTextMessage("tm1");
+
+ prod1.send(tm1);
+
+ res1.end(xid1, XAResource.TMSUCCESS);
+
+ log.trace("Sent message");
+
+ //prepare tx
+
+ res1.prepare(xid1);
+
+ log.trace("prepared tx");
+
+ conn2 = cf.createConnection();
+
+ Session sess2 = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageConsumer cons2 = sess2.createConsumer(queueTX);
+
+ conn2.start();
+
+ //Verify message can't be received
+
+ Message m = cons2.receive(1000);
+
+ assertNull(m);
+
+
+ //Now recover
+
+ conn3 = cf.createXAConnection();
+
+ XASession sess3 = conn3.createXASession();
+
+ XAResource res3 = sess3.getXAResource();
+
+ Xid[] xids = res3.recover(XAResource.TMSTARTRSCAN);
+ assertEquals(1, xids.length);
+
+ Xid[] xids2 = res3.recover(XAResource.TMENDRSCAN);
+ assertEquals(0, xids2.length);
+
+ assertEquals(xid1, xids[0]);
+
+ // Verify message still can't be received
+
+ m = cons2.receive(1000);
+
+ assertNull(m);
+
+ //Commit the tx
+
+ res1.commit(xids[0], false);
+
+ //The message should now be available
+
+ TextMessage rm1 = (TextMessage)cons2.receive(1000);
+
+ assertNotNull(rm1);
+
+ assertEquals(tm1.getText(), rm1.getText());
+
+ if (checkNoMessageData())
+ {
+ fail("Data remains in database");
+ }
+ }
+ finally
+ {
+ if (conn1 != null)
+ {
+ try
+ {
+ conn1.close();
+ }
+ catch (Exception e)
+ {
+ //Ignore
+ }
+ }
+
+ if (conn2 != null)
+ {
+ try
+ {
+ conn2.close();
+ }
+ catch (Exception e)
+ {
+ //Ignore
+ }
+ }
+
+ if (conn3 != null)
+ {
+ try
+ {
+ conn3.close();
+ }
+ catch (Exception e)
+ {
+ //Ignore
+ }
+ }
+ }
+ }
+
+ /* A simple send in a transaction - recovered after restarting the server */
+ public void testSimpleTransactionalSendRecoveryWithRestart() throws Exception
+ {
+ log.trace("starting testSimpleTransactionalDeliveryRecoveryWithRestart");
+
+ XAConnection conn1 = null;
+
+ Connection conn2 = null;
+
+ XAConnection conn3 = null;
+
+ try
+ {
+ conn1 = cf.createXAConnection();
+
+ XASession sess1 = conn1.createXASession();
+
+ XAResource res1 = sess1.getXAResource();
+
+ //Pretend to be a transaction manager by interacting through the XAResources
+ Xid xid1 = new XidImpl("bq1".getBytes(), 42, "eemeli".getBytes());
+
+ log.trace("Sending message");
+
+ //Send message in tx
+
+ res1.start(xid1, XAResource.TMNOFLAGS);
+
+ MessageProducer prod1 = sess1.createProducer(queueTX);
+
+ TextMessage tm1 = sess1.createTextMessage("tm1");
+
+ prod1.send(tm1);
+
+ res1.end(xid1, XAResource.TMSUCCESS);
+
+ log.trace("Sent message");
+
+ //prepare tx
+
+ res1.prepare(xid1);
+
+ log.trace("prepared tx");
+
+ conn2 = cf.createConnection();
+
+ Session sess2 = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageConsumer cons2 = sess2.createConsumer(queueTX);
+
+ conn2.start();
+
+ //Verify message can't be received
+
+ Message m = cons2.receive(1000);
+
+ assertNull(m);
+
+ conn1 = null;
+
+ conn2 = null;
+
+ // Now "crash" the server
+
+ ServerManagement.stopServerPeer();
+
+ ServerManagement.startServerPeer();
+
+ ServerManagement.deployQueue("TXQ");
+
+ log.trace("Restarted");
+
+ //Now recover
+
+ conn3 = cf.createXAConnection();
+
+ XASession sess3 = conn3.createXASession();
+
+ XAResource res3 = sess3.getXAResource();
+
+ log.trace("created connection");
+
+ Xid[] xids = res3.recover(XAResource.TMSTARTRSCAN);
+ assertEquals(1, xids.length);
+
+ Xid[] xids2 = res3.recover(XAResource.TMENDRSCAN);
+ assertEquals(0, xids2.length);
+
+ assertEquals(xid1, xids[0]);
+
+ log.trace("recovered");
+
+ conn2 = cf.createConnection();
+
+ sess2 = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ cons2 = sess2.createConsumer(queueTX);
+
+ conn2.start();
+
+ // Verify message still can't be received
+
+ m = cons2.receive(1000);
+
+ assertNull(m);
+
+ log.trace("still can't see message");
+
+ //Commit the tx
+
+ res3.commit(xids[0], false);
+
+ log.trace("committed");
+
+ //The message should now be available
+
+ TextMessage rm1 = (TextMessage)cons2.receive(1000);
+
+ assertNotNull(rm1);
+
+ assertEquals(tm1.getText(), rm1.getText());
+
+ if (checkNoMessageData())
+ {
+ fail("Data remains in database");
+ }
+ }
+ finally
+ {
+ if (conn1 != null)
+ {
+ try
+ {
+ conn1.close();
+ }
+ catch (Exception e)
+ {
+ //Ignore
+ }
+ }
+
+ if (conn2 != null)
+ {
+ try
+ {
+ conn2.close();
+ }
+ catch (Exception e)
+ {
+ //Ignore
+ }
+ }
+
+ if (conn3 != null)
+ {
+ try
+ {
+ conn3.close();
+ }
+ catch (Exception e)
+ {
+ //Ignore
+ }
+ }
+ }
+ }
+
+
+
+
+ /* A simple acknowledgement in a transaction, recovered without restart */
+ public void testSimpleTransactionalAcknowledgementRecoveryWithoutRestart() throws Exception
+ {
+ log.trace("starting testSimpleTransactionalAcknowledgementRecovery");
+
+ Connection conn1 = null;
+
+ XAConnection conn2 = null;
+
+ XAConnection conn3 = null;
+
+ try
+ {
+ //First send a message to the queue
+ conn1 = cf.createConnection();
+
+ Session sess1 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageProducer prod = sess1.createProducer(queueTX);
+
+ TextMessage tm1 = sess1.createTextMessage("tm1");
+
+ prod.send(tm1);
+
+
+ conn2 = cf.createXAConnection();
+
+ XASession sess2 = conn2.createXASession();
+
+ XAResource res1 = sess2.getXAResource();
+
+ //Pretend to be a transaction manager by interacting through the XAResources
+ Xid xid1 = new XidImpl("bq1".getBytes(), 42, "eemeli".getBytes());
+
+ res1.start(xid1, XAResource.TMNOFLAGS);
+
+ MessageConsumer cons = sess2.createConsumer(queueTX);
+
+ conn2.start();
+
+ //Consume the message
+
+ TextMessage rm1 = (TextMessage)cons.receive(1000);
+
+ assertNotNull(rm1);
+
+ assertEquals(tm1.getText(), rm1.getText());
+
+ res1.end(xid1, XAResource.TMSUCCESS);
+
+ //prepare the tx
+
+ res1.prepare(xid1);
+
+
+ //Now recover
+
+ conn3 = cf.createXAConnection();
+
+ XASession sess3 = conn3.createXASession();
+
+ XAResource res3 = sess3.getXAResource();
+
+ Xid[] xids = res3.recover(XAResource.TMSTARTRSCAN);
+ assertEquals(1, xids.length);
+
+ Xid[] xids2 = res3.recover(XAResource.TMENDRSCAN);
+ assertEquals(0, xids2.length);
+
+ assertEquals(xid1, xids[0]);
+
+ //Commit the tx
+
+ res1.commit(xids[0], false);
+
+ //The message should be acknowldged
+
+ conn1.close();
+
+ conn2.close();
+
+ conn3.close();
+
+ conn1 = cf.createConnection();
+
+ sess1 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageConsumer cons1 = sess1.createConsumer(queueTX);
+
+ conn1.start();
+
+ Message m = cons1.receive(1000);
+
+ assertNull(m);
+
+ if (checkNoMessageData())
+ {
+ fail("Data remains in database");
+ }
+ }
+ finally
+ {
+ if (conn1 != null)
+ {
+ try
+ {
+ conn1.close();
+ }
+ catch (Exception e)
+ {
+ //Ignore
+ }
+ }
+
+ if (conn2 != null)
+ {
+ try
+ {
+ conn2.close();
+ }
+ catch (Exception e)
+ {
+ //Ignore
+ }
+ }
+
+ if (conn3 != null)
+ {
+ try
+ {
+ conn3.close();
+ }
+ catch (Exception e)
+ {
+ //Ignore
+ }
+ }
+ }
+ }
+
+
+
+ /* A simple acknowledgement in a transaction, recovered with restart */
+ public void testSimpleTransactionalAcknowledgementRecoveryWithRestart() throws Exception
+ {
+ log.trace("starting testSimpleTransactionalAcknowledgementRecoveryWithRestart");
+
+ Connection conn1 = null;
+
+ XAConnection conn2 = null;
+
+ XAConnection conn3 = null;
+
+ try
+ {
+ //First send a message to the queue
+ conn1 = cf.createConnection();
+
+ Session sess1 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageProducer prod = sess1.createProducer(queueTX);
+
+ TextMessage tm1 = sess1.createTextMessage("tm1");
+
+ prod.send(tm1);
+
+ conn2 = cf.createXAConnection();
+
+ XASession sess2 = conn2.createXASession();
+
+ XAResource res1 = sess2.getXAResource();
+
+ //Pretend to be a transaction manager by interacting through the XAResources
+ Xid xid1 = new XidImpl("bq1".getBytes(), 42, "eemeli".getBytes());
+
+ res1.start(xid1, XAResource.TMNOFLAGS);
+
+ MessageConsumer cons = sess2.createConsumer(queueTX);
+
+ conn2.start();
+
+ //Consume the message
+
+ TextMessage rm1 = (TextMessage)cons.receive(1000);
+
+ assertNotNull(rm1);
+
+ assertEquals(tm1.getText(), rm1.getText());
+
+ res1.end(xid1, XAResource.TMSUCCESS);
+
+ //prepare the tx
+
+ res1.prepare(xid1);
+
+ conn1 = null;
+
+ conn2 = null;
+
+ // Now "crash" the server
+
+ ServerManagement.stopServerPeer();
+
+ ServerManagement.startServerPeer();
+
+ ServerManagement.deployQueue("TXQ");
+
+
+ //Now recover
+
+ conn3 = cf.createXAConnection();
+
+ XASession sess3 = conn3.createXASession();
+
+ XAResource res3 = sess3.getXAResource();
+
+ Xid[] xids = res3.recover(XAResource.TMSTARTRSCAN);
+ assertEquals(1, xids.length);
+
+ Xid[] xids2 = res3.recover(XAResource.TMENDRSCAN);
+ assertEquals(0, xids2.length);
+
+ assertEquals(xid1, xids[0]);
+
+ //Commit the tx
+
+ res3.commit(xids[0], false);
+
+ //The message should be acknowldged
+
+ conn3.close();
+
+ conn1 = cf.createConnection();
+
+ sess1 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageConsumer cons1 = sess1.createConsumer(queueTX);
+
+ conn1.start();
+
+ Message m = cons1.receive(1000);
+
+ assertNull(m);
+
+ if (checkNoMessageData())
+ {
+ fail("Data remains in database");
+ }
+ }
+ finally
+ {
+ if (conn1 != null)
+ {
+ try
+ {
+ conn1.close();
+ }
+ catch (Exception e)
+ {
+ //Ignore
+ }
+ }
+
+ if (conn2 != null)
+ {
+ try
+ {
+ conn2.close();
+ }
+ catch (Exception e)
+ {
+ //Ignore
+ }
+ }
+
+ if (conn3 != null)
+ {
+ try
+ {
+ conn3.close();
+ }
+ catch (Exception e)
+ {
+ //Ignore
+ }
+ }
+ }
+ }
+
+
+ /*
+ * In this test, we have 4 messages in a 2 durable subs on the same topic.
+ *
+ * We ack them, then add four more messages
+ *
+ * This test tests for the recovery when the same message is in multiple channels
+ *
+ * We don't restart in this test
+ *
+ */
+ public void testRecoveryWithTwoDurableSubsWithoutRestart() throws Exception
+ {
+ Connection conn1 = null;
+
+ XAConnection conn2 = null;
+
+ XAConnection conn3 = null;
+
+ try
+ {
+ conn1 = cf.createConnection();
+
+ conn1.setClientID("wib1");
+
+ Session sess1 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageProducer prod1 = sess1.createProducer(topicTX);
+
+ MessageConsumer sub1 = sess1.createDurableSubscriber((Topic)topicTX, "sub1");
+
+ MessageConsumer sub2 = sess1.createDurableSubscriber((Topic)topicTX, "sub2");
+
+ //send four messages
+
+ TextMessage tm1 = sess1.createTextMessage("tm1");
+ TextMessage tm2 = sess1.createTextMessage("tm2");
+ TextMessage tm3 = sess1.createTextMessage("tm3");
+ TextMessage tm4 = sess1.createTextMessage("tm4");
+
+ prod1.send(tm1);
+ prod1.send(tm2);
+ prod1.send(tm3);
+ prod1.send(tm4);
+
+ conn1.close();
+
+ //The messages should now be in both durable subs
+
+ conn2 = cf.createXAConnection();
+
+ conn2.setClientID("wib1");
+
+ conn2.start();
+
+ XASession sess2 = conn2.createXASession();
+
+ XAResource res = sess2.getXAResource();
+
+ Xid xid1 = new XidImpl("bq1".getBytes(), 42, "eemeli".getBytes());
+
+ res.start(xid1, XAResource.TMNOFLAGS);
+
+ //Now send four more messages in a global tx
+
+ MessageProducer prod2 = sess2.createProducer(topicTX);
+
+ TextMessage tm5 = sess2.createTextMessage("tm5");
+ TextMessage tm6 = sess2.createTextMessage("tm6");
+ TextMessage tm7 = sess2.createTextMessage("tm7");
+ TextMessage tm8 = sess2.createTextMessage("tm8");
+
+ prod2.send(tm5);
+ prod2.send(tm6);
+ prod2.send(tm7);
+ prod2.send(tm8);
+
+ //And consume the first four from each in the tx
+
+ sub1 = sess2.createDurableSubscriber((Topic)topicTX, "sub1");
+
+ sub2 = sess2.createDurableSubscriber((Topic)topicTX, "sub2");
+
+ TextMessage rm1 = (TextMessage)sub1.receive(1000);
+ assertNotNull(rm1);
+ assertEquals(tm1.getText(), rm1.getText());
+
+ TextMessage rm2 = (TextMessage)sub1.receive(1000);
+ assertNotNull(rm2);
+ assertEquals(tm2.getText(), rm2.getText());
+
+ TextMessage rm3 = (TextMessage)sub1.receive(1000);
+ assertNotNull(rm3);
+ assertEquals(tm3.getText(), rm3.getText());
+
+ TextMessage rm4 = (TextMessage)sub1.receive(1000);
+ assertNotNull(rm4);
+ assertEquals(tm4.getText(), rm4.getText());
+
+ Message m = sub1.receive(1000);
+
+ assertNull(m);
+
+ rm1 = (TextMessage)sub2.receive(1000);
+ assertNotNull(rm1);
+ assertEquals(tm1.getText(), rm1.getText());
+
+ rm2 = (TextMessage)sub2.receive(1000);
+ assertNotNull(rm2);
+ assertEquals(tm2.getText(), rm2.getText());
+
+ rm3 = (TextMessage)sub2.receive(1000);
+ assertNotNull(rm3);
+ assertEquals(tm3.getText(), rm3.getText());
+
+ rm4 = (TextMessage)sub2.receive(1000);
+ assertNotNull(rm4);
+ assertEquals(tm4.getText(), rm4.getText());
+
+ m = sub2.receive(1000);
+
+ assertNull(m);
+
+ res.end(xid1, XAResource.TMSUCCESS);
+
+ //prepare it
+
+ res.prepare(xid1);
+
+ conn3 = cf.createXAConnection();
+
+ XASession sess3 = conn3.createXASession();
+
+ XAResource res3 = sess3.getXAResource();
+
+ //recover
+
+ Xid[] xids = res3.recover(XAResource.TMSTARTRSCAN);
+ assertEquals(1, xids.length);
+
+ Xid[] xids2 = res3.recover(XAResource.TMENDRSCAN);
+ assertEquals(0, xids2.length);
+
+ assertEquals(xid1, xids[0]);
+
+ log.trace("Committing the tx");
+
+ //Commit
+ res3.commit(xids[0], false);
+
+ log.trace("committed the tx");
+
+ conn2.close();
+
+
+ conn1 = cf.createConnection();
+
+ conn1.setClientID("wib1");
+
+ conn1.start();
+
+ sess1 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ //Should now see the last 4 messages
+
+ sub1 = sess1.createDurableSubscriber((Topic)topicTX, "sub1");
+
+ sub2 = sess1.createDurableSubscriber((Topic)topicTX, "sub2");
+
+ TextMessage rm5 = (TextMessage)sub1.receive(1000);
+ assertNotNull(rm5);
+ assertEquals(tm5.getText(), rm5.getText());
+
+ TextMessage rm6 = (TextMessage)sub1.receive(1000);
+ assertNotNull(rm6);
+ assertEquals(tm6.getText(), rm6.getText());
+
+ TextMessage rm7 = (TextMessage)sub1.receive(1000);
+ assertNotNull(rm7);
+ assertEquals(tm7.getText(), rm7.getText());
+
+ TextMessage rm8 = (TextMessage)sub1.receive(1000);
+ assertNotNull(rm8);
+ assertEquals(tm8.getText(), rm8.getText());
+
+ m = sub1.receive(1000);
+
+ assertNull(m);
+
+ rm5 = (TextMessage)sub2.receive(1000);
+ assertNotNull(rm5);
+ assertEquals(tm5.getText(), rm5.getText());
+
+ rm6 = (TextMessage)sub2.receive(1000);
+ assertNotNull(rm6);
+ assertEquals(tm6.getText(), rm6.getText());
+
+ rm7 = (TextMessage)sub2.receive(1000);
+ assertNotNull(rm7);
+ assertEquals(tm7.getText(), rm7.getText());
+
+ rm8 = (TextMessage)sub2.receive(1000);
+ assertNotNull(rm8);
+ assertEquals(tm8.getText(), rm8.getText());
+
+ m = sub2.receive(1000);
+
+ assertNull(m);
+
+ if (checkNoMessageData())
+ {
+ fail("Data remains in database");
+ }
+ }
+ finally
+ {
+ if (conn1 != null)
+ {
+ try
+ {
+ conn1.close();
+ }
+ catch (Exception e)
+ {
+ //Ignore
+ }
+ }
+
+ if (conn2 != null)
+ {
+ try
+ {
+ conn2.close();
+ }
+ catch (Exception e)
+ {
+ //Ignore
+ }
+ }
+
+ if (conn3 != null)
+ {
+ try
+ {
+ conn3.close();
+ }
+ catch (Exception e)
+ {
+ //Ignore
+ }
+ }
+ }
+ }
+
+
+
+ /*
+ * In this test, we have 4 messages in a 2 durable subs on the same topic.
+ *
+ * We ack them, then add four more messages
+ *
+ * This test tests for the recovery when the same message is in multiple channels
+ *
+ * We do restart in this test
+ *
+ */
+ public void testRecoveryWithTwoDurableSubsWithRestart() throws Exception
+ {
+ Connection conn1 = null;
+
+ XAConnection conn2 = null;
+
+ XAConnection conn3 = null;
+
+ try
+ {
+ conn1 = cf.createConnection();
+
+ conn1.setClientID("wib1");
+
+ Session sess1 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageProducer prod1 = sess1.createProducer(topicTX);
+
+ MessageConsumer sub1 = sess1.createDurableSubscriber((Topic)topicTX, "sub1");
+
+ MessageConsumer sub2 = sess1.createDurableSubscriber((Topic)topicTX, "sub2");
+
+ //send four messages
+
+ TextMessage tm1 = sess1.createTextMessage("tm1");
+ TextMessage tm2 = sess1.createTextMessage("tm2");
+ TextMessage tm3 = sess1.createTextMessage("tm3");
+ TextMessage tm4 = sess1.createTextMessage("tm4");
+
+ prod1.send(tm1);
+ prod1.send(tm2);
+ prod1.send(tm3);
+ prod1.send(tm4);
+
+ conn1.close();
+
+ //The messages should now be in both durable subs
+
+ conn2 = cf.createXAConnection();
+
+ conn2.setClientID("wib1");
+
+ conn2.start();
+
+ XASession sess2 = conn2.createXASession();
+
+ XAResource res = sess2.getXAResource();
+
+ Xid xid1 = new XidImpl("bq1".getBytes(), 42, "eemeli".getBytes());
+
+ res.start(xid1, XAResource.TMNOFLAGS);
+
+ //Now send four more messages in a global tx
+
+ MessageProducer prod2 = sess2.createProducer(topicTX);
+
+ TextMessage tm5 = sess2.createTextMessage("tm5");
+ TextMessage tm6 = sess2.createTextMessage("tm6");
+ TextMessage tm7 = sess2.createTextMessage("tm7");
+ TextMessage tm8 = sess2.createTextMessage("tm8");
+
+ prod2.send(tm5);
+ prod2.send(tm6);
+ prod2.send(tm7);
+ prod2.send(tm8);
+
+ //And consume the first four from each in the tx
+
+ sub1 = sess2.createDurableSubscriber((Topic)topicTX, "sub1");
+
+ sub2 = sess2.createDurableSubscriber((Topic)topicTX, "sub2");
+
+ TextMessage rm1 = (TextMessage)sub1.receive(1000);
+ assertNotNull(rm1);
+ assertEquals(tm1.getText(), rm1.getText());
+
+ TextMessage rm2 = (TextMessage)sub1.receive(1000);
+ assertNotNull(rm2);
+ assertEquals(tm2.getText(), rm2.getText());
+
+ TextMessage rm3 = (TextMessage)sub1.receive(1000);
+ assertNotNull(rm3);
+ assertEquals(tm3.getText(), rm3.getText());
+
+ TextMessage rm4 = (TextMessage)sub1.receive(1000);
+ assertNotNull(rm4);
+ assertEquals(tm4.getText(), rm4.getText());
+
+ Message m = sub1.receive(1000);
+
+ assertNull(m);
+
+ rm1 = (TextMessage)sub2.receive(1000);
+ assertNotNull(rm1);
+ assertEquals(tm1.getText(), rm1.getText());
+
+ rm2 = (TextMessage)sub2.receive(1000);
+ assertNotNull(rm2);
+ assertEquals(tm2.getText(), rm2.getText());
+
+ rm3 = (TextMessage)sub2.receive(1000);
+ assertNotNull(rm3);
+ assertEquals(tm3.getText(), rm3.getText());
+
+ rm4 = (TextMessage)sub2.receive(1000);
+ assertNotNull(rm4);
+ assertEquals(tm4.getText(), rm4.getText());
+
+ m = sub2.receive(1000);
+
+ assertNull(m);
+
+ res.end(xid1, XAResource.TMSUCCESS);
+
+ //prepare it
+
+ res.prepare(xid1);
+
+
+ conn1 = null;
+
+ conn2 = null;
+
+ // Now "crash" the server
+
+ ServerManagement.stopServerPeer();
+
+ ServerManagement.startServerPeer();
+
+ ServerManagement.deployTopic("TXTOPIC");
+
+
+ conn3 = cf.createXAConnection();
+
+ XASession sess3 = conn3.createXASession();
+
+ XAResource res3 = sess3.getXAResource();
+
+ //recover
+
+ Xid[] xids = res3.recover(XAResource.TMSTARTRSCAN);
+ assertEquals(1, xids.length);
+
+ Xid[] xids2 = res3.recover(XAResource.TMENDRSCAN);
+ assertEquals(0, xids2.length);
+
+ assertEquals(xid1, xids[0]);
+
+ log.trace("Committing the tx");
+
+ //Commit
+ res3.commit(xids[0], false);
+
+ log.trace("committed the tx");
+
+ conn1 = cf.createConnection();
+
+ conn1.setClientID("wib1");
+
+ conn1.start();
+
+ sess1 = conn1.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ //Should now see the last 4 messages
+
+ sub1 = sess1.createDurableSubscriber((Topic)topicTX, "sub1");
+
+ sub2 = sess1.createDurableSubscriber((Topic)topicTX, "sub2");
+
+ TextMessage rm5 = (TextMessage)sub1.receive(1000);
+ assertNotNull(rm5);
+ assertEquals(tm5.getText(), rm5.getText());
+
+ TextMessage rm6 = (TextMessage)sub1.receive(1000);
+ assertNotNull(rm6);
+ assertEquals(tm6.getText(), rm6.getText());
+
+ TextMessage rm7 = (TextMessage)sub1.receive(1000);
+ assertNotNull(rm7);
+ assertEquals(tm7.getText(), rm7.getText());
+
+ TextMessage rm8 = (TextMessage)sub1.receive(1000);
+ assertNotNull(rm8);
+ assertEquals(tm8.getText(), rm8.getText());
+
+ m = sub1.receive(1000);
+
+ assertNull(m);
+
+ rm5 = (TextMessage)sub2.receive(1000);
+ assertNotNull(rm5);
+ assertEquals(tm5.getText(), rm5.getText());
+
+ rm6 = (TextMessage)sub2.receive(1000);
+ assertNotNull(rm6);
+ assertEquals(tm6.getText(), rm6.getText());
+
+ rm7 = (TextMessage)sub2.receive(1000);
+ assertNotNull(rm7);
+ assertEquals(tm7.getText(), rm7.getText());
+
+ rm8 = (TextMessage)sub2.receive(1000);
+ assertNotNull(rm8);
+ assertEquals(tm8.getText(), rm8.getText());
+
+ m = sub2.receive(1000);
+
+ assertNull(m);
+
+ if (checkNoMessageData())
+ {
+ fail("Data remains in database");
+ }
+ }
+ finally
+ {
+ if (conn1 != null)
+ {
+ try
+ {
+ conn1.close();
+ }
+ catch (Exception e)
+ {
+ //Ignore
+ }
+ }
+
+ if (conn2 != null)
+ {
+ try
+ {
+ conn2.close();
+ }
+ catch (Exception e)
+ {
+ //Ignore
+ }
+ }
+
+ if (conn3 != null)
+ {
+ try
+ {
+ conn3.close();
+ }
+ catch (Exception e)
+ {
+ //Ignore
+ }
+ }
+ }
+ }
+
+
+
+ /*
+ * Send two messages in two transactions.
+ * Prepare tx
+ * Crash the server
+ * Restart the server
+ * Make sure the messages can be received
+ * NOTE this test only tests transactional sends, not transactional acknowledgments
+ *
+ */
+ public void testTransactionalDeliveryRecovery() throws Exception
+ {
+ log.trace("starting testTransactionalDeliveryRecovery");
+
+ XAConnection conn1 = null;
+
+ XAConnection conn2 = null;
+
+ Connection conn3 = null;
+
+ try
+ {
+ conn1 = cf.createXAConnection();
+
+ conn2 = cf.createXAConnection();
+
+ XASession sess1 = conn1.createXASession();
+
+ XASession sess2 = conn2.createXASession();
+
+ XAResource res1 = sess1.getXAResource();
+
+ XAResource res2 = sess2.getXAResource();
+
+ //Pretend to be a transaction manager by interacting through the XAResources
+ Xid xid1 = new XidImpl("bq1".getBytes(), 42, "eemeli".getBytes());
+ Xid xid2 = new XidImpl("bq2".getBytes(), 42, "frigtard".getBytes());
+
+ log.trace("Sending messages");
+
+ //Send two messages in transaction 1
+
+ res1.start(xid1, XAResource.TMNOFLAGS);
+
+ MessageProducer prod1 = sess1.createProducer(queueTX);
+
+ TextMessage tm1 = sess1.createTextMessage("tm1");
+
+ prod1.send(tm1);
+
+ TextMessage tm2 = sess1.createTextMessage("tm2");
+
+ prod1.send(tm2);
+
+ res1.end(xid1, XAResource.TMSUCCESS);
+
+ //Send two messages in transaction 2
+
+ res2.start(xid2, XAResource.TMNOFLAGS);
+
+ MessageProducer prod2 = sess2.createProducer(queueTX);
+
+ TextMessage tm3 = sess2.createTextMessage("tm3");
+
+ prod2.send(tm3);
+
+ TextMessage tm4 = sess2.createTextMessage("tm4");
+
+ prod2.send(tm4);
+
+ res2.end(xid2, XAResource.TMSUCCESS);
+
+ log.trace("Sent messages");
+
+ //prepare both txs
+
+ res1.prepare(xid1);
+ res2.prepare(xid2);
+
+ log.trace("prepared messages");
+
+ //Now "crash" the server
+
+ conn1 = null;
+
+ conn2 = null;
+
+ ServerManagement.stopServerPeer();
+
+ ServerManagement.startServerPeer();
+
+ ServerManagement.deployQueue("TXQ");
+
+ //Try and recover
+
+ XAResource res = cf.createXAConnection().createXASession().getXAResource();
+
+ log.trace("Recovering");
+
+ Xid[] xids = res.recover(XAResource.TMSTARTRSCAN);
+ assertEquals(2, xids.length);
+
+ Xid[] xids2 = res.recover(XAResource.TMENDRSCAN);
+ assertEquals(0, xids2.length);
+
+ //They may be in a different order
+ assertTrue(xids[0].equals(xid1) || xids[1].equals(xid1));
+ assertTrue(xids[0].equals(xid2) || xids[1].equals(xid2));
+
+ //Make sure can't receive the messages
+
+ log.trace("Creating conn");
+
+ conn3 = cf.createConnection();
+
+ Session sessRec = conn3.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ MessageConsumer cons = sessRec.createConsumer(queueTX);
+ conn3.start();
+
+ log.trace("Created conn3");
+
+ TextMessage m1 = (TextMessage)cons.receive(1000);
+ assertNull(m1);
+
+ log.trace("comitting");
+
+ //Commit tx1
+
+ res.commit(xid1, false);
+
+ log.trace("comitted");
+
+
+ //Should now be able to receive tm1 and tm2
+
+ m1 = (TextMessage)cons.receive(MAX_TIMEOUT);
+ assertNotNull(m1);
+
+ assertEquals(tm1.getText(), m1.getText());
+
+ TextMessage m2 = (TextMessage)cons.receive(MAX_TIMEOUT);
+ assertNotNull(m2);
+
+ assertEquals(tm2.getText(), m2.getText());
+
+ TextMessage m3 = (TextMessage)cons.receive(1000);
+ assertNull(m3);
+
+ //Now commit tx2
+
+ res.commit(xid2, false);
+
+ //Should now be able to receive tm3 and tm4
+
+ m3 = (TextMessage)cons.receive(MAX_TIMEOUT);
+ assertNotNull(m3);
+
+ assertEquals(tm3.getText(), m3.getText());
+
+ TextMessage m4 = (TextMessage)cons.receive(MAX_TIMEOUT);
+ assertNotNull(m4);
+
+ assertEquals(tm4.getText(), m4.getText());
+
+ TextMessage m5 = (TextMessage)cons.receive(1000);
+ assertNull(m5);
+
+ if (checkNoMessageData())
+ {
+ fail("Data remains in database");
+ }
+ }
+ finally
+ {
+ if (conn1 != null)
+ {
+ try
+ {
+ conn1.close();
+ }
+ catch (Exception e)
+ {
+ //Ignore
+ }
+ }
+
+ if (conn2 != null)
+ {
+ try
+ {
+ conn2.close();
+ }
+ catch (Exception e)
+ {
+ //Ignore
+ }
+ }
+
+ if (conn3 != null)
+ {
+ try
+ {
+ conn3.close();
+ }
+ catch (Exception e)
+ {
+ //Ignore
+ }
+ }
+ }
+ }
+
+
+ /*
+ * This test sends some messages in a couple of txs, crashes then recovers
+ * NOTE it does not test transactional acknowledgements
+ */
+ public void testMockCoordinatorRecovery() throws Exception
+ {
+ XAConnection conn1 = null;
+
+ XAConnection conn2 = null;
+
+ Connection conn3 = null;
+
+ try
+ {
+
+ conn1 = cf.createXAConnection();
+
+ conn2 = cf.createXAConnection();
+
+ XASession sess1 = conn1.createXASession();
+
+ XASession sess2 = conn2.createXASession();
+
+ XAResource res1 = sess1.getXAResource();
+
+ XAResource res2 = sess2.getXAResource();
+
+ //Pretend to be a transaction manager by interacting through the XAResources
+ Xid xid1 = new XidImpl("bq1".getBytes(), 42, "aapeli".getBytes());
+ Xid xid2 = new XidImpl("bq2".getBytes(), 42, "belsebub".getBytes());
+
+ // Send a message in each tx
+
+ res1.start(xid1, XAResource.TMNOFLAGS);
+
+ MessageProducer prod1 = sess1.createProducer(queueA);
+
+ TextMessage tm1 = sess1.createTextMessage("alpha");
+
+ prod1.send(tm1);
+
+ res1.end(xid1, XAResource.TMSUCCESS);
+
+
+ res2.start(xid2, XAResource.TMNOFLAGS);
+
+ MessageProducer prod2 = sess2.createProducer(queueA);
+
+ TextMessage tm2 = sess2.createTextMessage("beta");
+
+ prod2.send(tm2);
+
+ res2.end(xid2, XAResource.TMSUCCESS);
+
+ //prepare both txs
+
+
+ res1.prepare(xid1);
+ res2.prepare(xid2);
+
+ //Now "crash" the server
+
+ ServerManagement.stopServerPeer();
+
+ ServerManagement.startServerPeer();
+
+ ServerManagement.deployQueue("QA");
+
+
+ XAResource res = cf.createXAConnection().createXASession().getXAResource();
+
+ Xid[] xids = res.recover(XAResource.TMSTARTRSCAN);
+ assertEquals(2, xids.length);
+
+ Xid[] xids2 = res.recover(XAResource.TMENDRSCAN);
+ assertEquals(0, xids2.length);
+
+ assertTrue(xids[0].equals(xid1) || xids[1].equals(xid1));
+ assertTrue(xids[0].equals(xid2) || xids[1].equals(xid2));
+
+ res.commit(xid1, false);
+
+ res.commit(xid2, false);
+
+
+ conn3 = cf.createConnection();
+
+ Session sessRec = conn3.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ MessageConsumer cons = sessRec.createConsumer(queueA);
+ conn3.start();
+
+ Message msg = cons.receive(MAX_TIMEOUT);
+
+ TextMessage m1 = (TextMessage)msg;
+ assertNotNull(m1);
+
+ assertTrue("alpha".equals(m1.getText()) ||
+ "beta".equals(m1.getText()));
+
+ TextMessage m2 = (TextMessage)cons.receive(MAX_TIMEOUT);
+ assertNotNull(m2);
+
+ assertTrue("alpha".equals(m2.getText()) ||
+ "beta".equals(m2.getText()));
+
+ assertTrue(!tm1.getText().equals(tm2.getText()));
+
+ Message nullMessage = cons.receive(MIN_TIMEOUT);
+ assertTrue(nullMessage == null);
+
+ if (checkNoMessageData())
+ {
+ fail("Data remains in database");
+ }
+ }
+ finally
+ {
+ if (conn1 != null)
+ {
+ try
+ {
+ conn1.close();
+ }
+ catch (Exception e)
+ {
+ //Ignore
+ }
+ }
+
+ if (conn2 != null)
+ {
+ try
+ {
+ conn2.close();
+ }
+ catch (Exception e)
+ {
+ //Ignore
+ }
+ }
+
+ if (conn3 != null)
+ {
+ try
+ {
+ conn3.close();
+ }
+ catch (Exception e)
+ {
+ //Ignore
+ }
+ }
+ }
+
+ }
+
+
+ /*
+ * This test sends some messages in a couple of txs, crashes then recovers
+ * It uses the JBoss TS XId implementation - so we can show compatibility
+ * NOTE it does not test transactional acknowledgements
+ */
+ public void testMockCoordinatorRecoveryWithJBossTSXids() throws Exception
+ {
+ XAConnection conn1 = null;
+
+ XAConnection conn2 = null;
+
+ Connection conn3 = null;
+
+ try
+ {
+
+ conn1 = cf.createXAConnection();
+
+ conn2 = cf.createXAConnection();
+
+ XASession sess1 = conn1.createXASession();
+
+ XASession sess2 = conn2.createXASession();
+
+ XAResource res1 = sess1.getXAResource();
+
+ XAResource res2 = sess2.getXAResource();
+
+ //Pretend to be a transaction manager by interacting through the XAResources
+ Xid xid1 = new XidImple(new Uid("cadaver"), new Uid("bq1"), 666);
+ Xid xid2 = new XidImple(new Uid("dalidom"), new Uid("bq2"), 661); // TODO
+
+
+ // Send a message in each tx
+
+ res1.start(xid1, XAResource.TMNOFLAGS);
+
+ MessageProducer prod1 = sess1.createProducer(queue);
+
+ TextMessage tm1 = sess1.createTextMessage("testing1");
+
+ prod1.send(tm1);
+
+ res1.end(xid1, XAResource.TMSUCCESS);
+
+
+ res2.start(xid2, XAResource.TMNOFLAGS);
+
+ MessageProducer prod2 = sess2.createProducer(queue);
+
+ TextMessage tm2 = sess2.createTextMessage("testing2");
+
+ prod2.send(tm2);
+
+ res2.end(xid2, XAResource.TMSUCCESS);
+
+ //prepare both txs
+
+
+ res1.prepare(xid1);
+ res2.prepare(xid2);
+
+ //Now "crash" the server
+
+ ServerManagement.stopServerPeer();
+
+ ServerManagement.startServerPeer();
+
+ ServerManagement.deployQueue("Queue");
+
+
+ XAResource res = cf.createXAConnection().createXASession().getXAResource();
+
+ Xid[] xids = res.recover(XAResource.TMSTARTRSCAN);
+ assertEquals(2, xids.length);
+
+ Xid[] xids2 = res.recover(XAResource.TMENDRSCAN);
+ assertEquals(0, xids2.length);
+
+ assertTrue(xids[0].equals(xid1) || xids[1].equals(xid1));
+ assertTrue(xids[0].equals(xid2) || xids[1].equals(xid2));
+
+ res.commit(xid1, false);
+
+ res.commit(xid2, false);
+
+ conn3 = cf.createConnection();
+
+ Session sessRec = conn3.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ MessageConsumer cons = sessRec.createConsumer(queue);
+ conn3.start();
+
+ TextMessage m1 = (TextMessage)cons.receive(MAX_TIMEOUT);
+ assertNotNull(m1);
+ assertEquals("testing1", m1.getText());
+
+ TextMessage m2 = (TextMessage)cons.receive(MAX_TIMEOUT);
+ assertNotNull(m2);
+
+ assertEquals("testing2", m2.getText());
+
+ if (checkNoMessageData())
+ {
+ fail("Data remains in database");
+ }
+ }
+ finally
+ {
+ if (conn1 != null)
+ {
+ try
+ {
+ conn1.close();
+ }
+ catch (Exception e)
+ {
+ //Ignore
+ }
+ }
+
+ if (conn2 != null)
+ {
+ try
+ {
+ conn2.close();
+ }
+ catch (Exception e)
+ {
+ //Ignore
+ }
+ }
+
+ if (conn3 != null)
+ {
+ try
+ {
+ conn3.close();
+ }
+ catch (Exception e)
+ {
+ //Ignore
+ }
+ }
+ }
+ }
+
+
+ public void testMockCoordinatorRecovery3() throws Exception
+ {
+ XAConnection conn1 = null;
+
+ XAConnection conn2 = null;
+
+ Connection conn3 = null;
+
+ try
+ {
+
+ conn1 = cf.createXAConnection();
+
+ conn2 = cf.createXAConnection();
+
+ XASession sess1 = conn1.createXASession();
+
+ XASession sess2 = conn2.createXASession();
+
+ XAResource res1 = sess1.getXAResource();
+
+ XAResource res2 = sess2.getXAResource();
+
+ //Pretend to be a transaction manager by interacting through the XAResources
+ Xid xid1 = new XidImpl("bq1".getBytes(), 123, "gbtxid1".getBytes());
+ Xid xid2 = new XidImpl("bq2".getBytes(), 124, "gbtxid2".getBytes());
+
+ // Send a message in each tx
+
+ res1.start(xid1, XAResource.TMNOFLAGS);
+
+ MessageProducer prod1 = sess1.createProducer(queue);
+
+ TextMessage tm1 = sess1.createTextMessage("testing1");
+
+ prod1.send(tm1);
+
+ res1.end(xid1, XAResource.TMSUCCESS);
+
+
+ res2.start(xid2, XAResource.TMNOFLAGS);
+
+ MessageProducer prod2 = sess2.createProducer(queue);
+
+ TextMessage tm2 = sess2.createTextMessage("testing2");
+
+ prod2.send(tm2);
+
+ res2.end(xid2, XAResource.TMSUCCESS);
+
+ //prepare both txs
+
+
+ res1.prepare(xid1);
+ res2.prepare(xid2);
+
+ //Now "crash" the server
+
+ ServerManagement.stopServerPeer();
+
+ ServerManagement.startServerPeer();
+
+ ServerManagement.deployQueue("Queue");
+
+
+
+ XAResource res = cf.createXAConnection().createXASession().getXAResource();
+
+ Xid[] xids = res.recover(XAResource.TMSTARTRSCAN);
+ assertEquals(2, xids.length);
+
+ Xid[] xids2 = res.recover(XAResource.TMENDRSCAN);
+ assertEquals(0, xids2.length);
+
+ assertTrue(xids[0].equals(xid1) || xids[1].equals(xid1));
+ assertTrue(xids[0].equals(xid2) || xids[1].equals(xid2));
+
+ res.commit(xids[0], false);
+
+ res.commit(xids[1], false);
+
+ conn3 = cf.createConnection();
+
+ Session sessRec = conn3.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ MessageConsumer cons = sessRec.createConsumer(queue);
+ conn3.start();
+
+ TextMessage m1 = (TextMessage)cons.receive(MAX_TIMEOUT);
+ assertNotNull(m1);
+ assertEquals("testing1", m1.getText());
+
+ TextMessage m2 = (TextMessage)cons.receive(MAX_TIMEOUT);
+ assertNotNull(m2);
+
+ assertEquals("testing2", m2.getText());
+
+ if (checkNoMessageData())
+ {
+ fail("Data remains in database");
+ }
+ }
+ finally
+ {
+ if (conn1 != null)
+ {
+ try
+ {
+ conn1.close();
+ }
+ catch (Exception e)
+ {
+ //Ignore
+ }
+ }
+
+ if (conn2 != null)
+ {
+ try
+ {
+ conn2.close();
+ }
+ catch (Exception e)
+ {
+ //Ignore
+ }
+ }
+
+ if (conn3 != null)
+ {
+ try
+ {
+ conn3.close();
+ }
+ catch (Exception e)
+ {
+ //Ignore
+ }
+ }
+ }
+ }
+
+
+ public void testMultiChannelRecovery() throws Exception
+ {
+ XAConnection conn1 = null;
+
+ XAConnection conn2 = null;
+
+ Connection conn3 = null;
+
+ try
+ {
+
+ conn1 = cf.createXAConnection();
+
+ conn2 = cf.createXAConnection();
+
+ XASession sess1 = conn1.createXASession();
+
+ XASession sess2 = conn2.createXASession();
+
+ XAResource res1 = sess1.getXAResource();
+
+ XAResource res2 = sess2.getXAResource();
+
+ //Pretend to be a transaction manager by interacting through the XAResources
+ Xid xid1 = new XidImpl("bq1".getBytes(), 123, "gbtxid1".getBytes());
+ Xid xid2 = new XidImpl("bq2".getBytes(), 124, "gbtxid2".getBytes());
+
+ // Send a message in each tx
+
+ res1.start(xid1, XAResource.TMNOFLAGS);
+
+ MessageProducer prod1 = sess1.createProducer(queueA);
+ MessageProducer prod2 = sess1.createProducer(queueB);
+
+ TextMessage tm1 = sess1.createTextMessage("testing1");
+ TextMessage tm2 = sess1.createTextMessage("testing2");
+
+ prod1.send(tm1);
+ prod2.send(tm2);
+
+ res1.end(xid1, XAResource.TMSUCCESS);
+
+
+ res2.start(xid2, XAResource.TMNOFLAGS);
+
+ MessageProducer prod3 = sess2.createProducer(queue);
+
+ TextMessage tm3 = sess2.createTextMessage("testing3");
+
+ prod3.send(tm3);
+
+ res2.end(xid2, XAResource.TMSUCCESS);
+
+ //prepare both txs
+
+
+ res1.prepare(xid1);
+ res2.prepare(xid2);
+
+ //Now "crash" the server
+
+ ServerManagement.stopServerPeer();
+
+ ServerManagement.startServerPeer();
+
+ ServerManagement.deployQueue("Queue");
+ ServerManagement.deployQueue("QA");
+ ServerManagement.deployQueue("QB");
+
+
+
+ XAResource res = cf.createXAConnection().createXASession().getXAResource();
+
+ Xid[] xids = res.recover(XAResource.TMSTARTRSCAN);
+ assertEquals(2, xids.length);
+
+ Xid[] xids2 = res.recover(XAResource.TMENDRSCAN);
+ assertEquals(0, xids2.length);
+
+ assertTrue(xids[0].equals(xid1) || xids[1].equals(xid1));
+ assertTrue(xids[0].equals(xid2) || xids[1].equals(xid2));
+
+ res.commit(xids[0], false);
+
+ res.commit(xids[1], false);
+
+ conn3 = cf.createConnection();
+
+ Session sessRec = conn3.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ MessageConsumer cons1 = sessRec.createConsumer(queueA);
+ MessageConsumer cons2 = sessRec.createConsumer(queueB);
+ MessageConsumer cons3 = sessRec.createConsumer(queue);
+
+ conn3.start();
+
+ TextMessage m1 = (TextMessage)cons1.receive(MAX_TIMEOUT);
+ assertNotNull(m1);
+ assertEquals("testing1", m1.getText());
+
+ TextMessage m2 = (TextMessage)cons2.receive(MAX_TIMEOUT);
+ assertNotNull(m2);
+ assertEquals("testing2", m2.getText());
+
+ TextMessage m3 = (TextMessage)cons3.receive(MAX_TIMEOUT);
+ assertNotNull(m3);
+ assertEquals("testing3", m3.getText());
+
+ if (checkNoMessageData())
+ {
+ fail("Data remains in database");
+ }
+ }
+ finally
+ {
+ if (conn1 != null)
+ {
+ try
+ {
+ conn1.close();
+ }
+ catch (Exception e)
+ {
+ //Ignore
+ }
+ }
+
+ if (conn2 != null)
+ {
+ try
+ {
+ conn2.close();
+ }
+ catch (Exception e)
+ {
+ //Ignore
+ }
+ }
+
+ if (conn3 != null)
+ {
+ try
+ {
+ conn3.close();
+ }
+ catch (Exception e)
+ {
+ //Ignore
+ }
+ }
+ }
+
+ }
+
}
Modified: trunk/tests/src/org/jboss/test/messaging/jms/XATest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/XATest.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/tests/src/org/jboss/test/messaging/jms/XATest.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -41,15 +41,17 @@
import org.jboss.jms.client.JBossConnectionFactory;
import org.jboss.jms.tx.MessagingXAResource;
import org.jboss.test.messaging.MessagingTestCase;
+import org.jboss.test.messaging.util.TransactionManagerLocator;
import org.jboss.test.messaging.tools.ServerManagement;
-import org.jboss.tm.TransactionManagerLocator;
+import org.jboss.tm.TxUtils;
/**
*
* A XATest
-
+ *
* @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
* @version <tt>$Revision: 1.1 $</tt>
+ * @author <a href="mailto:juha at jboss.org">Juha Lindfors</a>
*
* $Id$
*
@@ -88,13 +90,20 @@
initialContext = new InitialContext(ServerManagement.getJNDIEnvironment());
cf = (JBossConnectionFactory)initialContext.lookup("/ConnectionFactory");
- if (!ServerManagement.isRemote()) tm = TransactionManagerLocator.getInstance().locate();
-
+ if (!ServerManagement.isRemote())
+ {
+ tm = TransactionManagerLocator.getInstance().locate();
+ }
+
ServerManagement.undeployQueue("Queue");
ServerManagement.deployQueue("Queue");
queue = (Destination)initialContext.lookup("/queue/Queue");
-
- if (!ServerManagement.isRemote()) suspendedTx = tm.suspend();
+
+
+ if (!ServerManagement.isRemote())
+ {
+ suspendedTx = tm.suspend();
+ }
}
public void tearDown() throws Exception
@@ -103,11 +112,17 @@
if (!ServerManagement.isRemote())
{
- if (tm.getTransaction() != null)
+ if (TxUtils.isUncommitted(tm))
{
//roll it back
tm.rollback();
}
+ if (tm.getTransaction() != null)
+ {
+ Transaction tx = tm.suspend();
+ if (tx != null)
+ log.warn("Transaction still associated with thread " + tx + " at status " + TxUtils.getStatusAsString(tx.getStatus()));
+ }
}
if (suspendedTx != null)
@@ -122,7 +137,6 @@
// Public --------------------------------------------------------
-
public void test2PCSendCommit1PCOptimization() throws Exception
{
@@ -134,8 +148,7 @@
Connection conn2 = null;
try
- {
-
+ {
conn = cf.createXAConnection();
tm.begin();
@@ -156,7 +169,7 @@
m = sess.createTextMessage("XATest2");
prod.send(queue, m);
- tx.commit();
+ tm.commit();
conn2 = cf.createConnection();
conn2.start();
@@ -182,50 +195,52 @@
}
}
-
+
+
+
public void test2PCSendCommit() throws Exception
{
if (ServerManagement.isRemote()) return;
-
+
XAConnection conn = null;
Connection conn2 = null;
-
+
try
{
-
+
conn = cf.createXAConnection();
-
+
tm.begin();
-
+
XASession sess = conn.createXASession();
-
- MessagingXAResource res = (MessagingXAResource)sess.getXAResource();
+
+ MessagingXAResource res = (MessagingXAResource)sess.getXAResource();
XAResource res2 = new DummyXAResource();
-
+
//To prevent 1PC optimization being used
res.setPreventJoining(true);
-
+
Transaction tx = tm.getTransaction();
tx.enlistResource(res);
tx.enlistResource(res2);
-
+
MessageProducer prod = sess.createProducer(queue);
prod.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
Message m = sess.createTextMessage("XATest1");
prod.send(queue, m);
m = sess.createTextMessage("XATest2");
prod.send(queue, m);
-
- tx.commit();
-
+
+ tm.commit();
+
conn2 = cf.createConnection();
conn2.start();
Session sessReceiver = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageConsumer cons = sessReceiver.createConsumer(queue);
- TextMessage m2 = (TextMessage)cons.receive(1000);
+ TextMessage m2 = (TextMessage)cons.receive(MAX_TIMEOUT);
assertNotNull(m2);
assertEquals("XATest1", m2.getText());
- m2 = (TextMessage)cons.receive(1000);
+ m2 = (TextMessage)cons.receive(MAX_TIMEOUT);
assertNotNull(m2);
assertEquals("XATest2", m2.getText());
}
@@ -242,47 +257,47 @@
}
}
-
-
+
+
public void test2PCSendRollback1PCOptimization() throws Exception
{
if (ServerManagement.isRemote()) return;
-
+
//Since both resources have some RM, TM will probably use 1PC optimization
-
+
XAConnection conn = null;
Connection conn2 = null;
try
{
conn = cf.createXAConnection();
-
+
tm.begin();
-
+
XASession sess = conn.createXASession();
XAResource res = sess.getXAResource();
-
+
XAResource res2 = new DummyXAResource();
-
+
Transaction tx = tm.getTransaction();
tx.enlistResource(res);
tx.enlistResource(res2);
-
+
MessageProducer prod = sess.createProducer(queue);
prod.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
Message m = sess.createTextMessage("XATest1");
- prod.send(queue, m);
+ prod.send(queue, m);
m = sess.createTextMessage("XATest2");
prod.send(queue, m);
-
- tx.rollback();
-
+
+ tm.rollback();
+
conn2 = cf.createConnection();
conn2.start();
Session sessReceiver = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageConsumer cons = sessReceiver.createConsumer(queue);
- Message m2 = cons.receive(1000);
+ Message m2 = cons.receive(MIN_TIMEOUT);
assertNull(m2);
-
+
}
finally
{
@@ -296,59 +311,61 @@
}
}
}
-
-
+
+
public void test2PCSendFailOnPrepare() throws Exception
{
if (ServerManagement.isRemote()) return;
-
+
XAConnection conn = null;
Connection conn2 = null;
try
{
conn = cf.createXAConnection();
-
+
tm.begin();
-
+
XASession sess = conn.createXASession();
MessagingXAResource res = (MessagingXAResource)sess.getXAResource();
-
+
//prevent 1Pc optimisation
res.setPreventJoining(true);
-
+
XAResource res2 = new DummyXAResource(true);
XAResource res3 = new DummyXAResource();
XAResource res4 = new DummyXAResource();
-
+
Transaction tx = tm.getTransaction();
tx.enlistResource(res);
tx.enlistResource(res2);
tx.enlistResource(res3);
tx.enlistResource(res4);
-
+
MessageProducer prod = sess.createProducer(queue);
prod.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
Message m = sess.createTextMessage("XATest1");
- prod.send(queue, m);
+ prod.send(queue, m);
m = sess.createTextMessage("XATest2");
prod.send(queue, m);
-
+
try
{
- tx.commit();
+ tm.commit();
+
+ fail("should not get here");
}
catch (Exception e)
{
//We should expect this
}
-
+
conn2 = cf.createConnection();
conn2.start();
Session sessReceiver = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageConsumer cons = sessReceiver.createConsumer(queue);
- Message m2 = cons.receive(1000);
+ Message m2 = cons.receive(MIN_TIMEOUT);
assertNull(m2);
-
+
}
finally
{
@@ -362,47 +379,47 @@
}
}
}
-
+
public void test2PCSendRollback() throws Exception
{
if (ServerManagement.isRemote()) return;
-
+
XAConnection conn = null;
Connection conn2 = null;
try
{
conn = cf.createXAConnection();
-
+
tm.begin();
-
+
XASession sess = conn.createXASession();
MessagingXAResource res = (MessagingXAResource)sess.getXAResource();
-
+
//prevent 1Pc optimisation
res.setPreventJoining(true);
-
+
XAResource res2 = new DummyXAResource();
-
+
Transaction tx = tm.getTransaction();
tx.enlistResource(res);
tx.enlistResource(res2);
-
+
MessageProducer prod = sess.createProducer(queue);
prod.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
Message m = sess.createTextMessage("XATest1");
- prod.send(queue, m);
+ prod.send(queue, m);
m = sess.createTextMessage("XATest2");
prod.send(queue, m);
-
- tx.rollback();
-
+
+ tm.rollback();
+
conn2 = cf.createConnection();
conn2.start();
Session sessReceiver = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageConsumer cons = sessReceiver.createConsumer(queue);
- Message m2 = cons.receive(1000);
+ Message m2 = cons.receive(MIN_TIMEOUT);
assertNull(m2);
-
+
}
finally
{
@@ -420,12 +437,12 @@
public void test2PCReceiveCommit1PCOptimization() throws Exception
{
if (ServerManagement.isRemote()) return;
-
+
//Since both resources have some RM, TM will probably use 1PC optimization
-
+
XAConnection conn = null;
Connection conn2 = null;
-
+
try
{
conn2 = cf.createConnection();
@@ -436,49 +453,49 @@
prod.send(m);
m = sessProducer.createTextMessage("XATest2");
prod.send(m);
-
+
conn = cf.createXAConnection();
conn.start();
-
+
tm.begin();
-
+
XASession sess = conn.createXASession();
XAResource res = sess.getXAResource();
-
+
XAResource res2 = new DummyXAResource();
-
+
Transaction tx = tm.getTransaction();
tx.enlistResource(res);
tx.enlistResource(res2);
-
+
MessageConsumer cons = sess.createConsumer(queue);
-
- TextMessage m2 = (TextMessage)cons.receive(1000);
-
+
+ TextMessage m2 = (TextMessage)cons.receive(MAX_TIMEOUT);
+
assertNotNull(m2);
assertEquals("XATest1", m2.getText());
-
- m2 = (TextMessage)cons.receive(1000);
-
+
+ m2 = (TextMessage)cons.receive(MAX_TIMEOUT);
+
assertNotNull(m2);
assertEquals("XATest2", m2.getText());
-
- tx.commit();
-
+
+ tm.commit();
+
//New tx
tm.begin();
tx = tm.getTransaction();
tx.enlistResource(res);
tx.enlistResource(res2);
-
- Message m3 = cons.receive(1000);
-
+
+ Message m3 = cons.receive(MIN_TIMEOUT);
+
assertNull(m3);
-
+
tm.commit();
-
+
}
finally
{
@@ -491,16 +508,16 @@
conn2.close();
}
}
-
+
}
-
+
public void test2PCReceiveCommit() throws Exception
{
if (ServerManagement.isRemote()) return;
-
+
XAConnection conn = null;
Connection conn2 = null;
-
+
try
{
conn2 = cf.createConnection();
@@ -511,50 +528,50 @@
prod.send(m);
m = sessProducer.createTextMessage("XATest2");
prod.send(m);
-
+
conn = cf.createXAConnection();
conn.start();
-
+
tm.begin();
-
+
XASession sess = conn.createXASession();
MessagingXAResource res = (MessagingXAResource)sess.getXAResource();
res.setPreventJoining(true);
-
+
XAResource res2 = new DummyXAResource();
-
+
Transaction tx = tm.getTransaction();
tx.enlistResource(res);
tx.enlistResource(res2);
-
+
MessageConsumer cons = sess.createConsumer(queue);
-
- TextMessage m2 = (TextMessage)cons.receive(1000);
-
+
+ TextMessage m2 = (TextMessage)cons.receive(MAX_TIMEOUT);
+
assertNotNull(m2);
assertEquals("XATest1", m2.getText());
-
- m2 = (TextMessage)cons.receive(1000);
-
+
+ m2 = (TextMessage)cons.receive(MAX_TIMEOUT);
+
assertNotNull(m2);
assertEquals("XATest2", m2.getText());
-
- tx.commit();
-
+
+ tm.commit();
+
//New tx
tm.begin();
tx = tm.getTransaction();
tx.enlistResource(res);
tx.enlistResource(res2);
-
- Message m3 = cons.receive(1000);
-
+
+ Message m3 = cons.receive(MIN_TIMEOUT);
+
assertNull(m3);
-
+
tm.commit();
-
+
}
finally
{
@@ -567,18 +584,18 @@
conn2.close();
}
}
-
+
}
-
+
public void test2PCReceiveRollback1PCOptimization() throws Exception
{
if (ServerManagement.isRemote()) return;
-
+
//Since both resources have some RM, TM will probably use 1PC optimization
-
+
XAConnection conn = null;
Connection conn2 = null;
-
+
try
{
conn2 = cf.createConnection();
@@ -586,54 +603,54 @@
MessageProducer prod = sessProducer.createProducer(queue);
Message m = sessProducer.createTextMessage("XATest1");
prod.send(m);
-
+
m = sessProducer.createTextMessage("XATest2");
prod.send(m);
-
-
+
+
conn = cf.createXAConnection();
- conn.start();
-
+ conn.start();
+
tm.begin();
-
+
XASession sess = conn.createXASession();
XAResource res = sess.getXAResource();
-
+
XAResource res2 = new DummyXAResource();
-
+
Transaction tx = tm.getTransaction();
tx.enlistResource(res);
tx.enlistResource(res2);
-
+
MessageConsumer cons = sess.createConsumer(queue);
-
- TextMessage m2 = (TextMessage)cons.receive(1000);
+
+ TextMessage m2 = (TextMessage)cons.receive(MAX_TIMEOUT);
assertNotNull(m2);
assertEquals("XATest1", m2.getText());
- m2 = (TextMessage)cons.receive(1000);
+ m2 = (TextMessage)cons.receive(MAX_TIMEOUT);
assertNotNull(m2);
assertEquals("XATest2", m2.getText());
-
- tx.rollback();
-
+
+ tm.rollback();
+
//Message should be redelivered
-
+
//New tx
tm.begin();
tx = tm.getTransaction();
tx.enlistResource(res);
tx.enlistResource(res2);
-
- TextMessage m3 = (TextMessage)cons.receive(1000);
+
+ TextMessage m3 = (TextMessage)cons.receive(MAX_TIMEOUT);
assertNotNull(m3);
assertEquals("XATest1", m3.getText());
- m3 = (TextMessage)cons.receive(1000);
+ m3 = (TextMessage)cons.receive(MAX_TIMEOUT);
assertNotNull(m3);
assertEquals("XATest2", m3.getText());
-
+
assertTrue(m3.getJMSRedelivered());
-
+
tm.commit();
}
@@ -648,16 +665,16 @@
conn2.close();
}
}
-
+
}
-
+
public void test2PCReceiveRollback() throws Exception
{
if (ServerManagement.isRemote()) return;
-
+
XAConnection conn = null;
Connection conn2 = null;
-
+
try
{
conn2 = cf.createConnection();
@@ -665,55 +682,55 @@
MessageProducer prod = sessProducer.createProducer(queue);
Message m = sessProducer.createTextMessage("XATest1");
prod.send(m);
-
+
m = sessProducer.createTextMessage("XATest2");
prod.send(m);
-
-
+
+
conn = cf.createXAConnection();
- conn.start();
-
+ conn.start();
+
tm.begin();
-
+
XASession sess = conn.createXASession();
MessagingXAResource res = (MessagingXAResource)sess.getXAResource();
res.setPreventJoining(true);
-
+
XAResource res2 = new DummyXAResource();
-
+
Transaction tx = tm.getTransaction();
tx.enlistResource(res);
tx.enlistResource(res2);
-
+
MessageConsumer cons = sess.createConsumer(queue);
-
- TextMessage m2 = (TextMessage)cons.receive(1000);
+
+ TextMessage m2 = (TextMessage)cons.receive(MAX_TIMEOUT);
assertNotNull(m2);
assertEquals("XATest1", m2.getText());
- m2 = (TextMessage)cons.receive(1000);
+ m2 = (TextMessage)cons.receive(MAX_TIMEOUT);
assertNotNull(m2);
assertEquals("XATest2", m2.getText());
-
- tx.rollback();
-
+
+ tm.rollback();
+
//Message should be redelivered
-
+
//New tx
tm.begin();
tx = tm.getTransaction();
tx.enlistResource(res);
tx.enlistResource(res2);
-
- TextMessage m3 = (TextMessage)cons.receive(1000);
+
+ TextMessage m3 = (TextMessage)cons.receive(MAX_TIMEOUT);
assertNotNull(m3);
assertEquals("XATest1", m3.getText());
- m3 = (TextMessage)cons.receive(1000);
+ m3 = (TextMessage)cons.receive(MAX_TIMEOUT);
assertNotNull(m3);
assertEquals("XATest2", m3.getText());
-
+
assertTrue(m3.getJMSRedelivered());
-
+
tm.commit();
}
@@ -728,49 +745,49 @@
conn2.close();
}
}
-
+
}
-
-
+
+
public void test1PCSendCommit() throws Exception
{
if (ServerManagement.isRemote()) return;
-
+
XAConnection conn = null;
Connection conn2 = null;
-
+
try
{
-
+
conn = cf.createXAConnection();
-
+
tm.begin();
-
+
XASession sess = conn.createXASession();
XAResource res = sess.getXAResource();
-
-
+
+
Transaction tx = tm.getTransaction();
tx.enlistResource(res);
-
+
MessageProducer prod = sess.createProducer(queue);
prod.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
Message m = sess.createTextMessage("XATest1");
prod.send(queue, m);
m = sess.createTextMessage("XATest2");
prod.send(queue, m);
-
- tx.commit();
-
+
+ tm.commit();
+
conn2 = cf.createConnection();
conn2.start();
Session sessReceiver = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageConsumer cons = sessReceiver.createConsumer(queue);
- TextMessage m2 = (TextMessage)cons.receive(1000);
+ TextMessage m2 = (TextMessage)cons.receive(MAX_TIMEOUT);
assertNotNull(m2);
assertEquals("XATest1", m2.getText());
- m2 = (TextMessage)cons.receive(1000);
+ m2 = (TextMessage)cons.receive(MAX_TIMEOUT);
assertNotNull(m2);
assertEquals("XATest2", m2.getText());
}
@@ -787,20 +804,20 @@
}
}
-
-
+
+
public void test1PCSendRollback() throws Exception
{
if (ServerManagement.isRemote()) return;
-
+
XAConnection conn = null;
Connection conn2 = null;
try
{
conn = cf.createXAConnection();
-
+
tm.begin();
-
+
XASession sess = conn.createXASession();
XAResource res = sess.getXAResource();
@@ -810,19 +827,19 @@
MessageProducer prod = sess.createProducer(queue);
prod.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
Message m = sess.createTextMessage("XATest1");
- prod.send(queue, m);
+ prod.send(queue, m);
m = sess.createTextMessage("XATest2");
- prod.send(queue, m);
-
- tx.rollback();
-
+ prod.send(queue, m);
+
+ tm.rollback();
+
conn2 = cf.createConnection();
conn2.start();
Session sessReceiver = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageConsumer cons = sessReceiver.createConsumer(queue);
- Message m2 = cons.receive(1000);
+ Message m2 = cons.receive(MIN_TIMEOUT);
assertNull(m2);
-
+
}
finally
{
@@ -840,10 +857,10 @@
public void test1PCReceiveCommit() throws Exception
{
if (ServerManagement.isRemote()) return;
-
+
XAConnection conn = null;
Connection conn2 = null;
-
+
try
{
conn2 = cf.createConnection();
@@ -854,44 +871,44 @@
prod.send(m);
m = sessProducer.createTextMessage("XATest2");
prod.send(m);
-
+
conn = cf.createXAConnection();
conn.start();
-
+
tm.begin();
-
+
XASession sess = conn.createXASession();
XAResource res = sess.getXAResource();
-
+
Transaction tx = tm.getTransaction();
tx.enlistResource(res);
-
+
MessageConsumer cons = sess.createConsumer(queue);
-
- TextMessage m2 = (TextMessage)cons.receive(1000);
-
+
+ TextMessage m2 = (TextMessage)cons.receive(MAX_TIMEOUT);
+
assertNotNull(m2);
assertEquals("XATest1", m2.getText());
- m2 = (TextMessage)cons.receive(1000);
-
+ m2 = (TextMessage)cons.receive(MAX_TIMEOUT);
+
assertNotNull(m2);
assertEquals("XATest2", m2.getText());
-
- tx.commit();
-
+
+ tm.commit();
+
//New tx
tm.begin();
tx = tm.getTransaction();
tx.enlistResource(res);
-
- Message m3 = cons.receive(1000);
-
+
+ Message m3 = cons.receive(MIN_TIMEOUT);
+
assertNull(m3);
-
+
tm.commit();
-
+
}
finally
{
@@ -904,16 +921,16 @@
conn2.close();
}
}
-
+
}
-
+
public void test1PCReceiveRollback() throws Exception
{
if (ServerManagement.isRemote()) return;
-
+
XAConnection conn = null;
Connection conn2 = null;
-
+
try
{
conn2 = cf.createConnection();
@@ -923,53 +940,53 @@
prod.send(m);
m = sessProducer.createTextMessage("XATest2");
prod.send(m);
-
-
+
+
conn = cf.createXAConnection();
- conn.start();
-
+ conn.start();
+
tm.begin();
-
+
XASession sess = conn.createXASession();
XAResource res = sess.getXAResource();
-
+
Transaction tx = tm.getTransaction();
tx.enlistResource(res);
MessageConsumer cons = sess.createConsumer(queue);
-
- TextMessage m2 = (TextMessage)cons.receive(1000);
-
+
+ TextMessage m2 = (TextMessage)cons.receive(MAX_TIMEOUT);
+
assertNotNull(m2);
assertEquals("XATest1", m2.getText());
-
- m2 = (TextMessage)cons.receive(1000);
-
+
+ m2 = (TextMessage)cons.receive(MAX_TIMEOUT);
+
assertNotNull(m2);
assertEquals("XATest2", m2.getText());
-
- tx.rollback();
-
+
+ tm.rollback();
+
//Message should be redelivered
-
+
//New tx
tm.begin();
tx = tm.getTransaction();
tx.enlistResource(res);
-
- TextMessage m3 = (TextMessage)cons.receive(1000);
-
+
+ TextMessage m3 = (TextMessage)cons.receive(MAX_TIMEOUT);
+
assertNotNull(m3);
assertEquals("XATest1", m3.getText());
-
- m3 = (TextMessage)cons.receive(1000);
-
+
+ m3 = (TextMessage)cons.receive(MAX_TIMEOUT);
+
assertNotNull(m3);
assertEquals("XATest2", m3.getText());
-
+
assertTrue(m3.getJMSRedelivered());
-
+
tm.commit();
}
@@ -984,18 +1001,18 @@
conn2.close();
}
}
-
+
}
-
+
public void testMultipleSessionsOneTxCommitAcknowledge1PCOptimization() throws Exception
{
if (ServerManagement.isRemote()) return;
-
+
XAConnection conn = null;
Connection conn2 = null;
-
+
//Since both resources have some RM, TM will probably use 1PC optimization
-
+
try
{
//First send 2 messages
@@ -1006,49 +1023,47 @@
prod.send(m);
m = sessProducer.createTextMessage("jellyfish2");
prod.send(m);
-
-
+
+
conn = cf.createXAConnection();
- conn.start();
-
+ conn.start();
+
tm.begin();
-
+
//Create 2 sessions and enlist them
XASession sess1 = conn.createXASession();
XAResource res1 = sess1.getXAResource();
XASession sess2 = conn.createXASession();
XAResource res2 = sess2.getXAResource();
-
+
Transaction tx = tm.getTransaction();
tx.enlistResource(res1);
tx.enlistResource(res2);
-
+
//Receive the messages, one on each consumer
MessageConsumer cons1 = sess1.createConsumer(queue);
- TextMessage r1 = (TextMessage)cons1.receive(1000);
-
+ TextMessage r1 = (TextMessage)cons1.receive(MAX_TIMEOUT);
+
assertNotNull(r1);
assertEquals("jellyfish1", r1.getText());
-
+
cons1.close();
-
+
MessageConsumer cons2 = sess2.createConsumer(queue);
- TextMessage r2 = (TextMessage)cons2.receive(1000);
-
+ TextMessage r2 = (TextMessage)cons2.receive(MAX_TIMEOUT);
+
assertNotNull(r2);
assertEquals("jellyfish2", r2.getText());
-
- //commit
- tx.commit();
-
+
+ //commit
+ tm.commit();
+
Session sess = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageConsumer cons = sess.createConsumer(queue);
conn2.start();
-
- TextMessage r3 = (TextMessage)cons.receive(1000);
+
+ TextMessage r3 = (TextMessage)cons.receive(MIN_TIMEOUT);
assertNull(r3);
-
-
}
finally
@@ -1062,16 +1077,16 @@
conn2.close();
}
}
-
+
}
-
+
public void testMultipleSessionsOneTxCommitAcknowledge() throws Exception
{
if (ServerManagement.isRemote()) return;
-
+
XAConnection conn = null;
Connection conn2 = null;
-
+
try
{
//First send 2 messages
@@ -1082,13 +1097,13 @@
prod.send(m);
m = sessProducer.createTextMessage("jellyfish2");
prod.send(m);
-
-
+
+
conn = cf.createXAConnection();
- conn.start();
-
+ conn.start();
+
tm.begin();
-
+
//Create 2 sessions and enlist them
XASession sess1 = conn.createXASession();
MessagingXAResource res1 = (MessagingXAResource)sess1.getXAResource();
@@ -1096,36 +1111,36 @@
MessagingXAResource res2 = (MessagingXAResource)sess2.getXAResource();
res1.setPreventJoining(true);
res2.setPreventJoining(true);
-
+
Transaction tx = tm.getTransaction();
tx.enlistResource(res1);
tx.enlistResource(res2);
-
+
//Receive the messages, one on each consumer
MessageConsumer cons1 = sess1.createConsumer(queue);
- TextMessage r1 = (TextMessage)cons1.receive(1000);
-
+ TextMessage r1 = (TextMessage)cons1.receive(MAX_TIMEOUT);
+
assertNotNull(r1);
assertEquals("jellyfish1", r1.getText());
-
+
cons1.close();
-
+
MessageConsumer cons2 = sess2.createConsumer(queue);
- TextMessage r2 = (TextMessage)cons2.receive(1000);
-
+ TextMessage r2 = (TextMessage)cons2.receive(MAX_TIMEOUT);
+
assertNotNull(r2);
assertEquals("jellyfish2", r2.getText());
-
- //commit
- tx.commit();
-
+
+ //commit
+ tm.commit();
+
Session sess = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageConsumer cons = sess.createConsumer(queue);
conn2.start();
-
- TextMessage r3 = (TextMessage)cons.receive(1000);
+
+ TextMessage r3 = (TextMessage)cons.receive(MIN_TIMEOUT);
assertNull(r3);
-
+
}
finally
{
@@ -1138,19 +1153,19 @@
conn2.close();
}
}
-
+
}
-
-
+
+
public void testMultipleSessionsOneTxRollbackAcknowledge1PCOptimization() throws Exception
{
if (ServerManagement.isRemote()) return;
-
+
XAConnection conn = null;
Connection conn2 = null;
-
+
//Since both resources have some RM, TM will probably use 1PC optimization
-
+
try
{
//First send 2 messages
@@ -1165,74 +1180,128 @@
prod.send(m);
m = sessProducer.createTextMessage("jellyfish4");
prod.send(m);
-
-
+
+
conn = cf.createXAConnection();
- conn.start();
-
+ conn.start();
+
tm.begin();
-
+
//Create 2 sessions and enlist them
XASession sess1 = conn.createXASession();
MessagingXAResource res1 = (MessagingXAResource)sess1.getXAResource();
XASession sess2 = conn.createXASession();
MessagingXAResource res2 = (MessagingXAResource)sess2.getXAResource();
-
+
Transaction tx = tm.getTransaction();
tx.enlistResource(res1);
tx.enlistResource(res2);
-
+
//Receive the messages, two on each consumer
MessageConsumer cons1 = sess1.createConsumer(queue);
- TextMessage r1 = (TextMessage)cons1.receive(1000);
-
+ TextMessage r1 = (TextMessage)cons1.receive(MAX_TIMEOUT);
+
assertNotNull(r1);
assertEquals("jellyfish1", r1.getText());
-
- r1 = (TextMessage)cons1.receive(1000);
-
+
+ r1 = (TextMessage)cons1.receive(MAX_TIMEOUT);
+
assertNotNull(r1);
assertEquals("jellyfish2", r1.getText());
-
+
cons1.close();
-
+
MessageConsumer cons2 = sess2.createConsumer(queue);
- TextMessage r2 = (TextMessage)cons2.receive(1000);
-
+ TextMessage r2 = (TextMessage)cons2.receive(MAX_TIMEOUT);
+
assertNotNull(r2);
assertEquals("jellyfish3", r2.getText());
-
- r2 = (TextMessage)cons2.receive(1000);
-
+
+ r2 = (TextMessage)cons2.receive(MAX_TIMEOUT);
+
assertNotNull(r2);
assertEquals("jellyfish4", r2.getText());
+
+ cons2.close();
+
+ //rollback
+
+ tm.rollback();
+
+ //Rollback causes cancel which is asynch
+ Thread.sleep(1000);
- cons2.close();
+ //We cannot assume anything about the order in which the transaction manager rollsback
+ //the sessions - this is implementation dependent
+
+ Session sess = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ MessageConsumer cons = sess.createConsumer(queue);
+ conn2.start();
- //rollback
+ TextMessage r = (TextMessage)cons.receive(MAX_TIMEOUT);
+ assertNotNull(r);
- tx.rollback();
+ boolean session1First = false;
- Session sess = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE);
- MessageConsumer cons = sess.createConsumer(queue);
- conn2.start();
+ if (r.getText().equals("jellyfish1"))
+ {
+ session1First = true;
+ }
+ else if (r.getText().equals("jellyfish3"))
+ {
+ session1First = false;
+ }
+ else
+ {
+ fail("Unexpected message");
+ }
- TextMessage r3 = (TextMessage)cons.receive(1000);
- assertNotNull(r3);
- assertEquals("jellyfish1", r3.getText());
+ if (session1First)
+ {
+ r = (TextMessage)cons.receive(MAX_TIMEOUT);
+
+ assertNotNull(r);
+
+ assertEquals("jellyfish2", r.getText());
+
+ r = (TextMessage)cons.receive(MAX_TIMEOUT);
+
+ assertNotNull(r);
+
+ assertEquals("jellyfish3", r.getText());
+
+ r = (TextMessage)cons.receive(MAX_TIMEOUT);
+
+ assertNotNull(r);
+
+ assertEquals("jellyfish4", r.getText());
+
+
+ }
+ else
+ {
+ r = (TextMessage)cons.receive(MAX_TIMEOUT);
+
+ assertNotNull(r);
+
+ assertEquals("jellyfish4", r.getText());
+
+ r = (TextMessage)cons.receive(MAX_TIMEOUT);
+
+ assertNotNull(r);
+
+ assertEquals("jellyfish1", r.getText());
+
+ r = (TextMessage)cons.receive(MAX_TIMEOUT);
+
+ assertNotNull(r);
+
+ assertEquals("jellyfish2", r.getText());
+ }
- r3 = (TextMessage)cons.receive(1000);
- assertNotNull(r3);
- assertEquals("jellyfish2", r3.getText());
-
- TextMessage r4 = (TextMessage)cons.receive(1000);
- assertNotNull(r4);
- assertEquals("jellyfish3", r4.getText());
-
- r4 = (TextMessage)cons.receive(1000);
- assertNotNull(r4);
- assertEquals("jellyfish4", r4.getText());
+ r = (TextMessage)cons.receive(MIN_TIMEOUT);
+ assertNull(r);
}
finally
@@ -1246,13 +1315,13 @@
conn2.close();
}
}
-
+
}
-
+
public void testMultipleSessionsOneTxRollbackAcknowledge() throws Exception
{
if (ServerManagement.isRemote()) return;
-
+
XAConnection conn = null;
Connection conn2 = null;
@@ -1270,13 +1339,13 @@
prod.send(m);
m = sessProducer.createTextMessage("jellyfish4");
prod.send(m);
-
-
+
+
conn = cf.createXAConnection();
- conn.start();
-
+ conn.start();
+
tm.begin();
-
+
//Create 2 sessions and enlist them
XASession sess1 = conn.createXASession();
MessagingXAResource res1 = (MessagingXAResource)sess1.getXAResource();
@@ -1284,69 +1353,119 @@
MessagingXAResource res2 = (MessagingXAResource)sess2.getXAResource();
res1.setPreventJoining(true);
res2.setPreventJoining(true);
-
+
Transaction tx = tm.getTransaction();
tx.enlistResource(res1);
tx.enlistResource(res2);
-
+
//Receive the messages, two on each consumer
MessageConsumer cons1 = sess1.createConsumer(queue);
- TextMessage r1 = (TextMessage)cons1.receive(1000);
-
+ TextMessage r1 = (TextMessage)cons1.receive(MAX_TIMEOUT);
+
assertNotNull(r1);
assertEquals("jellyfish1", r1.getText());
-
- r1 = (TextMessage)cons1.receive(1000);
-
+
+ r1 = (TextMessage)cons1.receive(MAX_TIMEOUT);
+
assertNotNull(r1);
assertEquals("jellyfish2", r1.getText());
-
+
cons1.close();
-
+
MessageConsumer cons2 = sess2.createConsumer(queue);
- TextMessage r2 = (TextMessage)cons2.receive(1000);
-
+ TextMessage r2 = (TextMessage)cons2.receive(MAX_TIMEOUT);
+
assertNotNull(r2);
assertEquals("jellyfish3", r2.getText());
-
- r2 = (TextMessage)cons2.receive(1000);
-
+
+ r2 = (TextMessage)cons2.receive(MAX_TIMEOUT);
+
assertNotNull(r2);
assertEquals("jellyfish4", r2.getText());
-
- //rollback
-
+
+ //rollback
+
cons2.close();
+
+ tm.rollback();
- tx.rollback();
+ // Rollback causes cancel which is asynch
+ Thread.sleep(1000);
+ //We cannot assume anything about the order in which the transaction manager rollsback
+ //the sessions - this is implementation dependent
+
+
Session sess = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageConsumer cons = sess.createConsumer(queue);
conn2.start();
+
+ TextMessage r = (TextMessage)cons.receive(MAX_TIMEOUT);
+ assertNotNull(r);
- //NOTE
- //The order here is actually probably dependent on the transaction manager implementation
- //In this case, rollback will be called on each session, but whether it is called first on res1
- //or res2 determines the order the messages are put back in the queue
- //This test assumes it is called in order res1, res2
+ boolean session1First = false;
- TextMessage r3 = (TextMessage)cons.receive(1000);
- assertNotNull(r3);
- assertEquals("jellyfish3", r3.getText());
+ if (r.getText().equals("jellyfish1"))
+ {
+ session1First = true;
+ }
+ else if (r.getText().equals("jellyfish3"))
+ {
+ session1First = false;
+ }
+ else
+ {
+ fail("Unexpected message");
+ }
- r3 = (TextMessage)cons.receive(1000);
- assertNotNull(r3);
- assertEquals("jellyfish4", r3.getText());
-
- TextMessage r4 = (TextMessage)cons.receive(1000);
- assertNotNull(r4);
- assertEquals("jellyfish1", r4.getText());
-
- r4 = (TextMessage)cons.receive(1000);
- assertNotNull(r4);
- assertEquals("jellyfish2", r4.getText());
+ if (session1First)
+ {
+ r = (TextMessage)cons.receive(MAX_TIMEOUT);
+
+ assertNotNull(r);
+
+ assertEquals("jellyfish2", r.getText());
+
+ r = (TextMessage)cons.receive(MAX_TIMEOUT);
+
+ assertNotNull(r);
+
+ assertEquals("jellyfish3", r.getText());
+
+ r = (TextMessage)cons.receive(MAX_TIMEOUT);
+
+ assertNotNull(r);
+
+ assertEquals("jellyfish4", r.getText());
+
+
+ }
+ else
+ {
+ r = (TextMessage)cons.receive(MAX_TIMEOUT);
+
+ assertNotNull(r);
+
+ assertEquals("jellyfish4", r.getText());
+
+ r = (TextMessage)cons.receive(MAX_TIMEOUT);
+
+ assertNotNull(r);
+
+ assertEquals("jellyfish1", r.getText());
+
+ r = (TextMessage)cons.receive(MAX_TIMEOUT);
+
+ assertNotNull(r);
+
+ assertEquals("jellyfish2", r.getText());
+ }
+ r = (TextMessage)cons.receive(MIN_TIMEOUT);
+
+ assertNull(r);
+
}
finally
{
@@ -1359,13 +1478,13 @@
conn2.close();
}
}
-
+
}
-
+
public void testMultipleSessionsOneTxRollbackAcknowledgeForceFailureInCommit() throws Exception
{
if (ServerManagement.isRemote()) return;
-
+
XAConnection conn = null;
Connection conn2 = null;
@@ -1375,6 +1494,7 @@
conn2 = cf.createConnection();
Session sessProducer = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer prod = sessProducer.createProducer(queue);
+
Message m = sessProducer.createTextMessage("jellyfish1");
prod.send(m);
m = sessProducer.createTextMessage("jellyfish2");
@@ -1383,79 +1503,101 @@
prod.send(m);
m = sessProducer.createTextMessage("jellyfish4");
prod.send(m);
-
-
+
conn = cf.createXAConnection();
- conn.start();
+ conn.start();
tm.begin();
-
+
XASession sess1 = conn.createXASession();
MessagingXAResource res1 = (MessagingXAResource)sess1.getXAResource();
DummyXAResource res2 = new DummyXAResource(true);
res1.setPreventJoining(true);
-
+
Transaction tx = tm.getTransaction();
tx.enlistResource(res1);
tx.enlistResource(res2);
-
+
MessageConsumer cons1 = sess1.createConsumer(queue);
- TextMessage r1 = (TextMessage)cons1.receive(1000);
-
+ TextMessage r1 = (TextMessage)cons1.receive(MAX_TIMEOUT);
+
assertNotNull(r1);
assertEquals("jellyfish1", r1.getText());
-
- r1 = (TextMessage)cons1.receive(1000);
-
+
+ r1 = (TextMessage)cons1.receive(MAX_TIMEOUT);
+
assertNotNull(r1);
assertEquals("jellyfish2", r1.getText());
-
- r1 = (TextMessage)cons1.receive(1000);
-
+
+ r1 = (TextMessage)cons1.receive(MAX_TIMEOUT);
+
assertNotNull(r1);
assertEquals("jellyfish3", r1.getText());
+
+ r1 = (TextMessage)cons1.receive(MAX_TIMEOUT);
+
+ assertNotNull(r1);
+ assertEquals("jellyfish4", r1.getText());
r1 = (TextMessage)cons1.receive(1000);
- assertNotNull(r1);
- assertEquals("jellyfish4", r1.getText());
-
+ assertNull(r1);
+
cons1.close();
+
+
+ //try and commit - and we're going to make the dummyxaresource throw an exception on commit,
+ //which should cause rollback to be called on the other resource
-
- //try and commit - and we're going to make the dummyxaresource throw an exception on commit,
- //which should cause rollback to be called on the other resource
+ //rollback will cause an attemp to deliver messages locally to the original consumers.
+ //the original consumer has closed, so it will cancelled to the server
+ //the server cancel is asynch, so we need to sleep for a bit to make sure it completes
+ log.trace("Forcing failure");
try
{
- tx.commit();
+ tm.commit();
+ fail("should not get here");
}
catch (Exception e)
{
//We should expect this
}
+ Thread.sleep(1000);
+
+
Session sess = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageConsumer cons = sess.createConsumer(queue);
conn2.start();
-
- TextMessage r3 = (TextMessage)cons.receive(1000);
- assertNotNull(r3);
- assertEquals("jellyfish1", r3.getText());
+
+ TextMessage r = (TextMessage)cons.receive(MAX_TIMEOUT);
- r3 = (TextMessage)cons.receive(1000);
- assertNotNull(r3);
- assertEquals("jellyfish2", r3.getText());
-
- TextMessage r4 = (TextMessage)cons.receive(1000);
- assertNotNull(r4);
- assertEquals("jellyfish3", r4.getText());
-
- r4 = (TextMessage)cons.receive(1000);
- assertNotNull(r4);
- assertEquals("jellyfish4", r4.getText());
+ assertNotNull(r);
-
+ assertEquals("jellyfish1", r.getText());
+
+ r = (TextMessage)cons.receive(MAX_TIMEOUT);
+
+ assertNotNull(r);
+
+ assertEquals("jellyfish2", r.getText());
+
+ r = (TextMessage)cons.receive(MAX_TIMEOUT);
+
+ assertNotNull(r);
+
+ assertEquals("jellyfish3", r.getText());
+
+ r = (TextMessage)cons.receive(MAX_TIMEOUT);
+
+ assertNotNull(r);
+
+ assertEquals("jellyfish4", r.getText());
+
+ r = (TextMessage)cons.receive(MIN_TIMEOUT);
+
+ assertNull(r);
}
finally
{
@@ -1468,60 +1610,59 @@
conn2.close();
}
}
-
+
}
-
+
public void testMultipleSessionsOneTxCommitSend1PCOptimization() throws Exception
{
if (ServerManagement.isRemote()) return;
-
+
//Since both resources have some RM, TM will probably use 1PC optimization
-
+
XAConnection conn = null;
-
+
Connection conn2 = null;
-
+
try
{
-
conn = cf.createXAConnection();
- conn.start();
-
+ conn.start();
+
tm.begin();
-
+
//Create 2 sessions and enlist them
XASession sess1 = conn.createXASession();
XAResource res1 = sess1.getXAResource();
XASession sess2 = conn.createXASession();
XAResource res2 = sess2.getXAResource();
-
+
Transaction tx = tm.getTransaction();
tx.enlistResource(res1);
tx.enlistResource(res2);
-
+
// Send 2 messages - one from each session
-
+
MessageProducer prod1 = sess1.createProducer(queue);
MessageProducer prod2 = sess2.createProducer(queue);
-
+
prod1.send(sess1.createTextMessage("echidna1"));
prod2.send(sess2.createTextMessage("echidna2"));
-
+
//commit
- tx.commit();
-
+ tm.commit();
+
//Messages should be in queue
-
+
conn2 = cf.createConnection();
Session sess = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageConsumer cons = sess.createConsumer(queue);
conn2.start();
-
- TextMessage r1 = (TextMessage)cons.receive(1000);
+
+ TextMessage r1 = (TextMessage)cons.receive(MAX_TIMEOUT);
assertNotNull(r1);
assertEquals("echidna1", r1.getText());
-
- TextMessage r2 = (TextMessage)cons.receive(1000);
+
+ TextMessage r2 = (TextMessage)cons.receive(MAX_TIMEOUT);
assertNotNull(r2);
assertEquals("echidna2", r2.getText());
@@ -1538,27 +1679,27 @@
}
}
-
+
}
-
+
public void testMultipleSessionsOneTxCommitSend() throws Exception
{
if (ServerManagement.isRemote()) return;
-
+
//Since both resources have some RM, TM will probably use 1PC optimization
-
+
XAConnection conn = null;
-
+
Connection conn2 = null;
-
+
try
{
-
+
conn = cf.createXAConnection();
- conn.start();
-
+ conn.start();
+
tm.begin();
-
+
//Create 2 sessions and enlist them
XASession sess1 = conn.createXASession();
MessagingXAResource res1 = (MessagingXAResource)sess1.getXAResource();
@@ -1566,34 +1707,34 @@
MessagingXAResource res2 = (MessagingXAResource)sess2.getXAResource();
res1.setPreventJoining(true);
res2.setPreventJoining(true);
-
+
Transaction tx = tm.getTransaction();
tx.enlistResource(res1);
tx.enlistResource(res2);
-
+
// Send 2 messages - one from each session
-
+
MessageProducer prod1 = sess1.createProducer(queue);
MessageProducer prod2 = sess2.createProducer(queue);
-
+
prod1.send(sess1.createTextMessage("echidna1"));
prod2.send(sess2.createTextMessage("echidna2"));
-
+
//commit
- tx.commit();
-
+ tm.commit();
+
//Messages should be in queue
-
+
conn2 = cf.createConnection();
Session sess = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageConsumer cons = sess.createConsumer(queue);
conn2.start();
-
- TextMessage r1 = (TextMessage)cons.receive(1000);
+
+ TextMessage r1 = (TextMessage)cons.receive(MAX_TIMEOUT);
assertNotNull(r1);
assertEquals("echidna1", r1.getText());
-
- TextMessage r2 = (TextMessage)cons.receive(1000);
+
+ TextMessage r2 = (TextMessage)cons.receive(MAX_TIMEOUT);
assertNotNull(r2);
assertEquals("echidna2", r2.getText());
@@ -1610,60 +1751,60 @@
}
}
-
+
}
-
-
+
+
public void testMultipleSessionsOneTxRollbackSend1PCOptimization() throws Exception
{
if (ServerManagement.isRemote()) return;
-
+
//Since both resources have some RM, TM will probably use 1PC optimization
-
+
XAConnection conn = null;
-
+
Connection conn2 = null;
-
+
try
{
-
+
conn = cf.createXAConnection();
- conn.start();
-
+ conn.start();
+
tm.begin();
-
+
//Create 2 sessions and enlist them
XASession sess1 = conn.createXASession();
XAResource res1 = sess1.getXAResource();
XASession sess2 = conn.createXASession();
XAResource res2 = sess2.getXAResource();
-
+
Transaction tx = tm.getTransaction();
tx.enlistResource(res1);
tx.enlistResource(res2);
-
+
// Send 2 messages - one from each session
-
+
MessageProducer prod1 = sess1.createProducer(queue);
MessageProducer prod2 = sess2.createProducer(queue);
-
+
prod1.send(sess1.createTextMessage("echidna1"));
prod2.send(sess2.createTextMessage("echidna2"));
-
+
//rollback
- tx.rollback();
-
+ tm.rollback();
+
//Messages should not be in queue
-
+
conn2 = cf.createConnection();
Session sess = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageConsumer cons = sess.createConsumer(queue);
conn2.start();
-
- TextMessage r1 = (TextMessage)cons.receive(1000);
+
+ TextMessage r1 = (TextMessage)cons.receive(MIN_TIMEOUT);
assertNull(r1);
-
+
}
finally
{
@@ -1677,25 +1818,25 @@
}
}
-
+
}
-
+
public void testMultipleSessionsOneTxRollbackSend() throws Exception
{
if (ServerManagement.isRemote()) return;
-
+
XAConnection conn = null;
-
+
Connection conn2 = null;
-
+
try
{
-
+
conn = cf.createXAConnection();
- conn.start();
-
+ conn.start();
+
tm.begin();
-
+
//Create 2 sessions and enlist them
XASession sess1 = conn.createXASession();
MessagingXAResource res1 = (MessagingXAResource)sess1.getXAResource();
@@ -1703,33 +1844,33 @@
MessagingXAResource res2 = (MessagingXAResource)sess2.getXAResource();
res1.setPreventJoining(true);
res2.setPreventJoining(true);
-
+
Transaction tx = tm.getTransaction();
tx.enlistResource(res1);
tx.enlistResource(res2);
-
+
// Send 2 messages - one from each session
-
+
MessageProducer prod1 = sess1.createProducer(queue);
MessageProducer prod2 = sess2.createProducer(queue);
-
+
prod1.send(sess1.createTextMessage("echidna1"));
prod2.send(sess2.createTextMessage("echidna2"));
-
+
//rollback
- tx.rollback();
-
+ tm.rollback();
+
//Messages should not be in queue
-
+
conn2 = cf.createConnection();
Session sess = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageConsumer cons = sess.createConsumer(queue);
conn2.start();
-
- TextMessage r1 = (TextMessage)cons.receive(1000);
+
+ TextMessage r1 = (TextMessage)cons.receive(MIN_TIMEOUT);
assertNull(r1);
-
+
}
finally
{
@@ -1743,20 +1884,20 @@
}
}
-
+
}
-
-
+
+
public void testOneSessionTwoTransactionsCommitAcknowledge() throws Exception
{
if (ServerManagement.isRemote()) return;
-
+
XAConnection conn = null;
-
+
Connection conn2 = null;
-
+
try
- {
+ {
//First send 2 messages
conn2 = cf.createConnection();
Session sessProducer = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE);
@@ -1765,56 +1906,56 @@
prod.send(m);
m = sessProducer.createTextMessage("jellyfish2");
prod.send(m);
-
+
conn = cf.createXAConnection();
//Create a session
XASession sess1 = conn.createXASession();
XAResource res1 = sess1.getXAResource();
-
+
conn.start();
MessageConsumer cons1 = sess1.createConsumer(queue);
-
+
tm.begin();
-
+
Transaction tx1 = tm.getTransaction();
tx1.enlistResource(res1);
-
+
//Receive one message in one tx
-
- TextMessage r1 = (TextMessage)cons1.receive(1000);
+
+ TextMessage r1 = (TextMessage)cons1.receive(MAX_TIMEOUT);
assertNotNull(r1);
assertEquals("jellyfish1", r1.getText());
-
+
//suspend the tx
Transaction suspended = tm.suspend();
-
+
tm.begin();
-
+
Transaction tx2 = tm.getTransaction();
tx2.enlistResource(res1);
-
+
//Receive 2nd message in a different tx
- TextMessage r2 = (TextMessage)cons1.receive(1000);
+ TextMessage r2 = (TextMessage)cons1.receive(MAX_TIMEOUT);
assertNotNull(r2);
assertEquals("jellyfish2", r2.getText());
-
+
//commit this transaction
- tx2.commit();
-
+ tm.commit();
+
//verify that no messages are available
conn2 = cf.createConnection();
Session sess = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE);
conn2.start();
MessageConsumer cons = sess.createConsumer(queue);
- TextMessage r3 = (TextMessage)cons.receive(1000);
+ TextMessage r3 = (TextMessage)cons.receive(MIN_TIMEOUT);
assertNull(r3);
-
+
//now resume the first tx and then commit it
tm.resume(suspended);
- suspended.commit();
-
+ tm.commit();
+
}
finally
{
@@ -1828,20 +1969,20 @@
}
}
-
+
}
-
-
+
+
public void testOneSessionTwoTransactionsRollbackAcknowledge() throws Exception
{
if (ServerManagement.isRemote()) return;
-
+
XAConnection conn = null;
-
+
Connection conn2 = null;
-
+
try
- {
+ {
//First send 2 messages
conn2 = cf.createConnection();
Session sessProducer = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE);
@@ -1850,70 +1991,70 @@
prod.send(m);
m = sessProducer.createTextMessage("jellyfish2");
prod.send(m);
-
+
conn = cf.createXAConnection();
//Create a session
XASession sess1 = conn.createXASession();
XAResource res1 = sess1.getXAResource();
-
+
conn.start();
MessageConsumer cons1 = sess1.createConsumer(queue);
-
+
tm.begin();
-
+
Transaction tx1 = tm.getTransaction();
tx1.enlistResource(res1);
-
+
//Receive one message in one tx
-
- TextMessage r1 = (TextMessage)cons1.receive(1000);
+
+ TextMessage r1 = (TextMessage)cons1.receive(MAX_TIMEOUT);
assertNotNull(r1);
assertEquals("jellyfish1", r1.getText());
-
+
//suspend the tx
Transaction suspended = tm.suspend();
-
+
tm.begin();
-
+
Transaction tx2 = tm.getTransaction();
tx2.enlistResource(res1);
-
+
//Receive 2nd message in a different tx
- TextMessage r2 = (TextMessage)cons1.receive(1000);
+ TextMessage r2 = (TextMessage)cons1.receive(MAX_TIMEOUT);
assertNotNull(r2);
assertEquals("jellyfish2", r2.getText());
-
+
cons1.close();
-
+
//rollback this transaction
- tx2.rollback();
-
+ tm.rollback();
+
//verify that second message is available
conn2 = cf.createConnection();
Session sess = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE);
conn2.start();
MessageConsumer cons = sess.createConsumer(queue);
- TextMessage r3 = (TextMessage)cons.receive(1000);
+ TextMessage r3 = (TextMessage)cons.receive(MAX_TIMEOUT);
assertNotNull(r3);
assertEquals("jellyfish2", r3.getText());
- r3 = (TextMessage)cons.receive(1000);
+ r3 = (TextMessage)cons.receive(MIN_TIMEOUT);
assertNull(r3);
-
-
+
+
//rollback the other tx
tm.resume(suspended);
- suspended.rollback();
-
+ tm.rollback();
+
//Verify the first message is now available
- r3 = (TextMessage)cons.receive(1000);
+ r3 = (TextMessage)cons.receive(MAX_TIMEOUT);
assertNotNull(r3);
assertEquals("jellyfish1", r3.getText());
- r3 = (TextMessage)cons.receive(1000);
+ r3 = (TextMessage)cons.receive(MIN_TIMEOUT);
assertNull(r3);
-
+
}
finally
{
@@ -1927,72 +2068,72 @@
}
}
-
+
}
-
+
public void testOneSessionTwoTransactionsCommitSend() throws Exception
{
if (ServerManagement.isRemote()) return;
-
+
XAConnection conn = null;
-
+
Connection conn2 = null;
-
+
try
{
-
+
conn = cf.createXAConnection();
//Create a session
XASession sess1 = conn.createXASession();
XAResource res1 = sess1.getXAResource();
-
+
MessageProducer prod1 = sess1.createProducer(queue);
-
+
tm.begin();
-
+
Transaction tx1 = tm.getTransaction();
tx1.enlistResource(res1);
-
+
//Send a message
prod1.send(sess1.createTextMessage("kangaroo1"));
-
+
//suspend the tx
Transaction suspended = tm.suspend();
-
+
tm.begin();
-
+
//Send another message in another tx using the same session
Transaction tx2 = tm.getTransaction();
tx2.enlistResource(res1);
-
+
//Send a message
prod1.send(sess1.createTextMessage("kangaroo2"));
-
+
//commit this transaction
- tx2.commit();
-
+ tm.commit();
+
//verify only kangaroo2 message is sent
conn2 = cf.createConnection();
Session sess = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE);
conn2.start();
MessageConsumer cons = sess.createConsumer(queue);
- TextMessage r1 = (TextMessage)cons.receive(1000);
+ TextMessage r1 = (TextMessage)cons.receive(MAX_TIMEOUT);
assertNotNull(r1);
assertEquals("kangaroo2", r1.getText());
- TextMessage r2 = (TextMessage)cons.receive(1000);
+ TextMessage r2 = (TextMessage)cons.receive(MIN_TIMEOUT);
assertNull(r2);
-
+
//now resume the first tx and then commit it
tm.resume(suspended);
- suspended.commit();
-
+ tm.commit();
+
//verify that the first text message is received
- TextMessage r3 = (TextMessage)cons.receive(1000);
+ TextMessage r3 = (TextMessage)cons.receive(MAX_TIMEOUT);
assertNotNull(r3);
assertEquals("kangaroo1", r3.getText());
-
+
}
finally
{
@@ -2006,70 +2147,71 @@
}
}
-
+
}
-
-
+
+
public void testOneSessionTwoTransactionsRollbackSend() throws Exception
{
if (ServerManagement.isRemote()) return;
-
+
XAConnection conn = null;
-
+
Connection conn2 = null;
-
+
try
{
-
+
conn = cf.createXAConnection();
//Create a session
XASession sess1 = conn.createXASession();
XAResource res1 = sess1.getXAResource();
-
+
MessageProducer prod1 = sess1.createProducer(queue);
-
+
tm.begin();
-
+
Transaction tx1 = tm.getTransaction();
tx1.enlistResource(res1);
-
+
//Send a message
prod1.send(sess1.createTextMessage("kangaroo1"));
-
+
//suspend the tx
Transaction suspended = tm.suspend();
-
+
tm.begin();
-
+
//Send another message in another tx using the same session
Transaction tx2 = tm.getTransaction();
tx2.enlistResource(res1);
-
+
//Send a message
prod1.send(sess1.createTextMessage("kangaroo2"));
-
+
//rollback this transaction
- tx2.rollback();
-
+ tm.rollback();
+
//verify no messages are sent
conn2 = cf.createConnection();
Session sess = conn2.createSession(false, Session.AUTO_ACKNOWLEDGE);
conn2.start();
MessageConsumer cons = sess.createConsumer(queue);
- TextMessage r1 = (TextMessage)cons.receive(1000);
+ TextMessage r1 = (TextMessage)cons.receive(MIN_TIMEOUT);
+
assertNull(r1);
-
-
+
+
//now resume the first tx and then commit it
tm.resume(suspended);
- suspended.commit();
-
+ tm.commit();
+
//verify that the first text message is received
- TextMessage r3 = (TextMessage)cons.receive(1000);
+ TextMessage r3 = (TextMessage)cons.receive(MAX_TIMEOUT);
assertNotNull(r3);
assertEquals("kangaroo1", r3.getText());
-
+
}
finally
{
@@ -2083,9 +2225,9 @@
}
}
-
+
}
-
+
// Package protected ---------------------------------------------
// Protected -----------------------------------------------------
Modified: trunk/tests/src/org/jboss/test/messaging/jms/clustering/HATest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/clustering/HATest.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/tests/src/org/jboss/test/messaging/jms/clustering/HATest.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -1055,9 +1055,9 @@
log.info("++testTopicSubscriber");
log.info(">>Lookup Queue");
+
Destination destination = (Destination) topic[1];
-
Connection conn1 = cf.createConnection();
Connection conn2 = cf.createConnection();
@@ -1067,7 +1067,7 @@
conn.setClientID("testClient");
conn.start();
- JBossSession session = (JBossSession) conn.createSession(true, Session.AUTO_ACKNOWLEDGE);
+ JBossSession session = (JBossSession) conn.createSession(true, Session.SESSION_TRANSACTED);
ClientSessionDelegate clientSessionDelegate = (ClientSessionDelegate) session.getDelegate();
SessionState sessionState = (SessionState) clientSessionDelegate.getState();
@@ -1080,7 +1080,6 @@
log.info("subscriptionName=" + consumerState.getSubscriptionName());
-
log.info(">>Creating Producer");
MessageProducer producer = session.createProducer(destination);
log.info(">>creating Message");
@@ -1104,7 +1103,7 @@
ServerManagement.kill(1);
- Thread.sleep(30000);
+ Thread.sleep(60000);
// if failover happened, this object was replaced
assertNotSame(originalRemoting, delegate.getRemotingConnection());
@@ -1125,7 +1124,6 @@
receiveMessage("consumerHA", consumerHA, true, false);
receiveMessage("consumerHA", consumerHA, true, true);
-
session.commit();
conn1.close();
conn2.close();
@@ -1390,7 +1388,8 @@
if (message != null)
{
log.info(text + ": messageID from messageReceived=" + message.getMessage().getMessageID() + " message = " + message + " content=" + txtMessage.getText());
- } else
+ }
+ else
{
log.info(text + ": Message received was null");
}
@@ -1399,7 +1398,8 @@
if (shouldBeNull)
{
assertNull(message);
- } else
+ }
+ else
{
assertNotNull(message);
}
Modified: trunk/tests/src/org/jboss/test/messaging/jms/message/ObjectMessageDeliveryTest.java
===================================================================
--- trunk/tests/src/org/jboss/test/messaging/jms/message/ObjectMessageDeliveryTest.java 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/tests/src/org/jboss/test/messaging/jms/message/ObjectMessageDeliveryTest.java 2006-12-21 23:41:19 UTC (rev 1843)
@@ -37,11 +37,12 @@
import org.jboss.test.messaging.MessagingTestCase;
import org.jboss.test.messaging.tools.ServerManagement;
+
/**
*
* A ObjectMessageDeliveryTest
-
* @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @author <a href="mailto:juha at jboss.org">Juha Lindfors</a>
* @version <tt>$Revision$</tt>
*
* $Id$
@@ -143,11 +144,11 @@
publisher.send(om3);
- ObjectMessage rm1 = (ObjectMessage)sub.receive(1000);
+ ObjectMessage rm1 = (ObjectMessage)sub.receive(MAX_TIMEOUT);
- ObjectMessage rm2 = (ObjectMessage)sub.receive(1000);
+ ObjectMessage rm2 = (ObjectMessage)sub.receive(MAX_TIMEOUT);
- ObjectMessage rm3 = (ObjectMessage)sub.receive(1000);
+ ObjectMessage rm3 = (ObjectMessage)sub.receive(MAX_TIMEOUT);
assertNotNull(rm1);
Copied: trunk/tests/src/org/jboss/test/messaging/jms/stress/ConcurrentCloseStressTest.java (from rev 1823, branches/Branch_1_0/tests/src/org/jboss/test/messaging/jms/stress/ConcurrentCloseStressTest.java)
Copied: trunk/tests/src/org/jboss/test/messaging/util/TransactionManagerLocator.java (from rev 1823, branches/Branch_1_0/tests/src/org/jboss/test/messaging/util/TransactionManagerLocator.java)
Modified: trunk/util/do-not-distribute.properties
===================================================================
--- trunk/util/do-not-distribute.properties 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/util/do-not-distribute.properties 2006-12-21 23:41:19 UTC (rev 1843)
@@ -2,7 +2,15 @@
# This file provides values for in-workarea example testing.
# DO NOT DISTRIBUTE!
#
+<<<<<<< .working
#jboss.home=/home/clebert/workspaces/jboss-4.0-tmp/build/output/jboss-4.0.5.GA
+=======
+#jboss.home=C:\\work/src/jboss-4.0.1sp1-src/build/output/jboss-4.0.1sp1
+#jboss.home=C:\\work/src/cvs/jboss-head/build/output/jboss-5.0.0.Alpha
+#jboss.home=C:\\work\\src\\jboss-4.0.3SP1-src\\build\\output\\jboss-4.0.3SP1
+jboss.home=C:\\work\\src\\jboss-4.0.4.GA-src\\build\\output\\jboss-4.0.4.GA
+jboss.home=C:\\work\\src\\jboss-4.0.5.GA-src\\build\\output\\jboss-4.0.5.GA-ejb3
+>>>>>>> .merge-right.r1823
messaging.config.name=messaging
main.artifact.location=../output/lib
auxiliary.artifacts.location=../src/etc/server/default/deploy
Modified: trunk/util/release-admin.xml
===================================================================
--- trunk/util/release-admin.xml 2006-12-20 20:49:40 UTC (rev 1842)
+++ trunk/util/release-admin.xml 2006-12-21 23:41:19 UTC (rev 1843)
@@ -19,10 +19,20 @@
<property name="messaging.config.name" value="messaging"/>
<property name="id" value="0"/>
<property name="database" value="mysql"/>
+ <property name="thirdparty.home" value="../thirdparty"/>
+ <property name="thirdparty.jbossts.home" value="${thirdparty.home}/jboss/jbossts"/>
+ <property name="lib.home" value="../lib"/>
+ <property name="lib.jbossts.home" value="${lib.home}/jbossts"/>
+ <property name="output.lib.home" value="../output/lib"/>
+<<<<<<< .working
<!--
DO NOT change these values here, otherwise the installation script won't work. If you need
to change them, to it in do-not-distribute.properties.
+=======
+ <!-- DO NOT change this value here, otherwise the installation script won't work. Change it in
+ do-not-distribute.properties.
+>>>>>>> .merge-right.r1823
-->
<property name="main.artifact.location" value=".."/>
<property name="auxiliary.artifacts.location" value="../examples/config"/>
@@ -116,6 +126,22 @@
<substitution expression="<category name="org.jboss.serial">
 <priority value="INFO"/>
 </category>

 \1"/>
</replaceregexp>
+ <!-- Replace local TM with JBossTS -->
+
+ <copy file="${thirdparty.jbossts.home}/lib/jbossjta.jar"
+ todir="${jboss.home}/server/${messaging.config.name}/lib"/>
+ <copy file="${thirdparty.jbossts.home}/lib/jbossjta-integration.jar"
+ todir="${jboss.home}/server/${messaging.config.name}/lib"/>
+ <copy file="${thirdparty.jbossts.home}/lib/jbossts-common.jar"
+ todir="${jboss.home}/server/${messaging.config.name}/lib"/>
+ <copy file="${lib.jbossts.home}/jbossjta-properties.xml"
+ todir="${jboss.home}/server/${messaging.config.name}/conf"/>
+ <copy overwrite="true"
+ file="${lib.jbossts.home}/jboss-service.xml"
+ todir="${jboss.home}/server/${messaging.config.name}/conf"/>
+ <copy file="${output.lib.home}/jboss-messaging-integration.jar"
+ todir="${jboss.home}/server/${messaging.config.name}/lib"/>
+
<!-- copy the scoped sar
<copy todir="${jboss.home}/server/${config.name}/deploy"
file="${relative.sar.location}/${messaging.sar.name}"/>
More information about the jboss-cvs-commits
mailing list