From a8edb1d41b401c6c9bd18e55ea3cfb73c33ebcff Mon Sep 17 00:00:00 2001
From: jakubs <jakubs>
Date: Mon, 5 Oct 2015 15:07:20 +0000
Subject: [PATCH] SSDM-2276: add cache of many entities for data set
 registrations in entity operations

SVN: 34787
---
 .../server/ServiceForDataStoreServer.java     |  59 ++++++---
 .../generic/server/business/bo/DataBO.java    | 104 ++++++++++++---
 .../generic/server/business/bo/IDataBO.java   |   6 +-
 .../bo/util/DataSetRegistrationCache.java     | 122 ++++++++++++++++++
 .../generic/server/ETLServiceTest.java        |  32 +++++
 .../server/business/bo/DataBOTest.java        |   6 +-
 6 files changed, 290 insertions(+), 39 deletions(-)
 create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/util/DataSetRegistrationCache.java

diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ServiceForDataStoreServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ServiceForDataStoreServer.java
index d1c2f6f0624..7289a9818cf 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ServiceForDataStoreServer.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ServiceForDataStoreServer.java
@@ -98,6 +98,7 @@ import ch.systemsx.cisd.openbis.generic.server.business.bo.datasetlister.IDatase
 import ch.systemsx.cisd.openbis.generic.server.business.bo.fetchoptions.experimentlister.ExperimentLister;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.materiallister.IMaterialLister;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.samplelister.ISampleLister;
+import ch.systemsx.cisd.openbis.generic.server.business.bo.util.DataSetRegistrationCache;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDataDAO;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDataSetTypeDAO;
@@ -912,9 +913,10 @@ public class ServiceForDataStoreServer extends AbstractCommonServer<IServiceForD
             registerExperiment(session, experiment);
         }
 
+        DataSetRegistrationCache cache = new DataSetRegistrationCache();
         for (NewExternalData dataSet : collection.getNewDataSets())
         {
-            registerDataSetInternal(session, dataSet);
+            registerDataSetInternal(session, dataSet, cache);
         }
     }
 
@@ -1002,7 +1004,7 @@ public class ServiceForDataStoreServer extends AbstractCommonServer<IServiceForD
         assert sampleIdentifier != null : "Unspecified sample identifier.";
 
         final Session session = getSession(sessionToken);
-        registerDataSetInternal(session, sampleIdentifier, externalData);
+        registerDataSetInternal(session, sampleIdentifier, externalData, new DataSetRegistrationCache());
     }
 
     @Override
@@ -1016,7 +1018,7 @@ public class ServiceForDataStoreServer extends AbstractCommonServer<IServiceForD
         assert experimentIdentifier != null : "Unspecified experiment identifier.";
 
         final Session session = getSession(sessionToken);
-        registerDataSetInternal(session, experimentIdentifier, externalData);
+        registerDataSetInternal(session, experimentIdentifier, externalData, null);
     }
 
     @Override
@@ -1538,7 +1540,7 @@ public class ServiceForDataStoreServer extends AbstractCommonServer<IServiceForD
         SamplePE samplePE = registerSampleInternal(session, newSample, userIdOrNull);
 
         // Register the data set
-        registerDataSetInternal(getSession(sessionToken), samplePE, externalData);
+        registerDataSetInternal(getSession(sessionToken), samplePE, externalData, new DataSetRegistrationCache());
         Sample result =
                 SampleTranslator.translate(samplePE, session.getBaseIndexURL(), null,
                         managedPropertyEvaluatorFactory);
@@ -1558,7 +1560,7 @@ public class ServiceForDataStoreServer extends AbstractCommonServer<IServiceForD
 
         // Register the data set
         final SamplePE samplePE = sampleBO.getSample();
