Author: lektran
Date: Sat Aug  9 09:00:39 2014
New Revision: 1616925

URL: http://svn.apache.org/r1616925
Log:
Replace the ServiceXaWrapper with a simpler Synchronization implementation.  
Helps pave the way for use of alternative transaction management libraries that 
don't work well with our XA wrapper implementations. Still DebugXaResource to 
go.

Added:
    
ofbiz/trunk/framework/service/src/org/ofbiz/service/ServiceSynchronization.java 
  (with props)
Modified:
    
ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/thirdparty/valuelink/ValueLinkServices.java
    ofbiz/trunk/framework/common/src/org/ofbiz/common/CommonServices.java
    
ofbiz/trunk/framework/service/src/org/ofbiz/service/GenericAbstractDispatcher.java
    ofbiz/trunk/framework/service/src/org/ofbiz/service/LocalDispatcher.java
    ofbiz/trunk/framework/service/src/org/ofbiz/service/ServiceXaWrapper.java
    
ofbiz/trunk/framework/service/src/org/ofbiz/service/eca/ServiceEcaAction.java

Modified: 
ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/thirdparty/valuelink/ValueLinkServices.java
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/thirdparty/valuelink/ValueLinkServices.java?rev=1616925&r1=1616924&r2=1616925&view=diff
==============================================================================
--- 
ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/thirdparty/valuelink/ValueLinkServices.java
 (original)
+++ 
ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/thirdparty/valuelink/ValueLinkServices.java
 Sat Aug  9 09:00:39 2014
@@ -24,8 +24,6 @@ import java.util.Locale;
 import java.util.Map;
 import java.util.Properties;
 
-import javax.transaction.xa.XAException;
-
 import javolution.util.FastMap;
 
 import org.ofbiz.base.util.Debug;
@@ -48,7 +46,6 @@ import org.ofbiz.service.GenericServiceE
 import org.ofbiz.service.LocalDispatcher;
 import org.ofbiz.service.ModelService;
 import org.ofbiz.service.ServiceUtil;
