[jboss-svn-commits] JBL Code SVN: r26847 - in labs/jbosstm/trunk/txbridge: demo and 2 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Fri Jun 5 06:07:15 EDT 2009


Author: jhalliday
Date: 2009-06-05 06:07:15 -0400 (Fri, 05 Jun 2009)
New Revision: 26847

Added:
   labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/BridgeDurableParticipant.java
   labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/BridgeSynchronization.java
   labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/BridgeVolatileParticipant.java
Removed:
   labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/BridgeParticipantAT.java
Modified:
   labs/jbosstm/trunk/txbridge/build.xml
   labs/jbosstm/trunk/txbridge/demo/build.xml
   labs/jbosstm/trunk/txbridge/docs/TransactionBridgingGuide.odt
   labs/jbosstm/trunk/txbridge/docs/TransactionBridgingGuide.pdf
   labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/BridgeRecoveryManager.java
   labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/InboundBridge.java
   labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/InboundBridgeManager.java
   labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/OutboundBridgeManager.java
Log:
Added Synchronization/VolatileParticipant support to the txbridge. JBTM-44


Modified: labs/jbosstm/trunk/txbridge/build.xml
===================================================================
--- labs/jbosstm/trunk/txbridge/build.xml	2009-06-05 08:59:08 UTC (rev 26846)
+++ labs/jbosstm/trunk/txbridge/build.xml	2009-06-05 10:07:15 UTC (rev 26847)
@@ -26,18 +26,17 @@
 		JBossTS Transaction Bridge
 	</description>
 
-    <property name="jbossas.home" location="/home/jhalli/IdeaProjects/jboss/jbossas_branch5x/build/output/jboss-5.1.0.CR1"/>
+    <property name="jbossas.home" location="/home/jhalli/IdeaProjects/jboss/jbossas_510ga/build/output/jboss-5.1.0.GA"/>
     <property name="jbossas.server" value="default"/>
 
     <property name="jbossts.home" location=".."/>
 
 	<property name="src" location="src"/>
-	<property name="lib" location="lib"/>
-	<property name="resources" location="resources"/>
 	<property name="build" location="build"/>
 
 	<path id="build-prereqs">
         <fileset dir="${jbossts.home}/install/lib">
+            <include name="jbossjta.jar"/>
             <include name="jbossjts.jar"/>
             <include name="ext/jbossts-common.jar"/>
             <include name="ext/log4j-1.2.14.jar"/>
@@ -95,7 +94,6 @@
     <target name="install-jts">
         <copy todir="${jbossas.home}/common/lib">
             <fileset dir="${jbossts.home}/install/lib" includes="*.jar"/>
-            <fileset dir="${jbossts.home}/install/lib/ext/" includes="jbossts-common.jar"/>
         </copy>
     </target>
 

Modified: labs/jbosstm/trunk/txbridge/demo/build.xml
===================================================================
--- labs/jbosstm/trunk/txbridge/demo/build.xml	2009-06-05 08:59:08 UTC (rev 26846)
+++ labs/jbosstm/trunk/txbridge/demo/build.xml	2009-06-05 10:07:15 UTC (rev 26847)
@@ -26,7 +26,7 @@
 		JBossTS Transaction Bridge Demo App
 	</description>
 
-    <property name="jbossas.home" location="/home/jhalli/IdeaProjects/jboss/jbossas_branch5x/build/output/jboss-5.1.0.CR1"/>
+    <property name="jbossas.home" location="/home/jhalli/IdeaProjects/jboss/jbossas_510ga/build/output/jboss-5.1.0.GA"/>
     <property name="jbossas.server" value="default"/>
 
 	<property name="src" location="src"/>

Modified: labs/jbosstm/trunk/txbridge/docs/TransactionBridgingGuide.odt
===================================================================
(Binary files differ)

Modified: labs/jbosstm/trunk/txbridge/docs/TransactionBridgingGuide.pdf
===================================================================
(Binary files differ)