-        registerDataSetInternal(getSession(sessionToken), samplePE, externalData);
+        registerDataSetInternal(getSession(sessionToken), samplePE, externalData, new DataSetRegistrationCache());
 
         Collection<MetaprojectPE> metaprojectPEs =
                 getDAOFactory().getMetaprojectDAO().listMetaprojectsForEntity(
@@ -2411,11 +2413,13 @@ public class ServiceForDataStoreServer extends AbstractCommonServer<IServiceForD
             total += dependencyLevel.size();
         }
         int index = 0;
+
+        DataSetRegistrationCache cache = new DataSetRegistrationCache();
         for (List<NewExternalData> dependencyLevel : orderedRegistrations)
         {
             for (NewExternalData dataSet : dependencyLevel)
             {
-                registerDataSetInternal(session, dataSet);
+                registerDataSetInternal(session, dataSet, cache);
                 progress.update("createDataSets", total, ++index);
             }
         }
@@ -2469,16 +2473,16 @@ public class ServiceForDataStoreServer extends AbstractCommonServer<IServiceForD
         }
     }
 
-    private void registerDataSetInternal(final Session session, NewExternalData dataSet)
+    private IDataBO registerDataSetInternal(final Session session, NewExternalData dataSet, DataSetRegistrationCache cache)
     {
         SampleIdentifier sampleIdentifier = dataSet.getSampleIdentifierOrNull();
         if (sampleIdentifier != null)
         {
-            registerDataSetInternal(session, sampleIdentifier, dataSet);
+            return registerDataSetInternal(session, sampleIdentifier, dataSet, cache);
         } else
         {
             ExperimentIdentifier experimentIdentifier = dataSet.getExperimentIdentifierOrNull();
-            registerDataSetInternal(session, experimentIdentifier, dataSet);
+            return registerDataSetInternal(session, experimentIdentifier, dataSet, cache);
         }
     }
 