-import org.ofbiz.service.ServiceXaWrapper;
 
 /**
  * ValueLinkServices - Integration with ValueLink Gift Cards
@@ -792,13 +789,11 @@ public class ValueLinkServices {
         // Activate/Rollback is not supported by valuelink
         if (!vlInterface.equals("Activate")) {
             // create the listener
-            ServiceXaWrapper xaw = new ServiceXaWrapper(dctx);
-            xaw.setRollbackService("vlTimeOutReversal", context);
-            //xaw.setCommitService("vlTimeOutReversal", context);
             Debug.logInfo("Set 704 context : " + context, module);
             try {
-                xaw.enlist();
-            } catch (XAException e) {
+                dctx.getDispatcher().addRollbackService("vlTimeOutReversal", 
context, false);
+                //dctx.getDispatcher().addCommitService("vlTimeOutReversal", 
context, false);
+            } catch (GenericServiceException e) {
                 Debug.logError(e, "Unable to setup 0704 Timeout Reversal", 
module);
             }
         }
@@ -1214,14 +1209,10 @@ public class ValueLinkServices {
             }
 
             if (!failure) {
-                // set the void on rollback wrapper
-                ServiceXaWrapper xaw = new ServiceXaWrapper(dctx);
-                activateCtx.put("cardNumber", 
activateResult.get("cardNumber"));
-                activateCtx.put("pin", activateResult.get("pin"));
-                xaw.setRollbackService("voidActivateGiftCard", activateCtx);
+                // set the void on rollback
                 try {
-                    xaw.enlist();
-                } catch (XAException e) {
+                    dispatcher.addRollbackService("voidActivateGiftCard", 
activateCtx, false);
+                } catch (GenericServiceException e) {
                     Debug.logError(e, "Unable to setup Activate/Void on 
error", module);
                 }
             }

Modified: ofbiz/trunk/framework/common/src/org/ofbiz/common/CommonServices.java
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/framework/common/src/org/ofbiz/common/CommonServices.java?rev=1616925&r1=1616924&r2=1616925&view=diff
==============================================================================
--- ofbiz/trunk/framework/common/src/org/ofbiz/common/CommonServices.java 
(original)
+++ ofbiz/trunk/framework/common/src/org/ofbiz/common/CommonServices.java Sat 
Aug  9 09:00:39 2014
@@ -40,7 +40,6 @@ import java.util.Set;
 import java.util.TreeSet;
 
 import javax.mail.internet.MimeMessage;
-import javax.transaction.xa.XAException;
 
 import javolution.util.FastList;
 import javolution.util.FastMap;
@@ -65,8 +64,8 @@ import org.ofbiz.service.DispatchContext
 import org.ofbiz.service.GenericServiceException;
 import org.ofbiz.service.LocalDispatcher;
 import org.ofbiz.service.ModelService;
+import org.ofbiz.service.ServiceSynchronization;
 import org.ofbiz.service.ServiceUtil;
-import org.ofbiz.service.ServiceXaWrapper;
 import org.ofbiz.service.mail.MimeMessageWrapper;
 import org.owasp.esapi.errors.EncodingException;
 
@@ -142,23 +141,19 @@ public class CommonServices {
     }
 
     public static Map<String, Object> testRollbackListener(DispatchContext 
dctx, Map<String, ?> context) {
-        Locale locale = (Locale) context.get("locale");
-        ServiceXaWrapper xar = new ServiceXaWrapper(dctx);
-        xar.setRollbackService("testScv", context);
         try {
-            xar.enlist();
-        } catch (XAException e) {
+            ServiceSynchronization.registerRollbackService(dctx, "testScv", 
null, context, false, false);
+        } catch (GenericServiceException e) {
             Debug.logError(e, module);
         }
+        Locale locale = (Locale) context.get("locale");
         return ServiceUtil.returnError(UtilProperties.getMessage(resource, 
"CommonTestRollingBack", locale));
     }
 
     public static Map<String, Object> testCommitListener(DispatchContext dctx, 
Map<String, ?> context) {
-        ServiceXaWrapper xar = new ServiceXaWrapper(dctx);
-        xar.setCommitService("testScv", context);
         try {
-            xar.enlist();
-        } catch (XAException e) {
+            ServiceSynchronization.registerCommitService(dctx, "testScv", 
null, context, false, false);
+        } catch (GenericServiceException e) {
             Debug.logError(e, module);
         }
         return ServiceUtil.returnSuccess();

Modified: 
ofbiz/trunk/framework/service/src/org/ofbiz/service/GenericAbstractDispatcher.java
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/framework/service/src/org/ofbiz/service/GenericAbstractDispatcher.java?rev=1616925&r1=1616924&r2=1616925&view=diff
==============================================================================
--- 
ofbiz/trunk/framework/service/src/org/ofbiz/service/GenericAbstractDispatcher.java
 (original)
+++ 
ofbiz/trunk/framework/service/src/org/ofbiz/service/GenericAbstractDispatcher.java
 Sat Aug  9 09:00:39 2014
@@ -22,7 +22,6 @@ import java.util.Date;
 import java.util.Map;
 
 import javax.transaction.Transaction;
-import javax.transaction.xa.XAException;
 
 import org.ofbiz.service.calendar.RecurrenceRule;
 import org.ofbiz.entity.Delegator;
@@ -117,14 +116,7 @@ public abstract class GenericAbstractDis
     }
 
     public void addRollbackService(String serviceName, Map<String, ? extends 
Object> context, boolean persist) throws GenericServiceException {
-        ServiceXaWrapper xa = new ServiceXaWrapper(this.getDispatchContext());
-        xa.setRollbackService(serviceName, context, true, persist);
-        try {
-            xa.enlist();
-        } catch (XAException e) {
-            Debug.logError(e, module);
-            throw new GenericServiceException(e.getMessage(), e);
-        }
+        
ServiceSynchronization.registerRollbackService(this.getDispatchContext(), 
serviceName, null, context, true, persist);
     }
 
     public void addRollbackService(String serviceName, boolean persist, 
Object... context) throws GenericServiceException {
@@ -132,14 +124,7 @@ public abstract class GenericAbstractDis
     }
 
     public void addCommitService(String serviceName, Map<String, ? extends 
Object> context, boolean persist) throws GenericServiceException {
-        ServiceXaWrapper xa = new ServiceXaWrapper(this.getDispatchContext());
-        xa.setCommitService(serviceName, context, true, persist);
-        try {
-            xa.enlist();
-        } catch (XAException e) {
-            Debug.logError(e, module);
-            throw new GenericServiceException(e.getMessage(), e);
-        }
+        
ServiceSynchronization.registerCommitService(this.getDispatchContext(), 
serviceName, null, context, true, persist);
     }
 
     public void addCommitService(String serviceName, boolean persist, 
Object... context) throws GenericServiceException {

Modified: 
ofbiz/trunk/framework/service/src/org/ofbiz/service/LocalDispatcher.java
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/framework/service/src/org/ofbiz/service/LocalDispatcher.java?rev=1616925&r1=1616924&r2=1616925&view=diff
==============================================================================
--- ofbiz/trunk/framework/service/src/org/ofbiz/service/LocalDispatcher.java 
(original)
+++ ofbiz/trunk/framework/service/src/org/ofbiz/service/LocalDispatcher.java 
Sat Aug  9 09:00:39 2014
@@ -281,7 +281,7 @@ public interface LocalDispatcher {
 
 
     /**
-     * Adds a rollback service to the current TX using the ServiceXaWrapper
+     * Adds a rollback service to the current TX using ServiceSynchronization
      * @param serviceName
      * @param context
      * @param persist
@@ -291,7 +291,7 @@ public interface LocalDispatcher {
     public void addRollbackService(String serviceName, boolean persist, 
Object... context) throws GenericServiceException;
 
     /**
-     * Adds a commit service to the current TX using the ServiceXaWrapper
+     * Adds a commit service to the current TX using ServiceSynchronization
      * @param serviceName
      * @param context
      * @param persist

Added: 
ofbiz/trunk/framework/service/src/org/ofbiz/service/ServiceSynchronization.java
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/framework/service/src/org/ofbiz/service/ServiceSynchronization.java?rev=1616925&view=auto
==============================================================================
--- 
ofbiz/trunk/framework/service/src/org/ofbiz/service/ServiceSynchronization.java 
(added)
+++ 
ofbiz/trunk/framework/service/src/org/ofbiz/service/ServiceSynchronization.java 
Sat Aug  9 09:00:39 2014
@@ -0,0 +1,167 @@
+package org.ofbiz.service;
+
+import java.util.List;
+import java.util.Map;
+import java.util.WeakHashMap;
+
+import javax.transaction.RollbackException;
+import javax.transaction.Status;
+import javax.transaction.Synchronization;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+
+import javolution.util.FastList;
+import javolution.util.FastMap;
+
+import org.ofbiz.base.util.Debug;
+import org.ofbiz.entity.transaction.GenericTransactionException;
+import org.ofbiz.entity.transaction.TransactionFactory;
+import org.ofbiz.entity.transaction.TransactionUtil;
+
+/**
+ * This class is used to execute services when a transaction is either 
+ * committed or rolled back.  It should generally be accessed via
+ * LocalDispatcher's addCommitService and addRollbackService methods
+ * or by using the service ECA event attribute values global-commit,
+ * global-rollback or global-commit-post-run
+ *
+ */
+public class ServiceSynchronization implements Synchronization {
+
+    public static final String MODULE = ServiceSynchronization.class.getName();
+
+    private static Map<Transaction, ServiceSynchronization> syncingleton = new 
WeakHashMap<Transaction, ServiceSynchronization>();
+    private List<ServiceExecution> services = FastList.newInstance();
+
+    public static void registerCommitService(DispatchContext dctx, String 
serviceName, String runAsUser, Map<String, ? extends Object> context, boolean 
async, boolean persist) throws GenericServiceException {
+        ServiceSynchronization sync = ServiceSynchronization.getInstance();
+        if (sync != null) {
+            sync.services.add(new ServiceExecution(dctx, serviceName, 
runAsUser, context, async, persist, false));
+        }
+    }
+
+    public static void registerRollbackService(DispatchContext dctx, String 
serviceName, String runAsUser, Map<String, ? extends Object> context, boolean 
async, boolean persist) throws GenericServiceException {
+        ServiceSynchronization sync = ServiceSynchronization.getInstance();
+        if (sync != null) {
+            sync.services.add(new ServiceExecution(dctx, serviceName, 
runAsUser, context, async, persist, true));
+        }
+    }
+
+    protected static ServiceSynchronization getInstance() throws 
GenericServiceException {
+        ServiceSynchronization sync = null;
+        try {
+            Transaction transaction = 
TransactionFactory.getTransactionManager().getTransaction();
+            synchronized (transaction) {
+                sync = syncingleton.get(transaction);
+                if (sync == null) {
+                    sync = new ServiceSynchronization();
+                    transaction.registerSynchronization(sync);
+                    syncingleton.put(transaction, sync);
+                }
+            }
+        } catch (SystemException e) {
+            throw new GenericServiceException(e.getMessage(), e);
+        } catch (IllegalStateException e) {
+            throw new GenericServiceException(e.getMessage(), e);
+        } catch (RollbackException e) {
+            throw new GenericServiceException(e.getMessage(), e);
+        }
+        return sync;
+    }
+
+    @Override
+    public void afterCompletion(int status) {
+        for (ServiceExecution serviceExec : this.services) {
+            serviceExec.runService(status);
+        }
+    }
+
+    @Override
+    public void beforeCompletion() {
+
+    }
+
+    static class ServiceExecution {
+        protected DispatchContext dctx = null;
+        protected String serviceName;
+        protected String runAsUser = null;
+        protected Map<String, ? extends Object> context = null;
+        protected boolean rollback = false;
+        protected boolean persist = true;
+        protected boolean async = false;
+
+        ServiceExecution(DispatchContext dctx, String serviceName, String 
runAsUser, Map<String, ? extends Object> context, boolean async, boolean 
persist, boolean rollback) {
+            this.dctx = dctx;
+            this.serviceName = serviceName;
+            this.runAsUser = runAsUser;
+            this.context = context;
+            this.async = async;
+            this.persist = persist;
+            this.rollback = rollback;
+        }
+
+        protected void runService(int status) {
+            if ((status == Status.STATUS_COMMITTED && !rollback) || (status == 
Status.STATUS_ROLLEDBACK && rollback)) {
+                Thread thread = new Thread() {
+                    @Override
+                    public void run() {
+                        String msgPrefix = null;
+                        if (rollback) {
+                            msgPrefix = "[Rollback] ";
+                        } else {
+                            msgPrefix = "[Commit] ";
+                        }
+
+                        boolean beganTx;
+                        try {
+                            // begin the new tx
+                            beganTx = TransactionUtil.begin();
+                            // configure and run the service
+                            try {
+                                // obtain the model and get the valid context
+                                ModelService model = 
dctx.getModelService(serviceName);
+                                Map<String, Object> thisContext;
+                                if (model.validate) {
+                                    thisContext = model.makeValid(context, 
ModelService.IN_PARAM);
+                                } else {
+                                    thisContext = FastMap.newInstance();
+                                    thisContext.putAll(context);
+                                }
+
+                                // set the userLogin object
+                                thisContext.put("userLogin", 
ServiceUtil.getUserLogin(dctx, thisContext, runAsUser));
+                                if (async) {
+                                    if (Debug.infoOn()) 
Debug.logInfo(msgPrefix + "Invoking [" + serviceName + "] via runAsync", 
MODULE);
+                                    dctx.getDispatcher().runAsync(serviceName, 
thisContext, persist);
+                                } else {
+                                    if (Debug.infoOn()) 
Debug.logInfo(msgPrefix + "Invoking [" + serviceName + "] via runSyncIgnore", 
MODULE);
+                                    
dctx.getDispatcher().runSyncIgnore(serviceName, thisContext);
+                                }
+                            } catch (Throwable t) {
+                                Debug.logError(t, "Problem calling " + 
msgPrefix + "service : " + serviceName + " / " + context, MODULE);
+                                try {
+                                    TransactionUtil.rollback(beganTx, 
t.getMessage(), t);
+                                } catch (GenericTransactionException e) {
+                                    Debug.logError(e, MODULE);
+                                }
+
+                            } finally {
+                                // commit the transaction
+                                try {
+                                    TransactionUtil.commit(beganTx);
+                                } catch (GenericTransactionException e) {
+                                    Debug.logError(e, MODULE);
+                                }
+                            }
+                        } catch (GenericTransactionException e) {
+                            Debug.logError(e, MODULE);
+                        }
+
+                    }
+                };
+                thread.start();
+            }
+        }
+    }
+
+}

