[jboss-svn-commits] JBL Code SVN: r37789 - in labs/jbosstm/trunk/txframework/framework/src: main/java/org/jboss/narayana/txframework/api/configuration/service and 4 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Fri Dec 9 10:36:55 EST 2011


Author: paul.robinson
Date: 2011-12-09 10:36:55 -0500 (Fri, 09 Dec 2011)
New Revision: 37789

Added:
   labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/api/annotation/service/ServiceRequest.java
   labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/api/configuration/service/RequestType.java
   labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/impl/handlers/wsat/WSATInternalParticipant.java
   labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/impl/handlers/wsat/WSATParticipantRegistry.java
   labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/impl/handlers/wsba/WSBAInternalParticipant.java
   labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/impl/handlers/wsba/WSBAParticipantRegistry.java
Removed:
   labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/api/annotation/service/ServiceRequest.java
   labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/api/configuration/service/RequestType.java
Modified:
   labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/impl/handlers/wsat/WSATHandler.java
   labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/impl/handlers/wsba/WSBACoordinatorCompletionHandler.java
   labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/impl/handlers/wsba/WSBAHandler.java
   labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/impl/handlers/wsba/WSBAParticipantCompletionHandler.java
   labs/jbosstm/trunk/txframework/framework/src/test/java/org/jboss/narayana/txframework/functional/ATTest.java
   labs/jbosstm/trunk/txframework/framework/src/test/java/org/jboss/narayana/txframework/functional/BACoordinatorCompletionTest.java
   labs/jbosstm/trunk/txframework/framework/src/test/java/org/jboss/narayana/txframework/functional/BAParticipantCompletionTest.java
   labs/jbosstm/trunk/txframework/framework/src/test/java/org/jboss/narayana/txframework/functional/services/ATService.java
   labs/jbosstm/trunk/txframework/framework/src/test/java/org/jboss/narayana/txframework/functional/services/BAParticipantCompletionService.java
Log:
JBTM-988 Support multiple @ServiceRequest calls per transaction, creating a single participant per RM

Deleted: labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/api/annotation/service/ServiceRequest.java
===================================================================
--- labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/api/annotation/service/ServiceRequest.java	2011-12-09 15:36:12 UTC (rev 37788)
+++ labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/api/annotation/service/ServiceRequest.java	2011-12-09 15:36:55 UTC (rev 37789)
@@ -1,33 +0,0 @@
-package org.jboss.narayana.txframework.api.annotation.service;
-
-import org.jboss.narayana.txframework.api.configuration.service.Default;
-import org.jboss.narayana.txframework.api.configuration.service.RequestType;
-import javax.interceptor.InterceptorBinding;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Method level annotation used to enable lifecycle handling and configure parameters which control its operation
- */
-
- at InterceptorBinding
- at Retention(RetentionPolicy.RUNTIME)
- at Target({ElementType.METHOD, ElementType.TYPE})
-public @interface ServiceRequest
-{
-    /**
-     * The class which is the target of lifecycle handler callbacks. With POJO execution mode this class is the
-     * direct target for handler method invocations. With EJB execution mode it identifies the EJB interface
-     * class. With WS execution mode it identifies the client interface for  a JaxWS client.
-     */
-    public Class lifecycleClass() default Default.class;
-    /**
-     * identifies whether the service request is always read only as far as transactional modifications are
-     * concerned or, alternatively, that it may make changes to transactional data. in the latter case the
-     * service request method can indicate a read-only outcome by invoking the readOnly method of an injected
-     * control.
-     */
-    public RequestType requestType() default RequestType.MODIFY;
-}
\ No newline at end of file