@@ -2544,19 +2548,30 @@ public class ServiceForDataStoreServer extends AbstractCommonServer<IServiceForD
     }
 
     private IDataBO registerDataSetInternal(final Session session,
-            SampleIdentifier sampleIdentifier, NewExternalData externalData)
+            SampleIdentifier sampleIdentifier, NewExternalData externalData, DataSetRegistrationCache cache)
     {
-        final ISampleBO sampleBO = businessObjectFactory.createSampleBO(session);
-        sampleBO.loadBySampleIdentifier(sampleIdentifier);
-        return registerDataSetInternal(session, sampleBO.getSample(), externalData);
+        SamplePE sample = cache.getSamples().get(sampleIdentifier);
+
+        if (sample == null)
+        {
+            final ISampleBO sampleBO = businessObjectFactory.createSampleBO(session);
+            sampleBO.loadBySampleIdentifier(sampleIdentifier);
+            sample = sampleBO.getSample();
+            cache.getSamples().put(sampleIdentifier, sample);
+        }
+
+        return registerDataSetInternal(session, sample, externalData, cache);
     }
 
     private IDataBO registerDataSetInternal(final Session session, SamplePE sample,
-            NewExternalData externalData)
+            NewExternalData externalData, DataSetRegistrationCache cache)
     {
-        final IDataBO dataBO = businessObjectFactory.createDataBO(session);
+        final IDataBO dataBO = cache.getDataBO() != null ? cache.getDataBO() : businessObjectFactory.createDataBO(session);
+        cache.setDataBO(dataBO);
+
         SourceType sourceType =
                 externalData.isMeasured() ? SourceType.MEASUREMENT : SourceType.DERIVED;
+        dataBO.setCache(cache);
         dataBO.define(externalData, sample, sourceType);
         dataBO.save();
 
@@ -2573,9 +2588,14 @@ public class ServiceForDataStoreServer extends AbstractCommonServer<IServiceForD
     }
 
     private IDataBO registerDataSetInternal(final Session session,
-            ExperimentIdentifier experimentIdentifier, NewExternalData externalData)
+            ExperimentIdentifier experimentIdentifier, NewExternalData externalData, DataSetRegistrationCache cache)
     {
-        ExperimentPE experiment = tryLoadExperimentByIdentifier(session, experimentIdentifier);
+        if (false == cache.getExperiments().containsKey(experimentIdentifier))
+        {
+            cache.getExperiments().put(experimentIdentifier, tryLoadExperimentByIdentifier(session, experimentIdentifier));
+        }
+        ExperimentPE experiment = cache.getExperiments().get(experimentIdentifier);
+
         if (experiment == null)
         {
             throw new UserFailureException("Unknown experiment '" + experimentIdentifier + "'.");
@@ -2585,9 +2605,12 @@ public class ServiceForDataStoreServer extends AbstractCommonServer<IServiceForD
             throw new UserFailureException("Data set can not be registered because experiment '"
                     + experiment.getIdentifier() + "' is in trash.");
         }
-        final IDataBO externalDataBO = businessObjectFactory.createDataBO(session);
+        final IDataBO externalDataBO = cache.getDataBO() != null ? cache.getDataBO() : businessObjectFactory.createDataBO(session);
+        cache.setDataBO(externalDataBO);
+
         SourceType sourceType =
                 externalData.isMeasured() ? SourceType.MEASUREMENT : SourceType.DERIVED;
+        externalDataBO.setCache(cache);
         externalDataBO.define(externalData, experiment, sourceType);
         externalDataBO.save();
 
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataBO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataBO.java
index b4ac03abfa3..9242eb6a9d3 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataBO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataBO.java
@@ -31,6 +31,7 @@ import ch.rinn.restrictions.Friend;
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
 import ch.systemsx.cisd.openbis.generic.server.business.IRelationshipService;
 import ch.systemsx.cisd.openbis.generic.server.business.IServiceConversationClientManagerLocal;
+import ch.systemsx.cisd.openbis.generic.server.business.bo.util.DataSetRegistrationCache;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.util.DataSetTypeWithoutExperimentChecker;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDataDAO;
@@ -61,6 +62,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.ExternalDataManagementSystemP
 import ch.systemsx.cisd.openbis.generic.shared.dto.ExternalDataPE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.FileFormatTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.dto.LinkDataPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.LocatorTypePE;
 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.NewLinkDataSet;
@@ -295,7 +297,12 @@ public class DataBO extends AbstractDataSetBusinessObject implements IDataBO
         {
             for (String parentCode : parentDataSetCodes)
             {
-                final DataPE parent = getOrCreateData(parentCode, experiment, sample);
+                DataPE parent = this.getCache().getParentDataSets().get(parentCode);
+                if (parent == null)
+                {
+                    parent = getOrCreateData(parentCode, experiment, sample);
+                    this.getCache().getParentDataSets().put(parentCode, parent);
+                }
                 parentsToAdd.add(parent);
             }
         }
@@ -344,12 +351,12 @@ public class DataBO extends AbstractDataSetBusinessObject implements IDataBO
         externalData.setSpeedHint(newData.getSpeedHint());
         externalData.setStorageFormatVocabularyTerm(tryToFindStorageFormatTerm(newData
                 .getStorageFormat()));
-        externalData.setLocatorType(getLocatorTypeDAO().tryToFindLocatorTypeByCode(
-                locatorType.getCode()));
+        externalData.setLocatorType(tryToFindLocatorTypeByCode(locatorType));
+
         PersonPE registrator = tryToGetRegistrator(newData);
         externalData.setRegistrator(registrator);
         RelationshipUtils.updateModificationDateAndModifier(externalData, registrator);
-        dataStore = getDataStoreDAO().tryToFindDataStoreByCode(newData.getDataStoreCode());
+        dataStore = tryToFindDataStoreByCode(newData.getDataStoreCode());
         externalData.setDataStore(dataStore);
         defineDataSetProperties(externalData,
                 convertToDataSetProperties(newData.getDataSetProperties()));
@@ -358,6 +365,31 @@ public class DataBO extends AbstractDataSetBusinessObject implements IDataBO
         data = externalData;
     }
 
