From 94e909c9120a9f80b4ec847231a8b395b69b94b5 Mon Sep 17 00:00:00 2001
From: gakin <gakin>
Date: Thu, 6 Apr 2017 10:11:56 +0000
Subject: [PATCH] SSDM-5017 OpenbisSync Handle updated/removed properties
 properly for non-physical data sets

SVN: 38024
---
 .../synchronizer/DSPropertyUtils.java         | 56 +++++++++++++++++++
 .../DataSetRegistrationIngestionService.java  | 13 +----
 .../synchronizer/EntitySynchronizer.java      | 33 +++++++----
 3 files changed, 79 insertions(+), 23 deletions(-)
 create mode 100644 datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/DSPropertyUtils.java

diff --git a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/DSPropertyUtils.java b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/DSPropertyUtils.java
new file mode 100644
index 00000000000..0db251e86fb
--- /dev/null
+++ b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/DSPropertyUtils.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2017 ETH Zuerich, SIS
+ *
+ * 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.ethz.sis.openbis.generic.server.dss.plugins.sync.harvester.synchronizer;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty;
+import ch.systemsx.cisd.openbis.generic.shared.basic.dto.builders.PropertyBuilder;
+import ch.systemsx.cisd.openbis.generic.shared.dto.NewProperty;
+
+/**
+ * 
+ *
+ * @author Ganime Betul Akin
+ */
+public class DSPropertyUtils
+{
+    static Set<String> extractPropertyNames(List<NewProperty> dataSetProperties)
+    {
+        Set<String> existingPropertyNames = new HashSet<String>();
+        for (NewProperty prop : dataSetProperties)
+        {
+            existingPropertyNames.add(prop.getPropertyCode());
+        }
+        return existingPropertyNames;
+    }
+
+    static IEntityProperty[] convertToEntityProperty(List<NewProperty> dataSetProperties)
+    {
+        ArrayList<IEntityProperty> list = new ArrayList<IEntityProperty>();
+        for (NewProperty prop : dataSetProperties)
+        {
+            String propertyCode = prop.getPropertyCode();
+            String value = prop.getValue();
+            list.add(new PropertyBuilder(propertyCode).value(value).getProperty());
+        }
+        return list.toArray(new IEntityProperty[list.size()]);
+    }
+}
diff --git a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/DataSetRegistrationIngestionService.java b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/DataSetRegistrationIngestionService.java
index ff9501f12cf..d0e73beb849 100644
--- a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/DataSetRegistrationIngestionService.java
+++ b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/DataSetRegistrationIngestionService.java
@@ -23,7 +23,6 @@ import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -141,7 +140,7 @@ class DataSetRegistrationIngestionService extends IngestionService<DataSetInform
 
             // synchronize property changes including properties that were set to empty values
             List<String> existingPropertyCodes = dataSetForUpdate.getAllPropertyCodes();
-            Set<String> newPropertyCodes = extractPropertyNames(dataSetProperties);
+            Set<String> newPropertyCodes = DSPropertyUtils.extractPropertyNames(dataSetProperties);
             for (NewProperty newProperty : dataSetProperties)
             {
                 dataSetForUpdate.setPropertyValue(newProperty.getPropertyCode(), newProperty.getValue());
@@ -166,16 +165,6 @@ class DataSetRegistrationIngestionService extends IngestionService<DataSetInform
         return builder.getTableModel();
     }
 