Added: labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/api/annotation/service/ServiceRequest.java
===================================================================
--- labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/api/annotation/service/ServiceRequest.java	                        (rev 0)
+++ labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/api/annotation/service/ServiceRequest.java	2011-12-09 15:36:55 UTC (rev 37789)
@@ -0,0 +1,33 @@
+package org.jboss.narayana.txframework.api.annotation.service;
+
+import org.jboss.narayana.txframework.api.configuration.service.Default;
+import org.jboss.narayana.txframework.api.configuration.service.RequestType;
+import javax.interceptor.InterceptorBinding;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Method level annotation used to enable lifecycle handling and configure parameters which control its operation
+ */
+
+ at InterceptorBinding
+ at Retention(RetentionPolicy.RUNTIME)
+ at Target({ElementType.METHOD, ElementType.TYPE})
+public @interface ServiceRequest
+{
+    /**
+     * The class which is the target of lifecycle handler callbacks. With POJO execution mode this class is the
+     * direct target for handler method invocations. With EJB execution mode it identifies the EJB interface
+     * class. With WS execution mode it identifies the client interface for  a JaxWS client.
+     */
+    public Class lifecycleClass() default Default.class;
+    /**
+     * identifies whether the service request is always read only as far as transactional modifications are
+     * concerned or, alternatively, that it may make changes to transactional data. in the latter case the
+     * service request method can indicate a read-only outcome by invoking the readOnly method of an injected
+     * control.
+     */
+    public RequestType requestType() default RequestType.MODIFY;
+}

Deleted: labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/api/configuration/service/RequestType.java
===================================================================
--- labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/api/configuration/service/RequestType.java	2011-12-09 15:36:12 UTC (rev 37788)
+++ labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/api/configuration/service/RequestType.java	2011-12-09 15:36:55 UTC (rev 37789)
@@ -1,17 +0,0 @@
-package org.jboss.narayana.txframework.api.configuration.service;
-
-/**
- * specifies values taken by the requestType field in {@link org.jboss.narayana.txframework.api.annotation.service.ServiceRequest#requestType()}annotations
- */
-public enum RequestType
-{
-    /**
-     * this value indicates that a service request method will never make changes to data.
-     */
-    READ_ONLY,
-    /**
-     * this value indicates that a service request method may make changes to data and will employ an
-     * injected control, where necessary, to notify read only status for a specific invocation.
-     */
-    MODIFY
-}

Added: labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/api/configuration/service/RequestType.java
===================================================================
--- labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/api/configuration/service/RequestType.java	                        (rev 0)
+++ labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/api/configuration/service/RequestType.java	2011-12-09 15:36:55 UTC (rev 37789)
@@ -0,0 +1,17 @@
+package org.jboss.narayana.txframework.api.configuration.service;
+
+/**
+ * specifies values taken by the requestType field in {@link org.jboss.narayana.txframework.api.annotation.service.ServiceRequest#requestType()}annotations
+ */
+public enum RequestType
+{
+    /**
+     * this value indicates that a service request method will never make changes to data.
+     */
+    READ_ONLY,
+    /**
+     * this value indicates that a service request method may make changes to data and will employ an
+     * injected control, where necessary, to notify read only status for a specific invocation.
+     */
+    MODIFY
+}

Modified: labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/impl/handlers/wsat/WSATHandler.java
===================================================================
--- labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/impl/handlers/wsat/WSATHandler.java	2011-12-09 15:36:12 UTC (rev 37788)
+++ labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/impl/handlers/wsat/WSATHandler.java	2011-12-09 15:36:55 UTC (rev 37789)
@@ -1,8 +1,10 @@
 package org.jboss.narayana.txframework.impl.handlers.wsat;
 
 import com.arjuna.ats.arjuna.common.Uid;
+import com.arjuna.mw.wst.TxContext;
 import com.arjuna.mw.wst11.TransactionManager;
 import com.arjuna.mw.wst11.TransactionManagerFactory;
+import com.arjuna.mw.wst11.UserTransactionFactory;
 import com.arjuna.wst.*;
 import org.jboss.narayana.txframework.api.annotation.management.TxManagement;
 import org.jboss.narayana.txframework.api.exception.TXFrameworkException;
@@ -10,21 +12,32 @@
 import org.jboss.narayana.txframework.impl.handlers.ParticipantRegistrationException;
 import org.jboss.narayana.txframework.impl.handlers.ProtocolHandler;
 import javax.interceptor.InvocationContext;
+import javax.transaction.Transaction;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
 
 public class WSATHandler implements ProtocolHandler
 {
     private Object serviceImpl;
     private ATTxControl atTxControl;
+    private static final WSATParticipantRegistry participantRegistry = new WSATParticipantRegistry();
 
     public WSATHandler(Object serviceImpl, Method serviceMethod) throws TXFrameworkException
     {
         this.serviceImpl = serviceImpl;
 
         String idPrefix = serviceImpl.getClass().getName();
-        registerParticipants(idPrefix);
 
+        //Register Service's participant
+        registerParticipants(serviceImpl, idPrefix);
+
+        //Register internal participant for tidy up at end of TX
+        registerParticipants(new WSATInternalParticipant(), WSATInternalParticipant.class.getName());
+
         atTxControl = new ATTxControlImpl();
         injectTxManagement(atTxControl);
     }
@@ -65,16 +78,29 @@
         }
     }
 
