From a16b76d7c19d626b0bc2108f223bfe5899ea4d8c Mon Sep 17 00:00:00 2001
From: jakubs <jakubs>
Date: Tue, 15 May 2012 16:07:42 +0000
Subject: [PATCH] SP-45, BIS-21 add new hook for transaction rollback in jython
 v2 dropboxes

SVN: 25263
---
 .../JythonTopLevelDataSetHandler.java         | 42 +++++++++++++++----
 .../JythonTopLevelDataSetRegistratorTest.java |  9 ++--
 .../TestingDataSetHandlerExpectations.java    |  6 ++-
 .../cisd/etlserver/registrator/all-hooks.py   |  4 ++
 4 files changed, 49 insertions(+), 12 deletions(-)

diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/JythonTopLevelDataSetHandler.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/JythonTopLevelDataSetHandler.java
index 8cdf1a25e98..379e6ff5fb3 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/JythonTopLevelDataSetHandler.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/JythonTopLevelDataSetHandler.java
@@ -79,6 +79,11 @@ public class JythonTopLevelDataSetHandler<T extends DataSetInformation> extends
          */
         POST_REGISTRATION_FUNCTION_NAME("post_metadata_registration", 1),
 
+        /**
+         * The name of the function to define to hook into the transaction rollback mechanism.
+         */
+        ROLLBACK_PRE_REGISTRATION_FUNCTION_NAME("rollback_pre_registration", 2),
+
         /**
          * The name of the function called when secondary transactions, DynamicTransactionQuery
          * objects, fail.
@@ -313,22 +318,35 @@ public class JythonTopLevelDataSetHandler<T extends DataSetInformation> extends
             DataSetStorageAlgorithmRunner<T> algorithmRunner, Throwable ex)
     {
         PythonInterpreter interpreter = getInterpreterFromService(service);
+
         PyFunction function =
                 tryJythonFunction(interpreter,
-                        JythonHookFunction.ROLLBACK_TRANSACTION_FUNCTION_NAME);
+                        JythonHookFunction.ROLLBACK_PRE_REGISTRATION_FUNCTION_NAME);
+
         if (null != function)
         {
-            invokeRollbackTransactionFunction(function, service, transaction, algorithmRunner, ex);
+            invokeTransactionFunctionWithContext(function, service, transaction, ex);
         } else if (shouldUseOldJythonHookFunctions())
         {
-            // No Rollback transaction function was called, see if the rollback service function was
-            // defined, and call it.
             function =
                     tryJythonFunction(interpreter,
-                            JythonHookFunction.ROLLBACK_SERVICE_FUNCTION_NAME);
+                            JythonHookFunction.ROLLBACK_TRANSACTION_FUNCTION_NAME);
             if (null != function)
             {
-                invokeRollbackServiceFunction(function, service, ex);
+                invokeRollbackTransactionFunction(function, service, transaction, algorithmRunner,
+                        ex);
+            } else
+            {
+                // No Rollback transaction function was called, see if the rollback service function
+                // was
+                // defined, and call it.
+                function =
+                        tryJythonFunction(interpreter,
+                                JythonHookFunction.ROLLBACK_SERVICE_FUNCTION_NAME);
+                if (null != function)
+                {
+                    invokeRollbackServiceFunction(function, service, ex);
+                }
             }
         }
     }
@@ -432,9 +450,17 @@ public class JythonTopLevelDataSetHandler<T extends DataSetInformation> extends
     }
 
     private void invokeTransactionFunctionWithContext(PyFunction function,
-            DataSetRegistrationService<T> service, DataSetRegistrationTransaction<T> transaction)
+            DataSetRegistrationService<T> service, DataSetRegistrationTransaction<T> transaction,
+            Object... additionalArgs)
     {
-        invokeFuncion(service, function, transaction.getTransactionPersistentMap());
+        if (additionalArgs.length > 0)
+        {
+            invokeFuncion(service, function, transaction.getTransactionPersistentMap(),
+                    additionalArgs);
+        } else
+        {
+            invokeFuncion(service, function, transaction.getTransactionPersistentMap());
+        }
     }
 
     private void invokeDidEncounterSecondaryTransactionErrorsFunction(PyFunction function,
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/JythonTopLevelDataSetRegistratorTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/JythonTopLevelDataSetRegistratorTest.java
index 179d550299d..f5adff2df4c 100644
--- a/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/JythonTopLevelDataSetRegistratorTest.java
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/JythonTopLevelDataSetRegistratorTest.java
@@ -643,9 +643,10 @@ public class JythonTopLevelDataSetRegistratorTest extends AbstractJythonDataSetH
                 Throwable t = isErrorCausedByUnexpectedInvocation(exception);
                 if (t != null)
                 {
-                    throw new RuntimeException("Extracted unexpected invocation error "+t.getMessage(), t);
+                    throw new RuntimeException("Extracted unexpected invocation error "
+                            + t.getMessage(), t);
                 }
-                
+
                 if (testCase.exceptionAcceptor != null)
                 {
                     assertTrue("Exception " + exception + "was not accepted by validator",
@@ -797,6 +798,7 @@ public class JythonTopLevelDataSetRegistratorTest extends AbstractJythonDataSetH
         } else if (testCase.failurePoint
                 .compareTo(TestCaseParameters.FailurePoint.DURING_VALIDATION) <= 0)
         {
+            assertFalse(handler.getExpectations().didPreRegistrationRollbackHappen);
             assertFalse(handler.getExpectations().didRollbackServiceFunctionRun);
             assertFalse(handler.getExpectations().didTransactionRollbackHappen);
             assertFalse(handler.getExpectations().didRollbackTransactionFunctionRunHappen);
@@ -809,8 +811,9 @@ public class JythonTopLevelDataSetRegistratorTest extends AbstractJythonDataSetH
         } else
         {
             assertFalse(handler.getExpectations().didRollbackServiceFunctionRun);
+            assertTrue(handler.getExpectations().didPreRegistrationRollbackHappen);
+            assertFalse(handler.getExpectations().didRollbackTransactionFunctionRunHappen);
             assertTrue(handler.getExpectations().didTransactionRollbackHappen);
-            assertTrue(handler.getExpectations().didRollbackTransactionFunctionRunHappen);
 
             assertTrue(handler.getExpectations().didPreRegistrationFunctionRunHappen);
             assertFalse(handler.getExpectations().didPostRegistrationFunctionRunHappen);
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/TestingDataSetHandlerExpectations.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/TestingDataSetHandlerExpectations.java
index db95b9773b7..0c9194e2b0d 100644
--- a/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/TestingDataSetHandlerExpectations.java
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/TestingDataSetHandlerExpectations.java
@@ -36,10 +36,11 @@ public class TestingDataSetHandlerExpectations
 
     protected boolean didServiceRollbackHappen = false;
 
+    protected boolean didPreRegistrationRollbackHappen = false;
+    
     protected String registrationContextError;
 
     
-    
     public boolean isShouldRegistrationFail()
     {
         return shouldRegistrationFail;
@@ -88,6 +89,9 @@ public class TestingDataSetHandlerExpectations
                 readBoolean(interpreter, "didPostStorageFunctionRunHappen");
         didSecondaryTransactionErrorNotificationHappen =
                 readBoolean(interpreter, "didSecondaryTransactionErrorNotificationHappen");
+        didPreRegistrationRollbackHappen =
+                readBoolean(interpreter, "didPreRegistrationRollbackHappen");
+        
 
         registrationContextError = interpreter.get("contextTestFailed", String.class);
     }
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/all-hooks.py b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/all-hooks.py
index 97cddf7a1ae..330495c24cf 100644
--- a/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/all-hooks.py
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/all-hooks.py
@@ -2,6 +2,10 @@ def rollback_transaction(service, transaction, algorithmRunner, throwable):
     global didTransactionRollbackHappen
     didTransactionRollbackHappen = True
 
+def rollback_pre_registration(context, throwable):
+    global didPreRegistrationRollbackHappen
+    didPreRegistrationRollbackHappen = True
+
 def commit_transaction(service, transaction):
     global didTransactionCommitHappen
     didTransactionCommitHappen = True
-- 
GitLab