+    private DataStorePE tryToFindDataStoreByCode(String dataStoreCode)
+    {
+        DataStorePE dataStorePe = this.getCache().getDataStores().get(dataStoreCode);
+
+        if (dataStorePe == null)
+        {
+            dataStorePe = getDataStoreDAO().tryToFindDataStoreByCode(dataStoreCode);
+            this.getCache().getDataStores().put(dataStoreCode, dataStorePe);
+        }
+        return dataStorePe;
+    }
+
+    private LocatorTypePE tryToFindLocatorTypeByCode(final LocatorType locatorType)
+    {
+        LocatorTypePE locatorTypePe = this.getCache().getLocatorTypes().get(locatorType.getCode());
+        if (locatorTypePe == null)
+        {
+            locatorTypePe = getLocatorTypeDAO().tryToFindLocatorTypeByCode(
+                    locatorType.getCode());
+            this.getCache().getLocatorTypes().put(locatorType.getCode(), locatorTypePe);
+
+        }
+        return locatorTypePe;
+    }
+
     private void define(NewContainerDataSet newData, SourceType sourceType)
     {
         assert newData != null : "Undefined data.";
@@ -374,7 +406,7 @@ public class DataBO extends AbstractDataSetBusinessObject implements IDataBO
         PersonPE registrator = tryToGetRegistrator(newData);
         dataPE.setRegistrator(registrator);
         RelationshipUtils.updateModificationDateAndModifier(dataPE, registrator);
-        dataStore = getDataStoreDAO().tryToFindDataStoreByCode(newData.getDataStoreCode());
+        dataStore = tryToFindDataStoreByCode(newData.getDataStoreCode());
         dataPE.setDataStore(dataStore);
         defineDataSetProperties(dataPE, convertToDataSetProperties(newData.getDataSetProperties()));
         dataPE.setDerived(sourceType == SourceType.DERIVED);
@@ -404,7 +436,7 @@ public class DataBO extends AbstractDataSetBusinessObject implements IDataBO
         dataPE.setCode(newData.getCode());
         dataPE.setDataSetType(getDataSetType(dataSetType, DataSetKind.LINK));
         dataPE.setRegistrator(tryToGetRegistrator(newData));
-        dataStore = getDataStoreDAO().tryToFindDataStoreByCode(newData.getDataStoreCode());
+        dataStore = tryToFindDataStoreByCode(newData.getDataStoreCode());
         dataPE.setDataStore(dataStore);
         defineDataSetProperties(dataPE, convertToDataSetProperties(newData.getDataSetProperties()));
         dataPE.setDerived(sourceType == SourceType.DERIVED);
@@ -438,8 +470,14 @@ public class DataBO extends AbstractDataSetBusinessObject implements IDataBO
     private VocabularyTermPE tryToFindStorageFormatTerm(StorageFormat storageFormat)
     {
         IVocabularyDAO vocabularyDAO = getVocabularyDAO();
-        VocabularyPE vocabulary =
-                vocabularyDAO.tryFindVocabularyByCode(StorageFormat.VOCABULARY_CODE);
+
+        VocabularyPE vocabulary = this.getCache().getStorageFormatVocabulary();
+
+        if (vocabulary == null)
+        {
+            vocabulary = vocabularyDAO.tryFindVocabularyByCode(StorageFormat.VOCABULARY_CODE);
+            this.getCache().setStorageFormatVocabulary(vocabulary);
+        }
         Set<VocabularyTermPE> terms = vocabulary.getTerms();
         for (VocabularyTermPE term : terms)
         {
@@ -455,8 +493,15 @@ public class DataBO extends AbstractDataSetBusinessObject implements IDataBO
             DataSetKind expectedDataSetKind)
     {
         final String dataSetTypeCode = dataSetType.getCode();
-        final DataSetTypePE dataSetTypeOrNull =
-                getDataSetTypeDAO().tryToFindDataSetTypeByCode(dataSetTypeCode);
+
+        DataSetTypePE dataSetTypeOrNull = this.getCache().getDataSetTypes().get(dataSetTypeCode);
+
+        if (dataSetTypeOrNull == null)
+        {
+            dataSetTypeOrNull = getDataSetTypeDAO().tryToFindDataSetTypeByCode(dataSetTypeCode);
+            this.getCache().getDataSetTypes().put(dataSetTypeCode, dataSetTypeOrNull);
+        }
+
         if (dataSetTypeOrNull == null)
         {
             throw UserFailureException.fromTemplate("There is no data set type with code '%s'",
@@ -477,8 +522,15 @@ public class DataBO extends AbstractDataSetBusinessObject implements IDataBO
     private final FileFormatTypePE getFileFomatType(final FileFormatType fileFormatType)
     {
         final String fileFormatTypeCode = fileFormatType.getCode();
-        final FileFormatTypePE fileFormatTypeOrNull =
-                getFileFormatTypeDAO().tryToFindFileFormatTypeByCode(fileFormatTypeCode);
+
+        FileFormatTypePE fileFormatTypeOrNull = this.getCache().getFileFormatTypes().get(fileFormatTypeCode);
+
+        if (fileFormatTypeOrNull == null)
+        {
+            fileFormatTypeOrNull =
+                    getFileFormatTypeDAO().tryToFindFileFormatTypeByCode(fileFormatTypeCode);
+            this.getCache().getFileFormatTypes().put(fileFormatTypeCode, fileFormatTypeOrNull);
+        }
         if (fileFormatTypeOrNull == null)
         {
             throw UserFailureException.fromTemplate("There is no file format type with code '%s'",
@@ -547,7 +599,7 @@ public class DataBO extends AbstractDataSetBusinessObject implements IDataBO
             dataDAO.updateDataSet(data, findPerson());
         }
         entityPropertiesConverter.checkMandatoryProperties(data.getProperties(),
-                data.getDataSetType());
+                data.getDataSetType(), this.getCache().getEntityTypePropertyTypes());
     }
 
     @Override
@@ -556,7 +608,7 @@ public class DataBO extends AbstractDataSetBusinessObject implements IDataBO
         loadByCode(dataSetCode);
         updatePropertiesPreservingExisting(properties);
         entityPropertiesConverter.checkMandatoryProperties(data.getProperties(),
-                data.getDataSetType());
+                data.getDataSetType(), this.getCache().getEntityTypePropertyTypes());
         validateAndSave();
     }
 
@@ -604,9 +656,9 @@ public class DataBO extends AbstractDataSetBusinessObject implements IDataBO
     }
 
     @Override
-    public void assignDataSetToSampleAndExperiment(DataPE data, SamplePE sample, ExperimentPE experiment)
+    public void assignDataSetToSampleAndExperiment(DataPE dataSet, SamplePE sample, ExperimentPE experiment)
     {
-        super.assignDataSetToSampleAndExperiment(data, sample, experiment);
+        super.assignDataSetToSampleAndExperiment(dataSet, sample, experiment);
     }
 
     @Override
@@ -635,7 +687,7 @@ public class DataBO extends AbstractDataSetBusinessObject implements IDataBO
         updateProperties(data.getEntityType(), updates.getProperties(), extractPropertiesCodes(updates.getProperties()), data, data);
 
         entityPropertiesConverter.checkMandatoryProperties(data.getProperties(),
-                data.getDataSetType());
+                data.getDataSetType(), this.getCache().getEntityTypePropertyTypes());
 
         data.setModificationDate(new Date(data.getModificationDate().getTime() + 1));
         validateAndSave();
@@ -838,4 +890,22 @@ public class DataBO extends AbstractDataSetBusinessObject implements IDataBO
         }
         return true;
     }
