From c6e32cba30a16d3146736edeb45c86a4b23385a7 Mon Sep 17 00:00:00 2001 From: cramakri <cramakri> Date: Tue, 8 Feb 2011 15:34:03 +0000 Subject: [PATCH] LMS-2033 Introduced generic types to the OmniscientDataSetHandler hierarchy. SVN: 19814 --- ...ractDataSetRegistrationDetailsFactory.java | 68 ++++++++ ...tOmniscientTopLevelDataSetRegistrator.java | 23 +-- .../DataSetRegistrationService.java | 150 ++++++++++-------- ...aultDataSetRegistrationDetailsFactory.java | 44 +++++ .../DefaultEntityRegistrationService.java | 5 +- .../JythonTopLevelDataSetHandler.java | 122 +++++++------- .../api/v1/impl/AbstractTransactionState.java | 6 +- .../impl/DataSetRegistrationTransaction.java | 9 +- .../JythonTopLevelDataSetRegistratorTest.java | 20 ++- .../DataSetRegistrationTransactionTest.java | 13 +- 10 files changed, 307 insertions(+), 153 deletions(-) create mode 100644 datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/AbstractDataSetRegistrationDetailsFactory.java create mode 100644 datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/DefaultDataSetRegistrationDetailsFactory.java diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/AbstractDataSetRegistrationDetailsFactory.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/AbstractDataSetRegistrationDetailsFactory.java new file mode 100644 index 00000000000..0c2118e51e0 --- /dev/null +++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/AbstractDataSetRegistrationDetailsFactory.java @@ -0,0 +1,68 @@ +/* + * Copyright 2011 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.etlserver.registrator; + +import java.io.File; + +import ch.systemsx.cisd.etlserver.registrator.AbstractOmniscientTopLevelDataSetRegistrator.OmniscientTopLevelDataSetRegistratorState; +import ch.systemsx.cisd.etlserver.registrator.api.v1.impl.DataSet; +import ch.systemsx.cisd.openbis.dss.generic.shared.dto.DataSetInformation; + +/** + * @author Chandrasekhar Ramakrishnan + */ +public abstract class AbstractDataSetRegistrationDetailsFactory<T extends DataSetInformation> + implements IDataSetRegistrationDetailsFactory<T> +{ + protected final OmniscientTopLevelDataSetRegistratorState registratorState; + + public AbstractDataSetRegistrationDetailsFactory( + OmniscientTopLevelDataSetRegistratorState registratorState) + { + this.registratorState = registratorState; + } + + /** + * Factory method that creates a new registration details object. + */ + public DataSetRegistrationDetails<T> createDataSetRegistrationDetails() + { + DataSetRegistrationDetails<T> registrationDetails = new DataSetRegistrationDetails<T>(); + T dataSetInfo = createDataSetInformation(); + setDatabaseInstance(dataSetInfo); + registrationDetails.setDataSetInformation(dataSetInfo); + return registrationDetails; + } + + protected final void setDatabaseInstance(T dataSetInfo) + { + dataSetInfo.setInstanceCode(registratorState.getHomeDatabaseInstance().getCode()); + dataSetInfo.setInstanceUUID(registratorState.getHomeDatabaseInstance().getUuid()); + } + + public DataSet<T> createDataSet(DataSetRegistrationDetails<T> registrationDetails, + File stagingFile) + { + return new DataSet<T>(registrationDetails, stagingFile); + } + + /** + * Factory method that creates a new data set information object. + */ + protected abstract T createDataSetInformation(); + +} 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 e43308aa606..9a452c0525f 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 @@ -55,8 +55,8 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.NewExternalData; * * @author Chandrasekhar Ramakrishnan */ -public abstract class AbstractOmniscientTopLevelDataSetRegistrator extends - AbstractTopLevelDataSetRegistrator +public abstract class AbstractOmniscientTopLevelDataSetRegistrator<T extends DataSetInformation> + extends AbstractTopLevelDataSetRegistrator { static final Logger notificationLog = LogFactory.getLogger(LogCategory.NOTIFY, AbstractOmniscientTopLevelDataSetRegistrator.class); @@ -234,7 +234,7 @@ public abstract class AbstractOmniscientTopLevelDataSetRegistrator extends }; } - DataSetRegistrationService service = + DataSetRegistrationService<T> service = createDataSetRegistrationService(cleanAfterwardsAction); try @@ -273,7 +273,7 @@ public abstract class AbstractOmniscientTopLevelDataSetRegistrator extends * * @param dataSetRegistrationService */ - public void rollback(DataSetRegistrationService dataSetRegistrationService, + public void rollback(DataSetRegistrationService<T> dataSetRegistrationService, DataSetRegistrationAlgorithm registrationAlgorithm, Throwable throwable) { updateStopped(throwable instanceof InterruptedExceptionUnchecked); @@ -289,8 +289,7 @@ public abstract class AbstractOmniscientTopLevelDataSetRegistrator extends * Subclasses may override, but should call super. */ - public <T extends DataSetInformation> void rollbackTransaction( - DataSetRegistrationService dataSetRegistrationService, + public void rollbackTransaction(DataSetRegistrationService<T> dataSetRegistrationService, DataSetRegistrationTransaction<T> transaction, DataSetStorageAlgorithmRunner<T> algorithm, Throwable ex) { @@ -303,7 +302,7 @@ public abstract class AbstractOmniscientTopLevelDataSetRegistrator extends * <p> * Subclasses may override, but should call super. */ - protected void rollback(DataSetRegistrationService service, Throwable throwable) + protected void rollback(DataSetRegistrationService<T> service, Throwable throwable) { updateStopped(throwable instanceof InterruptedExceptionUnchecked); @@ -313,11 +312,13 @@ public abstract class AbstractOmniscientTopLevelDataSetRegistrator extends /** * Create the data set registration service. */ - protected DataSetRegistrationService createDataSetRegistrationService( + protected DataSetRegistrationService<T> createDataSetRegistrationService( final IDelegatedActionWithResult<Boolean> cleanAfterwardsAction) { - DataSetRegistrationService service = - new DataSetRegistrationService(this, cleanAfterwardsAction); + @SuppressWarnings("unchecked") + DataSetRegistrationService<T> service = + new DataSetRegistrationService(this, new DefaultDataSetRegistrationDetailsFactory( + getRegistratorState()), cleanAfterwardsAction); return service; } @@ -345,6 +346,6 @@ public abstract class AbstractOmniscientTopLevelDataSetRegistrator extends * * @throws Throwable */ - protected abstract void handleDataSet(File dataSetFile, DataSetRegistrationService service) + protected abstract void handleDataSet(File dataSetFile, DataSetRegistrationService<T> service) throws Throwable; } 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 3e583a04c8f..a39b9632cf5 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 @@ -24,8 +24,6 @@ import ch.systemsx.cisd.common.utilities.IDelegatedActionWithResult; import ch.systemsx.cisd.common.utilities.PropertyUtils; import ch.systemsx.cisd.etlserver.DataSetRegistrationAlgorithm; import ch.systemsx.cisd.etlserver.DataSetRegistrationAlgorithm.DataSetRegistrationAlgorithmState; -import ch.systemsx.cisd.etlserver.DataSetRegistrationAlgorithm.IDataSetInApplicationServerRegistrator; -import ch.systemsx.cisd.etlserver.DataSetRegistrationAlgorithm.IRollbackDelegate; import ch.systemsx.cisd.etlserver.DataSetRegistrationAlgorithmRunner; import ch.systemsx.cisd.etlserver.IDataStoreStrategy; import ch.systemsx.cisd.etlserver.TopLevelDataSetRegistratorGlobalState; @@ -40,23 +38,28 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.NewExternalData; * * @author Chandrasekhar Ramakrishnan */ -public class DataSetRegistrationService implements IRollbackDelegate +public class DataSetRegistrationService<T extends DataSetInformation> implements + DataSetRegistrationAlgorithm.IRollbackDelegate { static final String STAGING_DIR = "staging-dir"; - private final AbstractOmniscientTopLevelDataSetRegistrator registrator; + private final AbstractOmniscientTopLevelDataSetRegistrator<T> registrator; - private final OmniscientTopLevelDataSetRegistratorState registratorState; + private final OmniscientTopLevelDataSetRegistratorState registratorContext; private final IDelegatedActionWithResult<Boolean> globalCleanAfterwardsAction; private final ArrayList<DataSetRegistrationAlgorithm> dataSetRegistrations = new ArrayList<DataSetRegistrationAlgorithm>(); + private final IDataSetRegistrationDetailsFactory<T> dataSetRegistrationDetailsFactory; + + private final File stagingDirectory; + /** * The currently live child transaction. */ - private DataSetRegistrationTransaction<DataSetInformation> liveTransactionOrNull; + private DataSetRegistrationTransaction<T> liveTransactionOrNull; /** * A data set that will be created but might not yet exist. @@ -84,24 +87,37 @@ public class DataSetRegistrationService implements IRollbackDelegate * @param registrator The top level data set registrator * @param globalCleanAfterwardsAction An action to execute when the service has finished */ - public DataSetRegistrationService(AbstractOmniscientTopLevelDataSetRegistrator registrator, + public DataSetRegistrationService(AbstractOmniscientTopLevelDataSetRegistrator<T> registrator, + IDataSetRegistrationDetailsFactory<T> registrationDetailsFactory, IDelegatedActionWithResult<Boolean> globalCleanAfterwardsAction) { this.registrator = registrator; - this.registratorState = registrator.getRegistratorState(); + this.registratorContext = registrator.getRegistratorState(); this.globalCleanAfterwardsAction = globalCleanAfterwardsAction; + this.dataSetRegistrationDetailsFactory = registrationDetailsFactory; + + Properties properties = + registratorContext.getGlobalState().getThreadParameters().getThreadProperties(); + String stagingDirString = PropertyUtils.getProperty(properties, STAGING_DIR); + if (null == stagingDirString) + { + stagingDirectory = registratorContext.getGlobalState().getStoreRootDir(); + } else + { + stagingDirectory = new File(stagingDirString); + } } - public OmniscientTopLevelDataSetRegistratorState getRegistratorState() + public OmniscientTopLevelDataSetRegistratorState getRegistratorContext() { - return registratorState; + return registratorContext; } /** * Queue registration a data set and return a future for the data set that will be created. */ public FutureDataSet queueDataSetRegistration(File dataSetFile, - DataSetRegistrationDetails<?> details) + final DataSetRegistrationDetails<T> details) { DataSetRegistrationAlgorithm registration = createRegistrationAlgorithm(dataSetFile, details); @@ -112,24 +128,33 @@ public class DataSetRegistrationService implements IRollbackDelegate return future; } + /** + * Create a new transaction that atomically performs file operations and registers entities. + */ + public IDataSetRegistrationTransaction transaction(File dataSetFile) + { + return transaction(dataSetFile, getDataSetRegistrationDetailsFactory()); + } + + protected IDataSetRegistrationDetailsFactory<T> getDataSetRegistrationDetailsFactory() + { + return dataSetRegistrationDetailsFactory; + } + /** * Create a new transaction that atomically performs file operations and registers entities. */ public IDataSetRegistrationTransaction transaction(File dataSetFile, - IDataSetRegistrationDetailsFactory<DataSetInformation> detailsFactory) + IDataSetRegistrationDetailsFactory<T> detailsFactory) { // If a transaction is hanging around, commit it before starting a new one commitExtantTransaction(); File workingDirectory = dataSetFile.getParentFile(); - Properties properties = - registratorState.getGlobalState().getThreadParameters().getThreadProperties(); - File stagingDirectory = - new File(PropertyUtils.getMandatoryProperty(properties, STAGING_DIR)); // Clone this service for the transaction to keep them independent liveTransactionOrNull = - new DataSetRegistrationTransaction<DataSetInformation>(registrator.getGlobalState() + new DataSetRegistrationTransaction<T>(registrator.getGlobalState() .getStoreRootDir(), workingDirectory, stagingDirectory, this, detailsFactory); @@ -160,13 +185,7 @@ public class DataSetRegistrationService implements IRollbackDelegate dataSetRegistrations.clear(); } - public void rollback(DataSetRegistrationAlgorithm algorithm, Throwable ex) - { - registrator.rollback(this, algorithm, ex); - } - - public <T extends DataSetInformation> void rollbackTransaction( - DataSetRegistrationTransaction<T> transaction, + public void rollbackTransaction(DataSetRegistrationTransaction<T> transaction, DataSetStorageAlgorithmRunner<T> algorithm, Throwable ex) { registrator.rollbackTransaction(this, transaction, algorithm, ex); @@ -176,31 +195,53 @@ public class DataSetRegistrationService implements IRollbackDelegate * Create a storage algorithm for storing an individual data set. This is internally used by * transactions. Other clients may find it useful as well. */ - public <T extends DataSetInformation> DataSetStorageAlgorithm<T> createStorageAlgorithm( - File dataSetFile, DataSetRegistrationDetails<T> dataSetDetails) + public DataSetStorageAlgorithm<T> createStorageAlgorithm(File dataSetFile, + DataSetRegistrationDetails<T> dataSetDetails) { IDataStoreStrategy strategy = - registratorState.getDataStrategyStore().getDataStoreStrategy( + registratorContext.getDataStrategyStore().getDataStoreStrategy( dataSetDetails.getDataSetInformation(), dataSetFile); - TopLevelDataSetRegistratorGlobalState globalContext = registratorState.getGlobalState(); + TopLevelDataSetRegistratorGlobalState globalContext = registratorContext.getGlobalState(); DataSetStorageAlgorithm<T> algorithm = new DataSetStorageAlgorithm<T>(dataSetFile, dataSetDetails, strategy, - registratorState.getStorageProcessor(), + registratorContext.getStorageProcessor(), globalContext.getDataSetValidator(), globalContext.getDssCode(), - registratorState.getFileOperations(), globalContext.getMailClient()); + registratorContext.getFileOperations(), globalContext.getMailClient()); return algorithm; } - public <T extends DataSetInformation> IEntityRegistrationService<T> getEntityRegistrationService() + public IEntityRegistrationService<T> getEntityRegistrationService() { return new DefaultEntityRegistrationService<T>(registrator); } + /** + * If a transaction is hanging around, commit it + */ + private void commitExtantTransaction() + { + if (null != liveTransactionOrNull + && false == liveTransactionOrNull.isCommittedOrRolledback()) + { + // Commit the existing transaction + liveTransactionOrNull.commit(); + } + } + + private void rollbackExtantTransaction() + { + if (null != liveTransactionOrNull) + { + liveTransactionOrNull.rollback(); + } + } + private DataSetRegistrationAlgorithm createRegistrationAlgorithm(File incomingDataSetFile, - DataSetRegistrationDetails<?> details) + DataSetRegistrationDetails<T> details) { - final TopLevelDataSetRegistratorGlobalState globalState = registratorState.getGlobalState(); + final TopLevelDataSetRegistratorGlobalState globalState = + registratorContext.getGlobalState(); final IDelegatedActionWithResult<Boolean> cleanAfterwardsAction = new IDelegatedActionWithResult<Boolean>() { @@ -211,55 +252,34 @@ public class DataSetRegistrationService implements IRollbackDelegate }; IDataStoreStrategy dataStoreStrategy = - registratorState.getDataStrategyStore().getDataStoreStrategy( + registratorContext.getDataStrategyStore().getDataStoreStrategy( details.getDataSetInformation(), incomingDataSetFile); DataSetRegistrationAlgorithmState state = new DataSetRegistrationAlgorithmState(incomingDataSetFile, globalState.getOpenBisService(), cleanAfterwardsAction, - registratorState.getPreRegistrationAction(), - registratorState.getPostRegistrationAction(), + registratorContext.getPreRegistrationAction(), + registratorContext.getPostRegistrationAction(), details.getDataSetInformation(), dataStoreStrategy, details, - registratorState.getStorageProcessor(), - registratorState.getFileOperations(), globalState.getDataSetValidator(), + registratorContext.getStorageProcessor(), + registratorContext.getFileOperations(), globalState.getDataSetValidator(), globalState.getMailClient(), globalState.isDeleteUnidentified(), - registratorState.getRegistrationLock(), globalState.getDssCode(), + registratorContext.getRegistrationLock(), globalState.getDssCode(), globalState.isNotifySuccessfulRegistration()); return new DataSetRegistrationAlgorithm(state, this, new DefaultApplicationServerRegistrator(registrator, details.getDataSetInformation())); } - /** - * If a transaction is hanging around, commit it - */ - private void commitExtantTransaction() - { - if (null != liveTransactionOrNull - && false == liveTransactionOrNull.isCommittedOrRolledback()) - { - // Commit the existing transaction - liveTransactionOrNull.commit(); - } - } - - private void rollbackExtantTransaction() - { - if (null != liveTransactionOrNull) - { - liveTransactionOrNull.rollback(); - } - } - private static class DefaultApplicationServerRegistrator implements - IDataSetInApplicationServerRegistrator + DataSetRegistrationAlgorithm.IDataSetInApplicationServerRegistrator { - private final AbstractOmniscientTopLevelDataSetRegistrator registrator; + private final AbstractOmniscientTopLevelDataSetRegistrator<?> registrator; private final DataSetInformation dataSetInformation; DefaultApplicationServerRegistrator( - AbstractOmniscientTopLevelDataSetRegistrator registrator, + AbstractOmniscientTopLevelDataSetRegistrator<?> registrator, DataSetInformation dataSetInformation) { this.dataSetInformation = dataSetInformation; @@ -272,4 +292,8 @@ public class DataSetRegistrationService implements IRollbackDelegate } } + public void rollback(DataSetRegistrationAlgorithm algorithm, Throwable ex) + { + registrator.rollback(this, algorithm, ex); + } } diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/DefaultDataSetRegistrationDetailsFactory.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/DefaultDataSetRegistrationDetailsFactory.java new file mode 100644 index 00000000000..46020bd2449 --- /dev/null +++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/DefaultDataSetRegistrationDetailsFactory.java @@ -0,0 +1,44 @@ +/* + * Copyright 2011 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.etlserver.registrator; + +import ch.systemsx.cisd.etlserver.registrator.AbstractOmniscientTopLevelDataSetRegistrator.OmniscientTopLevelDataSetRegistratorState; +import ch.systemsx.cisd.openbis.dss.generic.shared.dto.DataSetInformation; + +/** + * @author Chandrasekhar Ramakrishnan + */ +public class DefaultDataSetRegistrationDetailsFactory extends + AbstractDataSetRegistrationDetailsFactory<DataSetInformation> +{ + + /** + * @param registratorState + */ + public DefaultDataSetRegistrationDetailsFactory( + OmniscientTopLevelDataSetRegistratorState registratorState) + { + super(registratorState); + } + + @Override + protected DataSetInformation createDataSetInformation() + { + return new DataSetInformation(); + } + +} diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/DefaultEntityRegistrationService.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/DefaultEntityRegistrationService.java index 2e8f3f0f75a..f491ac1d090 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/DefaultEntityRegistrationService.java +++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/DefaultEntityRegistrationService.java @@ -33,9 +33,10 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifi public class DefaultEntityRegistrationService<T extends DataSetInformation> implements IEntityRegistrationService<T> { - private final AbstractOmniscientTopLevelDataSetRegistrator registrator; + private final AbstractOmniscientTopLevelDataSetRegistrator<T> registrator; - public DefaultEntityRegistrationService(AbstractOmniscientTopLevelDataSetRegistrator registrator) + public DefaultEntityRegistrationService( + AbstractOmniscientTopLevelDataSetRegistrator<T> registrator) { this.registrator = registrator; } 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 193a465014e..97e16c62df2 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 @@ -28,7 +28,7 @@ import ch.systemsx.cisd.common.utilities.IDelegatedActionWithResult; import ch.systemsx.cisd.common.utilities.PropertyUtils; import ch.systemsx.cisd.etlserver.DataSetRegistrationAlgorithm; import ch.systemsx.cisd.etlserver.TopLevelDataSetRegistratorGlobalState; -import ch.systemsx.cisd.etlserver.registrator.api.v1.impl.DataSet; +import ch.systemsx.cisd.etlserver.registrator.api.v1.impl.DataSetRegistrationTransaction; import ch.systemsx.cisd.openbis.dss.generic.shared.dto.DataSetInformation; /** @@ -36,7 +36,8 @@ import ch.systemsx.cisd.openbis.dss.generic.shared.dto.DataSetInformation; * * @author Chandrasekhar Ramakrishnan */ -public class JythonTopLevelDataSetHandler extends AbstractOmniscientTopLevelDataSetRegistrator +public class JythonTopLevelDataSetHandler<T extends DataSetInformation> extends + AbstractOmniscientTopLevelDataSetRegistrator<T> { /** * The name of the function to define to hook into the data set registration rollback mechanism. @@ -49,6 +50,11 @@ public class JythonTopLevelDataSetHandler extends AbstractOmniscientTopLevelData */ private static final String ROLLBACK_SERVICE_FUNCTION_NAME = "rollback_service"; + /** + * The name of the function to define to hook into the transaction rollback mechanism. + */ + private static final String ROLLBACK_TRANSACTION_FUNCTION_NAME = "rollback_transaction"; + private static final String FACTORY_VARIABLE_NAME = "factory"; /** @@ -94,14 +100,14 @@ public class JythonTopLevelDataSetHandler extends AbstractOmniscientTopLevelData } @Override - protected void handleDataSet(File dataSetFile, DataSetRegistrationService genericService) + protected void handleDataSet(File dataSetFile, DataSetRegistrationService<T> genericService) throws Throwable { // Load the script String scriptString = FileUtilities.loadToString(scriptFile); - JythonDataSetRegistrationService service = - (JythonDataSetRegistrationService) genericService; + JythonDataSetRegistrationService<T> service = + (JythonDataSetRegistrationService<T>) genericService; // Configure the evaluator PythonInterpreter interpreter = service.interpreter; @@ -129,21 +135,21 @@ public class JythonTopLevelDataSetHandler extends AbstractOmniscientTopLevelData * the service so we can use it in error handling). */ @Override - protected DataSetRegistrationService createDataSetRegistrationService( + protected DataSetRegistrationService<T> createDataSetRegistrationService( IDelegatedActionWithResult<Boolean> cleanAfterwardsAction) { PythonInterpreter interpreter = new PythonInterpreter(); interpreter.set(STATE_VARIABLE_NAME, getGlobalState()); - JythonDataSetRegistrationService service = - new JythonDataSetRegistrationService(this, cleanAfterwardsAction, interpreter); + JythonDataSetRegistrationService<T> service = + new JythonDataSetRegistrationService<T>(this, cleanAfterwardsAction, interpreter); return service; } @Override - public void rollback(DataSetRegistrationService service, + public void rollback(DataSetRegistrationService<T> service, DataSetRegistrationAlgorithm registrationAlgorithm, Throwable throwable) { - PythonInterpreter interpreter = ((JythonDataSetRegistrationService) service).interpreter; + PythonInterpreter interpreter = getInterpreterFromService(service); PyFunction function = tryJythonFunction(interpreter, ROLLBACK_DATA_SET_REGISTRATION_FUNCTION_NAME); if (null != function) @@ -156,9 +162,9 @@ public class JythonTopLevelDataSetHandler extends AbstractOmniscientTopLevelData } @Override - protected void rollback(DataSetRegistrationService service, Throwable throwable) + protected void rollback(DataSetRegistrationService<T> service, Throwable throwable) { - PythonInterpreter interpreter = ((JythonDataSetRegistrationService) service).interpreter; + PythonInterpreter interpreter = getInterpreterFromService(service); PyFunction function = tryJythonFunction(interpreter, ROLLBACK_SERVICE_FUNCTION_NAME); if (null != function) { @@ -168,6 +174,21 @@ public class JythonTopLevelDataSetHandler extends AbstractOmniscientTopLevelData super.rollback(service, throwable); } + @Override + public void rollbackTransaction(DataSetRegistrationService<T> service, + DataSetRegistrationTransaction<T> transaction, + DataSetStorageAlgorithmRunner<T> algorithmRunner, Throwable ex) + { + PythonInterpreter interpreter = getInterpreterFromService(service); + PyFunction function = tryJythonFunction(interpreter, ROLLBACK_TRANSACTION_FUNCTION_NAME); + if (null != function) + { + invokeRollbackTransactionFunction(function, service, transaction, algorithmRunner, ex); + } + + super.rollbackTransaction(service, transaction, algorithmRunner, ex); + } + private PyFunction tryJythonFunction(PythonInterpreter interpreter, String functionName) { try @@ -185,17 +206,28 @@ public class JythonTopLevelDataSetHandler extends AbstractOmniscientTopLevelData * Pulled out as a separate method so tests can hook in. */ protected void invokeRollbackServiceFunction(PyFunction function, - DataSetRegistrationService service, Throwable throwable) + DataSetRegistrationService<T> service, Throwable throwable) { function.__call__(Py.java2py(service), Py.java2py(throwable)); } + /** + * Pulled out as a separate method so tests can hook in. + */ + protected void invokeRollbackTransactionFunction(PyFunction function, + DataSetRegistrationService<T> service, DataSetRegistrationTransaction<T> transaction, + DataSetStorageAlgorithmRunner<T> algorithmRunner, Throwable throwable) + { + function.__call__(Py.java2py(service), Py.java2py(transaction), + Py.java2py(algorithmRunner), Py.java2py(throwable)); + } + /** * Pulled out as a separate method so tests can hook in. */ protected void invokeRollbackDataSetRegistrationFunction(PyFunction function, - DataSetRegistrationService service, DataSetRegistrationAlgorithm registrationAlgorithm, - Throwable throwable) + DataSetRegistrationService<T> service, + DataSetRegistrationAlgorithm registrationAlgorithm, Throwable throwable) { function.__call__(Py.java2py(service), Py.java2py(registrationAlgorithm), Py.java2py(throwable)); @@ -204,10 +236,12 @@ public class JythonTopLevelDataSetHandler extends AbstractOmniscientTopLevelData /** * Set the factory available to the python script. Subclasses may want to override. */ - protected IDataSetRegistrationDetailsFactory<? extends DataSetInformation> createObjectFactory( + @SuppressWarnings("unchecked") + protected IDataSetRegistrationDetailsFactory<T> createObjectFactory( PythonInterpreter interpreter) { - return new JythonObjectFactory<DataSetInformation>(getRegistratorState()) + return (IDataSetRegistrationDetailsFactory<T>) new JythonObjectFactory<DataSetInformation>( + getRegistratorState()) { @Override protected DataSetInformation createDataSetInformation() @@ -217,14 +251,12 @@ public class JythonTopLevelDataSetHandler extends AbstractOmniscientTopLevelData }; } - public abstract static class JythonObjectFactory<T extends DataSetInformation> implements - IDataSetRegistrationDetailsFactory<T> + public abstract static class JythonObjectFactory<T extends DataSetInformation> extends + AbstractDataSetRegistrationDetailsFactory<T> { - protected final OmniscientTopLevelDataSetRegistratorState registratorState; - public JythonObjectFactory(OmniscientTopLevelDataSetRegistratorState registratorState) { - this.registratorState = registratorState; + super(registratorState); } /** @@ -232,40 +264,12 @@ public class JythonTopLevelDataSetHandler extends AbstractOmniscientTopLevelData */ public DataSetRegistrationDetails<T> createRegistrationDetails() { - DataSetRegistrationDetails<T> registrationDetails = new DataSetRegistrationDetails<T>(); - T dataSetInfo = createDataSetInformation(); - setDatabaseInstance(dataSetInfo); - registrationDetails.setDataSetInformation(dataSetInfo); - return registrationDetails; - } - - protected final void setDatabaseInstance(T dataSetInfo) - { - dataSetInfo.setInstanceCode(registratorState.getHomeDatabaseInstance().getCode()); - dataSetInfo.setInstanceUUID(registratorState.getHomeDatabaseInstance().getUuid()); - } - - /** - * Adaptor for the IDataSetRegistrationDetailsFactory interface. - */ - public DataSetRegistrationDetails<T> createDataSetRegistrationDetails() - { - return createRegistrationDetails(); + return createDataSetRegistrationDetails(); } - - public DataSet<T> createDataSet(DataSetRegistrationDetails<T> registrationDetails, - File stagingFile) - { - return new DataSet<T>(registrationDetails, stagingFile); - } - - /** - * Factory method that creates a new data set information object. - */ - protected abstract T createDataSetInformation(); } - protected static class JythonDataSetRegistrationService extends DataSetRegistrationService + protected static class JythonDataSetRegistrationService<T extends DataSetInformation> extends + DataSetRegistrationService<T> { private final PythonInterpreter interpreter; @@ -273,12 +277,12 @@ public class JythonTopLevelDataSetHandler extends AbstractOmniscientTopLevelData * @param registrator * @param globalCleanAfterwardsAction */ - public JythonDataSetRegistrationService( - AbstractOmniscientTopLevelDataSetRegistrator registrator, + public JythonDataSetRegistrationService(JythonTopLevelDataSetHandler<T> registrator, IDelegatedActionWithResult<Boolean> globalCleanAfterwardsAction, PythonInterpreter interpreter) { - super(registrator, globalCleanAfterwardsAction); + super(registrator, registrator.createObjectFactory(interpreter), + globalCleanAfterwardsAction); this.interpreter = interpreter; } @@ -287,4 +291,10 @@ public class JythonTopLevelDataSetHandler extends AbstractOmniscientTopLevelData return interpreter; } } + + protected PythonInterpreter getInterpreterFromService(DataSetRegistrationService<T> service) + { + PythonInterpreter interpreter = ((JythonDataSetRegistrationService<T>) service).interpreter; + return interpreter; + } } diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/AbstractTransactionState.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/AbstractTransactionState.java index 66947e3bc3d..0ca5a6f796e 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/AbstractTransactionState.java +++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/AbstractTransactionState.java @@ -75,7 +75,7 @@ abstract class AbstractTransactionState<T extends DataSetInformation> private final File stagingDirectory; // The registration service that owns this transaction - private final DataSetRegistrationService registrationService; + private final DataSetRegistrationService<T> registrationService; // The interface to openBIS private final IEncapsulatedOpenBISService openBisService; @@ -88,7 +88,7 @@ abstract class AbstractTransactionState<T extends DataSetInformation> public LiveTransactionState(DataSetRegistrationTransaction<T> parent, RollbackStack rollbackStack, File workingDirectory, File stagingDirectory, - DataSetRegistrationService registrationService, + DataSetRegistrationService<T> registrationService, IDataSetRegistrationDetailsFactory<T> registrationDetailsFactory) { super(parent); @@ -97,7 +97,7 @@ abstract class AbstractTransactionState<T extends DataSetInformation> this.stagingDirectory = stagingDirectory; this.registrationService = registrationService; this.openBisService = - this.registrationService.getRegistratorState().getGlobalState() + this.registrationService.getRegistratorContext().getGlobalState() .getOpenBisService(); this.registrationDetailsFactory = registrationDetailsFactory; } 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 1b1b9259ccb..071404795c4 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 @@ -139,13 +139,13 @@ public class DataSetRegistrationTransaction<T extends DataSetInformation> implem private AbstractTransactionState<T> state; // The registration service that owns this transaction - private final DataSetRegistrationService registrationService; + private final DataSetRegistrationService<T> registrationService; // The interface to openBIS private final IEncapsulatedOpenBISService openBisService; public DataSetRegistrationTransaction(File rollBackStackParentFolder, File workingDirectory, - File stagingDirectory, DataSetRegistrationService registrationService, + File stagingDirectory, DataSetRegistrationService<T> registrationService, IDataSetRegistrationDetailsFactory<T> registrationDetailsFactory) { this(createNewRollbackStack(rollBackStackParentFolder), workingDirectory, stagingDirectory, @@ -153,7 +153,7 @@ public class DataSetRegistrationTransaction<T extends DataSetInformation> implem } DataSetRegistrationTransaction(RollbackStack rollbackStack, File workingDirectory, - File stagingDirectory, DataSetRegistrationService registrationService, + File stagingDirectory, DataSetRegistrationService<T> registrationService, IDataSetRegistrationDetailsFactory<T> registrationDetailsFactory) { state = @@ -161,7 +161,8 @@ public class DataSetRegistrationTransaction<T extends DataSetInformation> implem stagingDirectory, registrationService, registrationDetailsFactory); this.registrationService = registrationService; this.openBisService = - this.registrationService.getRegistratorState().getGlobalState().getOpenBisService(); + this.registrationService.getRegistratorContext().getGlobalState() + .getOpenBisService(); } public IDataSet createNewDataSet() 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 9a858e328b6..8c6a3779625 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 @@ -82,7 +82,7 @@ public class JythonTopLevelDataSetRegistratorTest extends AbstractFileSystemTest private static final DataSetType DATA_SET_TYPE = new DataSetType("O1"); - private JythonTopLevelDataSetHandler handler; + private JythonTopLevelDataSetHandler<DataSetInformation> handler; private Mockery context; @@ -735,7 +735,7 @@ public class JythonTopLevelDataSetRegistratorTest extends AbstractFileSystemTest } } - private class TestingDataSetHandler extends JythonTopLevelDataSetHandler + private class TestingDataSetHandler extends JythonTopLevelDataSetHandler<DataSetInformation> { private final boolean shouldRegistrationFail; @@ -767,7 +767,7 @@ public class JythonTopLevelDataSetRegistratorTest extends AbstractFileSystemTest } @Override - public void rollback(DataSetRegistrationService service, + public void rollback(DataSetRegistrationService<DataSetInformation> service, DataSetRegistrationAlgorithm registrationAlgorithm, Throwable throwable) { super.rollback(service, registrationAlgorithm, throwable); @@ -775,7 +775,8 @@ public class JythonTopLevelDataSetRegistratorTest extends AbstractFileSystemTest } @Override - public void rollback(DataSetRegistrationService service, Throwable throwable) + public void rollback(DataSetRegistrationService<DataSetInformation> service, + Throwable throwable) { super.rollback(service, throwable); didServiceRollbackHappen = true; @@ -783,29 +784,32 @@ public class JythonTopLevelDataSetRegistratorTest extends AbstractFileSystemTest { throw CheckedExceptionTunnel.wrapIfNecessary(throwable); } + throwable.printStackTrace(); } @Override protected void invokeRollbackServiceFunction(PyFunction function, - DataSetRegistrationService service, Throwable throwable) + DataSetRegistrationService<DataSetInformation> service, Throwable throwable) { super.invokeRollbackServiceFunction(function, service, throwable); PythonInterpreter interpreter = - ((JythonDataSetRegistrationService) service).getInterpreter(); + ((JythonDataSetRegistrationService<DataSetInformation>) service) + .getInterpreter(); didRollbackServiceFunctionRun = (Boolean) interpreter.get("didRollbackServiceFunctionRun", Boolean.class); } @Override protected void invokeRollbackDataSetRegistrationFunction(PyFunction function, - DataSetRegistrationService service, + DataSetRegistrationService<DataSetInformation> service, DataSetRegistrationAlgorithm registrationAlgorithm, Throwable throwable) { super.invokeRollbackDataSetRegistrationFunction(function, service, registrationAlgorithm, throwable); PythonInterpreter interpreter = - ((JythonDataSetRegistrationService) service).getInterpreter(); + ((JythonDataSetRegistrationService<DataSetInformation>) service) + .getInterpreter(); didRollbackDataSetRegistrationFunctionRun = (Boolean) interpreter.get("didRollbackServiceFunctionRun", Boolean.class); } diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/DataSetRegistrationTransactionTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/DataSetRegistrationTransactionTest.java index 537fa842351..076c1961f30 100644 --- a/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/DataSetRegistrationTransactionTest.java +++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/DataSetRegistrationTransactionTest.java @@ -92,7 +92,7 @@ public class DataSetRegistrationTransactionTest extends AbstractFileSystemTestCa private File srcFile; - private DataSetRegistrationService service; + private DataSetRegistrationService<DataSetInformation> service; @BeforeTest public void init() @@ -457,8 +457,9 @@ public class DataSetRegistrationTransactionTest extends AbstractFileSystemTestCa } } - private class TestingDataSetHandler extends AbstractOmniscientTopLevelDataSetRegistrator - implements IDataSetRegistrationDetailsFactory<DataSetInformation> + private class TestingDataSetHandler extends + AbstractOmniscientTopLevelDataSetRegistrator<DataSetInformation> implements + IDataSetRegistrationDetailsFactory<DataSetInformation> { /** @@ -470,13 +471,13 @@ public class DataSetRegistrationTransactionTest extends AbstractFileSystemTestCa } @Override - protected void handleDataSet(File dataSetFile, DataSetRegistrationService aService) - throws Throwable + protected void handleDataSet(File dataSetFile, + DataSetRegistrationService<DataSetInformation> aService) throws Throwable { } - public DataSetRegistrationService createNewService() + public DataSetRegistrationService<DataSetInformation> createNewService() { IDelegatedActionWithResult<Boolean> cleanAfterwardsAction = new IDelegatedActionWithResult<Boolean>() -- GitLab