From 539dbfbe6766951a9e12105fd698e727703feb9c Mon Sep 17 00:00:00 2001 From: jakubs <jakubs> Date: Tue, 22 May 2012 11:15:10 +0000 Subject: [PATCH] SP-45, BIS-21 Call jython post-registration hook from recovery code SVN: 25330 --- ...tOmniscientTopLevelDataSetRegistrator.java | 4 +- ... => DataSetRegistrationPersistentMap.java} | 9 +- .../DataSetRegistrationService.java | 10 +- .../DataSetStorageAlgorithmRunner.java | 23 ++-- .../DataSetStoragePrecommitRecoveryState.java | 6 +- .../JythonTopLevelDataSetHandler.java | 51 ++++--- .../v1/IDataSetRegistrationTransaction.java | 4 +- .../impl/DataSetRegistrationTransaction.java | 18 ++- .../v2/JythonTopLevelDataSetHandlerV2.java | 124 +++++++++++++++--- 9 files changed, 180 insertions(+), 69 deletions(-) rename datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/{DataSetRegistrationContext.java => DataSetRegistrationPersistentMap.java} (87%) diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/AbstractOmniscientTopLevelDataSetRegistrator.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/AbstractOmniscientTopLevelDataSetRegistrator.java index 88561c438e3..605cb5e5b81 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/AbstractOmniscientTopLevelDataSetRegistrator.java +++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/AbstractOmniscientTopLevelDataSetRegistrator.java @@ -613,7 +613,7 @@ public abstract class AbstractOmniscientTopLevelDataSetRegistrator<T extends Dat * Subclasses can override and implement their own handling logic. */ public void didPreRegistration(DataSetRegistrationService<T> service, - DataSetRegistrationTransaction<T> transaction) + DataSetRegistrationPersistentMap.IHolder persistentMapHolder) { } @@ -623,7 +623,7 @@ public abstract class AbstractOmniscientTopLevelDataSetRegistrator<T extends Dat * Subclasses can override and implement their own handling logic. */ public void didPostRegistration(DataSetRegistrationService<T> service, - DataSetRegistrationTransaction<T> transaction) + DataSetRegistrationPersistentMap.IHolder persistentMapHolder) { } diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/DataSetRegistrationContext.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/DataSetRegistrationPersistentMap.java similarity index 87% rename from datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/DataSetRegistrationContext.java rename to datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/DataSetRegistrationPersistentMap.java index c80398f9f35..ec39af853e2 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/DataSetRegistrationContext.java +++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/DataSetRegistrationPersistentMap.java @@ -12,13 +12,18 @@ import java.util.Set; * * @author jakubs */ -public class DataSetRegistrationContext implements Serializable +public class DataSetRegistrationPersistentMap implements Serializable { + public static interface IHolder + { + DataSetRegistrationPersistentMap getPersistentMap(); + } + private static final long serialVersionUID = 1L; private HashMap<String, Serializable> persistentMap; - public DataSetRegistrationContext() + public DataSetRegistrationPersistentMap() { persistentMap = new HashMap<String, Serializable>(); } diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/DataSetRegistrationService.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/DataSetRegistrationService.java index 177a2be39a3..2eeb8c838fc 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/DataSetRegistrationService.java +++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/DataSetRegistrationService.java @@ -259,19 +259,19 @@ public class DataSetRegistrationService<T extends DataSetInformation> implements registrator.didRollbackTransaction(this, transaction, algorithm, ex); } - public void didCommitTransaction(DataSetRegistrationTransaction<T> transaction) + public void executePostCommit(DataSetRegistrationTransaction<T> transaction) { registrator.didCommitTransaction(this, transaction); } - public void executePreRegistration(DataSetRegistrationTransaction<T> transaction) + public void executePreRegistration(DataSetRegistrationPersistentMap.IHolder persistentMapHolder) { - registrator.didPreRegistration(this, transaction); + registrator.didPreRegistration(this, persistentMapHolder); } - public void executePostRegistration(DataSetRegistrationTransaction<T> transaction) + public void executePostRegistration(DataSetRegistrationPersistentMap.IHolder persistentMapHolder) { - registrator.didPostRegistration(this, transaction); + registrator.didPostRegistration(this, persistentMapHolder); } public void didEncounterSecondaryTransactionErrors( diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/DataSetStorageAlgorithmRunner.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/DataSetStorageAlgorithmRunner.java index e48c1bb7a04..a9105811583 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/DataSetStorageAlgorithmRunner.java +++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/DataSetStorageAlgorithmRunner.java @@ -66,9 +66,9 @@ public class DataSetStorageAlgorithmRunner<T extends DataSetInformation> public static interface IPrePostRegistrationHook<T extends DataSetInformation> { - public void executePreRegistration(DataSetRegistrationTransaction<T> transaction); + public void executePreRegistration(DataSetRegistrationPersistentMap.IHolder persistentMapHolder); - public void executePostRegistration(DataSetRegistrationTransaction<T> transaction); + public void executePostRegistration(DataSetRegistrationPersistentMap.IHolder persistentMapHolder); } static private final Logger operationLog = LogFactory.getLogger(LogCategory.OPERATION, @@ -89,8 +89,8 @@ public class DataSetStorageAlgorithmRunner<T extends DataSetInformation> private final IRollbackStack rollbackStack; - private final DataSetRegistrationTransaction<T> transaction; - + private final DataSetRegistrationPersistentMap.IHolder persistentMapHolder; + private final IPrePostRegistrationHook<T> postPreRegistrationHooks; private final DssRegistrationLogger dssRegistrationLog; @@ -113,7 +113,7 @@ public class DataSetStorageAlgorithmRunner<T extends DataSetInformation> new ArrayList<DataSetStorageAlgorithm<T>>(dataSetStorageAlgorithms); this.rollbackDelegate = transaction; this.applicationServerRegistrator = transaction; - this.transaction = transaction; + this.persistentMapHolder = transaction; this.rollbackStack = rollbackStack; this.dssRegistrationLog = dssRegistrationLog; this.openBISService = openBISService; @@ -130,13 +130,14 @@ public class DataSetStorageAlgorithmRunner<T extends DataSetInformation> IRollbackDelegate<T> rollbackDelegate, IRollbackStack rollbackStack, DssRegistrationLogger dssRegistrationLog, IEncapsulatedOpenBISService openBISService, IPrePostRegistrationHook<T> postPreRegistrationHooks, - IDataSetStorageRecoveryManager storageRecoveryManager) + IDataSetStorageRecoveryManager storageRecoveryManager, + DataSetRegistrationPersistentMap.IHolder persistentMapHolder) { this.dataSetStorageAlgorithms = new ArrayList<DataSetStorageAlgorithm<T>>(dataSetStorageAlgorithms); this.rollbackDelegate = rollbackDelegate; this.applicationServerRegistrator = null; - this.transaction = null; + this.persistentMapHolder = persistentMapHolder; this.rollbackStack = rollbackStack; this.dssRegistrationLog = dssRegistrationLog; this.openBISService = openBISService; @@ -249,7 +250,7 @@ public class DataSetStorageAlgorithmRunner<T extends DataSetInformation> { try { - postPreRegistrationHooks.executePreRegistration(transaction); + postPreRegistrationHooks.executePreRegistration(persistentMapHolder); } catch (Throwable throwable) { rollbackDuringPreRegistration(throwable); @@ -483,7 +484,7 @@ public class DataSetStorageAlgorithmRunner<T extends DataSetInformation> { try { - postPreRegistrationHooks.executePostRegistration(transaction); + postPreRegistrationHooks.executePostRegistration(persistentMapHolder); } catch (final Throwable throwable) { dssRegistrationLog.log("Post-registration action failed:"); @@ -562,8 +563,8 @@ public class DataSetStorageAlgorithmRunner<T extends DataSetInformation> return incomingDataSetFile; } - public DataSetRegistrationContext getPersistentMap() + public DataSetRegistrationPersistentMap getPersistentMap() { - return transaction.getTransactionPersistentMap(); + return persistentMapHolder.getPersistentMap(); } } diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/DataSetStoragePrecommitRecoveryState.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/DataSetStoragePrecommitRecoveryState.java index b4f5c95f6ca..91d1f0d122e 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/DataSetStoragePrecommitRecoveryState.java +++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/DataSetStoragePrecommitRecoveryState.java @@ -43,9 +43,9 @@ public class DataSetStoragePrecommitRecoveryState<T extends DataSetInformation> private final DataSetFile incomingDataSetFile; - private final DataSetRegistrationContext persistentMap; + private final DataSetRegistrationPersistentMap persistentMap; - public DataSetRegistrationContext getPersistentMap() + public DataSetRegistrationPersistentMap getPersistentMap() { return persistentMap; } @@ -53,7 +53,7 @@ public class DataSetStoragePrecommitRecoveryState<T extends DataSetInformation> public DataSetStoragePrecommitRecoveryState( List<DataSetStorageAlgorithm<T>> dataSetStorageAlgorithms, DssRegistrationLogger logger, IRollbackStack rollbackStack, DataSetFile incomingDataSetFile, - DataSetRegistrationContext persistentMap) + DataSetRegistrationPersistentMap persistentMap) { this.dataSetRecoveryStorageAlgorithms = new ArrayList<DataSetStoragePrecommitRecoveryAlgorithm<T>>(); 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 f1530488d62..ef133ae9a04 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 @@ -45,7 +45,7 @@ import ch.systemsx.cisd.openbis.dss.generic.shared.dto.DataSetInformation; public class JythonTopLevelDataSetHandler<T extends DataSetInformation> extends AbstractOmniscientTopLevelDataSetRegistrator<T> { - private enum JythonHookFunction + protected enum JythonHookFunction { /** * The name of the function to define to hook into the service rollback mechanism. @@ -129,7 +129,7 @@ public class JythonTopLevelDataSetHandler<T extends DataSetInformation> extends // The key for the script in the properties file public static final String SCRIPT_PATH_KEY = "script-path"; - private final File scriptFile; + protected final File scriptFile; /** * Constructor. @@ -176,7 +176,7 @@ public class JythonTopLevelDataSetHandler<T extends DataSetInformation> extends interpreter.exec(scriptString); executeJythonProcessFunction(service.interpreter); - + verifyEvaluatorHookFunctions(interpreter); } @@ -188,7 +188,7 @@ public class JythonTopLevelDataSetHandler<T extends DataSetInformation> extends } - private void verifyEvaluatorHookFunctions(PythonInterpreter interpreter) + protected void verifyEvaluatorHookFunctions(PythonInterpreter interpreter) { for (JythonHookFunction function : JythonHookFunction.values()) { @@ -290,18 +290,18 @@ public class JythonTopLevelDataSetHandler<T extends DataSetInformation> extends @Override public void didPreRegistration(DataSetRegistrationService<T> service, - DataSetRegistrationTransaction<T> transaction) + DataSetRegistrationPersistentMap.IHolder persistentMapHolder) { - super.didPreRegistration(service, transaction); - invokePreRegistrationFunction(service, transaction); + super.didPreRegistration(service, persistentMapHolder); + invokePreRegistrationFunction(service, persistentMapHolder); } @Override public void didPostRegistration(DataSetRegistrationService<T> service, - DataSetRegistrationTransaction<T> transaction) + DataSetRegistrationPersistentMap.IHolder persistentMapHolder) { - super.didPostRegistration(service, transaction); - invokePostRegistrationFunction(service, transaction); + super.didPostRegistration(service, persistentMapHolder); + invokePostRegistrationFunction(service, persistentMapHolder); } @Override @@ -408,7 +408,7 @@ public class JythonTopLevelDataSetHandler<T extends DataSetInformation> extends } private void invokePreRegistrationFunction(DataSetRegistrationService<T> service, - DataSetRegistrationTransaction<T> transaction) + DataSetRegistrationPersistentMap.IHolder persistentMapholder) { PythonInterpreter interpreter = getInterpreterFromService(service); PyFunction function = @@ -416,17 +416,17 @@ public class JythonTopLevelDataSetHandler<T extends DataSetInformation> extends if (null != function) { - invokeTransactionFunctionWithContext(function, service, transaction); + invokeTransactionFunctionWithContext(function, service, persistentMapholder); } } private void invokePostRegistrationFunction(DataSetRegistrationService<T> service, - DataSetRegistrationTransaction<T> transaction) + DataSetRegistrationPersistentMap.IHolder persistentMapHolder) { PyFunction function = tryGetPostRegistrationFunction(service); if (null != function) { - invokeTransactionFunctionWithContext(function, service, transaction); + invokeTransactionFunctionWithContext(function, service, persistentMapHolder); } } @@ -449,7 +449,7 @@ public class JythonTopLevelDataSetHandler<T extends DataSetInformation> extends } } - private PyFunction tryJythonFunction(PythonInterpreter interpreter, + protected PyFunction tryJythonFunction(PythonInterpreter interpreter, JythonHookFunction functionDefinition) { try @@ -482,16 +482,16 @@ public class JythonTopLevelDataSetHandler<T extends DataSetInformation> extends } private void invokeTransactionFunctionWithContext(PyFunction function, - DataSetRegistrationService<T> service, DataSetRegistrationTransaction<T> transaction, + DataSetRegistrationService<T> service, DataSetRegistrationPersistentMap.IHolder persistentMapHolder, Object... additionalArgs) { if (additionalArgs.length > 0) { - invokeFunction(service, function, transaction.getTransactionPersistentMap(), + invokeFunction(service, function, persistentMapHolder.getPersistentMap(), additionalArgs); } else { - invokeFunction(service, function, transaction.getTransactionPersistentMap()); + invokeFunction(service, function, persistentMapHolder.getPersistentMap()); } } @@ -502,6 +502,7 @@ public class JythonTopLevelDataSetHandler<T extends DataSetInformation> extends invokeFunction(service, function, service, transaction, secondaryErrors); } + //TODO: refactor tests to not use the service to test the hooks! /** * Turns all arguments into a python objects, and calls the specified function. Service is here * only for the tests, so that the tests can hook it @@ -517,6 +518,20 @@ public class JythonTopLevelDataSetHandler<T extends DataSetInformation> extends function.__call__(pyArgs); } + /** + * Turn all arguments into a python objects, and calls the specified + * function. Preferable way of calling functions. + */ + protected void invokeFunction(PyFunction function, Object... args) + { + PyObject[] pyArgs = new PyObject[args.length]; + for (int i = 0; i < args.length; i++) + { + pyArgs[i] = Py.java2py(args[i]); + } + function.__call__(pyArgs); + } + /** * Set the factory available to the python script. Subclasses may want to override. */ diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/IDataSetRegistrationTransaction.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/IDataSetRegistrationTransaction.java index 9f8ee8a087c..a59777ff138 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/IDataSetRegistrationTransaction.java +++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/IDataSetRegistrationTransaction.java @@ -18,7 +18,7 @@ package ch.systemsx.cisd.etlserver.registrator.api.v1; import net.lemnik.eodsql.DynamicTransactionQuery; -import ch.systemsx.cisd.etlserver.registrator.DataSetRegistrationContext; +import ch.systemsx.cisd.etlserver.registrator.DataSetRegistrationPersistentMap; import ch.systemsx.cisd.etlserver.registrator.AbstractOmniscientTopLevelDataSetRegistrator.OmniscientTopLevelDataSetRegistratorState; import ch.systemsx.cisd.openbis.dss.generic.shared.api.internal.v1.IDataSetImmutable; import ch.systemsx.cisd.openbis.dss.generic.shared.api.internal.v1.IExperimentImmutable; @@ -245,7 +245,7 @@ public interface IDataSetRegistrationTransaction * * @return The context, a hash-map-like object. */ - DataSetRegistrationContext getTransactionPersistentMap(); + DataSetRegistrationPersistentMap getPersistentMap(); /** * Returns the service registrator context. diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/DataSetRegistrationTransaction.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/DataSetRegistrationTransaction.java index 845fab10e0d..f5eb113b241 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/DataSetRegistrationTransaction.java +++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/DataSetRegistrationTransaction.java @@ -34,7 +34,7 @@ import ch.systemsx.cisd.etlserver.DssRegistrationLogger; import ch.systemsx.cisd.etlserver.registrator.AbstractOmniscientTopLevelDataSetRegistrator.OmniscientTopLevelDataSetRegistratorState; import ch.systemsx.cisd.etlserver.registrator.AutoRecoverySettings; import ch.systemsx.cisd.etlserver.registrator.DataSetFile; -import ch.systemsx.cisd.etlserver.registrator.DataSetRegistrationContext; +import ch.systemsx.cisd.etlserver.registrator.DataSetRegistrationPersistentMap; import ch.systemsx.cisd.etlserver.registrator.DataSetRegistrationDetails; import ch.systemsx.cisd.etlserver.registrator.DataSetRegistrationService; import ch.systemsx.cisd.etlserver.registrator.DataSetStorageAlgorithmRunner; @@ -85,7 +85,8 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SpaceIdentifier; */ public class DataSetRegistrationTransaction<T extends DataSetInformation> implements IDataSetRegistrationTransaction, DataSetStorageAlgorithmRunner.IRollbackDelegate<T>, - DataSetStorageAlgorithmRunner.IDataSetInApplicationServerRegistrator<T> + DataSetStorageAlgorithmRunner.IDataSetInApplicationServerRegistrator<T>, + DataSetRegistrationPersistentMap.IHolder { private static final String ROLLBACK_QUEUE1_FILE_NAME_SUFFIX = "rollBackQueue1"; @@ -186,7 +187,7 @@ public class DataSetRegistrationTransaction<T extends DataSetInformation> implem private AbstractTransactionState<T> state; - private DataSetRegistrationContext registrationContext; + private DataSetRegistrationPersistentMap registrationContext; // The registration service that owns this transaction private final DataSetRegistrationService<T> registrationService; @@ -215,7 +216,7 @@ public class DataSetRegistrationTransaction<T extends DataSetInformation> implem this.openBisService = this.registrationService.getRegistratorContext().getGlobalState() .getOpenBisService(); - this.registrationContext = new DataSetRegistrationContext(); + this.registrationContext = new DataSetRegistrationPersistentMap(); this.autoRecoverySettings = autoRecoverySettings; } @@ -375,7 +376,12 @@ public class DataSetRegistrationTransaction<T extends DataSetInformation> implem getStateAsLiveState().deleteFile(src); } - public DataSetRegistrationContext getTransactionPersistentMap() + /** + * Marked as deprecated, to prevent using this method directly. Instead it should only be used + * implicitly as an implementation of the persistent map holder interface. + */ + @Deprecated + public DataSetRegistrationPersistentMap getPersistentMap() { return registrationContext; } @@ -412,7 +418,7 @@ public class DataSetRegistrationTransaction<T extends DataSetInformation> implem { try { - registrationService.didCommitTransaction(this); + registrationService.executePostCommit(this); } catch (Throwable t) { DssRegistrationLogger dssRegistrationLog = registrationService.getDssRegistrationLog(); diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v2/JythonTopLevelDataSetHandlerV2.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v2/JythonTopLevelDataSetHandlerV2.java index 0d481e1450f..679b48da498 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v2/JythonTopLevelDataSetHandlerV2.java +++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v2/JythonTopLevelDataSetHandlerV2.java @@ -26,6 +26,8 @@ import org.python.core.PyFunction; import org.python.util.PythonInterpreter; import ch.systemsx.cisd.base.exceptions.CheckedExceptionTunnel; +import ch.systemsx.cisd.common.exceptions.NotImplementedException; +import ch.systemsx.cisd.common.filesystem.FileUtilities; import ch.systemsx.cisd.common.utilities.IDelegatedActionWithResult; import ch.systemsx.cisd.common.utilities.PythonUtils; import ch.systemsx.cisd.etlserver.DssRegistrationLogger; @@ -33,6 +35,7 @@ import ch.systemsx.cisd.etlserver.IStorageProcessorTransactional.UnstoreDataActi import ch.systemsx.cisd.etlserver.ITopLevelDataSetRegistratorDelegate; import ch.systemsx.cisd.etlserver.TopLevelDataSetRegistratorGlobalState; import ch.systemsx.cisd.etlserver.registrator.DataSetFile; +import ch.systemsx.cisd.etlserver.registrator.DataSetRegistrationPersistentMap; import ch.systemsx.cisd.etlserver.registrator.DataSetRegistrationService; import ch.systemsx.cisd.etlserver.registrator.DataSetStorageAlgorithmRunner; import ch.systemsx.cisd.etlserver.registrator.DataSetStorageAlgorithmRunner.IPrePostRegistrationHook; @@ -43,7 +46,6 @@ import ch.systemsx.cisd.etlserver.registrator.DataSetStorageRollbacker; import ch.systemsx.cisd.etlserver.registrator.IDataSetOnErrorActionDecision.ErrorType; import ch.systemsx.cisd.etlserver.registrator.MarkerFileUtility; import ch.systemsx.cisd.etlserver.registrator.api.v1.impl.AbstractTransactionState; -import ch.systemsx.cisd.etlserver.registrator.api.v1.impl.DataSetRegistrationTransaction; import ch.systemsx.cisd.etlserver.registrator.api.v1.impl.RollbackStack.IRollbackStackDelegate; import ch.systemsx.cisd.openbis.dss.generic.shared.dto.DataSetInformation; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData; @@ -106,9 +108,13 @@ public class JythonTopLevelDataSetHandlerV2<T extends DataSetInformation> extend PythonInterpreter interpreter) { interpreter.set(INCOMING_DATA_SET_VARIABLE_NAME, dataSetFile); - interpreter.set(TRANSACTION_VARIABLE_NAME, service.transaction()); interpreter.set(STATE_VARIABLE_NAME, getGlobalState()); - interpreter.set(FACTORY_VARIABLE_NAME, service.getDataSetRegistrationDetailsFactory()); + + if (service != null) + { + interpreter.set(TRANSACTION_VARIABLE_NAME, service.transaction()); + interpreter.set(FACTORY_VARIABLE_NAME, service.getDataSetRegistrationDetailsFactory()); + } } @Override @@ -266,7 +272,7 @@ public class JythonTopLevelDataSetHandlerV2<T extends DataSetInformation> extend return c.getTime().before(new Date()); } - private void handleRecoveryState(DataSetStoragePrecommitRecoveryState<T> recoveryState, + private void handleRecoveryState(final DataSetStoragePrecommitRecoveryState<T> recoveryState, final IDelegatedActionWithResult<Boolean> cleanAfterwardsAction, final IDelegatedActionWithResult<Boolean> recoveryMarkerCleanup) { @@ -295,7 +301,19 @@ public class JythonTopLevelDataSetHandlerV2<T extends DataSetInformation> extend }; // hookAdaptor - IPrePostRegistrationHook<T> hookAdaptor = createRecoveryHookAdaptor(); + RecoveryHookAdaptor hookAdaptor = + new RecoveryHookAdaptor(recoveryState.getIncomingDataSetFile() + .getLogicalIncomingFile()); + + DataSetRegistrationPersistentMap.IHolder persistentMapHolder = + new DataSetRegistrationPersistentMap.IHolder() + { + + public DataSetRegistrationPersistentMap getPersistentMap() + { + return recoveryState.getPersistentMap(); + } + }; DataSetStorageAlgorithmRunner<T> runner = new DataSetStorageAlgorithmRunner<T>(recoveryState.getIncomingDataSetFile(), // incoming @@ -305,7 +323,7 @@ public class JythonTopLevelDataSetHandlerV2<T extends DataSetInformation> extend logger, // registrationLogger state.getGlobalState().getOpenBisService(), // openBisService hookAdaptor, // the hooks - state.getGlobalState().getStorageRecoveryManager()); + state.getGlobalState().getStorageRecoveryManager(), persistentMapHolder); boolean registrationSuccessful = false; @@ -345,10 +363,9 @@ public class JythonTopLevelDataSetHandlerV2<T extends DataSetInformation> extend rollbacker.doRollback(logger); shouldDeleteRecoveryFiles = true; - // - // invokeRollbackTransactionFunction - // - // // rollback during metadata registration + + hookAdaptor.executePreRegistrationRollback(persistentMapHolder, null); + } else { operationLog @@ -357,6 +374,8 @@ public class JythonTopLevelDataSetHandlerV2<T extends DataSetInformation> extend logger.registerSuccess(); registrationSuccessful = true; + hookAdaptor.executePostStorage(persistentMapHolder); + shouldDeleteRecoveryFiles = true; } } catch (Throwable error) @@ -385,18 +404,83 @@ public class JythonTopLevelDataSetHandlerV2<T extends DataSetInformation> extend /** * Create an adaptor that offers access to the recovery hook functions. */ - protected IPrePostRegistrationHook<T> createRecoveryHookAdaptor() + protected class RecoveryHookAdaptor implements IPrePostRegistrationHook<T> { - IPrePostRegistrationHook<T> hookAdaptor = new IPrePostRegistrationHook<T>() + /** + * internally use only with getInterpreter + */ + private PythonInterpreter internalInterpreter; + + private final File incoming; + + public RecoveryHookAdaptor(File incoming) + { + this.incoming = incoming; + } + + private PythonInterpreter getInterpreter() + { + if (internalInterpreter == null) { - public void executePreRegistration(DataSetRegistrationTransaction<T> transaction) - { - } + internalInterpreter = PythonUtils.createIsolatedPythonInterpreter(); + // interpreter.execute script - public void executePostRegistration(DataSetRegistrationTransaction<T> transaction) - { - } - }; - return hookAdaptor; + configureEvaluator(incoming, null, internalInterpreter); + + // Load the script + String scriptString = FileUtilities.loadToString(scriptFile); + + // Invoke the evaluator + internalInterpreter.exec(scriptString); + + verifyEvaluatorHookFunctions(internalInterpreter); + } + return internalInterpreter; + } + + public void executePreRegistration( + DataSetRegistrationPersistentMap.IHolder persistentMapHolder) + { + throw new NotImplementedException("Recovery cannot execute pre-registration hook."); + } + + public void executePostRegistration( + DataSetRegistrationPersistentMap.IHolder persistentMapHolder) + { + PyFunction function = + tryJythonFunction(getInterpreter(), + JythonHookFunction.POST_REGISTRATION_FUNCTION_NAME); + if (function != null) + { + invokeFunction(function, persistentMapHolder.getPersistentMap()); + } + } + + /** + * This method does not belong to the IPrePostRegistrationHook interface. Is called directly + * by recovery. + */ + public void executePostStorage(DataSetRegistrationPersistentMap.IHolder persistentMapHolder) + { + PyFunction function = + tryJythonFunction(getInterpreter(), + JythonHookFunction.POST_STORAGE_FUNCTION_NAME); + if (function != null) + { + invokeFunction(function, persistentMapHolder.getPersistentMap()); + } + } + + public void executePreRegistrationRollback(DataSetRegistrationPersistentMap.IHolder persistentMapHolder, Throwable t) + { + PyFunction function = + tryJythonFunction(getInterpreter(), + JythonHookFunction.ROLLBACK_PRE_REGISTRATION_FUNCTION_NAME); + if (function != null) + { + invokeFunction(function, persistentMapHolder.getPersistentMap(), t); + } + } + } } -- GitLab