[jboss-svn-commits] JBL Code SVN: r25556 - in labs/jbosstm/trunk/XTS: WSTX/classes10/com/arjuna/mw/wst/service and 3 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Mon Mar 9 12:54:06 EDT 2009


Author: adinn
Date: 2009-03-09 12:54:06 -0400 (Mon, 09 Mar 2009)
New Revision: 25556

Added:
   labs/jbosstm/trunk/XTS/WSTX/classes10/com/arjuna/mwlabs/wst/at/SubordinateImporter.java
   labs/jbosstm/trunk/XTS/WSTX/classes11/com/arjuna/mwlabs/wst11/at/SubordinateImporter.java
Modified:
   labs/jbosstm/trunk/XTS/WSCF/classes/com/arjuna/mwlabs/wscf/model/twophase/arjunacore/subordinate/SubordinateCoordinator.java
   labs/jbosstm/trunk/XTS/WSTX/classes10/com/arjuna/mw/wst/service/JaxBaseHeaderContextProcessor.java
   labs/jbosstm/trunk/XTS/WSTX/classes11/com/arjuna/mw/wst11/service/JaxBaseHeaderContextProcessor.java
Log:
fixes JBTM-510. the subordinate is always created using the local context factory/coordinator. this ensures that the subordinate can delete the parent to subordinate mapping at subordinate commit/rollback.

Modified: labs/jbosstm/trunk/XTS/WSCF/classes/com/arjuna/mwlabs/wscf/model/twophase/arjunacore/subordinate/SubordinateCoordinator.java
===================================================================
--- labs/jbosstm/trunk/XTS/WSCF/classes/com/arjuna/mwlabs/wscf/model/twophase/arjunacore/subordinate/SubordinateCoordinator.java	2009-03-09 15:57:48 UTC (rev 25555)
+++ labs/jbosstm/trunk/XTS/WSCF/classes/com/arjuna/mwlabs/wscf/model/twophase/arjunacore/subordinate/SubordinateCoordinator.java	2009-03-09 16:54:06 UTC (rev 25556)
@@ -2,7 +2,7 @@
  * JBoss, Home of Professional Open Source
  * Copyright 2006, Red Hat Middleware LLC, and individual contributors
  * as indicated by the @author tags. 
- * See the copyright.txt in the distribution for a full listing 
+ * See the copyritypeght.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
@@ -188,6 +188,11 @@
         if (status != ActionStatus.COMMITTING) {
             SubordinateCoordinator.removeRecoveredCoordinator(this);
         }
+        
+        // run any callback associated with this transaction
+
+        runCallback(get_uid().stringForm());
+
 	}
 
     /**
@@ -232,6 +237,10 @@
 
         // iemove the coordinator from the recovered coordinatros table
         SubordinateCoordinator.removeRecoveredCoordinator(this);
+
+        // run any callback associated with this transaction
+
+        runCallback(get_uid().stringForm());
         
         this.finalStatus = status;
 	}
@@ -317,4 +326,43 @@
     private boolean activated;
 
     private static final HashMap<String, SubordinateCoordinator> recoveredCoordinators = new HashMap<String, SubordinateCoordinator>();
+
+    /**
+     * we need to remove the association between parent and subordinate context at completion
+     * of commit or rollback -- we use a callback mechanism keyed by transaction id to achieve this
+     */
+
+    private static final HashMap<String, SubordinateCallback> callbacks = new HashMap<String, SubordinateCallback>();
+
+    /**
+     * class implemented by any code which wishes to register a callabck
+     */
+    public static abstract class SubordinateCallback
+    {
+        private SubordinateCallback next; // in case multiple callbacks are registered
+
+        public abstract void run();
+    }
+
+    /**
+     * register a callback to be called when a subordinate transaction with a specific key executes
+     * a commit or rollback. the callback will not be called in the case of a crash
+     * @param key
+     * @param callback
+     */
+    public static void addCallback(String key, SubordinateCallback callback)
+    {
+        SubordinateCallback old = callbacks.put(key, callback);
+        // chian any existign callback so we ensure to call them all
+        callback.next = old;
+    }
+
+    private void runCallback(String key)
+    {
+        SubordinateCallback callback = callbacks.get(key);
+        while (callback != null) {
+            callback.run();
+            callback = callback.next;
+        }
+    }
 }

