This is an automated email from the ASF dual-hosted git repository.

machristie pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/airavata.git

commit b8004747428f969eda9345cab84ad73d70e068fd
Author: Marcus Christie <[email protected]>
AuthorDate: Wed Aug 18 10:06:40 2021 -0400

    AIRAVATA-3302 Push experiment search filters into sharing registry query
    
    This fixes the issue where only the most recent 1000 experiments are ever
    searched in the searchExperiments API method. As much filtering as possible
    occurs in the sharing API call and when there are experiment filters that
    don't map to the sharing API, all accessible experiment ids are retrieved
    and further filtered by the Registry.
---
 .../api/server/handler/AiravataServerHandler.java  |  86 +++++++++++++++---
 .../core/repositories/AbstractRepository.java      |  15 ++++
 .../expcatalog/ExperimentSummaryRepository.java    | 100 +++++++++++++++++----
 .../ExperimentSummaryRepositoryTest.java           |  62 ++++++++++---
 4 files changed, 224 insertions(+), 39 deletions(-)

diff --git 
a/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/handler/AiravataServerHandler.java
 
b/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/handler/AiravataServerHandler.java
index 6b86d01..34a5f35 100644
--- 
a/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/handler/AiravataServerHandler.java
+++ 
b/airavata-api/airavata-api-server/src/main/java/org/apache/airavata/api/server/handler/AiravataServerHandler.java
@@ -1160,7 +1160,7 @@ public class AiravataServerHandler implements 
Airavata.Iface {
                 searchCriteria.setValue(gatewayId + ":PROJECT");
                 sharingFilters.add(searchCriteria);
                 
sharingClient.searchEntities(authzToken.getClaimsMap().get(Constants.GATEWAY_ID),
-                        userName + "@" + gatewayId, sharingFilters, 0, 
-1).stream().forEach(e -> accessibleProjIds.add(e.getEntityId()));
+                        userName + "@" + gatewayId, sharingFilters, 0, 
Integer.MAX_VALUE).stream().forEach(e -> 
accessibleProjIds.add(e.getEntityId()));
                 if (accessibleProjIds.isEmpty()) {
                     result = Collections.emptyList();
                 } else {
@@ -1208,17 +1208,81 @@ public class AiravataServerHandler implements 
Airavata.Iface {
         SharingRegistryService.Client sharingClient = 
sharingClientPool.getResource();
         try {
             List<String> accessibleExpIds = new ArrayList<>();
-            if (ServerSettings.isEnableSharing()) {
-                List<SearchCriteria> sharingFilters = new ArrayList<>();
-                SearchCriteria searchCriteria = new SearchCriteria();
-                
searchCriteria.setSearchField(EntitySearchField.ENTITY_TYPE_ID);
-                searchCriteria.setSearchCondition(SearchCondition.EQUAL);
-                searchCriteria.setValue(gatewayId + ":EXPERIMENT");
-                sharingFilters.add(searchCriteria);
-                
sharingClient.searchEntities(authzToken.getClaimsMap().get(Constants.GATEWAY_ID),
-                        userName + "@" + gatewayId, sharingFilters, 0, 
-1).forEach(e -> accessibleExpIds.add(e.getEntityId()));
+            Map<ExperimentSearchFields, String> filtersCopy = new 
HashMap<>(filters);
+            List<SearchCriteria> sharingFilters = new ArrayList<>();
+            SearchCriteria searchCriteria = new SearchCriteria();
+            searchCriteria.setSearchField(EntitySearchField.ENTITY_TYPE_ID);
+            searchCriteria.setSearchCondition(SearchCondition.EQUAL);
+            searchCriteria.setValue(gatewayId + ":EXPERIMENT");
+            sharingFilters.add(searchCriteria);
+
+            // Apply as much of the filters in the sharing API as possible,
+            // removing each filter that can be filtered via the sharing API
+            if (filtersCopy.containsKey(ExperimentSearchFields.FROM_DATE)) {
+                String fromTime = 
filtersCopy.remove(ExperimentSearchFields.FROM_DATE);
+                SearchCriteria fromCreatedTimeCriteria = new SearchCriteria();
+                
fromCreatedTimeCriteria.setSearchField(EntitySearchField.CREATED_TIME);
+                
fromCreatedTimeCriteria.setSearchCondition(SearchCondition.GTE);
+                fromCreatedTimeCriteria.setValue(fromTime);
+                sharingFilters.add(fromCreatedTimeCriteria);
+            }
+            if (filtersCopy.containsKey(ExperimentSearchFields.TO_DATE)) {
+                String toTime = 
filtersCopy.remove(ExperimentSearchFields.TO_DATE);
+                SearchCriteria toCreatedTimeCriteria = new SearchCriteria();
+                
toCreatedTimeCriteria.setSearchField(EntitySearchField.CREATED_TIME);
+                toCreatedTimeCriteria.setSearchCondition(SearchCondition.LTE);
+                toCreatedTimeCriteria.setValue(toTime);
+                sharingFilters.add(toCreatedTimeCriteria);
+            }
+            if (filtersCopy.containsKey(ExperimentSearchFields.PROJECT_ID)) {
+                String projectId = 
filtersCopy.remove(ExperimentSearchFields.PROJECT_ID);
+                SearchCriteria projectParentEntityCriteria = new 
SearchCriteria();
+                
projectParentEntityCriteria.setSearchField(EntitySearchField.PARRENT_ENTITY_ID);
+                
projectParentEntityCriteria.setSearchCondition(SearchCondition.EQUAL);
+                projectParentEntityCriteria.setValue(projectId);
+                sharingFilters.add(projectParentEntityCriteria);
+            }
+            if (filtersCopy.containsKey(ExperimentSearchFields.USER_NAME)) {
+                String username = 
filtersCopy.remove(ExperimentSearchFields.USER_NAME);
+                SearchCriteria usernameOwnerCriteria = new SearchCriteria();
+                
usernameOwnerCriteria.setSearchField(EntitySearchField.OWNER_ID);
+                
usernameOwnerCriteria.setSearchCondition(SearchCondition.EQUAL);
+                usernameOwnerCriteria.setValue(username + "@" + gatewayId);
+                sharingFilters.add(usernameOwnerCriteria);
+            }
+            if 
(filtersCopy.containsKey(ExperimentSearchFields.EXPERIMENT_NAME)) {
+                String experimentName = 
filtersCopy.remove(ExperimentSearchFields.EXPERIMENT_NAME);
+                SearchCriteria experimentNameCriteria = new SearchCriteria();
+                experimentNameCriteria.setSearchField(EntitySearchField.NAME);
+                
experimentNameCriteria.setSearchCondition(SearchCondition.LIKE);
+                experimentNameCriteria.setValue(experimentName);
+                sharingFilters.add(experimentNameCriteria);
+            }
+            if 
(filtersCopy.containsKey(ExperimentSearchFields.EXPERIMENT_DESC)) {
+                String experimentDescription = 
filtersCopy.remove(ExperimentSearchFields.EXPERIMENT_DESC);
+                SearchCriteria experimentDescriptionCriteria = new 
SearchCriteria();
+                
experimentDescriptionCriteria.setSearchField(EntitySearchField.DESCRIPTION);
+                
experimentDescriptionCriteria.setSearchCondition(SearchCondition.LIKE);
+                experimentDescriptionCriteria.setValue(experimentDescription);
+                sharingFilters.add(experimentDescriptionCriteria);
+            }
+            // Grab all of the matching experiments in the sharing registry
+            // unless all of the filtering can be done through the sharing API
+            int searchOffset = 0;
+            int searchLimit = Integer.MAX_VALUE;
+            boolean filteredInSharing = filtersCopy.isEmpty();
+            if (filteredInSharing) {
+                searchOffset = offset;
+                searchLimit = limit;
+            }
+            
sharingClient.searchEntities(authzToken.getClaimsMap().get(Constants.GATEWAY_ID),
+                    userName + "@" + gatewayId, sharingFilters, searchOffset, 
searchLimit).forEach(e -> accessibleExpIds.add(e.getEntityId()));
+            int finalOffset = offset;
+            // If no more filtering to be done (either empty or all done 
through sharing API), set the offset to 0
+            if (filteredInSharing) {
+                finalOffset = 0;
             }
-            List<ExperimentSummaryModel> result = 
regClient.searchExperiments(gatewayId, userName, accessibleExpIds, filters, 
limit, offset);
+            List<ExperimentSummaryModel> result = 
regClient.searchExperiments(gatewayId, userName, accessibleExpIds, filtersCopy, 
limit, finalOffset);
             registryClientPool.returnResource(regClient);
             sharingClientPool.returnResource(sharingClient);
             return result;
diff --git 
a/modules/registry/registry-core/src/main/java/org/apache/airavata/registry/core/repositories/AbstractRepository.java
 
b/modules/registry/registry-core/src/main/java/org/apache/airavata/registry/core/repositories/AbstractRepository.java
index acbd3fb..95062c3 100644
--- 
a/modules/registry/registry-core/src/main/java/org/apache/airavata/registry/core/repositories/AbstractRepository.java
+++ 
b/modules/registry/registry-core/src/main/java/org/apache/airavata/registry/core/repositories/AbstractRepository.java
@@ -113,6 +113,21 @@ public abstract class AbstractRepository<T, E, Id> {
         return get(id) != null;
     }
 
+    public int scalarInt(String query, Map<String, Object> queryParams) {
+
+        int scalarInt = execute(entityManager -> {
+            Query jpaQuery = entityManager.createQuery(query);
+
+            for (Map.Entry<String, Object> entry : queryParams.entrySet()) {
+
+                jpaQuery.setParameter(entry.getKey(), entry.getValue());
+            }
+
+            return ((Number)jpaQuery.getSingleResult()).intValue();
+        });
+        return scalarInt;
+    }
+
     public <R> R execute(Committer<EntityManager, R> committer){
         EntityManager entityManager = null;
         try {
diff --git 
a/modules/registry/registry-core/src/main/java/org/apache/airavata/registry/core/repositories/expcatalog/ExperimentSummaryRepository.java
 
b/modules/registry/registry-core/src/main/java/org/apache/airavata/registry/core/repositories/expcatalog/ExperimentSummaryRepository.java
index f6ab852..ee887fd 100644
--- 
a/modules/registry/registry-core/src/main/java/org/apache/airavata/registry/core/repositories/expcatalog/ExperimentSummaryRepository.java
+++ 
b/modules/registry/registry-core/src/main/java/org/apache/airavata/registry/core/repositories/expcatalog/ExperimentSummaryRepository.java
@@ -25,13 +25,9 @@ import 
org.apache.airavata.model.experiment.ExperimentSummaryModel;
 import org.apache.airavata.model.status.ExperimentState;
 import 
org.apache.airavata.registry.core.entities.expcatalog.ExperimentSummaryEntity;
 import org.apache.airavata.registry.core.entities.expcatalog.JobEntity;
-import org.apache.airavata.registry.core.entities.expcatalog.ProcessEntity;
-import org.apache.airavata.registry.core.entities.expcatalog.TaskEntity;
 import org.apache.airavata.registry.core.utils.DBConstants;
 import org.apache.airavata.registry.cpi.RegistryException;
 import org.apache.airavata.registry.cpi.ResultOrderType;
-import org.apache.airavata.registry.cpi.utils.Constants;
-import org.apache.derby.vti.Restriction;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -47,12 +43,14 @@ import javax.persistence.Query;
 
 public class ExperimentSummaryRepository extends 
ExpCatAbstractRepository<ExperimentSummaryModel, ExperimentSummaryEntity, 
String> {
     private final static Logger logger = 
LoggerFactory.getLogger(ExperimentSummaryRepository.class);
+    private final static int ACCESSIBLE_EXPERIMENT_IDS_BATCH_SIZE = 10000;
 
     public ExperimentSummaryRepository() { super(ExperimentSummaryModel.class, 
ExperimentSummaryEntity.class); }
 
     public List<ExperimentSummaryModel> 
searchAllAccessibleExperiments(List<String> accessibleExperimentIds, 
Map<String, String> filters, int limit,
                                                                        int 
offset, Object orderByIdentifier, ResultOrderType resultOrderType) throws 
RegistryException, IllegalArgumentException {
         String query = "SELECT ES FROM " + 
ExperimentSummaryEntity.class.getSimpleName() + " ES WHERE ";
+        String whereClause = "";
         Map<String, Object> queryParameters = new HashMap<>();
 
         if (filters == null || 
!filters.containsKey(DBConstants.Experiment.GATEWAY_ID)) {
@@ -68,50 +66,50 @@ public class ExperimentSummaryRepository extends 
ExpCatAbstractRepository<Experi
                     + " JOIN J.task T"
                     + " JOIN T.process P"
                     + " WHERE J.jobId = : " + DBConstants.Job.JOB_ID;
-            query += "ES.experimentId IN  ( "+ query_jobId + " ) AND ";
+            whereClause += "ES.experimentId IN  ( " + query_jobId + " ) AND ";
         }
 
         if (filters.get(DBConstants.Experiment.USER_NAME) != null) {
             logger.debug("Filter Experiments by User");
             queryParameters.put(DBConstants.Experiment.USER_NAME, 
filters.get(DBConstants.Experiment.USER_NAME));
-            query += "ES.userName LIKE :" + DBConstants.Experiment.USER_NAME + 
" AND ";
+            whereClause += "ES.userName LIKE :" + 
DBConstants.Experiment.USER_NAME + " AND ";
         }
 
         if (filters.get(DBConstants.Experiment.GATEWAY_ID) != null) {
             logger.debug("Filter Experiments by Gateway ID");
             queryParameters.put(DBConstants.Experiment.GATEWAY_ID, 
filters.get(DBConstants.Experiment.GATEWAY_ID));
-            query += "ES.gatewayId LIKE :" + DBConstants.Experiment.GATEWAY_ID 
+ " AND ";
+            whereClause += "ES.gatewayId LIKE :" + 
DBConstants.Experiment.GATEWAY_ID + " AND ";
         }
 
         if (filters.get(DBConstants.Experiment.PROJECT_ID) != null) {
             logger.debug("Filter Experiments by Project ID");
             queryParameters.put(DBConstants.Experiment.PROJECT_ID, 
filters.get(DBConstants.Experiment.PROJECT_ID));
-            query += "ES.projectId LIKE :" + DBConstants.Experiment.PROJECT_ID 
+ " AND ";
+            whereClause += "ES.projectId LIKE :" + 
DBConstants.Experiment.PROJECT_ID + " AND ";
         }
 
         if (filters.get(DBConstants.Experiment.EXPERIMENT_NAME) != null) {
             logger.debug("Filter Experiments by Name");
             queryParameters.put(DBConstants.Experiment.EXPERIMENT_NAME, 
filters.get(DBConstants.Experiment.EXPERIMENT_NAME));
-            query += "ES.name LIKE :" + DBConstants.Experiment.EXPERIMENT_NAME 
+ " AND ";
+            whereClause += "ES.name LIKE :" + 
DBConstants.Experiment.EXPERIMENT_NAME + " AND ";
         }
 
         if (filters.get(DBConstants.Experiment.DESCRIPTION) != null) {
             logger.debug("Filter Experiments by Description");
             queryParameters.put(DBConstants.Experiment.DESCRIPTION, 
filters.get(DBConstants.Experiment.DESCRIPTION));
-            query += "ES.description LIKE :" + 
DBConstants.Experiment.DESCRIPTION + " AND ";
+            whereClause += "ES.description LIKE :" + 
DBConstants.Experiment.DESCRIPTION + " AND ";
         }
 
         if (filters.get(DBConstants.Experiment.EXECUTION_ID) != null) {
             logger.debug("Filter Experiments by Execution ID");
             queryParameters.put(DBConstants.Experiment.EXECUTION_ID, 
filters.get(DBConstants.Experiment.EXECUTION_ID));
-            query += "ES.executionId LIKE :" + 
DBConstants.Experiment.EXECUTION_ID + " AND ";
+            whereClause += "ES.executionId LIKE :" + 
DBConstants.Experiment.EXECUTION_ID + " AND ";
         }
 
         if (filters.get(DBConstants.ExperimentSummary.EXPERIMENT_STATUS) != 
null) {
             logger.debug("Filter Experiments by State");
             String state = 
ExperimentState.valueOf(filters.get(DBConstants.ExperimentSummary.EXPERIMENT_STATUS)).toString();
             
queryParameters.put(DBConstants.ExperimentSummary.EXPERIMENT_STATUS, state);
-            query += "ES.experimentStatus LIKE :" + 
DBConstants.ExperimentSummary.EXPERIMENT_STATUS + " AND ";
+            whereClause += "ES.experimentStatus LIKE :" + 
DBConstants.ExperimentSummary.EXPERIMENT_STATUS + " AND ";
         }
 
         if (filters.get(DBConstants.ExperimentSummary.FROM_DATE) != null
@@ -124,7 +122,8 @@ public class ExperimentSummaryRepository extends 
ExpCatAbstractRepository<Experi
                 logger.debug("Filter Experiments by CreationTime");
                 queryParameters.put(DBConstants.ExperimentSummary.FROM_DATE, 
fromDate);
                 queryParameters.put(DBConstants.ExperimentSummary.TO_DATE, 
toDate);
-                query += "ES.creationTime BETWEEN :" + 
DBConstants.ExperimentSummary.FROM_DATE + " AND :" + 
DBConstants.ExperimentSummary.TO_DATE + " AND ";
+                whereClause += "ES.creationTime BETWEEN :" + 
DBConstants.ExperimentSummary.FROM_DATE + " AND :"
+                        + DBConstants.ExperimentSummary.TO_DATE + " AND ";
             }
 
         }
@@ -132,13 +131,13 @@ public class ExperimentSummaryRepository extends 
ExpCatAbstractRepository<Experi
         if (filters.get(DBConstants.Experiment.USER_NAME) != null) {
             logger.debug("Filter Experiments by Username");
             queryParameters.put(DBConstants.Experiment.USER_NAME, 
filters.get(DBConstants.Experiment.USER_NAME));
-            query += "ES.userName = :" + DBConstants.Experiment.USER_NAME + " 
AND ";
+            whereClause += "ES.userName = :" + 
DBConstants.Experiment.USER_NAME + " AND ";
         }
 
         if (!accessibleExperimentIds.isEmpty()) {
             logger.debug("Filter Experiments by Accessible Experiment IDs");
             
queryParameters.put(DBConstants.Experiment.ACCESSIBLE_EXPERIMENT_IDS, 
accessibleExperimentIds);
-            query += " ES.experimentId IN :" + 
DBConstants.Experiment.ACCESSIBLE_EXPERIMENT_IDS;
+            whereClause += " ES.experimentId IN :" + 
DBConstants.Experiment.ACCESSIBLE_EXPERIMENT_IDS;
         }
 
         else {
@@ -146,13 +145,80 @@ public class ExperimentSummaryRepository extends 
ExpCatAbstractRepository<Experi
             return new ArrayList<ExperimentSummaryModel>();
         }
 
+        int queryLimit = limit;
+        int queryOffset = offset;
+        int accessibleExperimentIdsBatchNum = 0;
+
+        // Figure out the initial batch of accessible experiment ids and the
+        // offset into it by counting the matching experiments in each batch
+        if (queryOffset > 0) {
+            String countQuery = "SELECT COUNT(ES) FROM " + 
ExperimentSummaryEntity.class.getSimpleName() + " ES WHERE ";
+            countQuery += whereClause;
+            BatchOffset batchOffset = 
findInitialAccessibleExperimentsBatchOffset(countQuery, queryOffset, 
queryParameters, accessibleExperimentIds);
+            queryOffset = batchOffset.offset;
+            accessibleExperimentIdsBatchNum = batchOffset.batchNum;
+        }
+
+        query += whereClause;
         if (orderByIdentifier != null && resultOrderType != null && 
orderByIdentifier.equals(DBConstants.Experiment.CREATION_TIME)) {
             String order = (resultOrderType == ResultOrderType.ASC) ? "ASC" : 
"DESC";
             query += " ORDER BY ES." + DBConstants.Experiment.CREATION_TIME + 
" " + order;
         }
 
-        List<ExperimentSummaryModel> experimentSummaryModelList = 
select(query, limit, offset, queryParameters);
-        return experimentSummaryModelList;
+        List<ExperimentSummaryModel> allExperimentSummaryModels = new 
ArrayList<>();
+
+        // Break up the query in batches over accessibleExperimentIds
+        // NOTE: this assumes that the accessibleExperimentIds are sorted in 
the
+        // same order as the expected experiment summary results
+        double totalBatches = Math.ceil(
+                Integer.valueOf(accessibleExperimentIds.size()).floatValue() / 
ACCESSIBLE_EXPERIMENT_IDS_BATCH_SIZE);
+        for (int batchNum = accessibleExperimentIdsBatchNum; batchNum < 
totalBatches; batchNum++) {
+            List<String> accessibleExperimentIdsBatch = 
accessibleExperimentIds.subList(
+                    batchNum * ACCESSIBLE_EXPERIMENT_IDS_BATCH_SIZE,
+                    Math.min(accessibleExperimentIds.size(), (batchNum + 1) * 
ACCESSIBLE_EXPERIMENT_IDS_BATCH_SIZE));
+            
queryParameters.put(DBConstants.Experiment.ACCESSIBLE_EXPERIMENT_IDS, 
accessibleExperimentIdsBatch);
+            List<ExperimentSummaryModel> experimentSummaryModelList = 
select(query, queryLimit, queryOffset, queryParameters);
+            allExperimentSummaryModels.addAll(experimentSummaryModelList);
+            if (allExperimentSummaryModels.size() == limit) {
+                return allExperimentSummaryModels;
+            } else if (limit > 0 && allExperimentSummaryModels.size() < limit) 
{
+                queryLimit -= experimentSummaryModelList.size();
+                // In the next and subsequent batches, start from offset 0
+                queryOffset = 0;
+            }
+        }
+        return allExperimentSummaryModels;
+    }
+
+    class BatchOffset {
+        final int batchNum;
+        final int offset;
+
+        BatchOffset(int batchNum, int offset) {
+            this.batchNum = batchNum;
+            this.offset = offset;
+        }
+    }
+
+    private BatchOffset findInitialAccessibleExperimentsBatchOffset(String 
query, int queryOffset,
+            Map<String, Object> queryParameters, List<String> 
accessibleExperimentIds) {
+        
+        int accumulator = 0;
+
+        double totalBatches = Math.ceil(
+                Integer.valueOf(accessibleExperimentIds.size()).floatValue() / 
ACCESSIBLE_EXPERIMENT_IDS_BATCH_SIZE);
+        for (int batchNum = 0; batchNum < totalBatches; batchNum++) {
+            List<String> accessibleExperimentIdsBatch = 
accessibleExperimentIds.subList(
+                    batchNum * ACCESSIBLE_EXPERIMENT_IDS_BATCH_SIZE,
+                    Math.min(accessibleExperimentIds.size(), (batchNum + 1) * 
ACCESSIBLE_EXPERIMENT_IDS_BATCH_SIZE));
+            
queryParameters.put(DBConstants.Experiment.ACCESSIBLE_EXPERIMENT_IDS, 
accessibleExperimentIdsBatch);
+            int count = scalarInt(query, queryParameters);
+            if (accumulator + count > queryOffset ) {
+                return new BatchOffset(batchNum, queryOffset - accumulator);
+            }
+            accumulator += count;
+        }
+        return new BatchOffset(0, 0);
     }
 
     public ExperimentStatistics getAccessibleExperimentStatistics(List<String> 
accessibleExperimentIds, Map<String,String> filters, int limit, int offset) 
throws RegistryException {
diff --git 
a/modules/registry/registry-core/src/test/java/org/apache/airavata/registry/core/repositories/expcatalog/ExperimentSummaryRepositoryTest.java
 
b/modules/registry/registry-core/src/test/java/org/apache/airavata/registry/core/repositories/expcatalog/ExperimentSummaryRepositoryTest.java
index 248b12e..bbc9ad4 100644
--- 
a/modules/registry/registry-core/src/test/java/org/apache/airavata/registry/core/repositories/expcatalog/ExperimentSummaryRepositoryTest.java
+++ 
b/modules/registry/registry-core/src/test/java/org/apache/airavata/registry/core/repositories/expcatalog/ExperimentSummaryRepositoryTest.java
@@ -93,6 +93,15 @@ public class ExperimentSummaryRepositoryTest extends 
TestBase{
         experimentModelTwo.setDescription("descriptionTwo");
         experimentModelTwo.setExecutionId("executionIdTwo");
 
+        ExperimentModel experimentModelThree = new ExperimentModel();
+        experimentModelThree.setProjectId(projectId);
+        experimentModelThree.setGatewayId(gatewayId);
+        
experimentModelThree.setExperimentType(ExperimentType.SINGLE_APPLICATION);
+        experimentModelThree.setUserName("userThree");
+        experimentModelThree.setExperimentName("nameThree");
+        experimentModelThree.setDescription("descriptionThree");
+        experimentModelThree.setExecutionId("executionIdThree");
+
         String experimentIdOne = 
experimentRepository.addExperiment(experimentModelOne);
         assertTrue(experimentIdOne != null);
         // Reload experiment to get its status' identifier
@@ -103,6 +112,11 @@ public class ExperimentSummaryRepositoryTest extends 
TestBase{
         // Reload experiment to get its status' identifier
         experimentModelTwo = 
experimentRepository.getExperiment(experimentIdTwo);
 
+        String experimentIdThree = 
experimentRepository.addExperiment(experimentModelThree);
+        assertTrue(experimentIdThree != null);
+        // Reload experiment to get its status' identifier
+        experimentModelThree = 
experimentRepository.getExperiment(experimentIdThree);
+
         Timestamp timeOne = Timestamp.valueOf("2010-01-01 09:00:00");
         experimentModelOne.setCreationTime(timeOne.getTime());
         experimentRepository.updateExperiment(experimentModelOne, 
experimentIdOne);
@@ -111,14 +125,18 @@ public class ExperimentSummaryRepositoryTest extends 
TestBase{
         experimentModelTwo.setCreationTime(timeTwo.getTime());
         experimentRepository.updateExperiment(experimentModelTwo, 
experimentIdTwo);
 
+        Timestamp timeThree = Timestamp.valueOf("2020-01-01 09:00:00");
+        experimentModelThree.setCreationTime(timeThree.getTime());
+        experimentRepository.updateExperiment(experimentModelThree, 
experimentIdThree);
+
         Map<String, String> filters = new HashMap<>();
         filters.put(DBConstants.Experiment.GATEWAY_ID, gatewayId);
         filters.put(DBConstants.Experiment.PROJECT_ID, projectId);
 
-        List<String> allExperimentIds = Arrays.asList( experimentIdOne, 
experimentIdTwo);
+        List<String> allExperimentIds = Arrays.asList( experimentIdOne, 
experimentIdTwo, experimentIdThree);
         List<ExperimentSummaryModel> experimentSummaryModelList = 
experimentSummaryRepository.
                 searchAllAccessibleExperiments(allExperimentIds, filters, -1, 
0, null, null);
-        assertEquals(2, experimentSummaryModelList.size());
+        assertEquals(3, experimentSummaryModelList.size());
 
         filters.put(DBConstants.Experiment.EXECUTION_ID, "executionIdTwo");
 
@@ -166,6 +184,22 @@ public class ExperimentSummaryRepositoryTest extends 
TestBase{
         assertEquals("should return only userOne's exp", 1, 
experimentSummaryModelList.size());
         assertEquals("userOne", 
experimentSummaryModelList.get(0).getUserName());
 
+        // Test with pagination
+        filters.clear();
+        filters.put(DBConstants.Experiment.GATEWAY_ID, gatewayId);
+        experimentSummaryModelList = 
experimentSummaryRepository.searchAllAccessibleExperiments(
+                                allExperimentIds, filters, 2, 0,
+                                DBConstants.Experiment.CREATION_TIME, 
ResultOrderType.ASC);
+        assertEquals("should only return 2 experiments since limit=2", 2, 
experimentSummaryModelList.size());
+        assertEquals(experimentIdOne, 
experimentSummaryModelList.get(0).getExperimentId());
+        assertEquals(experimentIdTwo, 
experimentSummaryModelList.get(1).getExperimentId());
+        // page 2
+        experimentSummaryModelList = 
experimentSummaryRepository.searchAllAccessibleExperiments(
+                                allExperimentIds, filters, 2, 2,
+                                DBConstants.Experiment.CREATION_TIME, 
ResultOrderType.ASC);
+        assertEquals("should only return 1 experiment since limit=2 but 
partial last page", 1, experimentSummaryModelList.size());
+        assertEquals(experimentIdThree, 
experimentSummaryModelList.get(0).getExperimentId());
+
         filters = new HashMap<>();
         filters.put(DBConstants.Experiment.GATEWAY_ID, gatewayId);
         filters.put(DBConstants.Experiment.USER_NAME, "userTwo");
@@ -194,16 +228,21 @@ public class ExperimentSummaryRepositoryTest extends 
TestBase{
         String statusIdTwo = 
experimentStatusRepository.addExperimentStatus(experimentStatusTwo, 
experimentIdTwo);
         assertTrue(statusIdTwo != null);
 
+        ExperimentStatus experimentStatusThree = new 
ExperimentStatus(ExperimentState.CANCELED);
+        String statusIdThree = 
experimentStatusRepository.addExperimentStatus(experimentStatusThree, 
experimentIdThree);
+        assertTrue(statusIdThree != null);
+
         experimentStatistics = 
experimentSummaryRepository.getAccessibleExperimentStatistics(allExperimentIds, 
filters, 10, 0);
-        assertTrue(experimentStatistics.getAllExperimentCount() == 1);
+        assertEquals(2, experimentStatistics.getAllExperimentCount());
         assertTrue(experimentStatistics.getRunningExperimentCount() == 1);
-        assertEquals(experimentIdTwo, 
experimentStatistics.getAllExperiments().get(0).getExperimentId());
+        // Experiment 3 is most recent
+        assertEquals(experimentIdThree, 
experimentStatistics.getAllExperiments().get(0).getExperimentId());
 
         filters.remove(DBConstants.ExperimentSummary.FROM_DATE);
         filters.remove(DBConstants.ExperimentSummary.TO_DATE);
 
         experimentStatistics = 
experimentSummaryRepository.getAccessibleExperimentStatistics(allExperimentIds, 
filters, 10, 0);
-        assertTrue(experimentStatistics.getAllExperimentCount() == 2);
+        assertTrue(experimentStatistics.getAllExperimentCount() == 3);
         assertTrue(experimentStatistics.getCreatedExperimentCount() == 1);
         assertTrue(experimentStatistics.getRunningExperimentCount() == 1);
 
@@ -237,20 +276,21 @@ public class ExperimentSummaryRepositoryTest extends 
TestBase{
         // First page
         experimentStatistics = 
experimentSummaryRepository.getAccessibleExperimentStatistics(allExperimentIds, 
filters, 1, 0);
         // Should still return total count even when only returning the first 
page of experiment summaries
-        assertEquals(2, experimentStatistics.getAllExperimentCount());
-        // experiment 2 is more recent
+        assertEquals(3, experimentStatistics.getAllExperimentCount());
+        // experiment 3 is most recent
         assertEquals(1, experimentStatistics.getAllExperimentsSize());
-        assertEquals(experimentIdTwo, 
experimentStatistics.getAllExperiments().get(0).getExperimentId());
+        assertEquals(experimentIdThree, 
experimentStatistics.getAllExperiments().get(0).getExperimentId());
         // Second page
         experimentStatistics = 
experimentSummaryRepository.getAccessibleExperimentStatistics(allExperimentIds, 
filters, 1, 1);
         // Should still return total count even when only returning the first 
page of experiment summaries
-        assertEquals(2, experimentStatistics.getAllExperimentCount());
-        // experiment 1 is less recent
+        assertEquals(3, experimentStatistics.getAllExperimentCount());
+        // experiment 2 is less recent
         assertEquals(1, experimentStatistics.getAllExperimentsSize());
-        assertEquals(experimentIdOne, 
experimentStatistics.getAllExperiments().get(0).getExperimentId());
+        assertEquals(experimentIdTwo, 
experimentStatistics.getAllExperiments().get(0).getExperimentId());
 
         experimentRepository.removeExperiment(experimentIdOne);
         experimentRepository.removeExperiment(experimentIdTwo);
+        experimentRepository.removeExperiment(experimentIdThree);
 
         gatewayRepository.removeGateway(gatewayId);
         projectRepository.removeProject(projectId);

Reply via email to