+
+    private DataSetRegistrationCache cache;
+
+    @Override
+    public void setCache(DataSetRegistrationCache cache)
+    {
+        this.cache = cache;
+    }
+
+    @Override
+    public DataSetRegistrationCache getCache()
+    {
+        if (this.cache == null)
+        {
+            this.cache = new DataSetRegistrationCache();
+        }
+        return this.cache;
+    }
 }
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IDataBO.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IDataBO.java
index ea45cee532d..6f82ed54e8b 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IDataBO.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IDataBO.java
@@ -20,6 +20,7 @@ import java.util.List;
 import java.util.Map;
 
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
+import ch.systemsx.cisd.openbis.generic.server.business.bo.util.DataSetRegistrationCache;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetArchivingStatus;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SourceType;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.api.IManagedProperty;
@@ -31,7 +32,6 @@ 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.SamplePE;
-import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifier;
 
 /**
  * @author Franz-Josef Elmer
@@ -69,6 +69,10 @@ public interface IDataBO extends IEntityBusinessObject
      */
     public void define(NewExternalData data, ExperimentPE experiment, SourceType sourceType);
 
+    public void setCache(DataSetRegistrationCache cache);
+
+    public DataSetRegistrationCache getCache();
+
     /**
      * Changes given data set. Currently allowed changes: properties, sample, parents, components.
      */
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/util/DataSetRegistrationCache.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/util/DataSetRegistrationCache.java
new file mode 100644
index 00000000000..fe18e2ba14d
--- /dev/null
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/util/DataSetRegistrationCache.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2015 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.openbis.generic.server.business.bo.util;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import ch.systemsx.cisd.openbis.generic.server.business.bo.IDataBO;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetTypePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.DataStorePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.EntityTypePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.EntityTypePropertyTypePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.FileFormatTypePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.LocatorTypePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.VocabularyPE;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ExperimentIdentifier;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifier;
+
+/**
+ * @author Jakub Straszewski
+ */
+public class DataSetRegistrationCache
+{
+    private HashMap<ExperimentIdentifier, ExperimentPE> experiments = new HashMap<>();
+
+    private HashMap<SampleIdentifier, SamplePE> samples = new HashMap<>();
+
+    private HashMap<String, DataSetTypePE> dataSetTypes = new HashMap<>();
+
+    private VocabularyPE storageFormatVocabulary;
+
+    private HashMap<String, LocatorTypePE> locatorTypeByCode = new HashMap<>();
+
+    private HashMap<String, FileFormatTypePE> fileFormatTypeByCode = new HashMap<>();
+
+    private HashMap<String, DataStorePE> dataStores = new HashMap<>();
+
+    private Map<EntityTypePE, List<EntityTypePropertyTypePE>> entityTypePropertyTypes = new HashMap<>();
+
+    private Map<String, DataPE> parentDataSets = new HashMap<>();
+
+    public Map<String, DataPE> getParentDataSets()
+    {
+        return parentDataSets;
+    }
+
+    public Map<EntityTypePE, List<EntityTypePropertyTypePE>> getEntityTypePropertyTypes()
+    {
+        return entityTypePropertyTypes;
+    }
+
+    public HashMap<String, DataStorePE> getDataStores()
+    {
+        return dataStores;
+    }
+
+    public HashMap<String, FileFormatTypePE> getFileFormatTypes()
+    {
+        return fileFormatTypeByCode;
+    }
+
+    public HashMap<String, LocatorTypePE> getLocatorTypes()
+    {
+        return locatorTypeByCode;
+    }
+
+    public VocabularyPE getStorageFormatVocabulary()
+    {
+        return storageFormatVocabulary;
+    }
+
+    public void setStorageFormatVocabulary(VocabularyPE storageFormatVocabulary)
+    {
+        this.storageFormatVocabulary = storageFormatVocabulary;
+    }
+
+    private IDataBO dataBO;
+
+    public IDataBO getDataBO()
+    {
+        return dataBO;
+    }
+
+    public void setDataBO(IDataBO dataBO)
+    {
+        this.dataBO = dataBO;
+    }
+
+    public HashMap<ExperimentIdentifier, ExperimentPE> getExperiments()
+    {
+        return experiments;
+    }
+
+    public HashMap<SampleIdentifier, SamplePE> getSamples()
+    {
+        return samples;
+    }
+
+    public HashMap<String, DataSetTypePE> getDataSetTypes()
+    {
+        return dataSetTypes;
+    }
+
+}
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/ETLServiceTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/ETLServiceTest.java
index e43e6fafe7f..8902e5ee415 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/ETLServiceTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/ETLServiceTest.java
@@ -30,6 +30,8 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
 import org.jmock.Expectations;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
