[jboss-svn-commits] JBL Code SVN: r30325 - in labs/jbosstm/branches/JBOSSTS_4_6_1_GA_CP/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
Tue Nov 24 10:53:25 EST 2009
Author: adinn
Date: 2009-11-24 10:53:25 -0500 (Tue, 24 Nov 2009)
New Revision: 30325
Added:
labs/jbosstm/branches/JBOSSTS_4_6_1_GA_CP/XTS/sar/tests/dd/scripts/ATSubordinateCrashDuringPrepare.txt
Modified:
labs/jbosstm/branches/JBOSSTS_4_6_1_GA_CP/XTS/WS-T/dev/src11/com/arjuna/wst11/stub/SubordinateDurable2PCStub.java
labs/jbosstm/branches/JBOSSTS_4_6_1_GA_CP/XTS/WSCF/classes/com/arjuna/mwlabs/wscf/model/twophase/arjunacore/subordinate/SubordinateCoordinator.java
labs/jbosstm/branches/JBOSSTS_4_6_1_GA_CP/XTS/sar/src/org/jboss/jbossts/xts/recovery/participant/at/XTSATRecoveryManagerImple.java
Log:
back ported fix to AT subordinate implementation described in JBTM-646. this closes a window between subordinate prepared and parent prepared where the old version could have left a subordinate TX record stranded in the log
Modified: labs/jbosstm/branches/JBOSSTS_4_6_1_GA_CP/XTS/WS-T/dev/src11/com/arjuna/wst11/stub/SubordinateDurable2PCStub.java
===================================================================
--- labs/jbosstm/branches/JBOSSTS_4_6_1_GA_CP/XTS/WS-T/dev/src11/com/arjuna/wst11/stub/SubordinateDurable2PCStub.java 2009-11-24 14:21:49 UTC (rev 30324)
+++ labs/jbosstm/branches/JBOSSTS_4_6_1_GA_CP/XTS/WS-T/dev/src11/com/arjuna/wst11/stub/SubordinateDurable2PCStub.java 2009-11-24 15:53:25 UTC (rev 30325)
@@ -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();
+ SubordinateCoordinator.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();
+ SubordinateCoordinator.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();
+ SubordinateCoordinator.addActiveProxy(coordinatorId);
return true;
} catch (IOException e) {
return false;
Modified: labs/jbosstm/branches/JBOSSTS_4_6_1_GA_CP/XTS/WSCF/classes/com/arjuna/mwlabs/wscf/model/twophase/arjunacore/subordinate/SubordinateCoordinator.java
===================================================================
--- labs/jbosstm/branches/JBOSSTS_4_6_1_GA_CP/XTS/WSCF/classes/com/arjuna/mwlabs/wscf/model/twophase/arjunacore/subordinate/SubordinateCoordinator.java 2009-11-24 14:21:49 UTC (rev 30324)
+++ labs/jbosstm/branches/JBOSSTS_4_6_1_GA_CP/XTS/WSCF/classes/com/arjuna/mwlabs/wscf/model/twophase/arjunacore/subordinate/SubordinateCoordinator.java 2009-11-24 15:53:25 UTC (rev 30325)
@@ -45,6 +45,7 @@
import com.arjuna.mwlabs.wscf.model.twophase.arjunacore.ACCoordinator;
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 SubordinateCoordinator getRecoveredCoordinator(String coordinatorId)
{
return recoveredCoordinators.get(coordinatorId);
}
+ public static synchronized SubordinateCoordinator[] listRecoveredCoordinators()
+ {
+ Collection<SubordinateCoordinator> values = recoveredCoordinators.values();
+ int length = values.size();
+ return values.toArray(new SubordinateCoordinator[length]);
+ }
+
/**
* this saves the status after the subtransaction commit or rollback so it can be referred to during
* afterCompletion processing.
@@ -334,6 +380,8 @@
private static final HashMap<String, SubordinateCallback> callbacks = new HashMap<String, SubordinateCallback>();
+ private static final HashMap<String, Boolean> activeProxies = new HashMap<String, Boolean>();
+
/**
* class implemented by any code which wishes to register a callabck
*/
Modified: labs/jbosstm/branches/JBOSSTS_4_6_1_GA_CP/XTS/sar/src/org/jboss/jbossts/xts/recovery/participant/at/XTSATRecoveryManagerImple.java
===================================================================
--- labs/jbosstm/branches/JBOSSTS_4_6_1_GA_CP/XTS/sar/src/org/jboss/jbossts/xts/recovery/participant/at/XTSATRecoveryManagerImple.java 2009-11-24 14:21:49 UTC (rev 30324)
+++ labs/jbosstm/branches/JBOSSTS_4_6_1_GA_CP/XTS/sar/src/org/jboss/jbossts/xts/recovery/participant/at/XTSATRecoveryManagerImple.java 2009-11-24 15:53:25 UTC (rev 30325)
@@ -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.SubordinateCoordinator;
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,9 +255,38 @@
}
}
}
+
+ // 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;
+
+ SubordinateCoordinator[] coordinators = SubordinateCoordinator.listRecoveredCoordinators();
+ for (SubordinateCoordinator 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
* direct over the table so any deletions performed during iteration need to be done
* via the iterator and need to be sure to avoid concurrent modification
@@ -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>();
Added: labs/jbosstm/branches/JBOSSTS_4_6_1_GA_CP/XTS/sar/tests/dd/scripts/ATSubordinateCrashDuringPrepare.txt
===================================================================
--- labs/jbosstm/branches/JBOSSTS_4_6_1_GA_CP/XTS/sar/tests/dd/scripts/ATSubordinateCrashDuringPrepare.txt (rev 0)
+++ labs/jbosstm/branches/JBOSSTS_4_6_1_GA_CP/XTS/sar/tests/dd/scripts/ATSubordinateCrashDuringPrepare.txt 2009-11-24 15:53:25 UTC (rev 30325)
@@ -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