Copied: labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/BridgeDurableParticipant.java (from rev 26793, labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/BridgeParticipantAT.java)
===================================================================
--- labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/BridgeDurableParticipant.java	                        (rev 0)
+++ labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/BridgeDurableParticipant.java	2009-06-05 10:07:15 UTC (rev 26847)
@@ -0,0 +1,251 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ * (C) 2007, 2009 @author JBoss Inc
+ */
+package org.jboss.jbossts.txbridge;
+
+import com.arjuna.wst.*;
+import com.arjuna.ats.arjuna.common.Uid;
+import com.arjuna.ats.internal.jta.transaction.arjunacore.jca.SubordinationManager;
+import org.apache.log4j.Logger;
+
+import javax.transaction.xa.Xid;
+import javax.transaction.xa.XAException;
+import javax.transaction.xa.XAResource;
+
+import javax.resource.spi.XATerminator;
+
+import java.io.Serializable;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+/**
+ * Provides method call mapping between WS-AT Durable Participant interface
+ * and an underlying JTA subtransaction coordinator.
+ *
+ * @author jonathan.halliday at redhat.com, 2007-04-30
+ */
+public class BridgeDurableParticipant implements Durable2PCParticipant, Serializable
+{
+	private static Logger log = Logger.getLogger(BridgeDurableParticipant.class);
+
+    /*
+     * Uniq String used to prefix ids at participant registration,
+     * so that the recovery module can identify relevant instances.
+     */
+    public static String TYPE_IDENTIFIER = "BridgeParticipantAT_";
+
+	private transient XATerminator xaTerminator;
+
+    private transient String externalTxId;
+
+    static final long serialVersionUID = -5739871936627778072L;
+
+    // Xid not guarateed Serializable by spec, but our XidImple happens to be
+	private Xid xid;
+
+    // Id needed for recovery of the subordinate tx. Uids are likewise Serializable.
+    private Uid subordinateTransactionId;
+
+    /**
+     * Create a new WS-AT Durable Participant which wraps the subordinate XA tx terminator.
+     *
+     * @param externalTxId the WS-AT Tx identifier
+     * @param xid the Xid to use when driving the subordinate XA transaction.
+     */
+	BridgeDurableParticipant(String externalTxId, Xid xid)
+    {
+		log.trace("BridgeDurableParticipant(TxId="+externalTxId+", Xid="+xid+")");
+
+        this.xid = xid;
+        this.externalTxId = externalTxId;
+		xaTerminator = SubordinationManager.getXATerminator();
+	}
+
+    /**
+     * Serialization hook. Gathers and writes information needed for transaction recovery.
+     *
+     * @param out the strean to which the object state is serialized.
+     * @throws IOException if serialization fails.
+     */
+    private void writeObject(ObjectOutputStream out) throws IOException
+    {
+        log.trace("writeObject() for Xid="+xid);
+
+        // we need to preserve the Uid of the underlying SubordinateTx, as it's required
+        // to get a handle on it again during recovery, Using the xid wont work,
+        // although we do need to serialize that too for use after recovery.
+        try
+        {
+            subordinateTransactionId = SubordinationManager.getTransactionImporter().getImportedTransaction(xid).get_uid();
+        }
+        catch(XAException xaException)
+        {
+            log.error("Unable to get subordinate transaction id", xaException);
+            IOException ioException = new IOException("Unable to serialize");
+            ioException.initCause(xaException);
+            throw ioException;
+        }
+
+        out.defaultWriteObject();
+    }
+
+    /**
+     * Deserialization hook. Unpacks transaction recovery information and uses it to
+     * recover the subordinate transaction.
+     *
+     * @param in the strean from which to unpack the object state.
+     * @throws IOException if deserialzation and recovery fail.
+     * @throws ClassNotFoundException if deserialzation fails.
+     */
+    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
+    {
+        log.trace("readObject()");
+
+        in.defaultReadObject();
+        xaTerminator = SubordinationManager.getXATerminator();
+
+        try
+        {
+            SubordinationManager.getTransactionImporter().recoverTransaction(subordinateTransactionId);
+        }
+        catch(XAException xaException)
+        {
+            log.error("Unable to recover subordinate transaction id="+subordinateTransactionId, xaException);
+            IOException ioException = new IOException("unable to deserialize");
+            ioException.initCause(xaException);
+            throw ioException;
+        }
+    }
+
+    /**
+     * Perform any work necessary to allow it to either commit or rollback
+     * the work performed by the Web service under the scope of the
+     * transaction. The implementation is free to do whatever it needs to in
+     * order to fulfill the implicit contract between it and the coordinator.
+     *
+     * @return an indication of whether it can prepare or not.
+     * @see com.arjuna.wst.Vote
+     */
+	public Vote prepare() throws WrongStateException, SystemException
+	{
+		log.trace("prepare(Xid="+xid+")");
+
+		try
+        {
+			// XAResource.XA_OK, XAResource.XA_RDONLY or exception.  if RDONLY, don't call commit
+			int result = xaTerminator.prepare(xid);
+			if(result == XAResource.XA_OK)
+            {
+				log.debug("prepare on Xid="+xid+" returning Prepared");
+				return new Prepared();
+			}
+            else
+            {
+                InboundBridgeManager.removeMapping(externalTxId);
+				log.debug("prepare on Xid="+xid+" returning ReadOnly");
+				return new ReadOnly();
+			}
+
+		}
+        catch(XAException e)
+        {
+            InboundBridgeManager.removeMapping(externalTxId);
+			log.warn("prepare on Xid="+xid+" returning Aborted", e);
+			return new Aborted();
+		}
+    }
+
+    /**
+     * The participant should make permanent the work that it controls.
+	 *
+     * @throws WrongStateException
+     * @throws SystemException
+     */
+    public void commit() throws WrongStateException, SystemException
+    {
+		log.trace("commit(Xid="+xid+")");
+
+		try
+		{
+			xaTerminator.commit(xid, false);
+			log.debug("commit on Xid="+xid+" OK");
+		}
+		catch (XAException e)
+		{
+			log.error("commit on Xid="+xid+" failed", e);
+		}
+        finally
+        {
+            InboundBridgeManager.removeMapping(externalTxId);
+        }
+    }
+
+    /**
+     * The participant should undo the work that it controls. The participant
+     * will then return an indication of whether or not it succeeded..
+     *
+     * @throws WrongStateException
+     * @throws SystemException
+     */
+    public void rollback() throws WrongStateException, SystemException
+    {
+		log.trace("rollback(Xid="+xid+")");
+
+		try
+		{
+			xaTerminator.rollback(xid);
+			log.debug("rollback on Xid="+xid+" OK");
+		}
+		catch (XAException e)
+		{
+			log.error("rollback on Xid="+xid+" failed", e);
+		}
+        finally
+        {
+            InboundBridgeManager.removeMapping(externalTxId);
+        }
+    }
+
+    /**
+     * During recovery the participant can enquire as to the status of the
+     * transaction it was registered with. If that transaction is no longer
+     * available (has rolled back) then this operation will be invoked by the
+     * coordination service.
+     */
+	public void unknown() throws SystemException
+    {
+		log.trace("unknown(Xid="+xid+"): NOT IMPLEMENTED");
+    }
+
+    /**
+     * During recovery the participant can enquire as to the status of the
+     * transaction it was registered with. If an error occurs (e.g., the
+     * transaction service is unavailable) then this operation will be invoked.
+     */
+	public void error() throws SystemException
+    {
+		log.trace("error(Xid="+xid+"): NOT IMPLEMENTED");
+    }
+}
+

