[jboss-svn-commits] JBL Code SVN: r30056 - in labs/jbosstm/trunk/XTS: WSCF/classes/com/arjuna/mwlabs/wscf/model/twophase/arjunacore/subordinate and 2 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Fri Nov 6 07:07:15 EST 2009


Author: adinn
Date: 2009-11-06 07:07:14 -0500 (Fri, 06 Nov 2009)
New Revision: 30056

Added:
   labs/jbosstm/trunk/XTS/sar/tests/dd/scripts/ATSubordinateCrashDuringPrepare.txt
Modified:
   labs/jbosstm/trunk/XTS/WS-T/dev/src11/com/arjuna/wst11/stub/SubordinateDurable2PCStub.java
   labs/jbosstm/trunk/XTS/WSCF/classes/com/arjuna/mwlabs/wscf/model/twophase/arjunacore/subordinate/SubordinateATCoordinator.java
   labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/recovery/participant/at/XTSATRecoveryManagerImple.java
   labs/jbosstm/trunk/XTS/sar/tests/dd/scripts/ATHeuristicRecoveryAfterDelayedCommit.txt
   labs/jbosstm/trunk/XTS/sar/tests/dd/scripts/ATParticipantCrashAndRecover.txt
   labs/jbosstm/trunk/XTS/sar/tests/dd/scripts/ATSubordinateCrashDuringCommit.txt
Log:
removed window from AT subordinate crash recovery where subordinate TX could get orphaned and added service test script to verify that it works -- fixes JBTM-646

Modified: labs/jbosstm/trunk/XTS/WS-T/dev/src11/com/arjuna/wst11/stub/SubordinateDurable2PCStub.java
===================================================================
--- labs/jbosstm/trunk/XTS/WS-T/dev/src11/com/arjuna/wst11/stub/SubordinateDurable2PCStub.java	2009-11-06 12:05:02 UTC (rev 30055)
+++ labs/jbosstm/trunk/XTS/WS-T/dev/src11/com/arjuna/wst11/stub/SubordinateDurable2PCStub.java	2009-11-06 12:07:14 UTC (rev 30056)
@@ -102,6 +102,7 @@
                 if (status == ActionStatus.PREPARED || status == ActionStatus.COMMITTING) {
                     // ok, the commit process was not previously initiated so start it now
                     coordinator.commit();
+                    SubordinateATCoordinator.removeActiveProxy(coordinatorId);
                     status = coordinator.status();
                 }
 
@@ -150,6 +151,7 @@
                         (status == ActionStatus.ABORT_ONLY)) {
                     // ok, the rollback process was not previously initiated so start it now
                     coordinator.rollback();
+                    SubordinateATCoordinator.removeActiveProxy(coordinatorId);
                     status = coordinator.status();
                 }
             }
