From 9def66150b21799e96cf394ab240fd550db25435 Mon Sep 17 00:00:00 2001 From: felmer <felmer> Date: Thu, 5 Mar 2015 10:59:35 +0000 Subject: [PATCH] SSDM-1366: datastore_server: merge feature branch 'data-set-sample' with trunk. SVN: 33561 --- .../DataSetRegistrationAlgorithm.java | 27 +-- .../cisd/etlserver/DataStrategyStore.java | 168 +++++++++++------- .../SampleAndDataSetRegistrator.java | 6 +- .../TemplateBasedLinkNamingStrategy.java | 16 +- .../etlserver/plugins/grouping/Grouping.java | 8 +- .../Hdf5CompressingPostRegistrationTask.java | 4 +- .../api/v1/impl/DataSetImmutable.java | 63 +++++-- .../api/v2/impl/DataSetImmutable.java | 61 ++++++- .../dss/generic/server/MetaDataBuilder.java | 19 +- .../dss/generic/server/UploadingCommand.java | 12 +- .../AbstractDropboxProcessingPlugin.java | 30 +++- .../AbstractDataSetFileOperationsManager.java | 5 +- .../shared/ExperimentBasedShareFinder.java | 17 +- .../IdentifierAttributeMappingManager.java | 8 + .../TransferredDataSetHandlerTest.java | 13 +- 15 files changed, 318 insertions(+), 139 deletions(-) diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/DataSetRegistrationAlgorithm.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/DataSetRegistrationAlgorithm.java index 9e91c50cc81..cbfb5cff099 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/DataSetRegistrationAlgorithm.java +++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/DataSetRegistrationAlgorithm.java @@ -51,6 +51,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetType; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment; 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.SampleIdentifier; /** @@ -123,8 +124,6 @@ public class DataSetRegistrationAlgorithm private final String defaultErrorMessageTemplate; - private final String emailSubjectTemplate; - public DataSetRegistrationAlgorithmState(File incomingDataSetFile, IEncapsulatedOpenBISService openBisService, IDelegatedActionWithResult<Boolean> cleanAfterwardsAction, @@ -164,7 +163,6 @@ public class DataSetRegistrationAlgorithm dataSetInformation.setDataSetType(dataSetType); this.storeRoot = storageProcessor.getStoreRootDirectory(); this.defaultErrorMessageTemplate = DATA_SET_STORAGE_FAILURE_TEMPLATE; - this.emailSubjectTemplate = EMAIL_SUBJECT_TEMPLATE; } public File getIncomingDataSetFile() @@ -179,7 +177,7 @@ public class DataSetRegistrationAlgorithm static private final Logger operationLog = LogFactory.getLogger(LogCategory.OPERATION, DataSetRegistrationAlgorithm.class); - public static final String EMAIL_SUBJECT_TEMPLATE = "Success: data set for experiment '%s"; + public static final String EMAIL_SUBJECT_TEMPLATE = "Success: data set for sample or experiment '%s"; public static final String DATA_SET_REGISTRATION_FAILURE_TEMPLATE = "Registration of data set '%s' failed."; @@ -264,12 +262,9 @@ public class DataSetRegistrationAlgorithm boolean deleted = false; if (userEmailOrNull != null) { - final String errorMessage = - "Error when trying to register data set '" + incomingDataSetFile.getName() - + "'."; - state.mailClient.sendMessage(String.format(errorMessage, dataSetInformation - .getExperimentIdentifier().getExperimentCode()), ex.getMessage(), null, - null, userEmailOrNull); + final String errorMessage = "Error when trying to register data set '" + + incomingDataSetFile.getName() + "'."; + state.mailClient.sendMessage(errorMessage, ex.getMessage(), null, null, userEmailOrNull); if (state.shouldDeleteUnidentified) { deleted = removeAndLog(errorMessage + " [" + ex.getMessage() + "]"); @@ -498,8 +493,16 @@ public class DataSetRegistrationAlgorithm } if (StringUtils.isBlank(email) == false) { - state.mailClient.sendMessage(String.format(state.emailSubjectTemplate, - dataSetInformation.getExperimentIdentifier().getExperimentCode()), msg, + String code = dataSetInformation.getSampleCode(); + if (code == null) + { + ExperimentIdentifier experimentIdentifier = dataSetInformation.getExperimentIdentifier(); + if (experimentIdentifier != null) + { + code = experimentIdentifier.getExperimentCode(); + } + } + state.mailClient.sendMessage(String.format(EMAIL_SUBJECT_TEMPLATE, code), msg, null, null, email); } } diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/DataStrategyStore.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/DataStrategyStore.java index 55dacbe72fe..00d503a1dcf 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/DataStrategyStore.java +++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/DataStrategyStore.java @@ -36,6 +36,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty; 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.Space; import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifier; import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifier; @@ -50,6 +51,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifier; public class DataStrategyStore implements IDataStrategyStore { static final String SUBJECT_FORMAT = "ATTENTION: experiment '%s'"; + static final String SUBJECT_SAMPLE_FORMAT = "ATTENTION: sample '%s'"; private static final Logger notificationLog = LogFactory.getLogger(LogCategory.NOTIFY, DataStrategyStore.class); @@ -137,100 +139,65 @@ public class DataStrategyStore implements IDataStrategyStore return dataStoreStrategies.get(DataStoreStrategyKey.UNIDENTIFIED); } - if (dataSetInfo.isNoFileDataSet()) - { - assert incomingDataSetPath == null : "Incoming data set path for a no-file data set must be null"; - } else - { - assert incomingDataSetPath != null : "Incoming data set path for a normal data set can not be null."; - } - - String containerDatasetPermId = dataSetInfo.tryGetContainerDatasetPermId(); - if (containerDatasetPermId != null) - { - AbstractExternalData container = - openbisServiceWrapper.tryGetDataSet(containerDatasetPermId); - if (container != null) - { - dataSetInfo.setContainerDataSet(container); - } - } + assertIncomingDataSetPath(incomingDataSetPath, dataSetInfo); + injectContainerDataSet(dataSetInfo); String emailOrNull = dataSetInfo.tryGetUploadingUserEmail(); - ExperimentIdentifier experimentIdentifier; + ExperimentIdentifier experimentIdentifier = dataSetInfo.getExperimentIdentifier(); final SampleIdentifier sampleIdentifier = dataSetInfo.getSampleIdentifier(); if (sampleIdentifier == null) { - experimentIdentifier = dataSetInfo.getExperimentIdentifier(); - Experiment experiment = dataSetInfo.tryToGetExperiment(); - if (experiment == null) - { - experiment = openbisServiceWrapper.tryGetExperiment(experimentIdentifier); - } + Experiment experiment = tryGetExperiment(dataSetInfo); if (experiment == null) { error(emailOrNull, "Unknown experiment identifier '" + experimentIdentifier + "'."); return dataStoreStrategies.get(DataStoreStrategyKey.UNIDENTIFIED); } - if (experiment.getDeletion() != null) - { - error(emailOrNull, "Experiment '" + experimentIdentifier + "' has been deleted."); - return dataStoreStrategies.get(DataStoreStrategyKey.UNIDENTIFIED); - } dataSetInfo.setExperiment(experiment); } else { - Sample sample = dataSetInfo.tryToGetSample(); - if (sample == null) - { - sample = openbisServiceWrapper.tryGetSample(sampleIdentifier); - } - + Sample sample = tryGetSample(dataSetInfo); if (sample == null) { error(emailOrNull, createNotificationMessage(dataSetInfo, incomingDataSetPath)); return dataStoreStrategies.get(DataStoreStrategyKey.UNIDENTIFIED); } + dataSetInfo.setSample(sample); final Experiment experiment = sample.getExperiment(); if (experiment == null) { - error(emailOrNull, String.format("Data set for sample '%s' can not be registered " - + "because the sample is not attached to an experiment.", sampleIdentifier)); - return dataStoreStrategies.get(DataStoreStrategyKey.UNIDENTIFIED); - } else if (experiment.getDeletion() != null) + if (sample.getSpace() == null) + { + error(emailOrNull, String.format("Data set for sample '%s' can not be registered " + + "because the sample is a shared sample not assigned to a particular space.", + sampleIdentifier)); + return dataStoreStrategies.get(DataStoreStrategyKey.UNIDENTIFIED); + } + } else { - error(emailOrNull, String.format("Data set for sample '%s' can not be registered " - + "because experiment '%s' has been deleted.", sampleIdentifier, - experiment.getCode())); - return dataStoreStrategies.get(DataStoreStrategyKey.UNIDENTIFIED); + experimentIdentifier = new ExperimentIdentifier(experiment); + dataSetInfo.setExperimentIdentifier(experimentIdentifier); } - dataSetInfo.setSample(sample); - experimentIdentifier = new ExperimentIdentifier(experiment); - dataSetInfo.setExperimentIdentifier(experimentIdentifier); final IEntityProperty[] properties = openbisServiceWrapper.tryGetPropertiesOfSample(sampleIdentifier); if (properties == null) { - final Person registrator = experiment.getRegistrator(); + final Person registrator = experiment == null ? sample.getRegistrator() : experiment.getRegistrator(); assert registrator != null : "Registrator must be known"; final String message = createInvalidSampleCodeMessage(dataSetInfo); final String recipientMail = registrator.getEmail(); if (StringUtils.isNotBlank(recipientMail)) { - sendEmail(message, experimentIdentifier, recipientMail); + sendEmail(message, experimentIdentifier, sampleIdentifier, recipientMail); } else { error(emailOrNull, "The registrator '" + registrator + "' has a blank email, sending the following email failed:\n" + message); } - operationLog.error(String.format("Incoming data set '%s' claims to " - + "belong to experiment '%s' and sample" - + " identifier '%s', but according to the openBIS server " - + "there is no such sample for this " - + "experiment (maybe it has been deleted?). We thus consider it invalid.", - incomingDataSetPath, experimentIdentifier, sampleIdentifier)); + operationLog.error(createLogMessageForMissingSampleProperties(incomingDataSetPath, + experimentIdentifier, sampleIdentifier)); return dataStoreStrategies.get(DataStoreStrategyKey.INVALID); } dataSetInfo.setSampleProperties(properties); @@ -238,13 +205,87 @@ public class DataStrategyStore implements IDataStrategyStore if (operationLog.isInfoEnabled()) { - operationLog.info("Identified that database knows experiment '" + experimentIdentifier - + "'" - + (sampleIdentifier == null ? "." : " and sample '" + sampleIdentifier + "'.")); + operationLog.info(createLogMessageForIdentified(experimentIdentifier, sampleIdentifier)); } return dataStoreStrategies.get(DataStoreStrategyKey.IDENTIFIED); } + private String createLogMessageForIdentified(ExperimentIdentifier experimentIdentifier, + SampleIdentifier sampleIdentifier) + { + String prefix = "Identified that database knows "; + if (sampleIdentifier == null) + { + return prefix + "experiment '" + experimentIdentifier + "'."; + } else if (experimentIdentifier == null) + { + return prefix + "sample '" + sampleIdentifier + "'."; + } + return prefix + "experiment '" + experimentIdentifier + "' and sample '" + sampleIdentifier + "'."; + } + + private String createLogMessageForMissingSampleProperties(final File incomingDataSetPath, + ExperimentIdentifier experimentIdentifier, final SampleIdentifier sampleIdentifier) + { + String claimedOwner; + if (experimentIdentifier == null) + { + claimedOwner = String.format("sample '%s'", sampleIdentifier); + } else + { + claimedOwner = String.format("experiment '%s' and sample '%s'", + experimentIdentifier, sampleIdentifier); + } + return String.format("Incoming data set '%s' claims to belong to %s, but according to the openBIS server " + + "there is no such sample (maybe it has been deleted?). We thus consider it invalid.", + incomingDataSetPath, claimedOwner); + } + + public Sample tryGetSample(final DataSetInformation dataSetInfo) + { + Sample sample = dataSetInfo.tryToGetSample(); + if (sample == null) + { + sample = openbisServiceWrapper.tryGetSample(dataSetInfo.getSampleIdentifier()); + } + return sample; + } + + public Experiment tryGetExperiment(final DataSetInformation dataSetInfo) + { + Experiment experiment = dataSetInfo.tryToGetExperiment(); + if (experiment == null) + { + experiment = openbisServiceWrapper.tryGetExperiment(dataSetInfo.getExperimentIdentifier()); + } + return experiment; + } + + public void injectContainerDataSet(final DataSetInformation dataSetInfo) + { + String containerDatasetPermId = dataSetInfo.tryGetContainerDatasetPermId(); + if (containerDatasetPermId != null) + { + AbstractExternalData container = + openbisServiceWrapper.tryGetDataSet(containerDatasetPermId); + if (container != null) + { + dataSetInfo.setContainerDataSet(container); + } + } + } + + public void assertIncomingDataSetPath(final File incomingDataSetPath, final DataSetInformation dataSetInfo) + { + if (dataSetInfo.isNoFileDataSet()) + { + assert incomingDataSetPath == null : "Incoming data set path for a no-file data set must be null"; + } else + { + assert incomingDataSetPath != null : "Incoming data set path for a normal data set can not be null."; + } + } + private void error(String emailOrNull, String message) { if (emailOrNull == null) @@ -259,9 +300,16 @@ public class DataStrategyStore implements IDataStrategyStore } private void sendEmail(final String message, final ExperimentIdentifier experimentIdentifier, - final String recipientMail) + SampleIdentifier sampleIdentifier, final String recipientMail) { - final String subject = String.format(SUBJECT_FORMAT, experimentIdentifier); + final String subject; + if (experimentIdentifier == null) + { + subject = String.format(SUBJECT_SAMPLE_FORMAT, sampleIdentifier); + } else + { + subject = String.format(SUBJECT_FORMAT, experimentIdentifier); + } try { mailClient.sendMessage(subject, message, null, null, recipientMail); diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/entityregistration/SampleAndDataSetRegistrator.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/entityregistration/SampleAndDataSetRegistrator.java index 097138a8e77..e82a3f93fa3 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/entityregistration/SampleAndDataSetRegistrator.java +++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/entityregistration/SampleAndDataSetRegistrator.java @@ -79,7 +79,7 @@ class SampleAndDataSetRegistrator extends AbstractSampleAndDataSetProcessor impl try { checkDataSetFileNotEmpty(); - checkExperimentExists(); + injectExperiment(); retrieveSampleOrNull(); } catch (UserFailureException ex) { @@ -188,13 +188,13 @@ class SampleAndDataSetRegistrator extends AbstractSampleAndDataSetProcessor impl sampleOrNull = globalState.getOpenbisService().tryGetSampleWithExperiment(sampleIdentifier); } - private void checkExperimentExists() + private void injectExperiment() { ExperimentIdentifier experimentId = sampleDataSetPair.getDataSetInformation().getExperimentIdentifier(); if (null == experimentId) { - throw new UserFailureException("An experiment identifier must be specified"); + return; } Experiment experiment = globalState.getOpenbisService().tryGetExperiment(experimentId); diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/plugins/TemplateBasedLinkNamingStrategy.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/plugins/TemplateBasedLinkNamingStrategy.java index e88e246064d..9660f7d14e0 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/plugins/TemplateBasedLinkNamingStrategy.java +++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/plugins/TemplateBasedLinkNamingStrategy.java @@ -154,12 +154,7 @@ public class TemplateBasedLinkNamingStrategy implements IHierarchicalStorageLink @Override String extractValueFromData(SimpleDataSetInformationDTO data) { - String samplePathElement = data.getSampleCode(); - if (samplePathElement == null) - { - samplePathElement = NOT_DIRECTLY_CONNECTED; - } - return samplePathElement; + return getPathElement(data.getSampleCode()); } }, @@ -170,7 +165,7 @@ public class TemplateBasedLinkNamingStrategy implements IHierarchicalStorageLink @Override String extractValueFromData(SimpleDataSetInformationDTO data) { - return data.getExperimentCode(); + return getPathElement(data.getExperimentCode()); } }, @@ -180,7 +175,7 @@ public class TemplateBasedLinkNamingStrategy implements IHierarchicalStorageLink @Override String extractValueFromData(SimpleDataSetInformationDTO data) { - return data.getProjectCode(); + return getPathElement(data.getProjectCode()); } }, @@ -208,5 +203,10 @@ public class TemplateBasedLinkNamingStrategy implements IHierarchicalStorageLink abstract String extractValueFromData(SimpleDataSetInformationDTO data); + private static String getPathElement(String pathElement) + { + return pathElement == null ? NOT_DIRECTLY_CONNECTED : pathElement; + } + } } \ No newline at end of file diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/plugins/grouping/Grouping.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/plugins/grouping/Grouping.java index fd15217a20a..3be39aa57b5 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/plugins/grouping/Grouping.java +++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/plugins/grouping/Grouping.java @@ -17,6 +17,7 @@ package ch.systemsx.cisd.etlserver.plugins.grouping; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.AbstractExternalData; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample; /** @@ -37,7 +38,7 @@ public enum Grouping implements IGroupKeyProvider @Override public String getGroupKey(AbstractExternalData dataset) { - return dataset.getExperiment().getProject().getSpace().getCode(); + return dataset.getSpace().getCode(); } }, Project @@ -53,7 +54,8 @@ public enum Grouping implements IGroupKeyProvider @Override public String getGroupKey(AbstractExternalData dataset) { - return dataset.getExperiment().getIdentifier(); + Experiment experiment = dataset.getExperiment(); + return experiment != null ? experiment.getIdentifier() : "no_experiment"; } }, @@ -87,7 +89,7 @@ public enum Grouping implements IGroupKeyProvider @Override public String getGroupKey(AbstractExternalData dataset) { - return dataset.getExperiment().getIdentifier() + "#" + dataset.getDataSetType().getCode(); + return Experiment.getGroupKey(dataset) + "#" + DataSetType.getGroupKey(dataset); } } diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/postregistration/Hdf5CompressingPostRegistrationTask.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/postregistration/Hdf5CompressingPostRegistrationTask.java index 4308ea02a0b..629be03cead 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/postregistration/Hdf5CompressingPostRegistrationTask.java +++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/postregistration/Hdf5CompressingPostRegistrationTask.java @@ -46,6 +46,7 @@ import ch.systemsx.cisd.openbis.dss.generic.shared.dto.DataSetInformation; import ch.systemsx.cisd.openbis.generic.shared.basic.TechId; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Code; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ContainerDataSet; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PhysicalDataSet; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.AbstractExternalData; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty; @@ -433,7 +434,8 @@ public class Hdf5CompressingPostRegistrationTask extends AbstractPostRegistratio private ExperimentIdentifier extractExperimentIdentifier(AbstractExternalData data) { - return ExperimentIdentifierFactory.parse(data.getExperiment().getIdentifier()); + Experiment experiment = data.getExperiment(); + return experiment == null ? null : ExperimentIdentifierFactory.parse(experiment.getIdentifier()); } private SampleIdentifier extractSampleIdentifier(AbstractExternalData data) diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/DataSetImmutable.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/DataSetImmutable.java index 612d4945cac..921f79397b3 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/DataSetImmutable.java +++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/DataSetImmutable.java @@ -29,11 +29,13 @@ import ch.systemsx.cisd.openbis.dss.generic.shared.api.internal.v1.ISampleImmuta import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataSetType; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.id.IObjectId; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.id.dataset.DataSetCodeId; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.AbstractExternalData; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Code; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ContainerDataSet; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.AbstractExternalData; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalDataManagementSystem; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample; import ch.systemsx.cisd.openbis.generic.shared.util.EntityHelper; /** @@ -43,6 +45,52 @@ import ch.systemsx.cisd.openbis.generic.shared.util.EntityHelper; */ public class DataSetImmutable extends AbstractDataSetImmutable { + private static final class NullExperiment implements IExperimentImmutable + { + private String message; + + NullExperiment(String dataSetCode) + { + message = "No experiment defined for data set '" + dataSetCode + "'."; + } + + @Override + public IObjectId getEntityId() + { + throw new UnsupportedOperationException(message); + } + + @Override + public String getExperimentIdentifier() + { + throw new UnsupportedOperationException(message); + } + + @Override + public boolean isExistingExperiment() + { + return false; + } + + @Override + public String getExperimentType() + { + return null; + } + + @Override + public String getPropertyValue(String propertyCode) + { + return null; + } + + @Override + public String getPermId() + { + throw new UnsupportedOperationException(message); + } + } + protected final AbstractExternalData dataSet; public DataSetImmutable(AbstractExternalData dataSet, IEncapsulatedBasicOpenBISService service) @@ -66,20 +114,15 @@ public class DataSetImmutable extends AbstractDataSetImmutable @Override public IExperimentImmutable getExperiment() { - return new ExperimentImmutable(dataSet.getExperiment()); + Experiment experiment = dataSet.getExperiment(); + return experiment == null ? new NullExperiment(getDataSetCode()) : new ExperimentImmutable(experiment); } @Override public ISampleImmutable getSample() { - ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample sample = dataSet.getSample(); - if (sample == null) - { - return null; - } else - { - return new SampleImmutable(sample); - } + Sample sample = dataSet.getSample(); + return sample == null ? null : new SampleImmutable(sample); } @Override diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v2/impl/DataSetImmutable.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v2/impl/DataSetImmutable.java index 2da13d1f84f..40e83d1c231 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v2/impl/DataSetImmutable.java +++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v2/impl/DataSetImmutable.java @@ -32,8 +32,10 @@ import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.id.dataset.DataSetCode import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Code; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ContainerDataSet; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.AbstractExternalData; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalDataManagementSystem; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample; import ch.systemsx.cisd.openbis.generic.shared.util.EntityHelper; /** @@ -43,6 +45,52 @@ import ch.systemsx.cisd.openbis.generic.shared.util.EntityHelper; */ public class DataSetImmutable extends AbstractDataSetImmutable { + private static final class NullExperiment implements IExperimentImmutable + { + private String message; + + NullExperiment(String dataSetCode) + { + message = "No experiment defined for data set '" + dataSetCode + "'."; + } + + @Override + public IObjectId getEntityId() + { + throw new UnsupportedOperationException(message); + } + + @Override + public String getExperimentIdentifier() + { + throw new UnsupportedOperationException(message); + } + + @Override + public boolean isExistingExperiment() + { + return false; + } + + @Override + public String getExperimentType() + { + return null; + } + + @Override + public String getPropertyValue(String propertyCode) + { + return null; + } + + @Override + public String getPermId() + { + throw new UnsupportedOperationException(message); + } + } + protected final AbstractExternalData dataSet; public DataSetImmutable(AbstractExternalData dataSet, IEncapsulatedBasicOpenBISService service) @@ -66,20 +114,15 @@ public class DataSetImmutable extends AbstractDataSetImmutable @Override public IExperimentImmutable getExperiment() { - return new ExperimentImmutable(dataSet.getExperiment()); + Experiment experiment = dataSet.getExperiment(); + return experiment == null ? new NullExperiment(getDataSetCode()) : new ExperimentImmutable(experiment); } @Override public ISampleImmutable getSample() { - ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample sample = dataSet.getSample(); - if (sample == null) - { - return null; - } else - { - return new SampleImmutable(sample); - } + Sample sample = dataSet.getSample(); + return sample == null ? null : new SampleImmutable(sample); } @Override diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/MetaDataBuilder.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/MetaDataBuilder.java index fc8934a5f12..ee9363997cf 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/MetaDataBuilder.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/MetaDataBuilder.java @@ -130,14 +130,17 @@ public class MetaDataBuilder builder.sampleProperties(sample.getProperties()); } Experiment experiment = dataSet.getExperiment(); - Project project = experiment.getProject(); - builder.experiment("space_code", project.getSpace().getCode()); - builder.experiment("project_code", project.getCode()); - builder.experiment("experiment_code", experiment.getCode()); - builder.experiment("experiment_type_code", experiment.getExperimentType().getCode()); - builder.experiment("registration_timestamp", experiment.getRegistrationDate()); - builder.experiment("registrator", experiment.getRegistrator()); - builder.experimentProperties(experiment.getProperties()); + if (experiment != null) + { + Project project = experiment.getProject(); + builder.experiment("space_code", project.getSpace().getCode()); + builder.experiment("project_code", project.getCode()); + builder.experiment("experiment_code", experiment.getCode()); + builder.experiment("experiment_type_code", experiment.getExperimentType().getCode()); + builder.experiment("registration_timestamp", experiment.getRegistrationDate()); + builder.experiment("registrator", experiment.getRegistrator()); + builder.experimentProperties(experiment.getProperties()); + } return builder.getRenderedMetaData(); } diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/UploadingCommand.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/UploadingCommand.java index 0adce36e2a7..ea9c31dc70f 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/UploadingCommand.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/UploadingCommand.java @@ -326,9 +326,15 @@ class UploadingCommand implements IDataSetCommand { Sample sample = dataSet.getSample(); Experiment experiment = dataSet.getExperiment(); - Project project = experiment.getProject(); - return project.getSpace().getCode() + "/" + project.getCode() + "/" + experiment.getCode() - + "/" + (sample == null ? "" : sample.getCode() + "/") + dataSet.getCode(); + if (experiment != null) + { + Project project = experiment.getProject(); + return project.getSpace().getCode() + "/" + project.getCode() + "/" + experiment.getCode() + + "/" + (sample == null ? "" : sample.getCode() + "/") + dataSet.getCode(); + } else + { + return sample.getSpace().getCode() + "/" + sample.getCode() + "/" + dataSet.getCode(); + } } private void sendEMail(String message) diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/AbstractDropboxProcessingPlugin.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/AbstractDropboxProcessingPlugin.java index 3bfae5ee1c3..057e02fb439 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/AbstractDropboxProcessingPlugin.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/AbstractDropboxProcessingPlugin.java @@ -40,6 +40,8 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.BasicConstant; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetType; import ch.systemsx.cisd.openbis.generic.shared.dto.DatasetDescription; import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifier; +import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifier; +import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SpaceIdentifier; /** * The base class for processing plugins that employ a {@link IPostRegistrationDatasetHandler}. @@ -116,9 +118,10 @@ abstract public class AbstractDropboxProcessingPlugin extends AbstractDatastoreP render(dataSetDescription.getSampleIdentifier(), dataSetDescription.getSampleTypeCode()); boolean withSample = sampleOrNull != null; + boolean withExperiment = experiment != null; boolean processingFailed = status.isError(); String processingDescription = getProcessingDescription(dataSetDescription, context); - Template template = getEMailMessageTemplate(processingFailed, withSample).createFreshCopy(); + Template template = getEMailMessageTemplate(processingFailed, withSample, withExperiment).createFreshCopy(); String subject; if (processingFailed) { @@ -130,7 +133,10 @@ abstract public class AbstractDropboxProcessingPlugin extends AbstractDatastoreP } template.bind("processing-description", processingDescription); template.bind("data-set", dataSet); - template.bind("experiment", experiment); + if (withExperiment) + { + template.bind("experiment", experiment); + } if (withSample) { template.bind("sample", sampleOrNull); @@ -144,14 +150,14 @@ abstract public class AbstractDropboxProcessingPlugin extends AbstractDatastoreP mailClient.sendEmailMessage(subject, template.createText(), null, null, eMailAddress); } - private Template getEMailMessageTemplate(boolean withError, boolean withSample) + private Template getEMailMessageTemplate(boolean withError, boolean withSample, boolean withExperiment) { return new Template( (withError ? "Processing of data set ${data-set} failed.\nReason: ${error}" : "Successfully processed data set ${data-set}.") + "\n\nProcessing details:\n" + "Description: ${processing-description}\n" - + "Experiment: ${experiment}\n" + + (withExperiment ? "Experiment: ${experiment}\n" : "") + (withSample ? "Sample: ${sample}\n" : "") + "Started: ${start-time}.\n" + "Finished: ${end-time}."); } @@ -201,10 +207,18 @@ abstract public class AbstractDropboxProcessingPlugin extends AbstractDatastoreP datasetInfo.setSampleCode(dataset.getSampleCode()); datasetInfo.setSpaceCode(dataset.getSpaceCode()); datasetInfo.setDataSetCode(dataset.getDataSetCode()); - ExperimentIdentifier expIdent = - new ExperimentIdentifier(null, dataset.getSpaceCode(), dataset.getProjectCode(), - dataset.getExperimentCode()); - datasetInfo.setExperimentIdentifier(expIdent); + if (dataset.getExperimentCode() != null) + { + ExperimentIdentifier expIdent = + new ExperimentIdentifier(null, dataset.getSpaceCode(), dataset.getProjectCode(), + dataset.getExperimentCode()); + datasetInfo.setExperimentIdentifier(expIdent); + } + if (dataset.getSampleCode() != null) + { + SpaceIdentifier spaceIdentifier = new SpaceIdentifier(dataset.getSpaceCode()); + datasetInfo.setSampleIdentifier(new SampleIdentifier(spaceIdentifier, dataset.getSampleCode())); + } return datasetInfo; } diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/archiver/AbstractDataSetFileOperationsManager.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/archiver/AbstractDataSetFileOperationsManager.java index 5d6187ea24c..1f4d65d59ba 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/archiver/AbstractDataSetFileOperationsManager.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/plugins/standard/archiver/AbstractDataSetFileOperationsManager.java @@ -91,7 +91,10 @@ public abstract class AbstractDataSetFileOperationsManager { AbstractExternalData dataSet = getService().tryGetDataSet(datasetDescription.getDataSetCode()); String experimentIdentifier = datasetDescription.getExperimentIdentifier(); - dataSet.setExperiment(getService().tryGetExperiment(ExperimentIdentifierFactory.parse(experimentIdentifier))); + if (experimentIdentifier != null) + { + dataSet.setExperiment(getService().tryGetExperiment(ExperimentIdentifierFactory.parse(experimentIdentifier))); + } String sampleIdentifier = datasetDescription.getSampleIdentifier(); if (sampleIdentifier != null) { diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/ExperimentBasedShareFinder.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/ExperimentBasedShareFinder.java index da9b9daf483..64f5c0875b3 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/ExperimentBasedShareFinder.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/ExperimentBasedShareFinder.java @@ -42,15 +42,18 @@ public class ExperimentBasedShareFinder implements IShareFinder @Override public Share tryToFindShare(SimpleDataSetInformationDTO dataSet, List<Share> shares) { - String experimentIdentifier = - new ExperimentIdentifier(null, dataSet.getSpaceCode(), dataSet.getProjectCode(), - dataSet.getExperimentCode()).toString(); - for (Share share : shares) + if (dataSet.getExperimentCode() != null) { - if (share.getExperimentIdentifiers().contains(experimentIdentifier) - && share.calculateFreeSpace() > dataSet.getDataSetSize()) + String experimentIdentifier = + new ExperimentIdentifier(null, dataSet.getSpaceCode(), dataSet.getProjectCode(), + dataSet.getExperimentCode()).toString(); + for (Share share : shares) { - return share; + if (share.getExperimentIdentifiers().contains(experimentIdentifier) + && share.calculateFreeSpace() > dataSet.getDataSetSize()) + { + return share; + } } } return null; diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/IdentifierAttributeMappingManager.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/IdentifierAttributeMappingManager.java index d0feefffc9a..e12b21f2652 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/IdentifierAttributeMappingManager.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/IdentifierAttributeMappingManager.java @@ -270,12 +270,20 @@ public class IdentifierAttributeMappingManager private Attributes tryGetExperimentAttributes(String spaceCode, String projectCode, String experimentCode) { + if (experimentCode == null) + { + return null; + } String identifier = new ExperimentIdentifier(null, spaceCode, projectCode, experimentCode).toString(); return getAttributesMap().get(identifier); } private Attributes tryGetProjectAttributes(String spaceCode, String projectCode) { + if (projectCode == null) + { + return null; + } String identifier = new ProjectIdentifier(null, spaceCode, projectCode).toString(); return getAttributesMap().get(identifier); } diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/TransferredDataSetHandlerTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/TransferredDataSetHandlerTest.java index 044e6ced80c..3e4b4c97aab 100644 --- a/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/TransferredDataSetHandlerTest.java +++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/TransferredDataSetHandlerTest.java @@ -77,6 +77,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.NewExternalData; import ch.systemsx.cisd.openbis.generic.shared.dto.OpenBISSessionHolder; 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.SampleIdentifier; import ch.systemsx.cisd.openbis.util.LogRecordingUtils; /** @@ -486,9 +487,11 @@ public final class TransferredDataSetHandlerTest extends AbstractFileSystemTestC private final void checkSuccessEmailNotification(final Expectations expectations, final DataSetInformation dataSet, final String dataSetCode, final String recipient) { + SampleIdentifier sampleIdentifier = dataSet.getSampleIdentifier(); + String code = sampleIdentifier != null ? sampleIdentifier.getSampleCode() : + dataSet.getExperimentIdentifier().getExperimentCode(); expectations.one(mailClient).sendMessage( - String.format(DataSetRegistrationHelper.EMAIL_SUBJECT_TEMPLATE, dataSet - .getExperimentIdentifier().getExperimentCode()), + String.format(DataSetRegistrationHelper.EMAIL_SUBJECT_TEMPLATE, code), getNotificationEmailContent(dataSet, dataSetCode), null, null, recipient); } @@ -662,10 +665,8 @@ public final class TransferredDataSetHandlerTest extends AbstractFileSystemTestC assertEquals(false, isFinishedData1.exists()); assertLog("ERROR OPERATION.DataStrategyStore - " + "Incoming data set '<wd>/data1' claims to belong to experiment " - + "'/GROUP1/PROJECT1/EXPERIMENT1' and sample identifier '/" - + SAMPLE_CODE - + "', " - + "but according to the openBIS server there is no such sample for this experiment " + + "'/GROUP1/PROJECT1/EXPERIMENT1' and sample '/" + SAMPLE_CODE + "', " + + "but according to the openBIS server there is no such sample " + "(maybe it has been deleted?). We thus consider it invalid." + OSUtilities.LINE_SEPARATOR + "INFO OPERATION.FileRenamer - " + "Moving file 'data1' from '<wd>' to '<wd>/1/invalid/DataSetType_O1'."); -- GitLab