Deleted: labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/BridgeParticipantAT.java
===================================================================
--- labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/BridgeParticipantAT.java	2009-06-05 08:59:08 UTC (rev 26846)
+++ labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/BridgeParticipantAT.java	2009-06-05 10:07:15 UTC (rev 26847)
@@ -1,251 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2009, Red Hat Middleware LLC, and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- * (C) 2007, 2009 @author JBoss Inc
- */
-package org.jboss.jbossts.txbridge;
-
-import com.arjuna.wst.*;
-import com.arjuna.ats.arjuna.common.Uid;
-import com.arjuna.ats.internal.jta.transaction.arjunacore.jca.SubordinationManager;
-import org.apache.log4j.Logger;
-
-import javax.transaction.xa.Xid;
-import javax.transaction.xa.XAException;
-import javax.transaction.xa.XAResource;
-
-import javax.resource.spi.XATerminator;
-
-import java.io.Serializable;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-
-/**
- * Provides method call mapping between WS-AT Participant interface
- * and an underlying JTA subtransaction coordinator.
- *
- * @author jonathan.halliday at redhat.com, 2007-04-30
- */
-public class BridgeParticipantAT implements Durable2PCParticipant, Serializable
-{
-	private static Logger log = Logger.getLogger(BridgeParticipantAT.class);
-
-    /*
-     * Uniq String used to prefix ids at participant registration,
-     * so that the recovery module can identify relevant instances.
-     */
-    public static String TYPE_IDENTIFIER = "BridgeParticipantAT_";
-
-	private transient XATerminator xaTerminator;
-
-    private transient String externalTxId;
-
-    static final long serialVersionUID = -5739871936627778072L;
-
-    // Xid not guarateed Serializable by spec, but our XidImple happens to be
-	private Xid xid;
-
-    // Id needed for recovery of the subordinate tx. Uids are likewise Serializable.
-    private Uid subordinateTransactionId;
-
-    /**
-     * Create a new WS-AT Participant which wraps the subordinate XA tx terminator.
-     *
-     * @param externalTxId the WS-AT Tx identifier
-     * @param xid the Xid to use when driving the subordinate XA transaction.
-     */
-	BridgeParticipantAT(String externalTxId, Xid xid)
-    {
-		log.trace("BridgeParticipantAT(TxId="+externalTxId+", Xid="+xid+")");
-
-        this.xid = xid;
-        this.externalTxId = externalTxId;
-		xaTerminator = SubordinationManager.getXATerminator();
-	}
-
-    /**
-     * Serialization hook. Gathers and writes information needed for transaction recovery.
-     *
-     * @param out the strean to which the object state is serialized.
-     * @throws IOException if serialization fails.
-     */
-    private void writeObject(ObjectOutputStream out) throws IOException
-    {
-        log.trace("writeObject() for Xid="+xid);
-
-        // we need to preserve the Uid of the underlying SubordinateTx, as it's required
-        // to get a handle on it again during recovery, Using the xid wont work,
-        // although we do need to serialize that too for use after recovery.
-        try
-        {
-            subordinateTransactionId = SubordinationManager.getTransactionImporter().getImportedTransaction(xid).get_uid();
-        }
-        catch(XAException xaException)
-        {
-            log.error("Unable to get subordinate transaction id", xaException);
-            IOException ioException = new IOException("Unable to serialize");
-            ioException.initCause(xaException);
-            throw ioException;
-        }
-
-        out.defaultWriteObject();
-    }
-
-    /**
-     * Deserialization hook. Unpacks transaction recovery information and uses it to
-     * recover the subordinate transaction.
-     *
-     * @param in the strean from which to unpack the object state.
-     * @throws IOException if deserialzation and recovery fail.
-     * @throws ClassNotFoundException if deserialzation fails.
-     */
-    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
-    {
-        log.trace("readObject()");
-
-        in.defaultReadObject();
-        xaTerminator = SubordinationManager.getXATerminator();
-
-        try
-        {
-            SubordinationManager.getTransactionImporter().recoverTransaction(subordinateTransactionId);
-        }
-        catch(XAException xaException)
-        {
-            log.error("Unable to recover subordinate transaction id="+subordinateTransactionId, xaException);
-            IOException ioException = new IOException("unable to deserialize");
-            ioException.initCause(xaException);
-            throw ioException;
-        }
-    }
-
-    /**
-     * Perform any work necessary to allow it to either commit or rollback
-     * the work performed by the Web service under the scope of the
-     * transaction. The implementation is free to do whatever it needs to in
-     * order to fulfill the implicit contract between it and the coordinator.
-     *
-     * @return an indication of whether it can prepare or not.
-     * @see com.arjuna.wst.Vote
-     */
-	public Vote prepare() throws WrongStateException, SystemException
-	{
-		log.trace("prepare(Xid="+xid+")");
-
-		try
-        {
-			// XAResource.XA_OK, XAResource.XA_RDONLY or exception.  if RDONLY, don't call commit
-			int result = xaTerminator.prepare(xid);
-			if(result == XAResource.XA_OK)
-            {
-				log.debug("prepare on Xid="+xid+" returning Prepared");
-				return new Prepared();
-			}
-            else
-            {
-                InboundBridgeManager.removeMapping(externalTxId);
-				log.debug("prepare on Xid="+xid+" returning ReadOnly");
-				return new ReadOnly();
-			}
-
-		}
-        catch(XAException e)
-        {
-            InboundBridgeManager.removeMapping(externalTxId);
-			log.warn("prepare on Xid="+xid+" returning Aborted", e);
-			return new Aborted();
-		}
-    }
-
-    /**
-     * The participant should make permanent the work that it controls.
-	 *
-     * @throws WrongStateException
-     * @throws SystemException
-     */
-    public void commit() throws WrongStateException, SystemException
-    {
-		log.trace("commit(Xid="+xid+")");
-
-		try
-		{
-			xaTerminator.commit(xid, false);
-			log.debug("commit on Xid="+xid+" OK");
-		}
-		catch (XAException e)
-		{
-			log.error("commit on Xid="+xid+" failed", e);
-		}
-        finally
-        {
-            InboundBridgeManager.removeMapping(externalTxId);
-        }
-    }
-
-    /**
-     * The participant should undo the work that it controls. The participant
-     * will then return an indication of whether or not it succeeded..
-     *
-     * @throws WrongStateException
-     * @throws SystemException
-     */
-    public void rollback() throws WrongStateException, SystemException
-    {
-		log.trace("rollback(Xid="+xid+")");
-
-		try
-		{
-			xaTerminator.rollback(xid);
-			log.debug("rollback on Xid="+xid+" OK");
-		}
-		catch (XAException e)
-		{
-			log.error("rollback on Xid="+xid+" failed", e);
-		}
-        finally
-        {
-            InboundBridgeManager.removeMapping(externalTxId);
-        }
-    }
-
-    /**
-     * During recovery the participant can enquire as to the status of the
-     * transaction it was registered with. If that transaction is no longer
-     * available (has rolled back) then this operation will be invoked by the
-     * coordination service.
-     */
-	public void unknown() throws SystemException
-    {
-		log.trace("unknown(Xid="+xid+"): NOT IMPLEMENTED");
-    }
-
-    /**
-     * During recovery the participant can enquire as to the status of the
-     * transaction it was registered with. If an error occurs (e.g., the
-     * transaction service is unavailable) then this operation will be invoked.
-     */
-	public void error() throws SystemException
-    {
-		log.trace("error(Xid="+xid+"): NOT IMPLEMENTED");
-    }
-}
-