Propchange: 
ofbiz/trunk/framework/service/src/org/ofbiz/service/ServiceSynchronization.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
ofbiz/trunk/framework/service/src/org/ofbiz/service/ServiceSynchronization.java
------------------------------------------------------------------------------
    svn:keywords = "Date Rev Author URL Id"

Propchange: 
ofbiz/trunk/framework/service/src/org/ofbiz/service/ServiceSynchronization.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: 
ofbiz/trunk/framework/service/src/org/ofbiz/service/ServiceXaWrapper.java
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/framework/service/src/org/ofbiz/service/ServiceXaWrapper.java?rev=1616925&r1=1616924&r2=1616925&view=diff
==============================================================================
--- ofbiz/trunk/framework/service/src/org/ofbiz/service/ServiceXaWrapper.java 
(original)
+++ ofbiz/trunk/framework/service/src/org/ofbiz/service/ServiceXaWrapper.java 
Sat Aug  9 09:00:39 2014
@@ -34,7 +34,9 @@ import org.ofbiz.entity.transaction.Tran
 
 /**
  * ServiceXaWrapper - XA Resource wrapper for running services on commit() or 
rollback()
+ * @deprecated - Use ServiceSynchronization instead (via LocalDispatcher)
  */
+@Deprecated
 public class ServiceXaWrapper extends GenericXaResource {
 
     public static final String module = ServiceXaWrapper.class.getName();

Modified: 
ofbiz/trunk/framework/service/src/org/ofbiz/service/eca/ServiceEcaAction.java
URL: 
http://svn.apache.org/viewvc/ofbiz/trunk/framework/service/src/org/ofbiz/service/eca/ServiceEcaAction.java?rev=1616925&r1=1616924&r2=1616925&view=diff
==============================================================================
--- 
ofbiz/trunk/framework/service/src/org/ofbiz/service/eca/ServiceEcaAction.java 
(original)
+++ 
ofbiz/trunk/framework/service/src/org/ofbiz/service/eca/ServiceEcaAction.java 
Sat Aug  9 09:00:39 2014
@@ -22,8 +22,6 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 
-import javax.transaction.xa.XAException;
-
 import javolution.util.FastMap;
 
 import org.ofbiz.base.util.Debug;
@@ -33,8 +31,8 @@ import org.ofbiz.service.DispatchContext
 import org.ofbiz.service.GenericServiceException;
 import org.ofbiz.service.LocalDispatcher;
 import org.ofbiz.service.ModelService;
+import org.ofbiz.service.ServiceSynchronization;
 import org.ofbiz.service.ServiceUtil;
-import org.ofbiz.service.ServiceXaWrapper;
 import org.w3c.dom.Element;
 
 /**
@@ -115,19 +113,12 @@ public class ServiceEcaAction implements
         }
 
         if (eventName.startsWith("global-")) {
-            // XA resource ECA
-            ServiceXaWrapper xaw = new ServiceXaWrapper(dctx);
             if (eventName.equals("global-rollback")) {
-                xaw.setRollbackService(serviceName, runAsUser, context, 
"async".equals(serviceMode), persist); // using the actual context so we get 
updates
+                ServiceSynchronization.registerRollbackService(dctx, 
serviceName, runAsUser, context, "async".equals(serviceMode), persist); // 
using the actual context so we get updates
             } else if (eventName.equals("global-commit")) {
-                xaw.setCommitService(serviceName, runAsUser, context, 
"async".equals(serviceMode), persist);   // using the actual context so we get 
updates
+                ServiceSynchronization.registerCommitService(dctx, 
serviceName, runAsUser, context, "async".equals(serviceMode), persist); // 
using the actual context so we get updates
             } else if (eventName.equals("global-commit-post-run")) {
-                xaw.setCommitService(serviceName, runAsUser, context, 
"async".equals(serviceMode), persist);   // using the actual context so we get 
updates
-            }
-            try {
-                xaw.enlist();
-            } catch (XAException e) {
-                throw new GenericServiceException("Unable to enlist 
ServiceXaWrapper with transaction", e);
+                ServiceSynchronization.registerCommitService(dctx, 
serviceName, runAsUser, context, "async".equals(serviceMode), persist); // 
using the actual context so we get updates
             }
         } else {
             // standard ECA


Reply via email to