@@ -42,6 +44,7 @@ import ch.systemsx.cisd.openbis.generic.server.business.IDataStoreServiceFactory
 import ch.systemsx.cisd.openbis.generic.server.business.IServiceConversationClientManagerLocal;
 import ch.systemsx.cisd.openbis.generic.server.business.IServiceConversationServerManagerLocal;
 import ch.systemsx.cisd.openbis.generic.server.business.bo.ICommonBusinessObjectFactory;
+import ch.systemsx.cisd.openbis.generic.server.business.bo.util.DataSetRegistrationCache;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDataStoreDataSourceManager;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.PersistencyResources;
 import ch.systemsx.cisd.openbis.generic.shared.AbstractServerTestCase;
@@ -175,6 +178,8 @@ public class ETLServiceTest extends AbstractServerTestCase
 
     private ISessionManager<Session> sessionManagerForEntityOperations;
 
+    private DataSetRegistrationCache dataSetRegistrationCache;
+
     private IManagedPropertyEvaluatorFactory managedPropertyEvaluatorFactory;
 
     private PersonPE sessionPerson;
@@ -200,6 +205,8 @@ public class ETLServiceTest extends AbstractServerTestCase
         sessionPerson = new PersonPE();
         session.setPerson(sessionPerson);
         managedPropertyEvaluatorFactory = new ManagedPropertyEvaluatorFactory(null, new TestJythonEvaluatorPool());
