[jboss-svn-commits] JBL Code SVN: r27633 - in labs/jbosstm/trunk/XTS: recovery and 14 other directories.
jboss-svn-commits at lists.jboss.org
jboss-svn-commits at lists.jboss.org
Mon Jul 6 10:30:00 EDT 2009
Author: adinn
Date: 2009-07-06 10:30:00 -0400 (Mon, 06 Jul 2009)
New Revision: 27633
Added:
labs/jbosstm/trunk/XTS/recovery/
labs/jbosstm/trunk/XTS/recovery/build.xml
labs/jbosstm/trunk/XTS/recovery/src/
labs/jbosstm/trunk/XTS/recovery/src/org/
labs/jbosstm/trunk/XTS/recovery/src/org/jboss/
labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/
labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/
labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/logging/
labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/logging/XTSLogger.java
labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/recovery/
labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/recovery/coordinator/
labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/recovery/participant/
labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/recovery/participant/at/
labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/recovery/participant/at/ATParticipantRecoveryModule.java
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/XTSATSubordinateRecoveryModule.java
labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/recovery/participant/ba/
labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/recovery/participant/ba/BAParticipantRecoveryModule.java
labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/recovery/participant/ba/XTSBARecoveryManagerImple.java
Removed:
labs/jbosstm/trunk/XTS/sar/src/org/jboss/jbossts/xts/logging/XTSLogger.java
labs/jbosstm/trunk/XTS/sar/src/org/jboss/jbossts/xts/recovery/coordinator/
labs/jbosstm/trunk/XTS/sar/src/org/jboss/jbossts/xts/recovery/participant/at/ATParticipantRecoveryModule.java
labs/jbosstm/trunk/XTS/sar/src/org/jboss/jbossts/xts/recovery/participant/at/XTSATRecoveryManagerImple.java
labs/jbosstm/trunk/XTS/sar/src/org/jboss/jbossts/xts/recovery/participant/at/XTSATSubordinateRecoveryModule.java
labs/jbosstm/trunk/XTS/sar/src/org/jboss/jbossts/xts/recovery/participant/ba/BAParticipantRecoveryModule.java
labs/jbosstm/trunk/XTS/sar/src/org/jboss/jbossts/xts/recovery/participant/ba/XTSBARecoveryManagerImple.java
Modified:
labs/jbosstm/trunk/XTS/build.xml
Log:
separated recovery code into its own tree. it was just lumped in with the sar code because it need to be built after the other modules
Modified: labs/jbosstm/trunk/XTS/build.xml
===================================================================
--- labs/jbosstm/trunk/XTS/build.xml 2009-07-06 14:14:03 UTC (rev 27632)
+++ labs/jbosstm/trunk/XTS/build.xml 2009-07-06 14:30:00 UTC (rev 27633)
@@ -146,7 +146,10 @@
</target>
<!-- Project targets - must add all module names to each target -->
- <target name="build-projects" depends="com.arjuna.mwlabs.xts.init, com.arjuna.mwlabs.xts.wsas.build, com.arjuna.mwlabs.xts.ws-c.build, com.arjuna.mwlabs.xts.wscf.build, com.arjuna.mwlabs.xts.ws-t.build, com.arjuna.mwlabs.xts.wstx.build, htdocs">
+ <target name="build-projects" depends="com.arjuna.mwlabs.xts.init, com.arjuna.mwlabs.xts.wsas.build,
+ com.arjuna.mwlabs.xts.ws-c.build, com.arjuna.mwlabs.xts.wscf.build,
+ com.arjuna.mwlabs.xts.ws-t.build, com.arjuna.mwlabs.xts.wstx.build,
+ org.jboss.jbossts.xts.recovery.build, htdocs">
</target>
@@ -179,7 +182,8 @@
<fileset dir="WS-C/build/dev/lib" includes="*.jar"/>
<fileset dir="WSCF/build/lib" includes="*.jar"/>
<fileset dir="WS-T/build/dev/lib" includes="*.jar"/>
- <fileset dir="WSTX/build/lib" includes="*.jar"/>
+ <fileset dir="WSTX/build/lib" includes="*.jar"/>
+ <fileset dir="recovery/build/lib" includes="*.jar"/>
</path>
<javadoc
@@ -203,7 +207,8 @@
<fileset dir="WS-C/build/dev/lib" includes="*.jar"/>
<fileset dir="WSCF/build/lib" includes="*.jar"/>
<fileset dir="WS-T/build/dev/lib" includes="*.jar"/>
- <fileset dir="WSTX/build/lib" includes="*.jar"/>
+ <fileset dir="WSTX/build/lib" includes="*.jar"/>
+ <fileset dir="recovery/build/lib" includes="*.jar"/>
</copy>
<mkdir dir="${com.arjuna.mwlabs.installationdirectory}/lib/ext"/>
<copy todir="${com.arjuna.mwlabs.installationdirectory}/lib/ext">
@@ -314,7 +319,8 @@
com.arjuna.mwlabs.xts.wscf.clean,
com.arjuna.mwlabs.xts.ws-t.clean,
com.arjuna.mwlabs.xts.wstx.clean,
- com.arjuna.mwlabs.xts.sar.clean,
+ com.arjuna.mwlabs.xts.wstx.clean,
+ org.jboss.jbossts.xts.recovery.clean,
com.arjuna.mwlabs.xts.interop-tests.clean">
<delete dir="${com.arjuna.mwlabs.xts.htdocs.dest}"/>
@@ -345,10 +351,14 @@
</ant>
</target>
- <target name="com.arjuna.mwlabs.xts.wstx.build">
- <ant dir="WSTX"/>
- </target>
+ <target name="com.arjuna.mwlabs.xts.wstx.build">
+ <ant dir="WSTX"/>
+ </target>
+ <target name="org.jboss.jbossts.xts.recovery.build">
+ <ant dir="recovery"/>
+ </target>
+
<target name="com.arjuna.mwlabs.xts.sar.build">
<!-- by default we build 1.0 and 1.1 for ease of testing,
but release bundles should use -Dsartype=sar-11 so that
@@ -399,10 +409,14 @@
<ant dir="WS-T" target="clean"/>
</target>
- <target name="com.arjuna.mwlabs.xts.wstx.clean">
- <ant dir="WSTX" target="clean"/>
- </target>
+ <target name="com.arjuna.mwlabs.xts.wstx.clean">
+ <ant dir="WSTX" target="clean"/>
+ </target>
+ <target name="org.jboss.jbossts.xts.recovery.clean">
+ <ant dir="recovery" target="clean"/>
+ </target>
+
<target name="com.arjuna.mwlabs.xts.sar.clean">
<ant dir="sar" target="clean"/>
</target>
Copied: labs/jbosstm/trunk/XTS/recovery/build.xml (from rev 27481, labs/jbosstm/trunk/XTS/sar/build.xml)
===================================================================
--- labs/jbosstm/trunk/XTS/recovery/build.xml (rev 0)
+++ labs/jbosstm/trunk/XTS/recovery/build.xml 2009-07-06 14:30:00 UTC (rev 27633)
@@ -0,0 +1,229 @@
+<!--
+ JBoss, Home of Professional Open Source
+ Copyright 2007, 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) 2007,
+ @author JBoss Inc.
+-->
+<project name="recovery" default="jar" basedir=".">
+ <!-- Set module name -->
+ <property name="modulename" value="recovery"/>
+
+ <!-- Set default properties filename -->
+ <property name="org.jboss.jbossts.xts.recovery.properties" value="recovery.properties"/>
+
+ <!-- Load Build Properties File -->
+ <property file="${org.jboss.jbossts.xts.recovery.properties}"/>
+
+ <!-- Set property defaults -->
+ <property environment="env"/>
+ <property name="jboss.home" value="${env.JBOSS_HOME}"/>
+ <property name="jboss.server" value="default"/>
+ <property name="jboss.lib.dir" location="${jboss.home}/lib"/>
+ <property name="jboss.client.lib.dir" location="${jboss.home}/client"/>
+ <property name="jboss.server.dir" location="${jboss.home}/server/${jboss.server}"/>
+ <property name="jboss.server.lib.dir" location="${jboss.server.dir}/lib"/>
+ <property name="jboss.common.lib.dir" location="${jboss.home}/common/lib"/>
+
+ <!-- Path names -->
+ <property name="org.jboss.jbossts.xts.recovery.src" value="src"/>
+ <property name="org.jboss.jbossts.xts.recovery.dest.root" value="build"/>
+ <property name="org.jboss.jbossts.xts.recovery.dest" value="build/classes"/>
+ <property name="org.jboss.jbossts.xts.recovery.jar.dest" value="build/lib"/>
+ <property name="org.jboss.jbossts.xts.recovery.htdocs.dest" value="build/htdocs"/>
+
+ <property name="com.arjuna.buildsystem.dir" location="../../antbuildsystem"/>
+ <property name="com.arjuna.jta.install" location="../../install"/>
+
+ <property name="com.arjuna.buildsystem.lib" location="${com.arjuna.buildsystem.dir}/build/lib"/>
+ <property name="com.arjuna.jta.install.lib" location="${com.arjuna.jta.install}/lib"/>
+ <property name="com.arjuna.jta.install.ext" location="${com.arjuna.jta.install.lib}/ext"/>
+ <property name="com.arjuna.xts.ext" location="../ext"/>
+
+ <property name="com.arjuna.buildsystem.lib.jars" value="buildsystem.jar"/>
+
+ <property name="jta.lib.jars" value="jbossjta.jar jbossjts.jar"/>
+ <property name="jta.ext.jars" value="jbossts-common.jar"/>
+ <property name="jta.ext.compile.jars" value="commons-logging.jar"/>
+ <condition property="cxf.client.lib.jars" value="cxf-api.jar saaj-api.jar jaxrpc-api.jar jaxws-api.jar
+ geronimo-ws-metadata_2.0_spec.jar">
+ <isset property="cxf.build"/>
+ </condition>
+ <property name="jboss.client.lib.jars" value="jaxb-api.jar jboss-javaee.jar jbossws-native-jaxrpc.jar
+ jbossws-native-jaxws.jar jbossws-client.jar stax-api.jar jbossws-native-saaj.jar
+ jbossws-native-jaxws-ext.jar jbossws-native-core.jar jbossws-common.jar jboss-logging-spi.jar ${cxf.client.lib.jars}"/>
+ <property name="jboss.common.lib.jars" value="servlet-api.jar"/>
+ <property name="jboss.lib.jars" value="dom4j.jar"/>
+
+ <property name="wsas.libs" value="wsas.jar"/>
+ <property name="wsc.libs" value="ws-c.jar"/>
+ <property name="wsc-api.libs" value="ws-c-api.jar"/>
+ <property name="wscf.libs" value="wscf.jar"/>
+ <property name="wst.libs" value="ws-t.jar"/>
+ <property name="wst-api.libs" value="ws-t-api.jar"/>
+ <property name="wstx.libs" value="wstx.jar"/>
+ <property name="wstx-api.libs" value="wstx-api.jar"/>
+ <property name="recovery.libs" value="${modulename}.jar"/>
+ <property name="recovery-api.libs" value="${modulename}-api.jar"/>
+ <property name="recovery.all.libs" value="${recovery.libs}"/>
+
+ <!-- Define classpath builder task -->
+ <path id="com.arjuna.buildsystem.classpath">
+ <fileset dir="${com.arjuna.buildsystem.lib}" includes="${com.arjuna.buildsystem.lib.jars}"/>
+ </path>
+ <property name="com.arjuna.buildsystem.classpath" refid="com.arjuna.buildsystem.classpath"/>
+ <taskdef name="classpath-builder" classname="com.hp.mw.buildsystem.ant.ClasspathBuilder" classpathref="com.arjuna.buildsystem.classpath"/>
+ <!-- class path behaviour -->
+ <property name="build.sysclasspath" value="last"/>
+ <property name="com.arjuna.mwlabs.classpathbuilderfilename" location="buildsystem.classpath"/>
+
+ <property name="org.jboss.jbossts.xts.recovery.resourcebundle"
+ value="recovery_msg_en_US.properties"/>
+
+ <!--Set external directories -->
+
+ <property name="com.arjuna.mwlabs.wsas.jar.dest" value="../WSAS/build/lib"/>
+ <property name="com.arjuna.mwlabs.wsc.jar.dest" value="../WS-C/build/dev/lib"/>
+ <property name="com.arjuna.mwlabs.wscf.jar.dest" value="../WSCF/build/lib"/>
+ <property name="com.arjuna.mwlabs.wst.jar.dest" value="../WS-T/build/dev/lib"/>
+ <property name="com.arjuna.mwlabs.wstx.jar.dest" value="../WSTX/build/lib"/>
+
+ <path id="org.jboss.jbossts.xts.recovery.lib.classpath">
+ <fileset dir="${com.arjuna.jta.install.lib}" includes="${jta.lib.jars}"/>
+ <fileset dir="${com.arjuna.jta.install.ext}" includes="${jta.ext.jars} ${jta.ext.compile.jars}"/>
+ <fileset dir="${jboss.client.lib.dir}" includes="${jboss.client.lib.jars}"/>
+ <fileset dir="${jboss.common.lib.dir}" includes="${jboss.common.lib.jars}"/>
+ <fileset dir="${com.arjuna.mwlabs.wsas.jar.dest}" includes="${wsas.libs}"/>
+ <fileset dir="${com.arjuna.mwlabs.wsc.jar.dest}" includes="${wsc.libs} ${wsc-api.libs}"/>
+ <fileset dir="${com.arjuna.mwlabs.wscf.jar.dest}" includes="${wscf.libs}"/>
+ <fileset dir="${com.arjuna.mwlabs.wst.jar.dest}" includes="${wst.libs} ${wst-api.libs}"/>
+ <fileset dir="${com.arjuna.mwlabs.wstx.jar.dest}" includes="${wstx.libs} ${wstx-api.libs}"/>
+ </path>
+
+ <!-- Initialisation -->
+ <target name="org.jboss.jbossts.xts.recovery.init">
+ <!-- Define default build properties -->
+ <tstamp>
+ <format property="org.jboss.jbossts.xts.recovery.date" pattern="yyyy/mm/dd hh:mm aa"/>
+ </tstamp>
+ <!-- Make the destination directory -->
+ <mkdir dir="${org.jboss.jbossts.xts.recovery.dest}"/>
+ </target>
+
+ <!-- Compilation targets -->
+
+ <target name="org.jboss.jbossts.xts.recovery.compile"
+ depends="org.jboss.jbossts.xts.recovery.compile-generic,
+ org.jboss.jbossts.xts.recovery.htdocs, org.jboss.jbossts.xts.recovery.generateresourcebundle"/>
+
+ <target name="org.jboss.jbossts.xts.recovery.compile-generic" depends="org.jboss.jbossts.xts.recovery.init">
+ <echo message="Compiling module generic code"/>
+ <javac srcdir="${org.jboss.jbossts.xts.recovery.src}"
+ destdir="${org.jboss.jbossts.xts.recovery.dest}"
+ debug="on">
+ <classpath>
+ <path refid="org.jboss.jbossts.xts.recovery.lib.classpath"/>
+ </classpath>
+ </javac>
+ </target>
+
+ <!-- Build htdocs for just mw, or mw and mwlabs -->
+ <property name="org.jboss.jbossts.xts.recovery.htdocs.list" value="org.jboss.jbosts.xts.*"/>
+
+ <!-- Jar targets -->
+ <target name="org.jboss.jbossts.xts.recovery.jar" depends="org.jboss.jbossts.xts.recovery.compile">
+ <echo message="Building jar file"/>
+ <mkdir dir="${org.jboss.jbossts.xts.recovery.jar.dest}"/>
+
+ <jar jarfile="${org.jboss.jbossts.xts.recovery.jar.dest}/${modulename}.jar">
+ <fileset dir="${org.jboss.jbossts.xts.recovery.dest}"/>
+ </jar>
+ </target>
+
+ <target name="org.jboss.jbossts.xts.recovery.htdocs"
+ depends="org.jboss.jbossts.xts.recovery.init">
+ <echo message="Building htdocs "/>
+ <mkdir dir="${org.jboss.jbossts.xts.recovery.htdocs.dest}"/>
+ <path id="org.jboss.jbossts.xts.recovery.htdocs.path">
+ <pathelement path="src"/>
+ </path>
+
+ <!--
+ <javadoc
+ sourcepathref="org.jboss.jbossts.xts.recovery.htdocs.path"
+ destdir="${org.jboss.jbossts.xts.recovery.htdocs.dest}"
+ packagenames="${org.jboss.jbossts.xts.recovery.htdocs.list}"
+ >
+ <classpath>
+ <path refid="org.jboss.jbossts.xts.recovery.lib.classpath"/>
+ <path path="${org.jboss.jbossts.xts.recovery.src}"/>
+ </classpath>
+ </javadoc>
+ -->
+ <javadoc
+ destdir="${org.jboss.jbossts.xts.recovery.htdocs.dest}"
+ packagenames="${org.jboss.jbossts.xts.recovery.htdocs.list}"
+ >
+ <fileset dir="src" includes="**"/>
+ <classpath>
+ <path refid="org.jboss.jbossts.xts.recovery.lib.classpath"/>
+ <path path="${org.jboss.jbossts.xts.recovery.src}"/>
+ </classpath>
+ </javadoc>
+ </target>
+
+ <target name="org.jboss.jbossts.xts.recovery.generateresourcebundle">
+
+ <echo message="Generating recovery Bundle"/>
+
+ <classpath-builder filename="${com.arjuna.mwlabs.classpathbuilderfilename}" inproperty="build.classpath"/>
+
+ <javadoc packagenames="com.arjuna.*"
+ failonerror="yes"
+ private="yes"
+ defaultexcludes="yes"
+ classpath="${build.classpath}">
+
+ <packageset dir="${org.jboss.jbossts.xts.recovery.src}" defaultexcludes="yes">
+ <include name="org/jboss/jbossts/**"/>
+ </packageset>
+
+ <doclet name="com.hp.mw.buildsystem.doclet.resbundledoclet.ResourceBundleDoclet">
+ <path>
+ <pathelement path="${com.arjuna.buildsystem.classpath}"/>
+ </path>
+ <param name="-basedir" value="${basedir}/${org.jboss.jbossts.xts.recovery.dest}"/>
+ <param name="-resourcebundle" value="${org.jboss.jbossts.xts.recovery.resourcebundle}"/>
+ </doclet>
+ </javadoc>
+
+ </target>
+
+ <!-- Clean targets -->
+ <target name="org.jboss.jbossts.xts.recovery.clean">
+ <echo message="Cleaning module"/>
+ <delete dir="${org.jboss.jbossts.xts.recovery.dest}"/>
+ <delete dir="${org.jboss.jbossts.xts.recovery.dest.root}"/>
+ <delete dir="${org.jboss.jbossts.xts.recovery.htdocs.dest}"/>
+ <delete file="${org.jboss.jbossts.xts.recovery.jar.dest}/${modulename}.jar"/>
+ </target>
+
+ <!-- Short target names -->
+ <target name="compile" depends="org.jboss.jbossts.xts.recovery.compile"/>
+ <target name="jar" depends="org.jboss.jbossts.xts.recovery.jar"/>
+ <target name="clean" depends="org.jboss.jbossts.xts.recovery.clean"/>
+</project>
Copied: labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/logging/XTSLogger.java (from rev 27481, labs/jbosstm/trunk/XTS/sar/src/org/jboss/jbossts/xts/logging/XTSLogger.java)
===================================================================
--- labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/logging/XTSLogger.java (rev 0)
+++ labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/logging/XTSLogger.java 2009-07-06 14:30:00 UTC (rev 27633)
@@ -0,0 +1,34 @@
+package org.jboss.jbossts.xts.logging;
+
+import java.util.Locale;
+import java.util.ResourceBundle;
+
+import com.arjuna.ats.arjuna.common.arjPropertyManager;
+import com.arjuna.common.internal.util.logging.commonPropertyManager;
+import com.arjuna.common.util.logging.LogFactory;
+import com.arjuna.common.util.logging.LogNoi18n;
+import com.arjuna.common.util.logging.Logi18n;
+
+public class XTSLogger
+{
+ public static LogNoi18n arjLogger;
+ public static Logi18n arjLoggerI18N;
+ public static ResourceBundle log_mesg;
+
+ static
+ {
+ /** Ensure the properties are loaded before initialising the logger **/
+ arjPropertyManager.getPropertyManager();
+
+ arjLogger = LogFactory.getLogNoi18n("com.arjuna.webservices.logging.XTSLogger");
+
+ final String language = commonPropertyManager.getPropertyManager().getProperty("language","en");
+ final String country = commonPropertyManager.getPropertyManager().getProperty("country","US");
+
+ final Locale currentLocale = new Locale(language, country);
+ log_mesg = ResourceBundle.getBundle("recovery_msg",currentLocale);
+
+ arjLoggerI18N = LogFactory.getLogi18n("com.arjuna.webservices.logging.XTSLoggerI18N",
+ "recovery_msg_"+language+"_"+country);
+ }
+}
Copied: labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/recovery/coordinator (from rev 27481, labs/jbosstm/trunk/XTS/sar/src/org/jboss/jbossts/xts/recovery/coordinator)
Copied: labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/recovery/participant/at/ATParticipantRecoveryModule.java (from rev 27481, labs/jbosstm/trunk/XTS/sar/src/org/jboss/jbossts/xts/recovery/participant/at/ATParticipantRecoveryModule.java)
===================================================================
--- labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/recovery/participant/at/ATParticipantRecoveryModule.java (rev 0)
+++ labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/recovery/participant/at/ATParticipantRecoveryModule.java 2009-07-06 14:30:00 UTC (rev 27633)
@@ -0,0 +1,341 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2007, 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) 2007,
+ * @author Red Hat Middleware LLC.
+ */
+package org.jboss.jbossts.xts.recovery.participant.at;
+
+import org.jboss.jbossts.xts.logging.XTSLogger;
+
+import com.arjuna.ats.arjuna.recovery.RecoveryModule;
+import com.arjuna.ats.arjuna.logging.FacilityCode;
+import com.arjuna.ats.arjuna.coordinator.TxControl;
+import com.arjuna.ats.arjuna.state.InputObjectState;
+import com.arjuna.ats.arjuna.exceptions.ObjectStoreException;
+import com.arjuna.ats.arjuna.common.Uid;
+import com.arjuna.ats.arjuna.objectstore.ObjectStore;
+import com.arjuna.common.util.logging.DebugLevel;
+import com.arjuna.common.util.logging.VisibilityLevel;
+
+import java.util.Vector;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.io.IOException;
+
+import org.jboss.jbossts.xts.recovery.participant.at.ATParticipantRecoveryRecord;
+
+/**
+ * This class is a plug-in module for the recovery manager.
+ * It is responsible for recovering XTS AT participants.
+ * (instances of org.jboss.jbossts.xts.recovery.participant.at.ATParticipantRecoveryRecord)
+ *
+ * $Id$
+ *
+ * @message org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryModule_1 [org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryModule_1] - RecoveryManagerStatusModule: Object store exception: {0}
+ * @message org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryModule_3 [org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryModule_3] - failed to access transaction store {0}
+ * @message org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryModule_4 [org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryModule_4] - unable to load recovery record implementation class {0} for WS-AT participant recovery record {1}
+ * @message org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryModule_5 [org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryModule_5] - unable to instantiate recovery record implementation class {0} for WS-AT participant recovery record {1}
+ * @message org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryModule_6 [org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryModule_6] - unable to unpack recovery record data for WS-AT participant recovery record {0}
+ * @message org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryModule_7 [org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryModule_7] - missing recovery record data for WS-AT participant recovery record {0}
+ * @message org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryModule_8 [org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryModule_8] - unable to read recovery record data for WS-AT participant recovery record {0}
+ */
+
+public class ATParticipantRecoveryModule implements RecoveryModule
+{
+ public ATParticipantRecoveryModule()
+ {
+ if (XTSLogger.arjLogger.isDebugEnabled())
+ {
+ XTSLogger.arjLogger.debug
+ ( DebugLevel.CONSTRUCTORS,
+ VisibilityLevel.VIS_PUBLIC,
+ FacilityCode.FAC_CRASH_RECOVERY,
+ "ATParticipantRecoveryModule created - default" );
+ }
+
+ if (_objectStore == null)
+ {
+ _objectStore = TxControl.getStore() ;
+ }
+
+ _participantType = ATParticipantRecoveryRecord.type();
+ }
+
+ /**
+ * called by the service startup code before the recovery module is added to the recovery managers
+ * module list
+ */
+ public void install()
+ {
+ XTSATRecoveryManager.setRecoveryManager(new XTSATRecoveryManagerImple(_objectStore));
+ // Subordinate Coordinators register durable participants with their parent transaction so
+ // we need to add an XTSATRecoveryModule which knows about the registered participants
+
+ subordinateRecoveryModule = new XTSATSubordinateRecoveryModule();
+ XTSATRecoveryManager.getRecoveryManager().registerRecoveryModule(subordinateRecoveryModule);
+ }
+
+ /**
+ * a recovery module which knows hwo to recover the participants registered by Subordinate AT Coordinators
+ */
+
+ private XTSATSubordinateRecoveryModule subordinateRecoveryModule;
+
+ /**
+ * called by the service shutdown code after the recovery module is removed from the recovery managers
+ * module list
+ */
+ public void uninstall()
+ {
+ XTSATRecoveryManager.getRecoveryManager().unregisterRecoveryModule(subordinateRecoveryModule);
+ }
+
+ /**
+ * This is called periodically by the RecoveryManager
+ */
+ public void periodicWorkFirstPass()
+ {
+ // Transaction type
+ boolean ATParticipants = false ;
+
+ // uids per transaction type
+ InputObjectState acc_uids = new InputObjectState() ;
+
+ try
+ {
+ if (XTSLogger.arjLogger.isDebugEnabled())
+ {
+ XTSLogger.arjLogger.debug( "StatusModule: first pass " );
+ }
+
+ ATParticipants = _objectStore.allObjUids(_participantType, acc_uids );
+
+ }
+ catch ( ObjectStoreException ex )
+ {
+ if (XTSLogger.arjLoggerI18N.isWarnEnabled())
+ {
+ XTSLogger.arjLoggerI18N.warn("org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryModule_1",
+ ex);
+ }
+ }
+
+ if ( ATParticipants )
+ {
+ _participantUidVector = processParticipants( acc_uids ) ;
+ }
+ }
+
+ public void periodicWorkSecondPass()
+ {
+ if (XTSLogger.arjLogger.isDebugEnabled())
+ {
+ XTSLogger.arjLogger.debug( "ATParticipantRecoveryModule: Second pass " );
+ }
+
+ processParticipantsStatus() ;
+ }
+
+ private void doRecoverParticipant( Uid recoverUid )
+ {
+ // Retrieve the participant from its original process.
+
+ if (XTSLogger.arjLogger.isDebugEnabled())
+ {
+ XTSLogger.arjLogger.debug
+ ( DebugLevel.FUNCTIONS,
+ VisibilityLevel.VIS_PUBLIC,
+ FacilityCode.FAC_CRASH_RECOVERY,
+ "participant type is "+ _participantType + " uid is " +
+ recoverUid.toString()) ;
+ }
+
+ // we don't need to use a lock here because we only attempt the read
+ // when the uid is inactive which means it cannto be pulled out form under our
+ // feet at commit. uniqueness of uids also means we can't be foiled by a reused
+ // uid.
+
+ XTSATRecoveryManager recoveryManager = XTSATRecoveryManager.getRecoveryManager();
+
+ if (!recoveryManager.isParticipantPresent(recoverUid)) {
+ // ok, the participant can neither be active nor loaded awaiting recreation by
+ // an application recovery module so we need to load it
+ try {
+ // retrieve the data for the participant
+ InputObjectState inputState = _objectStore.read_committed(recoverUid, _participantType);
+
+ if (inputState != null) {
+ try {
+ String participantRecordClazzName = inputState.unpackString();
+ try {
+ // create a participant engine instance and tell it to recover itself
+ Class participantRecordClazz = Class.forName(participantRecordClazzName);
+ ATParticipantRecoveryRecord participantRecord = (ATParticipantRecoveryRecord)participantRecordClazz.newInstance();
+ participantRecord.restoreState(inputState);
+ // ok, now insert into recovery map if needed
+ XTSATRecoveryManager.getRecoveryManager().addParticipantRecoveryRecord(recoverUid, participantRecord);
+ } catch (ClassNotFoundException cnfe) {
+ // oh boy, not supposed to happen -- n.b. either the user deployed 1.0
+ // last time and 1.1 this time or vice versa or something is rotten in
+ // the state of Danmark
+ if (XTSLogger.arjLoggerI18N.isErrorEnabled())
+ {
+ XTSLogger.arjLoggerI18N.error("org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryModule_4",
+ new Object[]{participantRecordClazzName, recoverUid.toString()}, cnfe);
+ }
+ } catch (InstantiationException ie) {
+ // this is also worrying, log an error
+ if (XTSLogger.arjLoggerI18N.isErrorEnabled())
+ {
+ XTSLogger.arjLoggerI18N.error("org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryModule_5",
+ new Object[]{participantRecordClazzName, recoverUid.toString()}, ie);
+ }
+ } catch (IllegalAccessException iae) {
+ // this is another configuration problem, log an error
+ if (XTSLogger.arjLoggerI18N.isErrorEnabled())
+ {
+ XTSLogger.arjLoggerI18N.error("org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryModule_5",
+ new Object[]{participantRecordClazzName, recoverUid.toString()}, iae);
+ }
+ }
+ } catch (IOException ioe) {
+ // hmm, record corrupted? log this as a warning
+ if (XTSLogger.arjLoggerI18N.isWarnEnabled())
+ {
+ XTSLogger.arjLoggerI18N.warn("org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryModule_6",
+ new Object[]{recoverUid.toString()}, ioe);
+ }
+ }
+ } else {
+ // hmm, it ought not to be able to disappear unless the recovery manager knows about it
+ // this is an error!
+ if (XTSLogger.arjLoggerI18N.isErrorEnabled())
+ {
+ XTSLogger.arjLoggerI18N.error("org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryModule_7",
+ new Object[]{recoverUid.toString()});
+ }
+ }
+ } catch (ObjectStoreException ose) {
+ // if the object store is not working this is serious
+ if (XTSLogger.arjLoggerI18N.isErrorEnabled())
+ {
+ XTSLogger.arjLoggerI18N.error("org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryModule_8",
+ new Object[]{recoverUid.toString()}, ose);
+ }
+ }
+ }
+ }
+
+ private Vector processParticipants( InputObjectState uids )
+ {
+ Vector uidVector = new Vector() ;
+
+ if (XTSLogger.arjLogger.isDebugEnabled())
+ {
+ XTSLogger.arjLogger.debug( DebugLevel.FUNCTIONS,
+ VisibilityLevel.VIS_PUBLIC,
+ FacilityCode.FAC_CRASH_RECOVERY,
+ "processing " + _participantType
+ + " WS-AT participants" ) ;
+ }
+
+ Uid theUid = new Uid( Uid.nullUid() );
+
+ boolean moreUids = true ;
+
+ while (moreUids)
+ {
+ try
+ {
+ theUid.unpack( uids ) ;
+
+ if (theUid.equals( Uid.nullUid() ))
+ {
+ moreUids = false;
+ }
+ else
+ {
+ Uid newUid = new Uid( theUid ) ;
+
+ if (XTSLogger.arjLogger.isDebugEnabled())
+ {
+ XTSLogger.arjLogger.debug
+ ( DebugLevel.FUNCTIONS,
+ VisibilityLevel.VIS_PUBLIC,
+ FacilityCode.FAC_CRASH_RECOVERY,
+ "found WS-AT participant "+ newUid ) ;
+ }
+
+ uidVector.addElement( newUid ) ;
+ }
+ }
+ catch ( Exception ex )
+ {
+ moreUids = false;
+ }
+ }
+ return uidVector ;
+ }
+
+ private void processParticipantsStatus()
+ {
+ if (_participantUidVector != null) {
+ // Process the Vector of transaction Uids
+ Enumeration participantUidEnum = _participantUidVector.elements() ;
+
+ while ( participantUidEnum.hasMoreElements() )
+ {
+ Uid currentUid = (Uid) participantUidEnum.nextElement();
+
+ try
+ {
+ if ( _objectStore.currentState( currentUid, _participantType) != ObjectStore.OS_UNKNOWN )
+ {
+ doRecoverParticipant( currentUid ) ;
+ }
+ }
+ catch ( ObjectStoreException ex )
+ {
+ if (XTSLogger.arjLogger.isWarnEnabled())
+ {
+ XTSLogger.arjLoggerI18N.warn("org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryModule_3",
+ new Object[]{currentUid.toString()}, ex);
+ }
+ }
+ }
+ }
+
+ // now get the AT recovery manager to try to activate recovered participants
+
+ XTSATRecoveryManager.getRecoveryManager().recoverParticipants();
+ }
+
+ // 'type' within the Object Store for ATParticipant record.
+ private String _participantType = ATParticipantRecoveryRecord.type() ;
+
+ // Array of transactions found in the object store of the
+ // ACCoordinator type.
+ private Vector _participantUidVector = null ;
+
+ // Reference to the Object Store.
+ private static ObjectStore _objectStore = null ;
+
+ // This object provides information about whether or not a participant is currently active.
+
+ private HashMap<String, ATParticipantRecoveryRecord> _recoveredParticipantMap ;
+}
\ No newline at end of file
Copied: labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/recovery/participant/at/XTSATRecoveryManagerImple.java (from rev 27481, labs/jbosstm/trunk/XTS/sar/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 (rev 0)
+++ labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/recovery/participant/at/XTSATRecoveryManagerImple.java 2009-07-06 14:30:00 UTC (rev 27633)
@@ -0,0 +1,367 @@
+package org.jboss.jbossts.xts.recovery.participant.at;
+
+import org.jboss.jbossts.xts.logging.XTSLogger;
+
+import com.arjuna.wst.Durable2PCParticipant;
+import com.arjuna.ats.arjuna.objectstore.ObjectStore;
+import com.arjuna.ats.arjuna.state.OutputObjectState;
+import com.arjuna.ats.arjuna.common.Uid;
+import com.arjuna.ats.arjuna.exceptions.ObjectStoreException;
+
+import java.util.*;
+import java.io.IOException;
+
+/**
+ * A class which manages the table of recovered participant records.
+ *
+ * @message org.jboss.transactions.xts.recovery.participant.at.XTSATRecoveryModule_1 [org.jboss.transactions.xts.recovery.participant.at.XTSATRecoveryModule_1] exception writing recovery record for WS-AT participant {0}
+ * @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}
+ */
+public class XTSATRecoveryManagerImple extends XTSATRecoveryManager {
+ /**
+ * constructor for use by ATParticipantRecoveryModule
+ * @param objectStore
+ */
+ XTSATRecoveryManagerImple(ObjectStore objectStore)
+ {
+ this.objectStore = objectStore;
+ }
+
+ /**
+ * register an application specific recovery module which acts as a helper to recreate
+ * a WS-AT durable participant from the participant's recovery data saved at prepare
+ *
+ * @param module the module which will be used to identify and recreate participants
+ * for the application
+ * @throws NullPointerException if the supplied module is null
+ */
+ public void registerRecoveryModule(XTSATRecoveryModule module) throws NullPointerException
+ {
+ // TODO other sanity checks?
+ if (module == null) {
+ throw new NullPointerException("XTSATRecoveryModule value must be non-null");
+ }
+
+ recoveryModules.add(module);
+ }
+
+ /**
+ * unregister an application specific recovery module previously registered as
+ * a helper to recretae WS-AT durable participants
+ *
+ * @param module the module to be unregistered
+ * @throws java.util.NoSuchElementException
+ * if the module is not currently registered
+ */
+ public void unregisterRecoveryModule(XTSATRecoveryModule module) throws NoSuchElementException {
+ if (!recoveryModules.remove(module)) {
+ throw new NoSuchElementException();
+ }
+ }
+
+ /**
+ * save the supplied participant recovery record to persistent storage
+ *
+ * @param participantRecoveryRecord
+ */
+ public boolean writeParticipantRecoveryRecord(ATParticipantRecoveryRecord participantRecoveryRecord)
+ {
+ OutputObjectState oos = new OutputObjectState();
+ // we need to be able to retrieve the class of the participant record so we can
+ // create an instancde to load the rest of the participant specific data
+ try {
+ oos.packString(participantRecoveryRecord.getClass().getCanonicalName());
+ } catch (IOException ioe) {
+ if (XTSLogger.arjLoggerI18N.isWarnEnabled())
+ {
+ XTSLogger.arjLoggerI18N.warn("org.jboss.transactions.xts.recovery.participant.at.XTSATRecoveryModule_1",
+ new Object[] {participantRecoveryRecord.getId()}, ioe);
+ }
+ return false;
+ }
+
+ if (participantRecoveryRecord.saveState(oos)) {
+ Uid uid = new Uid();
+ try {
+ objectStore.write_committed(uid, type, oos);
+ // we need to be able to identify the uid from the participant id
+ // in order to delete it later
+ uidMap.put(participantRecoveryRecord.getId(), uid);
+ return true;
+ } catch (ObjectStoreException ose) {
+ if (XTSLogger.arjLoggerI18N.isWarnEnabled())
+ {
+ XTSLogger.arjLoggerI18N.warn("org.jboss.transactions.xts.recovery.participant.at.XTSATRecoveryModule_1",
+ new Object[] {participantRecoveryRecord.getId()}, ose);
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * remove any participant recovery record with the supplied id from persistent storage
+ * @param id the id of the participant whose recovery details are being deleted
+ */
+ public boolean deleteParticipantRecoveryRecord(String id)
+ {
+ Uid uid = uidMap.get(id);
+
+ if (uid != null) {
+
+ try {
+ objectStore.remove_committed(uid, type);
+ uidMap.remove(id);
+ return true;
+ } catch (ObjectStoreException ose) {
+ if (XTSLogger.arjLoggerI18N.isWarnEnabled())
+ {
+ XTSLogger.arjLoggerI18N.warn("org.jboss.transactions.xts.recovery.participant.at.XTSATRecoveryModule_2",
+ new Object[] {uid, id},
+ ose);
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * test whether the supplied uid identifies an active participant or a recovered but inactive
+ * participant
+ *
+ * n.b. this method is not synchronized because of two assumptions: first, that uids are
+ * never reused; and second that only recovery scanning (as a minimum, for a given recovery
+ * record type) is single-threaded. Correctness of the first assumption ensures there are no
+ * races with participant processor threads, the second races between recovery threads.
+ *
+ * @param uid
+ */
+ public boolean isParticipantPresent(Uid uid)
+ {
+ return (uidMap.get(uid) != null);
+ }
+
+ /**
+ * add a recovered participant record to the table of unrecovered participants which
+ * need to be recreated following recovery
+ *
+ * @param uid the uid under which the participant was saved in the file store
+ * @param participantRecoveryRecord the in-memory representation of the recovery record
+ * saved to disk
+ */
+ public void addParticipantRecoveryRecord(Uid uid, ATParticipantRecoveryRecord participantRecoveryRecord)
+ {
+ String participantId = participantRecoveryRecord.getId();
+ if (recoveryMap.get(participantId) == null && !participantRecoveryRecord.isActive()) {
+ // ok, we have not seen this entry before so add it to the list
+ recoveryMap.put(participantId, participantRecoveryRecord);
+ uidMap.put(participantId, uid);
+ }
+ }
+
+ /**
+ * see if a participant recovery record with a given id exists in the table of participants which
+ * need to be recreated following recovery
+ * @param id the identifier of the participant being sought
+ * @return the participant recovery record with the supplied id or null if it is not found
+ */
+ public synchronized ATParticipantRecoveryRecord findParticipantRecoveryRecord(String id)
+ {
+ return recoveryMap.get(id);
+ }
+
+ /**
+ * process all entries in the recovered participant map and attempt to recreate the
+ * application participant and activate it
+ */
+ public void recoverParticipants()
+ {
+ // the first scan has been performed so allow processing of commit and rollback requests
+ // for unknown ids to proceed now
+
+ setParticipantRecoveryStarted();
+
+ // we operate on a copy of the recovery modules to avoid the list being modified
+ // by register and unregister operations while we are iterating over it
+ // we should probably also make sure unregister does not proceed until
+ // the current scan is complete . . .
+
+ List<XTSATRecoveryModule> recoveryModulesCopy;
+ synchronized (recoveryModules) {
+ recoveryModulesCopy = new ArrayList<XTSATRecoveryModule>(recoveryModules);
+ }
+
+ // iterate through the participant recovery records and try to convert them to
+ // a durable participant. if successful activate the participant and then remove the
+ // recovery entry. note that since recovery is single threaded we can be sure that
+ // no concurrent modifications will be made to the table while we are iterating and,
+ // possibly, deleting via the iterator
+
+ Iterator<ATParticipantRecoveryRecord> participantIterator = iterator();
+
+ while(participantIterator.hasNext()) {
+ ATParticipantRecoveryRecord participantRecoveryRecord = participantIterator.next();
+ if (participantRecoveryRecord.isActive()) {
+ // this participant must have already been activated by a by a previous
+ // scan and been reloaded by this scan so just remove the entry
+
+ participantIterator.remove();
+ } else {
+ Iterator<XTSATRecoveryModule> moduleIterator = recoveryModulesCopy.iterator();
+ boolean found = false;
+
+ while (!found && moduleIterator.hasNext()) {
+ XTSATRecoveryModule module = moduleIterator.next();
+ try {
+ if (participantRecoveryRecord.restoreParticipant(module)) {
+ // ok, this participant has recovered so tell it to
+ // activate and *then* remove it from the hashmap. this makes
+ // sure we don't open a window where an incoming
+ // commit may fail to find the object in either table
+
+ found = true;
+ participantRecoveryRecord.activate();
+
+ participantIterator.remove();
+ }
+ } catch (Exception e) {
+ // we foudn a helper but it failed to convert the participant record -- log a warning
+ // but leave the participant in the table for next time in case the helper has merely
+ // suffered a transient failure
+ found = true;
+ if (XTSLogger.arjLoggerI18N.isWarnEnabled())
+ {
+ XTSLogger.arjLoggerI18N.warn("org.jboss.transactions.xts.recovery.participant.at.XTSATRecoveryModule_3",
+ new Object[] {participantRecoveryRecord.getId()},
+ e);
+ }
+ }
+ }
+
+ if (!found) {
+ // we failed to find a helper to convert a participant record so log a warning
+ // but leave it in the table for next time
+ if (XTSLogger.arjLoggerI18N.isWarnEnabled())
+ {
+ XTSLogger.arjLoggerI18N.warn("org.jboss.transactions.xts.recovery.participant.at.XTSATRecoveryModule_4",
+ new Object[] {participantRecoveryRecord.getId()});
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * 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
+ * @return
+ */
+ private synchronized Iterator<ATParticipantRecoveryRecord> iterator()
+ {
+ return recoveryMap.values().iterator();
+ }
+
+ /**
+ * set a global flag indicating that the first AT participant recovery scan has
+ * been performed.
+ */
+ private synchronized void setParticipantRecoveryStarted()
+ {
+ participantRecoveryStarted = true;
+ }
+
+ /**
+ * test whether the first AT participant recovery scan has completed. this indicates whether
+ * there may or may not still be unknown participant recovery records on disk. If the first
+ * scan has not yet completed then a commit or rollback message for an unknown participant
+ * must be dropped. If it has then a commit or rollback for an unknown participant must be
+ * acknowledged with, respectively, a committed or aborted message.
+ */
+ public synchronized boolean isParticipantRecoveryStarted()
+ {
+ return participantRecoveryStarted;
+ }
+
+ /**
+ * test whether the first AT coordinator recovery scan has completed. this indicates whether
+ * there may or may not still be unknown AT transcation records on disk. If the first
+ * scan has not yet completed then a prepare message for an unknown participant
+ * must be dropped. If it has then a perpare for an unknown participant must be
+ * acknowledged with a rollback message.
+ */
+ public synchronized boolean isCoordinatorRecoveryStarted() {
+ return coordinatorRecoveryStarted;
+ }
+
+ /**
+ * test whether the first AT subordinate coordinator recovery scan has completed. this indicates
+ * whether there may or may not still be unknown AT subtransaction records on disk. If the first
+ * scan has not yet completed then a commit for an unknown subtransaction must raise an exception
+ * delaying commit of the parent transaction.
+ */
+ public synchronized boolean isSubordinateCoordinatorRecoveryStarted() {
+ return subordinateCoordinatorRecoveryStarted;
+ }
+
+ /**
+ * record the fact that the first AT coordinator recovery scan has completed.
+ */
+
+ public synchronized void setCoordinatorRecoveryStarted() {
+ coordinatorRecoveryStarted = true;
+ }
+
+ /**
+ * record the fact that the first AT subordinate coordinator recovery scan has completed.
+ */
+
+ public synchronized void setSubordinateCoordinatorRecoveryStarted() {
+ subordinateCoordinatorRecoveryStarted = true;
+ }
+
+ /**
+ * a global flag indicating whether the first AT participant recovery scan has
+ * been performed.
+ */
+ private boolean participantRecoveryStarted = false;
+
+ /**
+ * a global flag indicating whether the first AT coordinator recovery scan has
+ * been performed.
+ */
+ private boolean coordinatorRecoveryStarted = false;
+
+ /**
+ * a global flag indicating whether the first AT subordinate coordinator recovery scan has
+ * been performed.
+ */
+ private boolean subordinateCoordinatorRecoveryStarted = false;
+
+ /**
+ * a map from participant ids to participant recovery records
+ */
+ private HashMap<String, ATParticipantRecoveryRecord> recoveryMap = new HashMap<String, ATParticipantRecoveryRecord>();
+
+ /**
+ * a map from participant id to the uid under which the participant has been saved in the
+ * persistent store
+ */
+ private HashMap<String, Uid> uidMap = new HashMap<String, Uid>();
+
+ /**
+ * a map from participant ids to participant recover records
+ */
+ private List<XTSATRecoveryModule> recoveryModules = new ArrayList<XTSATRecoveryModule>();
+
+ /**
+ * the tx object store to be used for saving and deleting participant details
+ */
+ private ObjectStore objectStore;
+
+ private final static String type = ATParticipantRecoveryRecord.type();
+}
Copied: labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/recovery/participant/at/XTSATSubordinateRecoveryModule.java (from rev 27481, labs/jbosstm/trunk/XTS/sar/src/org/jboss/jbossts/xts/recovery/participant/at/XTSATSubordinateRecoveryModule.java)
===================================================================
--- labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/recovery/participant/at/XTSATSubordinateRecoveryModule.java (rev 0)
+++ labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/recovery/participant/at/XTSATSubordinateRecoveryModule.java 2009-07-06 14:30:00 UTC (rev 27633)
@@ -0,0 +1,36 @@
+package org.jboss.jbossts.xts.recovery.participant.at;
+
+import com.arjuna.wst.Durable2PCParticipant;
+import com.arjuna.wst.PersistableParticipant;
+import com.arjuna.mwlabs.wscf.model.twophase.arjunacore.subordinate.SubordinateCoordinator;
+import com.arjuna.ats.arjuna.state.InputObjectState;
+
+import java.io.ObjectInputStream;
+
+/**
+ * A recovery module which recovers durable participants registered by subordinate coordinators
+ */
+
+public class XTSATSubordinateRecoveryModule implements XTSATRecoveryModule
+{
+ public Durable2PCParticipant deserialize(String id, ObjectInputStream stream) throws Exception {
+ if (id.startsWith(SubordinateCoordinator.PARTICIPANT_PREFIX)) {
+ // throw an exception because we don't expect these participants to use serialization
+ throw new Exception("XTSATSubordinateRecoveryModule : invalid request to deserialize() subordinate WS-AT coordinator durable participant " + id);
+ }
+ return null;
+ }
+
+ public Durable2PCParticipant recreate(String id, byte[] recoveryState) throws Exception {
+ if (id.startsWith(SubordinateCoordinator.PARTICIPANT_PREFIX)) {
+ InputObjectState ios = new InputObjectState();
+ ios.setBuffer(recoveryState);
+ String className = ios.unpackString();
+ Class participantClass = this.getClass().getClassLoader().loadClass(className);
+ Durable2PCParticipant participant = (Durable2PCParticipant)participantClass.newInstance();
+ ((PersistableParticipant)participant).restoreState(ios);
+ return participant;
+ }
+ return null;
+ }
+}
Copied: labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/recovery/participant/ba/BAParticipantRecoveryModule.java (from rev 27481, labs/jbosstm/trunk/XTS/sar/src/org/jboss/jbossts/xts/recovery/participant/ba/BAParticipantRecoveryModule.java)
===================================================================
--- labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/recovery/participant/ba/BAParticipantRecoveryModule.java (rev 0)
+++ labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/recovery/participant/ba/BAParticipantRecoveryModule.java 2009-07-06 14:30:00 UTC (rev 27633)
@@ -0,0 +1,327 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2007, 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) 2007,
+ * @author Red Hat Middleware LLC.
+ */
+package org.jboss.jbossts.xts.recovery.participant.ba;
+
+import org.jboss.jbossts.xts.logging.XTSLogger;
+
+import com.arjuna.ats.arjuna.recovery.RecoveryModule;
+import com.arjuna.ats.arjuna.logging.FacilityCode;
+import com.arjuna.ats.arjuna.coordinator.TxControl;
+import com.arjuna.ats.arjuna.state.InputObjectState;
+import com.arjuna.ats.arjuna.exceptions.ObjectStoreException;
+import com.arjuna.ats.arjuna.common.Uid;
+import com.arjuna.ats.arjuna.objectstore.ObjectStore;
+import com.arjuna.common.util.logging.DebugLevel;
+import com.arjuna.common.util.logging.VisibilityLevel;
+
+import java.util.Vector;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.io.IOException;
+
+/**
+ * This class is a plug-in module for the recovery manager.
+ * It is responsible for recovering XTS BA participants
+ * (instances of org.jboss.jbossts.xts.recovery.participant.ba.BAParticipantRecoveryRecord)
+ *
+ * $Id$
+ *
+ * @message org.jboss.transactions.xts.recovery.participant.ba.BAParticipantRecoveryModule_1 [org.jboss.transactions.xts.recovery.participant.ba.BAParticipantRecoveryModule_1] - RecoveryManagerStatusModule: Object store exception: {0}
+ * @message org.jboss.transactions.xts.recovery.participant.ba.BAParticipantRecoveryModule_3 [org.jboss.transactions.xts.recovery.participant.ba.BAParticipantRecoveryModule_3] - failed to access transaction store {0}
+ * @message org.jboss.transactions.xts.recovery.participant.ba.BAParticipantRecoveryModule_4 [org.jboss.transactions.xts.recovery.participant.ba.BAParticipantRecoveryModule_4] - unable to load recovery record implementation class {0} for WS-BA participant recovery record {1}
+ * @message org.jboss.transactions.xts.recovery.participant.ba.BAParticipantRecoveryModule_5 [org.jboss.transactions.xts.recovery.participant.ba.BAParticipantRecoveryModule_5] - unable to instantiate recovery record implementation class {0} for WS-BA participant recovery record {1}
+ * @message org.jboss.transactions.xts.recovery.participant.ba.BAParticipantRecoveryModule_6 [org.jboss.transactions.xts.recovery.participant.ba.BAParticipantRecoveryModule_6] - unable to unpack recovery record data for WS-BA participant recovery record {0}
+ * @message org.jboss.transactions.xts.recovery.participant.ba.BAParticipantRecoveryModule_7 [org.jboss.transactions.xts.recovery.participant.ba.BAParticipantRecoveryModule_7] - missing recovery record data for WS-BA participant recovery record {0}
+ * @message org.jboss.transactions.xts.recovery.participant.ba.BAParticipantRecoveryModule_8 [org.jboss.transactions.xts.recovery.participant.ba.BAParticipantRecoveryModule_8] - unable to read recovery record data for WS-BA participant recovery record {0}
+ */
+
+public class BAParticipantRecoveryModule implements RecoveryModule
+{
+ public BAParticipantRecoveryModule()
+ {
+ if (XTSLogger.arjLogger.isDebugEnabled())
+ {
+ XTSLogger.arjLogger.debug
+ ( DebugLevel.CONSTRUCTORS,
+ VisibilityLevel.VIS_PUBLIC,
+ FacilityCode.FAC_CRASH_RECOVERY,
+ "BAParticipantRecoveryModule created - default" );
+ }
+
+ if (_objectStore == null)
+ {
+ _objectStore = TxControl.getStore() ;
+ }
+
+ _participantType = BAParticipantRecoveryRecord.type();
+ }
+
+ /**
+ * called by the service startup code before the recovery module is added to the recovery managers
+ * module list
+ */
+ public void install()
+ {
+ XTSBARecoveryManager.setRecoveryManager(new XTSBARecoveryManagerImple(_objectStore));
+ }
+
+ /**
+ * called by the service shutdown code after the recovery module is removed from the recovery managers
+ * module list
+ */
+ public void uninstall()
+ {
+ }
+
+ /**
+ * This is called periodically by the RecoveryManager
+ */
+ public void periodicWorkFirstPass()
+ {
+ // Transaction type
+ boolean BAParticipants = false ;
+
+ // uids per transaction type
+ InputObjectState acc_uids = new InputObjectState() ;
+
+ try
+ {
+ if (XTSLogger.arjLogger.isDebugEnabled())
+ {
+ XTSLogger.arjLogger.debug( "StatusModule: first pass " );
+ }
+
+ BAParticipants = _objectStore.allObjUids(_participantType, acc_uids );
+
+ }
+ catch ( ObjectStoreException ex )
+ {
+ if (XTSLogger.arjLoggerI18N.isWarnEnabled())
+ {
+ XTSLogger.arjLoggerI18N.warn("org.jboss.transactions.xts.recovery.participant.ba.BAParticipantRecoveryModule_1",
+ ex);
+ }
+ }
+
+ if ( BAParticipants )
+ {
+ _participantUidVector = processParticipants( acc_uids ) ;
+ }
+ }
+
+ public void periodicWorkSecondPass()
+ {
+ if (XTSLogger.arjLogger.isDebugEnabled())
+ {
+ XTSLogger.arjLogger.debug( "BAParticipantRecoveryModule: Second pass " );
+ }
+
+ processParticipantsStatus() ;
+ }
+
+ private void doRecoverParticipant( Uid recoverUid )
+ {
+ // Retrieve the participant from its original process.
+
+ if (XTSLogger.arjLogger.isDebugEnabled())
+ {
+ XTSLogger.arjLogger.debug
+ ( DebugLevel.FUNCTIONS,
+ VisibilityLevel.VIS_PUBLIC,
+ FacilityCode.FAC_CRASH_RECOVERY,
+ "participant type is "+ _participantType + " uid is " +
+ recoverUid.toString()) ;
+ }
+
+ // we don't need to use a lock here because we only attempt the read
+ // when the uid is inactive which means it cannto be pulled out form under our
+ // feet at commit. uniqueness of uids also means we can't be foiled by a reused
+ // uid.
+
+ XTSBARecoveryManager recoveryManager = XTSBARecoveryManager.getRecoveryManager();
+
+ if (!recoveryManager.isParticipantPresent(recoverUid)) {
+ // ok, the participant can neither be active nor loaded awaiting recreation by
+ // an application recovery module so we need to load it
+ try {
+ // retrieve the data for the participant
+ InputObjectState inputState = _objectStore.read_committed(recoverUid, _participantType);
+
+ if (inputState != null) {
+ try {
+ String participantRecordClazzName = inputState.unpackString();
+ try {
+ // create a participant engine instance and tell it to recover itself
+ Class participantRecordClazz = Class.forName(participantRecordClazzName);
+ BAParticipantRecoveryRecord participantRecord = (BAParticipantRecoveryRecord)participantRecordClazz.newInstance();
+ participantRecord.restoreState(inputState);
+ // ok, now insert into recovery map if needed
+ XTSBARecoveryManager.getRecoveryManager().addParticipantRecoveryRecord(recoverUid, participantRecord);
+ } catch (ClassNotFoundException cnfe) {
+ // oh boy, not supposed to happen -- n.b. either the user deployed 1.0
+ // last time and 1.1 this time or vice versa or something is rotten in
+ // the state of Danmark
+ if (XTSLogger.arjLoggerI18N.isErrorEnabled())
+ {
+ XTSLogger.arjLoggerI18N.error("org.jboss.transactions.xts.recovery.participant.ba.BAParticipantRecoveryModule_4",
+ new Object[]{participantRecordClazzName, recoverUid.toString()}, cnfe);
+ }
+ } catch (InstantiationException ie) {
+ // this is also worrying, log an error
+ if (XTSLogger.arjLoggerI18N.isErrorEnabled())
+ {
+ XTSLogger.arjLoggerI18N.error("org.jboss.transactions.xts.recovery.participant.ba.BAParticipantRecoveryModule_5",
+ new Object[]{participantRecordClazzName, recoverUid.toString()}, ie);
+ }
+ } catch (IllegalAccessException iae) {
+ // this is another configuration problem, log an error
+ if (XTSLogger.arjLoggerI18N.isErrorEnabled())
+ {
+ XTSLogger.arjLoggerI18N.error("org.jboss.transactions.xts.recovery.participant.ba.BAParticipantRecoveryModule_5",
+ new Object[]{participantRecordClazzName, recoverUid.toString()}, iae);
+ }
+ }
+ } catch (IOException ioe) {
+ // hmm, record corrupted? log this as a warning
+ if (XTSLogger.arjLoggerI18N.isWarnEnabled())
+ {
+ XTSLogger.arjLoggerI18N.warn("org.jboss.transactions.xts.recovery.participant.ba.BAParticipantRecoveryModule_6",
+ new Object[]{recoverUid.toString()}, ioe);
+ }
+ }
+ } else {
+ // hmm, it ought not to be able to disappear unless the recovery manager knows about it
+ // this is an error!
+ if (XTSLogger.arjLoggerI18N.isErrorEnabled())
+ {
+ XTSLogger.arjLoggerI18N.error("org.jboss.transactions.xts.recovery.participant.ba.BAParticipantRecoveryModule_7",
+ new Object[]{recoverUid.toString()});
+ }
+ }
+ } catch (ObjectStoreException ose) {
+ // if the object store is not working this is serious
+ if (XTSLogger.arjLoggerI18N.isErrorEnabled())
+ {
+ XTSLogger.arjLoggerI18N.error("org.jboss.transactions.xts.recovery.participant.ba.BAParticipantRecoveryModule_8",
+ new Object[]{recoverUid.toString()}, ose);
+ }
+ }
+ }
+ }
+
+ private Vector processParticipants( InputObjectState uids )
+ {
+ Vector uidVector = new Vector() ;
+
+ if (XTSLogger.arjLogger.isDebugEnabled())
+ {
+ XTSLogger.arjLogger.debug( DebugLevel.FUNCTIONS,
+ VisibilityLevel.VIS_PUBLIC,
+ FacilityCode.FAC_CRASH_RECOVERY,
+ "processing " + _participantType
+ + " WS-BA participants" ) ;
+ }
+
+ Uid theUid = new Uid( Uid.nullUid() );
+
+ boolean moreUids = true ;
+
+ while (moreUids)
+ {
+ try
+ {
+ theUid.unpack( uids ) ;
+
+ if (theUid.equals( Uid.nullUid() ))
+ {
+ moreUids = false;
+ }
+ else
+ {
+ Uid newUid = new Uid( theUid ) ;
+
+ if (XTSLogger.arjLogger.isDebugEnabled())
+ {
+ XTSLogger.arjLogger.debug
+ ( DebugLevel.FUNCTIONS,
+ VisibilityLevel.VIS_PUBLIC,
+ FacilityCode.FAC_CRASH_RECOVERY,
+ "found WS-BA participant "+ newUid ) ;
+ }
+
+ uidVector.addElement( newUid ) ;
+ }
+ }
+ catch ( Exception ex )
+ {
+ moreUids = false;
+ }
+ }
+ return uidVector ;
+ }
+
+ private void processParticipantsStatus()
+ {
+ if (_participantUidVector != null) {
+ // Process the Vector of transaction Uids
+ Enumeration participantUidEnum = _participantUidVector.elements() ;
+
+ while ( participantUidEnum.hasMoreElements() )
+ {
+ Uid currentUid = (Uid) participantUidEnum.nextElement();
+
+ try
+ {
+ if ( _objectStore.currentState( currentUid, _participantType) != ObjectStore.OS_UNKNOWN )
+ {
+ doRecoverParticipant( currentUid ) ;
+ }
+ }
+ catch ( ObjectStoreException ex )
+ {
+ if (XTSLogger.arjLogger.isWarnEnabled())
+ {
+ XTSLogger.arjLoggerI18N.warn("org.jboss.transactions.xts.recovery.participant.ba.BAParticipantRecoveryModule_3",
+ new Object[]{currentUid.toString()}, ex);
+ }
+ }
+ }
+ }
+
+ // now get the BA recovery manager to try to activate recovered participants
+
+ XTSBARecoveryManager.getRecoveryManager().recoverParticipants();
+ }
+
+ // 'type' within the Object Store for BAParticipant record.
+ private String _participantType = BAParticipantRecoveryRecord.type() ;
+
+ // Array of transactions found in the object store of the
+ // ACCoordinator type.
+ private Vector _participantUidVector = null ;
+
+ // Reference to the Object Store.
+ private static ObjectStore _objectStore = null ;
+
+ // This object provides information about whether or not a participant is currently active.
+
+ private HashMap<String, BAParticipantRecoveryRecord> _recoveredParticipantMap ;
+}
\ No newline at end of file
Copied: labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/recovery/participant/ba/XTSBARecoveryManagerImple.java (from rev 27481, labs/jbosstm/trunk/XTS/sar/src/org/jboss/jbossts/xts/recovery/participant/ba/XTSBARecoveryManagerImple.java)
===================================================================
--- labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/recovery/participant/ba/XTSBARecoveryManagerImple.java (rev 0)
+++ labs/jbosstm/trunk/XTS/recovery/src/org/jboss/jbossts/xts/recovery/participant/ba/XTSBARecoveryManagerImple.java 2009-07-06 14:30:00 UTC (rev 27633)
@@ -0,0 +1,342 @@
+package org.jboss.jbossts.xts.recovery.participant.ba;
+
+import org.jboss.jbossts.xts.logging.XTSLogger;
+
+import com.arjuna.ats.arjuna.objectstore.ObjectStore;
+import com.arjuna.ats.arjuna.state.OutputObjectState;
+import com.arjuna.ats.arjuna.common.Uid;
+import com.arjuna.ats.arjuna.exceptions.ObjectStoreException;
+
+import java.util.*;
+import java.io.IOException;
+
+/**
+ * A class which manages the table of recovered participant records.
+ *
+ * @message org.jboss.transactions.xts.recovery.participant.ba.XTSBARecoveryModule_1 [org.jboss.transactions.xts.recovery.participant.ba.XTSBARecoveryModule_1] exception writing recovery record for WS-BA participant {0}
+ * @message org.jboss.transactions.xts.recovery.participant.ba.XTSBARecoveryModule_2 [org.jboss.transactions.xts.recovery.participant.ba.XTSBARecoveryModule_2] exception removing recovery record {0} for WS-BA participant {1}
+ * @message org.jboss.transactions.xts.recovery.participant.ba.XTSBARecoveryModule_3 [org.jboss.transactions.xts.recovery.participant.ba.XTSBARecoveryModule_3] exception reactivating recovered WS-BA participant {0}
+ * @message org.jboss.transactions.xts.recovery.participant.ba.XTSBARecoveryModule_4 [org.jboss.transactions.xts.recovery.participant.ba.XTSBARecoveryModule_4] no XTS application recovery module found to help reactivate recovered WS-BA participant {0}
+ */
+public class XTSBARecoveryManagerImple extends XTSBARecoveryManager {
+ /**
+ * constructor for use by BAParticipantRecoveryModule
+ * @param objectStore
+ */
+ XTSBARecoveryManagerImple(ObjectStore objectStore)
+ {
+ this.objectStore = objectStore;
+ }
+
+ /**
+ * register an application specific recovery module which acts as a helper to recreate
+ * a WS-BA durable participant from the participant's recovery data saved at prepare
+ *
+ * @param module the module which will be used to identify and recreate participants
+ * for the application
+ * @throws NullPointerException if the supplied module is null
+ */
+ public void registerRecoveryModule(XTSBARecoveryModule module) throws NullPointerException
+ {
+ // TODO other sanity checks?
+ if (module == null) {
+ throw new NullPointerException("XTSBARecoveryModule value must be non-null");
+ }
+
+ recoveryModules.add(module);
+ }
+
+ /**
+ * unregister an application specific recovery module previously registered as
+ * a helper to recretae WS-BA durable participants
+ *
+ * @param module the module to be unregistered
+ * @throws java.util.NoSuchElementException
+ * if the module is not currently registered
+ */
+ public void unregisterRecoveryModule(XTSBARecoveryModule module) throws NoSuchElementException {
+ if (!recoveryModules.remove(module)) {
+ throw new NoSuchElementException();
+ }
+ }
+
+ /**
+ * save the supplied participant recovery record to persistent storage
+ *
+ * @param participantRecoveryRecord
+ */
+ public boolean writeParticipantRecoveryRecord(BAParticipantRecoveryRecord participantRecoveryRecord)
+ {
+ OutputObjectState oos = new OutputObjectState();
+ // we need to be able to retrieve the class of the participant record so we can
+ // create an instancde to load the rest of the participant specific data
+ try {
+ oos.packString(participantRecoveryRecord.getClass().getCanonicalName());
+ } catch (IOException ioe) {
+ if (XTSLogger.arjLoggerI18N.isWarnEnabled())
+ {
+ XTSLogger.arjLoggerI18N.warn("org.jboss.transactions.xts.recovery.participant.ba.XTSBARecoveryModule_1",
+ new Object[] {participantRecoveryRecord.getId()}, ioe);
+ }
+ return false;
+ }
+
+ if (participantRecoveryRecord.saveState(oos)) {
+ Uid uid = new Uid();
+ try {
+ objectStore.write_committed(uid, type, oos);
+ // we need to be able to identify the uid from the participant id
+ // in order to delete it later
+ uidMap.put(participantRecoveryRecord.getId(), uid);
+ return true;
+ } catch (ObjectStoreException ose) {
+ if (XTSLogger.arjLoggerI18N.isWarnEnabled())
+ {
+ XTSLogger.arjLoggerI18N.warn("org.jboss.transactions.xts.recovery.participant.ba.XTSBARecoveryModule_1",
+ new Object[] {participantRecoveryRecord.getId()}, ose);
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * remove any participant recovery record with the supplied id from persistent storage
+ * @param id the id of the participant whose recovery details are being deleted
+ */
+ public boolean deleteParticipantRecoveryRecord(String id)
+ {
+ Uid uid = uidMap.get(id);
+
+ if (uid != null) {
+
+ try {
+ objectStore.remove_committed(uid, type);
+ uidMap.remove(id);
+ return true;
+ } catch (ObjectStoreException ose) {
+ if (XTSLogger.arjLoggerI18N.isWarnEnabled())
+ {
+ XTSLogger.arjLoggerI18N.warn("org.jboss.transactions.xts.recovery.participant.ba.XTSBARecoveryModule_2",
+ new Object[] {uid, id},
+ ose);
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * test whether the supplied uid identifies an active participant or a recovered but inactive
+ * participant
+ *
+ * n.b. this method is not synchronized because of two assumptions: first, that uids are
+ * never reused; and second that only recovery scanning (as a minimum, for a given recovery
+ * record type) is single-threaded. Correctness of the first assumption ensures there are no
+ * races with participant processor threads, the second races between recovery threads.
+ *
+ * @param uid
+ */
+ public boolean isParticipantPresent(Uid uid)
+ {
+ return (uidMap.get(uid) != null);
+ }
+
+ /**
+ * add a recovered participant record to the table of unrecovered participants which
+ * need to be recreated following recovery
+ *
+ * @param uid the uid under which the participant was saved in the file store
+ * @param participantRecoveryRecord the in-memory representation of the recovery record
+ * saved to disk
+ */
+ public void addParticipantRecoveryRecord(Uid uid, BAParticipantRecoveryRecord participantRecoveryRecord)
+ {
+ String participantId = participantRecoveryRecord.getId();
+ if (recoveryMap.get(participantId) == null && !participantRecoveryRecord.isActive()) {
+ // ok, we have not seen this entry before so add it to the list
+ recoveryMap.put(participantId, participantRecoveryRecord);
+ uidMap.put(participantId, uid);
+ }
+ }
+
+ /**
+ * see if a participant recovery record with a given id exists in the table of participants which
+ * need to be recreated following recovery
+ * @param id the identifier of the participant being sought
+ * @return the participant recovery record with the supplied id or null if it is not found
+ */
+ public synchronized BAParticipantRecoveryRecord findParticipantRecoveryRecord(String id)
+ {
+ return recoveryMap.get(id);
+ }
+
+ /**
+ * process all entries in the recovered participant map and attempt to recreate the
+ * application participant and activate it
+ */
+ public void recoverParticipants()
+ {
+ // the first scan has been performed so allow processing of commit and rollback requests
+ // for unknown ids to proceed now
+
+ setParticipantRecoveryStarted();
+
+ // we operate on a copy of the recovery modules to avoid the list being modified
+ // by register and unregister operations while we are iterating over it
+ // we should probably also make sure unregister does not proceed until
+ // the current scan is complete . . .
+
+ List<XTSBARecoveryModule> recoveryModulesCopy;
+ synchronized (recoveryModules) {
+ recoveryModulesCopy = new ArrayList<XTSBARecoveryModule>(recoveryModules);
+ }
+
+ // iterate through the participant recovery records and try to convert them to
+ // a durable participant. if successful activate the participant and then remove the
+ // recovery entry. note that since recovery is single threaded we can be sure that
+ // no concurrent modifications will be made to the table while we are iterating and,
+ // possibly, deleting via the iterator
+
+ Iterator<BAParticipantRecoveryRecord> participantIterator = iterator();
+
+ while(participantIterator.hasNext()) {
+ BAParticipantRecoveryRecord participantRecoveryRecord = participantIterator.next();
+ if (participantRecoveryRecord.isActive()) {
+ // this participant must have already been activated by a by a previous
+ // scan and been reloaded by this scan so just remove the entry
+
+ participantIterator.remove();
+ } else {
+ Iterator<XTSBARecoveryModule> moduleIterator = recoveryModulesCopy.iterator();
+ boolean found = false;
+
+ while (!found && moduleIterator.hasNext()) {
+ XTSBARecoveryModule module = moduleIterator.next();
+ try {
+ if (participantRecoveryRecord.restoreParticipant(module)) {
+ // ok, this participant has recovered so tell it to
+ // activate and *then* remove it from the hashmap. this makes
+ // sure we don't open a window where an incoming
+ // commit may fail to find the object in either table
+
+ found = true;
+ participantRecoveryRecord.activate();
+
+ participantIterator.remove();
+ }
+ } catch (Exception e) {
+ // we foudn a helper but it failed to convert the participant record -- log a warning
+ // but leave the participant in the table for next time in case the helper has merely
+ // suffered a transient failure
+ found = true;
+ if (XTSLogger.arjLoggerI18N.isWarnEnabled())
+ {
+ XTSLogger.arjLoggerI18N.warn("org.jboss.transactions.xts.recovery.participant.ba.XTSBARecoveryModule_3",
+ new Object[] {participantRecoveryRecord.getId()},
+ e);
+ }
+ }
+ }
+
+ if (!found) {
+ // we failed to find a helper to convert a participant record so log a warning
+ // but leave it in the table for next time
+ if (XTSLogger.arjLoggerI18N.isWarnEnabled())
+ {
+ XTSLogger.arjLoggerI18N.warn("org.jboss.transactions.xts.recovery.participant.ba.XTSBARecoveryModule_4",
+ new Object[] {participantRecoveryRecord.getId()});
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * 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
+ * @return
+ */
+ private synchronized Iterator<BAParticipantRecoveryRecord> iterator()
+ {
+ return recoveryMap.values().iterator();
+ }
+
+ /**
+ * set a global flag indicating that the first BA participant recovery scan has
+ * been performed.
+ */
+ private synchronized void setParticipantRecoveryStarted()
+ {
+ participantRecoveryStarted = true;
+ }
+
+ /**
+ * test whether the first BA participant recovery scan has completed. this indicates whether
+ * there may or may not still be unknown participant recovery records on disk. If the first
+ * scan has not yet completed then a commit or rollback message for an unknown participant
+ * must be dropped. If it has then a commit or rollback for an unknown participant must be
+ * acknowledged with, respectively, a committed or aborted message.
+ */
+ public synchronized boolean isParticipantRecoveryStarted()
+ {
+ return participantRecoveryStarted;
+ }
+
+ /**
+ * test whether the first BA coordinator recovery scan has completed. this indicates whether
+ * there may or may not still be unknown BA transcation records on disk. If the first
+ * scan has not yet completed then a prepare message for an unknown participant
+ * must be dropped. If it has then a perpare for an unknown participant must be
+ * acknowledged with a rollback message.
+ */
+ public synchronized boolean isCoordinatorRecoveryStarted() {
+ return coordinatorRecoveryStarted;
+ }
+
+ /**
+ * record the fact that the first BA coordinator recovery scan has completed.
+ */
+
+ public synchronized void setCoordinatorRecoveryStarted() {
+ coordinatorRecoveryStarted = true;
+ }
+
+ /**
+ * a global flag indicating whether the first BA participant recovery scan has
+ * been performed.
+ */
+ private boolean participantRecoveryStarted = false;
+
+ /**
+ * a global flag indicating whether the first AT coordinator recovery scan has
+ * been performed.
+ */
+ private boolean coordinatorRecoveryStarted = false;
+
+ /**
+ * a map from participant ids to participant recovery records
+ */
+ private HashMap<String, BAParticipantRecoveryRecord> recoveryMap = new HashMap<String, BAParticipantRecoveryRecord>();
+
+ /**
+ * a map from participant id to the uid under which the participant has been saved in the
+ * persistent store
+ */
+ private HashMap<String, Uid> uidMap = new HashMap<String, Uid>();
+
+ /**
+ * a map from participant ids to participant recover records
+ */
+ private List<XTSBARecoveryModule> recoveryModules = new ArrayList<XTSBARecoveryModule>();
+
+ /**
+ * the tx object store to be used for saving and deleting participant details
+ */
+ private ObjectStore objectStore;
+
+ private final static String type = BAParticipantRecoveryRecord.type();
+}
\ No newline at end of file
Deleted: labs/jbosstm/trunk/XTS/sar/src/org/jboss/jbossts/xts/logging/XTSLogger.java
===================================================================
--- labs/jbosstm/trunk/XTS/sar/src/org/jboss/jbossts/xts/logging/XTSLogger.java 2009-07-06 14:14:03 UTC (rev 27632)
+++ labs/jbosstm/trunk/XTS/sar/src/org/jboss/jbossts/xts/logging/XTSLogger.java 2009-07-06 14:30:00 UTC (rev 27633)
@@ -1,34 +0,0 @@
-package org.jboss.jbossts.xts.logging;
-
-import java.util.Locale;
-import java.util.ResourceBundle;
-
-import com.arjuna.ats.arjuna.common.arjPropertyManager;
-import com.arjuna.common.internal.util.logging.commonPropertyManager;
-import com.arjuna.common.util.logging.LogFactory;
-import com.arjuna.common.util.logging.LogNoi18n;
-import com.arjuna.common.util.logging.Logi18n;
-
-public class XTSLogger
-{
- public static LogNoi18n arjLogger;
- public static Logi18n arjLoggerI18N;
- public static ResourceBundle log_mesg;
-
- static
- {
- /** Ensure the properties are loaded before initialising the logger **/
- arjPropertyManager.getPropertyManager();
-
- arjLogger = LogFactory.getLogNoi18n("com.arjuna.webservices.logging.XTSLogger");
-
- final String language = commonPropertyManager.getPropertyManager().getProperty("language","en");
- final String country = commonPropertyManager.getPropertyManager().getProperty("country","US");
-
- final Locale currentLocale = new Locale(language, country);
- log_mesg = ResourceBundle.getBundle("xts_msg",currentLocale);
-
- arjLoggerI18N = LogFactory.getLogi18n("com.arjuna.webservices.logging.XTSLoggerI18N",
- "xts_msg_"+language+"_"+country);
- }
-}
Deleted: labs/jbosstm/trunk/XTS/sar/src/org/jboss/jbossts/xts/recovery/participant/at/ATParticipantRecoveryModule.java
===================================================================
--- labs/jbosstm/trunk/XTS/sar/src/org/jboss/jbossts/xts/recovery/participant/at/ATParticipantRecoveryModule.java 2009-07-06 14:14:03 UTC (rev 27632)
+++ labs/jbosstm/trunk/XTS/sar/src/org/jboss/jbossts/xts/recovery/participant/at/ATParticipantRecoveryModule.java 2009-07-06 14:30:00 UTC (rev 27633)
@@ -1,341 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2007, 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) 2007,
- * @author Red Hat Middleware LLC.
- */
-package org.jboss.jbossts.xts.recovery.participant.at;
-
-import org.jboss.jbossts.xts.logging.XTSLogger;
-
-import com.arjuna.ats.arjuna.recovery.RecoveryModule;
-import com.arjuna.ats.arjuna.logging.FacilityCode;
-import com.arjuna.ats.arjuna.coordinator.TxControl;
-import com.arjuna.ats.arjuna.state.InputObjectState;
-import com.arjuna.ats.arjuna.exceptions.ObjectStoreException;
-import com.arjuna.ats.arjuna.common.Uid;
-import com.arjuna.ats.arjuna.objectstore.ObjectStore;
-import com.arjuna.common.util.logging.DebugLevel;
-import com.arjuna.common.util.logging.VisibilityLevel;
-
-import java.util.Vector;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.io.IOException;
-
-import org.jboss.jbossts.xts.recovery.participant.at.ATParticipantRecoveryRecord;
-
-/**
- * This class is a plug-in module for the recovery manager.
- * It is responsible for recovering XTS AT participants.
- * (instances of org.jboss.jbossts.xts.recovery.participant.at.ATParticipantRecoveryRecord)
- *
- * $Id$
- *
- * @message org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryModule_1 [org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryModule_1] - RecoveryManagerStatusModule: Object store exception: {0}
- * @message org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryModule_3 [org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryModule_3] - failed to access transaction store {0}
- * @message org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryModule_4 [org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryModule_4] - unable to load recovery record implementation class {0} for WS-AT participant recovery record {1}
- * @message org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryModule_5 [org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryModule_5] - unable to instantiate recovery record implementation class {0} for WS-AT participant recovery record {1}
- * @message org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryModule_6 [org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryModule_6] - unable to unpack recovery record data for WS-AT participant recovery record {0}
- * @message org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryModule_7 [org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryModule_7] - missing recovery record data for WS-AT participant recovery record {0}
- * @message org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryModule_8 [org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryModule_8] - unable to read recovery record data for WS-AT participant recovery record {0}
- */
-
-public class ATParticipantRecoveryModule implements RecoveryModule
-{
- public ATParticipantRecoveryModule()
- {
- if (XTSLogger.arjLogger.isDebugEnabled())
- {
- XTSLogger.arjLogger.debug
- ( DebugLevel.CONSTRUCTORS,
- VisibilityLevel.VIS_PUBLIC,
- FacilityCode.FAC_CRASH_RECOVERY,
- "ATParticipantRecoveryModule created - default" );
- }
-
- if (_objectStore == null)
- {
- _objectStore = TxControl.getStore() ;
- }
-
- _participantType = ATParticipantRecoveryRecord.type();
- }
-
- /**
- * called by the service startup code before the recovery module is added to the recovery managers
- * module list
- */
- public void install()
- {
- XTSATRecoveryManager.setRecoveryManager(new XTSATRecoveryManagerImple(_objectStore));
- // Subordinate Coordinators register durable participants with their parent transaction so
- // we need to add an XTSATRecoveryModule which knows about the registered participants
-
- subordinateRecoveryModule = new XTSATSubordinateRecoveryModule();
- XTSATRecoveryManager.getRecoveryManager().registerRecoveryModule(subordinateRecoveryModule);
- }
-
- /**
- * a recovery module which knows hwo to recover the participants registered by Subordinate AT Coordinators
- */
-
- private XTSATSubordinateRecoveryModule subordinateRecoveryModule;
-
- /**
- * called by the service shutdown code after the recovery module is removed from the recovery managers
- * module list
- */
- public void uninstall()
- {
- XTSATRecoveryManager.getRecoveryManager().unregisterRecoveryModule(subordinateRecoveryModule);
- }
-
- /**
- * This is called periodically by the RecoveryManager
- */
- public void periodicWorkFirstPass()
- {
- // Transaction type
- boolean ATParticipants = false ;
-
- // uids per transaction type
- InputObjectState acc_uids = new InputObjectState() ;
-
- try
- {
- if (XTSLogger.arjLogger.isDebugEnabled())
- {
- XTSLogger.arjLogger.debug( "StatusModule: first pass " );
- }
-
- ATParticipants = _objectStore.allObjUids(_participantType, acc_uids );
-
- }
- catch ( ObjectStoreException ex )
- {
- if (XTSLogger.arjLoggerI18N.isWarnEnabled())
- {
- XTSLogger.arjLoggerI18N.warn("org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryModule_1",
- ex);
- }
- }
-
- if ( ATParticipants )
- {
- _participantUidVector = processParticipants( acc_uids ) ;
- }
- }
-
- public void periodicWorkSecondPass()
- {
- if (XTSLogger.arjLogger.isDebugEnabled())
- {
- XTSLogger.arjLogger.debug( "ATParticipantRecoveryModule: Second pass " );
- }
-
- processParticipantsStatus() ;
- }
-
- private void doRecoverParticipant( Uid recoverUid )
- {
- // Retrieve the participant from its original process.
-
- if (XTSLogger.arjLogger.isDebugEnabled())
- {
- XTSLogger.arjLogger.debug
- ( DebugLevel.FUNCTIONS,
- VisibilityLevel.VIS_PUBLIC,
- FacilityCode.FAC_CRASH_RECOVERY,
- "participant type is "+ _participantType + " uid is " +
- recoverUid.toString()) ;
- }
-
- // we don't need to use a lock here because we only attempt the read
- // when the uid is inactive which means it cannto be pulled out form under our
- // feet at commit. uniqueness of uids also means we can't be foiled by a reused
- // uid.
-
- XTSATRecoveryManager recoveryManager = XTSATRecoveryManager.getRecoveryManager();
-
- if (!recoveryManager.isParticipantPresent(recoverUid)) {
- // ok, the participant can neither be active nor loaded awaiting recreation by
- // an application recovery module so we need to load it
- try {
- // retrieve the data for the participant
- InputObjectState inputState = _objectStore.read_committed(recoverUid, _participantType);
-
- if (inputState != null) {
- try {
- String participantRecordClazzName = inputState.unpackString();
- try {
- // create a participant engine instance and tell it to recover itself
- Class participantRecordClazz = Class.forName(participantRecordClazzName);
- ATParticipantRecoveryRecord participantRecord = (ATParticipantRecoveryRecord)participantRecordClazz.newInstance();
- participantRecord.restoreState(inputState);
- // ok, now insert into recovery map if needed
- XTSATRecoveryManager.getRecoveryManager().addParticipantRecoveryRecord(recoverUid, participantRecord);
- } catch (ClassNotFoundException cnfe) {
- // oh boy, not supposed to happen -- n.b. either the user deployed 1.0
- // last time and 1.1 this time or vice versa or something is rotten in
- // the state of Danmark
- if (XTSLogger.arjLoggerI18N.isErrorEnabled())
- {
- XTSLogger.arjLoggerI18N.error("org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryModule_4",
- new Object[]{participantRecordClazzName, recoverUid.toString()}, cnfe);
- }
- } catch (InstantiationException ie) {
- // this is also worrying, log an error
- if (XTSLogger.arjLoggerI18N.isErrorEnabled())
- {
- XTSLogger.arjLoggerI18N.error("org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryModule_5",
- new Object[]{participantRecordClazzName, recoverUid.toString()}, ie);
- }
- } catch (IllegalAccessException iae) {
- // this is another configuration problem, log an error
- if (XTSLogger.arjLoggerI18N.isErrorEnabled())
- {
- XTSLogger.arjLoggerI18N.error("org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryModule_5",
- new Object[]{participantRecordClazzName, recoverUid.toString()}, iae);
- }
- }
- } catch (IOException ioe) {
- // hmm, record corrupted? log this as a warning
- if (XTSLogger.arjLoggerI18N.isWarnEnabled())
- {
- XTSLogger.arjLoggerI18N.warn("org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryModule_6",
- new Object[]{recoverUid.toString()}, ioe);
- }
- }
- } else {
- // hmm, it ought not to be able to disappear unless the recovery manager knows about it
- // this is an error!
- if (XTSLogger.arjLoggerI18N.isErrorEnabled())
- {
- XTSLogger.arjLoggerI18N.error("org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryModule_7",
- new Object[]{recoverUid.toString()});
- }
- }
- } catch (ObjectStoreException ose) {
- // if the object store is not working this is serious
- if (XTSLogger.arjLoggerI18N.isErrorEnabled())
- {
- XTSLogger.arjLoggerI18N.error("org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryModule_8",
- new Object[]{recoverUid.toString()}, ose);
- }
- }
- }
- }
-
- private Vector processParticipants( InputObjectState uids )
- {
- Vector uidVector = new Vector() ;
-
- if (XTSLogger.arjLogger.isDebugEnabled())
- {
- XTSLogger.arjLogger.debug( DebugLevel.FUNCTIONS,
- VisibilityLevel.VIS_PUBLIC,
- FacilityCode.FAC_CRASH_RECOVERY,
- "processing " + _participantType
- + " WS-AT participants" ) ;
- }
-
- Uid theUid = new Uid( Uid.nullUid() );
-
- boolean moreUids = true ;
-
- while (moreUids)
- {
- try
- {
- theUid.unpack( uids ) ;
-
- if (theUid.equals( Uid.nullUid() ))
- {
- moreUids = false;
- }
- else
- {
- Uid newUid = new Uid( theUid ) ;
-
- if (XTSLogger.arjLogger.isDebugEnabled())
- {
- XTSLogger.arjLogger.debug
- ( DebugLevel.FUNCTIONS,
- VisibilityLevel.VIS_PUBLIC,
- FacilityCode.FAC_CRASH_RECOVERY,
- "found WS-AT participant "+ newUid ) ;
- }
-
- uidVector.addElement( newUid ) ;
- }
- }
- catch ( Exception ex )
- {
- moreUids = false;
- }
- }
- return uidVector ;
- }
-
- private void processParticipantsStatus()
- {
- if (_participantUidVector != null) {
- // Process the Vector of transaction Uids
- Enumeration participantUidEnum = _participantUidVector.elements() ;
-
- while ( participantUidEnum.hasMoreElements() )
- {
- Uid currentUid = (Uid) participantUidEnum.nextElement();
-
- try
- {
- if ( _objectStore.currentState( currentUid, _participantType) != ObjectStore.OS_UNKNOWN )
- {
- doRecoverParticipant( currentUid ) ;
- }
- }
- catch ( ObjectStoreException ex )
- {
- if (XTSLogger.arjLogger.isWarnEnabled())
- {
- XTSLogger.arjLoggerI18N.warn("org.jboss.transactions.xts.recovery.participant.at.ATParticipantRecoveryModule_3",
- new Object[]{currentUid.toString()}, ex);
- }
- }
- }
- }
-
- // now get the AT recovery manager to try to activate recovered participants
-
- XTSATRecoveryManager.getRecoveryManager().recoverParticipants();
- }
-
- // 'type' within the Object Store for ATParticipant record.
- private String _participantType = ATParticipantRecoveryRecord.type() ;
-
- // Array of transactions found in the object store of the
- // ACCoordinator type.
- private Vector _participantUidVector = null ;
-
- // Reference to the Object Store.
- private static ObjectStore _objectStore = null ;
-
- // This object provides information about whether or not a participant is currently active.
-
- private HashMap<String, ATParticipantRecoveryRecord> _recoveredParticipantMap ;
-}
\ No newline at end of file
Deleted: labs/jbosstm/trunk/XTS/sar/src/org/jboss/jbossts/xts/recovery/participant/at/XTSATRecoveryManagerImple.java
===================================================================
--- labs/jbosstm/trunk/XTS/sar/src/org/jboss/jbossts/xts/recovery/participant/at/XTSATRecoveryManagerImple.java 2009-07-06 14:14:03 UTC (rev 27632)
+++ labs/jbosstm/trunk/XTS/sar/src/org/jboss/jbossts/xts/recovery/participant/at/XTSATRecoveryManagerImple.java 2009-07-06 14:30:00 UTC (rev 27633)
@@ -1,367 +0,0 @@
-package org.jboss.jbossts.xts.recovery.participant.at;
-
-import org.jboss.jbossts.xts.logging.XTSLogger;
-
-import com.arjuna.wst.Durable2PCParticipant;
-import com.arjuna.ats.arjuna.objectstore.ObjectStore;
-import com.arjuna.ats.arjuna.state.OutputObjectState;
-import com.arjuna.ats.arjuna.common.Uid;
-import com.arjuna.ats.arjuna.exceptions.ObjectStoreException;
-
-import java.util.*;
-import java.io.IOException;
-
-/**
- * A class which manages the table of recovered participant records.
- *
- * @message org.jboss.transactions.xts.recovery.participant.at.XTSATRecoveryModule_1 [org.jboss.transactions.xts.recovery.participant.at.XTSATRecoveryModule_1] exception writing recovery record for WS-AT participant {0}
- * @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}
- */
-public class XTSATRecoveryManagerImple extends XTSATRecoveryManager {
- /**
- * constructor for use by ATParticipantRecoveryModule
- * @param objectStore
- */
- XTSATRecoveryManagerImple(ObjectStore objectStore)
- {
- this.objectStore = objectStore;
- }
-
- /**
- * register an application specific recovery module which acts as a helper to recreate
- * a WS-AT durable participant from the participant's recovery data saved at prepare
- *
- * @param module the module which will be used to identify and recreate participants
- * for the application
- * @throws NullPointerException if the supplied module is null
- */
- public void registerRecoveryModule(XTSATRecoveryModule module) throws NullPointerException
- {
- // TODO other sanity checks?
- if (module == null) {
- throw new NullPointerException("XTSATRecoveryModule value must be non-null");
- }
-
- recoveryModules.add(module);
- }
-
- /**
- * unregister an application specific recovery module previously registered as
- * a helper to recretae WS-AT durable participants
- *
- * @param module the module to be unregistered
- * @throws java.util.NoSuchElementException
- * if the module is not currently registered
- */
- public void unregisterRecoveryModule(XTSATRecoveryModule module) throws NoSuchElementException {
- if (!recoveryModules.remove(module)) {
- throw new NoSuchElementException();
- }
- }
-
- /**
- * save the supplied participant recovery record to persistent storage
- *
- * @param participantRecoveryRecord
- */
- public boolean writeParticipantRecoveryRecord(ATParticipantRecoveryRecord participantRecoveryRecord)
- {
- OutputObjectState oos = new OutputObjectState();
- // we need to be able to retrieve the class of the participant record so we can
- // create an instancde to load the rest of the participant specific data
- try {
- oos.packString(participantRecoveryRecord.getClass().getCanonicalName());
- } catch (IOException ioe) {
- if (XTSLogger.arjLoggerI18N.isWarnEnabled())
- {
- XTSLogger.arjLoggerI18N.warn("org.jboss.transactions.xts.recovery.participant.at.XTSATRecoveryModule_1",
- new Object[] {participantRecoveryRecord.getId()}, ioe);
- }
- return false;
- }
-
- if (participantRecoveryRecord.saveState(oos)) {
- Uid uid = new Uid();
- try {
- objectStore.write_committed(uid, type, oos);
- // we need to be able to identify the uid from the participant id
- // in order to delete it later
- uidMap.put(participantRecoveryRecord.getId(), uid);
- return true;
- } catch (ObjectStoreException ose) {
- if (XTSLogger.arjLoggerI18N.isWarnEnabled())
- {
- XTSLogger.arjLoggerI18N.warn("org.jboss.transactions.xts.recovery.participant.at.XTSATRecoveryModule_1",
- new Object[] {participantRecoveryRecord.getId()}, ose);
- }
- }
- }
-
- return false;
- }
-
- /**
- * remove any participant recovery record with the supplied id from persistent storage
- * @param id the id of the participant whose recovery details are being deleted
- */
- public boolean deleteParticipantRecoveryRecord(String id)
- {
- Uid uid = uidMap.get(id);
-
- if (uid != null) {
-
- try {
- objectStore.remove_committed(uid, type);
- uidMap.remove(id);
- return true;
- } catch (ObjectStoreException ose) {
- if (XTSLogger.arjLoggerI18N.isWarnEnabled())
- {
- XTSLogger.arjLoggerI18N.warn("org.jboss.transactions.xts.recovery.participant.at.XTSATRecoveryModule_2",
- new Object[] {uid, id},
- ose);
- }
- }
- }
-
- return false;
- }
-
- /**
- * test whether the supplied uid identifies an active participant or a recovered but inactive
- * participant
- *
- * n.b. this method is not synchronized because of two assumptions: first, that uids are
- * never reused; and second that only recovery scanning (as a minimum, for a given recovery
- * record type) is single-threaded. Correctness of the first assumption ensures there are no
- * races with participant processor threads, the second races between recovery threads.
- *
- * @param uid
- */
- public boolean isParticipantPresent(Uid uid)
- {
- return (uidMap.get(uid) != null);
- }
-
- /**
- * add a recovered participant record to the table of unrecovered participants which
- * need to be recreated following recovery
- *
- * @param uid the uid under which the participant was saved in the file store
- * @param participantRecoveryRecord the in-memory representation of the recovery record
- * saved to disk
- */
- public void addParticipantRecoveryRecord(Uid uid, ATParticipantRecoveryRecord participantRecoveryRecord)
- {
- String participantId = participantRecoveryRecord.getId();
- if (recoveryMap.get(participantId) == null && !participantRecoveryRecord.isActive()) {
- // ok, we have not seen this entry before so add it to the list
- recoveryMap.put(participantId, participantRecoveryRecord);
- uidMap.put(participantId, uid);
- }
- }
-
- /**
- * see if a participant recovery record with a given id exists in the table of participants which
- * need to be recreated following recovery
- * @param id the identifier of the participant being sought
- * @return the participant recovery record with the supplied id or null if it is not found
- */
- public synchronized ATParticipantRecoveryRecord findParticipantRecoveryRecord(String id)
- {
- return recoveryMap.get(id);
- }
-
- /**
- * process all entries in the recovered participant map and attempt to recreate the
- * application participant and activate it
- */
- public void recoverParticipants()
- {
- // the first scan has been performed so allow processing of commit and rollback requests
- // for unknown ids to proceed now
-
- setParticipantRecoveryStarted();
-
- // we operate on a copy of the recovery modules to avoid the list being modified
- // by register and unregister operations while we are iterating over it
- // we should probably also make sure unregister does not proceed until
- // the current scan is complete . . .
-
- List<XTSATRecoveryModule> recoveryModulesCopy;
- synchronized (recoveryModules) {
- recoveryModulesCopy = new ArrayList<XTSATRecoveryModule>(recoveryModules);
- }
-
- // iterate through the participant recovery records and try to convert them to
- // a durable participant. if successful activate the participant and then remove the
- // recovery entry. note that since recovery is single threaded we can be sure that
- // no concurrent modifications will be made to the table while we are iterating and,
- // possibly, deleting via the iterator
-
- Iterator<ATParticipantRecoveryRecord> participantIterator = iterator();
-
- while(participantIterator.hasNext()) {
- ATParticipantRecoveryRecord participantRecoveryRecord = participantIterator.next();
- if (participantRecoveryRecord.isActive()) {
- // this participant must have already been activated by a by a previous
- // scan and been reloaded by this scan so just remove the entry
-
- participantIterator.remove();
- } else {
- Iterator<XTSATRecoveryModule> moduleIterator = recoveryModulesCopy.iterator();
- boolean found = false;
-
- while (!found && moduleIterator.hasNext()) {
- XTSATRecoveryModule module = moduleIterator.next();
- try {
- if (participantRecoveryRecord.restoreParticipant(module)) {
- // ok, this participant has recovered so tell it to
- // activate and *then* remove it from the hashmap. this makes
- // sure we don't open a window where an incoming
- // commit may fail to find the object in either table
-
- found = true;
- participantRecoveryRecord.activate();
-
- participantIterator.remove();
- }
- } catch (Exception e) {
- // we foudn a helper but it failed to convert the participant record -- log a warning
- // but leave the participant in the table for next time in case the helper has merely
- // suffered a transient failure
- found = true;
- if (XTSLogger.arjLoggerI18N.isWarnEnabled())
- {
- XTSLogger.arjLoggerI18N.warn("org.jboss.transactions.xts.recovery.participant.at.XTSATRecoveryModule_3",
- new Object[] {participantRecoveryRecord.getId()},
- e);
- }
- }
- }
-
- if (!found) {
- // we failed to find a helper to convert a participant record so log a warning
- // but leave it in the table for next time
- if (XTSLogger.arjLoggerI18N.isWarnEnabled())
- {
- XTSLogger.arjLoggerI18N.warn("org.jboss.transactions.xts.recovery.participant.at.XTSATRecoveryModule_4",
- new Object[] {participantRecoveryRecord.getId()});
- }
- }
- }
- }
- }
-
- /**
- * 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
- * @return
- */
- private synchronized Iterator<ATParticipantRecoveryRecord> iterator()
- {
- return recoveryMap.values().iterator();
- }
-
- /**
- * set a global flag indicating that the first AT participant recovery scan has
- * been performed.
- */
- private synchronized void setParticipantRecoveryStarted()
- {
- participantRecoveryStarted = true;
- }
-
- /**
- * test whether the first AT participant recovery scan has completed. this indicates whether
- * there may or may not still be unknown participant recovery records on disk. If the first
- * scan has not yet completed then a commit or rollback message for an unknown participant
- * must be dropped. If it has then a commit or rollback for an unknown participant must be
- * acknowledged with, respectively, a committed or aborted message.
- */
- public synchronized boolean isParticipantRecoveryStarted()
- {
- return participantRecoveryStarted;
- }
-
- /**
- * test whether the first AT coordinator recovery scan has completed. this indicates whether
- * there may or may not still be unknown AT transcation records on disk. If the first
- * scan has not yet completed then a prepare message for an unknown participant
- * must be dropped. If it has then a perpare for an unknown participant must be
- * acknowledged with a rollback message.
- */
- public synchronized boolean isCoordinatorRecoveryStarted() {
- return coordinatorRecoveryStarted;
- }
-
- /**
- * test whether the first AT subordinate coordinator recovery scan has completed. this indicates
- * whether there may or may not still be unknown AT subtransaction records on disk. If the first
- * scan has not yet completed then a commit for an unknown subtransaction must raise an exception
- * delaying commit of the parent transaction.
- */
- public synchronized boolean isSubordinateCoordinatorRecoveryStarted() {
- return subordinateCoordinatorRecoveryStarted;
- }
-
- /**
- * record the fact that the first AT coordinator recovery scan has completed.
- */
-
- public synchronized void setCoordinatorRecoveryStarted() {
- coordinatorRecoveryStarted = true;
- }
-
- /**
- * record the fact that the first AT subordinate coordinator recovery scan has completed.
- */
-
- public synchronized void setSubordinateCoordinatorRecoveryStarted() {
- subordinateCoordinatorRecoveryStarted = true;
- }
-
- /**
- * a global flag indicating whether the first AT participant recovery scan has
- * been performed.
- */
- private boolean participantRecoveryStarted = false;
-
- /**
- * a global flag indicating whether the first AT coordinator recovery scan has
- * been performed.
- */
- private boolean coordinatorRecoveryStarted = false;
-
- /**
- * a global flag indicating whether the first AT subordinate coordinator recovery scan has
- * been performed.
- */
- private boolean subordinateCoordinatorRecoveryStarted = false;
-
- /**
- * a map from participant ids to participant recovery records
- */
- private HashMap<String, ATParticipantRecoveryRecord> recoveryMap = new HashMap<String, ATParticipantRecoveryRecord>();
-
- /**
- * a map from participant id to the uid under which the participant has been saved in the
- * persistent store
- */
- private HashMap<String, Uid> uidMap = new HashMap<String, Uid>();
-
- /**
- * a map from participant ids to participant recover records
- */
- private List<XTSATRecoveryModule> recoveryModules = new ArrayList<XTSATRecoveryModule>();
-
- /**
- * the tx object store to be used for saving and deleting participant details
- */
- private ObjectStore objectStore;
-
- private final static String type = ATParticipantRecoveryRecord.type();
-}
Deleted: labs/jbosstm/trunk/XTS/sar/src/org/jboss/jbossts/xts/recovery/participant/at/XTSATSubordinateRecoveryModule.java
===================================================================
--- labs/jbosstm/trunk/XTS/sar/src/org/jboss/jbossts/xts/recovery/participant/at/XTSATSubordinateRecoveryModule.java 2009-07-06 14:14:03 UTC (rev 27632)
+++ labs/jbosstm/trunk/XTS/sar/src/org/jboss/jbossts/xts/recovery/participant/at/XTSATSubordinateRecoveryModule.java 2009-07-06 14:30:00 UTC (rev 27633)
@@ -1,36 +0,0 @@
-package org.jboss.jbossts.xts.recovery.participant.at;
-
-import com.arjuna.wst.Durable2PCParticipant;
-import com.arjuna.wst.PersistableParticipant;
-import com.arjuna.mwlabs.wscf.model.twophase.arjunacore.subordinate.SubordinateCoordinator;
-import com.arjuna.ats.arjuna.state.InputObjectState;
-
-import java.io.ObjectInputStream;
-
-/**
- * A recovery module which recovers durable participants registered by subordinate coordinators
- */
-
-public class XTSATSubordinateRecoveryModule implements XTSATRecoveryModule
-{
- public Durable2PCParticipant deserialize(String id, ObjectInputStream stream) throws Exception {
- if (id.startsWith(SubordinateCoordinator.PARTICIPANT_PREFIX)) {
- // throw an exception because we don't expect these participants to use serialization
- throw new Exception("XTSATSubordinateRecoveryModule : invalid request to deserialize() subordinate WS-AT coordinator durable participant " + id);
- }
- return null;
- }
-
- public Durable2PCParticipant recreate(String id, byte[] recoveryState) throws Exception {
- if (id.startsWith(SubordinateCoordinator.PARTICIPANT_PREFIX)) {
- InputObjectState ios = new InputObjectState();
- ios.setBuffer(recoveryState);
- String className = ios.unpackString();
- Class participantClass = this.getClass().getClassLoader().loadClass(className);
- Durable2PCParticipant participant = (Durable2PCParticipant)participantClass.newInstance();
- ((PersistableParticipant)participant).restoreState(ios);
- return participant;
- }
- return null;
- }
-}
Deleted: labs/jbosstm/trunk/XTS/sar/src/org/jboss/jbossts/xts/recovery/participant/ba/BAParticipantRecoveryModule.java
===================================================================
--- labs/jbosstm/trunk/XTS/sar/src/org/jboss/jbossts/xts/recovery/participant/ba/BAParticipantRecoveryModule.java 2009-07-06 14:14:03 UTC (rev 27632)
+++ labs/jbosstm/trunk/XTS/sar/src/org/jboss/jbossts/xts/recovery/participant/ba/BAParticipantRecoveryModule.java 2009-07-06 14:30:00 UTC (rev 27633)
@@ -1,327 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2007, 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) 2007,
- * @author Red Hat Middleware LLC.
- */
-package org.jboss.jbossts.xts.recovery.participant.ba;
-
-import org.jboss.jbossts.xts.logging.XTSLogger;
-
-import com.arjuna.ats.arjuna.recovery.RecoveryModule;
-import com.arjuna.ats.arjuna.logging.FacilityCode;
-import com.arjuna.ats.arjuna.coordinator.TxControl;
-import com.arjuna.ats.arjuna.state.InputObjectState;
-import com.arjuna.ats.arjuna.exceptions.ObjectStoreException;
-import com.arjuna.ats.arjuna.common.Uid;
-import com.arjuna.ats.arjuna.objectstore.ObjectStore;
-import com.arjuna.common.util.logging.DebugLevel;
-import com.arjuna.common.util.logging.VisibilityLevel;
-
-import java.util.Vector;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.io.IOException;
-
-/**
- * This class is a plug-in module for the recovery manager.
- * It is responsible for recovering XTS BA participants
- * (instances of org.jboss.jbossts.xts.recovery.participant.ba.BAParticipantRecoveryRecord)
- *
- * $Id$
- *
- * @message org.jboss.transactions.xts.recovery.participant.ba.BAParticipantRecoveryModule_1 [org.jboss.transactions.xts.recovery.participant.ba.BAParticipantRecoveryModule_1] - RecoveryManagerStatusModule: Object store exception: {0}
- * @message org.jboss.transactions.xts.recovery.participant.ba.BAParticipantRecoveryModule_3 [org.jboss.transactions.xts.recovery.participant.ba.BAParticipantRecoveryModule_3] - failed to access transaction store {0}
- * @message org.jboss.transactions.xts.recovery.participant.ba.BAParticipantRecoveryModule_4 [org.jboss.transactions.xts.recovery.participant.ba.BAParticipantRecoveryModule_4] - unable to load recovery record implementation class {0} for WS-BA participant recovery record {1}
- * @message org.jboss.transactions.xts.recovery.participant.ba.BAParticipantRecoveryModule_5 [org.jboss.transactions.xts.recovery.participant.ba.BAParticipantRecoveryModule_5] - unable to instantiate recovery record implementation class {0} for WS-BA participant recovery record {1}
- * @message org.jboss.transactions.xts.recovery.participant.ba.BAParticipantRecoveryModule_6 [org.jboss.transactions.xts.recovery.participant.ba.BAParticipantRecoveryModule_6] - unable to unpack recovery record data for WS-BA participant recovery record {0}
- * @message org.jboss.transactions.xts.recovery.participant.ba.BAParticipantRecoveryModule_7 [org.jboss.transactions.xts.recovery.participant.ba.BAParticipantRecoveryModule_7] - missing recovery record data for WS-BA participant recovery record {0}
- * @message org.jboss.transactions.xts.recovery.participant.ba.BAParticipantRecoveryModule_8 [org.jboss.transactions.xts.recovery.participant.ba.BAParticipantRecoveryModule_8] - unable to read recovery record data for WS-BA participant recovery record {0}
- */
-
-public class BAParticipantRecoveryModule implements RecoveryModule
-{
- public BAParticipantRecoveryModule()
- {
- if (XTSLogger.arjLogger.isDebugEnabled())
- {
- XTSLogger.arjLogger.debug
- ( DebugLevel.CONSTRUCTORS,
- VisibilityLevel.VIS_PUBLIC,
- FacilityCode.FAC_CRASH_RECOVERY,
- "BAParticipantRecoveryModule created - default" );
- }
-
- if (_objectStore == null)
- {
- _objectStore = TxControl.getStore() ;
- }
-
- _participantType = BAParticipantRecoveryRecord.type();
- }
-
- /**
- * called by the service startup code before the recovery module is added to the recovery managers
- * module list
- */
- public void install()
- {
- XTSBARecoveryManager.setRecoveryManager(new XTSBARecoveryManagerImple(_objectStore));
- }
-
- /**
- * called by the service shutdown code after the recovery module is removed from the recovery managers
- * module list
- */
- public void uninstall()
- {
- }
-
- /**
- * This is called periodically by the RecoveryManager
- */
- public void periodicWorkFirstPass()
- {
- // Transaction type
- boolean BAParticipants = false ;
-
- // uids per transaction type
- InputObjectState acc_uids = new InputObjectState() ;
-
- try
- {
- if (XTSLogger.arjLogger.isDebugEnabled())
- {
- XTSLogger.arjLogger.debug( "StatusModule: first pass " );
- }
-
- BAParticipants = _objectStore.allObjUids(_participantType, acc_uids );
-
- }
- catch ( ObjectStoreException ex )
- {
- if (XTSLogger.arjLoggerI18N.isWarnEnabled())
- {
- XTSLogger.arjLoggerI18N.warn("org.jboss.transactions.xts.recovery.participant.ba.BAParticipantRecoveryModule_1",
- ex);
- }
- }
-
- if ( BAParticipants )
- {
- _participantUidVector = processParticipants( acc_uids ) ;
- }
- }
-
- public void periodicWorkSecondPass()
- {
- if (XTSLogger.arjLogger.isDebugEnabled())
- {
- XTSLogger.arjLogger.debug( "BAParticipantRecoveryModule: Second pass " );
- }
-
- processParticipantsStatus() ;
- }
-
- private void doRecoverParticipant( Uid recoverUid )
- {
- // Retrieve the participant from its original process.
-
- if (XTSLogger.arjLogger.isDebugEnabled())
- {
- XTSLogger.arjLogger.debug
- ( DebugLevel.FUNCTIONS,
- VisibilityLevel.VIS_PUBLIC,
- FacilityCode.FAC_CRASH_RECOVERY,
- "participant type is "+ _participantType + " uid is " +
- recoverUid.toString()) ;
- }
-
- // we don't need to use a lock here because we only attempt the read
- // when the uid is inactive which means it cannto be pulled out form under our
- // feet at commit. uniqueness of uids also means we can't be foiled by a reused
- // uid.
-
- XTSBARecoveryManager recoveryManager = XTSBARecoveryManager.getRecoveryManager();
-
- if (!recoveryManager.isParticipantPresent(recoverUid)) {
- // ok, the participant can neither be active nor loaded awaiting recreation by
- // an application recovery module so we need to load it
- try {
- // retrieve the data for the participant
- InputObjectState inputState = _objectStore.read_committed(recoverUid, _participantType);
-
- if (inputState != null) {
- try {
- String participantRecordClazzName = inputState.unpackString();
- try {
- // create a participant engine instance and tell it to recover itself
- Class participantRecordClazz = Class.forName(participantRecordClazzName);
- BAParticipantRecoveryRecord participantRecord = (BAParticipantRecoveryRecord)participantRecordClazz.newInstance();
- participantRecord.restoreState(inputState);
- // ok, now insert into recovery map if needed
- XTSBARecoveryManager.getRecoveryManager().addParticipantRecoveryRecord(recoverUid, participantRecord);
- } catch (ClassNotFoundException cnfe) {
- // oh boy, not supposed to happen -- n.b. either the user deployed 1.0
- // last time and 1.1 this time or vice versa or something is rotten in
- // the state of Danmark
- if (XTSLogger.arjLoggerI18N.isErrorEnabled())
- {
- XTSLogger.arjLoggerI18N.error("org.jboss.transactions.xts.recovery.participant.ba.BAParticipantRecoveryModule_4",
- new Object[]{participantRecordClazzName, recoverUid.toString()}, cnfe);
- }
- } catch (InstantiationException ie) {
- // this is also worrying, log an error
- if (XTSLogger.arjLoggerI18N.isErrorEnabled())
- {
- XTSLogger.arjLoggerI18N.error("org.jboss.transactions.xts.recovery.participant.ba.BAParticipantRecoveryModule_5",
- new Object[]{participantRecordClazzName, recoverUid.toString()}, ie);
- }
- } catch (IllegalAccessException iae) {
- // this is another configuration problem, log an error
- if (XTSLogger.arjLoggerI18N.isErrorEnabled())
- {
- XTSLogger.arjLoggerI18N.error("org.jboss.transactions.xts.recovery.participant.ba.BAParticipantRecoveryModule_5",
- new Object[]{participantRecordClazzName, recoverUid.toString()}, iae);
- }
- }
- } catch (IOException ioe) {
- // hmm, record corrupted? log this as a warning
- if (XTSLogger.arjLoggerI18N.isWarnEnabled())
- {
- XTSLogger.arjLoggerI18N.warn("org.jboss.transactions.xts.recovery.participant.ba.BAParticipantRecoveryModule_6",
- new Object[]{recoverUid.toString()}, ioe);
- }
- }
- } else {
- // hmm, it ought not to be able to disappear unless the recovery manager knows about it
- // this is an error!
- if (XTSLogger.arjLoggerI18N.isErrorEnabled())
- {
- XTSLogger.arjLoggerI18N.error("org.jboss.transactions.xts.recovery.participant.ba.BAParticipantRecoveryModule_7",
- new Object[]{recoverUid.toString()});
- }
- }
- } catch (ObjectStoreException ose) {
- // if the object store is not working this is serious
- if (XTSLogger.arjLoggerI18N.isErrorEnabled())
- {
- XTSLogger.arjLoggerI18N.error("org.jboss.transactions.xts.recovery.participant.ba.BAParticipantRecoveryModule_8",
- new Object[]{recoverUid.toString()}, ose);
- }
- }
- }
- }
-
- private Vector processParticipants( InputObjectState uids )
- {
- Vector uidVector = new Vector() ;
-
- if (XTSLogger.arjLogger.isDebugEnabled())
- {
- XTSLogger.arjLogger.debug( DebugLevel.FUNCTIONS,
- VisibilityLevel.VIS_PUBLIC,
- FacilityCode.FAC_CRASH_RECOVERY,
- "processing " + _participantType
- + " WS-BA participants" ) ;
- }
-
- Uid theUid = new Uid( Uid.nullUid() );
-
- boolean moreUids = true ;
-
- while (moreUids)
- {
- try
- {
- theUid.unpack( uids ) ;
-
- if (theUid.equals( Uid.nullUid() ))
- {
- moreUids = false;
- }
- else
- {
- Uid newUid = new Uid( theUid ) ;
-
- if (XTSLogger.arjLogger.isDebugEnabled())
- {
- XTSLogger.arjLogger.debug
- ( DebugLevel.FUNCTIONS,
- VisibilityLevel.VIS_PUBLIC,
- FacilityCode.FAC_CRASH_RECOVERY,
- "found WS-BA participant "+ newUid ) ;
- }
-
- uidVector.addElement( newUid ) ;
- }
- }
- catch ( Exception ex )
- {
- moreUids = false;
- }
- }
- return uidVector ;
- }
-
- private void processParticipantsStatus()
- {
- if (_participantUidVector != null) {
- // Process the Vector of transaction Uids
- Enumeration participantUidEnum = _participantUidVector.elements() ;
-
- while ( participantUidEnum.hasMoreElements() )
- {
- Uid currentUid = (Uid) participantUidEnum.nextElement();
-
- try
- {
- if ( _objectStore.currentState( currentUid, _participantType) != ObjectStore.OS_UNKNOWN )
- {
- doRecoverParticipant( currentUid ) ;
- }
- }
- catch ( ObjectStoreException ex )
- {
- if (XTSLogger.arjLogger.isWarnEnabled())
- {
- XTSLogger.arjLoggerI18N.warn("org.jboss.transactions.xts.recovery.participant.ba.BAParticipantRecoveryModule_3",
- new Object[]{currentUid.toString()}, ex);
- }
- }
- }
- }
-
- // now get the BA recovery manager to try to activate recovered participants
-
- XTSBARecoveryManager.getRecoveryManager().recoverParticipants();
- }
-
- // 'type' within the Object Store for BAParticipant record.
- private String _participantType = BAParticipantRecoveryRecord.type() ;
-
- // Array of transactions found in the object store of the
- // ACCoordinator type.
- private Vector _participantUidVector = null ;
-
- // Reference to the Object Store.
- private static ObjectStore _objectStore = null ;
-
- // This object provides information about whether or not a participant is currently active.
-
- private HashMap<String, BAParticipantRecoveryRecord> _recoveredParticipantMap ;
-}
\ No newline at end of file
Deleted: labs/jbosstm/trunk/XTS/sar/src/org/jboss/jbossts/xts/recovery/participant/ba/XTSBARecoveryManagerImple.java
===================================================================
--- labs/jbosstm/trunk/XTS/sar/src/org/jboss/jbossts/xts/recovery/participant/ba/XTSBARecoveryManagerImple.java 2009-07-06 14:14:03 UTC (rev 27632)
+++ labs/jbosstm/trunk/XTS/sar/src/org/jboss/jbossts/xts/recovery/participant/ba/XTSBARecoveryManagerImple.java 2009-07-06 14:30:00 UTC (rev 27633)
@@ -1,342 +0,0 @@
-package org.jboss.jbossts.xts.recovery.participant.ba;
-
-import org.jboss.jbossts.xts.logging.XTSLogger;
-
-import com.arjuna.ats.arjuna.objectstore.ObjectStore;
-import com.arjuna.ats.arjuna.state.OutputObjectState;
-import com.arjuna.ats.arjuna.common.Uid;
-import com.arjuna.ats.arjuna.exceptions.ObjectStoreException;
-
-import java.util.*;
-import java.io.IOException;
-
-/**
- * A class which manages the table of recovered participant records.
- *
- * @message org.jboss.transactions.xts.recovery.participant.ba.XTSBARecoveryModule_1 [org.jboss.transactions.xts.recovery.participant.ba.XTSBARecoveryModule_1] exception writing recovery record for WS-BA participant {0}
- * @message org.jboss.transactions.xts.recovery.participant.ba.XTSBARecoveryModule_2 [org.jboss.transactions.xts.recovery.participant.ba.XTSBARecoveryModule_2] exception removing recovery record {0} for WS-BA participant {1}
- * @message org.jboss.transactions.xts.recovery.participant.ba.XTSBARecoveryModule_3 [org.jboss.transactions.xts.recovery.participant.ba.XTSBARecoveryModule_3] exception reactivating recovered WS-BA participant {0}
- * @message org.jboss.transactions.xts.recovery.participant.ba.XTSBARecoveryModule_4 [org.jboss.transactions.xts.recovery.participant.ba.XTSBARecoveryModule_4] no XTS application recovery module found to help reactivate recovered WS-BA participant {0}
- */
-public class XTSBARecoveryManagerImple extends XTSBARecoveryManager {
- /**
- * constructor for use by BAParticipantRecoveryModule
- * @param objectStore
- */
- XTSBARecoveryManagerImple(ObjectStore objectStore)
- {
- this.objectStore = objectStore;
- }
-
- /**
- * register an application specific recovery module which acts as a helper to recreate
- * a WS-BA durable participant from the participant's recovery data saved at prepare
- *
- * @param module the module which will be used to identify and recreate participants
- * for the application
- * @throws NullPointerException if the supplied module is null
- */
- public void registerRecoveryModule(XTSBARecoveryModule module) throws NullPointerException
- {
- // TODO other sanity checks?
- if (module == null) {
- throw new NullPointerException("XTSBARecoveryModule value must be non-null");
- }
-
- recoveryModules.add(module);
- }
-
- /**
- * unregister an application specific recovery module previously registered as
- * a helper to recretae WS-BA durable participants
- *
- * @param module the module to be unregistered
- * @throws java.util.NoSuchElementException
- * if the module is not currently registered
- */
- public void unregisterRecoveryModule(XTSBARecoveryModule module) throws NoSuchElementException {
- if (!recoveryModules.remove(module)) {
- throw new NoSuchElementException();
- }
- }
-
- /**
- * save the supplied participant recovery record to persistent storage
- *
- * @param participantRecoveryRecord
- */
- public boolean writeParticipantRecoveryRecord(BAParticipantRecoveryRecord participantRecoveryRecord)
- {
- OutputObjectState oos = new OutputObjectState();
- // we need to be able to retrieve the class of the participant record so we can
- // create an instancde to load the rest of the participant specific data
- try {
- oos.packString(participantRecoveryRecord.getClass().getCanonicalName());
- } catch (IOException ioe) {
- if (XTSLogger.arjLoggerI18N.isWarnEnabled())
- {
- XTSLogger.arjLoggerI18N.warn("org.jboss.transactions.xts.recovery.participant.ba.XTSBARecoveryModule_1",
- new Object[] {participantRecoveryRecord.getId()}, ioe);
- }
- return false;
- }
-
- if (participantRecoveryRecord.saveState(oos)) {
- Uid uid = new Uid();
- try {
- objectStore.write_committed(uid, type, oos);
- // we need to be able to identify the uid from the participant id
- // in order to delete it later
- uidMap.put(participantRecoveryRecord.getId(), uid);
- return true;
- } catch (ObjectStoreException ose) {
- if (XTSLogger.arjLoggerI18N.isWarnEnabled())
- {
- XTSLogger.arjLoggerI18N.warn("org.jboss.transactions.xts.recovery.participant.ba.XTSBARecoveryModule_1",
- new Object[] {participantRecoveryRecord.getId()}, ose);
- }
- }
- }
-
- return false;
- }
-
- /**
- * remove any participant recovery record with the supplied id from persistent storage
- * @param id the id of the participant whose recovery details are being deleted
- */
- public boolean deleteParticipantRecoveryRecord(String id)
- {
- Uid uid = uidMap.get(id);
-
- if (uid != null) {
-
- try {
- objectStore.remove_committed(uid, type);
- uidMap.remove(id);
- return true;
- } catch (ObjectStoreException ose) {
- if (XTSLogger.arjLoggerI18N.isWarnEnabled())
- {
- XTSLogger.arjLoggerI18N.warn("org.jboss.transactions.xts.recovery.participant.ba.XTSBARecoveryModule_2",
- new Object[] {uid, id},
- ose);
- }
- }
- }
-
- return false;
- }
-
- /**
- * test whether the supplied uid identifies an active participant or a recovered but inactive
- * participant
- *
- * n.b. this method is not synchronized because of two assumptions: first, that uids are
- * never reused; and second that only recovery scanning (as a minimum, for a given recovery
- * record type) is single-threaded. Correctness of the first assumption ensures there are no
- * races with participant processor threads, the second races between recovery threads.
- *
- * @param uid
- */
- public boolean isParticipantPresent(Uid uid)
- {
- return (uidMap.get(uid) != null);
- }
-
- /**
- * add a recovered participant record to the table of unrecovered participants which
- * need to be recreated following recovery
- *
- * @param uid the uid under which the participant was saved in the file store
- * @param participantRecoveryRecord the in-memory representation of the recovery record
- * saved to disk
- */
- public void addParticipantRecoveryRecord(Uid uid, BAParticipantRecoveryRecord participantRecoveryRecord)
- {
- String participantId = participantRecoveryRecord.getId();
- if (recoveryMap.get(participantId) == null && !participantRecoveryRecord.isActive()) {
- // ok, we have not seen this entry before so add it to the list
- recoveryMap.put(participantId, participantRecoveryRecord);
- uidMap.put(participantId, uid);
- }
- }
-
- /**
- * see if a participant recovery record with a given id exists in the table of participants which
- * need to be recreated following recovery
- * @param id the identifier of the participant being sought
- * @return the participant recovery record with the supplied id or null if it is not found
- */
- public synchronized BAParticipantRecoveryRecord findParticipantRecoveryRecord(String id)
- {
- return recoveryMap.get(id);
- }
-
- /**
- * process all entries in the recovered participant map and attempt to recreate the
- * application participant and activate it
- */
- public void recoverParticipants()
- {
- // the first scan has been performed so allow processing of commit and rollback requests
- // for unknown ids to proceed now
-
- setParticipantRecoveryStarted();
-
- // we operate on a copy of the recovery modules to avoid the list being modified
- // by register and unregister operations while we are iterating over it
- // we should probably also make sure unregister does not proceed until
- // the current scan is complete . . .
-
- List<XTSBARecoveryModule> recoveryModulesCopy;
- synchronized (recoveryModules) {
- recoveryModulesCopy = new ArrayList<XTSBARecoveryModule>(recoveryModules);
- }
-
- // iterate through the participant recovery records and try to convert them to
- // a durable participant. if successful activate the participant and then remove the
- // recovery entry. note that since recovery is single threaded we can be sure that
- // no concurrent modifications will be made to the table while we are iterating and,
- // possibly, deleting via the iterator
-
- Iterator<BAParticipantRecoveryRecord> participantIterator = iterator();
-
- while(participantIterator.hasNext()) {
- BAParticipantRecoveryRecord participantRecoveryRecord = participantIterator.next();
- if (participantRecoveryRecord.isActive()) {
- // this participant must have already been activated by a by a previous
- // scan and been reloaded by this scan so just remove the entry
-
- participantIterator.remove();
- } else {
- Iterator<XTSBARecoveryModule> moduleIterator = recoveryModulesCopy.iterator();
- boolean found = false;
-
- while (!found && moduleIterator.hasNext()) {
- XTSBARecoveryModule module = moduleIterator.next();
- try {
- if (participantRecoveryRecord.restoreParticipant(module)) {
- // ok, this participant has recovered so tell it to
- // activate and *then* remove it from the hashmap. this makes
- // sure we don't open a window where an incoming
- // commit may fail to find the object in either table
-
- found = true;
- participantRecoveryRecord.activate();
-
- participantIterator.remove();
- }
- } catch (Exception e) {
- // we foudn a helper but it failed to convert the participant record -- log a warning
- // but leave the participant in the table for next time in case the helper has merely
- // suffered a transient failure
- found = true;
- if (XTSLogger.arjLoggerI18N.isWarnEnabled())
- {
- XTSLogger.arjLoggerI18N.warn("org.jboss.transactions.xts.recovery.participant.ba.XTSBARecoveryModule_3",
- new Object[] {participantRecoveryRecord.getId()},
- e);
- }
- }
- }
-
- if (!found) {
- // we failed to find a helper to convert a participant record so log a warning
- // but leave it in the table for next time
- if (XTSLogger.arjLoggerI18N.isWarnEnabled())
- {
- XTSLogger.arjLoggerI18N.warn("org.jboss.transactions.xts.recovery.participant.ba.XTSBARecoveryModule_4",
- new Object[] {participantRecoveryRecord.getId()});
- }
- }
- }
- }
- }
-
- /**
- * 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
- * @return
- */
- private synchronized Iterator<BAParticipantRecoveryRecord> iterator()
- {
- return recoveryMap.values().iterator();
- }
-
- /**
- * set a global flag indicating that the first BA participant recovery scan has
- * been performed.
- */
- private synchronized void setParticipantRecoveryStarted()
- {
- participantRecoveryStarted = true;
- }
-
- /**
- * test whether the first BA participant recovery scan has completed. this indicates whether
- * there may or may not still be unknown participant recovery records on disk. If the first
- * scan has not yet completed then a commit or rollback message for an unknown participant
- * must be dropped. If it has then a commit or rollback for an unknown participant must be
- * acknowledged with, respectively, a committed or aborted message.
- */
- public synchronized boolean isParticipantRecoveryStarted()
- {
- return participantRecoveryStarted;
- }
-
- /**
- * test whether the first BA coordinator recovery scan has completed. this indicates whether
- * there may or may not still be unknown BA transcation records on disk. If the first
- * scan has not yet completed then a prepare message for an unknown participant
- * must be dropped. If it has then a perpare for an unknown participant must be
- * acknowledged with a rollback message.
- */
- public synchronized boolean isCoordinatorRecoveryStarted() {
- return coordinatorRecoveryStarted;
- }
-
- /**
- * record the fact that the first BA coordinator recovery scan has completed.
- */
-
- public synchronized void setCoordinatorRecoveryStarted() {
- coordinatorRecoveryStarted = true;
- }
-
- /**
- * a global flag indicating whether the first BA participant recovery scan has
- * been performed.
- */
- private boolean participantRecoveryStarted = false;
-
- /**
- * a global flag indicating whether the first AT coordinator recovery scan has
- * been performed.
- */
- private boolean coordinatorRecoveryStarted = false;
-
- /**
- * a map from participant ids to participant recovery records
- */
- private HashMap<String, BAParticipantRecoveryRecord> recoveryMap = new HashMap<String, BAParticipantRecoveryRecord>();
-
- /**
- * a map from participant id to the uid under which the participant has been saved in the
- * persistent store
- */
- private HashMap<String, Uid> uidMap = new HashMap<String, Uid>();
-
- /**
- * a map from participant ids to participant recover records
- */
- private List<XTSBARecoveryModule> recoveryModules = new ArrayList<XTSBARecoveryModule>();
-
- /**
- * the tx object store to be used for saving and deleting participant details
- */
- private ObjectStore objectStore;
-
- private final static String type = BAParticipantRecoveryRecord.type();
-}
\ No newline at end of file
More information about the jboss-svn-commits
mailing list