From 97c292ce4899e8debc84e3f32738237f7ea4e47c Mon Sep 17 00:00:00 2001
From: cramakri <cramakri>
Date: Wed, 27 Jun 2012 19:24:37 +0000
Subject: [PATCH] BIS-94 SP-145 : Track and throw an exception of the contained
 samples are not available in the DSS-side DTO.

SVN: 25901
---
 .../api/v1/impl/SampleImmutable.java          | 46 ++++++++++++
 .../api/v1/impl/SearchService.java            | 11 ++-
 .../api/internal/v1/ISampleImmutable.java     | 12 ++-
 .../systemtests/SearchServiceTest.java        | 73 +++++++++++++++++++
 4 files changed, 138 insertions(+), 4 deletions(-)
 create mode 100644 datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/datastoreserver/systemtests/SearchServiceTest.java

diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/SampleImmutable.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/SampleImmutable.java
index bb5a0d23409..14f3ba7af66 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/SampleImmutable.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/SampleImmutable.java
@@ -17,12 +17,14 @@
 package ch.systemsx.cisd.etlserver.registrator.api.v1.impl;
 
 import java.util.ArrayList;
+import java.util.EnumSet;
 import java.util.List;
 import java.util.Set;
 
 import ch.systemsx.cisd.common.exceptions.UserFailureException;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.internal.v1.IExperimentImmutable;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.internal.v1.ISampleImmutable;
+import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SampleFetchOption;
 import ch.systemsx.cisd.openbis.generic.shared.util.EntityHelper;
 
 /**
@@ -32,17 +34,51 @@ public class SampleImmutable implements ISampleImmutable
 {
     private final ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample sample;
 
+    private final EnumSet<SampleFetchOption> retrievedFetchOptions;
+
     private final boolean existingSample;
 
+    /**
+     * Creates a new object that wraps the sample, which is assumed be an existing sample with all
+     * fetch options retrieved.
+     * 
+     * @param sample The sample to wrap.
+     */
     public SampleImmutable(ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample sample)
     {
         this(sample, true);
     }
 
+    /**
+     * Creates a new object that wraps the sample, which is assumed be an existing sample.
+     * 
+     * @param sample The sample to wrap.
+     * @param retrievedFetchOptions The fetch options the sample includes.
+     */
+    public SampleImmutable(ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample sample,
+            EnumSet<SampleFetchOption> retrievedFetchOptions)
+    {
+        this(sample, retrievedFetchOptions, true);
+    }
+
+    /**
+     * Creates a new object that wraps the sample, which is assumed to have all fetch options
+     * retrieved.
+     * 
+     * @param sample The sample to wrap.
+     * @param existingSample True if the sample exists in the DB.
+     */
     public SampleImmutable(ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample sample,
             boolean existingSample)
+    {
+        this(sample, EnumSet.allOf(SampleFetchOption.class), existingSample);
+    }
+
+    public SampleImmutable(ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample sample,
+            EnumSet<SampleFetchOption> retrievedFetchOptions, boolean existingSample)
     {
         this.sample = sample;
+        this.retrievedFetchOptions = retrievedFetchOptions;
         this.existingSample = existingSample;
     }
 
@@ -120,6 +156,10 @@ public class SampleImmutable implements ISampleImmutable
     @Override
     public List<ISampleImmutable> getContainedSamples()
     {
+        if (false == canGetContainedSamples())
+        {
+            throw new IllegalStateException("Contained samples were not returned by the server.");
+        }
         List<ISampleImmutable> result = new ArrayList<ISampleImmutable>();
         List<ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample> containedSamples =
                 sample.tryGetContainedSamples();
@@ -147,6 +187,12 @@ public class SampleImmutable implements ISampleImmutable
         return parentIdentifiers;
     }
 