+
+        prepareDataSetRegistrationCache();
     }
 
     @Test
@@ -474,6 +481,31 @@ public class ETLServiceTest extends AbstractServerTestCase
             });
     }
 
+    private void prepareDataSetRegistrationCache()
+    {
+        context.checking(new Expectations()
+            {
+                {
+                    allowing(dataBO).setCache(with(new BaseMatcher<DataSetRegistrationCache>()
+                        {
+                            @Override
+                            public boolean matches(Object arg0)
+                            {
+                                dataSetRegistrationCache = (DataSetRegistrationCache) arg0;
+                                return true;
+                            }
+
+                            @Override
+                            public void describeTo(Description arg0)
+                            {
+                            }
+                        }));
+                    allowing(dataBO).getCache();
+                    will(returnValue(dataSetRegistrationCache));
+                }
+            });
+    }
+
     @Test
     public void testCreatePermId()
     {
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataBOTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataBOTest.java
index 1f86b993ff9..46824dfcf93 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataBOTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataBOTest.java
@@ -24,6 +24,7 @@ import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Date;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedHashSet;
 import java.util.List;
@@ -614,8 +615,7 @@ public class DataBOTest extends AbstractBOTest
                     fileFormatTypePE.setCode(FILE_FORMAT_TYPE.getCode());
                     will(returnValue(fileFormatTypePE));
 
-                    one(propertiesConverter).checkMandatoryProperties(
-                            Collections.<DataSetPropertyPE> emptySet(), dataSet.getDataSetType());
+                    expectMandatoryPropertiesCheck(this, dataSet.getDataSetType());
 
                     allowing(dataDAO).validateAndSaveUpdatedEntity(dataSet);
                 }
@@ -1114,7 +1114,7 @@ public class DataBOTest extends AbstractBOTest
     private void expectMandatoryPropertiesCheck(Expectations exp, final DataSetTypePE type)
     {
         exp.one(propertiesConverter).checkMandatoryProperties(
-                exp.with(Expectations.any(Collection.class)), exp.with(type));
+                exp.with(Expectations.any(Collection.class)), exp.with(type), exp.with(Expectations.any(HashMap.class)));
     }
 
     private DataSetTypePE createDataSetType()
-- 
GitLab