From 6a0d20b42ff52e24beb471fa48d0e6b1e8b955f7 Mon Sep 17 00:00:00 2001 From: kaloyane <kaloyane> Date: Fri, 11 Feb 2011 11:36:40 +0000 Subject: [PATCH] [LMS-2033] - implemented createNewSample(), createNewExperiment(), getSampleForUpdate() in DataSetRegistrationTransaction - added convenience getter/settter methods in the ISample/IExperiment interfaces SVN: 19900 --- .../registrator/DataSetStorageAlgorithm.java | 2 + .../DataSetStorageAlgorithmRunner.java | 9 - .../DefaultEntityOperationService.java | 49 +++--- .../registrator/api/v1/IExperiment.java | 16 ++ .../api/v1/IExperimentImmutable.java | 25 ++- .../etlserver/registrator/api/v1/ISample.java | 22 +++ .../registrator/api/v1/ISampleImmutable.java | 27 +++ .../api/v1/impl/AbstractTransactionState.java | 106 ++++++++++-- .../registrator/api/v1/impl/DataSet.java | 3 +- .../impl/DataSetRegistrationTransaction.java | 2 +- .../registrator/api/v1/impl/Experiment.java | 25 +++ .../api/v1/impl/ExperimentImmutable.java | 33 +++- .../registrator/api/v1/impl/Sample.java | 43 +++-- .../api/v1/impl/SampleImmutable.java | 88 ++++++++++ .../server/EncapsulatedOpenBISService.java | 8 + .../shared/IEncapsulatedOpenBISService.java | 10 ++ .../JythonTopLevelDataSetRegistratorTest.java | 155 ++++++++++++------ .../DataSetRegistrationTransactionTest.java | 11 +- .../transaction-with-new-experiment.py | 6 +- ...transactions.py => two-simple-datasets.py} | 0 .../dto/AtomicEntityOperationResult.java | 7 + .../ExperimentIdentifierFactory.java | 4 +- .../generic/shared/util/EntityHelper.java | 45 ++++- 23 files changed, 559 insertions(+), 137 deletions(-) create mode 100644 datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/SampleImmutable.java rename datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/{two-simple-transactions.py => two-simple-datasets.py} (100%) diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/DataSetStorageAlgorithm.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/DataSetStorageAlgorithm.java index 28786b907c0..3e8fb7de3dd 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/DataSetStorageAlgorithm.java +++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/DataSetStorageAlgorithm.java @@ -218,6 +218,8 @@ public class DataSetStorageAlgorithm<T extends DataSetInformation> data.setFileFormatType(registrationDetails.getFileFormatType()); data.setMeasured(registrationDetails.isMeasuredData()); data.setDataStoreCode(dataStoreCode); + data.setExperimentIdentifierOrNull(dataSetInformation.getExperimentIdentifier()); + data.setSampleIdentifierOrNull(dataSetInformation.getSampleIdentifier()); File dataFile = ((StoredState<T>) state).getDataFile(); 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 064b62ddb19..6b95debfb66 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 @@ -23,7 +23,6 @@ import java.util.List; import org.apache.log4j.Logger; import ch.systemsx.cisd.base.exceptions.InterruptedExceptionUnchecked; -import ch.systemsx.cisd.common.exceptions.HighLevelException; import ch.systemsx.cisd.common.logging.LogCategory; import ch.systemsx.cisd.common.logging.LogFactory; import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService; @@ -110,10 +109,6 @@ public class DataSetStorageAlgorithmRunner<T extends DataSetInformation> // Runs or throws a throwable runStorageProcessors(); - } catch (final HighLevelException ex) - { - rollbackDuringStorageProcessorRun(ex); - return Collections.emptyList(); } catch (final Throwable throwable) { rollbackDuringStorageProcessorRun(throwable); @@ -125,10 +120,6 @@ public class DataSetStorageAlgorithmRunner<T extends DataSetInformation> // Runs or throw a throwable registerDataSetsInApplicationServer(); - } catch (final HighLevelException ex) - { - rollbackDuringMetadataRegistration(ex); - return Collections.emptyList(); } catch (final Throwable throwable) { rollbackDuringMetadataRegistration(throwable); diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/DefaultEntityOperationService.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/DefaultEntityOperationService.java index 834443b9f15..6a39aadc618 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/DefaultEntityOperationService.java +++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/DefaultEntityOperationService.java @@ -24,12 +24,10 @@ import ch.systemsx.cisd.openbis.dss.generic.shared.dto.AtomicEntityOperationDeta import ch.systemsx.cisd.openbis.dss.generic.shared.dto.DataSetInformation; import ch.systemsx.cisd.openbis.dss.generic.shared.dto.DataSetRegistrationInformation; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.AtomicEntityOperationResult; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewExperiment; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample; -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.basic.dto.NewSample; +import ch.systemsx.cisd.openbis.generic.shared.dto.NewExternalData; +import ch.systemsx.cisd.openbis.generic.shared.dto.SampleUpdatesDTO; public class DefaultEntityOperationService<T extends DataSetInformation> implements IEntityOperationService<T> @@ -44,36 +42,29 @@ public class DefaultEntityOperationService<T extends DataSetInformation> impleme public AtomicEntityOperationResult performOperationsInApplcationServer( AtomicEntityOperationDetails<T> registrationDetails) { - ArrayList<Experiment> experimentsCreated = new ArrayList<Experiment>(); - ArrayList<Sample> samplesUpdated = new ArrayList<Sample>(); - ArrayList<Sample> samplesCreated = new ArrayList<Sample>(); - ArrayList<ExternalData> dataSetsCreated = new ArrayList<ExternalData>(); - IEncapsulatedOpenBISService openBisService = registrator.getGlobalState().getOpenBisService(); - List<NewExperiment> experimentRegistrations = - registrationDetails.getExperimentRegistrations(); - for (NewExperiment experiment : experimentRegistrations) - { - openBisService.registerExperiment(experiment); - ExperimentIdentifier experimentIdentifier = - new ExperimentIdentifierFactory(experiment.getIdentifier()).createIdentifier(); - experimentsCreated.add(openBisService.tryToGetExperiment(experimentIdentifier)); - } - List<DataSetRegistrationInformation<T>> dataSetRegistrations = - registrationDetails.getDataSetRegistrations(); - for (DataSetRegistrationInformation<T> dataSetRegistration : dataSetRegistrations) + return openBisService.performEntityOperations(convert(registrationDetails)); + } + + private ch.systemsx.cisd.openbis.generic.shared.dto.AtomicEntityOperationDetails convert( + AtomicEntityOperationDetails<T> details) + { + + List<NewExperiment> experimentRegistrations = details.getExperimentRegistrations(); + List<SampleUpdatesDTO> sampleUpdates = details.getSampleUpdates(); + List<NewSample> sampleRegistrations = details.getSampleRegistrations(); + List<NewExternalData> dataSetRegistrations = new ArrayList<NewExternalData>(); + + for (DataSetRegistrationInformation<?> dsRegistration : details.getDataSetRegistrations()) { - openBisService.registerDataSet(dataSetRegistration.getDataSetInformation(), - dataSetRegistration.getExternalData()); - dataSetsCreated.add(openBisService.tryGetDataSet(dataSetRegistration - .getDataSetInformation().getDataSetCode())); + NewExternalData newExternalData = dsRegistration.getExternalData(); + dataSetRegistrations.add(newExternalData); } - return new AtomicEntityOperationResult(experimentsCreated, samplesUpdated, samplesCreated, - dataSetsCreated); - + return new ch.systemsx.cisd.openbis.generic.shared.dto.AtomicEntityOperationDetails( + experimentRegistrations, sampleUpdates, sampleRegistrations, dataSetRegistrations); } } \ No newline at end of file diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/IExperiment.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/IExperiment.java index 9a123ffc7d6..ec38be0b6ae 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/IExperiment.java +++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/IExperiment.java @@ -23,4 +23,20 @@ package ch.systemsx.cisd.etlserver.registrator.api.v1; */ public interface IExperiment extends IExperimentImmutable { + /** + * Set the value for a property. + * + * @throws IllegalArgumentException if no property for code <code>propertyCode</code> is found. + */ + void setPropertyValue(String propertyCode, String propertyValue); + + /** + * Set the code for this experiment. + */ + void setCode(String code); + + /** + * Set the experiment type for this experiment. + */ + void setType(String experimentType); } diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/IExperimentImmutable.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/IExperimentImmutable.java index ddc8bda7414..f48b20aeb9c 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/IExperimentImmutable.java +++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/IExperimentImmutable.java @@ -17,14 +17,35 @@ package ch.systemsx.cisd.etlserver.registrator.api.v1; /** - * Read-only interface to an existing experiment. - * + * Read-only interface to an existing experiment. + * * @author Chandrasekhar Ramakrishnan */ public interface IExperimentImmutable { + /** + * Return the experiment identifier of this experiment. + */ + String getExperimentIdentifier(); + /** * Return true if the experiment is in openBIS. */ boolean isExistingExperiment(); + + /** + * Return the code for this experiment. May be null. + */ + String getCode(); + + /** + * Return the type for this experiment. May be null. + */ + String getType(); + + /** + * Return the value of a property specified by a code. May return null of no such property with + * code <code>propertyCode</code> is found. + */ + String getPropertyValue(String propertyCode); } diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/ISample.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/ISample.java index ab82ffb1f34..216ffab8151 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/ISample.java +++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/ISample.java @@ -22,4 +22,26 @@ package ch.systemsx.cisd.etlserver.registrator.api.v1; public interface ISample extends ISampleImmutable { + /** + * Set the experiment for this sample. The experiment need not be immutable, but the immutable + * one is the superclass. + */ + void setExperiment(IExperimentImmutable experiment); + + /** + * Set the code for this sample. + */ + void setCode(String code); + + /** + * Set the type for this sample. + */ + void setType(String type); + + /** + * Set the value for a property. + * + * @throws IllegalArgumentException if no property for code <code>propertyCode</code> is found. + */ + void setPropertyValue(String propertyCode, String propertyValue); } diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/ISampleImmutable.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/ISampleImmutable.java index 3fbfe8a3238..aa0554ada30 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/ISampleImmutable.java +++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/ISampleImmutable.java @@ -23,8 +23,35 @@ package ch.systemsx.cisd.etlserver.registrator.api.v1; */ public interface ISampleImmutable { + /** + * Return the identifier for this sample. + */ + String getSampleIdentifier(); + + /** + * Return the code for this sample. May be null. + */ + String getCode(); + + /** + * Return the experiment for this sample. May be null. + */ + IExperimentImmutable getExperiment(); + + /** + * Return the type for this sample. May be null. + */ + String getType(); + /** * Return true if the sample exists in the database. */ boolean isExistingSample(); + + /** + * Return the value of a property specified by a code. May return null of no such property with + * code <code>propertyCode</code> is found. + */ + String getPropertyValue(String propertyCode); + } 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 b8adafbba62..f4675b3d48c 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 @@ -18,8 +18,10 @@ package ch.systemsx.cisd.etlserver.registrator.api.v1.impl; import java.io.File; import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import ch.systemsx.cisd.common.exceptions.NotImplementedException; import ch.systemsx.cisd.common.filesystem.FileUtilities; import ch.systemsx.cisd.etlserver.registrator.DataSetRegistrationDetails; import ch.systemsx.cisd.etlserver.registrator.DataSetRegistrationService; @@ -33,10 +35,16 @@ import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService; import ch.systemsx.cisd.openbis.dss.generic.shared.dto.AtomicEntityOperationDetails; import ch.systemsx.cisd.openbis.dss.generic.shared.dto.DataSetInformation; import ch.systemsx.cisd.openbis.dss.generic.shared.dto.DataSetRegistrationInformation; +import ch.systemsx.cisd.openbis.generic.shared.basic.TechId; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewAttachment; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewExperiment; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewSample; import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentUpdatesDTO; import ch.systemsx.cisd.openbis.generic.shared.dto.SampleUpdatesDTO; +import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifierFactory; +import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifier; +import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifierFactory; /** * Abstract superclass for the states a DataSetRegistrationTransaction can be in. @@ -86,6 +94,10 @@ abstract class AbstractTransactionState<T extends DataSetInformation> private final List<Experiment> experimentsToBeRegistered = new ArrayList<Experiment>(); + private final List<Sample> samplesToBeRegistered = new ArrayList<Sample>(); + + private final List<Sample> samplesToBeUpdated = new ArrayList<Sample>(); + public LiveTransactionState(DataSetRegistrationTransaction<T> parent, RollbackStack rollbackStack, File workingDirectory, File stagingDirectory, DataSetRegistrationService<T> registrationService, @@ -134,26 +146,39 @@ abstract class AbstractTransactionState<T extends DataSetInformation> public ISample getSampleForUpdate(String sampleIdentifierString) { - // TODO Auto-generated method stub - return null; + SampleIdentifier sampleIdentifier = + new SampleIdentifierFactory(sampleIdentifierString).createIdentifier(); + ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample sample = + openBisService.tryGetSampleWithExperiment(sampleIdentifier); + // TODO KE: Ask Sekhar if we should throw an exception or simply return NULL + if (sample == null) + { + throw new IllegalArgumentException("Could not find sample with identifier" + + sampleIdentifierString); + } + Sample result = new Sample(sample); + samplesToBeUpdated.add(result); + return result; } public ISample createNewSample(String sampleIdentifierString) { - // TODO Auto-generated method stub - return null; + // TODO KE: should we create a new method with a more sensible name (createPermId()) + String permId = openBisService.createDataSetCode(); + Sample sample = new Sample(sampleIdentifierString, permId); + samplesToBeRegistered.add(sample); + return sample; } public IExperiment getExperimentForUpdate(String experimentIdentifierString) { - // TODO Auto-generated method stub - return null; + throw new NotImplementedException(); } public IExperiment createNewExperiment(String experimentIdentifierString) { - String permID = openBisService.createDataSetCode(); - Experiment experiment = new Experiment(experimentIdentifierString, permID); + String permId = openBisService.createDataSetCode(); + Experiment experiment = new Experiment(experimentIdentifierString, permId); experimentsToBeRegistered.add(experiment); return experiment; } @@ -275,11 +300,14 @@ abstract class AbstractTransactionState<T extends DataSetInformation> AtomicEntityOperationDetails<T> createEntityOperationDetails( List<DataSetRegistrationInformation<T>> dataSetRegistrations) { - ArrayList<NewExperiment> experimentRegistrations = new ArrayList<NewExperiment>(); - ArrayList<ExperimentUpdatesDTO> experimentUpdates = + + List<NewExperiment> experimentRegistrations = convertExperimentsToBeRegistered(); + List<SampleUpdatesDTO> sampleUpdates = convertSamplesToBeUpdated(); + List<NewSample> sampleRegistrations = convertSamplesToBeRegistered(); + + // experiment updates not yet supported + List<ExperimentUpdatesDTO> experimentUpdates = new ArrayList<ExperimentUpdatesDTO>(); - ArrayList<SampleUpdatesDTO> sampleUpdates = new ArrayList<SampleUpdatesDTO>(); - ArrayList<NewSample> sampleRegistrations = new ArrayList<NewSample>(); AtomicEntityOperationDetails<T> registrationDetails = new AtomicEntityOperationDetails<T>(experimentUpdates, @@ -288,6 +316,60 @@ abstract class AbstractTransactionState<T extends DataSetInformation> return registrationDetails; } + private List<NewExperiment> convertExperimentsToBeRegistered() { + List<NewExperiment> result = new ArrayList<NewExperiment>(); + for (Experiment apiExperiment : experimentsToBeRegistered) { + ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment experiment = apiExperiment.getExperiment(); + NewExperiment newExperiment = new NewExperiment(); + newExperiment.setIdentifier(experiment.getIdentifier()); + newExperiment.setPermID(experiment.getPermId()); + IEntityProperty[] properties = + experiment.getProperties().toArray(new IEntityProperty[0]); + newExperiment.setProperties(properties); + result.add(newExperiment); + } + return result; + } + + private List<NewSample> convertSamplesToBeRegistered() + { + List<NewSample> result = new ArrayList<NewSample>(); + for (Sample apiSample : samplesToBeRegistered) + { + ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample sample = + apiSample.getSample(); + NewSample newSample = new NewSample(); + newSample.setIdentifier(sample.getIdentifier()); + newSample.setPermID(sample.getPermId()); + IEntityProperty[] properties = + sample.getProperties().toArray(new IEntityProperty[0]); + newSample.setProperties(properties); + newSample.setExperimentIdentifier(sample.getExperiment().getIdentifier()); + } + return result; + } + + private List<SampleUpdatesDTO> convertSamplesToBeUpdated() { + List<SampleUpdatesDTO> result = new ArrayList<SampleUpdatesDTO>(); + for (Sample apiSample : samplesToBeRegistered) { + ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample sample = + apiSample.getSample(); + + List<NewAttachment> attachments = Collections.emptyList(); + SampleUpdatesDTO sampleUpdate = new SampleUpdatesDTO(TechId.create(sample), // db id + sample.getProperties(), // List<IEntityProperty> + ExperimentIdentifierFactory.parse(sample.getExperiment().getIdentifier()), // ExperimentIdentifier + attachments, // Collection<NewAttachment> + sample.getModificationDate(), // Sample version + SampleIdentifierFactory.parse(sample.getIdentifier()), // Sample Identifier + sample.getContainer().getIdentifier(), // Container Identifier + null // Parent Identifiers + ); + result.add(sampleUpdate); + } + return result; + } + @Override public boolean isCommitted() { diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/DataSet.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/DataSet.java index b3a9b0aa3f9..2c5449dd903 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/DataSet.java +++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/DataSet.java @@ -27,6 +27,7 @@ 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.FileFormatType; import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifier; +import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifierFactory; /** * A generic class that represents a data set for the registration API. Can be subclassed. @@ -148,7 +149,7 @@ public class DataSet<T extends DataSetInformation> implements IDataSet protected void setExperiment(ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment exp) { registrationDetails.getDataSetInformation().setExperiment(exp); - ExperimentIdentifier experimentId = new ExperimentIdentifier(exp); + ExperimentIdentifier experimentId = ExperimentIdentifierFactory.parse(exp.getIdentifier()); registrationDetails.getDataSetInformation().setExperimentIdentifier(experimentId); } } 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 427ad66fe7c..4ead56eec83 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 @@ -179,7 +179,7 @@ public class DataSetRegistrationTransaction<T extends DataSetInformation> implem { SampleIdentifier sampleIdentifier = new SampleIdentifierFactory(sampleIdentifierString).createIdentifier(); - return new Sample(openBisService.tryGetSampleWithExperiment(sampleIdentifier)); + return new SampleImmutable(openBisService.tryGetSampleWithExperiment(sampleIdentifier)); } public ISample getSampleForUpdate(String sampleIdentifierString) diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/Experiment.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/Experiment.java index 4b2437c6a13..15f720caef3 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/Experiment.java +++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/Experiment.java @@ -16,7 +16,13 @@ package ch.systemsx.cisd.etlserver.registrator.api.v1.impl; +import java.util.ArrayList; +import java.util.List; + import ch.systemsx.cisd.etlserver.registrator.api.v1.IExperiment; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExperimentType; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty; +import ch.systemsx.cisd.openbis.generic.shared.util.EntityHelper; /** * Implementation of {@link IExperiment}. @@ -31,6 +37,9 @@ class Experiment extends ExperimentImmutable implements IExperiment ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment experiment = getExperiment(); experiment.setIdentifier(identifier); experiment.setPermId(permID); + + List<IEntityProperty> properties = new ArrayList<IEntityProperty>(); + experiment.setProperties(properties); } @Override @@ -39,6 +48,22 @@ class Experiment extends ExperimentImmutable implements IExperiment return false; } + public void setCode(String code) + { + getExperiment().setCode(code); + } + + public void setPropertyValue(String propertyCode, String propertyValue) + { + EntityHelper.createOrUpdateProperty(getExperiment(), propertyCode, propertyValue); + } + public void setType(String experimentType) + { + ExperimentType type = new ExperimentType(); + type.setCode(experimentType); + + getExperiment().setExperimentType(type); + } } diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/ExperimentImmutable.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/ExperimentImmutable.java index 63afb7afa13..b49cd4ceeea 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/ExperimentImmutable.java +++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/ExperimentImmutable.java @@ -18,6 +18,7 @@ package ch.systemsx.cisd.etlserver.registrator.api.v1.impl; import ch.systemsx.cisd.common.exceptions.UserFailureException; import ch.systemsx.cisd.etlserver.registrator.api.v1.IExperimentImmutable; +import ch.systemsx.cisd.openbis.generic.shared.util.EntityHelper; /** * @author Chandrasekhar Ramakrishnan @@ -26,14 +27,15 @@ class ExperimentImmutable implements IExperimentImmutable { private final ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment experiment; - public ExperimentImmutable(ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment experiment) + public ExperimentImmutable( + ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment experiment) { this.experiment = experiment; } - ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment getExperiment() + public String getExperimentIdentifier() { - return experiment; + return experiment.getIdentifier(); } public boolean isExistingExperiment() @@ -51,4 +53,29 @@ class ExperimentImmutable implements IExperimentImmutable throw new UserFailureException("Experiment does not exist."); } } + + public ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment getExperiment() + { + return experiment; + } + + public String getPropertyValue(String propertyCode) + { + return EntityHelper.tryFindPropertyValue(experiment, propertyCode); + } + + public String getCode() + { + return experiment.getCode(); + } + + public String getType() + { + if (experiment.getExperimentType() != null) + { + return experiment.getExperimentType().getCode(); + } + return null; + } + } diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/Sample.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/Sample.java index 103c64301cb..4c7206be08c 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/Sample.java +++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/Sample.java @@ -16,40 +16,51 @@ package ch.systemsx.cisd.etlserver.registrator.api.v1.impl; -import ch.systemsx.cisd.common.exceptions.UserFailureException; +import ch.systemsx.cisd.etlserver.registrator.api.v1.IExperimentImmutable; import ch.systemsx.cisd.etlserver.registrator.api.v1.ISample; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleType; +import ch.systemsx.cisd.openbis.generic.shared.util.EntityHelper; /** * @author Chandrasekhar Ramakrishnan */ -public class Sample implements ISample +public class Sample extends SampleImmutable implements ISample { - private final ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample sample; + + public Sample(String sampleIdentifier, String permId) + { + super(new ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample()); + getSample().setIdentifier(sampleIdentifier); + getSample().setPermId(permId); + } public Sample(ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample sample) { - this.sample = sample; + super(sample); } - public ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample getSample() + public void setExperiment(IExperimentImmutable experiment) { - return sample; + ExperimentImmutable exp = (ExperimentImmutable) experiment; + getSample().setExperiment(exp.getExperiment()); } - public boolean isExistingSample() + public void setCode(String code) { - return null != sample; + getSample().setCode(code); } - /** - * Throw an exception if the sample does not exist - */ - protected void checkExists() + public void setPropertyValue(String propertyCode, String propertyValue) { - if (false == isExistingSample()) - { - throw new UserFailureException("Sample does not exist."); - } + EntityHelper.createOrUpdateProperty(getSample(), propertyCode, propertyValue); + } + + public void setType(String type) + { + SampleType sampleType = new SampleType(); + sampleType.setCode(type); + + getSample().setSampleType(sampleType); } } diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/SampleImmutable.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/SampleImmutable.java new file mode 100644 index 00000000000..efdb2918242 --- /dev/null +++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/SampleImmutable.java @@ -0,0 +1,88 @@ +/* + * 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.api.v1.impl; + +import ch.systemsx.cisd.common.exceptions.UserFailureException; +import ch.systemsx.cisd.etlserver.registrator.api.v1.IExperimentImmutable; +import ch.systemsx.cisd.etlserver.registrator.api.v1.ISampleImmutable; +import ch.systemsx.cisd.openbis.generic.shared.util.EntityHelper; + +/** + * @author Chandrasekhar Ramakrishnan + */ +public class SampleImmutable implements ISampleImmutable +{ + private final ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample sample; + + public SampleImmutable(ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample sample) + { + this.sample = sample; + } + + public IExperimentImmutable getExperiment() + { + ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment experiment = + sample.getExperiment(); + return (null != experiment) ? new ExperimentImmutable(experiment) : null; + } + + public String getSampleIdentifier() + { + return sample.getIdentifier(); + } + + public String getCode() + { + return sample.getCode(); + } + + public ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample getSample() + { + return sample; + } + + public boolean isExistingSample() + { + return null != sample; + } + + /** + * Throw an exception if the sample does not exist + */ + protected void checkExists() + { + if (false == isExistingSample()) + { + throw new UserFailureException("Sample does not exist."); + } + } + + public String getPropertyValue(String propertyCode) + { + return EntityHelper.tryFindPropertyValue(sample, propertyCode); + } + + public String getType() + { + if (sample.getSampleType() != null) + { + return sample.getSampleType().getCode(); + } + return null; + } + +} diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/EncapsulatedOpenBISService.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/EncapsulatedOpenBISService.java index 745dcdf7e6b..051194a6457 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/EncapsulatedOpenBISService.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/EncapsulatedOpenBISService.java @@ -34,6 +34,7 @@ import ch.systemsx.cisd.openbis.generic.shared.ResourceNames; import ch.systemsx.cisd.openbis.generic.shared.api.v1.OpenBisServiceFactory; import ch.systemsx.cisd.openbis.generic.shared.basic.TechId; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ArchiverDataSetCriteria; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.AtomicEntityOperationResult; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetArchivingStatus; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetTypeWithVocabularyTerms; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseInstance; @@ -50,6 +51,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Person; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleType; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.VocabularyTerm; +import ch.systemsx.cisd.openbis.generic.shared.dto.AtomicEntityOperationDetails; import ch.systemsx.cisd.openbis.generic.shared.dto.ListSamplesByPropertyCriteria; import ch.systemsx.cisd.openbis.generic.shared.dto.NewExternalData; import ch.systemsx.cisd.openbis.generic.shared.dto.NewProperty; @@ -465,5 +467,11 @@ public final class EncapsulatedOpenBISService implements IEncapsulatedOpenBISSer dataSetOrNull.setShareId(Constants.DEFAULT_SHARE_ID); } } + + public AtomicEntityOperationResult performEntityOperations( + AtomicEntityOperationDetails operationDetails) + { + return service.performEntityOperations(session.getToken(), operationDetails); + } } \ No newline at end of file diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/IEncapsulatedOpenBISService.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/IEncapsulatedOpenBISService.java index 4963b869a2c..26d60b20f4d 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/IEncapsulatedOpenBISService.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/IEncapsulatedOpenBISService.java @@ -23,6 +23,7 @@ import ch.systemsx.cisd.common.exceptions.UserFailureException; import ch.systemsx.cisd.openbis.dss.generic.shared.dto.DataSetInformation; import ch.systemsx.cisd.openbis.generic.shared.IETLLIMSService; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ArchiverDataSetCriteria; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.AtomicEntityOperationResult; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetArchivingStatus; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetTypeWithVocabularyTerms; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseInstance; @@ -39,6 +40,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Person; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SampleType; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.VocabularyTerm; +import ch.systemsx.cisd.openbis.generic.shared.dto.AtomicEntityOperationDetails; import ch.systemsx.cisd.openbis.generic.shared.dto.ListSamplesByPropertyCriteria; import ch.systemsx.cisd.openbis.generic.shared.dto.NewExternalData; import ch.systemsx.cisd.openbis.generic.shared.dto.NewProperty; @@ -367,4 +369,12 @@ public interface IEncapsulatedOpenBISService @ManagedAuthentication public Sample updateSampleAndRegisterDataSet(SampleUpdatesDTO newSample, NewExternalData externalData); + + /** + * {@link IETLLIMSService#performEntityOperations(String, AtomicEntityOperationDetails)} + */ + @ManagedAuthentication + public AtomicEntityOperationResult performEntityOperations( + AtomicEntityOperationDetails operationDetails); + } \ No newline at end of file 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 3f2fc3bfc83..a091d4f2fb8 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 @@ -65,11 +65,11 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.AtomicEntityOperationRe 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.basic.dto.Experiment; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Person; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.builders.ExperimentBuilder; import ch.systemsx.cisd.openbis.generic.shared.dto.NewExternalData; import ch.systemsx.cisd.openbis.generic.shared.dto.StorageFormat; +import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifier; import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifierFactory; /** @@ -88,6 +88,8 @@ public class JythonTopLevelDataSetRegistratorTest extends AbstractFileSystemTest private static final DataSetType DATA_SET_TYPE = new DataSetType("O1"); + private static final String EXPERIMENT_PERM_ID = "experiment-perm-id"; + private JythonTopLevelDataSetHandler<DataSetInformation> handler; private Mockery context; @@ -152,9 +154,8 @@ public class JythonTopLevelDataSetRegistratorTest extends AbstractFileSystemTest createData(); ExperimentBuilder builder = new ExperimentBuilder().identifier("/SPACE/PROJECT/EXP"); final Experiment experiment = builder.getExperiment(); - final RecordingMatcher<DataSetInformation> dataSetInfo = - new RecordingMatcher<DataSetInformation>(); - final RecordingMatcher<NewExternalData> dataSet = new RecordingMatcher<NewExternalData>(); + final RecordingMatcher<ch.systemsx.cisd.openbis.generic.shared.dto.AtomicEntityOperationDetails> atomicatOperationDetails = + new RecordingMatcher<ch.systemsx.cisd.openbis.generic.shared.dto.AtomicEntityOperationDetails>(); context.checking(new Expectations() { { @@ -167,30 +168,28 @@ public class JythonTopLevelDataSetRegistratorTest extends AbstractFileSystemTest one(dataSetValidator).assertValidDataSet(DATA_SET_TYPE, new File(new File(stagingDir, DATA_SET_CODE), "sub_data_set_1")); - one(openBisService).registerDataSet(with(dataSetInfo), with(dataSet)); - one(openBisService).tryGetDataSet(DATA_SET_CODE); - ExternalData externalData = new ExternalData(); - externalData.setCode(DATA_SET_CODE); - will(returnValue(externalData)); + one(openBisService).performEntityOperations(with(atomicatOperationDetails)); + will(returnValue(new AtomicEntityOperationResult())); } }); handler.handle(markerFile); assertEquals(1, MockStorageProcessor.instance.incomingDirs.size()); - assertEquals(DATA_SET_CODE, dataSetInfo.recordedObject().getDataSetCode()); - assertEquals(DATA_SET_TYPE, dataSetInfo.recordedObject().getDataSetType()); - assertEquals(experiment.getIdentifier(), dataSetInfo.recordedObject() - .getExperimentIdentifier().toString()); - assertEquals(DATA_SET_CODE, dataSet.recordedObject().getCode()); - assertEquals(DATA_SET_TYPE, dataSet.recordedObject().getDataSetType()); + assertEquals(1, atomicatOperationDetails.recordedObject().getDataSetRegistrations().size()); + + NewExternalData dataSet = + atomicatOperationDetails.recordedObject().getDataSetRegistrations().get(0); + + assertEquals(DATA_SET_CODE, dataSet.getCode()); + assertEquals(DATA_SET_TYPE, dataSet.getDataSetType()); File datasetLocation = DatasetLocationUtil.getDatasetLocationPath(workingDirectory, DATA_SET_CODE, ch.systemsx.cisd.openbis.dss.generic.shared.Constants.DEFAULT_SHARE_ID, DATABASE_INSTANCE_UUID); assertEquals(FileUtilities.getRelativeFile(new File(workingDirectory, - ch.systemsx.cisd.openbis.dss.generic.shared.Constants.DEFAULT_SHARE_ID), datasetLocation), dataSet.recordedObject() - .getLocation()); + ch.systemsx.cisd.openbis.dss.generic.shared.Constants.DEFAULT_SHARE_ID), + datasetLocation), dataSet.getLocation()); assertEquals(1, MockStorageProcessor.instance.calledCommitCount); assertEquals(datasetLocation, MockStorageProcessor.instance.rootDirs.get(0)); File incomingDir = MockStorageProcessor.instance.incomingDirs.get(0); @@ -271,8 +270,9 @@ public class JythonTopLevelDataSetRegistratorTest extends AbstractFileSystemTest one(dataSetValidator).assertValidDataSet(DATA_SET_TYPE, new File(new File(stagingDir, DATA_SET_CODE), "sub_data_set_1")); - one(openBisService).registerDataSet(with(new IsAnything<DataSetInformation>()), - with(new IsAnything<NewExternalData>())); + one(openBisService) + .performEntityOperations( + with(new IsAnything<ch.systemsx.cisd.openbis.generic.shared.dto.AtomicEntityOperationDetails>())); will(throwException(new AssertionError("Fail"))); } }); @@ -300,11 +300,10 @@ public class JythonTopLevelDataSetRegistratorTest extends AbstractFileSystemTest } @Test - public void testTwoSimpleTransactions() + public void testTwoSimpleDataSets() { setUpHomeDataBaseExpectations(); - Properties properties = - createThreadProperties(SCRIPTS_FOLDER + "two-simple-transactions.py"); + Properties properties = createThreadProperties(SCRIPTS_FOLDER + "two-simple-datasets.py"); final File stagingDir = new File(workingDirectory, "staging"); properties.setProperty(DataSetRegistrationService.STAGING_DIR, stagingDir.getPath()); createHandler(properties, false, true); @@ -313,12 +312,8 @@ public class JythonTopLevelDataSetRegistratorTest extends AbstractFileSystemTest final Experiment experiment1 = builder1.getExperiment(); ExperimentBuilder builder2 = new ExperimentBuilder().identifier("/SPACE/PROJECT/EXP2"); final Experiment experiment2 = builder2.getExperiment(); - final RecordingMatcher<DataSetInformation> dataSetInfo1 = - new RecordingMatcher<DataSetInformation>(); - final RecordingMatcher<NewExternalData> dataSet1 = new RecordingMatcher<NewExternalData>(); - final RecordingMatcher<DataSetInformation> dataSetInfo2 = - new RecordingMatcher<DataSetInformation>(); - final RecordingMatcher<NewExternalData> dataSet2 = new RecordingMatcher<NewExternalData>(); + final RecordingMatcher<ch.systemsx.cisd.openbis.generic.shared.dto.AtomicEntityOperationDetails> operations = + new RecordingMatcher<ch.systemsx.cisd.openbis.generic.shared.dto.AtomicEntityOperationDetails>(); context.checking(new Expectations() { { @@ -332,12 +327,6 @@ public class JythonTopLevelDataSetRegistratorTest extends AbstractFileSystemTest one(dataSetValidator).assertValidDataSet(DATA_SET_TYPE, new File(new File(stagingDir, DATA_SET_CODE + 1), "sub_data_set_1")); - one(openBisService).registerDataSet(with(dataSetInfo1), with(dataSet1)); - - one(openBisService).tryGetDataSet(DATA_SET_CODE + 1); - ExternalData externalData = new ExternalData(); - externalData.setCode(DATA_SET_CODE + 1); - will(returnValue(externalData)); one(openBisService).createDataSetCode(); will(returnValue(DATA_SET_CODE + 2)); @@ -349,12 +338,9 @@ public class JythonTopLevelDataSetRegistratorTest extends AbstractFileSystemTest one(dataSetValidator).assertValidDataSet(DATA_SET_TYPE, new File(new File(stagingDir, DATA_SET_CODE + 2), "sub_data_set_2")); - one(openBisService).registerDataSet(with(dataSetInfo2), with(dataSet2)); - one(openBisService).tryGetDataSet(DATA_SET_CODE + 2); - externalData = new ExternalData(); - externalData.setCode(DATA_SET_CODE + 2); - will(returnValue(externalData)); + one(openBisService).performEntityOperations(with(operations)); + will(returnValue(new AtomicEntityOperationResult())); } }); @@ -362,17 +348,21 @@ public class JythonTopLevelDataSetRegistratorTest extends AbstractFileSystemTest assertEquals(2, MockStorageProcessor.instance.incomingDirs.size()); assertEquals(2, MockStorageProcessor.instance.calledCommitCount); - assertEquals(DATA_SET_CODE + 1, dataSetInfo1.recordedObject().getDataSetCode()); - assertEquals(DATA_SET_TYPE, dataSetInfo1.recordedObject().getDataSetType()); - assertEquals(experiment1.getIdentifier(), dataSetInfo1.recordedObject() - .getExperimentIdentifier().toString()); - assertEquals(DATA_SET_CODE + 1, dataSet1.recordedObject().getCode()); - assertEquals(DATA_SET_TYPE, dataSet1.recordedObject().getDataSetType()); + assertEquals(2, operations.recordedObject().getDataSetRegistrations().size()); + + NewExternalData dataSet1 = operations.recordedObject().getDataSetRegistrations().get(0); + NewExternalData dataSet2 = operations.recordedObject().getDataSetRegistrations().get(1); + + assertEquals(experiment1.getIdentifier(), dataSet1.getExperimentIdentifierOrNull() + .toString()); + assertEquals(DATA_SET_CODE + 1, dataSet1.getCode()); + assertEquals(DATA_SET_TYPE, dataSet1.getDataSetType()); File datasetLocation1 = DatasetLocationUtil.getDatasetLocationPath(workingDirectory, DATA_SET_CODE + 1, ch.systemsx.cisd.openbis.dss.generic.shared.Constants.DEFAULT_SHARE_ID, DATABASE_INSTANCE_UUID); assertEquals(FileUtilities.getRelativeFile(new File(workingDirectory, - ch.systemsx.cisd.openbis.dss.generic.shared.Constants.DEFAULT_SHARE_ID), datasetLocation1), dataSet1.recordedObject() + ch.systemsx.cisd.openbis.dss.generic.shared.Constants.DEFAULT_SHARE_ID), + datasetLocation1), dataSet1 .getLocation()); assertEquals(datasetLocation1, MockStorageProcessor.instance.rootDirs.get(0)); File incomingDir1 = MockStorageProcessor.instance.incomingDirs.get(0); @@ -380,17 +370,16 @@ public class JythonTopLevelDataSetRegistratorTest extends AbstractFileSystemTest incomingDir1); assertEquals("hello world1", FileUtilities.loadToString(new File(datasetLocation1, "read1.me")).trim()); - assertEquals(DATA_SET_CODE + 2, dataSetInfo2.recordedObject().getDataSetCode()); - assertEquals(DATA_SET_TYPE, dataSetInfo2.recordedObject().getDataSetType()); - assertEquals(experiment2.getIdentifier(), dataSetInfo2.recordedObject() - .getExperimentIdentifier().toString()); - assertEquals(DATA_SET_CODE + 2, dataSet2.recordedObject().getCode()); - assertEquals(DATA_SET_TYPE, dataSet2.recordedObject().getDataSetType()); + assertEquals(experiment2.getIdentifier(), dataSet2.getExperimentIdentifierOrNull() + .toString()); + assertEquals(DATA_SET_CODE + 2, dataSet2.getCode()); + assertEquals(DATA_SET_TYPE, dataSet2.getDataSetType()); File datasetLocation2 = DatasetLocationUtil.getDatasetLocationPath(workingDirectory, DATA_SET_CODE + 2, ch.systemsx.cisd.openbis.dss.generic.shared.Constants.DEFAULT_SHARE_ID, DATABASE_INSTANCE_UUID); assertEquals(FileUtilities.getRelativeFile(new File(workingDirectory, - ch.systemsx.cisd.openbis.dss.generic.shared.Constants.DEFAULT_SHARE_ID), datasetLocation2), dataSet2.recordedObject() + ch.systemsx.cisd.openbis.dss.generic.shared.Constants.DEFAULT_SHARE_ID), + datasetLocation2), dataSet2 .getLocation()); assertEquals(datasetLocation2, MockStorageProcessor.instance.rootDirs.get(1)); File incomingDir2 = MockStorageProcessor.instance.incomingDirs.get(1); @@ -427,6 +416,66 @@ public class JythonTopLevelDataSetRegistratorTest extends AbstractFileSystemTest MockStorageProcessor.instance.dataSetInfoString); } + // TODO KE: 2011-02-11 Make this test run + //@Test + public void testTransactionWithNewExperiment() + { + setUpHomeDataBaseExpectations(); + Properties properties = + createThreadProperties(SCRIPTS_FOLDER + "transaction-with-new-experiment.py"); + final File stagingDir = new File(workingDirectory, "staging"); + properties.setProperty(DataSetRegistrationService.STAGING_DIR, stagingDir.getPath()); + createHandler(properties, false, true); + createData(); + final ExperimentIdentifier experimentIdentifier = + ExperimentIdentifierFactory.parse("/SPACE/PROJECT/EXP"); + final RecordingMatcher<ch.systemsx.cisd.openbis.generic.shared.dto.AtomicEntityOperationDetails> atomicatOperationDetails = + new RecordingMatcher<ch.systemsx.cisd.openbis.generic.shared.dto.AtomicEntityOperationDetails>(); + context.checking(new Expectations() + { + { + one(openBisService).createDataSetCode(); + will(returnValue(DATA_SET_CODE)); + + one(openBisService).createDataSetCode(); + will(returnValue(EXPERIMENT_PERM_ID)); + + one(openBisService).tryToGetExperiment(experimentIdentifier); + will(returnValue(null)); + + one(dataSetValidator).assertValidDataSet(DATA_SET_TYPE, + new File(new File(stagingDir, DATA_SET_CODE), "sub_data_set_1")); + one(openBisService).performEntityOperations(with(atomicatOperationDetails)); + will(returnValue(new AtomicEntityOperationResult())); + } + }); + + handler.handle(markerFile); + + assertEquals(1, MockStorageProcessor.instance.incomingDirs.size()); + assertEquals(1, atomicatOperationDetails.recordedObject().getDataSetRegistrations().size()); + + NewExternalData dataSet = + atomicatOperationDetails.recordedObject().getDataSetRegistrations().get(0); + + assertEquals(DATA_SET_CODE, dataSet.getCode()); + assertEquals(DATA_SET_TYPE, dataSet.getDataSetType()); + File datasetLocation = + DatasetLocationUtil.getDatasetLocationPath(workingDirectory, DATA_SET_CODE, + ch.systemsx.cisd.openbis.dss.generic.shared.Constants.DEFAULT_SHARE_ID, + DATABASE_INSTANCE_UUID); + assertEquals(FileUtilities.getRelativeFile(new File(workingDirectory, + ch.systemsx.cisd.openbis.dss.generic.shared.Constants.DEFAULT_SHARE_ID), + datasetLocation), + + dataSet.getLocation()); + assertEquals(1, MockStorageProcessor.instance.calledCommitCount); + assertEquals(datasetLocation, MockStorageProcessor.instance.rootDirs.get(0)); + File incomingDir = MockStorageProcessor.instance.incomingDirs.get(0); + assertEquals(new File(new File(stagingDir, DATA_SET_CODE), "sub_data_set_1"), incomingDir); + context.assertIsSatisfied(); + } + @Test public void testScriptDies() { 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 8f77056b5b4..af63e7a9649 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 @@ -50,13 +50,14 @@ import ch.systemsx.cisd.etlserver.registrator.api.v1.IExperimentImmutable; import ch.systemsx.cisd.etlserver.validation.IDataSetValidator; import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService; import ch.systemsx.cisd.openbis.dss.generic.shared.dto.DataSetInformation; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.AtomicEntityOperationResult; 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.basic.dto.Experiment; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Person; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Project; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Space; -import ch.systemsx.cisd.openbis.generic.shared.dto.NewExternalData; +import ch.systemsx.cisd.openbis.generic.shared.dto.AtomicEntityOperationDetails; import ch.systemsx.cisd.openbis.generic.shared.dto.StorageFormat; import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifierFactory; @@ -157,7 +158,6 @@ public class DataSetRegistrationTransactionTest extends AbstractFileSystemTestCa rollbackQueueFiles = listRollbackQueueFiles(); assertEquals(0, rollbackQueueFiles.length); - // Commented out for the moment. context.assertIsSatisfied(); } @@ -365,14 +365,15 @@ public class DataSetRegistrationTransactionTest extends AbstractFileSystemTestCa .createIdentifier()); will(returnValue(experiment)); - exactly(1).of(openBisService).registerDataSet( - with(any(DataSetInformation.class)), - with(any(NewExternalData.class))); + exactly(1).of(openBisService).performEntityOperations( + with(any(AtomicEntityOperationDetails.class))); + will(returnValue(new AtomicEntityOperationResult())); } } }); } + private void setUpDataSetValidatorExpectations() { File dataSetDir = new File(stagingDirectory, DATA_SET_CODE + "1"); diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/transaction-with-new-experiment.py b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/transaction-with-new-experiment.py index 735a44c0d4e..02b475407c8 100644 --- a/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/transaction-with-new-experiment.py +++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/transaction-with-new-experiment.py @@ -2,5 +2,9 @@ transaction = service.transaction(incoming, factory) dataSet = transaction.createNewDataSet() transaction.moveFile(incoming.getPath() + '/sub_data_set_1', dataSet) dataSet.setDataSetType('O1') -dataSet.setExperiment(transaction.createNewExperiment('/SPACE/PROJECT/EXP')) + +experiment = transaction.createNewExperiment('/SPACE/PROJECT/EXP') +experiment.setPropertyValue('propCode', 'propValue') + +dataSet.setExperiment(experiment) diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/two-simple-transactions.py b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/two-simple-datasets.py similarity index 100% rename from datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/two-simple-transactions.py rename to datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/registrator/two-simple-datasets.py diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/AtomicEntityOperationResult.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/AtomicEntityOperationResult.java index 7a108148702..f1a6c9ae2ce 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/AtomicEntityOperationResult.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/basic/dto/AtomicEntityOperationResult.java @@ -18,6 +18,7 @@ package ch.systemsx.cisd.openbis.generic.shared.basic.dto; import java.io.Serializable; import java.util.ArrayList; +import java.util.Collections; import java.util.List; /** @@ -39,6 +40,12 @@ public class AtomicEntityOperationResult implements Serializable private final ArrayList<ExternalData> dataSetsCreated; + public AtomicEntityOperationResult() + { + this(Collections.<Experiment> emptyList(), Collections.<Sample> emptyList(), Collections + .<Sample> emptyList(), Collections.<ExternalData> emptyList()); + } + public AtomicEntityOperationResult(List<Experiment> experimentsCreated, List<Sample> samplesUpdated, List<Sample> samplesCreated, List<ExternalData> dataSetsCreated) diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/ExperimentIdentifierFactory.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/ExperimentIdentifierFactory.java index 5f7164e03f6..c8802de02ca 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/ExperimentIdentifierFactory.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/dto/identifier/ExperimentIdentifierFactory.java @@ -38,10 +38,10 @@ public final class ExperimentIdentifierFactory extends AbstractIdentifierFactory public final ExperimentIdentifier createIdentifier() throws UserFailureException { - return parseIdentifier(getTextToParse()); + return parse(getTextToParse()); } - private static ExperimentIdentifier parseIdentifier(final String text) + public static ExperimentIdentifier parse(final String text) { final TokenLexer lexer = new TokenLexer(text); final ProjectIdentifier parentIdentifier = ProjectIdentifierFactory.parseIdentifier(lexer); diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/util/EntityHelper.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/util/EntityHelper.java index 4fc488fb638..af5e4482464 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/util/EntityHelper.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/util/EntityHelper.java @@ -18,8 +18,10 @@ package ch.systemsx.cisd.openbis.generic.shared.util; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetType; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityKind; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityProperty; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityType; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExperimentType; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityPropertiesHolder; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.MaterialType; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType; @@ -77,15 +79,12 @@ public class EntityHelper /** * does the same as {@link #tryFindProperty(Iterable, String)} but with arrays. */ - // TODO 2011-01-13 KE : could we scratch the usage of arrays and only have lists ? - // if so, we could delete this method public static IEntityProperty tryFindProperty(IEntityProperty[] properties, final String propertyCode) { for (final IEntityProperty property : properties) { final PropertyType propertyType = property.getPropertyType(); - // TODO KE : ugly, why is the extracting logic not uppercasing ?? if (propertyType.getCode().equalsIgnoreCase(propertyCode)) { return property; @@ -93,4 +92,44 @@ public class EntityHelper } return null; } + + public static String tryFindPropertyValue(IEntityPropertiesHolder holder, String propertyCode) + { + IEntityProperty property = null; + + if (holder.getProperties() != null) + { + property = EntityHelper.tryFindProperty(holder.getProperties(), propertyCode); + } + + return (property != null) ? property.tryGetOriginalValue() : null; + } + + /** + * Tries to set the value for a given property in an {@link IEntityPropertiesHolder} instance. + * Creates a new property if no property for the specified code is found. + */ + public static void createOrUpdateProperty(IEntityPropertiesHolder holder, String propertyCode, + String propertyValue) + { + IEntityProperty property = tryFindProperty(holder.getProperties(), propertyCode); + + if (property == null) { + property = createNewProperty(propertyCode); + holder.getProperties().add(property); + } + property.setValue(propertyValue); + } + + + private static IEntityProperty createNewProperty(String propertyCode) + { + IEntityProperty property; + property = new EntityProperty(); + PropertyType propertyType = new PropertyType(); + propertyType.setCode(propertyCode); + property.setPropertyType(propertyType); + return property; + } + } -- GitLab