-    private void registerParticipants(String idPrefix) throws ParticipantRegistrationException
+    private void registerParticipants(Object participant, String idPrefix) throws ParticipantRegistrationException
     {
         try
         {
-            Volatile2PCParticipant volatileParticipant = new WSATVolatile2PCParticipant(serviceImpl);
-            Durable2PCParticipant durableParticipant = new WSATDurable2PCParticipant(serviceImpl);
+            synchronized (participantRegistry)
+            {
+                String txid = UserTransactionFactory.userTransaction().toString();
 
-            TransactionManager transactionManager = TransactionManagerFactory.transactionManager();
-            transactionManager.enlistForVolatileTwoPhase(volatileParticipant, idPrefix + new Uid().toString());
-            transactionManager.enlistForDurableTwoPhase(durableParticipant, idPrefix + new Uid().toString());
+                //Only create participant if there is not already a participant for this ServiceImpl and this transaction
+                if (!participantRegistry.isRegistered(txid, participant.getClass()))
+                {
+                    //Internal participant for doing tidy up at the end of the transaction
+                    Volatile2PCParticipant volatileParticipant = new WSATVolatile2PCParticipant(participant);
+                    Durable2PCParticipant durableParticipant = new WSATDurable2PCParticipant(participant);
+
+
+                    TransactionManager transactionManager = TransactionManagerFactory.transactionManager();
+                    transactionManager.enlistForVolatileTwoPhase(volatileParticipant, idPrefix + new Uid().toString());
+                    transactionManager.enlistForDurableTwoPhase(durableParticipant, idPrefix + new Uid().toString());
+
+                    participantRegistry.register(txid, participant.getClass());
+                }
+            }
         }
         catch (WrongStateException e)
         {

Added: labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/impl/handlers/wsat/WSATInternalParticipant.java
===================================================================
--- labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/impl/handlers/wsat/WSATInternalParticipant.java	                        (rev 0)
+++ labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/impl/handlers/wsat/WSATInternalParticipant.java	2011-12-09 15:36:55 UTC (rev 37789)
@@ -0,0 +1,32 @@
+package org.jboss.narayana.txframework.impl.handlers.wsat;
+
+import com.arjuna.mw.wst11.BusinessActivityManager;
+import com.arjuna.mw.wst11.BusinessActivityManagerFactory;
+import com.arjuna.mw.wst11.UserTransactionFactory;
+import com.arjuna.wst.SystemException;
+import org.jboss.narayana.txframework.api.annotation.lifecycle.wsat.Commit;
+import org.jboss.narayana.txframework.api.annotation.lifecycle.wsat.PostCommit;
+import org.jboss.narayana.txframework.api.annotation.lifecycle.wsat.Rollback;
+import org.jboss.narayana.txframework.api.annotation.lifecycle.wsba.*;
+import org.jboss.narayana.txframework.api.annotation.lifecycle.wsba.Error;
+import org.jboss.narayana.txframework.impl.handlers.ParticipantRegistrationException;
+import org.jboss.narayana.txframework.impl.handlers.wsba.WSBAParticipantRegistry;
+
+public class WSATInternalParticipant
+{
+    protected final WSATParticipantRegistry participantRegistry = new WSATParticipantRegistry();
+    private String txid;
+
+    public WSATInternalParticipant() throws ParticipantRegistrationException
+    {
+        txid = UserTransactionFactory.userTransaction().toString();
+    }
+
+    @PostCommit
+    @Rollback
+    public void forgetPaticipant()
+    {
+        participantRegistry.forget(txid);
+    }
+
+}

Added: labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/impl/handlers/wsat/WSATParticipantRegistry.java
===================================================================
--- labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/impl/handlers/wsat/WSATParticipantRegistry.java	                        (rev 0)
+++ labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/impl/handlers/wsat/WSATParticipantRegistry.java	2011-12-09 15:36:55 UTC (rev 37789)
@@ -0,0 +1,59 @@
+package org.jboss.narayana.txframework.impl.handlers.wsat;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class WSATParticipantRegistry
+{
+    private static final Map<String, List<Class>> participantMap = new HashMap<String, List<Class>>();
+
+    public WSATParticipantRegistry()
+    {
+    }
+
+     public void register(String txid, Class participant)
+    {
+        synchronized (participantMap)
+        {
+            if (isRegistered(txid, participant))
+            {
+                return;
+            }
+
+            List<Class> participantList = participantMap.get(txid);
+
+            if (participantList == null)
+            {
+                participantList = new ArrayList<Class>();
+                participantMap.put(txid, participantList);
+            }
+
+            synchronized (participantMap.get(txid))
+            {
+                if (!participantList.contains(participant))
+                {
+                    participantList.add(participant);
+                }
+            }
+        }
+    }
+
+    public void forget(String txid)
+    {
+        synchronized (participantMap)
+        {
+            participantMap.remove(txid);
+        }
+    }
+
+    public boolean isRegistered(String txid, Class participant)
+    {
+        synchronized (participantMap)
+        {
+            List<Class> participantList = participantMap.get(txid);
+            return participantList != null && participantList.contains(participant);
+        }
+    }
+}
\ No newline at end of file

Modified: labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/impl/handlers/wsba/WSBACoordinatorCompletionHandler.java
===================================================================
--- labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/impl/handlers/wsba/WSBACoordinatorCompletionHandler.java	2011-12-09 15:36:12 UTC (rev 37788)
+++ labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/impl/handlers/wsba/WSBACoordinatorCompletionHandler.java	2011-12-09 15:36:55 UTC (rev 37789)
@@ -13,23 +13,55 @@
 
 public class WSBACoordinatorCompletionHandler extends WSBAHandler
 {
-    private WSBACoordinatorCompletionParticipant participant;
-
     public WSBACoordinatorCompletionHandler(Object serviceImpl, Method serviceMethod) throws TXFrameworkException
     {
         super(serviceImpl, serviceMethod);
     }
 
     @Override
-    protected BAParticipantManager registerParticipants(Object serviceImpl, Method serviceMethod) throws ParticipantRegistrationException
+    protected BAParticipantManager registerParticipants(Object participant, Method serviceMethod) throws ParticipantRegistrationException
     {
         try
         {
-            participant = new WSBACoordinatorCompletionParticipant(serviceImpl);
+            register(new WSBAInternalParticipant()).completed();
+        }
+        catch (Exception e)
+        {
+            throw new ParticipantRegistrationException("", e);
+        }
 
-            Class serviceClass = serviceImpl.getClass();
-            BusinessActivityManager businessActivityManager = BusinessActivityManagerFactory.businessActivityManager();
-            return businessActivityManager.enlistForBusinessAgreementWithCoordinatorCompletion(participant, serviceClass.getName() + new Uid().toString());
+        return register(participant);
+    }
+
+    private BAParticipantManager register(Object participantObject) throws ParticipantRegistrationException
+    {
+        try
+        {
+            BAParticipantManager baParticipantManager = null;
+
+            synchronized (participantRegistry)
+            {
+                BusinessActivityManager businessActivityManager = BusinessActivityManagerFactory.businessActivityManager();
+                String txid = businessActivityManager.currentTransaction().toString();
+
+                //Only create participant if there is not already a participant for this ServiceImpl and this transaction
+                Class participantClass = participantObject.getClass();
+                if (!participantRegistry.isRegistered(txid, participantClass))
+                {
+
+                    WSBACoordinatorCompletionParticipant coordinatorCompletionParticipant = new WSBACoordinatorCompletionParticipant(participantObject);
+
+                    baParticipantManager = businessActivityManager.enlistForBusinessAgreementWithCoordinatorCompletion(coordinatorCompletionParticipant, participantClass.getName() + new Uid().toString());
+
+                    participantRegistry.register(txid, participantClass, baParticipantManager);
+                }
+                else
+                {
+                    baParticipantManager = participantRegistry.lookupBAParticipantManager(txid, participantClass);
+                }
+            }
+
+            return baParticipantManager;
         }
         catch (WrongStateException e)
         {

Modified: labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/impl/handlers/wsba/WSBAHandler.java
===================================================================
--- labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/impl/handlers/wsba/WSBAHandler.java	2011-12-09 15:36:12 UTC (rev 37788)
+++ labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/impl/handlers/wsba/WSBAHandler.java	2011-12-09 15:36:55 UTC (rev 37789)
@@ -1,5 +1,11 @@
 package org.jboss.narayana.txframework.impl.handlers.wsba;
 
+import com.arjuna.ats.arjuna.common.Uid;
+import com.arjuna.mw.wst11.BusinessActivityManager;
+import com.arjuna.mw.wst11.BusinessActivityManagerFactory;
+import com.arjuna.wst.SystemException;
+import com.arjuna.wst.UnknownTransactionException;
+import com.arjuna.wst.WrongStateException;
 import com.arjuna.wst11.BAParticipantManager;
 import org.jboss.narayana.txframework.api.annotation.lifecycle.wsba.Completes;
 import org.jboss.narayana.txframework.api.annotation.management.TxManagement;
@@ -10,6 +16,9 @@
 import javax.interceptor.InvocationContext;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 public abstract class WSBAHandler implements ProtocolHandler
 {
@@ -18,6 +27,8 @@
     private WSBATxControl wsbaTxControl;
     private BAParticipantManager participantManager;
 
+    protected final WSBAParticipantRegistry participantRegistry = new WSBAParticipantRegistry();
+
     public WSBAHandler(Object serviceImpl, Method serviceMethod) throws TXFrameworkException
     {
         this.serviceImpl = serviceImpl;

Added: labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/impl/handlers/wsba/WSBAInternalParticipant.java
===================================================================
--- labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/impl/handlers/wsba/WSBAInternalParticipant.java	                        (rev 0)
+++ labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/impl/handlers/wsba/WSBAInternalParticipant.java	2011-12-09 15:36:55 UTC (rev 37789)
@@ -0,0 +1,36 @@
+package org.jboss.narayana.txframework.impl.handlers.wsba;
+
+import com.arjuna.mw.wst11.BusinessActivityManager;
+import com.arjuna.mw.wst11.BusinessActivityManagerFactory;
+import com.arjuna.wst.SystemException;
+import org.jboss.narayana.txframework.api.annotation.lifecycle.wsba.*;
+import org.jboss.narayana.txframework.api.annotation.lifecycle.wsba.Error;
+import org.jboss.narayana.txframework.impl.handlers.ParticipantRegistrationException;
+
+public class WSBAInternalParticipant
+{
+    protected final WSBAParticipantRegistry participantRegistry = new WSBAParticipantRegistry();
+    private String txid;
+
+    public WSBAInternalParticipant() throws ParticipantRegistrationException
+    {
+        try
+        {
+            BusinessActivityManager businessActivityManager = BusinessActivityManagerFactory.businessActivityManager();
+            txid = businessActivityManager.currentTransaction().toString();
+        }
+        catch (SystemException e)
+        {
+            throw new ParticipantRegistrationException("Unable to lookup current tranaction id", e);
+        }
+    }
+
+    @Close
+    @Cancel
+    @Compensate
+    public void forgetPaticipant()
+    {
+        participantRegistry.forget(txid);
+    }
+
+}

Modified: labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/impl/handlers/wsba/WSBAParticipantCompletionHandler.java
===================================================================
--- labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/impl/handlers/wsba/WSBAParticipantCompletionHandler.java	2011-12-09 15:36:12 UTC (rev 37788)
+++ labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/impl/handlers/wsba/WSBAParticipantCompletionHandler.java	2011-12-09 15:36:55 UTC (rev 37789)
@@ -21,16 +21,61 @@
     }
 
     @Override
-    protected BAParticipantManager registerParticipants(Object serviceImpl, Method serviceMethod) throws ParticipantRegistrationException
+    protected BAParticipantManager registerParticipants(Object participant, Method serviceMethod) throws ParticipantRegistrationException
     {
+        registerInternalParticipant();
+        return register(participant);
+    }
+
+    private void registerInternalParticipant() throws ParticipantRegistrationException
+    {
         try
         {
-            Class serviceClass = serviceImpl.getClass();
+            BAParticipantManager participantManager = register(new WSBAInternalParticipant());
+            //This particular participant does no work, so notify Completed
+            participantManager.completed();
+        }
+        catch (WrongStateException e)
+        {
+            throw new ParticipantRegistrationException("Error registering internal participant", e);
+        }
+        catch (UnknownTransactionException e)
+        {
+            throw new ParticipantRegistrationException("Error registering internal participant", e);
+        }
+        catch (SystemException e)
+        {
+            throw new ParticipantRegistrationException("Error registering internal participant", e);
+        }
+    }
 
-            participant = new WSBAParticipantCompletionParticipant(serviceImpl);
+    protected BAParticipantManager register(Object participantObject) throws ParticipantRegistrationException
+    {
+        try
+        {
+            BAParticipantManager baParticipantManager = null;
 
-            BusinessActivityManager businessActivityManager = BusinessActivityManagerFactory.businessActivityManager();
-            return businessActivityManager.enlistForBusinessAgreementWithParticipantCompletion(participant, serviceClass.getName() + new Uid().toString());
+            synchronized (participantRegistry)
+            {
+                BusinessActivityManager businessActivityManager = BusinessActivityManagerFactory.businessActivityManager();
+                String txid = businessActivityManager.currentTransaction().toString();
+
+                //Only create participant if there is not already a participant for this ServiceImpl and this transaction
+                Class participantClass = participantObject.getClass();
+                if (!participantRegistry.isRegistered(txid, participantClass))
+                {
+
+                    WSBAParticipantCompletionParticipant participantCompletionParticipant = new WSBAParticipantCompletionParticipant(participantObject);
+                    baParticipantManager = businessActivityManager.enlistForBusinessAgreementWithParticipantCompletion(participantCompletionParticipant, participantClass.getName() + new Uid().toString());
+                    participantRegistry.register(txid, participantClass, baParticipantManager);
+                }
+                else
+                {
+                    baParticipantManager = participantRegistry.lookupBAParticipantManager(txid, participantClass);
+                }
+            }
+
+            return baParticipantManager;
         }
         catch (WrongStateException e)
         {

Added: labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/impl/handlers/wsba/WSBAParticipantRegistry.java
===================================================================
--- labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/impl/handlers/wsba/WSBAParticipantRegistry.java	                        (rev 0)
+++ labs/jbosstm/trunk/txframework/framework/src/main/java/org/jboss/narayana/txframework/impl/handlers/wsba/WSBAParticipantRegistry.java	2011-12-09 15:36:55 UTC (rev 37789)
@@ -0,0 +1,71 @@
+package org.jboss.narayana.txframework.impl.handlers.wsba;
+
+import com.arjuna.wst11.BAParticipantManager;
+import java.util.HashMap;
+import java.util.Map;
+
+public class WSBAParticipantRegistry
+{
+    protected static final Map<String, Map<Class, BAParticipantManager>> participantMap = new HashMap<String, Map<Class, BAParticipantManager>>();
+
+    public WSBAParticipantRegistry()
+    {
+    }
+
+    public void register(String txid, Class participant, BAParticipantManager baParticipantManager)
+    {
+        synchronized (participantMap)
+        {
+            if (isRegistered(txid, participant))
+            {
+                return;
+            }
+
+            Map<Class, BAParticipantManager> baParticipantManagerMap = participantMap.get(txid);
+
+            if (baParticipantManagerMap == null)
+            {
+                baParticipantManagerMap = new HashMap<Class, BAParticipantManager>();
+                participantMap.put(txid, baParticipantManagerMap);
+            }
+
+            synchronized (participantMap.get(txid))
+            {
+                if (baParticipantManagerMap.get(participant) == null)
+                {
+                    baParticipantManagerMap.put(participant, baParticipantManager);
+                }
+            }
+        }
+    }
+
+    public void forget(String txid)
+    {
+        synchronized (participantMap)
+        {
+            participantMap.remove(txid);
+        }
+    }
+
+    public boolean isRegistered(String txid, Class participant)
+    {
+        synchronized (participantMap)
+        {
+            Map<Class, BAParticipantManager> baParticipantManagerMap = participantMap.get(txid);
+            return baParticipantManagerMap != null && baParticipantManagerMap.containsKey(participant);
+        }
+    }
+
+    public BAParticipantManager lookupBAParticipantManager(String txid, Class participantClass)
+    {
+        synchronized (participantMap)
+        {
+            Map<Class, BAParticipantManager> baParticipantManagerMap = participantMap.get(txid);
+            if(baParticipantManagerMap != null && baParticipantManagerMap.containsKey(participantClass))
+            {
+                return baParticipantManagerMap.get(participantClass);
+            }
+            return null;
+        }
+    }
+}

Modified: labs/jbosstm/trunk/txframework/framework/src/test/java/org/jboss/narayana/txframework/functional/ATTest.java
===================================================================
--- labs/jbosstm/trunk/txframework/framework/src/test/java/org/jboss/narayana/txframework/functional/ATTest.java	2011-12-09 15:36:12 UTC (rev 37788)
+++ labs/jbosstm/trunk/txframework/framework/src/test/java/org/jboss/narayana/txframework/functional/ATTest.java	2011-12-09 15:36:55 UTC (rev 37789)
@@ -3,10 +3,9 @@
 import com.arjuna.mw.wst11.UserTransaction;
 import com.arjuna.mw.wst11.UserTransactionFactory;
 import com.arjuna.wst.TransactionRolledBackException;
-import org.jboss.narayana.txframework.api.annotation.lifecycle.wsat.Commit;
-import org.jboss.narayana.txframework.api.annotation.lifecycle.wsat.Prepare;
-import org.jboss.narayana.txframework.api.annotation.lifecycle.wsat.Rollback;
+import org.jboss.narayana.txframework.api.annotation.lifecycle.wsat.*;
 import org.jboss.narayana.txframework.functional.clients.ATClient;
+import org.jboss.narayana.txframework.functional.common.ServiceCommand;
 import org.jboss.narayana.txframework.functional.interfaces.AT;
 import org.jboss.shrinkwrap.api.asset.Asset;
 import org.junit.After;
@@ -49,10 +48,21 @@
         client.invoke();
         ut.commit();
 
-        assertOrder(Prepare.class, Commit.class);
+        assertOrder(PrePrepare.class, Prepare.class, Commit.class, PostCommit.class);
     }
 
     @Test
+    public void testMultiInvoke() throws Exception
+    {
+        ut.begin();
+        client.invoke();
+        client.invoke();
+        ut.commit();
+
+        assertOrder(PrePrepare.class, Prepare.class, Commit.class, PostCommit.class);
+    }
+
+    @Test
     public void testClientDrivenRollback() throws Exception
     {
         ut.begin();
@@ -76,7 +86,7 @@
         catch (TransactionRolledBackException e)
         {
             //todo: should rollback be called twice? once for volatile and once for durable
-            assertOrder(Prepare.class, Rollback.class);
+            assertOrder(PrePrepare.class, Prepare.class, Rollback.class);
             throw e;
         }
     }
@@ -118,25 +128,3 @@
     }
 }
 
-//todo: support multi invocation
-/*@Test
-public void testManualCompleteMultiInvoke() throws Exception
-{
-    UserBusinessActivity uba = UserBusinessActivityFactory.userBusinessActivity();
-    BAParticipantCompletion client = BAParticipantCompletionClient.newInstance();
-
-    Assert.assertTrue(!client.contains("a"));
-    Assert.assertTrue(!client.contains("b"));
-
-    uba.begin();
-    client.saveDataManualComplete("a");
-    client.saveDataManualComplete("b", ServiceCommand.COMPLETE);
-    uba.close();
-
-    Assert.assertTrue(client.contains("a"));
-    Assert.assertTrue(client.contains("b"));
-
-    client.clearData();
-    Assert.assertTrue(!client.contains("a"));
-    Assert.assertTrue(!client.contains("b"));
-}*/

Modified: labs/jbosstm/trunk/txframework/framework/src/test/java/org/jboss/narayana/txframework/functional/BACoordinatorCompletionTest.java
===================================================================
--- labs/jbosstm/trunk/txframework/framework/src/test/java/org/jboss/narayana/txframework/functional/BACoordinatorCompletionTest.java	2011-12-09 15:36:12 UTC (rev 37788)
+++ labs/jbosstm/trunk/txframework/framework/src/test/java/org/jboss/narayana/txframework/functional/BACoordinatorCompletionTest.java	2011-12-09 15:36:55 UTC (rev 37789)
@@ -53,6 +53,17 @@
     }
 
     @Test
+    public void testMultiInvoke() throws Exception
+    {
+        uba.begin();
+        client.saveData();
+        client.saveData();
+        uba.close();
+
+        assertOrder(Complete.class, ConfirmCompleted.class, Close.class);
+    }
+
+    @Test
     public void testClientDrivenCancel() throws Exception
     {
         uba.begin();

Modified: labs/jbosstm/trunk/txframework/framework/src/test/java/org/jboss/narayana/txframework/functional/BAParticipantCompletionTest.java
===================================================================
--- labs/jbosstm/trunk/txframework/framework/src/test/java/org/jboss/narayana/txframework/functional/BAParticipantCompletionTest.java	2011-12-09 15:36:12 UTC (rev 37788)
+++ labs/jbosstm/trunk/txframework/framework/src/test/java/org/jboss/narayana/txframework/functional/BAParticipantCompletionTest.java	2011-12-09 15:36:55 UTC (rev 37789)
@@ -6,6 +6,7 @@
 import junit.framework.Assert;
 import org.jboss.arquillian.junit.Arquillian;
 import org.jboss.narayana.txframework.api.annotation.lifecycle.wsba.Close;
+import org.jboss.narayana.txframework.api.annotation.lifecycle.wsba.Complete;
 import org.jboss.narayana.txframework.functional.clients.BAParticipantCompletionClient;
 import org.jboss.narayana.txframework.functional.common.ServiceCommand;
 import org.jboss.narayana.txframework.functional.interfaces.BAParticipantCompletion;
@@ -61,29 +62,17 @@
         assertOrder(ConfirmCompleted.class, Close.class);
     }
 
-    //todo: support multi invocation
-    /*@Test
-    public void testManualCompleteMultiInvoke() throws Exception
+    @Test
+    public void testMultiInvoke() throws Exception
     {
-        UserBusinessActivity uba = UserBusinessActivityFactory.userBusinessActivity();
-        BAParticipantCompletion client = BAParticipantCompletionClient.newInstance();
-
-        Assert.assertTrue(!client.contains());
-        Assert.assertTrue(!client.contains("b"));
-
         uba.begin();
         client.saveDataManualComplete();
-        client.saveDataManualComplete("b", ServiceCommand.COMPLETE);
+        client.saveDataManualComplete(ServiceCommand.COMPLETE);
         uba.close();
 
-        Assert.assertTrue(client.contains());
-        Assert.assertTrue(client.contains("b"));
+        assertOrder(ConfirmCompleted.class, Close.class);
+    }
 
-        client.clearData();
-        Assert.assertTrue(!client.contains());
-        Assert.assertTrue(!client.contains("b"));
-    }*/
-
     @Test
     public void testClientDrivenCompensate() throws Exception
     {
@@ -124,7 +113,6 @@
         assertOrder();
     }
 
-
     private void assertOrder(Class<? extends Annotation>... expectedOrder)
     {
         org.junit.Assert.assertEquals(Arrays.asList(expectedOrder), client.getEventLog().getEventLog());

Modified: labs/jbosstm/trunk/txframework/framework/src/test/java/org/jboss/narayana/txframework/functional/services/ATService.java
===================================================================
--- labs/jbosstm/trunk/txframework/framework/src/test/java/org/jboss/narayana/txframework/functional/services/ATService.java	2011-12-09 15:36:12 UTC (rev 37788)
+++ labs/jbosstm/trunk/txframework/framework/src/test/java/org/jboss/narayana/txframework/functional/services/ATService.java	2011-12-09 15:36:55 UTC (rev 37789)
@@ -110,6 +110,13 @@
         logEvent(Commit.class);
     }
 
+    @PostCommit
+    @WebMethod(exclude = true)
+    public void postCommit()
+    {
+        logEvent(PostCommit.class);
+    }
+
     @Rollback
     @WebMethod(exclude = true)
     public void rollback()
@@ -117,6 +124,14 @@
         logEvent(Rollback.class);
     }
 
+    @PrePrepare
+    @WebMethod(exclude = true)
+    public Vote prePrepare()
+    {
+        logEvent(PrePrepare.class);
+        return new Prepared();
+    }
+
     @Prepare
     @WebMethod(exclude = true)
     public Vote prepare()

Modified: labs/jbosstm/trunk/txframework/framework/src/test/java/org/jboss/narayana/txframework/functional/services/BAParticipantCompletionService.java
===================================================================
--- labs/jbosstm/trunk/txframework/framework/src/test/java/org/jboss/narayana/txframework/functional/services/BAParticipantCompletionService.java	2011-12-09 15:36:12 UTC (rev 37788)
+++ labs/jbosstm/trunk/txframework/framework/src/test/java/org/jboss/narayana/txframework/functional/services/BAParticipantCompletionService.java	2011-12-09 15:36:55 UTC (rev 37789)
@@ -156,7 +156,7 @@
     @WebMethod(exclude = true)
     public void error()
     {
-        logEvent(org.jboss.narayana.txframework.api.annotation.lifecycle.wsba.Error.class);
+        logEvent(Error.class);
     }
 
     @Status



More information about the jboss-svn-commits mailing list