@@ -197,6 +199,7 @@
         // restore the subordinate coordinator id so we can check to ensure it has been committed
         try {
             coordinatorId = ios.unpackString();
+            SubordinateATCoordinator.addActiveProxy(coordinatorId);
             return true;
         } catch (IOException e) {
             return false;

Modified: labs/jbosstm/trunk/XTS/WSCF/classes/com/arjuna/mwlabs/wscf/model/twophase/arjunacore/subordinate/SubordinateATCoordinator.java
===================================================================
--- labs/jbosstm/trunk/XTS/WSCF/classes/com/arjuna/mwlabs/wscf/model/twophase/arjunacore/subordinate/SubordinateATCoordinator.java	2009-11-06 12:05:02 UTC (rev 30055)
+++ labs/jbosstm/trunk/XTS/WSCF/classes/com/arjuna/mwlabs/wscf/model/twophase/arjunacore/subordinate/SubordinateATCoordinator.java	2009-11-06 12:07:14 UTC (rev 30056)
@@ -45,6 +45,7 @@
 import com.arjuna.mwlabs.wscf.model.twophase.arjunacore.ATCoordinator;
 
 import java.util.HashMap;
+import java.util.Collection;
 
 /**
  * This class represents a specific coordination instance. It is essentially an
@@ -298,6 +299,16 @@
         recoveredCoordinators.put(coordinator.get_uid().stringForm(), null);
     }
 
+    public static synchronized void addActiveProxy(String id)
+    {
+        activeProxies.put(id, Boolean.TRUE);
+    }
+
+    public static synchronized void removeActiveProxy(String id)
+    {
+        activeProxies.remove(id);
+    }
+
     protected void setActivated()
     {
         activated = true;
@@ -308,11 +319,46 @@
         return activated;
     }
 
+    /**
+     * test whether a transaction has been restored without its proxy participant. this indicates that
+     * we crashed between preparing the suborindate TX and logging the proxy participant.
+     * @return
+     */
+    public boolean isOrphaned()
+    {
+        String id = get_uid().stringForm();
+        if (isActiveProxy(id)) {
+            return false;
+        }
+
+        // the proxy may have been removed because this tx has been resolved while we were checking
+
+        if (getRecoveredCoordinator(id) == null) {
+            return false;
+        }
+
+        // ok we have a tx but no proxy so this is really an orphan
+
+        return true;
+    }
+
+    private static synchronized boolean isActiveProxy(String proxyId)
+    {
+        return activeProxies.get(proxyId) == Boolean.TRUE;
+    }
+
     public static synchronized SubordinateATCoordinator getRecoveredCoordinator(String coordinatorId)
     {
         return recoveredCoordinators.get(coordinatorId);
     }
 
+    public static synchronized SubordinateATCoordinator[] listRecoveredCoordinators()
+    {
+        Collection<SubordinateATCoordinator> values = recoveredCoordinators.values();
+        int length = values.size();
+        return values.toArray(new SubordinateATCoordinator[length]);
+    }
+
     /**
      * this saves the status after the subtransaction commit or rollback so it can be referred to during
      * afterCompletion processing.
@@ -327,6 +373,8 @@
 
     private static final HashMap<String, SubordinateATCoordinator> recoveredCoordinators = new HashMap<String, SubordinateATCoordinator>();
 
+    private static final HashMap<String, Boolean> activeProxies = new HashMap<String, Boolean>();
+
     /**
      * we need to remove the association between parent and subordinate context at completion
      * of commit or rollback -- we use a callback mechanism keyed by transaction id to achieve this

Modified: labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/recovery/participant/at/XTSATRecoveryManagerImple.java
===================================================================
--- labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/recovery/participant/at/XTSATRecoveryManagerImple.java	2009-11-06 12:05:02 UTC (rev 30055)
+++ labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/recovery/participant/at/XTSATRecoveryManagerImple.java	2009-11-06 12:07:14 UTC (rev 30056)
@@ -7,6 +7,7 @@
 import com.arjuna.ats.arjuna.state.OutputObjectState;
 import com.arjuna.ats.arjuna.common.Uid;
 import com.arjuna.ats.arjuna.exceptions.ObjectStoreException;
+import com.arjuna.mwlabs.wscf.model.twophase.arjunacore.subordinate.SubordinateATCoordinator;
 
 import java.util.*;
 import java.io.IOException;
@@ -18,6 +19,7 @@
  * @message org.jboss.transactions.xts.recovery.participant.at.XTSATRecoveryModule_2 [org.jboss.transactions.xts.recovery.participant.at.XTSATRecoveryModule_2] exception removing recovery record {0} for WS-AT participant {1}
  * @message org.jboss.transactions.xts.recovery.participant.at.XTSATRecoveryModule_3 [org.jboss.transactions.xts.recovery.participant.at.XTSATRecoveryModule_3] exception reactivating recovered WS-AT participant {0}
  * @message org.jboss.transactions.xts.recovery.participant.at.XTSATRecoveryModule_4 [org.jboss.transactions.xts.recovery.participant.at.XTSATRecoveryModule_4] no XTS application recovery module found to help reactivate recovered WS-AT participant {0}
+ * @message org.jboss.transactions.xts.recovery.participant.at.XTSATRecoveryModule_5 [org.jboss.transactions.xts.recovery.participant.at.XTSATRecoveryModule_5] Compensating orphaned subordinate WS-AT transcation {0}
  */
 public class XTSATRecoveryManagerImple extends XTSATRecoveryManager {
     /**
@@ -253,7 +255,36 @@
                 }
             }
         }
+
+        // ok, see if we are now in a position to cull any prepared subordinate transactions
+
+        cullOrphanedSubordinates();
     }
+
+    /**
+     * look for recovered subordinate transactions which do not have an associated proxy participant
+     * rolling back any that are found. this only needs doing once after the first participant and
+     * subordinate transaction recovery passes have both completed
+     */
+    private void cullOrphanedSubordinates()
+    {
+        if (culledOrphanSubordinates || !(subordinateCoordinatorRecoveryStarted && participantRecoveryStarted)) {
+            return;
+        }
+        culledOrphanSubordinates = true;
+
+        SubordinateATCoordinator[] coordinators = SubordinateATCoordinator.listRecoveredCoordinators();
+        for (SubordinateATCoordinator coordinator : coordinators) {
+            if (coordinator.isOrphaned()) {
+                if (XTSLogger.arjLoggerI18N.isWarnEnabled())
+                {
+                    XTSLogger.arjLoggerI18N.warn("org.jboss.transactions.xts.recovery.participant.at.XTSATRecoveryModule_5",
+                            new Object[] {coordinator.get_uid().stringForm()});
+                }
+                coordinator.rollback();
+            }
+        }
+    }
     
     /**
      * return an iterator over the collection of entries in the table. n.b. this iterates
@@ -322,6 +353,9 @@
 
     public synchronized void setSubordinateCoordinatorRecoveryStarted() {
         subordinateCoordinatorRecoveryStarted = true;
+
+        // see if we are now in a position to cull any orphaned subordinate transactions
+        cullOrphanedSubordinates();
     }
 
     /**
@@ -343,6 +377,12 @@
     private boolean subordinateCoordinatorRecoveryStarted = false;
 
     /**
+     * a global flag indicating whether we have already reconciled the list of subordinate transactions
+     * against their proxy participants looking for any orphans
+     */
+    private boolean culledOrphanSubordinates = false;
+
+    /**
      * a map from participant ids to participant recovery records
      */
     private HashMap<String, ATParticipantRecoveryRecord> recoveryMap = new HashMap<String, ATParticipantRecoveryRecord>();

Modified: labs/jbosstm/trunk/XTS/sar/tests/dd/scripts/ATHeuristicRecoveryAfterDelayedCommit.txt
===================================================================
--- labs/jbosstm/trunk/XTS/sar/tests/dd/scripts/ATHeuristicRecoveryAfterDelayedCommit.txt	2009-11-06 12:05:02 UTC (rev 30055)
+++ labs/jbosstm/trunk/XTS/sar/tests/dd/scripts/ATHeuristicRecoveryAfterDelayedCommit.txt	2009-11-06 12:07:14 UTC (rev 30056)
@@ -27,7 +27,7 @@
 # JBossTS XTS implementation of the WS-AT 1.1 protocol using orchestration
 # rules. The basic scenario employs a coordinator and 3 web services
 # running in a single JVM but other variants are possible (see below). The
-# scenario is as follows (** indicates intercession by a TOAST rule):
+# scenario is as follows (** indicates intercession by a Byteman rule):
 #
 # AS boots
 # Cient starts a WS-AT transaction
@@ -114,12 +114,12 @@
 # omitting to log the transaction. In this case the participant should be
 # rolled back at restart.
 #
-# This script needs to be passed to a TOAST agent in the JVM running
+# This script needs to be passed to a Byteman agent in the JVM running
 # the coordinator service both at first boot and at reboot. Output will be
 # written to file testlog in the working directory of the AS. n.b. the rules in
 # this script only refer to code executed by the coordinator. If the client
 # (the selected XTS Service Test) or the web services are located in another
-# AS/JVM then the other JVM does not require a TOAST agent or script.
+# AS/JVM then the other JVM does not require a Byteman agent or script.
 #
 # XTS Service tests which can operate with this scenario can be selected for
 # execution at AS boot by the XTSServiceTestRunnerBean by setting system

Modified: labs/jbosstm/trunk/XTS/sar/tests/dd/scripts/ATParticipantCrashAndRecover.txt
===================================================================
--- labs/jbosstm/trunk/XTS/sar/tests/dd/scripts/ATParticipantCrashAndRecover.txt	2009-11-06 12:05:02 UTC (rev 30055)
+++ labs/jbosstm/trunk/XTS/sar/tests/dd/scripts/ATParticipantCrashAndRecover.txt	2009-11-06 12:07:14 UTC (rev 30056)
@@ -29,7 +29,7 @@
 # and 2 web services located in one JVM/AS and a coordinator located in another
 # JVM/AS but it is possible for the lcinet and web services to be lcoated in
 # separate JVMs/ASs. The scenario is as follows (note ** AS<n> indicates
-# intercession by a TOAST rule executed in a specific AS):
+# intercession by a Byteman rule executed in a specific AS):
 #
 # AS1 boots
 # AS2 boots
@@ -87,9 +87,9 @@
 # !!! N.B. this test currently fails because JBossWS Native fails to cope
 # !!! with requests for services while they are bootstrapping
 #
-# The JVMs hosting AS1 and AS2 both need to be configured to run a TOAST
+# The JVMs hosting AS1 and AS2 both need to be configured to run a Byteman
 # agent supplied with this script. If the web service(s) is relocated
-# to AS3 then it needs to be configured to run the TOAST agent instead of
+# to AS3 then it needs to be configured to run the Byteman agent instead of
 # AS1 (rules only refer to participant and coordinator code, not to the
 # XTS service test code).
 #

Modified: labs/jbosstm/trunk/XTS/sar/tests/dd/scripts/ATSubordinateCrashDuringCommit.txt
===================================================================
--- labs/jbosstm/trunk/XTS/sar/tests/dd/scripts/ATSubordinateCrashDuringCommit.txt	2009-11-06 12:05:02 UTC (rev 30055)
+++ labs/jbosstm/trunk/XTS/sar/tests/dd/scripts/ATSubordinateCrashDuringCommit.txt	2009-11-06 12:07:14 UTC (rev 30056)
@@ -27,7 +27,7 @@
 # JBossTS XTS implementation of the WS-AT 1.1 protocol using orchestration
 # rules. The basic scenario employs a coordinator, a subordinate coordinator
 # and 2 web services running in a single JVM. The scenario is as follows
-# (** indicates intercession by a TOAST rule):
+# (** indicates intercession by a Byteman rule):
 #
 # AS boots
 # Cient starts a WS-AT transaction T1
@@ -110,7 +110,7 @@
 # should run automatically and the server should be killed after the recovered
 # transaction is successfuly replayed.
 #
-# This script needs to be passed to a TOAST agent in the JVM running
+# This script needs to be passed to a Byteman agent in the JVM running
 # the coordinator service both at first boot and at reboot. Output will be
 # written to file testlog in the working directory of the AS.
 #

Copied: labs/jbosstm/trunk/XTS/sar/tests/dd/scripts/ATSubordinateCrashDuringPrepare.txt (from rev 30016, labs/jbosstm/trunk/XTS/sar/tests/dd/scripts/BASubordinateCrashDuringComplete.txt)
===================================================================
--- labs/jbosstm/trunk/XTS/sar/tests/dd/scripts/ATSubordinateCrashDuringPrepare.txt	                        (rev 0)
+++ labs/jbosstm/trunk/XTS/sar/tests/dd/scripts/ATSubordinateCrashDuringPrepare.txt	2009-11-06 12:07:14 UTC (rev 30056)
@@ -0,0 +1,719 @@
+##############################################################################
+# JBoss, Home of Professional Open Source
+# Copyright 2009, Red Hat Middleware LLC, and individual contributors
+# 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.
+#
+# @authors Andrew Dinn
+#
+# BA Subordinate Transaction Crash During Prepare
+#
+# This script automates testing of a specific recovery scenario for the
+# JBossTS XTS implementation of the WS-AT 1.1 protocol using orchestration
+# rules. The basic scenario employs a coordinator, a subordinate coordinator
+# and 2 web services running in a single JVM, the second one employing local
+# (subordinate) coordination. It checks that the transaction rolls back
+# all prepared participants afetr crashing in the middle of prepare.
+# The crash happens after the subordinate transaction has been prepared and
+# logged to disk but before its proxy participant is able to write a log record.
+# The scenario is as follows
+# (** indicates intercession by a Byteman rule):
+#
+# AS boots
+# Cient starts a WS-AT transaction T1
+# Client invokes web service S1 with enlist durable request
+# S1 registers Participant P1 in T1
+# Client invokes subordinate web service S2 with enlist durable request
+# S2 creates a subordinate BA transaction T2
+# S2 registers pseudo-participant PP in T1
+# S2 registers Participant P2 in T2
+# Client invokes subordinate web service S2 with enlist durable request
+# S2 resumes T2
+# S2 registers Participant P3 in T2
+#
+# Client initiates transaction close for T1
+#
+# Coordinator initiates prepare of participant P1
+# ** Rule system logs dispatch of prepare to P1
+# ** Rule system logs receipt of prepared from P1
+#
+# Coordinator initiates prepare of subordinate participant PP
+# ** Rule system logs dispatch of prepare to PP
+# PP calls subordinate coordinator prepare
+# ** Rule system logs call to prepare
+#
+# Subordinate coordinator initiates prepare of participant P2
+# ** Rule system logs dispatch of prepare to P1
+# ** Rule system logs receipt of prepared from P1
+# Subordinate coordinator initiates prepare of participant P3
+# ** Rule system logs dispatch of prepare to P1
+# ** Rule system logs receipt of prepared from P1
+# Subordinate coordinator writes T2 to log
+# Subordinate coordinator complete returns
+# ** Rule system intercepts return and crashes JVM
+#
+# AS reboots
+# Recovery system starts after 2 minutes
+# Recovery system recreates transaction T2
+# ** Rule system traces create
+# ** Rule system traces create
+# Recovery system recreates participant engine for P1
+# ** Rule system traces create
+# Recovery system recreates participant engine for P2
+# ** Rule system traces create
+# Recovery system recreates participant engine for P3
+# ** Rule system traces create
+# Recovery system recreates coordinator engine for P2
+# ** Rule system traces create
+# Recovery system recreates coordinator engine for P3
+# ** Rule system traces create
+#
+# (parallel optional)
+# prepared sent for P2/P3 and ignored during recovery
+# ** Rule system traces dispatch of prepared
+# (parallel)
+# Recovery system detects missing proxy P2 for transaction T2
+# Recovery system calls rollback for subordinate coordinator
+# ** Rule system traces call to rollback
+#
+# Coordinator sends rollback to P2
+# ** Rule system traces dispatch of rollback
+# P2 replies with aborted
+# ** Rule system traces dispatch of aborted
+# ** Rule system detects removal of P2
+#
+# Coordinator sends rollback to P3
+# ** Rule system traces dispatch of rollback
+# P3 replies with aborted
+# ** Rule system traces dispatch of aborted
+# ** Rule system detects removal of P3
+# Subordinate coordinator rol;back call returns
+# ** Rule system traces return from rollback
+#
+# Recovery system removes transaction T2
+# ** Rule system traces removal of transaction
+# (parallel)
+# completed sent for P1
+# ** Rule system traces dispatch of completed
+# rollback sent to P1
+# ** Rule system traces dispatch of rollback
+# ** Rule system detects removal of P1
+# (end parallel)
+#
+# ** Rule system detects 3 participant deletes and 1 tx delete and kills JVM
+#
+# Use of this script
+#
+# The default way of exercising this test is to deploy the xtstest war
+# to a single AS and configure it to run the relevant XTS Service Test.
+# The web services and coordinator will be located with the client.
+# The number of participants and subordinate participants must be
+# exactly 3. The  web service(s), client (i.e. the XTS Service Test which
+# drives the test) and coordinator and subordinate coordinator service must
+# be colocated for this script to work (it is possible to distribute all of
+# these agents if desired but that woud lrequire more complex script rules).
+# The AS should crash when the client closes. At reboot the rest of the test
+# should run automatically and the server should be killed after the recovered
+# transaction is successfuly replayed.
+#
+# This script needs to be passed to a Byteman agent in the JVM running
+# the coordinator service both at first boot and at reboot. Output will be
+# written to file testlog in the working directory of the AS.
+#
+# XTS Service tests which can operate with this scenario can be selected for
+# execution at AS boot by the XTSServiceTestRunnerBean by setting system
+# property
+#    org.jboss.jbossts.xts.servicetests.XTSServiceTestName
+# to the name of a class which will execute the test. This property must
+# be defined in the JVM running the AS to which the xtstest war is deployed
+# i.e. the client AS. n.b. if the client is colocated with the coordinator then
+# this property must be left undefined at AS reboot otherwise the client
+# will run again, starting a new TX which may interfere with recovery of the
+# crashed TX. It is also possible to run the service test using the form
+# interface provided on the xtstest war's main index page.
+#
+# Available tests include:
+#
+# org.jboss.jbossts.xts.servicetests.test.at.subordinate.MultiParticipantPrepareAndCommitTest
+# this test starts an activity then registers a durable participant with the service whose location is defined by
+# system property:
+#    org.jboss.jbossts.xts.servicetests.ServiceURL1
+# if this is not set the value used defaults to
+#    http://localhost:8080/xtstest/xtsservicetest1
+# the test then registers two durable participants with a second web service (which must install a
+# subordinate transaction) whose location is defined system property:
+#    org.jboss.jbossts.xts.servicetests.serviceURL1
+# if this is not set the value used defaults to
+#    http://localhost:8080/xtstest/xtssubservicetest1
+# The test then closes the transaction
+#
+# Expected output
+#
+# After the first boot the JVM should exit leaving the following in file testlog
+# (the number and order of entries depends upon how many and which type of participants
+# are enlisted)
+#
+#   prepare sent for participant XXXXXX
+#   prepare received for participant XXXXXX
+#   prepared sent for participant XXXXXX
+#   prepared received for participant XXXXXX
+#   prepare sent for participant XXXXXX
+#   prepare received for participant XXXXXX
+#   prepare called for pseudo participant XXXXXX
+#   prepare sent for participant XXXXXX
+#   prepare received for participant XXXXXX
+#   prepared sent for participant XXXXXX
+#   prepared received for participant XXXXXX
+#   prepare returned for subordinate transaction XXXXXX
+#   saved to disk transaction XXXXXX
+#   prepare returned for pseudo participant XXXXXX
+#   JVM exit
+#
+# n.b. there should be at least one prepare/prepared sent/received message received for each participant
+#      there should be at least one prepare called/prepare returned message for the pseudo participant
+#
+# and in some cases there may be repeat messages
+#
+# After reboot the JVM should exit leaving output in the following format in file
+# testlog.
+#
+#   prepare sent for participant XXXXXX
+#   prepare received for participant XXXXXX
+#   prepared sent for participant XXXXXX
+#   prepared received for participant XXXXXX
+#   prepare sent for participant XXXXXX
+#   prepare received for participant XXXXXX
+#   prepare called for pseudo participant XXXXXX
+#   prepare sent for participant XXXXXX
+#   prepare received for participant XXXXXX
+#   prepared sent for participant XXXXXX
+#   prepared received for participant XXXXXX
+#   prepare returned for subordinate transaction XXXXXX
+#   saved to disk transaction XXXXXX
+#   prepare returned for pseudo participant XXXXXX
+#   JVM exit
+#   created recovered participant engine XXXXXX
+#   created recovered participant engine XXXXXX
+#   created recovered participant engine XXXXXX
+#   created recovered coordinator engine XXXXXX
+#   created recovered coordinator engine XXXXXX
+#   reinstated prepared subordinate transaction XXXXXX
+#
+#   (parallel -- optional and may be repeated depending upon timing)
+#   completed sent for participant P2/P3
+#   completed received for participant P2/P3
+#   (parallel)
+#   completed sent for participant P1
+#   completed received for participant P1
+#   rollback sent for participant P1
+#   rollback received for participant P1
+#   (parallel)
+#   rollback called for pseudo participant XXXXXX
+#   rollback called for subordinate transaction XXX
+#   rollback sent for Participant XXXXXX
+#   rollback received for Participant XXXXXX
+#   aborted sent for Participant XXXXXX
+#   aborted received for Participant XXXXXX
+#   rollback sent for Participant XXXXXX
+#   rollback received for Participant XXXXXX
+#   aborted sent for Participant XXXXXX
+#   aborted received for Participant XXXXXX
+#   rollback returned for subordinate transaction XXX
+#   rollback completed for pseudo participant XXXXXX
+#   removed transaction XXXXXX
+#   (end parallel)
+#
+#   JVM exit
+#
+#######################################################################
+# This rule opens a file for the trace output during XTS startup
+# It will be opened for append at reboot so messages from both runs
+# will go to this file
+#
+RULE open trace file
+CLASS org.jboss.jbossts.XTSService
+METHOD start()
+BIND NOTHING
+IF TRUE
+DO openTrace("log", "testlog")
+ENDRULE
+
+#######################################################################
+# This rule creates a counter used to track the number of participant
+# records which have been deleted
+RULE create participant deletes counter
+CLASS org.jboss.jbossts.XTSService
+METHOD start()
+BIND NOTHING
+IF TRUE
+DO createCounter("participant deletes")
+ENDRULE
+
+#######################################################################
+# This rule resets the periodic recovery wait period to 10 seconds
+# in order to speed up the test
+#
+RULE reset periodic recovery wait time
+CLASS com.arjuna.ats.arjuna.common.RecoveryEnvironmentBean
+METHOD getPeriodicRecoveryPeriod()
+AT ENTRY
+IF TRUE
+DO return 10
+ENDRULE
+
+#######################################################################
+## rules for first run of AS
+
+#######################################################################
+# This rule is triggered when a Coordinator engine
+# (CoordinatorEngine) is requested to send a prepare message. It
+# traces the call.
+
+RULE trace send participant prepare
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorEngine
+METHOD prepare
+AFTER SYNCHRONIZE
+BIND engine:CoordinatorEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("prepare sent for Coordinator engine " + identifier),
+   traceln("log", "prepare sent for Coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a Coordinator engine
+# (CoordinatorEngine) receives a prepared message. It traces the call.
+
+RULE trace receive participant prepared
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorEngine
+METHOD prepared(Notification, MAP, ArjunaContext)
+AT ENTRY
+BIND engine:CoordinatorEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("prepared received for Coordinator engine " + identifier),
+   traceln("log", "prepared received for Coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a participant
+# (ParticipantEngine) receives a prepare message. It
+# traces the call.
+
+RULE trace receive participant prepare
+CLASS com.arjuna.wst11.messaging.engines.ParticipantEngine
+METHOD prepare
+AFTER SYNCHRONIZE
+BIND engine:ParticipantEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("prepare received for participant " + identifier),
+   traceln("log", "prepare received for participant " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a Participant
+# (ParticipantEngine) is requested to send a prepared message. It
+# traces the call.
+
+RULE trace send Participant prepared
+CLASS com.arjuna.wst11.messaging.engines.ParticipantEngine
+METHOD sendPrepared(boolean)
+AT INVOKE sendPrepared
+BIND engine:ParticipantEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("prepared sent for Participant " + identifier),
+   traceln("log", "prepared sent for Participant " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a Coordinator engine
+# (CoordinatorEngine) is requested to send a rollback message. It
+# traces the call.
+
+RULE trace send Participant rollback
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorEngine
+METHOD rollback
+AFTER SYNCHRONIZE
+BIND engine:CoordinatorEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("rollback sent for Coordinator engine " + identifier),
+   traceln("log", "rollback sent for Coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a Coordinator engine
+# (CoordinatorEngine) receives an aborted message. It traces the call.
+
+RULE trace receive Participant aborted
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorEngine
+METHOD aborted(Notification, MAP, ArjunaContext)
+AT ENTRY
+BIND engine:CoordinatorEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("aborted received for Coordinator engine " + identifier),
+   traceln("log", "aborted received for Coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a Participant
+# (ParticipantEngine) receives a rollback message. It
+# traces the call.
+
+RULE trace receive Participant rollback
+CLASS com.arjuna.wst11.messaging.engines.ParticipantEngine
+METHOD rollback
+AFTER SYNCHRONIZE
+BIND engine:ParticipantEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("rollback received for Participant " + identifier),
+   traceln("log", "rollback received for Participant " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a Participant
+# (ParticipantEngine) is requested to send an aborted message. It
+# traces the call.
+
+RULE trace send Participant aborted
+CLASS com.arjuna.wst11.messaging.engines.ParticipantEngine
+METHOD sendAborted(boolean)
+AT INVOKE sendAborted
+BIND engine:ParticipantEngine = $0,
+     identifier:String = engine.getId()
+IF TRUE
+DO debug("aborted sent for Participant " + identifier),
+   traceln("log", "aborted sent for Participant " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate pseudo participant
+# (SubordinateDurable2PCStub) is requested to send a prepared message. It
+# traces the call.
+
+RULE trace subordinate participant stub prepare
+CLASS com.arjuna.wst11.stub.SubordinateDurable2PCStub
+METHOD prepare
+AT ENTRY
+BIND NOTHING
+IF TRUE
+DO debug("prepare called for pseudo-participant " + $0),
+   traceln("log", "prepare called for pseudo-participant " + $0)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate pseudo participant
+# (SubordinateDurable2PCStub) has forwarded a prepare message. It
+# kills the JVM.
+
+RULE trace subordinate participant stub prepare 2
+CLASS com.arjuna.wst11.stub.SubordinateDurable2PCStub
+METHOD prepare
+AFTER INVOKE prepare
+BIND NOTHING
+IF TRUE
+DO traceln("log", "JVM exit"),
+   debug("JVM exit"),
+   killJVM()
+ENDRULE
+
+#######################################################################
+## rules for reboot run of AS
+
+#######################################################################
+# This rule is triggered when a Coordinator engine (CoordinatorEngine)
+# is created from details located in the log record. It traces the
+# create operation. The trigger location is at entry but the rule
+# should only be triggered after calling the super constructor
+
+RULE trace Coordinator engine create
+CLASS com.arjuna.wst11.messaging.engines.CoordinatorEngine
+METHOD <init>(String, boolean, W3CEndpointReference, boolean, State)
+AT ENTRY
+BIND identifier = $1,
+     recovered=$4
+IF recovered
+DO debug("created recovered Coordinator engine " + identifier),
+   traceln("log", "created recovered Coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a Participant (ParticipantEngine)
+# is created from details located in the log record. It traces the
+# create operation. The trigger location is at entry but the rule
+# should only be triggered after calling the super constructor
+
+RULE trace Participant create
+CLASS com.arjuna.wst11.messaging.engines.ParticipantEngine
+METHOD <init>(Participant, String, State, W3CEndpointReference, boolean)
+AT ENTRY
+BIND identifier = $2,
+     recovered=$5
+IF recovered
+DO debug("created recovered Participant engine " + identifier),
+   traceln("log", "created recovered Participant engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a Coordinator processor
+# (CoordinatorProcessorImpl) sends a rollback.
+# This happens during replay of a prepared TX from
+# the log. It traces the call.
+
+RULE trace Participant send rollback
+CLASS com.arjuna.wst11.messaging.CoordinatorProcessorImpl
+METHOD prepared(Notification, MAP, ArjunaContext)
+AT CALL sendRollback
+BIND identifier:String = $3.getInstanceIdentifier().getInstanceIdentifier()
+IF TRUE
+DO debug("sent rollback for unknown Coordinator engine " + identifier),
+   traceln("log", "sent rollback for unknown Coordinator engine " + identifier)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate pseudo participant
+# (SubordinateDurable2PCStub) is requested to forward a rollback message. It
+# traces the call.
+
+RULE trace subordinate participant stub rollback
+CLASS com.arjuna.wst11.stub.SubordinateDurable2PCStub
+METHOD rollback
+AT ENTRY
+BIND NOTHING
+IF TRUE
+DO debug("rollback called for pseudo-participant " + $0),
+   traceln("log", "rollback called for pseudo-participant " + $0)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate pseudo participant
+# (SubordinateDurable2PCStub) forwards a rollback message to its subordinate
+# coordinator during recovery. It traces the call.
+
+RULE trace subordinate participant stub rollback forward
+CLASS com.arjuna.wst11.stub.SubordinateDurable2PCStub
+METHOD rollback
+AT INVOKE rollback 2
+BIND NOTHING
+IF TRUE
+DO debug("forwarding rollback or pseudo-participant " + $0 + " as rollback to subordinate coordinator"),
+   traceln("log", "forwarding rollback for pseudo-participant " + $0 + " as rollback to subordinate coordinator")
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate pseudo participant
+# (SubordinateDurable2PCStub) throws an error from its rollback method
+# because the subordinate coordinator has not yet been recovered. It
+# traces the throw.
+
+RULE trace subordinate participant stub rollback with no coordinator
+CLASS com.arjuna.wst11.stub.SubordinateDurable2PCStub
+METHOD rollback
+AT THROW
+BIND NOTHING
+IF TRUE
+DO debug("throw during rollback for pseudo-participant " + $0 + " with no subordinate coordinator"),
+   traceln("log", "throw during rollback for pseudo-participant " + $0 + " with no subordinate coordinator")
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate pseudo participant
+# (SubordinateDurable2PCStub) throws an error from its rollback method
+# because the subordinate coordinator has not yet been activated. It
+# traces the throw.
+
+
+RULE trace subordinate participant stub rollback with unactivated coordinator
+CLASS com.arjuna.wst11.stub.SubordinateDurable2PCStub
+METHOD rollback
+AT THROW 2
+BIND NOTHING
+IF TRUE
+DO debug("throw during rollback for pseudo-participant " + $0 + " with unactivated subordinate coordinator"),
+   traceln("log", "throw during rollback for pseudo-participant " + $0 + " with unactivated subordinate coordinator")
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate pseudo participant
+# (SubordinateDurable2PCStub) returns from frowarding a rollback message. It
+# traces the call.
+
+RULE trace subordinate participant stub rollback return
+CLASS com.arjuna.wst11.stub.SubordinateDurable2PCStub
+METHOD rollback
+AT EXIT
+BIND NOTHING
+IF TRUE
+DO debug("rollback completed for pseudo-participant " + $0),
+   traceln("log", "rollback completed for pseudo-participant " + $0)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate coordinator
+# (SubordinateATCoordinator) calls prepare during completion. It
+# traces the call.
+
+RULE trace subordinate coordinator prepare
+CLASS com.arjuna.mwlabs.wscf.model.twophase.arjunacore.subordinate.SubordinateATCoordinator
+METHOD prepare
+AT INVOKE prepare
+BIND uid = $0.get_uid()
+IF TRUE
+DO debug("prepare for subordinate transaction " + uid),
+   traceln("log", "prepare for subordinate transaction " + uid)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate coordinator
+# (SubordinateCoordinator) is requested to perform a rollback. It
+# traces the call.
+
+RULE trace subordinate coordinator close
+CLASS com.arjuna.mwlabs.wscf.model.twophase.arjunacore.subordinate.SubordinateATCoordinator
+METHOD rollback
+AT ENTRY
+BIND NOTHING
+IF TRUE
+DO debug("rollback called for subordinate coordinator " + $0),
+   traceln("log", "rollback called for subordinate coordinator " + $0)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a subordinate coordinator
+# (SubordinateCoordinator) is requested to perform a close. It
+# traces the call.
+
+RULE trace subordinate coordinator rollback 2
+CLASS com.arjuna.mwlabs.wscf.model.twophase.arjunacore.subordinate.SubordinateATCoordinator
+METHOD rollback
+AT EXIT
+BIND NOTHING
+IF TRUE
+DO debug("rollback returned for subordinate coordinator " + $0),
+   traceln("log", "rollback returned for subordinate coordinator " + $0)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when the recovery system finds a PREPARED
+# parent activity in the log and reruns the phase 2 commit operation.
+# It prints a message which can be used to verify that the test has
+# progressed as expected and creates a countdown used to detect exit of
+# both transactions
+
+RULE trace prepared replay
+CLASS org.jboss.jbossts.xts.recovery.coordinator.at.RecoveryATCoordinator
+METHOD replayPhase2
+AT INVOKE phase2Commit
+BIND coordinator = $0,
+     uid : Uid = coordinator.identifier(),
+     status : int = coordinator.status()
+IF (status == com.arjuna.ats.arjuna.coordinator.ActionStatus.PREPARED)
+     OR
+     (status == com.arjuna.ats.arjuna.coordinator.ActionStatus.COMMITTING)
+DO debug("replaying commit for prepared transaction " + uid),
+   traceln("log", "replaying commit for prepared transaction " + uid),
+   createCountDown("exit countdown", 1)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when the recovery system finds a PREPARED
+# subordinate activity in the log. It prints a message which can be
+# used to verify that the test has progressed as expected
+
+RULE trace subordinate prepared replay
+CLASS org.jboss.jbossts.xts.recovery.coordinator.at.RecoverySubordinateATCoordinator
+METHOD replayPhase2
+AT ENTRY
+BIND coordinator = $0,
+     uid : Uid = coordinator.identifier(),
+     status : int = coordinator.status()
+IF (status == com.arjuna.ats.arjuna.coordinator.ActionStatus.PREPARED)
+     OR
+     (status == com.arjuna.ats.arjuna.coordinator.ActionStatus.COMMITTING)
+DO debug("reinstated prepared subordinate transaction " + uid),
+   traceln("log", "reinstated prepared subordinate transaction " + uid)
+ENDRULE
+
+#######################################################################
+# This rule is triggered when a TX is saved to disk during prepare.
+
+RULE trace TX save at prepare
+CLASS com.arjuna.ats.arjuna.coordinator.BasicAction
+METHOD prepare(boolean)
+AFTER CALL save_state
+BIND action : BasicAction = $0,
+     uid  = action.get_uid()
+IF TRUE
+DO traceln("log", "saved to disk transaction " + uid),
+   debug("saved to disk transaction " + uid)
+ENDRULE
+
+#######################################################################
+# This rule is called when removing a transaction from the log. It
+# ensures that the JVM exits but only after we have seen all the
+# necessary aborted messages
+
+RULE trace remove committed state and exit JVM
+CLASS com.arjuna.ats.arjuna.coordinator.BasicAction
+METHOD updateState
+AFTER CALL remove_committed
+BIND action : BasicAction = $0,
+     uid  = action.get_uid(),
+     dummy = flag("tx removed")
+IF readCounter("participant deletes") == 3
+DO traceln("log", "JVM exit"),
+   debug("JVM exit"),
+   killJVM()
+ENDRULE
+
+#######################################################################
+# This rule is called when deleting a participant record from the log.
+# It ensures that the JVM exits but only after we have seen 3 deletes
+# and also seen the tx removed
+
+RULE trace delete participant and exit JVM
+CLASS org.jboss.jbossts.xts.recovery.participant.at.XTSATRecoveryManagerImple
+METHOD deleteParticipantRecoveryRecord
+AFTER CALL remove_committed
+BIND dummy = flag("tx removed")
+IF incrementCounter("participant deletes") == 3 &&
+   flagged("tx removed")
+DO traceln("log", "JVM exit"),
+   debug("JVM exit"),
+   killJVM()
+ENDRULE
+
+#######################################################################
+# This rule is triggered when the recovery system deletes an
+# activity from the log. It prints a message which can be used to
+# verify that the test has completed.
+
+RULE trace remove committed state
+CLASS com.arjuna.ats.arjuna.coordinator.BasicAction
+METHOD updateState
+AFTER CALL remove_committed
+BIND action : BasicAction = $0,
+     uid  = action.get_uid()
+IF TRUE
+DO traceln("log", "removed transaction " + uid),
+   debug("removed transaction " + uid)
+ENDRULE



More information about the jboss-svn-commits mailing list