From 6989010330f43adcc98a4ebee4e87dc90dc66160 Mon Sep 17 00:00:00 2001 From: pkupczyk <pkupczyk> Date: Thu, 20 Aug 2015 12:53:37 +0000 Subject: [PATCH] SSDM-2294 : V3 AS API - paging and sorting of search results - make it possible to sort/page/cache in all V3 searches and return SearchResult instead of a List SVN: 34500 --- .../server/api/v3/ApplicationServerApi.java | 13 +- .../api/v3/ApplicationServerApiLogger.java | 14 +- .../method/AbstractSearchMethodExecutor.java | 129 +++++++++++++++-- .../method/ISearchMethodExecutor.java | 4 +- .../SearchMaterialSqlMethodExecutor.java | 132 ++---------------- .../systemtest/api/v3/SearchDataSetTest.java | 4 +- .../api/v3/SearchExperimentTest.java | 9 +- .../systemtest/api/v3/SearchMaterialTest.java | 7 +- .../systemtest/api/v3/SearchProjectTest.java | 4 +- .../systemtest/api/v3/SearchSampleTest.java | 7 +- .../systemtest/api/v3/SearchSpaceTest.java | 4 +- .../shared/api/v3/IApplicationServerApi.java | 14 +- .../api/v3/dto/search/SearchResult.java | 18 ++- 13 files changed, 191 insertions(+), 168 deletions(-) diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/ApplicationServerApi.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/ApplicationServerApi.java index c132d629db1..80da12b7918 100644 --- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/ApplicationServerApi.java +++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/ApplicationServerApi.java @@ -104,6 +104,7 @@ import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.ExperimentSearchCrit import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.MaterialSearchCriterion; import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.ProjectSearchCriterion; import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.SampleSearchCriterion; +import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.SearchResult; import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.SpaceSearchCriterion; import ch.systemsx.cisd.openbis.common.spring.IInvocationLoggerContext; import ch.systemsx.cisd.openbis.generic.server.AbstractServer; @@ -420,7 +421,7 @@ public class ApplicationServerApi extends AbstractServer<IApplicationServerApi> @Override @Transactional(readOnly = true) @RolesAllowed({ RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER }) - public List<Space> searchSpaces(String sessionToken, SpaceSearchCriterion searchCriterion, SpaceFetchOptions fetchOptions) + public SearchResult<Space> searchSpaces(String sessionToken, SpaceSearchCriterion searchCriterion, SpaceFetchOptions fetchOptions) { return searchSpaceExecutor.search(sessionToken, searchCriterion, fetchOptions); } @@ -428,7 +429,7 @@ public class ApplicationServerApi extends AbstractServer<IApplicationServerApi> @Override @Transactional(readOnly = true) @RolesAllowed({ RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER }) - public List<Project> searchProjects(String sessionToken, ProjectSearchCriterion searchCriterion, ProjectFetchOptions fetchOptions) + public SearchResult<Project> searchProjects(String sessionToken, ProjectSearchCriterion searchCriterion, ProjectFetchOptions fetchOptions) { return searchProjectExecutor.search(sessionToken, searchCriterion, fetchOptions); } @@ -436,7 +437,7 @@ public class ApplicationServerApi extends AbstractServer<IApplicationServerApi> @Override @Transactional(readOnly = true) @RolesAllowed({ RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER }) - public List<Experiment> searchExperiments(String sessionToken, ExperimentSearchCriterion searchCriterion, + public SearchResult<Experiment> searchExperiments(String sessionToken, ExperimentSearchCriterion searchCriterion, ExperimentFetchOptions fetchOptions) { return searchExperimentExecutor.search(sessionToken, searchCriterion, fetchOptions); @@ -445,7 +446,7 @@ public class ApplicationServerApi extends AbstractServer<IApplicationServerApi> @Override @Transactional(readOnly = true) @RolesAllowed({ RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER }) - public List<Sample> searchSamples(String sessionToken, SampleSearchCriterion searchCriterion, SampleFetchOptions fetchOptions) + public SearchResult<Sample> searchSamples(String sessionToken, SampleSearchCriterion searchCriterion, SampleFetchOptions fetchOptions) { return searchSampleExecutor.search(sessionToken, searchCriterion, fetchOptions); } @@ -453,7 +454,7 @@ public class ApplicationServerApi extends AbstractServer<IApplicationServerApi> @Override @Transactional(readOnly = true) @RolesAllowed({ RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER }) - public List<DataSet> searchDataSets(String sessionToken, DataSetSearchCriterion searchCriterion, DataSetFetchOptions fetchOptions) + public SearchResult<DataSet> searchDataSets(String sessionToken, DataSetSearchCriterion searchCriterion, DataSetFetchOptions fetchOptions) { return searchDataSetExecutor.search(sessionToken, searchCriterion, fetchOptions); } @@ -461,7 +462,7 @@ public class ApplicationServerApi extends AbstractServer<IApplicationServerApi> @Override @Transactional(readOnly = true) @RolesAllowed({ RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER }) - public List<Material> searchMaterials(String sessionToken, MaterialSearchCriterion searchCriterion, MaterialFetchOptions fetchOptions) + public SearchResult<Material> searchMaterials(String sessionToken, MaterialSearchCriterion searchCriterion, MaterialFetchOptions fetchOptions) { return searchMaterialExecutor.search(sessionToken, searchCriterion, fetchOptions); } diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/ApplicationServerApiLogger.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/ApplicationServerApiLogger.java index 8e048d6c1fa..d5e66546597 100644 --- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/ApplicationServerApiLogger.java +++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/ApplicationServerApiLogger.java @@ -68,6 +68,7 @@ import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.ExperimentSearchCrit import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.MaterialSearchCriterion; import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.ProjectSearchCriterion; import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.SampleSearchCriterion; +import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.SearchResult; import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.SpaceSearchCriterion; import ch.systemsx.cisd.authentication.ISessionManager; import ch.systemsx.cisd.openbis.common.spring.IInvocationLoggerContext; @@ -226,42 +227,43 @@ public class ApplicationServerApiLogger extends AbstractServerLogger implements } @Override - public List<Space> searchSpaces(String sessionToken, SpaceSearchCriterion searchCriterion, SpaceFetchOptions fetchOptions) + public SearchResult<Space> searchSpaces(String sessionToken, SpaceSearchCriterion searchCriterion, SpaceFetchOptions fetchOptions) { logAccess(sessionToken, "search-for-spaces", "SEARCH_CRITERION:\n%s\nFETCH_OPTIONS:\n%s\n", searchCriterion, fetchOptions); return null; } @Override - public List<Project> searchProjects(String sessionToken, ProjectSearchCriterion searchCriterion, ProjectFetchOptions fetchOptions) + public SearchResult<Project> searchProjects(String sessionToken, ProjectSearchCriterion searchCriterion, ProjectFetchOptions fetchOptions) { logAccess(sessionToken, "search-for-projects", "SEARCH_CRITERION:\n%s\nFETCH_OPTIONS:\n%s\n", searchCriterion, fetchOptions); return null; } @Override - public List<Experiment> searchExperiments(String sessionToken, ExperimentSearchCriterion searchCriterion, ExperimentFetchOptions fetchOptions) + public SearchResult<Experiment> searchExperiments(String sessionToken, ExperimentSearchCriterion searchCriterion, + ExperimentFetchOptions fetchOptions) { logAccess(sessionToken, "search-for-experiments", "SEARCH_CRITERION:\n%s\nFETCH_OPTIONS:\n%s\n", searchCriterion, fetchOptions); return null; } @Override - public List<Sample> searchSamples(String sessionToken, SampleSearchCriterion searchCriterion, SampleFetchOptions fetchOptions) + public SearchResult<Sample> searchSamples(String sessionToken, SampleSearchCriterion searchCriterion, SampleFetchOptions fetchOptions) { logAccess(sessionToken, "search-for-samples", "SEARCH_CRITERION:\n%s\nFETCH_OPTIONS:\n%s\n", searchCriterion, fetchOptions); return null; } @Override - public List<DataSet> searchDataSets(String sessionToken, DataSetSearchCriterion searchCriterion, DataSetFetchOptions fetchOptions) + public SearchResult<DataSet> searchDataSets(String sessionToken, DataSetSearchCriterion searchCriterion, DataSetFetchOptions fetchOptions) { logAccess(sessionToken, "search-for-data-sets", "SEARCH_CRITERION:\n%s\nFETCH_OPTIONS:\n%s\n", searchCriterion, fetchOptions); return null; } @Override - public List<Material> searchMaterials(String sessionToken, MaterialSearchCriterion searchCriterion, MaterialFetchOptions fetchOptions) + public SearchResult<Material> searchMaterials(String sessionToken, MaterialSearchCriterion searchCriterion, MaterialFetchOptions fetchOptions) { logAccess(sessionToken, "search-for-materials", "SEARCH_CRITERION:\n%s\nFETCH_OPTIONS:\n%s\n", searchCriterion, fetchOptions); return null; diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/AbstractSearchMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/AbstractSearchMethodExecutor.java index cf677f9e0f8..b1d73886dbf 100644 --- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/AbstractSearchMethodExecutor.java +++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/AbstractSearchMethodExecutor.java @@ -17,51 +17,152 @@ package ch.ethz.sis.openbis.generic.server.api.v3.executor.method; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.cache.Cache; +import org.springframework.cache.Cache.ValueWrapper; +import org.springframework.cache.CacheManager; + import ch.ethz.sis.openbis.generic.server.api.v3.executor.IOperationContext; import ch.ethz.sis.openbis.generic.server.api.v3.executor.common.ISearchObjectExecutor; import ch.ethz.sis.openbis.generic.server.api.v3.translator.ITranslator; import ch.ethz.sis.openbis.generic.server.api.v3.translator.TranslationContext; +import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.CacheMode; +import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.FetchOptions; +import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.FetchOptionsMatcher; +import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.sort.SortAndPage; import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.AbstractObjectSearchCriterion; +import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.SearchResult; /** * @author pkupczyk */ -public abstract class AbstractSearchMethodExecutor<OBJECT, OBJECT_PE, CRITERION extends AbstractObjectSearchCriterion<?>, FETCH_OPTIONS> extends - AbstractMethodExecutor implements ISearchMethodExecutor<OBJECT, CRITERION, FETCH_OPTIONS> +public abstract class AbstractSearchMethodExecutor<OBJECT, OBJECT_PE, CRITERION extends AbstractObjectSearchCriterion<?>, FETCH_OPTIONS extends FetchOptions<OBJECT>> + extends AbstractMethodExecutor implements ISearchMethodExecutor<OBJECT, CRITERION, FETCH_OPTIONS> { + @Autowired + private CacheManager cacheManager; + + protected abstract ISearchObjectExecutor<CRITERION, OBJECT_PE> getSearchExecutor(); + + protected abstract ITranslator<OBJECT_PE, OBJECT, FETCH_OPTIONS> getTranslator(); + @Override - public List<OBJECT> search(final String sessionToken, final CRITERION criterion, final FETCH_OPTIONS fetchOptions) + public SearchResult<OBJECT> search(final String sessionToken, final CRITERION criterion, final FETCH_OPTIONS fetchOptions) { - return executeInContext(sessionToken, new IMethodAction<List<OBJECT>>() + return executeInContext(sessionToken, new IMethodAction<SearchResult<OBJECT>>() { @Override - public List<OBJECT> execute(IOperationContext context) + public SearchResult<OBJECT> execute(IOperationContext context) { - List<OBJECT_PE> results = getSearchExecutor().search(context, criterion); - return translate(context, results, fetchOptions); + Collection<OBJECT> allResults = searchAndTranslate(context, criterion, fetchOptions); + List<OBJECT> sortedAndPaged = sortAndPage(context, allResults, fetchOptions); + return new SearchResult<OBJECT>(sortedAndPaged, allResults.size()); } }); } - private List<OBJECT> translate(IOperationContext context, List<OBJECT_PE> peList, FETCH_OPTIONS fetchOptions) + @SuppressWarnings("unchecked") + private Collection<OBJECT> searchAndTranslate(IOperationContext context, CRITERION criterion, FETCH_OPTIONS fetchOptions) { - if (peList == null || peList.isEmpty()) + if (CacheMode.NO_CACHE.equals(fetchOptions.getCacheMode())) { - return Collections.emptyList(); + return doSearchAndTranslate(context, criterion, fetchOptions); + } else if (CacheMode.CACHE.equals(fetchOptions.getCacheMode()) || CacheMode.RELOAD_AND_CACHE.equals(fetchOptions.getCacheMode())) + { + Cache cache = cacheManager.getCache("searchCache"); + CacheKey key = new CacheKey(context.getSession().getSessionToken(), fetchOptions); + Collection<OBJECT> results = null; + + if (CacheMode.RELOAD_AND_CACHE.equals(fetchOptions.getCacheMode())) + { + cache.evict(key); + } else + { + ValueWrapper wrapper = cache.get(key); + if (wrapper != null) + { + results = (Collection<OBJECT>) wrapper.get(); + } + } + + if (results == null) + { + results = doSearchAndTranslate(context, criterion, fetchOptions); + cache.put(key, results); + } + + return results; + } else + { + throw new IllegalArgumentException("Unsupported cache mode: " + fetchOptions.getCacheMode()); } + } + private Collection<OBJECT> doSearchAndTranslate(IOperationContext context, CRITERION criterion, FETCH_OPTIONS fetchOptions) + { + List<OBJECT_PE> ids = getSearchExecutor().search(context, criterion); TranslationContext translationContext = new TranslationContext(context.getSession()); - Map<OBJECT_PE, OBJECT> peToObjectMap = getTranslator().translate(translationContext, peList, fetchOptions); - return new ArrayList<OBJECT>(peToObjectMap.values()); + Map<OBJECT_PE, OBJECT> idToObjectMap = getTranslator().translate(translationContext, ids, fetchOptions); + return idToObjectMap.values(); } - protected abstract ISearchObjectExecutor<CRITERION, OBJECT_PE> getSearchExecutor(); + private List<OBJECT> sortAndPage(IOperationContext context, Collection<OBJECT> results, FETCH_OPTIONS fetchOptions) + { + if (results == null || results.isEmpty()) + { + return Collections.emptyList(); + } - protected abstract ITranslator<OBJECT_PE, OBJECT, FETCH_OPTIONS> getTranslator(); + SortAndPage sap = new SortAndPage(); + Collection<OBJECT> objects = sap.sortAndPage(results, fetchOptions); + + return new ArrayList<OBJECT>(objects); + } + + private static class CacheKey + { + + private String sessionToken; + + private FetchOptions<?> fetchOptions; + + public CacheKey(String sessionToken, FetchOptions<?> fetchOptions) + { + this.sessionToken = sessionToken; + this.fetchOptions = fetchOptions; + } + + @Override + public int hashCode() + { + return sessionToken.hashCode() + fetchOptions.getClass().hashCode(); + } + + @Override + public boolean equals(Object obj) + { + if (this == obj) + { + return true; + } + if (obj == null) + { + return false; + } + if (getClass() != obj.getClass()) + { + return false; + } + + CacheKey other = (CacheKey) obj; + return sessionToken.equals(other.sessionToken) && FetchOptionsMatcher.arePartsEqual(fetchOptions, other.fetchOptions); + } + } } diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ISearchMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ISearchMethodExecutor.java index 0367622f1ca..c3b6167524d 100644 --- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ISearchMethodExecutor.java +++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/ISearchMethodExecutor.java @@ -16,7 +16,7 @@ package ch.ethz.sis.openbis.generic.server.api.v3.executor.method; -import java.util.List; +import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.SearchResult; /** * @author pkupczyk @@ -24,6 +24,6 @@ import java.util.List; public interface ISearchMethodExecutor<OBJECT, CRITERION, FETCH_OPTIONS> { - public List<OBJECT> search(String sessionToken, CRITERION searchCriterion, FETCH_OPTIONS fetchOptions); + public SearchResult<OBJECT> search(String sessionToken, CRITERION searchCriterion, FETCH_OPTIONS fetchOptions); } diff --git a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/SearchMaterialSqlMethodExecutor.java b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/SearchMaterialSqlMethodExecutor.java index 0c4b09eba6b..b6c670c673f 100644 --- a/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/SearchMaterialSqlMethodExecutor.java +++ b/openbis/source/java/ch/ethz/sis/openbis/generic/server/api/v3/executor/method/SearchMaterialSqlMethodExecutor.java @@ -16,35 +16,23 @@ package ch.ethz.sis.openbis.generic.server.api.v3.executor.method; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; - import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.cache.Cache; -import org.springframework.cache.Cache.ValueWrapper; -import org.springframework.cache.CacheManager; import org.springframework.stereotype.Component; -import ch.ethz.sis.openbis.generic.server.api.v3.executor.IOperationContext; +import ch.ethz.sis.openbis.generic.server.api.v3.executor.common.ISearchObjectExecutor; import ch.ethz.sis.openbis.generic.server.api.v3.executor.material.ISearchMaterialIdExecutor; -import ch.ethz.sis.openbis.generic.server.api.v3.translator.TranslationContext; +import ch.ethz.sis.openbis.generic.server.api.v3.translator.ITranslator; import ch.ethz.sis.openbis.generic.server.api.v3.translator.entity.material.sql.IMaterialSqlTranslator; import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.material.Material; -import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.CacheMode; -import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.FetchOptions; -import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.FetchOptionsMatcher; import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.material.MaterialFetchOptions; -import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.sort.SortAndPage; import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.MaterialSearchCriterion; /** * @author pkupczyk */ @Component -public class SearchMaterialSqlMethodExecutor extends AbstractMethodExecutor implements ISearchMaterialMethodExecutor +public class SearchMaterialSqlMethodExecutor extends AbstractSearchMethodExecutor<Material, Long, MaterialSearchCriterion, MaterialFetchOptions> + implements ISearchMaterialMethodExecutor { @Autowired @@ -53,118 +41,16 @@ public class SearchMaterialSqlMethodExecutor extends AbstractMethodExecutor impl @Autowired private IMaterialSqlTranslator translator; - @Autowired - private CacheManager cacheManager; - @Override - public List<Material> search(final String sessionToken, final MaterialSearchCriterion criterion, final MaterialFetchOptions fetchOptions) - { - return executeInContext(sessionToken, new IMethodAction<List<Material>>() - { - @Override - public List<Material> execute(IOperationContext context) - { - Collection<Material> results = searchAndTranslate(context, criterion, fetchOptions); - return sortAndPage(context, results, fetchOptions); - } - }); - } - - @SuppressWarnings("unchecked") - private Collection<Material> searchAndTranslate(IOperationContext context, MaterialSearchCriterion criterion, MaterialFetchOptions fetchOptions) - { - if (CacheMode.NO_CACHE.equals(fetchOptions.getCacheMode())) - { - return doSearchAndTranslate(context, criterion, fetchOptions); - } else if (CacheMode.CACHE.equals(fetchOptions.getCacheMode()) || CacheMode.RELOAD_AND_CACHE.equals(fetchOptions.getCacheMode())) - { - Cache cache = cacheManager.getCache("searchCache"); - CacheKey key = new CacheKey(context.getSession().getSessionToken(), fetchOptions); - Collection<Material> results = null; - - if (CacheMode.RELOAD_AND_CACHE.equals(fetchOptions.getCacheMode())) - { - cache.evict(key); - } else - { - ValueWrapper wrapper = cache.get(key); - if (wrapper != null) - { - results = (Collection<Material>) wrapper.get(); - } - } - - if (results == null) - { - results = doSearchAndTranslate(context, criterion, fetchOptions); - cache.put(key, results); - } - - return results; - } else - { - throw new IllegalArgumentException("Unsupported cache mode: " + fetchOptions.getCacheMode()); - } - } - - private Collection<Material> doSearchAndTranslate(IOperationContext context, MaterialSearchCriterion criterion, MaterialFetchOptions fetchOptions) + protected ISearchObjectExecutor<MaterialSearchCriterion, Long> getSearchExecutor() { - List<Long> ids = searchExecutor.search(context, criterion); - TranslationContext translationContext = new TranslationContext(context.getSession()); - Map<Long, Material> idToObjectMap = translator.translate(translationContext, ids, fetchOptions); - return idToObjectMap.values(); + return searchExecutor; } - private List<Material> sortAndPage(IOperationContext context, Collection<Material> results, MaterialFetchOptions fetchOptions) + @Override + protected ITranslator<Long, Material, MaterialFetchOptions> getTranslator() { - if (results == null || results.isEmpty()) - { - return Collections.emptyList(); - } - - SortAndPage sap = new SortAndPage(); - Collection<Material> objects = sap.sortAndPage(results, fetchOptions); - - return new ArrayList<Material>(objects); + return translator; } - private static class CacheKey - { - - private String sessionToken; - - private FetchOptions<?> fetchOptions; - - public CacheKey(String sessionToken, FetchOptions<?> fetchOptions) - { - this.sessionToken = sessionToken; - this.fetchOptions = fetchOptions; - } - - @Override - public int hashCode() - { - return sessionToken.hashCode() + fetchOptions.getClass().hashCode(); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) - { - return true; - } - if (obj == null) - { - return false; - } - if (getClass() != obj.getClass()) - { - return false; - } - - CacheKey other = (CacheKey) obj; - return sessionToken.equals(other.sessionToken) && FetchOptionsMatcher.arePartsEqual(fetchOptions, other.fetchOptions); - } - } } diff --git a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/SearchDataSetTest.java b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/SearchDataSetTest.java index 29fb16af686..c5440b1cf67 100644 --- a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/SearchDataSetTest.java +++ b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/SearchDataSetTest.java @@ -43,6 +43,7 @@ import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.entitytype.EntityTypePer import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.tag.TagPermId; import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.DataSetSearchCriterion; import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.SampleSearchCriterion; +import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.SearchResult; /** * @author pkupczyk @@ -408,7 +409,8 @@ public class SearchDataSetTest extends AbstractDataSetTest private List<DataSet> searchDataSets(String user, DataSetSearchCriterion criterion, DataSetFetchOptions fetchOptions) { String sessionToken = v3api.login(user, PASSWORD); - List<DataSet> dataSets = v3api.searchDataSets(sessionToken, criterion, fetchOptions); + SearchResult<DataSet> searchResult = v3api.searchDataSets(sessionToken, criterion, fetchOptions); + List<DataSet> dataSets = searchResult.getObjects(); v3api.logout(sessionToken); return dataSets; } diff --git a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/SearchExperimentTest.java b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/SearchExperimentTest.java index 0b10d60f7c4..0c5bd8ca943 100644 --- a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/SearchExperimentTest.java +++ b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/SearchExperimentTest.java @@ -35,6 +35,7 @@ import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.space.SpacePermId; import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.tag.TagCode; import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.tag.TagPermId; import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.ExperimentSearchCriterion; +import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.SearchResult; /** * @author pkupczyk @@ -236,7 +237,7 @@ public class SearchExperimentTest extends AbstractExperimentTest criterion.withProperty("COMMENT"); testSearch(TEST_USER, criterion, "/CISD/NEMO/EXP-TEST-1"); } - + @Test public void testSearchWithPropertyThatContains() { @@ -555,8 +556,9 @@ public class SearchExperimentTest extends AbstractExperimentTest { String sessionToken = v3api.login(user, PASSWORD); - List<Experiment> experiments = + SearchResult<Experiment> searchResult = v3api.searchExperiments(sessionToken, criterion, new ExperimentFetchOptions()); + List<Experiment> experiments = searchResult.getObjects(); assertExperimentIdentifiers(experiments, expectedIdentifiers); v3api.logout(sessionToken); @@ -566,8 +568,9 @@ public class SearchExperimentTest extends AbstractExperimentTest { String sessionToken = v3api.login(user, PASSWORD); - List<Experiment> experiments = + SearchResult<Experiment> searchResult = v3api.searchExperiments(sessionToken, criterion, new ExperimentFetchOptions()); + List<Experiment> experiments = searchResult.getObjects(); assertEquals(experiments.size(), expectedCount); v3api.logout(sessionToken); diff --git a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/SearchMaterialTest.java b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/SearchMaterialTest.java index 5b0a5a74027..e896ab6fb65 100644 --- a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/SearchMaterialTest.java +++ b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/SearchMaterialTest.java @@ -28,6 +28,7 @@ import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.entitytype.EntityTypePer import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.material.MaterialPermId; import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.tag.TagPermId; import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.MaterialSearchCriterion; +import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.SearchResult; import ch.systemsx.cisd.common.action.IDelegatedAction; /** @@ -259,8 +260,9 @@ public class SearchMaterialTest extends AbstractTest { String sessionToken = v3api.login(user, PASSWORD); - List<Material> materials = + SearchResult<Material> searchResult = v3api.searchMaterials(sessionToken, criterion, new MaterialFetchOptions()); + List<Material> materials = searchResult.getObjects(); assertMaterialPermIds(materials, expectedPermIds); v3api.logout(sessionToken); @@ -270,8 +272,9 @@ public class SearchMaterialTest extends AbstractTest { String sessionToken = v3api.login(user, PASSWORD); - List<Material> materials = + SearchResult<Material> searchResult = v3api.searchMaterials(sessionToken, criterion, new MaterialFetchOptions()); + List<Material> materials = searchResult.getObjects(); assertEquals(materials.size(), expectedCount); v3api.logout(sessionToken); diff --git a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/SearchProjectTest.java b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/SearchProjectTest.java index b6d2cf528ba..5a2b63f0521 100644 --- a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/SearchProjectTest.java +++ b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/SearchProjectTest.java @@ -26,6 +26,7 @@ import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.project.ProjectIdentifie import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.project.ProjectPermId; import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.space.SpacePermId; import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.ProjectSearchCriterion; +import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.SearchResult; /** * @author pkupczyk @@ -154,7 +155,8 @@ public class SearchProjectTest extends AbstractTest { String sessionToken = v3api.login(user, PASSWORD); - List<Project> projects = v3api.searchProjects(sessionToken, criterion, new ProjectFetchOptions()); + SearchResult<Project> searchResult = v3api.searchProjects(sessionToken, criterion, new ProjectFetchOptions()); + List<Project> projects = searchResult.getObjects(); assertProjectIdentifiers(projects, expectedIdentifiers); v3api.logout(sessionToken); diff --git a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/SearchSampleTest.java b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/SearchSampleTest.java index be5b4d60d73..d3c1691c7a1 100644 --- a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/SearchSampleTest.java +++ b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/SearchSampleTest.java @@ -35,6 +35,7 @@ import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.space.SpacePermId; import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.tag.TagCode; import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.tag.TagPermId; import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.SampleSearchCriterion; +import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.SearchResult; /** * @author pkupczyk @@ -476,8 +477,9 @@ public class SearchSampleTest extends AbstractSampleTest { String sessionToken = v3api.login(user, PASSWORD); - List<Sample> samples = + SearchResult<Sample> searchResult = v3api.searchSamples(sessionToken, criterion, new SampleFetchOptions()); + List<Sample> samples = searchResult.getObjects(); assertSampleIdentifiers(samples, expectedIdentifiers); v3api.logout(sessionToken); @@ -487,8 +489,9 @@ public class SearchSampleTest extends AbstractSampleTest { String sessionToken = v3api.login(user, PASSWORD); - List<Sample> samples = + SearchResult<Sample> searchResult = v3api.searchSamples(sessionToken, criterion, new SampleFetchOptions()); + List<Sample> samples = searchResult.getObjects(); assertEquals(samples.size(), expectedCount); v3api.logout(sessionToken); diff --git a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/SearchSpaceTest.java b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/SearchSpaceTest.java index d15cdb8d8d0..bc3547081e6 100644 --- a/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/SearchSpaceTest.java +++ b/openbis/sourceTest/java/ch/ethz/sis/openbis/systemtest/api/v3/SearchSpaceTest.java @@ -23,6 +23,7 @@ import org.testng.annotations.Test; import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.space.Space; import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.space.SpaceFetchOptions; import ch.ethz.sis.openbis.generic.shared.api.v3.dto.id.space.SpacePermId; +import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.SearchResult; import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.SpaceSearchCriterion; /** @@ -144,8 +145,9 @@ public class SearchSpaceTest extends AbstractTest { String sessionToken = v3api.login(user, PASSWORD); - List<Space> spaces = + SearchResult<Space> searchResult = v3api.searchSpaces(sessionToken, criterion, new SpaceFetchOptions()); + List<Space> spaces = searchResult.getObjects(); assertSpaceCodes(spaces, expectedCodes); v3api.logout(sessionToken); diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/shared/api/v3/IApplicationServerApi.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/shared/api/v3/IApplicationServerApi.java index ded9320b353..e08d53925ca 100644 --- a/openbis_api/source/java/ch/ethz/sis/openbis/generic/shared/api/v3/IApplicationServerApi.java +++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/shared/api/v3/IApplicationServerApi.java @@ -67,6 +67,7 @@ import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.ExperimentSearchCrit import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.MaterialSearchCriterion; import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.ProjectSearchCriterion; import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.SampleSearchCriterion; +import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.SearchResult; import ch.ethz.sis.openbis.generic.shared.api.v3.dto.search.SpaceSearchCriterion; import ch.systemsx.cisd.common.api.IRpcService; @@ -135,17 +136,18 @@ public interface IApplicationServerApi extends IRpcService public Map<IMaterialId, Material> mapMaterials(String sessionToken, List<? extends IMaterialId> materialIds, MaterialFetchOptions fetchOptions); - public List<Space> searchSpaces(String sessionToken, SpaceSearchCriterion searchCriterion, SpaceFetchOptions fetchOptions); + public SearchResult<Space> searchSpaces(String sessionToken, SpaceSearchCriterion searchCriterion, SpaceFetchOptions fetchOptions); - public List<Project> searchProjects(String sessionToken, ProjectSearchCriterion searchCriterion, ProjectFetchOptions fetchOptions); + public SearchResult<Project> searchProjects(String sessionToken, ProjectSearchCriterion searchCriterion, ProjectFetchOptions fetchOptions); - public List<Experiment> searchExperiments(String sessionToken, ExperimentSearchCriterion searchCriterion, ExperimentFetchOptions fetchOptions); + public SearchResult<Experiment> searchExperiments(String sessionToken, ExperimentSearchCriterion searchCriterion, + ExperimentFetchOptions fetchOptions); - public List<Sample> searchSamples(String sessionToken, SampleSearchCriterion searchCriterion, SampleFetchOptions fetchOptions); + public SearchResult<Sample> searchSamples(String sessionToken, SampleSearchCriterion searchCriterion, SampleFetchOptions fetchOptions); - public List<DataSet> searchDataSets(String sessionToken, DataSetSearchCriterion searchCriterion, DataSetFetchOptions fetchOptions); + public SearchResult<DataSet> searchDataSets(String sessionToken, DataSetSearchCriterion searchCriterion, DataSetFetchOptions fetchOptions); - public List<Material> searchMaterials(String sessionToken, MaterialSearchCriterion searchCriterion, MaterialFetchOptions fetchOptions); + public SearchResult<Material> searchMaterials(String sessionToken, MaterialSearchCriterion searchCriterion, MaterialFetchOptions fetchOptions); public void deleteSpaces(String sessionToken, List<? extends ISpaceId> spaceIds, SpaceDeletionOptions deletionOptions); diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/shared/api/v3/dto/search/SearchResult.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/shared/api/v3/dto/search/SearchResult.java index d1601f66ceb..2f5a66919a6 100644 --- a/openbis_api/source/java/ch/ethz/sis/openbis/generic/shared/api/v3/dto/search/SearchResult.java +++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/shared/api/v3/dto/search/SearchResult.java @@ -24,8 +24,24 @@ import java.util.List; public class SearchResult<OBJECT> { - private List<Object> objects; + private List<OBJECT> objects; private int totalCount; + public SearchResult(List<OBJECT> objects, int totalCount) + { + this.objects = objects; + this.totalCount = totalCount; + } + + public List<OBJECT> getObjects() + { + return objects; + } + + public int getTotalCount() + { + return totalCount; + } + } -- GitLab