Modified: labs/jbosstm/trunk/XTS/WSTX/classes10/com/arjuna/mw/wst/service/JaxBaseHeaderContextProcessor.java
===================================================================
--- labs/jbosstm/trunk/XTS/WSTX/classes10/com/arjuna/mw/wst/service/JaxBaseHeaderContextProcessor.java	2009-03-09 15:57:48 UTC (rev 25555)
+++ labs/jbosstm/trunk/XTS/WSTX/classes10/com/arjuna/mw/wst/service/JaxBaseHeaderContextProcessor.java	2009-03-09 16:54:06 UTC (rev 25556)
@@ -28,6 +28,7 @@
 import com.arjuna.mw.wst.common.SOAPUtil;
 import com.arjuna.mw.wst.*;
 import com.arjuna.mw.wstx.logging.wstxLogger;
+import com.arjuna.mwlabs.wst.at.SubordinateImporter;
 
 import javax.xml.soap.*;
 import java.util.Iterator;
@@ -74,16 +75,12 @@
                     final String coordinationType = cc.getCoordinationType().getValue() ;
                     if (AtomicTransactionConstants.WSAT_PROTOCOL.equals(coordinationType))
                     {
-                        final TxContext txContext = new com.arjuna.mwlabs.wst.at.context.TxContextImple(cc) ;
-                        TransactionManagerFactory.transactionManager().resume(txContext) ;
                         clearMustUnderstand(soapHeader, soapHeaderElement) ;
+                        TxContext txContext = new com.arjuna.mwlabs.wst.at.context.TxContextImple(cc) ;
                         if (installSubordinateTx) {
-                            // since we are now in an AT Tx  we just need to start a subordinate one using the
-                            // UserSubordinateTransaction instance. the begin call will register the
-                            // Tx on the thread
-                            UserTransaction ust = UserTransactionFactory.userSubordinateTransaction();
-                            ust.begin();
+                            txContext = SubordinateImporter.importContext(cc);
                         }
+                        TransactionManagerFactory.transactionManager().resume(txContext) ;
                     }
                     else if (BusinessActivityConstants.WSBA_PROTOCOL_ATOMIC_OUTCOME.equals(coordinationType))
                     {

Added: labs/jbosstm/trunk/XTS/WSTX/classes10/com/arjuna/mwlabs/wst/at/SubordinateImporter.java
===================================================================
--- labs/jbosstm/trunk/XTS/WSTX/classes10/com/arjuna/mwlabs/wst/at/SubordinateImporter.java	                        (rev 0)
+++ labs/jbosstm/trunk/XTS/WSTX/classes10/com/arjuna/mwlabs/wst/at/SubordinateImporter.java	2009-03-09 16:54:06 UTC (rev 25556)
@@ -0,0 +1,59 @@
+package com.arjuna.mwlabs.wst.at;
+
+import com.arjuna.mw.wst.TxContext;
+import com.arjuna.wsc.InvalidCreateParametersException;
+import com.arjuna.wsc.ContextFactoryMapper;
+import com.arjuna.mwlabs.wscf.model.twophase.arjunacore.subordinate.SubordinateCoordinator;
+import com.arjuna.mwlabs.wst.at.context.TxContextImple;
+import com.arjuna.webservices.wscoor.CoordinationContextType;
+import com.arjuna.webservices.wsat.AtomicTransactionConstants;
+
+import java.util.HashMap;
+
+/**
+ * class to manage association of incoming AT transactions with subordinate AT transactions
+ * coordinated by the local coordination servcie
+ */
+public class SubordinateImporter
+{
+    private static HashMap<String, TxContext> subordinateContextMap = new HashMap<String, TxContext>();
+
+    /**
+     * handle on the local 1.1 context factory implementation
+     */
+    private static ContextFactoryImple atContextFactory = (ContextFactoryImple) ContextFactoryMapper.getFactory().getContextFactory(AtomicTransactionConstants.WSAT_PROTOCOL);
+
+    public static TxContext importContext(CoordinationContextType cc)
+    {
+        // get the subordinate transaction manager to install any existing
+        // subordinate tx for this one or create and install a new one.
+        final String identifier = cc.getIdentifier().getValue();
+        TxContext subordinateTxContext = subordinateContextMap.get(identifier);
+        if (subordinateTxContext == null) {
+            // create a context for a local coordinator
+            CoordinationContextType context = null;
+            try {
+                context = atContextFactory.create(AtomicTransactionConstants.WSAT_PROTOCOL, 0L, cc);
+            } catch (InvalidCreateParametersException e) {
+                // should not happen
+            }
+            subordinateTxContext = new TxContextImple(context);
+            subordinateContextMap.put(identifier, subordinateTxContext);
+
+            // register a cleanup callback with the subordinate transactionso that the entry gets removed
+            // when the transcation commits or rolls back
+
+            String subordinateId = context.getIdentifier().getValue().substring(4); // remove "urn:" prefix
+            SubordinateCoordinator.SubordinateCallback callback = new SubordinateCoordinator.SubordinateCallback() {
+                public String parentId = identifier;
+                public void run()
+                {
+                    subordinateContextMap.remove(parentId);
+                }
+            };
+            SubordinateCoordinator.addCallback(subordinateId, callback);
+        }
+
+        return subordinateTxContext;
+    }
+}

Modified: labs/jbosstm/trunk/XTS/WSTX/classes11/com/arjuna/mw/wst11/service/JaxBaseHeaderContextProcessor.java
===================================================================
--- labs/jbosstm/trunk/XTS/WSTX/classes11/com/arjuna/mw/wst11/service/JaxBaseHeaderContextProcessor.java	2009-03-09 15:57:48 UTC (rev 25555)
+++ labs/jbosstm/trunk/XTS/WSTX/classes11/com/arjuna/mw/wst11/service/JaxBaseHeaderContextProcessor.java	2009-03-09 16:54:06 UTC (rev 25556)
@@ -29,10 +29,16 @@
 import com.arjuna.webservices11.wsba.BusinessActivityConstants;
 import com.arjuna.webservices11.wscoor.CoordinationConstants;
 import com.arjuna.mwlabs.wst11.at.context.TxContextImple;
+import com.arjuna.mwlabs.wst11.at.ContextFactoryImple;
+import com.arjuna.mwlabs.wst11.at.SubordinateImporter;
+import com.arjuna.mwlabs.wscf.model.twophase.arjunacore.subordinate.SubordinateCoordinator;
+import com.arjuna.wsc11.ContextFactoryMapper;
 import org.oasis_open.docs.ws_tx.wscoor._2006._06.CoordinationContextType;
+import org.oasis_open.docs.ws_tx.wscoor._2006._06.CoordinationContext;
 
 import javax.xml.soap.*;
 import java.util.Iterator;
+import java.util.HashMap;
 
 /**
  * Common base class for classes used to perform
@@ -76,16 +82,12 @@
                     final String coordinationType = cc.getCoordinationType();
                     if (AtomicTransactionConstants.WSAT_PROTOCOL.equals(coordinationType))
                     {
-                        final TxContext txContext = new TxContextImple(cc) ;
-                        TransactionManagerFactory.transactionManager().resume(txContext) ;
                         clearMustUnderstand(soapHeader, soapHeaderElement) ;
+                        TxContext txContext = new TxContextImple(cc) ;
                         if (installSubordinateTx) {
-                            // since we are now in an AT Tx  we just need to start a subordinate one using the
-                            // UserSubordinateTransaction instance. the begin call will register the
-                            // Tx on the thread
-                            UserTransaction ust = UserTransactionFactory.userSubordinateTransaction();
-                            ust.begin();
+                            txContext = SubordinateImporter.importContext(cc);
                         }
+                        TransactionManagerFactory.transactionManager().resume(txContext);
                     }
                     else if (BusinessActivityConstants.WSBA_PROTOCOL_ATOMIC_OUTCOME.equals(coordinationType))
                     {

Added: labs/jbosstm/trunk/XTS/WSTX/classes11/com/arjuna/mwlabs/wst11/at/SubordinateImporter.java
===================================================================
--- labs/jbosstm/trunk/XTS/WSTX/classes11/com/arjuna/mwlabs/wst11/at/SubordinateImporter.java	                        (rev 0)
+++ labs/jbosstm/trunk/XTS/WSTX/classes11/com/arjuna/mwlabs/wst11/at/SubordinateImporter.java	2009-03-09 16:54:06 UTC (rev 25556)
@@ -0,0 +1,63 @@
+package com.arjuna.mwlabs.wst11.at;
+
+import com.arjuna.mw.wst.TxContext;
+import com.arjuna.mw.wst11.UserTransaction;
+import com.arjuna.mw.wst11.TransactionManagerFactory;
+import com.arjuna.mw.wst11.UserTransactionFactory;
+import com.arjuna.mwlabs.wst11.at.context.TxContextImple;
+import com.arjuna.mwlabs.wscf.model.twophase.arjunacore.subordinate.SubordinateCoordinator;
+import com.arjuna.webservices11.wsat.AtomicTransactionConstants;
+import com.arjuna.wsc11.ContextFactoryMapper;
+import com.arjuna.wsc.InvalidCreateParametersException;
+import org.oasis_open.docs.ws_tx.wscoor._2006._06.CoordinationContext;
+import org.oasis_open.docs.ws_tx.wscoor._2006._06.CoordinationContextType;
+
+import java.util.HashMap;
+
+/**
+ * class to manage association of incoming AT transactions with subordinate AT transactions
+ * coordinated by the local coordination servcie
+ */
+public class SubordinateImporter
+{
+    private static HashMap<String, TxContext> subordinateContextMap = new HashMap<String, TxContext>();
+
+    /**
+     * handle on the local 1.1 context factory implementation
+     */
+    private static ContextFactoryImple atContextFactory = (ContextFactoryImple) ContextFactoryMapper.getFactory().getContextFactory(AtomicTransactionConstants.WSAT_PROTOCOL);
+
+    public static TxContext importContext(CoordinationContextType cc)
+    {
+        // get the subordinate transaction manager to install any existing
+        // subordinate tx for this one or create and install a new one.
+        final String identifier = cc.getIdentifier().getValue();
+        TxContext subordinateTxContext = subordinateContextMap.get(identifier);
+        if (subordinateTxContext == null) {
+            // create a context for a local coordinator
+            CoordinationContext context = null;
+            try {
+                context = atContextFactory.create(AtomicTransactionConstants.WSAT_PROTOCOL, 0L, cc, false);
+            } catch (InvalidCreateParametersException e) {
+                // should not happen
+            }
+            subordinateTxContext = new TxContextImple(context);
+            subordinateContextMap.put(identifier, subordinateTxContext);
+
+            // register a cleanup callback with the subordinate transactionso that the entry gets removed
+            // when the transcation commits or rolls back
+            
+            String subordinateId = context.getIdentifier().getValue().substring(4); // remove "urn:" prefix
+            SubordinateCoordinator.SubordinateCallback callback = new SubordinateCoordinator.SubordinateCallback() {
+                public String parentId = identifier;
+                public void run()
+                {
+                    subordinateContextMap.remove(parentId);
+                }
+            };
+            SubordinateCoordinator.addCallback(subordinateId, callback);
+        }
+
+        return subordinateTxContext;
+    }
+}




More information about the jboss-svn-commits mailing list