diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/api/v1/DataSetRegistrationHelper.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/api/v1/DataSetRegistrationHelper.java deleted file mode 100644 index 469e743854bcde173a3ce66dbbeab40aa3edced9..0000000000000000000000000000000000000000 --- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/api/v1/DataSetRegistrationHelper.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright 2010 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.api.v1; - -import java.io.File; -import java.util.concurrent.locks.Lock; - -import org.apache.log4j.Logger; - -import ch.systemsx.cisd.common.filesystem.FileOperations; -import ch.systemsx.cisd.common.filesystem.IFileOperations; -import ch.systemsx.cisd.common.mail.IMailClient; -import ch.systemsx.cisd.common.utilities.IDelegatedActionWithResult; -import ch.systemsx.cisd.etlserver.DataSetRegistrationAlgorithm; -import ch.systemsx.cisd.etlserver.IDataSetInfoExtractor; -import ch.systemsx.cisd.etlserver.IDataStrategyStore; -import ch.systemsx.cisd.etlserver.IETLServerPlugin; -import ch.systemsx.cisd.etlserver.IStorageProcessor; -import ch.systemsx.cisd.etlserver.ITypeExtractor; -import ch.systemsx.cisd.etlserver.validation.IDataSetValidator; -import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseInstance; - -/** - * @author Chandrasekhar Ramakrishnan - */ -class DataSetRegistrationHelper extends DataSetRegistrationAlgorithm -{ - - private final PutDataSetService service; - - private final IETLServerPlugin plugin; - - /** - * @param incomingDataSetFile - * @param cleanAftrewardsAction - */ - public DataSetRegistrationHelper(PutDataSetService service, IETLServerPlugin plugin, - File incomingDataSetFile, IDelegatedActionWithResult<Boolean> cleanAftrewardsAction) - { - super(incomingDataSetFile, cleanAftrewardsAction); - this.service = service; - this.plugin = plugin; - } - - @Override - protected IDataSetInfoExtractor getDataSetInfoExtractor() - { - return plugin.getDataSetInfoExtractor(); - } - - @Override - protected IDataSetValidator getDataSetValidator() - { - // TODO Auto-generated method stub - return null; - } - - @Override - protected String getDataStoreCode() - { - // TODO Auto-generated method stub - return null; - } - - @Override - protected IDataStrategyStore getDataStrategyStore() - { - // TODO Auto-generated method stub - return null; - } - - @Override - protected String getEmailSubjectTemplate() - { - // TODO Auto-generated method stub - return null; - } - - @Override - protected IFileOperations getFileOperations() - { - return FileOperations.getMonitoredInstanceForCurrentThread(); - } - - @Override - protected DatabaseInstance getHomeDatabaseInstance() - { - // TODO Auto-generated method stub - return null; - } - - @Override - protected IMailClient getMailClient() - { - return service.getMailClient(); - } - - @Override - protected Logger getNotificationLog() - { - return service.getOperationLog(); - } - - @Override - protected IEncapsulatedOpenBISService getOpenBisService() - { - return service.getOpenBisService(); - } - - @Override - protected Logger getOperationLog() - { - return service.getOperationLog(); - } - - @Override - protected Lock getRegistrationLock() - { - return service.getRegistrationLock(); - } - - @Override - protected IStorageProcessor getStorageProcessor() - { - return plugin.getStorageProcessor(); - } - - @Override - protected ITypeExtractor getTypeExtractor() - { - return plugin.getTypeExtractor(); - } - - @Override - protected void rollback(Throwable ex) - { - rollbackStorageProcessor(ex); - } - - @Override - protected boolean shouldDeleteUnidentified() - { - return true; - } - - @Override - protected boolean shouldNotifySuccessfulRegistration() - { - return false; - } - -} diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/api/v1/PutDataSetExecutor.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/api/v1/PutDataSetExecutor.java index 7b4f1d761f4a8eb4338dba929fedc01c394ec41b..9e36df1baca29baa393a2b3ad2e0fc99e1447fcb 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/api/v1/PutDataSetExecutor.java +++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/api/v1/PutDataSetExecutor.java @@ -23,19 +23,33 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.util.concurrent.locks.Lock; import org.apache.commons.io.FileUtils; import org.apache.log4j.Logger; import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException; import ch.systemsx.cisd.common.exceptions.UserFailureException; +import ch.systemsx.cisd.common.filesystem.FileOperations; +import ch.systemsx.cisd.common.filesystem.IFileOperations; import ch.systemsx.cisd.common.io.ConcatenatedFileOutputStreamWriter; +import ch.systemsx.cisd.common.mail.IMailClient; +import ch.systemsx.cisd.common.utilities.IDelegatedActionWithResult; +import ch.systemsx.cisd.etlserver.DataSetRegistrationAlgorithm; +import ch.systemsx.cisd.etlserver.IDataSetInfoExtractor; +import ch.systemsx.cisd.etlserver.IDataStrategyStore; import ch.systemsx.cisd.etlserver.IETLServerPlugin; +import ch.systemsx.cisd.etlserver.IStorageProcessor; +import ch.systemsx.cisd.etlserver.ITypeExtractor; +import ch.systemsx.cisd.etlserver.TransferredDataSetHandler; +import ch.systemsx.cisd.etlserver.validation.IDataSetValidator; import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService; import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.FileInfoDssDTO; import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.NewDataSetDTO; import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.NewDataSetDTO.DataSetOwner; -import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.NewDataSetDTO.DataSetOwnerType; +import ch.systemsx.cisd.openbis.dss.generic.shared.dto.DataSetInformation; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetType; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseInstance; import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifier; import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifierFactory; import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifier; @@ -72,6 +86,10 @@ class PutDataSetExecutor this.newDataSet = newDataSet; this.inputStream = inputStream; this.dataSetDir = new File(service.getIncomingDir(), newDataSet.getDataSetFolderName()); + if (dataSetDir.exists()) + { + deleteDataSetDir(); + } if (false == this.dataSetDir.mkdir()) { throw new EnvironmentFailureException("Could not create directory for data set " @@ -94,16 +112,25 @@ class PutDataSetExecutor writeDataSetToTempDirectory(); - // TODO: When registering, set the registrator to the session owner; only an admin on - // the space or an ETL server can override. - - // Register data set - DataSetRegistrationHelper helper = - new DataSetRegistrationHelper(service, plugin, dataSetDir, null); - helper.prepare(); - helper.registerDataSet(); - - deleteDataSetDir(); + // Register the data set + try + { + DataSetRegistrationHelper helper = + new DataSetRegistrationHelper(service, plugin, dataSetDir); + helper.prepare(); + if (helper.hasDataSetBeenIdentified()) + { + helper.registerDataSet(); + } else + { + helper.dealWithUnidentifiedDataSet(); + throw new UserFailureException("Could not find owner:\n\t" + + newDataSet.getDataSetOwner() + "\nfor data set:\n\t" + newDataSet); + } + } finally + { + deleteDataSetDir(); + } } private void writeDataSetToTempDirectory() throws IOException @@ -114,6 +141,8 @@ class PutDataSetExecutor { OutputStream output = getOutputStream(fileInfo); imagesWriter.writeNextBlock(output); + output.flush(); + output.close(); } } @@ -148,24 +177,65 @@ class PutDataSetExecutor private SpaceIdentifier getSpaceIdentifierForNewDataSet() { - SpaceIdentifier spaceId; + SpaceIdentifier spaceId = null; DataSetOwner owner = newDataSet.getDataSetOwner(); - if (DataSetOwnerType.EXPERIMENT == owner.getType()) - { - ExperimentIdentifier experimentId = - new ExperimentIdentifierFactory(owner.getIdentifier()).createIdentifier(); - spaceId = - new SpaceIdentifier(experimentId.getDatabaseInstanceCode(), experimentId - .getSpaceCode()); - } else + switch (owner.getType()) { - SampleIdentifier sampleId = - new SampleIdentifierFactory(owner.getIdentifier()).createIdentifier(); - spaceId = sampleId.getSpaceLevel(); + case EXPERIMENT: + { + ExperimentIdentifier experimentId = tryExperimentIdentifier(); + spaceId = + new SpaceIdentifier(experimentId.getDatabaseInstanceCode(), experimentId + .getSpaceCode()); + break; + } + case SAMPLE: + { + SampleIdentifier sampleId = trySampleIdentifier(); + spaceId = sampleId.getSpaceLevel(); + break; + } } return spaceId; } + private ExperimentIdentifier tryExperimentIdentifier() + { + DataSetOwner owner = newDataSet.getDataSetOwner(); + switch (owner.getType()) + { + case EXPERIMENT: + { + return new ExperimentIdentifierFactory(owner.getIdentifier()).createIdentifier(); + } + case SAMPLE: + { + return null; + } + } + + return null; + } + + private SampleIdentifier trySampleIdentifier() + { + DataSetOwner owner = newDataSet.getDataSetOwner(); + switch (owner.getType()) + { + case EXPERIMENT: + { + return null; + } + case SAMPLE: + { + return new SampleIdentifierFactory(owner.getIdentifier()).createIdentifier(); + + } + } + + return null; + } + private IEncapsulatedOpenBISService getOpenBisService() { return service.getOpenBisService(); @@ -175,4 +245,175 @@ class PutDataSetExecutor { return service.getOperationLog(); } + + private static class CleanAfterwardsAction implements IDelegatedActionWithResult<Boolean> + { + public Boolean execute() + { + return true; // do nothing + } + } + + /** + * An implementation of the registration algorithm that gets its state from the executor. + * + * @author Chandrasekhar Ramakrishnan + */ + private class DataSetRegistrationHelper extends DataSetRegistrationAlgorithm + { + /** + * @param service The provider of global state for the data set registration algorithm + * @param plugin The provider of the storage processor + * @param incomingDataSetFile The data set to register + */ + public DataSetRegistrationHelper(PutDataSetService service, IETLServerPlugin plugin, + File incomingDataSetFile) + { + super(incomingDataSetFile, new CleanAfterwardsAction()); + } + + @Override + protected IDataSetInfoExtractor getDataSetInfoExtractor() + { + return plugin.getDataSetInfoExtractor(); + } + + @Override + protected IDataSetValidator getDataSetValidator() + { + return service.getDataSetValidator(); + } + + @Override + protected String getDataStoreCode() + { + return service.getDataStoreCode(); + } + + @Override + protected IDataStrategyStore getDataStrategyStore() + { + return service.getDataStrategyStore(); + } + + @Override + protected String getEmailSubjectTemplate() + { + return TransferredDataSetHandler.EMAIL_SUBJECT_TEMPLATE; + } + + @Override + protected IFileOperations getFileOperations() + { + return FileOperations.getMonitoredInstanceForCurrentThread(); + } + + @Override + protected DatabaseInstance getHomeDatabaseInstance() + { + return service.getHomeDatabaseInstance(); + } + + @Override + protected IMailClient getMailClient() + { + return service.getMailClient(); + } + + @Override + protected Logger getNotificationLog() + { + return service.getOperationLog(); + } + + @Override + protected IEncapsulatedOpenBISService getOpenBisService() + { + return service.getOpenBisService(); + } + + @Override + protected Logger getOperationLog() + { + return service.getOperationLog(); + } + + @Override + protected Lock getRegistrationLock() + { + return service.getRegistrationLock(); + } + + @Override + protected IStorageProcessor getStorageProcessor() + { + return plugin.getStorageProcessor(); + } + + @Override + protected ITypeExtractor getTypeExtractor() + { + return plugin.getTypeExtractor(); + } + + @Override + protected void rollback(Throwable ex) + { + rollbackStorageProcessor(ex); + if (ex instanceof UserFailureException) + { + throw (UserFailureException) ex; + } + throw new EnvironmentFailureException("Could not register data set " + newDataSet, ex); + } + + @Override + protected boolean shouldDeleteUnidentified() + { + return true; + } + + @Override + protected boolean shouldNotifySuccessfulRegistration() + { + return false; + } + + @Override + protected DataSetInformation extractDataSetInformation(final File incomingDataSetPath) + { + DataSetInformation dataSetInfo = super.extractDataSetInformation(incomingDataSetPath); + if (null == dataSetInfo) + { + return dataSetInfo; + } + DataSetOwner owner = newDataSet.getDataSetOwner(); + switch (owner.getType()) + { + case EXPERIMENT: + dataSetInfo.setExperimentIdentifier(tryExperimentIdentifier()); + break; + case SAMPLE: + SampleIdentifier sampleId = trySampleIdentifier(); + + dataSetInfo.setSampleCode(sampleId.getSampleCode()); + dataSetInfo.setSpaceCode(sampleId.getSpaceLevel().getSpaceCode()); + dataSetInfo.setInstanceCode(sampleId.getSpaceLevel().getDatabaseInstanceCode()); + break; + } + + // TODO: Get the session owner's email address from OpenBIS + // dataSetInfo.setUploadingUserEmail() + + // TODO: When registering, set the registrator to the session owner; only an admin on + // the space or an ETL server can override. + return dataSetInfo; + } + + @Override + protected DataSetType extractDataSetType() + { + return new DataSetType(newDataSet.getDataSetType()); + } + } } diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/api/v1/PutDataSetService.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/api/v1/PutDataSetService.java index 849baa5468ef09c71daea18a3005a6c9a91b8379..a5323289a196e44644f740c15cbcffdca8460509 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/api/v1/PutDataSetService.java +++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/api/v1/PutDataSetService.java @@ -32,8 +32,12 @@ import ch.systemsx.cisd.etlserver.DataStrategyStore; import ch.systemsx.cisd.etlserver.IETLServerPlugin; import ch.systemsx.cisd.etlserver.Parameters; import ch.systemsx.cisd.etlserver.ThreadParameters; +import ch.systemsx.cisd.etlserver.validation.DataSetValidator; +import ch.systemsx.cisd.etlserver.validation.IDataSetValidator; import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService; import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.NewDataSetDTO; +import ch.systemsx.cisd.openbis.dss.generic.shared.utils.DssPropertyParametersUtil; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseInstance; /** * Helper class that maintains the state for handling put requests. The requests themselves are @@ -51,6 +55,12 @@ public class PutDataSetService private final DataStrategyStore dataStrategyStore; + // These are all initialized only once, but it is not possible to initialize them at + // construction time, since this causes a dependency loop that causes problems in Spring. + private File storeDirectory; + + private String dataStoreCode; + private boolean isInitialized = false; private MailClient mailClient; @@ -59,6 +69,10 @@ public class PutDataSetService private File incomingDir; + private IDataSetValidator dataSetValidator; + + private DatabaseInstance homeDatabaseInstance; + public PutDataSetService(IEncapsulatedOpenBISService openBisService, Logger operationLog) { this.openBisService = openBisService; @@ -80,7 +94,6 @@ public class PutDataSetService try { new PutDataSetExecutor(this, plugin, sessionToken, newDataSet, inputStream).execute(); - } catch (UserFailureException e) { throw new IllegalArgumentException(e); @@ -108,9 +121,16 @@ public class PutDataSetService incomingDir.mkdir(); plugin = initializer.getPlugin(); + plugin.getStorageProcessor().setStoreRootDirectory(storeDirectory); mailClient = new MailClient(initializer.getMailProperties()); + this.dataStoreCode = initializer.getDataStoreCode(); + + homeDatabaseInstance = openBisService.getHomeDatabaseInstance(); + + dataSetValidator = initializer.getDataSetValidator(); + isInitialized = true; } @@ -134,16 +154,41 @@ public class PutDataSetService return operationLog; } - public Lock getRegistrationLock() + Lock getRegistrationLock() { return registrationLock; } - public DataStrategyStore getDataStrategyStore() + DataStrategyStore getDataStrategyStore() { return dataStrategyStore; } + String getDataStoreCode() + { + return dataStoreCode; + } + + IDataSetValidator getDataSetValidator() + { + return dataSetValidator; + } + + DatabaseInstance getHomeDatabaseInstance() + { + return homeDatabaseInstance; + } + + public File getStoreRootDirectory() + { + return storeDirectory; + } + + public void setStoreDirectory(File storeDirectory) + { + this.storeDirectory = storeDirectory; + } + } /** @@ -176,4 +221,13 @@ class PutDataSetServiceInitializer return threadParams[0].getPlugin(); } + String getDataStoreCode() + { + return DssPropertyParametersUtil.getDataStoreCode(params.getProperties()); + } + + DataSetValidator getDataSetValidator() + { + return new DataSetValidator(params.getProperties()); + } }