From 69392719a13a982ac4e6e14164e13ae9ad3ee917 Mon Sep 17 00:00:00 2001 From: pkupczyk <piotr.kupczyk@id.ethz.ch> Date: Fri, 31 Aug 2018 20:12:56 +0200 Subject: [PATCH] SSDM-7081 : openBIS sync: Support project samples --- .../plugins/sync/common/EntityRetriever.java | 25 ++++++++ .../plugins/sync/common/entitygraph/Node.java | 4 +- .../synchronizer/MasterDataParser.java | 2 +- .../synchronizer/ResourceListParser.java | 63 +++++++++++-------- .../openbis_test_openbis_sync_openbis1.sql | 8 ++- .../generic/asapi/v3/dto/sample/Sample.java | 4 +- 6 files changed, 74 insertions(+), 32 deletions(-) diff --git a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/common/EntityRetriever.java b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/common/EntityRetriever.java index 916481ae4e8..e06ea3716ef 100644 --- a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/common/EntityRetriever.java +++ b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/common/EntityRetriever.java @@ -133,6 +133,7 @@ public class EntityRetriever implements IEntityRetriever Node<Project> prjNode = new Node<Project>(project); graph.addNode(prjNode); addExperiments(prjNode); + addSamplesForProject(prjNode); } // add space samples @@ -164,8 +165,11 @@ public class EntityRetriever implements IEntityRetriever private void addSpaceSamples(String spaceCode) { + // Add samples that are connected with a space only (i.e. have project == null and experiment == null). + SampleSearchCriteria criteria = new SampleSearchCriteria(); criteria.withSpace().withCode().thatEquals(spaceCode); + criteria.withoutProject(); criteria.withoutExperiment(); criteria.withAndOperator(); @@ -195,6 +199,8 @@ public class EntityRetriever implements IEntityRetriever { for (Sample sample : expNode.getEntity().getSamples()) { + // Add samples that are connected with an experiment and optionally a project. + Node<Sample> sampleNode = new Node<Sample>(sample); graph.addEdge(expNode, sampleNode, new Edge(CONNECTION)); @@ -203,6 +209,23 @@ public class EntityRetriever implements IEntityRetriever } } + private void addSamplesForProject(Node<Project> prjNode) + { + for (Sample sample : prjNode.getEntity().getSamples()) + { + // Add samples that are connected with a project only (i.e. have experiment == null). + + if (sample.getExperiment() == null) + { + Node<Sample> sampleNode = new Node<Sample>(sample); + graph.addEdge(prjNode, sampleNode, new Edge(CONNECTION)); + + addDataSetsForSample(sampleNode); + addChildAndComponentSamples(sampleNode); + } + } + } + private void addDataSetsForExperiment(Node<Experiment> expNode) { for (DataSet dataSet : expNode.getEntity().getDataSets()) @@ -339,6 +362,7 @@ public class EntityRetriever implements IEntityRetriever fo.withSpace(); fo.withAttachments(); fo.withExperimentsUsing(createExperimentFetchOptions()); + fo.withSamplesUsing(createSampleFetchOptions()); return fo; } @@ -361,6 +385,7 @@ public class EntityRetriever implements IEntityRetriever fo.withDataSets(); fo.withType(); fo.withExperiment(); + fo.withProject(); fo.withSpace(); fo.withAttachments(); fo.withChildrenUsing(fo); diff --git a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/common/entitygraph/Node.java b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/common/entitygraph/Node.java index 0468aba9952..45e219ceb01 100644 --- a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/common/entitygraph/Node.java +++ b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/common/entitygraph/Node.java @@ -142,7 +142,9 @@ public class Node<T extends IModificationDateHolder & IModifierHolder & IRegistr { return null; } - return ((IProjectHolder) entity).getProject().getCode(); + + Project project = ((IProjectHolder) entity).getProject(); + return project != null ? project.getCode() : null; } public Sample getSampleOrNull() diff --git a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/MasterDataParser.java b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/MasterDataParser.java index 551fc823ebe..74cf84519b7 100644 --- a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/MasterDataParser.java +++ b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/MasterDataParser.java @@ -190,7 +190,7 @@ public class MasterDataParser String entityKind = getAttribute(pluginElement, "entityKind").trim(); plugin.setScriptType(ScriptType.valueOf(getAttribute(pluginElement, "type"))); plugin.setPluginType(PluginType.JYTHON); - plugin.setEntityKind(entityKind.equals("") ? null : new EntityKind[] { EntityKind.valueOf(entityKind) }); + plugin.setEntityKind((entityKind.equals("") || entityKind.equals("All")) ? null : new EntityKind[] { EntityKind.valueOf(entityKind) }); plugin.setScript(pluginElement.getTextContent()); validationPlugins.put(plugin.getName(), plugin); } diff --git a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/ResourceListParser.java b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/ResourceListParser.java index e1fa5a6b888..3fd1e797a8d 100644 --- a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/ResourceListParser.java +++ b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/ResourceListParser.java @@ -183,8 +183,7 @@ public class ResourceListParser if (uri.endsWith("MASTER_DATA/MASTER_DATA/M")) { parseMasterData(doc, xpath, uri); - } - else if (uri.endsWith("/M")) + } else if (uri.endsWith("/M")) { list.add(uri); } @@ -218,20 +217,16 @@ public class ResourceListParser if (SyncEntityKind.PROJECT.getLabel().equals(entityKind)) { parseProjectMetaData(xpath, extractPermIdFromURI(uri), xdNode, lastModificationDate); - } - else if (SyncEntityKind.EXPERIMENT.getLabel().equals(entityKind)) + } else if (SyncEntityKind.EXPERIMENT.getLabel().equals(entityKind)) { parseExperimentMetaData(xpath, extractPermIdFromURI(uri), xdNode, lastModificationDate); - } - else if (SyncEntityKind.SAMPLE.getLabel().equals(entityKind)) + } else if (SyncEntityKind.SAMPLE.getLabel().equals(entityKind)) { parseSampleMetaData(xpath, extractPermIdFromURI(uri), xdNode, lastModificationDate); - } - else if (SyncEntityKind.DATA_SET.getLabel().equals(entityKind)) + } else if (SyncEntityKind.DATA_SET.getLabel().equals(entityKind)) { parseDataSetMetaData(xpath, extractDataSetCodeFromURI(uri), xdNode, lastModificationDate); - } - else if (SyncEntityKind.MATERIAL.getLabel().equals(entityKind)) + } else if (SyncEntityKind.MATERIAL.getLabel().equals(entityKind)) { parseMaterialMetaData(xpath, extractMaterialCodeFromURI(uri), xdNode, lastModificationDate); } @@ -287,13 +282,11 @@ public class ResourceListParser { ds = new NewContainerDataSet(); ds.setDataSetKind(ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetKind.CONTAINER); - } - else if (dsKind.equals(DataSetKind.PHYSICAL.toString())) + } else if (dsKind.equals(DataSetKind.PHYSICAL.toString())) { ds = new NewExternalData(); ds.setDataSetKind(ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetKind.PHYSICAL); - } - else + } else { throw new IllegalArgumentException(dsKind + " data sets are currently not supported"); } @@ -318,13 +311,11 @@ public class ResourceListParser if (nullAllowed == false) { throw new IllegalArgumentException(attrName + " cannot be empty in Resource List"); - } - else + } else { return null; } - } - else + } else { return val.trim(); } @@ -392,14 +383,20 @@ public class ResourceListParser return new ProjectIdentifier(createSpaceIdentifier(space), code); } - private SampleIdentifier createSampleIdentifier(String code, String space) + private SampleIdentifier createSampleIdentifier(String code, String project, String space) { if (space == null) { return new SampleIdentifier(nameTranslator.translate(code)); + } else if (project == null) + { + SpaceIdentifier spaceIdentifier = createSpaceIdentifier(space); + return new SampleIdentifier(spaceIdentifier, code); + } else + { + ProjectIdentifier projectIdentifier = createProjectIdentifier(project, space); + return new SampleIdentifier(projectIdentifier, code); } - SpaceIdentifier spaceIdentifier = createSpaceIdentifier(space); - return new SampleIdentifier(spaceIdentifier, code); } private SpaceIdentifier createSpaceIdentifier(String space) @@ -499,7 +496,7 @@ public class ResourceListParser val = nameTranslator.translate(val); val = translateMaterialIdentifier(val); } - + } propertyType.setCode(translatedCode); property.setPropertyType(propertyType); @@ -507,7 +504,8 @@ public class ResourceListParser return property; } - private String translateMaterialIdentifier(String value) { + private String translateMaterialIdentifier(String value) + { if (StringUtils.isBlank(value)) { return null; @@ -526,6 +524,7 @@ public class ResourceListParser } return new MaterialIdentifier(code, typeCode).toString(); } + private void parseExperimentMetaData(XPath xpath, String permId, Node xdNode, Date lastModificationDate) { String code = extractCode(xdNode); @@ -547,14 +546,21 @@ public class ResourceListParser String code = extractCode(xdNode); String type = extractType(xdNode); String experiment = extractAttribute(xdNode, "experiment", true); + String project = extractAttribute(xdNode, "project", true); String space = extractSpace(xdNode, true); SampleType sampleType = new SampleType(); sampleType.setCode(type); - - SampleIdentifier identifier = createSampleIdentifier(code, space); + + if (false == StringUtils.isBlank(project) && StringUtils.isBlank(space)) + { + throw new IllegalArgumentException("Sample with perm id '" + permId + "' has 'project' attribute specified but 'space' attribute empty"); + } + + SampleIdentifier identifier = createSampleIdentifier(code, project, space); String expIdentifier = null; ExperimentIdentifier experimentIdentifier = getExperimentIdentifier(experiment); - if (experimentIdentifier != null) { + if (experimentIdentifier != null) + { expIdentifier = experimentIdentifier.toString(); } NewSample newSample = new NewSample(identifier.toString(), sampleType, null, null, @@ -565,6 +571,10 @@ public class ResourceListParser { newSample.setDefaultSpaceIdentifier(null); } + if (space != null && project != null) + { + newSample.setProjectIdentifier(createProjectIdentifier(project, space).toString()); + } IncomingSample incomingSample = data.new IncomingSample(newSample, lastModificationDate); data.getSamplesToProcess().put(permId, incomingSample); incomingSample.setHasAttachments(hasAttachments(xpath, xdNode)); @@ -618,4 +628,3 @@ public class ResourceListParser // System.out.print(url_node.item(ji).getNodeName() + ":" + url_node.item(ji).getAttributes().getNamedItem("kind")); // System.out.println(); // } - diff --git a/integration-tests/templates/test_openbis_sync/openbis_test_openbis_sync_openbis1.sql b/integration-tests/templates/test_openbis_sync/openbis_test_openbis_sync_openbis1.sql index b6a61ef6635..f89b3cb5faa 100644 --- a/integration-tests/templates/test_openbis_sync/openbis_test_openbis_sync_openbis1.sql +++ b/integration-tests/templates/test_openbis_sync/openbis_test_openbis_sync_openbis1.sql @@ -3757,8 +3757,12 @@ COPY sample_types (id, code, description, is_listable, generated_from_depth, par -- COPY samples_all (id, perm_id, code, expe_id, saty_id, registration_timestamp, modification_timestamp, pers_id_registerer, del_id, orig_del, space_id, samp_id_part_of, pers_id_modifier, code_unique_check, subcode_unique_check, version, proj_id) FROM stdin; -1 20161010123907442-1 DEFAULT 1 1 2016-10-10 12:39:07.442524+02 2016-10-10 12:39:07.442524+02 1 \N \N 1 \N \N DEFAULT,-1,-1,1 \N 0 \N -2 20161010125004966-2 PLATE 2 4 2016-10-10 12:50:06.971812+02 2016-10-10 12:50:06.971812+02 3 \N \N 2 \N 3 PLATE,-1,-1,2 \N 0 \N +1 20161010123907442-1 DEFAULT 1 1 2016-10-10 12:39:07.442524+02 2016-10-10 12:39:07.442524+02 1 \N \N 1 \N \N DEFAULT,-1,1,1 \N 0 1 +2 20161010125004966-2 PLATE 2 4 2016-10-10 12:50:06.971812+02 2016-10-10 12:50:06.971812+02 3 \N \N 2 \N 3 PLATE,-1,2,2 \N 0 2 +4 20180831173535244-10 TEST_PROJECT_SAMPLE \N 1 2018-08-31 17:35:35.244317+02 2018-08-31 17:35:35.244317+02 2 \N \N 2 \N 2 TEST_PROJECT_SAMPLE,-1,2,2 \N 0 2 +5 20180831173606541-11 TEST_SPACE_SAMPLE \N 1 2018-08-31 17:36:06.541746+02 2018-08-31 17:36:06.541746+02 2 \N \N 2 \N 2 TEST_SPACE_SAMPLE,-1,-1,2 \N 0 \N +6 20180831173625312-12 TEST_SHARED_SAMPLE \N 1 2018-08-31 17:36:25.31212+02 2018-08-31 17:36:25.31212+02 2 \N \N \N \N 2 TEST_SHARED_SAMPLE,-1,-1,-1 \N 0 \N +7 20180831173705648-13 TEST_EXPERIMENT_SAMPLE 2 1 2018-08-31 17:37:05.64806+02 2018-08-31 17:37:05.64806+02 2 \N \N 2 \N 2 TEST_EXPERIMENT_SAMPLE,-1,2,2 \N 0 2 \. diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/sample/Sample.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/sample/Sample.java index 1bef10b2218..134a4500a4f 100644 --- a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/sample/Sample.java +++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/sample/Sample.java @@ -27,6 +27,7 @@ import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IModificationD import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IModifierHolder; import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IParentChildrenHolder; import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IPermIdHolder; +import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IProjectHolder; import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IPropertiesHolder; import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IRegistrationDateHolder; import ch.ethz.sis.openbis.generic.asapi.v3.dto.common.interfaces.IRegistratorHolder; @@ -60,7 +61,7 @@ import java.util.Set; * Class automatically generated with DtoGenerator */ @JsonObject("as.dto.sample.Sample") -public class Sample implements Serializable, IAttachmentsHolder, ICodeHolder, IDataSetsHolder, IEntityTypeHolder, IExperimentHolder, IIdentifierHolder, IMaterialPropertiesHolder, IModificationDateHolder, IModifierHolder, IParentChildrenHolder<Sample>, IPermIdHolder, IPropertiesHolder, IRegistrationDateHolder, IRegistratorHolder, ISpaceHolder, ITagsHolder +public class Sample implements Serializable, IAttachmentsHolder, ICodeHolder, IDataSetsHolder, IEntityTypeHolder, IExperimentHolder, IIdentifierHolder, IMaterialPropertiesHolder, IModificationDateHolder, IModifierHolder, IParentChildrenHolder<Sample>, IPermIdHolder, IProjectHolder, IPropertiesHolder, IRegistrationDateHolder, IRegistratorHolder, ISpaceHolder, ITagsHolder { private static final long serialVersionUID = 1L; @@ -236,6 +237,7 @@ public class Sample implements Serializable, IAttachmentsHolder, ICodeHolder, ID // Method automatically generated with DtoGenerator @JsonIgnore + @Override public Project getProject() { if (getFetchOptions() != null && getFetchOptions().hasProject()) -- GitLab