+    @Override
+    public boolean canGetContainedSamples()
+    {
+        return retrievedFetchOptions.contains(SampleFetchOption.CONTAINED);
+    }
+
     @Override
     public int hashCode()
     {
diff --git a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/SearchService.java b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/SearchService.java
index e3819323d1c..b8319f52b86 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/SearchService.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/etlserver/registrator/api/v1/impl/SearchService.java
@@ -17,6 +17,7 @@
 package ch.systemsx.cisd.etlserver.registrator.api.v1.impl;
 
 import java.util.ArrayList;
+import java.util.EnumSet;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -30,6 +31,7 @@ import ch.systemsx.cisd.openbis.dss.generic.shared.api.internal.v1.IMaterialImmu
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.internal.v1.ISampleImmutable;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.internal.v1.ISearchService;
 import ch.systemsx.cisd.openbis.dss.generic.shared.api.internal.v1.MaterialIdentifierCollection;
+import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SampleFetchOption;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchCriteria;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchCriteria.MatchClause;
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchCriteria.MatchClauseAttribute;
@@ -46,7 +48,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ProjectIdentifierF
 /**
  * @author Chandrasekhar Ramakrishnan
  */
-class SearchService implements ISearchService
+public class SearchService implements ISearchService
 {
     private final IEncapsulatedOpenBISService openBisService;
 
@@ -134,7 +136,9 @@ class SearchService implements ISearchService
         ArrayList<ISampleImmutable> samples = new ArrayList<ISampleImmutable>(serverSamples.size());
         for (Sample sample : serverSamples)
         {
-            samples.add(new SampleImmutable(sample));
+            // Search for samples only returns the basic object with with properties.
+            samples.add(new SampleImmutable(sample, EnumSet.of(SampleFetchOption.BASIC,
+                    SampleFetchOption.PROPERTIES)));
         }
         return samples;
     }
@@ -185,7 +189,8 @@ class SearchService implements ISearchService
             MaterialType materialType = new MaterialType();
             materialType.setCode(typeCode);
             List<ch.systemsx.cisd.openbis.generic.shared.basic.dto.Material> materialsOfType =
-                    openBisService.listMaterials(ListMaterialCriteria.createFromMaterialType(materialType), true);
+                    openBisService.listMaterials(
+                            ListMaterialCriteria.createFromMaterialType(materialType), true);
             accumulatedResults.addAll(materialsOfType);
         }
         return accumulatedResults;
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/internal/v1/ISampleImmutable.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/internal/v1/ISampleImmutable.java
index eed9ca55fcc..5d685958688 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/internal/v1/ISampleImmutable.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/internal/v1/ISampleImmutable.java
@@ -63,10 +63,20 @@ public interface ISampleImmutable
 
     /**
      * Return the contained sample objects. Only available for samples existing prior the
-     * transaction start.
+     * transaction start that were obtained from the server with their contained samples included.
+     * Call {@link #canReturnContainedSamples()} to see if these can be provided.
+     * 
+     * @throws IllegalStateException If the contained samples cannot be returned.
      */
     List<ISampleImmutable> getContainedSamples();
 
+    /**
+     * Return true if this sample object has contained samples available. This is independent of
+     * whether or not the sample has contained samples. This method only says if the contained
+     * samples were provided to this object by the application server.
+     */
+    public boolean canGetContainedSamples();
+
     /**
      * Returns the permId of this sample.
      */
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/datastoreserver/systemtests/SearchServiceTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/datastoreserver/systemtests/SearchServiceTest.java
new file mode 100644
index 00000000000..36ef516e926
--- /dev/null
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/datastoreserver/systemtests/SearchServiceTest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2012 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.datastoreserver.systemtests;
+
+import java.util.List;
+
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+import ch.systemsx.cisd.etlserver.registrator.api.v1.impl.SampleImmutable;
+import ch.systemsx.cisd.etlserver.registrator.api.v1.impl.SearchService;
+import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService;
+import ch.systemsx.cisd.openbis.dss.generic.shared.ServiceProvider;
+import ch.systemsx.cisd.openbis.dss.generic.shared.api.internal.v1.ISampleImmutable;
+import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifierFactory;
+
+/**
+ * @author Chandrasekhar Ramakrishnan
+ */
+public class SearchServiceTest extends SystemTestCase
+{
+    private IEncapsulatedOpenBISService openBis;
+
+    private SearchService searchService;
+
+    @BeforeTest
+    public void setUp()
+    {
+        openBis = ServiceProvider.getOpenBISService();
+        searchService = new SearchService(openBis);
+    }
+
+    @Test
+    public void testGettingContainedSamples()
+    {
+        List<ISampleImmutable> samples = searchService.searchForSamples("DESCRIPTION", "*", null);
+        assertTrue("Should have found at least one sample.", samples.size() > 0);
+
+        ISampleImmutable sampleFromSearch = samples.get(0);
+        // SampleSearch should return samples without contained samples
+        assertFalse(sampleFromSearch.canGetContainedSamples());
+        try
+        {
+            sampleFromSearch.getContainedSamples();
+            fail("getContainedSamples should have thrown an error");
+        } catch (IllegalStateException e)
+        {
+            // This is the correct behavior
+        }
+
+        // Getting the same sample from the openBis directly should include contained
+        ISampleImmutable sampleFromServer =
+                new SampleImmutable(openBis.tryGetSampleWithExperiment(SampleIdentifierFactory
+                        .parse(sampleFromSearch.getSampleIdentifier())));
+        assertTrue(sampleFromServer.canGetContainedSamples());
+        assertTrue(sampleFromServer.getContainedSamples().size() > 0);
+
+    }
+}
-- 
GitLab