-    private Set<String> extractPropertyNames(List<NewProperty> dataSetProperties)
-    {
-        Set<String> existingPropertyNames = new HashSet<String>();
-        for (NewProperty prop : dataSetProperties)
-        {
-            existingPropertyNames.add(prop.getPropertyCode());
-        }
-        return existingPropertyNames;
-    }
-
     class FileDetails
     {
         final int crc32checksum;
diff --git a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/EntitySynchronizer.java b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/EntitySynchronizer.java
index 8574607bd5a..6d100124413 100644
--- a/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/EntitySynchronizer.java
+++ b/datastore_server/source/java/ch/ethz/sis/openbis/generic/server/dss/plugins/sync/harvester/synchronizer/EntitySynchronizer.java
@@ -111,14 +111,12 @@ 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.basic.dto.TableModel;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TableModelColumnHeader;
-import ch.systemsx.cisd.openbis.generic.shared.basic.dto.builders.PropertyBuilder;
 import ch.systemsx.cisd.openbis.generic.shared.dto.AtomicEntityOperationResult;
 import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetBatchUpdatesDTO;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentUpdatesDTO;
 import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialUpdateDTO;
 import ch.systemsx.cisd.openbis.generic.shared.dto.NewContainerDataSet;
 import ch.systemsx.cisd.openbis.generic.shared.dto.NewExternalData;
-import ch.systemsx.cisd.openbis.generic.shared.dto.NewProperty;
 import ch.systemsx.cisd.openbis.generic.shared.dto.ProjectUpdatesDTO;
 import ch.systemsx.cisd.openbis.generic.shared.dto.SampleUpdatesDTO;
 import ch.systemsx.cisd.openbis.generic.shared.dto.builders.AtomicEntityOperationDetailsBuilder;
@@ -358,6 +356,13 @@ public class EntitySynchronizer
                 continue;
             }
             DataSetBatchUpdatesDTO dsBatchUpdatesDTO = createDataSetBatchUpdateDTO(dataSet, dsInHarvester);
+
+            // mark the properties to be updated otherwise properties that were reset (set to empty values) will not be carried over
+            Set<String> resetPropertyList =
+                    getResetPropertyList(DSPropertyUtils.convertToEntityProperty(dataSet.getDataSetProperties()), dsInHarvester.getProperties());
+            Set<String> propertiesToUpdate = dsBatchUpdatesDTO.getDetails().getPropertiesToUpdate();
+            propertiesToUpdate.addAll(resetPropertyList);
+            dsBatchUpdatesDTO.getDetails().setPropertiesToUpdate(propertiesToUpdate);
             if (dataSet instanceof NewContainerDataSet)
             {
                 NewContainerDataSet containerDS = (NewContainerDataSet) dataSet;
@@ -995,6 +1000,15 @@ public class EntitySynchronizer
         return incomingProperties;
     }
 
+    private Set<String> getResetPropertyList(IEntityProperty[] iEntityProperties, List<IEntityProperty> existingProperties)
+    {
+        ArrayList<IEntityProperty> incomingProperties = new ArrayList<IEntityProperty>(Arrays.asList(iEntityProperties));
+        Set<String> existingPropertyNames = extractPropertyNames(existingProperties);
+        Set<String> newPropertyNames = extractPropertyNames(incomingProperties);
+        existingPropertyNames.removeAll(newPropertyNames);
+        return existingPropertyNames;
+    }
+
     private Set<String> extractPropertyNames(List<IEntityProperty> existingProperties)
     {
         Set<String> existingPropertyNames = new HashSet<String>();
@@ -1160,20 +1174,17 @@ public class EntitySynchronizer
         return new String(Hex.encodeHex(digest));
     }
 
-    private DataSetBatchUpdatesDTO createDataSetBatchUpdateDTO(NewExternalData childDS, AbstractExternalData dsInHarvester)
+    private DataSetBatchUpdatesDTO createDataSetBatchUpdateDTO(NewExternalData dataSet, AbstractExternalData dsInHarvester)
     {
         ch.systemsx.cisd.etlserver.registrator.api.v1.impl.DataSetUpdatable updateUpdatable = new
                 ch.systemsx.cisd.etlserver.registrator.api.v1.impl.DataSetUpdatable(dsInHarvester, service);
         DataSetBatchUpdatesDTO dsBatchUpdatesDTO = ConversionUtils.convertToDataSetBatchUpdatesDTO(updateUpdatable);
         dsBatchUpdatesDTO.setDatasetId(TechId.create(dsInHarvester));
-        List<IEntityProperty> entityProperties = new ArrayList<IEntityProperty>();
-        for (NewProperty prop : childDS.getDataSetProperties())
-        {
-            String propertyCode = prop.getPropertyCode();
-            String value = prop.getValue();
-            entityProperties.add(new PropertyBuilder(propertyCode).value(value).getProperty());
-        }
-        dsBatchUpdatesDTO.setProperties(entityProperties);
+
+        List<IEntityProperty> updatedProperties =
+                prepareUpdatedPropertyList(DSPropertyUtils.convertToEntityProperty(dataSet.getDataSetProperties()), dsInHarvester.getProperties());
+
+        dsBatchUpdatesDTO.setProperties(updatedProperties);
         return dsBatchUpdatesDTO;
     }
 
-- 
GitLab