From a326ef13594f716eca4cbab9b61351fa8d059e43 Mon Sep 17 00:00:00 2001 From: felmer <felmer> Date: Tue, 18 Nov 2014 09:07:30 +0000 Subject: [PATCH] SSDM-1080: Extract search domain functionality from DataSetTable into new BO class SearchDomainSearcher. SVN: 32856 --- .../server/CommonBusinessObjectFactory.java | 9 + .../openbis/generic/server/CommonServer.java | 10 +- .../business/bo/AbstractBusinessObject.java | 16 + .../server/business/bo/DataSetTable.java | 225 +---------- .../bo/ICommonBusinessObjectFactory.java | 2 + .../server/business/bo/IDataSetTable.java | 13 - .../business/bo/ISearchDomainSearcher.java | 44 +++ .../business/bo/SearchDomainSearcher.java | 264 +++++++++++++ .../server/business/bo/DataSetTableTest.java | 101 ----- .../business/bo/SearchDomainSearcherTest.java | 374 ++++++++++++++++++ 10 files changed, 718 insertions(+), 340 deletions(-) create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ISearchDomainSearcher.java create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/SearchDomainSearcher.java create mode 100644 openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/SearchDomainSearcherTest.java diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonBusinessObjectFactory.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonBusinessObjectFactory.java index 408ba01ecaf..66ea1127e91 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonBusinessObjectFactory.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonBusinessObjectFactory.java @@ -60,6 +60,7 @@ import ch.systemsx.cisd.openbis.generic.server.business.bo.IRoleAssignmentTable; import ch.systemsx.cisd.openbis.generic.server.business.bo.ISampleBO; import ch.systemsx.cisd.openbis.generic.server.business.bo.ISampleTable; import ch.systemsx.cisd.openbis.generic.server.business.bo.IScriptBO; +import ch.systemsx.cisd.openbis.generic.server.business.bo.ISearchDomainSearcher; import ch.systemsx.cisd.openbis.generic.server.business.bo.ISpaceBO; import ch.systemsx.cisd.openbis.generic.server.business.bo.ITrashBO; import ch.systemsx.cisd.openbis.generic.server.business.bo.IVocabularyBO; @@ -74,6 +75,7 @@ import ch.systemsx.cisd.openbis.generic.server.business.bo.RoleAssignmentTable; import ch.systemsx.cisd.openbis.generic.server.business.bo.SampleBO; import ch.systemsx.cisd.openbis.generic.server.business.bo.SampleTable; import ch.systemsx.cisd.openbis.generic.server.business.bo.ScriptBO; +import ch.systemsx.cisd.openbis.generic.server.business.bo.SearchDomainSearcher; import ch.systemsx.cisd.openbis.generic.server.business.bo.SpaceBO; import ch.systemsx.cisd.openbis.generic.server.business.bo.TrashBO; import ch.systemsx.cisd.openbis.generic.server.business.bo.VocabularyBO; @@ -202,6 +204,13 @@ public final class CommonBusinessObjectFactory extends AbstractBusinessObjectFac getManagedPropertyEvaluatorFactory(), getMultiplexer()); } + @Override + public ISearchDomainSearcher createSearchDomainSearcher(Session session) + { + return new SearchDomainSearcher(getDaoFactory(), session, getManagedPropertyEvaluatorFactory(), + getDSSFactory()); + } + @Override public IDeletedDataSetTable createDeletedDataSetTable(Session session) { diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java index 32a64769c13..38d278e49f5 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServer.java @@ -115,6 +115,7 @@ import ch.systemsx.cisd.openbis.generic.server.business.bo.IRoleAssignmentTable; import ch.systemsx.cisd.openbis.generic.server.business.bo.ISampleBO; import ch.systemsx.cisd.openbis.generic.server.business.bo.ISampleTable; import ch.systemsx.cisd.openbis.generic.server.business.bo.IScriptBO; +import ch.systemsx.cisd.openbis.generic.server.business.bo.ISearchDomainSearcher; import ch.systemsx.cisd.openbis.generic.server.business.bo.ISpaceBO; import ch.systemsx.cisd.openbis.generic.server.business.bo.ITrashBO; import ch.systemsx.cisd.openbis.generic.server.business.bo.IVocabularyBO; @@ -1621,9 +1622,8 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt { Session session = getSession(sessionToken); - IDataSetTable dataSetTable = businessObjectFactory.createDataSetTable(session); - return dataSetTable.searchForDataSetsWithSequences(preferredSearchDomainOrNull, searchString, - optionalParametersOrNull); + ISearchDomainSearcher searcher = businessObjectFactory.createSearchDomainSearcher(session); + return searcher.searchForEntitiesWithSequences(preferredSearchDomainOrNull, searchString, optionalParametersOrNull); } @Override @@ -1632,8 +1632,8 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt { Session session = getSession(sessionToken); - IDataSetTable dataSetTable = businessObjectFactory.createDataSetTable(session); - return dataSetTable.listAvailableSearchDomains(); + ISearchDomainSearcher searcher = businessObjectFactory.createSearchDomainSearcher(session); + return searcher.listAvailableSearchDomains(); } @Override diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractBusinessObject.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractBusinessObject.java index 40328ce3664..d4b768b5e05 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractBusinessObject.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/AbstractBusinessObject.java @@ -25,10 +25,12 @@ import java.util.List; import java.util.Map; import java.util.Set; +import org.apache.commons.lang.StringUtils; import org.hibernate.SessionFactory; import org.springframework.dao.DataAccessException; import ch.systemsx.cisd.common.exceptions.UserFailureException; +import ch.systemsx.cisd.openbis.generic.server.business.IDataStoreServiceFactory; import ch.systemsx.cisd.openbis.generic.server.dataaccess.EntityPropertiesConverter; import ch.systemsx.cisd.openbis.generic.server.dataaccess.IAttachmentDAO; import ch.systemsx.cisd.openbis.generic.server.dataaccess.IAuthorizationGroupDAO; @@ -71,11 +73,13 @@ import ch.systemsx.cisd.openbis.generic.server.dataaccess.RelationshipUtils; import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.ICodeSequenceDAO; import ch.systemsx.cisd.openbis.generic.server.dataaccess.db.IPermIdDAO; import ch.systemsx.cisd.openbis.generic.server.util.SpaceIdentifierHelper; +import ch.systemsx.cisd.openbis.generic.shared.IDataStoreService; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Identifier; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewAttachment; import ch.systemsx.cisd.openbis.generic.shared.dto.AttachmentHolderPE; import ch.systemsx.cisd.openbis.generic.shared.dto.AttachmentPE; +import ch.systemsx.cisd.openbis.generic.shared.dto.DataStorePE; import ch.systemsx.cisd.openbis.generic.shared.dto.EntityPropertyPE; import ch.systemsx.cisd.openbis.generic.shared.dto.EntityTypePE; import ch.systemsx.cisd.openbis.generic.shared.dto.IEntityPropertiesHolder; @@ -207,6 +211,18 @@ abstract class AbstractBusinessObject implements IDAOFactory throw UserFailureException.fromTemplate(ERR_MODIFIED_ENTITY, entityName); } + protected static IDataStoreService tryGetDataStoreService(DataStorePE dataStore, + IDataStoreServiceFactory dataStoreServiceFactory) + { + String remoteURL = dataStore.getRemoteUrl(); + if (StringUtils.isBlank(remoteURL)) + { + // null if DSS URL has not been specified + return null; + } + return dataStoreServiceFactory.create(remoteURL); + } + /** * Returns the perm ID of specified identifier or creates a new one if it is <code>null</code>. */ diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataSetTable.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataSetTable.java index ca1b3c7a9be..b07c0e87967 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataSetTable.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataSetTable.java @@ -21,7 +21,6 @@ import static ch.systemsx.cisd.openbis.generic.shared.translator.DataSetTranslat import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.EnumMap; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -39,8 +38,6 @@ import org.springframework.dao.DataIntegrityViolationException; import ch.rinn.restrictions.Private; import ch.systemsx.cisd.common.collection.CollectionUtils; -import ch.systemsx.cisd.common.collection.IKeyExtractor; -import ch.systemsx.cisd.common.collection.TableMap; import ch.systemsx.cisd.common.exceptions.ConfigurationFailureException; import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException; import ch.systemsx.cisd.common.exceptions.UserFailureException; @@ -62,13 +59,7 @@ import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDataDAO; import ch.systemsx.cisd.openbis.generic.server.dataaccess.event.DeleteDataSetEventBuilder; import ch.systemsx.cisd.openbis.generic.shared.Constants; import ch.systemsx.cisd.openbis.generic.shared.IDataStoreService; -import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataSetFileSearchResultLocation; -import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.EntityPropertySearchResultLocation; -import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.ISearchDomainResultLocation; -import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchDomain; -import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchDomainSearchResult; import ch.systemsx.cisd.openbis.generic.shared.basic.BasicConstant; -import ch.systemsx.cisd.openbis.generic.shared.basic.IEntityInformationHolderWithPermId; import ch.systemsx.cisd.openbis.generic.shared.basic.TableModelAppender; import ch.systemsx.cisd.openbis.generic.shared.basic.TableModelAppender.TableModelWithDifferentColumnCountException; import ch.systemsx.cisd.openbis.generic.shared.basic.TableModelAppender.TableModelWithDifferentColumnIdsException; @@ -81,7 +72,6 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetBatchUpdateDetai import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataStoreServiceKind; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.LinkModel; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Metaproject; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SearchDomainSearchResultWithFullEntity; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TableModel; import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE; import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetBatchUpdatesDTO; @@ -98,8 +88,6 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.Session; import ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityKind; import ch.systemsx.cisd.openbis.generic.shared.managed_property.IManagedPropertyEvaluatorFactory; import ch.systemsx.cisd.openbis.generic.shared.translator.DataSetTranslator; -import ch.systemsx.cisd.openbis.generic.shared.translator.ExperimentTranslator; -import ch.systemsx.cisd.openbis.generic.shared.translator.SampleTranslator; import ch.systemsx.cisd.openbis.generic.shared.util.HibernateUtils; /** @@ -116,16 +104,6 @@ public final class DataSetTable extends AbstractDataSetBusinessObject implements private static final Logger operationLog = LogFactory.getLogger(LogCategory.OPERATION, DataSetTable.class); - private static final IKeyExtractor<String, IEntityInformationHolderWithPermId> PERM_ID_EXTRACTOR = - new IKeyExtractor<String, IEntityInformationHolderWithPermId>() - { - @Override - public String getKey(IEntityInformationHolderWithPermId e) - { - return e.getPermId(); - } - }; - @Private static final String UPLOAD_COMMENT_TEXT = "Uploaded zip file contains the following data sets:"; @@ -293,190 +271,6 @@ public final class DataSetTable extends AbstractDataSetBusinessObject implements this.dataSets = dataSets; } - @Override - public List<SearchDomainSearchResultWithFullEntity> searchForDataSetsWithSequences(String preferredSequenceDatabaseOrNull, - String sequenceSnippet, Map<String, String> optionalParametersOrNull) - { - List<SearchDomainSearchResult> searchResults = askAllDataStoreServers(preferredSequenceDatabaseOrNull, - sequenceSnippet, optionalParametersOrNull); - return enrichWithEntities(searchResults); - } - - private List<SearchDomainSearchResultWithFullEntity> enrichWithEntities(List<SearchDomainSearchResult> searchResults) - { - Map<EntityLoader, List<String>> map = separate(searchResults); - Map<EntityLoader, TableMap<String, IEntityInformationHolderWithPermId>> result = loadEntities(map); - List<SearchDomainSearchResultWithFullEntity> filteredResult = new ArrayList<SearchDomainSearchResultWithFullEntity>(); - for (SearchDomainSearchResult searchResult : searchResults) - { - Selector selector = new Selector(searchResult.getResultLocation()); - EntityLoader loader = selector.getLoader(); - IEntityInformationHolderWithPermId entity = result.get(loader).getOrDie(selector.getPermId()); - SearchDomainSearchResultWithFullEntity searchResultWithEntity = new SearchDomainSearchResultWithFullEntity(); - searchResultWithEntity.setSearchResult(searchResult); - searchResultWithEntity.setEntity(entity); - filteredResult.add(searchResultWithEntity); - } - return filteredResult; - } - - private Map<EntityLoader, List<String>> separate(List<SearchDomainSearchResult> searchResults) - { - Map<EntityLoader, List<String>> map = new EnumMap<DataSetTable.EntityLoader, List<String>>(EntityLoader.class); - for (SearchDomainSearchResult searchResult : searchResults) - { - ISearchDomainResultLocation resultLocation = searchResult.getResultLocation(); - Selector selector = new Selector(resultLocation); - EntityLoader loader = selector.getLoader(); - List<String> list = map.get(loader); - if (list == null) - { - list = new ArrayList<String>(); - map.put(loader, list); - } - list.add(selector.getPermId()); - } - return map; - } - - private Map<EntityLoader, TableMap<String, IEntityInformationHolderWithPermId>> loadEntities(Map<EntityLoader, List<String>> map) - { - Map<EntityLoader, TableMap<String, IEntityInformationHolderWithPermId>> result = - new EnumMap<DataSetTable.EntityLoader, TableMap<String, IEntityInformationHolderWithPermId>>(EntityLoader.class); - Set<Entry<EntityLoader, List<String>>> entrySet = map.entrySet(); - for (Entry<EntityLoader, List<String>> entry : entrySet) - { - EntityLoader loader = entry.getKey(); - List<String> permIds = entry.getValue(); - List<IEntityInformationHolderWithPermId> entities = loader.loadEntities(this, managedPropertyEvaluatorFactory, permIds); - result.put(loader, new TableMap<String, IEntityInformationHolderWithPermId>(entities, PERM_ID_EXTRACTOR)); - } - return result; - } - - private static enum EntityLoader - { - SAMPLE() - { - @Override - public List<? extends IEntityInformationHolderWithPermId> doLoadEntities(IDAOFactory daoFactory, - IManagedPropertyEvaluatorFactory evaluatorFactory, List<String> permIds) - { - return SampleTranslator.translate(daoFactory.getSampleDAO().listByPermID(permIds), - "", Collections.<Long, Set<Metaproject>>emptyMap(), evaluatorFactory); - } - }, - DATA_SET() - { - @Override - public List<? extends IEntityInformationHolderWithPermId> doLoadEntities(IDAOFactory daoFactory, - IManagedPropertyEvaluatorFactory evaluatorFactory, List<String> permIds) - { - return DataSetTranslator.translate(daoFactory.getDataDAO().listByCode(new HashSet<String>(permIds)), - "", "", Collections.<Long, Set<Metaproject>>emptyMap(), evaluatorFactory); - } - }, - EXPERIMENT() - { - @Override - public List<? extends IEntityInformationHolderWithPermId> doLoadEntities(IDAOFactory daoFactory, - IManagedPropertyEvaluatorFactory evaluatorFactory, List<String> permIds) - { - return ExperimentTranslator.translate(daoFactory.getExperimentDAO().listByPermID(permIds), - "", Collections.<Long, Set<Metaproject>>emptyMap(), evaluatorFactory); - } - }, - MATERIAL() - { - @Override - public List<? extends IEntityInformationHolderWithPermId> doLoadEntities(IDAOFactory daoFactory, - IManagedPropertyEvaluatorFactory evaluatorFactory, List<String> permIds) - { - throw new UnsupportedOperationException(); - } - }; - - public List<IEntityInformationHolderWithPermId> loadEntities(IDAOFactory daoFactory, - IManagedPropertyEvaluatorFactory evaluatorFactory, List<String> permIds) - { - List<IEntityInformationHolderWithPermId> result = new ArrayList<IEntityInformationHolderWithPermId>(); - for (IEntityInformationHolderWithPermId entity : doLoadEntities(daoFactory, evaluatorFactory, permIds)) - { - result.add(entity); - } - return result; - } - - public abstract List<? extends IEntityInformationHolderWithPermId> doLoadEntities(IDAOFactory daoFactory, - IManagedPropertyEvaluatorFactory evaluatorFactory, List<String> permIds); - } - - private static final class Selector - { - private EntityLoader loader; - - private String permId; - - Selector(ISearchDomainResultLocation resultLocation) - { - permId = null; - loader = EntityLoader.DATA_SET; - if (resultLocation instanceof DataSetFileSearchResultLocation) - { - permId = ((DataSetFileSearchResultLocation) resultLocation).getDataSetCode(); - } else if (resultLocation instanceof EntityPropertySearchResultLocation) - { - EntityPropertySearchResultLocation location = (EntityPropertySearchResultLocation) resultLocation; - permId = location.getPermId(); - loader = EntityLoader.valueOf(location.getEntityKind().toString()); - } - } - - EntityLoader getLoader() - { - return loader; - } - - String getPermId() - { - return permId; - } - - } - - @Override - public List<SearchDomain> listAvailableSearchDomains() - { - List<SearchDomain> result = new ArrayList<SearchDomain>(); - List<DataStorePE> stores = getDataStoreDAO().listDataStores(); - for (DataStorePE dataStore : stores) - { - IDataStoreService service = tryGetDataStoreService(dataStore); - if (service != null) - { - result.addAll(service.listAvailableSearchDomains(dataStore.getSessionToken())); - } - } - return result; - } - - private List<SearchDomainSearchResult> askAllDataStoreServers(String preferredSequenceDatabaseOrNull, - String sequenceSnippet, Map<String, String> optionalParametersOrNull) - { - List<SearchDomainSearchResult> result = new ArrayList<SearchDomainSearchResult>(); - List<DataStorePE> stores = getDataStoreDAO().listDataStores(); - for (DataStorePE dataStore : stores) - { - IDataStoreService service = tryGetDataStoreService(dataStore); - if (service != null) - { - result.addAll(service.searchForDataSetsWithSequences(dataStore.getSessionToken(), - preferredSequenceDatabaseOrNull, sequenceSnippet, optionalParametersOrNull)); - } - } - return result; - } - @Override public void loadByDataSetCodes(List<String> dataSetCodes, boolean withProperties, boolean lockForUpdate) @@ -691,23 +485,12 @@ public final class DataSetTable extends AbstractDataSetBusinessObject implements service.uploadDataSetsToCIFEX(sessionToken, cleanDataSets, context); } - // null if DSS URL has not been specified - private IDataStoreService tryGetDataStoreService(DataStorePE dataStore) - { - String remoteURL = dataStore.getRemoteUrl(); - if (StringUtils.isBlank(remoteURL)) - { - return null; - } - return dssFactory.create(remoteURL); - } - @Override public void processDatasets(String datastoreServiceKey, String datastoreCode, List<String> datasetCodes, Map<String, String> parameterBindings) { DataStorePE dataStore = findDataStore(datastoreCode); - IDataStoreService service = tryGetDataStoreService(dataStore); + IDataStoreService service = tryGetDataStoreService(dataStore, dssFactory); if (service == null) { throw createUnknownDataStoreServerException(); @@ -763,7 +546,7 @@ public final class DataSetTable extends AbstractDataSetBusinessObject implements DataStorePE dataStore = findDataStore(batch.getId()); String sessionToken = dataStore.getSessionToken(); String userSessionToken = session.getSessionToken(); - IDataStoreService service = tryGetDataStoreService(dataStore); + IDataStoreService service = tryGetDataStoreService(dataStore, dssFactory); parameterBindings.put(Constants.USER_PARAMETER, session.tryGetPerson().getUserId()); service.processDatasets(sessionToken, userSessionToken, datastoreServiceKey, batch.getObjects(), parameterBindings, tryGetLoggedUserId(), tryGetLoggedUserEmail()); @@ -1147,7 +930,7 @@ public final class DataSetTable extends AbstractDataSetBusinessObject implements for (Entry<DataStorePE, List<ExternalDataPE>> entry : datasetsByStore.entrySet()) { DataStorePE dataStore = entry.getKey(); - IDataStoreService service = tryGetDataStoreService(dataStore); + IDataStoreService service = tryGetDataStoreService(dataStore, dssFactory); if (service == null) { throw createUnknownDataStoreServerException(); @@ -1381,7 +1164,7 @@ public final class DataSetTable extends AbstractDataSetBusinessObject implements public LinkModel retrieveLinkFromDataSet(String key, String datastoreCode, String dataSetCode) { DataStorePE dataStore = findDataStore(datastoreCode); - IDataStoreService service = tryGetDataStoreService(dataStore); + IDataStoreService service = tryGetDataStoreService(dataStore, dssFactory); if (service == null) { throw createUnknownDataStoreServerException(); diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ICommonBusinessObjectFactory.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ICommonBusinessObjectFactory.java index 487489adc49..5d15adaa6fa 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ICommonBusinessObjectFactory.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ICommonBusinessObjectFactory.java @@ -46,6 +46,8 @@ public interface ICommonBusinessObjectFactory extends IAbstractBussinessObjectFa public IDataBO createDataBO(Session session); public IDataSetTable createDataSetTable(final Session session); + + public ISearchDomainSearcher createSearchDomainSearcher(Session session); public IDeletedDataSetTable createDeletedDataSetTable(final Session session); diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IDataSetTable.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IDataSetTable.java index 86d56e04b7c..afaeb18469a 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IDataSetTable.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/IDataSetTable.java @@ -19,10 +19,8 @@ package ch.systemsx.cisd.openbis.generic.server.business.bo; import java.util.List; import java.util.Map; -import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchDomain; import ch.systemsx.cisd.openbis.generic.shared.basic.TechId; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.LinkModel; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SearchDomainSearchResultWithFullEntity; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.TableModel; import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE; import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetBatchUpdatesDTO; @@ -37,17 +35,6 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.ExternalDataPE; */ public interface IDataSetTable { - /** - * Searchs for data sets with sequences. - */ - List<SearchDomainSearchResultWithFullEntity> searchForDataSetsWithSequences(String preferredSequenceDatabaseOrNull, - String sequenceSnippet, Map<String, String> optionalParametersOrNull); - - /** - * Lists all available sequence databases. - */ - List<SearchDomain> listAvailableSearchDomains(); - /** * Loads data sets specified by their codes. Data set codes will be ignored if no {@link DataPE} could be found. Properties will be loaded too * depending on <var>withProperties</var> value. Optionally if <var>lockForUpdate</var> is <var>true</var> all updates to loaded data sets from diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ISearchDomainSearcher.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ISearchDomainSearcher.java new file mode 100644 index 00000000000..6f075c9aa49 --- /dev/null +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/ISearchDomainSearcher.java @@ -0,0 +1,44 @@ +/* + * Copyright 2014 ETH Zuerich, SIS + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.openbis.generic.server.business.bo; + +import java.util.List; +import java.util.Map; + +import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchDomain; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SearchDomainSearchResultWithFullEntity; + +/** + * Business object for searching in search domains. + * + * @author Franz-Josef Elmer + */ +public interface ISearchDomainSearcher +{ + /** + * Lists all available sequence databases. + */ + List<SearchDomain> listAvailableSearchDomains(); + + /** + * Searches for entities with sequences. + */ + List<SearchDomainSearchResultWithFullEntity> searchForEntitiesWithSequences(String preferredSearchDomainOrNull, + String sequenceSnippet, Map<String, String> optionalParametersOrNull); + + +} diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/SearchDomainSearcher.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/SearchDomainSearcher.java new file mode 100644 index 00000000000..40b520bb424 --- /dev/null +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/business/bo/SearchDomainSearcher.java @@ -0,0 +1,264 @@ +/* + * Copyright 2014 ETH Zuerich, SIS + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.openbis.generic.server.business.bo; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.EnumMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import ch.systemsx.cisd.common.collection.IKeyExtractor; +import ch.systemsx.cisd.common.collection.TableMap; +import ch.systemsx.cisd.openbis.generic.server.business.IDataStoreServiceFactory; +import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory; +import ch.systemsx.cisd.openbis.generic.shared.IDataStoreService; +import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataSetFileSearchResultLocation; +import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.EntityPropertySearchResultLocation; +import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.ISearchDomainResultLocation; +import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchDomain; +import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchDomainSearchResult; +import ch.systemsx.cisd.openbis.generic.shared.basic.IEntityInformationHolderWithPermId; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Metaproject; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SearchDomainSearchResultWithFullEntity; +import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE; +import ch.systemsx.cisd.openbis.generic.shared.dto.DataStorePE; +import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentPE; +import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE; +import ch.systemsx.cisd.openbis.generic.shared.dto.Session; +import ch.systemsx.cisd.openbis.generic.shared.managed_property.IManagedPropertyEvaluatorFactory; +import ch.systemsx.cisd.openbis.generic.shared.translator.DataSetTranslator; +import ch.systemsx.cisd.openbis.generic.shared.translator.ExperimentTranslator; +import ch.systemsx.cisd.openbis.generic.shared.translator.SampleTranslator; + +/** + * + * + * @author Franz-Josef Elmer + */ +public class SearchDomainSearcher extends AbstractBusinessObject implements ISearchDomainSearcher +{ + private static final Map<Long, Set<Metaproject>> EMPTY_METAPROJECTS = Collections.<Long, Set<Metaproject>>emptyMap(); + + private static final IKeyExtractor<String, IEntityInformationHolderWithPermId> PERM_ID_EXTRACTOR = + new IKeyExtractor<String, IEntityInformationHolderWithPermId>() + { + @Override + public String getKey(IEntityInformationHolderWithPermId e) + { + return e.getPermId(); + } + }; + + private final IDataStoreServiceFactory dssFactory; + + public SearchDomainSearcher(IDAOFactory daoFactory, Session session, + IManagedPropertyEvaluatorFactory managedPropertyEvaluatorFactory, IDataStoreServiceFactory dssFactory) + { + super(daoFactory, session, managedPropertyEvaluatorFactory); + this.dssFactory = dssFactory; + } + + @Override + public List<SearchDomain> listAvailableSearchDomains() + { + List<SearchDomain> result = new ArrayList<SearchDomain>(); + List<DataStorePE> stores = getDataStoreDAO().listDataStores(); + for (DataStorePE dataStore : stores) + { + IDataStoreService service = tryGetDataStoreService(dataStore, dssFactory); + if (service != null) + { + result.addAll(service.listAvailableSearchDomains(dataStore.getSessionToken())); + } + } + return result; + } + + @Override + public List<SearchDomainSearchResultWithFullEntity> searchForEntitiesWithSequences(String preferredSearchDomainOrNull, + String sequenceSnippet, Map<String, String> optionalParametersOrNull) + { + List<SearchDomainSearchResult> searchResults + = askAllDataStoreServers(preferredSearchDomainOrNull, sequenceSnippet, optionalParametersOrNull); + return enrichWithEntities(searchResults); + } + + private List<SearchDomainSearchResult> askAllDataStoreServers(String preferredSearchDomainOrNull, + String sequenceSnippet, Map<String, String> optionalParametersOrNull) + { + List<SearchDomainSearchResult> result = new ArrayList<SearchDomainSearchResult>(); + List<DataStorePE> stores = getDataStoreDAO().listDataStores(); + for (DataStorePE dataStore : stores) + { + IDataStoreService service = tryGetDataStoreService(dataStore, dssFactory); + if (service != null) + { + result.addAll(service.searchForDataSetsWithSequences(dataStore.getSessionToken(), + preferredSearchDomainOrNull, sequenceSnippet, optionalParametersOrNull)); + } + } + return result; + } + + private List<SearchDomainSearchResultWithFullEntity> enrichWithEntities(List<SearchDomainSearchResult> searchResults) + { + Map<EntityLoader, List<String>> map = separate(searchResults); + Map<EntityLoader, TableMap<String, IEntityInformationHolderWithPermId>> result = loadEntities(map); + List<SearchDomainSearchResultWithFullEntity> enrichedResults = new ArrayList<SearchDomainSearchResultWithFullEntity>(); + for (SearchDomainSearchResult searchResult : searchResults) + { + Selector selector = new Selector(searchResult.getResultLocation()); + EntityLoader loader = selector.getLoader(); + IEntityInformationHolderWithPermId entity = result.get(loader).getOrDie(selector.getPermId()); + SearchDomainSearchResultWithFullEntity searchResultWithEntity = new SearchDomainSearchResultWithFullEntity(); + searchResultWithEntity.setSearchResult(searchResult); + searchResultWithEntity.setEntity(entity); + enrichedResults.add(searchResultWithEntity); + } + return enrichedResults; + } + + private Map<EntityLoader, List<String>> separate(List<SearchDomainSearchResult> searchResults) + { + Map<EntityLoader, List<String>> map = new EnumMap<EntityLoader, List<String>>(EntityLoader.class); + for (SearchDomainSearchResult searchResult : searchResults) + { + ISearchDomainResultLocation resultLocation = searchResult.getResultLocation(); + Selector selector = new Selector(resultLocation); + EntityLoader loader = selector.getLoader(); + List<String> list = map.get(loader); + if (list == null) + { + list = new ArrayList<String>(); + map.put(loader, list); + } + list.add(selector.getPermId()); + } + return map; + } + + private Map<EntityLoader, TableMap<String, IEntityInformationHolderWithPermId>> loadEntities(Map<EntityLoader, List<String>> map) + { + Map<EntityLoader, TableMap<String, IEntityInformationHolderWithPermId>> result = + new EnumMap<EntityLoader, TableMap<String, IEntityInformationHolderWithPermId>>(EntityLoader.class); + Set<Entry<EntityLoader, List<String>>> entrySet = map.entrySet(); + for (Entry<EntityLoader, List<String>> entry : entrySet) + { + EntityLoader loader = entry.getKey(); + List<String> permIds = entry.getValue(); + List<IEntityInformationHolderWithPermId> entities + = loader.loadEntities(this, managedPropertyEvaluatorFactory, permIds); + result.put(loader, new TableMap<String, IEntityInformationHolderWithPermId>(entities, PERM_ID_EXTRACTOR)); + } + return result; + } + + private static enum EntityLoader + { + SAMPLE() + { + @Override + public List<? extends IEntityInformationHolderWithPermId> doLoadEntities(IDAOFactory daoFactory, + IManagedPropertyEvaluatorFactory evaluatorFactory, List<String> permIds) + { + List<SamplePE> samples = daoFactory.getSampleDAO().listByPermID(permIds); + return SampleTranslator.translate(samples, "", EMPTY_METAPROJECTS, evaluatorFactory); + } + }, + DATA_SET() + { + @Override + public List<? extends IEntityInformationHolderWithPermId> doLoadEntities(IDAOFactory daoFactory, + IManagedPropertyEvaluatorFactory evaluatorFactory, List<String> permIds) + { + List<DataPE> dataSets = daoFactory.getDataDAO().listByCode(new HashSet<String>(permIds)); + return DataSetTranslator.translate(dataSets, "", "", EMPTY_METAPROJECTS, evaluatorFactory); + } + }, + EXPERIMENT() + { + @Override + public List<? extends IEntityInformationHolderWithPermId> doLoadEntities(IDAOFactory daoFactory, + IManagedPropertyEvaluatorFactory evaluatorFactory, List<String> permIds) + { + List<ExperimentPE> experiments = daoFactory.getExperimentDAO().listByPermID(permIds); + return ExperimentTranslator.translate(experiments, "", EMPTY_METAPROJECTS, evaluatorFactory); + } + }, + MATERIAL() + { + @Override + public List<? extends IEntityInformationHolderWithPermId> doLoadEntities(IDAOFactory daoFactory, + IManagedPropertyEvaluatorFactory evaluatorFactory, List<String> permIds) + { + throw new UnsupportedOperationException(); + } + }; + + public List<IEntityInformationHolderWithPermId> loadEntities(IDAOFactory daoFactory, + IManagedPropertyEvaluatorFactory evaluatorFactory, List<String> permIds) + { + List<IEntityInformationHolderWithPermId> result = new ArrayList<IEntityInformationHolderWithPermId>(); + for (IEntityInformationHolderWithPermId entity : doLoadEntities(daoFactory, evaluatorFactory, permIds)) + { + result.add(entity); + } + return result; + } + + public abstract List<? extends IEntityInformationHolderWithPermId> doLoadEntities(IDAOFactory daoFactory, + IManagedPropertyEvaluatorFactory evaluatorFactory, List<String> permIds); + } + + private static final class Selector + { + private EntityLoader loader; + + private String permId; + + Selector(ISearchDomainResultLocation resultLocation) + { + permId = null; + loader = EntityLoader.DATA_SET; + if (resultLocation instanceof DataSetFileSearchResultLocation) + { + permId = ((DataSetFileSearchResultLocation) resultLocation).getDataSetCode(); + } else if (resultLocation instanceof EntityPropertySearchResultLocation) + { + EntityPropertySearchResultLocation location = (EntityPropertySearchResultLocation) resultLocation; + permId = location.getPermId(); + loader = EntityLoader.valueOf(location.getEntityKind().toString()); + } + } + + EntityLoader getLoader() + { + return loader; + } + + String getPermId() + { + return permId; + } + + } + +} diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataSetTableTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataSetTableTest.java index b82b8bb38f3..e69c9856d54 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataSetTableTest.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/DataSetTableTest.java @@ -26,9 +26,7 @@ import static ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetArchiving import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.HashSet; import java.util.List; -import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -47,16 +45,12 @@ import ch.systemsx.cisd.openbis.generic.server.business.ManagerTestTool; import ch.systemsx.cisd.openbis.generic.server.dataaccess.event.DeleteDataSetEventBuilder; import ch.systemsx.cisd.openbis.generic.shared.CommonTestUtils; import ch.systemsx.cisd.openbis.generic.shared.IDataStoreService; -import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataSetFileSearchResultLocation; -import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchDomain; -import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchDomainSearchResult; import ch.systemsx.cisd.openbis.generic.shared.basic.BasicConstant; import ch.systemsx.cisd.openbis.generic.shared.basic.TechId; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.AbstractExternalData; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Code; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetArchivingStatus; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetKind; -import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SearchDomainSearchResultWithFullEntity; import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetTypePE; import ch.systemsx.cisd.openbis.generic.shared.dto.DataSetUploadContext; import ch.systemsx.cisd.openbis.generic.shared.dto.DataStorePE; @@ -82,12 +76,6 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.ProjectIdentifier; @Friend(toClasses = DataSetTable.class) public final class DataSetTableTest extends AbstractBOTest { - private static final Map<String, String> OPTIONAL_PARAMETERS = Collections.singletonMap("greeting", "hi"); - - private static final String SEQUENCE_SNIPPET = "GATTACA"; - - private static final String SEQUENCE_DATABASE = "MY_DB"; - private IDataStoreServiceFactory dssFactory; private DataStorePE dss1; @@ -165,95 +153,6 @@ public final class DataSetTableTest extends AbstractBOTest }); } - @Test - public void testSearchForDataSetsWithSequences() - { - DataStorePE store1 = new DataStorePE(); - store1.setRemoteUrl("http://abc1.de"); - DataStorePE store2 = new DataStorePE(); - store2.setRemoteUrl("http://abc2.de"); - store2.setSessionToken("session-2"); - DataStorePE store3 = new DataStorePE(); - prepareListDataStores(store1, store2, store3); - prepareSearchSequenceDatabase(store1, dataStoreService1, "ds1", "ds2"); - prepareSearchSequenceDatabase(store2, dataStoreService2, "ds3", "ds3"); - final ExternalDataPE ds1 = createDataSet("ds1", store1); - final ExternalDataPE ds2 = createDataSet("ds2", store1); - final ExternalDataPE ds3 = createDataSet("ds3", store2); - context.checking(new Expectations() - { - { - one(dataDAO).listByCode(new HashSet<String>(Arrays.asList("ds1", "ds2", "ds3"))); - will(returnValue(Arrays.asList(new ExternalDataPE[] { ds1, ds2, ds3 }))); - } - }); - - List<SearchDomainSearchResultWithFullEntity> results = - createDataSetTable().searchForDataSetsWithSequences(SEQUENCE_DATABASE, SEQUENCE_SNIPPET, OPTIONAL_PARAMETERS); - - assertEquals("Search Domain: test-db, Result location: [Data set: ds1, path: ds1/path, " - + "identifier: [id-ds1], position: 42]", - results.get(0).getSearchResult().toString()); - assertEquals(ds1.getCode(), ((AbstractExternalData) results.get(0).getEntity()).getCode()); - assertEquals("/G1/P1/exp1", ((AbstractExternalData) results.get(0).getEntity()).getExperiment().getIdentifier()); - assertEquals("Search Domain: test-db, Result location: [Data set: ds2, path: ds2/path, " - + "identifier: [id-ds2], position: 42]", - results.get(1).getSearchResult().toString()); - assertEquals(ds2.getCode(), ((AbstractExternalData) results.get(1).getEntity()).getCode()); - assertEquals("/G1/P1/exp1", ((AbstractExternalData) results.get(1).getEntity()).getExperiment().getIdentifier()); - assertEquals("Search Domain: test-db, Result location: [Data set: ds3, path: ds3/path, " - + "identifier: [id-ds3], position: 42]", - results.get(2).getSearchResult().toString()); - assertEquals(ds3.getCode(), ((AbstractExternalData) results.get(2).getEntity()).getCode()); - assertEquals("/G1/P1/exp1", ((AbstractExternalData) results.get(2).getEntity()).getExperiment().getIdentifier()); - assertEquals(ds3.getCode(), ((AbstractExternalData) results.get(3).getEntity()).getCode()); - assertEquals("/G1/P1/exp1", ((AbstractExternalData) results.get(3).getEntity()).getExperiment().getIdentifier()); - assertEquals(4, results.size()); - context.assertIsSatisfied(); - } - - private void prepareListDataStores(final DataStorePE... dataStores) - { - context.checking(new Expectations() - { - { - one(dataStoreDAO).listDataStores(); - will(returnValue(Arrays.asList(dataStores))); - } - }); - } - - private void prepareSearchSequenceDatabase(final DataStorePE dataStore, final IDataStoreService service, - final String... foundDataSets) - { - context.checking(new Expectations() - { - { - allowing(dssFactory).create(dataStore.getRemoteUrl()); - will(returnValue(service)); - - one(service).searchForDataSetsWithSequences(dataStore.getSessionToken(), - SEQUENCE_DATABASE, SEQUENCE_SNIPPET, OPTIONAL_PARAMETERS); - List<SearchDomainSearchResult> results = new ArrayList<SearchDomainSearchResult>(); - for (String foundDataSet : foundDataSets) - { - SearchDomainSearchResult result = new SearchDomainSearchResult(); - SearchDomain searchDomain = new SearchDomain(); - searchDomain.setName("test-db"); - result.setSearchDomain(searchDomain); - DataSetFileSearchResultLocation resultLocation = new DataSetFileSearchResultLocation(); - resultLocation.setDataSetCode(foundDataSet); - resultLocation.setPathInDataSet(foundDataSet + "/path"); - resultLocation.setPosition(42); - resultLocation.setIdentifier("id-" + foundDataSet); - result.setResultLocation(resultLocation); - results.add(result); - } - will(returnValue(results)); - } - }); - } - @Test public final void testLoadBySampleTechIdWithNullSampleId() { diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/SearchDomainSearcherTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/SearchDomainSearcherTest.java new file mode 100644 index 00000000000..905ca0b3e67 --- /dev/null +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/business/bo/SearchDomainSearcherTest.java @@ -0,0 +1,374 @@ +/* + * Copyright 2014 ETH Zuerich, SIS + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.openbis.generic.server.business.bo; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; + +import org.jmock.Expectations; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import ch.systemsx.cisd.openbis.generic.server.business.IDataStoreServiceFactory; +import ch.systemsx.cisd.openbis.generic.server.business.ManagerTestTool; +import ch.systemsx.cisd.openbis.generic.shared.IDataStoreService; +import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataSetFileSearchResultLocation; +import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.EntityKind; +import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.EntityPropertySearchResultLocation; +import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchDomain; +import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchDomainSearchResult; +import ch.systemsx.cisd.openbis.generic.shared.basic.IPermIdHolder; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.AbstractExternalData; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetKind; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SearchDomainSearchResultWithFullEntity; +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.ExperimentPE; +import ch.systemsx.cisd.openbis.generic.shared.dto.ExperimentTypePE; +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.ProjectPE; +import ch.systemsx.cisd.openbis.generic.shared.dto.SamplePE; +import ch.systemsx.cisd.openbis.generic.shared.dto.SampleTypePE; +import ch.systemsx.cisd.openbis.generic.shared.dto.SpacePE; + +/** + * @author Franz-Josef Elmer + */ +public class SearchDomainSearcherTest extends AbstractBOTest +{ + private static final Map<String, String> OPTIONAL_PARAMETERS = Collections.singletonMap("greeting", "hi"); + + private static final String SEQUENCE_SNIPPET = "GATTACA"; + + private static final String SEQUENCE_DATABASE = "MY_DB"; + + private IDataStoreServiceFactory dssFactory; + + private IDataStoreService dataStoreService1; + + private IDataStoreService dataStoreService2; + + private DataStorePE store1; + + private DataStorePE store2; + + private DataStorePE store3; + + @BeforeMethod + @Override + public void beforeMethod() + { + super.beforeMethod(); + dssFactory = context.mock(IDataStoreServiceFactory.class); + dataStoreService1 = context.mock(IDataStoreService.class, "dataStoreService1"); + dataStoreService2 = context.mock(IDataStoreService.class, "dataStoreService2"); + store1 = new DataStorePE(); + store1.setRemoteUrl("http://abc1.de"); + store1.setSessionToken("session-1"); + store2 = new DataStorePE(); + store2.setRemoteUrl("http://abc2.de"); + store2.setSessionToken("session-2"); + store3 = new DataStorePE(); + prepareListDataStores(store1, store2, store3); + prepareCreateService(dataStoreService1, store1); + prepareCreateService(dataStoreService2, store2); + } + + @Test + public void testListAvailableSearchDomains() + { + final SearchDomain searchDomain1 = new SearchDomain(); + final SearchDomain searchDomain2 = new SearchDomain(); + final SearchDomain searchDomain3 = new SearchDomain(); + context.checking(new Expectations() + { + { + one(dataStoreService1).listAvailableSearchDomains(store1.getSessionToken()); + will(returnValue(Arrays.asList(searchDomain1))); + + one(dataStoreService2).listAvailableSearchDomains(store2.getSessionToken()); + will(returnValue(Arrays.asList(searchDomain2, searchDomain3))); + } + }); + + List<SearchDomain> searchDomains = createSearcher().listAvailableSearchDomains(); + + assertSame(searchDomain1, searchDomains.get(0)); + assertSame(searchDomain2, searchDomains.get(1)); + assertSame(searchDomain3, searchDomains.get(2)); + assertEquals(3, searchDomains.size()); + context.assertIsSatisfied(); + + } + + @Test + public void testSearchForEntitiesWithSequences() + { + prepareSearchForEntityPropertiesWithSequences(store1, dataStoreService1, "DATA_SET:DS1:SEQ"); + prepareSearchForEntityPropertiesWithSequences(store2, dataStoreService2, + "SAMPLE:S1:OLIGO", "SAMPLE:S2:OLIGO", "EXPERIMENT:E1:S"); + ExternalDataPE ds1 = createDataSet("DS1", store1); + prepareListDataSetsByCode(ds1); + SamplePE s1 = createSample("S1"); + SamplePE s2 = createSample("S2"); + prepareListSamplesByPermId(s1, s2); + ExperimentPE e1 = createExperiment("E1"); + prepareListExperimentsByPermId(e1); + + List<SearchDomainSearchResultWithFullEntity> results = + createSearcher().searchForEntitiesWithSequences(SEQUENCE_DATABASE, SEQUENCE_SNIPPET, OPTIONAL_PARAMETERS); + + assertEquals("DS1", results.get(0).getEntity().getPermId()); + assertEquals("Search Domain: test-db, Result location: [Data_set perm id: DS1, property type: SEQ, position: 24]", + results.get(0).getSearchResult().toString()); + assertEquals("S1", results.get(1).getEntity().getPermId()); + assertEquals("Search Domain: test-db, Result location: [Sample perm id: S1, property type: OLIGO, position: 24]", + results.get(1).getSearchResult().toString()); + assertEquals("S2", results.get(2).getEntity().getPermId()); + assertEquals("Search Domain: test-db, Result location: [Sample perm id: S2, property type: OLIGO, position: 24]", + results.get(2).getSearchResult().toString()); + assertEquals("E1", results.get(3).getEntity().getPermId()); + assertEquals("Search Domain: test-db, Result location: [Experiment perm id: E1, property type: S, position: 24]", + results.get(3).getSearchResult().toString()); + assertEquals(4, results.size()); + context.assertIsSatisfied(); + } + + @Test + public void testSearchForDataSetsWithSequences() + { + prepareSearchForDataSetsWithSequences(store1, dataStoreService1, "ds1", "ds2"); + prepareSearchForDataSetsWithSequences(store2, dataStoreService2, "ds3", "ds3"); + final ExternalDataPE ds1 = createDataSet("ds1", store1); + final ExternalDataPE ds2 = createDataSet("ds2", store1); + final ExternalDataPE ds3 = createDataSet("ds3", store2); + prepareListDataSetsByCode(ds1, ds2, ds3); + + List<SearchDomainSearchResultWithFullEntity> results = + createSearcher().searchForEntitiesWithSequences(SEQUENCE_DATABASE, SEQUENCE_SNIPPET, OPTIONAL_PARAMETERS); + + assertEquals("Search Domain: test-db, Result location: [Data set: ds1, path: ds1/path, " + + "identifier: [id-ds1], position: 42]", + results.get(0).getSearchResult().toString()); + assertEquals(ds1.getCode(), ((AbstractExternalData) results.get(0).getEntity()).getCode()); + assertEquals("/G1/P1/exp1", ((AbstractExternalData) results.get(0).getEntity()).getExperiment().getIdentifier()); + assertEquals("Search Domain: test-db, Result location: [Data set: ds2, path: ds2/path, " + + "identifier: [id-ds2], position: 42]", + results.get(1).getSearchResult().toString()); + assertEquals(ds2.getCode(), ((AbstractExternalData) results.get(1).getEntity()).getCode()); + assertEquals("/G1/P1/exp1", ((AbstractExternalData) results.get(1).getEntity()).getExperiment().getIdentifier()); + assertEquals("Search Domain: test-db, Result location: [Data set: ds3, path: ds3/path, " + + "identifier: [id-ds3], position: 42]", + results.get(2).getSearchResult().toString()); + assertEquals(ds3.getCode(), ((AbstractExternalData) results.get(2).getEntity()).getCode()); + assertEquals("/G1/P1/exp1", ((AbstractExternalData) results.get(2).getEntity()).getExperiment().getIdentifier()); + assertEquals(ds3.getCode(), ((AbstractExternalData) results.get(3).getEntity()).getCode()); + assertEquals("/G1/P1/exp1", ((AbstractExternalData) results.get(3).getEntity()).getExperiment().getIdentifier()); + assertEquals(4, results.size()); + context.assertIsSatisfied(); + } + + private void prepareListDataStores(final DataStorePE... dataStores) + { + context.checking(new Expectations() + { + { + one(dataStoreDAO).listDataStores(); + will(returnValue(Arrays.asList(dataStores))); + } + }); + } + + private void prepareCreateService(final IDataStoreService service, final DataStorePE... dataStores) + { + context.checking(new Expectations() + { + { + for (DataStorePE dataStore : dataStores) + { + allowing(dssFactory).create(dataStore.getRemoteUrl()); + will(returnValue(service)); + } + } + }); + + } + + private void prepareSearchForDataSetsWithSequences(final DataStorePE dataStore, final IDataStoreService service, + final String... foundDataSets) + { + context.checking(new Expectations() + { + { + one(service).searchForDataSetsWithSequences(dataStore.getSessionToken(), + SEQUENCE_DATABASE, SEQUENCE_SNIPPET, OPTIONAL_PARAMETERS); + List<SearchDomainSearchResult> results = new ArrayList<SearchDomainSearchResult>(); + for (String foundDataSet : foundDataSets) + { + SearchDomainSearchResult result = new SearchDomainSearchResult(); + SearchDomain searchDomain = new SearchDomain(); + searchDomain.setName("test-db"); + result.setSearchDomain(searchDomain); + DataSetFileSearchResultLocation resultLocation = new DataSetFileSearchResultLocation(); + resultLocation.setDataSetCode(foundDataSet); + resultLocation.setPathInDataSet(foundDataSet + "/path"); + resultLocation.setPosition(42); + resultLocation.setIdentifier("id-" + foundDataSet); + result.setResultLocation(resultLocation); + results.add(result); + } + will(returnValue(results)); + } + }); + } + + private void prepareSearchForEntityPropertiesWithSequences(final DataStorePE dataStore, + final IDataStoreService service, final String... foundLocations) + { + context.checking(new Expectations() + { + { + one(service).searchForDataSetsWithSequences(dataStore.getSessionToken(), + SEQUENCE_DATABASE, SEQUENCE_SNIPPET, OPTIONAL_PARAMETERS); + List<SearchDomainSearchResult> results = new ArrayList<SearchDomainSearchResult>(); + for (String foundLocation : foundLocations) + { + SearchDomainSearchResult result = new SearchDomainSearchResult(); + SearchDomain searchDomain = new SearchDomain(); + searchDomain.setName("test-db"); + result.setSearchDomain(searchDomain); + EntityPropertySearchResultLocation resultLocation = new EntityPropertySearchResultLocation(); + String[] splittedLocation = foundLocation.split(":"); + resultLocation.setEntityKind(EntityKind.valueOf(splittedLocation[0])); + resultLocation.setPermId(splittedLocation[1]); + resultLocation.setPropertyType(splittedLocation[2]); + resultLocation.setPosition(24); + result.setResultLocation(resultLocation); + results.add(result); + } + will(returnValue(results)); + } + }); + } + + private void prepareListDataSetsByCode(final ExternalDataPE... dataSets) + { + context.checking(new Expectations() + { + { + one(dataDAO).listByCode(new LinkedHashSet<String>(getPermIds(dataSets))); + will(returnValue(Arrays.asList(dataSets))); + } + }); + } + + private void prepareListSamplesByPermId(final SamplePE... samples) + { + context.checking(new Expectations() + { + { + one(sampleDAO).listByPermID(getPermIds(samples)); + will(returnValue(Arrays.asList(samples))); + } + }); + } + + private void prepareListExperimentsByPermId(final ExperimentPE... experiments) + { + context.checking(new Expectations() + { + { + one(experimentDAO).listByPermID(getPermIds(experiments)); + will(returnValue(Arrays.asList(experiments))); + } + }); + } + + private ExternalDataPE createDataSet(String code, DataStorePE dataStore) + { + ExternalDataPE data = new ExternalDataPE(); + data.setId((long) code.hashCode()); + data.setCode(code); + data.setDataStore(dataStore); + data.setLocation("here/" + code); + ExperimentPE experiment = new ExperimentPE(); + experiment.setCode("exp1"); + experiment.setExperimentType(new ExperimentTypePE()); + ProjectPE project = new ProjectPE(); + project.setCode("p1"); + SpacePE group = new SpacePE(); + group.setCode("g1"); + project.setSpace(group); + experiment.setProject(project); + data.setExperiment(experiment); + DataSetTypePE type = new DataSetTypePE(); + type.setDataSetKind(DataSetKind.PHYSICAL.name()); + data.setDataSetType(type); + FileFormatTypePE fileFormatType = new FileFormatTypePE(); + fileFormatType.setCode("fileFormat"); + data.setFileFormatType(fileFormatType); + return data; + } + + private SamplePE createSample(String permID) + { + SamplePE sample = new SamplePE(); + sample.setPermId(permID); + SampleTypePE sampleType = new SampleTypePE(); + sampleType.setCode("TYPE"); + sampleType.setListable(true); + sampleType.setSubcodeUnique(false); + sampleType.setAutoGeneratedCode(false); + sampleType.setShowParentMetadata(false); + sampleType.setContainerHierarchyDepth(0); + sampleType.setGeneratedFromHierarchyDepth(0); + sample.setSampleType(sampleType); + return sample; + } + + private ExperimentPE createExperiment(String permID) + { + ExperimentPE experiment = new ExperimentPE(); + experiment.setPermId(permID); + experiment.setExperimentType(new ExperimentTypePE()); + ProjectPE project = new ProjectPE(); + project.setSpace(new SpacePE()); + experiment.setProject(project); + return experiment; + } + + private SearchDomainSearcher createSearcher() + { + return new SearchDomainSearcher(daoFactory, ManagerTestTool.EXAMPLE_SESSION, + managedPropertyEvaluatorFactory, dssFactory); + } + + protected List<String> getPermIds(final IPermIdHolder... permIdHolders) + { + List<String> permIds = new ArrayList<String>(); + for (IPermIdHolder permIdHolder : permIdHolders) + { + permIds.add(permIdHolder.getPermId()); + } + return permIds; + } +} -- GitLab