Modified: labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/BridgeRecoveryManager.java
===================================================================
--- labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/BridgeRecoveryManager.java	2009-06-05 08:59:08 UTC (rev 26846)
+++ labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/BridgeRecoveryManager.java	2009-06-05 10:07:15 UTC (rev 26847)
@@ -75,10 +75,10 @@
     {
         log.trace("deserialize(id="+id+")");
 
-        if(id.startsWith(BridgeParticipantAT.TYPE_IDENTIFIER))
+        if(id.startsWith(BridgeDurableParticipant.TYPE_IDENTIFIER))
         {
             Object participant = objectInputStream.readObject();
-            return (BridgeParticipantAT)participant;
+            return (BridgeDurableParticipant)participant;
         }
         else
         {

Added: labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/BridgeSynchronization.java
===================================================================
--- labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/BridgeSynchronization.java	                        (rev 0)
+++ labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/BridgeSynchronization.java	2009-06-05 10:07:15 UTC (rev 26847)
@@ -0,0 +1,90 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ * (C) 2009 @author JBoss Inc
+ */
+package org.jboss.jbossts.txbridge;
+
+import org.apache.log4j.Logger;
+import org.jboss.jbossts.xts.bridge.at.BridgeWrapper;
+
+import javax.transaction.Synchronization;
+import javax.transaction.Status;
+
+import com.arjuna.ats.jta.utils.JTAHelper;
+
+/**
+ * Provides method call mapping between JTA parent coordinator and WS-AT subordinate transaction.
+ *
+ * @author jonathan.halliday at redhat.com, 2009-06-01
+ */
+public class BridgeSynchronization implements Synchronization
+{
+    private static Logger log = Logger.getLogger(BridgeSynchronization.class);
+
+    private BridgeWrapper bridgeWrapper;
+
+    public BridgeSynchronization(BridgeWrapper bridgeWrapper)
+    {
+        log.trace("BridgeSynchronization(BridgeWrapper="+bridgeWrapper+")");
+
+        this.bridgeWrapper = bridgeWrapper;
+    }
+
+    /**
+     * The beforeCompletion method is called by the transaction manager prior to the start of the two-phase transaction commit process.
+     */
+    public void beforeCompletion()
+    {
+        log.trace("beforeCompletion()");
+
+        if(!bridgeWrapper.prepareVolatile())
+        {
+            // JTA does not explicitly provide for beforeCompletion signalling problems, but in
+            // our impl the engine will set the tx rollbackOnly if beforeCompletion throw an exception
+            // Note com.arjuna.ats.jta.TransactionManager.getTransaction().setRollbackOnly may also work.
+            throw new RuntimeException("BridgeWrapper.prepareVolatile() returned false");
+        }
+    }
+
+    /**
+     * This method is called by the transaction manager after the transaction is committed or rolled back.
+     *
+     * @param status the javax.transaction.Status representing the tx outcome.
+     */
+    public void afterCompletion(int status)
+    {
+        log.trace("afterCompletion(status="+status+"/"+ JTAHelper.stringForm(status)+")");
+
+        switch(status)
+        {
+            case Status.STATUS_COMMITTED:
+                bridgeWrapper.commitVolatile();
+                break;
+            case Status.STATUS_ROLLEDBACK:
+                bridgeWrapper.rollbackVolatile();
+                break;
+            default:
+                log.warn("unexpected Status "+status+", treating as ROLLEDBACK");
+                bridgeWrapper.rollbackVolatile();
+        }
+    }
+}

Added: labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/BridgeVolatileParticipant.java
===================================================================
--- labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/BridgeVolatileParticipant.java	                        (rev 0)
+++ labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/BridgeVolatileParticipant.java	2009-06-05 10:07:15 UTC (rev 26847)
@@ -0,0 +1,182 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2009, Red Hat Middleware LLC, and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ * (C) 2009 @author JBoss Inc
+ */
+package org.jboss.jbossts.txbridge;
+
+import com.arjuna.wst.*;
+import com.arjuna.ats.internal.jta.resources.spi.XATerminatorExtensions;
+import com.arjuna.ats.internal.jta.transaction.arjunacore.jca.SubordinationManager;
+import com.arjuna.ats.jta.utils.JTAHelper;
+import org.apache.log4j.Logger;
+
+import javax.transaction.xa.Xid;
+import javax.transaction.Status;
+
+/**
+ * Provides method call mapping between WS-AT Volatile Participant interface
+ * and an underlying JTA subtransaction coordinator.
+ *
+ * @author jonathan.halliday at redhat.com, 2009-06-01
+ */
+public class BridgeVolatileParticipant implements Volatile2PCParticipant
+{
+    private static Logger log = Logger.getLogger(BridgeVolatileParticipant.class);
+
+    // no standard interface for driving Synchronization phases separately
+    // in JCA, so we have to use proprietry API.
+    private XATerminatorExtensions xaTerminatorExtensions;
+
+    private String externalTxId;
+
+    private Xid xid;
+
+    /**
+     * Create a new WS-AT Volatile Participant which wraps the subordinate XA tx terminator.
+     *
+     * @param externalTxId the WS-AT Tx identifier
+     * @param xid the Xid to use when driving the subordinate XA transaction.
+     */
+    BridgeVolatileParticipant(String externalTxId, Xid xid)
+    {
+		log.trace("BridgeVolatileParticipant(TxId="+externalTxId+", Xid="+xid+")");
+
+        this.xid = xid;
+        this.externalTxId = externalTxId;
+        this.xaTerminatorExtensions = (XATerminatorExtensions)SubordinationManager.getXATerminator();
+    }
+
+    /**
+     * Perform beforeCompletion activities such as flushing cached state to stable store.
+     *
+     * @return an indication of whether it can prepare or not.
+     * @see com.arjuna.wst.Vote
+     */
+    public Vote prepare() throws WrongStateException, SystemException
+    {
+        log.trace("prepare(Xid="+xid+")");
+
+        // Usually a VolatileParticipant would return Aborted to stop the tx in error cases. However, that
+        // would mean rollback() would not be called on the instance returning Aborted, which would make it
+        // hard to invoke afterCompletion on the subordinate. So we cheat a bit by using setRollbackOnly instead.
+        // A slightly more efficient but less clear impl would be to have the same object implement both the Volatile
+        // and Durable Participants and keep count of the number of prepare/rollback invocations to know
+        // if being invoked as Volatile or Dirable.
+
+
+        // TODO InboundBridgeManager.getInboundBridge() would be better,
+        // but needs XTS to provide tx context on thread in (selected) Participant calls.
+        InboundBridge inboundBridge = InboundBridgeManager.getInboundBridge(externalTxId);
+
+        try
+        {
+            // TODO: check for rollbackOnly before bothering to invoke?
+            // beforeCompletion should run in tx context.
+            inboundBridge.start();
+
+            if(!xaTerminatorExtensions.beforeCompletion(xid))
+            {
+				log.warn("prepare on Xid="+xid+" failed, setting RollbackOnly");
+                inboundBridge.setRollbackOnly();
+            }
+
+            return new Prepared();
+        }
+        catch(Exception e)
+        {
+            log.warn("prepare on Xid="+xid+" failed, setting RollbackOnly", e);
+            try
+            {
+                inboundBridge.setRollbackOnly();
+            }
+            catch(Exception e2)
+            {
+                log.warn("setRollbackOnly failed", e2);
+            }
+
+            return new Prepared();
+        }
+        finally
+        {
+            try
+            {
+                inboundBridge.stop();
+            }
+            catch(Exception e)
+            {
+                log.warn("stop failed for Xid="+xid, e);
+            }
+        }
+    }
+
+    /**
+     * Perform afterCompletion cleanup activities such as releasing resources.
+     *
+     * Caution: may not be invoked in crash recovery situations.
+     */
+    public void commit() throws WrongStateException, SystemException
+    {
+        log.trace("commit(Xid="+xid+")");
+
+        afterCompletion(Status.STATUS_COMMITTED);
+    }
+
+    /**
+     * Perform afterCompletion cleanup activities such as releasing resources.
+     *
+     * Caution: may not be invoked in crash recovery situations.
+     */
+    public void rollback() throws WrongStateException, SystemException
+    {
+        log.trace("rollback(Xid="+xid+")");
+
+        afterCompletion(Status.STATUS_ROLLEDBACK);
+    }
+
+    /**
+     * Invoke afterCompletion on the subordinate JTA tx.
+     *
+     * @param status a javax.transaction.Status value, normally STATUS_COMMITTED or STATUS_ROLLEDBACK
+     */
+    private void afterCompletion(int status)
+    {
+        log.trace("afterCompletion(Xid="+xid+", status="+status+"/"+JTAHelper.stringForm(status)+")");
+
+        // this is a null-op, the afterCompletion is done implicitly at the XAResource commit/rollback stage.
+    }
+
+    /**
+     * Deprecated, should never be called.
+     */
+    public void unknown() throws SystemException
+    {
+        log.trace("unknown(Xid="+xid+"): NOT IMPLEMENTED");
+    }
+
+    /**
+     * VolatileParticipants don't support recovery, so this should never be called.
+     */
+    public void error() throws SystemException
+    {
+        log.trace("unknown(Xid="+xid+"): NOT IMPLEMENTED");
+    }
+}

Modified: labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/InboundBridge.java
===================================================================
--- labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/InboundBridge.java	2009-06-05 08:59:08 UTC (rev 26846)
+++ labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/InboundBridge.java	2009-06-05 10:07:15 UTC (rev 26847)
@@ -98,6 +98,13 @@
 		TransactionManager.transactionManager().suspend();
 	}
 
+    public void setRollbackOnly() throws XAException, SystemException
+    {
+        log.trace("setRollbackOnly("+xid+")");
+
+        getTransaction().setRollbackOnly();
+    }
+
 	/**
 	 * Get the JTA Transaction which corresponds to the Xid of the instance.
 	 *

Modified: labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/InboundBridgeManager.java
===================================================================
--- labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/InboundBridgeManager.java	2009-06-05 08:59:08 UTC (rev 26846)
+++ labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/InboundBridgeManager.java	2009-06-05 10:07:15 UTC (rev 26847)
@@ -28,6 +28,7 @@
 import com.arjuna.mw.wst11.UserTransactionFactory;
 
 import com.arjuna.mw.wst11.TransactionManagerFactory;
+import com.arjuna.mw.wst11.TransactionManager;
 import com.arjuna.wst.WrongStateException;
 import com.arjuna.wst.UnknownTransactionException;
 import com.arjuna.wsc.AlreadyRegisteredException;
@@ -82,6 +83,21 @@
 	}
 
     /**
+     * Return an InboundBridge instance for the specified WS-AT transaction context.
+     *
+     * This method exists only to allow BridgeVolatileParticipant to get tx context and may go away
+     * once its no longer needed for that purpose. Therefore it should probably not be relied upon.
+     *
+     * @deprecated
+     * @param externalTxId The WS-AT tx identifier.
+     * @return
+     */
+    static InboundBridge getInboundBridge(String externalTxId)
+    {
+        return inboundBridgeMappings.get(externalTxId);
+    }
+
+    /**
      * Remove the mapping for the given externalTxId. This should be called for gc when the tx is finished.
      *
      * @param externalTxId The WS-AT tx identifier.
@@ -114,16 +130,20 @@
 			return;
 		}
 
+        TransactionManager transactionManager = TransactionManagerFactory.transactionManager();
+
         // Xid for driving the subordinate,
         // shared by the bridge (thread assoc) and Participant (termination via XATerminator)
 		Xid xid = new XidImple(new Uid());
 
-		BridgeParticipantAT bridgeParticipantAT = new BridgeParticipantAT(externalTxId, xid);
-
+		BridgeDurableParticipant bridgeDurableParticipant = new BridgeDurableParticipant(externalTxId, xid);
         // construct the participantId in such as way as we can recognise it at recovery time:
-        String participantId = BridgeParticipantAT.TYPE_IDENTIFIER+new Uid().toString();
-		TransactionManagerFactory.transactionManager().enlistForDurableTwoPhase(bridgeParticipantAT, participantId);
+        String participantId = BridgeDurableParticipant.TYPE_IDENTIFIER+new Uid().toString();
+		transactionManager.enlistForDurableTwoPhase(bridgeDurableParticipant, participantId);
 
+        BridgeVolatileParticipant bridgeVolatileParticipant = new BridgeVolatileParticipant(externalTxId, xid);
+        transactionManager.enlistForVolatileTwoPhase(bridgeVolatileParticipant, new Uid().toString());
+
         inboundBridgeMappings.put(externalTxId, new InboundBridge(xid));
 	}
 }
\ No newline at end of file

Modified: labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/OutboundBridgeManager.java
===================================================================
--- labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/OutboundBridgeManager.java	2009-06-05 08:59:08 UTC (rev 26846)
+++ labs/jbosstm/trunk/txbridge/src/org/jboss/jbossts/txbridge/OutboundBridgeManager.java	2009-06-05 10:07:15 UTC (rev 26847)
@@ -29,6 +29,7 @@
 
 import javax.transaction.SystemException;
 import javax.transaction.RollbackException;
+import javax.transaction.Synchronization;
 import javax.transaction.xa.XAResource;
 
 import org.apache.log4j.Logger;
@@ -63,7 +64,8 @@
 	{
 		log.trace("getOutboundBridge()");
 
-        try {
+        try
+        {
             Transaction transaction = (Transaction)TransactionManager.transactionManager().getTransaction();
 
             Uid externalTxId = transaction.get_uid();
@@ -74,7 +76,9 @@
 
             return outboundBridgeMappings.get(externalTxId);
 
-        } catch(SystemException e) {
+        }
+        catch(SystemException e)
+        {
             log.error("problem", e);
         }
 
@@ -114,13 +118,16 @@
 
         OutboundBridge outboundBridge = new OutboundBridge(bridgeWrapper);
         XAResource xaResource = new BridgeXAResource(externalTxId, bridgeWrapper);
+        Synchronization synchronization = new BridgeSynchronization(bridgeWrapper);
 
         try
         {
             transaction.enlistResource(xaResource);
-        } catch(RollbackException e)
+            transaction.registerSynchronization(synchronization);
+        }
+        catch(RollbackException e)
         {
-            log.error("Unable to enlist BridgeXAResource: ", e);
+            log.error("Unable to enlist BridgeXAResource or register BridgeSynchronization: ", e);
             throw new SystemException(e.toString());
         }
 




More information about the jboss-svn-commits mailing list