[jboss-svn-commits] JBL Code SVN: r35995 - in labs/jbosstm/workspace/istudens: RecoveryDemo and 12 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Tue Nov 16 10:11:19 EST 2010
Author: istudens at redhat.com
Date: 2010-11-16 10:11:18 -0500 (Tue, 16 Nov 2010)
New Revision: 35995
Added:
labs/jbosstm/workspace/istudens/RecoveryDemo/
labs/jbosstm/workspace/istudens/RecoveryDemo/.classpath
labs/jbosstm/workspace/istudens/RecoveryDemo/.project
labs/jbosstm/workspace/istudens/RecoveryDemo/.settings/
labs/jbosstm/workspace/istudens/RecoveryDemo/.settings/org.eclipse.jdt.core.prefs
labs/jbosstm/workspace/istudens/RecoveryDemo/README
labs/jbosstm/workspace/istudens/RecoveryDemo/build.xml
labs/jbosstm/workspace/istudens/RecoveryDemo/lib/
labs/jbosstm/workspace/istudens/RecoveryDemo/lib/antlr.jar
labs/jbosstm/workspace/istudens/RecoveryDemo/lib/dbdriver/
labs/jbosstm/workspace/istudens/RecoveryDemo/lib/junit-4.5.jar
labs/jbosstm/workspace/istudens/RecoveryDemo/local.properties
labs/jbosstm/workspace/istudens/RecoveryDemo/resources/
labs/jbosstm/workspace/istudens/RecoveryDemo/resources/META-INF/
labs/jbosstm/workspace/istudens/RecoveryDemo/resources/META-INF/persistence.xml
labs/jbosstm/workspace/istudens/RecoveryDemo/resources/oracle10-xa-1-ds.xml
labs/jbosstm/workspace/istudens/RecoveryDemo/resources/oracle10-xa-2-ds.xml
labs/jbosstm/workspace/istudens/RecoveryDemo/src/
labs/jbosstm/workspace/istudens/RecoveryDemo/src/org/
labs/jbosstm/workspace/istudens/RecoveryDemo/src/org/jboss/
labs/jbosstm/workspace/istudens/RecoveryDemo/src/org/jboss/test/
labs/jbosstm/workspace/istudens/RecoveryDemo/src/org/jboss/test/recoverydemo/
labs/jbosstm/workspace/istudens/RecoveryDemo/src/org/jboss/test/recoverydemo/client/
labs/jbosstm/workspace/istudens/RecoveryDemo/src/org/jboss/test/recoverydemo/client/OrderIdGenerator.java
labs/jbosstm/workspace/istudens/RecoveryDemo/src/org/jboss/test/recoverydemo/client/RecoveryDemoTest.java
labs/jbosstm/workspace/istudens/RecoveryDemo/src/org/jboss/test/recoverydemo/ejb3/
labs/jbosstm/workspace/istudens/RecoveryDemo/src/org/jboss/test/recoverydemo/ejb3/OrderEntity.java
labs/jbosstm/workspace/istudens/RecoveryDemo/src/org/jboss/test/recoverydemo/ejb3/OrderFacade.java
labs/jbosstm/workspace/istudens/RecoveryDemo/src/org/jboss/test/recoverydemo/ejb3/OrderFacadeRemote.java
labs/jbosstm/workspace/istudens/RecoveryDemo/src/org/jboss/test/recoverydemo/recovery/
labs/jbosstm/workspace/istudens/RecoveryDemo/src/org/jboss/test/recoverydemo/recovery/ASFailureMode.java
labs/jbosstm/workspace/istudens/RecoveryDemo/src/org/jboss/test/recoverydemo/recovery/ASFailureSpec.java
labs/jbosstm/workspace/istudens/RecoveryDemo/src/org/jboss/test/recoverydemo/recovery/ASFailureType.java
labs/jbosstm/workspace/istudens/RecoveryDemo/src/org/jboss/test/recoverydemo/recovery/ASTestResource.java
Log:
copying RecoveryDemo from a private svn, JBQA-3344
Added: labs/jbosstm/workspace/istudens/RecoveryDemo/.classpath
===================================================================
--- labs/jbosstm/workspace/istudens/RecoveryDemo/.classpath (rev 0)
+++ labs/jbosstm/workspace/istudens/RecoveryDemo/.classpath 2010-11-16 15:11:18 UTC (rev 35995)
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="var" path="JBOSS_HOME/common/lib/ejb3-persistence.jar"/>
+ <classpathentry kind="var" path="JBOSS_HOME/common/lib/jboss-javaee.jar"/>
+ <classpathentry kind="var" path="JBOSS_HOME"/>
+ <classpathentry kind="lib" path="lib/junit-4.5.jar"/>
+ <classpathentry kind="var" path="JBOSS_HOME/common/lib/jbossjts.jar"/>
+ <classpathentry kind="var" path="JBOSS_HOME/client/jboss-ejb3-ext-api.jar"/>
+ <classpathentry kind="output" path="classes"/>
+</classpath>
Added: labs/jbosstm/workspace/istudens/RecoveryDemo/.project
===================================================================
--- labs/jbosstm/workspace/istudens/RecoveryDemo/.project (rev 0)
+++ labs/jbosstm/workspace/istudens/RecoveryDemo/.project 2010-11-16 15:11:18 UTC (rev 35995)
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>Recovery Demo</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.wst.common.project.facet.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+ </natures>
+</projectDescription>
Added: labs/jbosstm/workspace/istudens/RecoveryDemo/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- labs/jbosstm/workspace/istudens/RecoveryDemo/.settings/org.eclipse.jdt.core.prefs (rev 0)
+++ labs/jbosstm/workspace/istudens/RecoveryDemo/.settings/org.eclipse.jdt.core.prefs 2010-11-16 15:11:18 UTC (rev 35995)
@@ -0,0 +1,12 @@
+#Mon May 03 10:49:43 CEST 2010
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.6
Added: labs/jbosstm/workspace/istudens/RecoveryDemo/README
===================================================================
--- labs/jbosstm/workspace/istudens/RecoveryDemo/README (rev 0)
+++ labs/jbosstm/workspace/istudens/RecoveryDemo/README 2010-11-16 15:11:18 UTC (rev 35995)
@@ -0,0 +1,89 @@
+Recovery Demo Application
+=========================
+
+In order to use this recovery demo application one has to follow the steps below.
+
+1) Prepare two Oracle databases for the demo. You will need an db account with permissions for transaction recovery.
+ 1.a) Create database user account in your dbs
+ 1.b) Give it the right permissions
+ GRANT SELECT ON sys.dba_pending_transactions TO username;
+ GRANT SELECT ON sys.pending_trans$ TO username;
+ GRANT SELECT ON sys.dba_2pc_pending TO username;
+ GRANT EXECUTE ON sys.dbms_xa TO username;
+ If the last command fails, execute this one:
+ GRANT EXECUTE ON sys.dbms_system TO username;
+ For more info see:
+ http://www.redhat.com/docs/en-US/JBoss_Enterprise_Application_Platform/5.0.1/html/Transactions_Administrators_Guide/ch07s04.html
+
+2) Install JBoss EAP5 and set the JBOSS_HOME.
+
+3) Configure the demo application in the file local.properties.
+ Especially set the URLs, usernames and user passwords for your DBs.
+
+4) In the EAP turn on the recovery for both DBs. It is possible to run the following command to do that.
+ ant setup-crash-recovery
+
+5) Compile and deploy demo application to the EAP server.
+ ant deploy
+
+6) Start up the EAP server.
+ cd $JBOSS_HOME/bin
+ ./run.sh -c all &> log &
+
+7) Return to the demo application directory and run the test.
+ ant run-test
+
+8) During the test run, plug in/out the network cable of the second database server several times.
+ With default settings the test takes about 6 minute on typical PC.
+
+9) When the test is finished, check its result in the console and also in the TEST-org.jboss.test.recoverydemo.client.RecoveryDemoTest.xml file.
+ The databases should be in sync. The EAP server log should be full of "Cannot open connection" messages, but nothing more.
+ There should not be any messages like the one below if the recovery is properly configured.
+ Could not find new XAResource to use for recovering non-serializable XAResource
+
+
+
+It is also possible to run the test in a special mode with a fault XA resource. In order to enable
+this fault XA resource follow the steps below.
+
+1) Change the enlist.fault.xaresource property in the local.properties file of the demo application to true.
+ enlist.fault.xaresource=false
+
+2) Run the test.
+ ant run-test
+
+3) During the test run check the EAP server log and wait for signal from the fault XA resource
+ about suspending the transaction in the commit phase.
+ tail -f $JBOSS_HOME/server/all/log/server.log
+ The signal looks like this:
+ 2010-05-05 16:34:34,462 INFO [STDOUT] (WorkerThread#1[127.0.0.1:57387]) Applying fault injection with 1 active branches
+ 2010-05-05 16:34:34,462 INFO [STDOUT] (WorkerThread#1[127.0.0.1:57387]) xa commit ... suspending for 90000
+ where 90000 means 90secs.
+
+4) Plug out the network cable of the second database server.
+
+5) Wait for signal from the fault XA resource about resuming the transaction.
+ 2010-05-05 16:36:04,463 INFO [STDOUT] (WorkerThread#1[127.0.0.1:57387]) xa commit ... resuming
+
+6) Plug in the network cable back.
+
+7) When the test is finished, check its result in the console and also in the TEST-org.jboss.test.recoverydemo.client.RecoveryDemoTest.xml file.
+ The databases should be in sync. The EAP server log should be full of "Cannot open connection" messages, but nothing more.
+
+
+The time that the test takes depends on the client app. configuration,
+i.e. on the properties 'max.iterations' and 'max.threads' in the local.properties file.
+The 'max.threads' property stands for the number of threads used by client application to
+invoke the test method on the EAP server.
+The 'max.iterations' property stands for number of calls that will be done by each thread.
+
+
+Note: how to manually finish a pending transaction in the Oracle db.
+1) select local_tran_id from dba_2pc_pending;
+ '8.25.224633'
+2) ALTER SYSTEM DISABLE DISTRIBUTED RECOVERY;
+3) ROLLBACK FORCE '8.25.224633';
+4) exec dbms_transaction.purge_lost_db_entry('8.25.224633');
+5) ALTER SYSTEM ENABLE DISTRIBUTED RECOVERY;
+
+
Added: labs/jbosstm/workspace/istudens/RecoveryDemo/build.xml
===================================================================
--- labs/jbosstm/workspace/istudens/RecoveryDemo/build.xml (rev 0)
+++ labs/jbosstm/workspace/istudens/RecoveryDemo/build.xml 2010-11-16 15:11:18 UTC (rev 35995)
@@ -0,0 +1,140 @@
+<?xml version="1.0"?>
+<project name="Recovery Demo" default="compile" basedir=".">
+
+ <property environment="env"/>
+
+ <property file="local.properties"/>
+
+ <property name="jboss.home" value="${env.JBOSS_HOME}"/>
+ <property name="jboss.server" value="${jboss.home}/server/all"/>
+
+ <property name="src.dir" value="${basedir}/src" />
+ <property name="res.dir" value="${basedir}/resources" />
+ <property name="classes.dir" value="${basedir}/classes" />
+ <property name="build.dir" value="${basedir}/build" />
+ <property name="lib.dir" value="${basedir}/lib" />
+ <property name="dbdriver.dir" value="${lib.dir}/dbdriver" />
+
+ <path id="ejb-jars">
+ <fileset dir="${jboss.home}">
+ <include name="client/jbossall-client.jar"/>
+ <include name="client/log4j.jar" />
+ <include name="client/jboss-javaee.jar"/>
+ <include name="client/ejb3-persistence.jar"/>
+ </fileset>
+ </path>
+
+ <path id="classpath">
+ <pathelement location="${classes.dir}"/>
+ <fileset dir="${lib.dir}">
+ <include name="*.jar"/>
+ </fileset>
+ <path refid="ejb-jars"/>
+ </path>
+
+ <target name="init">
+ <mkdir dir="${classes.dir}"/>
+ <mkdir dir="${build.dir}"/>
+ </target>
+
+ <target name="compile" depends="init">
+ <javac srcdir="${src.dir}"
+ destdir="${classes.dir}"
+ debug="on"
+ deprecation="on"
+ optimize="off"
+ includes="**">
+ <classpath refid="classpath"/>
+ </javac>
+ </target>
+
+ <target name="ejb3jar" depends="compile" >
+ <jar jarfile="${build.dir}/recovery-ejb.jar">
+ <fileset dir="${res.dir}">
+ <include name="META-INF/*.xml"/>
+ </fileset>
+ <fileset dir="${classes.dir}">
+ <include name="**/ejb3/*.class"/>
+ <include name="**/recovery/*.class"/>
+ </fileset>
+ </jar>
+ </target>
+
+ <target name="deploy" depends="ejb3jar">
+ <copy todir="${jboss.server}/lib">
+ <fileset dir="${dbdriver.dir}">
+ <include name="*.jar"/>
+ </fileset>
+ </copy>
+ <copy file="${res.dir}/oracle10-xa-1-ds.xml" todir="${jboss.server}/deploy">
+ <filterset>
+ <filter token="URL" value="${db1.url}"/>
+ <filter token="USER" value="${db1.user}"/>
+ <filter token="PASS" value="${db1.pass}"/>
+ </filterset>
+ </copy>
+ <copy file="${res.dir}/oracle10-xa-2-ds.xml" todir="${jboss.server}/deploy">
+ <filterset>
+ <filter token="URL" value="${db2.url}"/>
+ <filter token="USER" value="${db2.user}"/>
+ <filter token="PASS" value="${db2.pass}"/>
+ </filterset>
+ </copy>
+ <copy file="${build.dir}/recovery-ejb.jar" todir="${jboss.server}/deploy"/>
+ </target>
+ <target name="undeploy" >
+ <delete file="${jboss.server}/deploy/recovery-ejb.jar"/>
+ <delete file="${res.dir}/oracle10-xa-1-ds.xml"/>
+ <delete file="${res.dir}/oracle10-xa-2-ds.xml"/>
+ </target>
+
+ <target name="clean">
+ <delete dir="${classes.dir}"/>
+ <delete dir="${build.dir}"/>
+ </target>
+
+ <target name="setup-crash-recovery">
+ <!-- enable crash recovery and point it to our datasource -->
+ <replace file="${jboss.server}/conf/jbossts-properties.xml">
+ <replacetoken><![CDATA[</transaction-service>]]></replacetoken>
+ <replacevalue><![CDATA[
+ <properties depends="arjuna" name="jta">
+ <property name="com.arjuna.ats.jta.recovery.XAResourceRecovery1" value= "com.arjuna.ats.internal.jbossatx.jta.AppServerJDBCXARecovery;jndiname=CrashRecoveryDS1"/>
+ <property name="com.arjuna.ats.jta.xaRecoveryNode" value="1"/>
+ </properties>
+ <properties depends="arjuna" name="jta">
+ <property name="com.arjuna.ats.jta.recovery.XAResourceRecovery2" value= "com.arjuna.ats.internal.jbossatx.jta.AppServerJDBCXARecovery;jndiname=CrashRecoveryDS2"/>
+ <property name="com.arjuna.ats.jta.xaRecoveryNode" value="1"/>
+ </properties>
+ </transaction-service>]]></replacevalue>
+ </replace>
+ <!-- comment out for more verbose logging
+ <replace file="${jboss.server}/conf/jbossts-properties.xml">
+ <replacetoken><![CDATA[type="System" value="0x00000000"]]></replacetoken>
+ <replacevalue><![CDATA[type="System" value="0xffffffff"]]></replacevalue>
+ </replace-->
+ </target>
+
+ <target name="run-test">
+ <junit printsummary="yes" haltonfailure="yes" fork="true" dir="${basedir}">
+ <classpath>
+ <path refid="classpath"/>
+ </classpath>
+
+ <formatter type="xml"/>
+
+ <test name="org.jboss.test.recoverydemo.client.RecoveryDemoTest"/>
+
+ <sysproperty key="maxIterations" value="${max.iterations}"/>
+ <sysproperty key="maxThreads" value="${max.threads}"/>
+ <sysproperty key="enlistFaultXAResource" value="${enlist.fault.xaresource}"/>
+ <sysproperty key="orderIdPrefix" value="node1"/> <!-- FIXME put hostname here -->
+
+ <sysproperty key="serverHostname" value="${server.hostname}"/>
+
+ <!--<jvmarg value="-Xdebug"/>-->
+ <!--<jvmarg value="-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5006"/>-->
+ </junit>
+ </target>
+
+</project>
Added: labs/jbosstm/workspace/istudens/RecoveryDemo/lib/antlr.jar
===================================================================
(Binary files differ)
Property changes on: labs/jbosstm/workspace/istudens/RecoveryDemo/lib/antlr.jar
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: labs/jbosstm/workspace/istudens/RecoveryDemo/lib/junit-4.5.jar
===================================================================
(Binary files differ)
Property changes on: labs/jbosstm/workspace/istudens/RecoveryDemo/lib/junit-4.5.jar
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: labs/jbosstm/workspace/istudens/RecoveryDemo/local.properties
===================================================================
--- labs/jbosstm/workspace/istudens/RecoveryDemo/local.properties (rev 0)
+++ labs/jbosstm/workspace/istudens/RecoveryDemo/local.properties 2010-11-16 15:11:18 UTC (rev 35995)
@@ -0,0 +1,18 @@
+# test configuration
+max.iterations=400
+max.threads=200
+enlist.fault.xaresource=false
+
+# AS server hostname
+server.hostname=localhost
+
+# db1
+db1.url=jdbc:oracle:thin:@jawa06.englab.brq.redhat.com:1521:soaesb1
+db1.user=soaesb1
+db1.pass=soaesb1
+
+# db2
+db2.url=jdbc:oracle:thin:@jawa01.englab.brq.redhat.com:1521:soaesb1
+db2.user=soaesb1
+db2.pass=soaesb1
+
Added: labs/jbosstm/workspace/istudens/RecoveryDemo/resources/META-INF/persistence.xml
===================================================================
--- labs/jbosstm/workspace/istudens/RecoveryDemo/resources/META-INF/persistence.xml (rev 0)
+++ labs/jbosstm/workspace/istudens/RecoveryDemo/resources/META-INF/persistence.xml 2010-11-16 15:11:18 UTC (rev 35995)
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<persistence xmlns="http://java.sun.com/xml/ns/persistence">
+ <persistence-unit name="recoveryDemo1">
+ <jta-data-source>java:/CrashRecoveryDS1</jta-data-source>
+ <properties>
+ <property name="jboss.entity.manager.jndi.name" value="java:/CrashRecoveryManager1" />
+ <property name="jboss.entity.manager.factory.jndi.name"
+ value="java:/CrashRecoveryManagerFactory1" />
+ <property name="hibernate.hbm2ddl.auto" value="update"/>
+ </properties>
+ </persistence-unit>
+ <persistence-unit name="recoveryDemo2">
+ <jta-data-source>java:/CrashRecoveryDS2</jta-data-source>
+ <properties>
+ <property name="jboss.entity.manager.jndi.name" value="java:/CrashRecoveryManager2" />
+ <property name="jboss.entity.manager.factory.jndi.name"
+ value="java:/CrashRecoveryManagerFactory2" />
+ <property name="hibernate.hbm2ddl.auto" value="update"/>
+ </properties>
+ </persistence-unit>
+</persistence>
Added: labs/jbosstm/workspace/istudens/RecoveryDemo/resources/oracle10-xa-1-ds.xml
===================================================================
--- labs/jbosstm/workspace/istudens/RecoveryDemo/resources/oracle10-xa-1-ds.xml (rev 0)
+++ labs/jbosstm/workspace/istudens/RecoveryDemo/resources/oracle10-xa-1-ds.xml 2010-11-16 15:11:18 UTC (rev 35995)
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- ===================================================================== -->
+<!-- -->
+<!-- JBoss Server Configuration -->
+<!-- -->
+<!-- ===================================================================== -->
+
+<!-- $Id: oracle-xa-ds.xml 71535 2008-04-01 07:05:03Z adrian at jboss.org $ -->
+
+<!-- ===================================================================== -->
+<!-- ATTENTION: DO NOT FORGET TO SET Pad=true IN transaction-service.xml -->
+<!-- ===================================================================== -->
+
+<datasources>
+
+ <xa-datasource>
+ <jndi-name>CrashRecoveryDS1</jndi-name>
+ <track-connection-by-tx>true</track-connection-by-tx>
+ <isSameRM-override-value>false</isSameRM-override-value>
+ <xa-datasource-class>oracle.jdbc.xa.client.OracleXADataSource</xa-datasource-class>
+ <xa-datasource-property name="URL">@URL@</xa-datasource-property>
+ <xa-datasource-property name="User">@USER@</xa-datasource-property>
+ <xa-datasource-property name="Password">@PASS@</xa-datasource-property>
+ <!-- Uses the pingDatabase method to check a connection is still valid before handing it out from the pool -->
+ <valid-connection-checker-class-name>org.jboss.resource.adapter.jdbc.vendor.OracleValidConnectionChecker</valid-connection-checker-class-name>
+ <!-- Checks the Oracle error codes and messages for fatal errors -->
+ <exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter</exception-sorter-class-name>
+ <!-- Oracles XA datasource cannot reuse a connection outside a transaction once enlisted in a global transaction and vice-versa -->
+ <no-tx-separate-pools/>
+
+ <!-- corresponding type-mapping in the standardjbosscmp-jdbc.xml (optional) -->
+ <metadata>
+ <type-mapping>Oracle9i</type-mapping>
+ </metadata>
+ </xa-datasource>
+
+</datasources>
Added: labs/jbosstm/workspace/istudens/RecoveryDemo/resources/oracle10-xa-2-ds.xml
===================================================================
--- labs/jbosstm/workspace/istudens/RecoveryDemo/resources/oracle10-xa-2-ds.xml (rev 0)
+++ labs/jbosstm/workspace/istudens/RecoveryDemo/resources/oracle10-xa-2-ds.xml 2010-11-16 15:11:18 UTC (rev 35995)
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- ===================================================================== -->
+<!-- -->
+<!-- JBoss Server Configuration -->
+<!-- -->
+<!-- ===================================================================== -->
+
+<!-- $Id: oracle-xa-ds.xml 71535 2008-04-01 07:05:03Z adrian at jboss.org $ -->
+
+<!-- ===================================================================== -->
+<!-- ATTENTION: DO NOT FORGET TO SET Pad=true IN transaction-service.xml -->
+<!-- ===================================================================== -->
+
+<datasources>
+
+ <xa-datasource>
+ <jndi-name>CrashRecoveryDS2</jndi-name>
+ <track-connection-by-tx>true</track-connection-by-tx>
+ <isSameRM-override-value>false</isSameRM-override-value>
+ <xa-datasource-class>oracle.jdbc.xa.client.OracleXADataSource</xa-datasource-class>
+ <xa-datasource-property name="URL">@URL@</xa-datasource-property>
+ <xa-datasource-property name="User">@USER@</xa-datasource-property>
+ <xa-datasource-property name="Password">@PASS@</xa-datasource-property>
+ <!-- Uses the pingDatabase method to check a connection is still valid before handing it out from the pool -->
+ <valid-connection-checker-class-name>org.jboss.resource.adapter.jdbc.vendor.OracleValidConnectionChecker</valid-connection-checker-class-name>
+ <!-- Checks the Oracle error codes and messages for fatal errors -->
+ <exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter</exception-sorter-class-name>
+ <!-- Oracles XA datasource cannot reuse a connection outside a transaction once enlisted in a global transaction and vice-versa -->
+ <no-tx-separate-pools/>
+
+ <!-- corresponding type-mapping in the standardjbosscmp-jdbc.xml (optional) -->
+ <metadata>
+ <type-mapping>Oracle9i</type-mapping>
+ </metadata>
+ </xa-datasource>
+
+</datasources>
Added: labs/jbosstm/workspace/istudens/RecoveryDemo/src/org/jboss/test/recoverydemo/client/OrderIdGenerator.java
===================================================================
--- labs/jbosstm/workspace/istudens/RecoveryDemo/src/org/jboss/test/recoverydemo/client/OrderIdGenerator.java (rev 0)
+++ labs/jbosstm/workspace/istudens/RecoveryDemo/src/org/jboss/test/recoverydemo/client/OrderIdGenerator.java 2010-11-16 15:11:18 UTC (rev 35995)
@@ -0,0 +1,31 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * 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,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * (C) 2010,
+ * @author JBoss Inc.
+ */
+package org.jboss.test.recoverydemo.client;
+
+public abstract class OrderIdGenerator {
+
+ private static long orderId = 0;
+
+ public static synchronized long getNextOrderId()
+ {
+ return ++orderId;
+ }
+}
Added: labs/jbosstm/workspace/istudens/RecoveryDemo/src/org/jboss/test/recoverydemo/client/RecoveryDemoTest.java
===================================================================
--- labs/jbosstm/workspace/istudens/RecoveryDemo/src/org/jboss/test/recoverydemo/client/RecoveryDemoTest.java (rev 0)
+++ labs/jbosstm/workspace/istudens/RecoveryDemo/src/org/jboss/test/recoverydemo/client/RecoveryDemoTest.java 2010-11-16 15:11:18 UTC (rev 35995)
@@ -0,0 +1,185 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * 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,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * (C) 2010,
+ * @author JBoss Inc.
+ */
+package org.jboss.test.recoverydemo.client;
+
+import static org.junit.Assert.*;
+
+import java.util.ArrayList;
+import java.util.Properties;
+
+import javax.ejb.EJBException;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+
+import org.jboss.test.recoverydemo.ejb3.OrderFacade;
+import org.jboss.test.recoverydemo.ejb3.OrderFacadeRemote;
+import org.junit.Before;
+import org.junit.Test;
+
+public class RecoveryDemoTest
+{
+ private int maxIterations;
+ private int maxThreads;
+ private String orderIdPrefix;
+ private boolean enlistFaultXAResource;
+
+ private String serverHostname;
+
+ private OrderFacadeRemote orderFacade = null;
+
+
+ @Before
+ public void initialize() throws NamingException
+ {
+ maxIterations = parseInt(System.getProperty("maxIterations"), 1000);
+ maxThreads = parseInt(System.getProperty("maxThreads"), 5);
+ orderIdPrefix = System.getProperty("orderIdPrefix");
+ enlistFaultXAResource = parseBoolean(System.getProperty("enlistFaultXAResource"));
+
+ serverHostname = System.getProperty("serverHostname");
+
+ if (orderFacade == null)
+ orderFacade = (OrderFacadeRemote) getNamingContext().lookup(OrderFacade.REMOTE_JNDI_NAME);
+
+ System.out.println("maxIterations = " + maxIterations);
+ System.out.println("maxThreads = " + maxThreads);
+ System.out.println("orderIdPrefix = " + orderIdPrefix);
+ System.out.println("enlistFaultXAResource = " + enlistFaultXAResource);
+ }
+
+ @Test
+ public void recoveryDemo()
+ {
+ // clear the dbs before the test
+ orderFacade.initDatabases();
+
+ // check that dbs are empty
+ int[] countsBefore = orderFacade.checkDatabaseStates();
+ assertEquals("Db1 should be empty", countsBefore[0], 0);
+ assertEquals("Db2 should be empty", countsBefore[1], 0);
+
+ // run the test
+ ArrayList<DemoTestRunner> threads = new ArrayList<DemoTestRunner>(maxThreads);
+ for (int i=0; i < maxThreads; i++)
+ {
+ DemoTestRunner runner = new DemoTestRunner(enlistFaultXAResource && i==0); // only the first thread potentially invokes the fault XA resource
+ threads.add(runner);
+ runner.start();
+ }
+ // wait for the threads to finish
+ for (DemoTestRunner runner: threads)
+ {
+ try
+ {
+ runner.join();
+ }
+ catch (InterruptedException e)
+ {
+ System.err.println("Join interrupted: " + e);
+ }
+ }
+
+ // check the dbs state after the test
+ int[] countsAfter = orderFacade.checkDatabaseStates();
+ System.out.println(countsAfter[0] + " orders in db1");
+ System.out.println(countsAfter[1] + " orders in db2");
+ assertEquals("There should be the same count of orders in both dbs after the test", countsAfter[0], countsAfter[1]);
+ }
+
+
+ class DemoTestRunner extends Thread
+ {
+ boolean enlistFaultXAResource;
+
+ public DemoTestRunner(boolean enlistFaultXAResource)
+ {
+ this.enlistFaultXAResource = enlistFaultXAResource;
+ }
+
+ public void run()
+ {
+ // the fault XA resource will be potentially invoked in the third of the cycle
+ int hitIndex = (enlistFaultXAResource) ? maxIterations/3 : -1;
+
+ OrderFacadeRemote facade;
+ try {
+ facade = (OrderFacadeRemote) getNamingContext().lookup(OrderFacade.REMOTE_JNDI_NAME);
+ } catch (NamingException e1) {
+ throw new EJBException(e1);
+ }
+
+ for (int k=0; k < maxIterations; k++)
+ {
+ try
+ {
+ long orderId = OrderIdGenerator.getNextOrderId();
+ facade.storeNewOrder(orderIdPrefix + "_" + Long.toString(orderId), hitIndex == k);
+ }
+ catch (Exception e)
+ {
+ System.err.println("Error: " + e.getMessage());
+ e.printStackTrace(System.err);
+ }
+ }
+ }
+
+ }
+
+ private Context getNamingContext() throws NamingException
+ {
+ Properties properties = new Properties();
+ properties.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.NamingContextFactory");
+ properties.setProperty(Context.URL_PKG_PREFIXES, "org.jboss.naming.client:org.jnp.interfaces");
+ properties.setProperty(Context.PROVIDER_URL, "jnp://" + serverHostname + ":1099");
+
+ return new InitialContext(properties);
+ }
+
+ private int parseInt(String value, int defaultValue)
+ {
+ int retVal;
+ try
+ {
+ retVal = Integer.parseInt(value);
+ }
+ catch (Exception e)
+ {
+ retVal = defaultValue;
+ }
+ return retVal;
+ }
+
+ private boolean parseBoolean(String value)
+ {
+ boolean retVal;
+ try
+ {
+ retVal = Boolean.parseBoolean(value);
+ }
+ catch (Exception e)
+ {
+ retVal = false;
+ }
+ return retVal;
+ }
+
+}
Added: labs/jbosstm/workspace/istudens/RecoveryDemo/src/org/jboss/test/recoverydemo/ejb3/OrderEntity.java
===================================================================
--- labs/jbosstm/workspace/istudens/RecoveryDemo/src/org/jboss/test/recoverydemo/ejb3/OrderEntity.java (rev 0)
+++ labs/jbosstm/workspace/istudens/RecoveryDemo/src/org/jboss/test/recoverydemo/ejb3/OrderEntity.java 2010-11-16 15:11:18 UTC (rev 35995)
@@ -0,0 +1,94 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * 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,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * (C) 2010,
+ * @author JBoss Inc.
+ */
+package org.jboss.test.recoverydemo.ejb3;
+
+import java.io.Serializable;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+/**
+ * Simple OrderEntity for the Recovery Demo App.
+ *
+ * @author <a href="istudens at redhat.com">Ivo Studensky</a>
+ * @version $Revision: 1.1 $
+ */
+ at Entity
+ at Table(name="orderentity")
+public class OrderEntity implements Serializable
+{
+ private String orderNumber;
+
+ public OrderEntity()
+ {
+ // default constructor
+ }
+
+ public OrderEntity(String orderNumber)
+ {
+ this.orderNumber = orderNumber;
+ }
+
+ @Id
+ public String getOrderNumber()
+ {
+ return orderNumber;
+ }
+ public void setOrderNumber(String orderNumber)
+ {
+ this.orderNumber = orderNumber;
+ }
+
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result
+ + ((orderNumber == null) ? 0 : orderNumber.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ OrderEntity other = (OrderEntity) obj;
+ if (orderNumber == null) {
+ if (other.orderNumber != null)
+ return false;
+ } else if (!orderNumber.equals(other.orderNumber))
+ return false;
+ return true;
+ }
+
+ @Override
+ public String toString()
+ {
+ return "OrderEntity [orderNumber=" + orderNumber + "]";
+ }
+
+}
Added: labs/jbosstm/workspace/istudens/RecoveryDemo/src/org/jboss/test/recoverydemo/ejb3/OrderFacade.java
===================================================================
--- labs/jbosstm/workspace/istudens/RecoveryDemo/src/org/jboss/test/recoverydemo/ejb3/OrderFacade.java (rev 0)
+++ labs/jbosstm/workspace/istudens/RecoveryDemo/src/org/jboss/test/recoverydemo/ejb3/OrderFacade.java 2010-11-16 15:11:18 UTC (rev 35995)
@@ -0,0 +1,105 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * 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,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * (C) 2010,
+ * @author JBoss Inc.
+ */
+package org.jboss.test.recoverydemo.ejb3;
+
+import javax.ejb.EJBException;
+import javax.ejb.Stateless;
+import javax.ejb.TransactionAttribute;
+import javax.ejb.TransactionAttributeType;
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+import javax.transaction.Transaction;
+
+import org.jboss.test.recoverydemo.recovery.ASFailureMode;
+import org.jboss.test.recoverydemo.recovery.ASFailureSpec;
+import org.jboss.test.recoverydemo.recovery.ASFailureType;
+import org.jboss.test.recoverydemo.recovery.ASTestResource;
+
+ at Stateless
+public class OrderFacade implements OrderFacadeRemote {
+ public static final String REMOTE_JNDI_NAME = OrderFacade.class.getSimpleName() + "/remote";
+
+
+ @PersistenceContext(unitName="recoveryDemo1")
+ EntityManager em1;
+
+ @PersistenceContext(unitName="recoveryDemo2")
+ EntityManager em2;
+
+
+ @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
+ public boolean storeNewOrder(String orderNumber, boolean enlistFaultXAResource)
+ {
+ OrderEntity order1 = new OrderEntity(orderNumber);
+ em1.persist(order1);
+
+ // enlist the special XA resource here
+ if (enlistFaultXAResource)
+ enlistFaultXAResource();
+
+ OrderEntity order2 = new OrderEntity(orderNumber);
+ em2.persist(order2);
+
+ return true;
+ }
+
+ private void enlistFaultXAResource()
+ {
+ try
+ {
+ Transaction tx = com.arjuna.ats.jta.TransactionManager.transactionManager().getTransaction();
+
+ int sleep = 90 * 1000; // in msec
+ ASFailureSpec failureSpec = new ASFailureSpec("commit_suspend", ASFailureMode.SUSPEND, ASFailureType.XARES_COMMIT, Integer.toString(sleep), 0);
+
+ ASTestResource res = new ASTestResource(failureSpec);
+
+ if (res.isXAResource())
+ tx.enlistResource(res);
+ else if (res.isSynchronization())
+ tx.registerSynchronization(res);
+
+ }
+ catch (Exception e)
+ {
+ System.err.println("Error: " + e.getMessage());
+ throw new EJBException(e);
+ }
+ }
+
+
+ @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
+ public void initDatabases()
+ {
+ em1.createQuery("DELETE FROM OrderEntity").executeUpdate();
+ em2.createQuery("DELETE FROM OrderEntity").executeUpdate();
+ }
+
+ @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
+ public int[] checkDatabaseStates()
+ {
+ int db1Size = em1.createQuery("SELECT OBJECT(a) FROM OrderEntity a").getResultList().size();
+ int db2Size = em2.createQuery("SELECT OBJECT(a) FROM OrderEntity a").getResultList().size();
+
+ return new int[] {db1Size, db2Size};
+ }
+
+}
Added: labs/jbosstm/workspace/istudens/RecoveryDemo/src/org/jboss/test/recoverydemo/ejb3/OrderFacadeRemote.java
===================================================================
--- labs/jbosstm/workspace/istudens/RecoveryDemo/src/org/jboss/test/recoverydemo/ejb3/OrderFacadeRemote.java (rev 0)
+++ labs/jbosstm/workspace/istudens/RecoveryDemo/src/org/jboss/test/recoverydemo/ejb3/OrderFacadeRemote.java 2010-11-16 15:11:18 UTC (rev 35995)
@@ -0,0 +1,30 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * 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,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * (C) 2010,
+ * @author JBoss Inc.
+ */
+package org.jboss.test.recoverydemo.ejb3;
+
+import javax.ejb.Remote;
+
+ at Remote
+public interface OrderFacadeRemote {
+ public boolean storeNewOrder(String orderNumber, boolean enlistFaultXAResource);
+ public void initDatabases();
+ public int[] checkDatabaseStates();
+}
Added: labs/jbosstm/workspace/istudens/RecoveryDemo/src/org/jboss/test/recoverydemo/recovery/ASFailureMode.java
===================================================================
--- labs/jbosstm/workspace/istudens/RecoveryDemo/src/org/jboss/test/recoverydemo/recovery/ASFailureMode.java (rev 0)
+++ labs/jbosstm/workspace/istudens/RecoveryDemo/src/org/jboss/test/recoverydemo/recovery/ASFailureMode.java 2010-11-16 15:11:18 UTC (rev 35995)
@@ -0,0 +1,55 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * 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,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * (C) 2008,
+ * @author JBoss Inc.
+ */
+package org.jboss.test.recoverydemo.recovery;
+
+import java.io.Serializable;
+
+/**
+ * Specification of what to do when a failure is injected.
+ * Borrowed from JBossAS Testsuite.
+ */
+public enum ASFailureMode implements Serializable
+{
+ NONE(false)
+
+ ,HALT(true) // halt the JVM
+ ,EXIT(true) // exit the JVM
+ ,SUSPEND(false) // suspend the calling thread
+ ,XAEXCEPTION(false) // fail via one of the xa exception codes
+ ;
+
+ private boolean willTerminateVM;
+
+ ASFailureMode(boolean willTerminateVM)
+ {
+ this.willTerminateVM = willTerminateVM;
+ }
+
+ public boolean willTerminateVM()
+ {
+ return willTerminateVM;
+ }
+
+ public static ASFailureMode toEnum(String mode)
+ {
+ return ASFailureMode.valueOf(mode.toUpperCase());
+ }
+}
Added: labs/jbosstm/workspace/istudens/RecoveryDemo/src/org/jboss/test/recoverydemo/recovery/ASFailureSpec.java
===================================================================
--- labs/jbosstm/workspace/istudens/RecoveryDemo/src/org/jboss/test/recoverydemo/recovery/ASFailureSpec.java (rev 0)
+++ labs/jbosstm/workspace/istudens/RecoveryDemo/src/org/jboss/test/recoverydemo/recovery/ASFailureSpec.java 2010-11-16 15:11:18 UTC (rev 35995)
@@ -0,0 +1,142 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * 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,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * (C) 2008,
+ * @author JBoss Inc.
+ */
+package org.jboss.test.recoverydemo.recovery;
+
+import java.io.Serializable;
+
+/**
+ * An ASFailureSpec is for defining different ways of generating
+ * failures and essentially consists of a mode and type.
+ *
+ * If you need to generate new kinds of failure you should
+ * modify the ASFailureMode and ASFailureType classes. Your
+ * test will be given a reference to these specifications and is
+ * responsible for interpreting their meaning.
+ *
+ * @see org.jboss.test.crashrecovery.ASCrashRecovery01.Test03 for an example
+ * @see org.jboss.test.crashrecovery.recovery.ASFailureMode
+ * @see org.jboss.test.crashrecovery.recovery.ASFailureType
+ *
+ * A failure specification is defined in ASTestConfig
+ * @see org.jboss.test.crashrecovery.taskdefs.ASTestConfig
+ *
+ * Borrowed from JBossAS Testsuite.
+ */
+public class ASFailureSpec implements Serializable
+{
+ String name;
+ ASFailureMode mode;
+ ASFailureType type;
+ String modeArg;
+ int recoveryArg;
+
+ public ASFailureSpec()
+ {
+ mode = ASFailureMode.NONE;
+ type = ASFailureType.NONE;
+ }
+
+ public ASFailureSpec(String name, ASFailureMode mode, ASFailureType type, String modeArg, int recoveryArg)
+ {
+ this.name = name;
+ this.mode = mode;
+ this.type = type;
+ this.modeArg = modeArg;
+ this.recoveryArg = recoveryArg;
+ }
+
+ public boolean willTerminateVM()
+ {
+ return mode.willTerminateVM();
+ }
+
+ public ASFailureMode getMode()
+ {
+ return mode;
+ }
+
+ public ASFailureType getType()
+ {
+ return type;
+ }
+
+ public String getModeArg()
+ {
+ return modeArg;
+ }
+
+ public int getRecoveryArg()
+ {
+ return recoveryArg;
+ }
+
+ public String getName()
+ {
+ return name;
+ }
+
+ public void setName(String name)
+ {
+ this.name = name;
+ }
+
+ public void setMode(String mode)
+ {
+ this.mode = ASFailureMode.valueOf(mode);
+ }
+
+ public void setType(String type)
+ {
+ this.type = ASFailureType.valueOf(type);
+ }
+
+ public void setModeArg(String modeArg)
+ {
+ this.modeArg = modeArg;
+ }
+
+ public void setRecoveryArg(int recoveryArg)
+ {
+ this.recoveryArg = recoveryArg;
+ }
+
+ public String toString()
+ {
+ return new StringBuilder().append(mode).append(',').append(type).append(',').append(modeArg).toString();
+ }
+
+ public boolean equals(Object o)
+ {
+ if (this == o) return true;
+ if (!(o instanceof ASFailureSpec)) return false;
+
+ ASFailureSpec that = (ASFailureSpec) o;
+
+ if (name != null ? !name.equals(that.name) : that.name != null) return false;
+
+ return true;
+ }
+
+ public int hashCode()
+ {
+ return (name != null ? name.hashCode() : 0);
+ }
+}
Added: labs/jbosstm/workspace/istudens/RecoveryDemo/src/org/jboss/test/recoverydemo/recovery/ASFailureType.java
===================================================================
--- labs/jbosstm/workspace/istudens/RecoveryDemo/src/org/jboss/test/recoverydemo/recovery/ASFailureType.java (rev 0)
+++ labs/jbosstm/workspace/istudens/RecoveryDemo/src/org/jboss/test/recoverydemo/recovery/ASFailureType.java 2010-11-16 15:11:18 UTC (rev 35995)
@@ -0,0 +1,66 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * 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,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * (C) 2008,
+ * @author JBoss Inc.
+ */
+package org.jboss.test.recoverydemo.recovery;
+
+import java.io.Serializable;
+
+/**
+ * Specification of when to inject a failure.
+ * Borrowed from JBossAS Testsuite.
+ */
+public enum ASFailureType implements Serializable
+{
+ NONE
+
+ ,PRE_PREPARE // do something before prepare is called
+
+ ,XARES_START // failures specific to the XA protocol
+ ,XARES_END
+ ,XARES_PREPARE
+ ,XARES_ROLLBACK
+ ,XARES_COMMIT
+ ,XARES_RECOVER
+ ,XARES_FORGET
+
+ ,SYNCH_BEFORE // do something before completion
+ ,SYNCH_AFTER
+ ;
+
+ public static ASFailureType toEnum(String type)
+ {
+ return ASFailureType.valueOf(type.toUpperCase());
+ }
+
+ public boolean isXA()
+ {
+ return name().startsWith("XARES");
+ }
+
+ public boolean isSynchronization()
+ {
+ return name().startsWith("SYNCH");
+ }
+
+ public boolean isPreCommit()
+ {
+ return equals(PRE_PREPARE);
+ }
+}
Added: labs/jbosstm/workspace/istudens/RecoveryDemo/src/org/jboss/test/recoverydemo/recovery/ASTestResource.java
===================================================================
--- labs/jbosstm/workspace/istudens/RecoveryDemo/src/org/jboss/test/recoverydemo/recovery/ASTestResource.java (rev 0)
+++ labs/jbosstm/workspace/istudens/RecoveryDemo/src/org/jboss/test/recoverydemo/recovery/ASTestResource.java 2010-11-16 15:11:18 UTC (rev 35995)
@@ -0,0 +1,328 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags.
+ * See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License, v. 2.1.
+ * This program is distributed in the hope that it will be useful, but WITHOUT A
+ * 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,
+ * v.2.1 along with this distribution; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * (C) 2008,
+ * @author JBoss Inc.
+ */
+package org.jboss.test.recoverydemo.recovery;
+
+import javax.transaction.xa.XAResource;
+import javax.transaction.xa.Xid;
+import javax.transaction.xa.XAException;
+import javax.transaction.Synchronization;
+import java.io.Serializable;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.HashMap;
+
+/**
+ * Simulate a variety of faults during the various phases of the XA protocol.
+ * Borrowed from JBossAS Testsuite.
+ */
+public class ASTestResource implements Synchronization, XAResource, Serializable
+{
+ private static final Map<String, XAException> xaCodeMap = new HashMap<String, XAException>();
+
+ private ASFailureType _xaFailureType = ASFailureType.NONE;
+ private ASFailureMode _xaFailureMode = ASFailureMode.NONE;
+ private String[] _args;
+ private int _suspend;
+ private int _recoveryAttempts = 1;
+ private XAException _xaException;
+ private int txTimeout = 10;
+ private Set<Xid> _xids = new HashSet<Xid>();
+ private transient boolean _isPrepared = false; // transient so it doesn't get persisted in the tx store
+
+ static
+ {
+ init();
+ }
+
+ public ASTestResource()
+ {
+ }
+
+ public ASTestResource(ASFailureSpec spec)
+ {
+ this();
+
+ if (spec == null)
+ throw new IllegalArgumentException("Invalid XA resource failure injection specification");
+
+ setFailureMode(spec.getMode(), spec.getModeArg());
+ setFailureType(spec.getType());
+ setRecoveryAttempts(spec.getRecoveryArg());
+ }
+
+ public void applySpec(String message) throws XAException
+ {
+ applySpec(message, _isPrepared);
+ }
+
+ public void applySpec(String message, boolean prepared) throws XAException
+ {
+ if (_xaFailureType.equals(ASFailureType.NONE) || _xaFailureMode.equals(ASFailureMode.NONE) || !prepared)
+ {
+ System.out.println(message + (_isPrepared ? " ... " : " recovery"));
+ return; // NB if !_isPrepared then we must have been called from the recovery subsystem
+ }
+
+ System.out.println("Applying fault injection with " + _xids.size() + " active branches");
+ if (_xaException != null)
+ {
+ System.out.println(message + " ... xa error: " + _xaException.getMessage());
+ throw _xaException;
+ }
+ else if (_xaFailureMode.equals(ASFailureMode.HALT))
+ {
+ System.out.println(message + " ... halting");
+ Runtime.getRuntime().halt(1);
+ }
+ else if (_xaFailureMode.equals(ASFailureMode.EXIT))
+ {
+ System.out.println(message + " ... exiting");
+ System.exit(1);
+ }
+ else if (_xaFailureMode.equals(ASFailureMode.SUSPEND))
+ {
+ System.out.println(message + " ... suspending for " + _suspend);
+ suspend(_suspend);
+ System.out.println(message + " ... resuming");
+ }
+ }
+
+ public String toString()
+ {
+ return _xaFailureType + ", " + _xaFailureMode + ", " + (_args != null && _args.length != 0 ? _args[0] : "");
+ }
+
+ private void suspend(int msecs)
+ {
+ try
+ {
+ Thread.sleep(msecs);
+ }
+ catch (InterruptedException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ public void setFailureMode(ASFailureMode mode, String ... args) throws IllegalArgumentException
+ {
+ _xaFailureMode = mode;
+ _args = args;
+
+ if (args != null && args.length != 0)
+ {
+ if (_xaFailureMode.equals(ASFailureMode.SUSPEND))
+ {
+ _suspend = Integer.parseInt(args[0]);
+ }
+ else if (_xaFailureMode.equals(ASFailureMode.XAEXCEPTION))
+ {
+ _xaException = xaCodeMap.get(args[0]);
+
+ if (_xaException == null)
+ _xaException = new XAException(XAException.XAER_RMFAIL);
+ }
+ }
+ }
+
+ public void setFailureType(ASFailureType type)
+ {
+ _xaFailureType = type;
+ }
+
+ public ASFailureType getFailureType()
+ {
+ return _xaFailureType;
+ }
+
+ public void setRecoveryAttempts(int _recoveryAttempts)
+ {
+ this._recoveryAttempts = _recoveryAttempts;
+ }
+
+ // Synchronizatons
+
+ public void beforeCompletion()
+ {
+ if (_xaFailureType.equals(ASFailureType.SYNCH_BEFORE))
+ try
+ {
+ applySpec("Before completion");
+ }
+ catch (XAException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public void afterCompletion(int i)
+ {
+ if (_xaFailureType.equals(ASFailureType.SYNCH_AFTER))
+ try
+ {
+ applySpec("After completion");
+ }
+ catch (XAException e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+ // XA Interface implementation
+
+ public void commit(Xid xid, boolean b) throws XAException
+ {
+ if (_xaFailureType.equals(ASFailureType.XARES_COMMIT))
+ applySpec("xa commit");
+
+ _isPrepared = false;
+ _xids.remove(xid);
+ }
+
+ public void rollback(Xid xid) throws XAException
+ {
+ if (_xaFailureType.equals(ASFailureType.XARES_ROLLBACK))
+ applySpec("xa rollback");
+
+ _isPrepared = false;
+ _xids.remove(xid);
+ }
+
+ public void end(Xid xid, int i) throws XAException
+ {
+ if (_xaFailureType.equals(ASFailureType.XARES_END))
+ applySpec("xa end");
+ }
+
+ public void forget(Xid xid) throws XAException
+ {
+ if (_xaFailureType.equals(ASFailureType.XARES_FORGET))
+ applySpec("xa forget");
+
+ _isPrepared = false;
+ _xids.remove(xid);
+ }
+
+ public int getTransactionTimeout() throws XAException
+ {
+ return txTimeout;
+ }
+
+ public boolean isSameRM(XAResource xaResource) throws XAException
+ {
+ return false;
+ }
+
+ public int prepare(Xid xid) throws XAException
+ {
+ _isPrepared = true;
+
+ if (_xaFailureType.equals(ASFailureType.XARES_PREPARE))
+ applySpec("xa prepare");
+
+ _xids.add(xid);
+
+ return XA_OK;
+ }
+
+ public Xid[] recover(int i) throws XAException
+ {
+ if (_recoveryAttempts <= 0)
+ return _xids.toArray(new Xid[_xids.size()]);
+
+ _recoveryAttempts -= 1;
+
+ if (_xaFailureType.equals(ASFailureType.XARES_RECOVER))
+ applySpec("xa recover");
+
+ return new Xid[0];
+ }
+
+ public boolean setTransactionTimeout(int txTimeout) throws XAException
+ {
+ this.txTimeout = txTimeout;
+
+ return true; // set was successfull
+ }
+
+ public void start(Xid xid, int i) throws XAException
+ {
+ _xids.add(xid);
+
+ if (_xaFailureType.equals(ASFailureType.XARES_START))
+ applySpec("xa start");
+ }
+
+ public String getEISProductName() { return "Test XAResouce";}
+
+ public String getEISProductVersion() { return "v666.0";}
+
+ @SuppressWarnings({"ThrowableInstanceNeverThrown"})
+ private static void init()
+ {
+ xaCodeMap.put("XA_HEURCOM", new XAException(XAException.XA_HEURCOM));
+ xaCodeMap.put("XA_HEURHAZ", new XAException(XAException.XA_HEURHAZ));
+ xaCodeMap.put("XA_HEURMIX", new XAException(XAException.XA_HEURMIX));
+ xaCodeMap.put("XA_HEURRB", new XAException(XAException.XA_HEURRB));
+ xaCodeMap.put("XA_NOMIGRATE", new XAException(XAException.XA_NOMIGRATE));
+ xaCodeMap.put("XA_RBBASE", new XAException(XAException.XA_RBBASE));
+ xaCodeMap.put("XA_RBCOMMFAIL", new XAException(XAException.XA_RBCOMMFAIL));
+ xaCodeMap.put("XA_RBDEADLOCK", new XAException(XAException.XA_RBDEADLOCK));
+ xaCodeMap.put("XA_RBEND", new XAException(XAException.XA_RBEND));
+ xaCodeMap.put("XA_RBINTEGRITY", new XAException(XAException.XA_RBINTEGRITY));
+ xaCodeMap.put("XA_RBOTHER", new XAException(XAException.XA_RBOTHER));
+ xaCodeMap.put("XA_RBPROTO", new XAException(XAException.XA_RBPROTO));
+ xaCodeMap.put("XA_RBROLLBACK", new XAException(XAException.XA_RBROLLBACK));
+ xaCodeMap.put("XA_RBTIMEOUT", new XAException(XAException.XA_RBTIMEOUT));
+ xaCodeMap.put("XA_RBTRANSIENT", new XAException(XAException.XA_RBTRANSIENT));
+ xaCodeMap.put("XA_RDONLY", new XAException(XAException.XA_RDONLY));
+ xaCodeMap.put("XA_RETRY", new XAException(XAException.XA_RETRY));
+ xaCodeMap.put("XAER_ASYNC", new XAException(XAException.XAER_ASYNC));
+ xaCodeMap.put("XAER_DUPID", new XAException(XAException.XAER_DUPID));
+ xaCodeMap.put("XAER_INVAL", new XAException(XAException.XAER_INVAL));
+ xaCodeMap.put("XAER_NOTA", new XAException(XAException.XAER_NOTA));
+ xaCodeMap.put("XAER_OUTSIDE", new XAException(XAException.XAER_OUTSIDE));
+ xaCodeMap.put("XAER_PROTO", new XAException(XAException.XAER_PROTO));
+ xaCodeMap.put("XAER_RMERR", new XAException(XAException.XAER_RMERR));
+ xaCodeMap.put("XAER_RMFAIL ", new XAException(XAException.XAER_RMFAIL));
+ }
+
+ public boolean isXAResource()
+ {
+ return _xaFailureType.isXA() || _xaFailureType.equals(ASFailureType.NONE);
+ }
+
+ public boolean isSynchronization()
+ {
+ return _xaFailureType.isSynchronization();
+ }
+
+ public boolean isPreCommit()
+ {
+ return _xaFailureType.isPreCommit();
+ }
+
+ public boolean expectException()
+ {
+ return _xaFailureMode.equals(ASFailureMode.XAEXCEPTION);
+ }
+}
More information about the jboss-svn-commits
mailing list