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 938f91c4122553dfebfa5040540cea6490fe9a87..6239fa321ad137b99dbe89669358f88a34c1e77f 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 @@ -71,7 +71,6 @@ import ch.systemsx.cisd.openbis.generic.server.business.bo.dynamic_property.calc import ch.systemsx.cisd.openbis.generic.server.business.bo.materiallister.IMaterialLister; import ch.systemsx.cisd.openbis.generic.server.business.bo.samplelister.ISampleLister; import ch.systemsx.cisd.openbis.generic.server.business.search.DataSetSearchManager; -import ch.systemsx.cisd.openbis.generic.server.business.search.SampleSearchManager; import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory; import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDataDAO; import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDataStoreDAO; @@ -266,7 +265,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt return businessObjectFactory; } - private static UserFailureException createUserFailureException(final DataAccessException ex) + static UserFailureException createUserFailureException(final DataAccessException ex) { return new UserFailureException(ex.getMostSpecificCause().getMessage(), ex); } @@ -492,15 +491,9 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt public List<Sample> searchForSamples(String sessionToken, DetailedSearchCriteria criteria) { final Session session = getSession(sessionToken); - try - { - final ISampleLister sampleLister = businessObjectFactory.createSampleLister(session); - final IHibernateSearchDAO searchDAO = getDAOFactory().getHibernateSearchDAO(); - return new SampleSearchManager(searchDAO, sampleLister).searchForSamples(criteria); - } catch (final DataAccessException ex) - { - throw createUserFailureException(ex); - } + SearchHelper searchHelper = + new SearchHelper(session, businessObjectFactory, getDAOFactory()); + return searchHelper.searchForSamples(criteria); } public final List<ExternalData> listSampleExternalData(final String sessionToken, diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLService.java index 3caa53ff5be80301626cb54b82f284eda0e366aa..af1f540cc45529c76fd7e0db0b8c6f8152f7007c 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLService.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLService.java @@ -31,6 +31,7 @@ import ch.systemsx.cisd.common.collections.CollectionUtils; import ch.systemsx.cisd.common.exceptions.ConfigurationFailureException; import ch.systemsx.cisd.common.exceptions.UserFailureException; import ch.systemsx.cisd.common.spring.IInvocationLoggerContext; +import ch.systemsx.cisd.openbis.generic.server.api.v1.SearchCriteriaToDetailedSearchCriteriaTranslator; import ch.systemsx.cisd.openbis.generic.server.business.IDataStoreServiceFactory; import ch.systemsx.cisd.openbis.generic.server.business.IPropertiesBatchManager; import ch.systemsx.cisd.openbis.generic.server.business.bo.ICommonBusinessObjectFactory; @@ -54,6 +55,8 @@ import ch.systemsx.cisd.openbis.generic.server.dataaccess.ISampleTypeDAO; import ch.systemsx.cisd.openbis.generic.server.plugin.IDataSetTypeSlaveServerPlugin; import ch.systemsx.cisd.openbis.generic.shared.IDataStoreService; import ch.systemsx.cisd.openbis.generic.shared.IServer; +import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchCriteria; +import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchableEntityKind; import ch.systemsx.cisd.openbis.generic.shared.basic.TechId; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ArchiverDataSetCriteria; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSet; @@ -63,6 +66,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataStoreServiceKind; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseInstance; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatastoreServiceDescription; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DeletedDataSet; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DetailedSearchCriteria; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityType; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExperimentType; @@ -1106,16 +1110,14 @@ public class ETLService extends AbstractCommonServer<IETLService> implements IET samplesUpdated, samplesCreated, dataSetsCreated, dataSetsUpdated); } - private List<Space> createSpaces(Session session, - AtomicEntityOperationDetails operationDetails) + private List<Space> createSpaces(Session session, AtomicEntityOperationDetails operationDetails) { ArrayList<SpacePE> spacePEsCreated = new ArrayList<SpacePE>(); List<NewSpace> newSpaces = operationDetails.getSpaceRegistrations(); for (NewSpace newSpace : newSpaces) { SpacePE spacePE = - registerSpaceInternal(session, newSpace, - operationDetails.tryUserIdOrNull()); + registerSpaceInternal(session, newSpace, operationDetails.tryUserIdOrNull()); spacePEsCreated.add(spacePE); } return GroupTranslator.translate(spacePEsCreated); @@ -1161,8 +1163,7 @@ public class ETLService extends AbstractCommonServer<IETLService> implements IET for (NewProject newProject : newProjects) { ProjectPE projectPE = - registerProjectInternal(session, newProject, - operationDetails.tryUserIdOrNull()); + registerProjectInternal(session, newProject, operationDetails.tryUserIdOrNull()); projectPEsCreated.add(projectPE); } return ProjectTranslator.translate(projectPEsCreated); @@ -1193,8 +1194,7 @@ public class ETLService extends AbstractCommonServer<IETLService> implements IET for (NewSample newSample : newSamples) { SamplePE samplePE = - registerSampleInternal(session, newSample, - operationDetails.tryUserIdOrNull()); + registerSampleInternal(session, newSample, operationDetails.tryUserIdOrNull()); samplePEsCreated.add(samplePE); } return SampleTranslator.translate(samplePEsCreated, session.getBaseIndexURL()); @@ -1354,4 +1354,15 @@ public class ETLService extends AbstractCommonServer<IETLService> implements IET return externalDataBO; } + public List<Sample> searchForSamples(String sessionToken, SearchCriteria searchCriteria) + { + Session session = getSession(sessionToken); + DetailedSearchCriteria detailedSearchCriteria = + SearchCriteriaToDetailedSearchCriteriaTranslator.convert( + SearchableEntityKind.SAMPLE, searchCriteria); + SearchHelper searchHelper = + new SearchHelper(session, businessObjectFactory, getDAOFactory()); + return searchHelper.searchForSamples(detailedSearchCriteria); + } + } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLServiceLogger.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLServiceLogger.java index 31c61ec419a3ce2c1cc14121b31f2d2efbfe2de7..7c503106f226a8312146ad5b556b167e40676691 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLServiceLogger.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/ETLServiceLogger.java @@ -24,6 +24,7 @@ import ch.systemsx.cisd.authentication.ISessionManager; import ch.systemsx.cisd.common.exceptions.UserFailureException; import ch.systemsx.cisd.common.spring.IInvocationLoggerContext; import ch.systemsx.cisd.openbis.generic.shared.AbstractServerLogger; +import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchCriteria; import ch.systemsx.cisd.openbis.generic.shared.basic.TechId; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ArchiverDataSetCriteria; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetArchivingStatus; @@ -342,8 +343,8 @@ public class ETLServiceLogger extends AbstractServerLogger implements IETLServic public void updateShareIdAndSize(String sessionToken, String dataSetCode, String shareId, long size) throws UserFailureException { - logTracking(sessionToken, "updateShareIdAndSize", "DATA_SET_CODE(%s) SHARE_ID(%s) SIZE(%s)", - dataSetCode, shareId, size); + logTracking(sessionToken, "updateShareIdAndSize", + "DATA_SET_CODE(%s) SHARE_ID(%s) SIZE(%s)", dataSetCode, shareId, size); } public void updateDataSetStatuses(String sessionToken, List<String> dataSetCodes, @@ -475,4 +476,10 @@ public class ETLServiceLogger extends AbstractServerLogger implements IETLServic return null; } + public List<Sample> searchForSamples(String sessionToken, SearchCriteria searchCriteria) + { + logAccess(sessionToken, "searchForSamples", "%s", searchCriteria); + return null; + } + } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/SearchHelper.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/SearchHelper.java new file mode 100644 index 0000000000000000000000000000000000000000..8df2ff513f209b97606c55c67b1f1d6db909620a --- /dev/null +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/SearchHelper.java @@ -0,0 +1,66 @@ +/* + * Copyright 2011 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.openbis.generic.server; + +import java.util.List; + +import org.springframework.dao.DataAccessException; + +import ch.systemsx.cisd.openbis.generic.server.business.bo.ICommonBusinessObjectFactory; +import ch.systemsx.cisd.openbis.generic.server.business.bo.samplelister.ISampleLister; +import ch.systemsx.cisd.openbis.generic.server.business.search.SampleSearchManager; +import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory; +import ch.systemsx.cisd.openbis.generic.server.dataaccess.IHibernateSearchDAO; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DetailedSearchCriteria; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Sample; +import ch.systemsx.cisd.openbis.generic.shared.dto.Session; + +/** + * A class with helper methods for implementing search. This is the shared code for that searches + * originating from CommonServer and ETLService. + * + * @author Chandrasekhar Ramakrishnan + */ +class SearchHelper +{ + private final Session session; + + private final ICommonBusinessObjectFactory businessObjectFactory; + + private final IDAOFactory daoFactory; + + public SearchHelper(Session session, ICommonBusinessObjectFactory businessObjectFactory, + IDAOFactory daoFactory) + { + this.session = session; + this.businessObjectFactory = businessObjectFactory; + this.daoFactory = daoFactory; + } + + public List<Sample> searchForSamples(DetailedSearchCriteria criteria) + { + try + { + final ISampleLister sampleLister = businessObjectFactory.createSampleLister(session); + final IHibernateSearchDAO searchDAO = daoFactory.getHibernateSearchDAO(); + return new SampleSearchManager(searchDAO, sampleLister).searchForSamples(criteria); + } catch (final DataAccessException ex) + { + throw CommonServer.createUserFailureException(ex); + } + } +} diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/SearchCriteriaToDetailedSearchCriteriaTranslator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/SearchCriteriaToDetailedSearchCriteriaTranslator.java index 133742196d06d0e7f310fde93dde65e2203ee3bb..3c043796aeeb946420303c98b51d3b0a13ac2bc9 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/SearchCriteriaToDetailedSearchCriteriaTranslator.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/api/v1/SearchCriteriaToDetailedSearchCriteriaTranslator.java @@ -47,7 +47,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SearchCriteriaConnectio * * @author Chandrasekhar Ramakrishnan */ -class SearchCriteriaToDetailedSearchCriteriaTranslator +public class SearchCriteriaToDetailedSearchCriteriaTranslator { private final static String INVALID_SEARCH_ATTRIBUTE_TEMPLATE = "%s is not a valid search attribute for %s"; @@ -288,7 +288,7 @@ class SearchCriteriaToDetailedSearchCriteriaTranslator ((AttributeMatchClause) matchClause).getAttribute(); IAttributeSearchFieldKind searchFieldKind = attributeTranslator - .convertMatchClauseAttributeToAttributeSearchFieldKind(attribute); + .convertMatchClauseAttributeToAttributeSearchFieldKind(attribute); searchField = DetailedSearchField.createAttributeField(searchFieldKind); break; default: diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IETLLIMSService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IETLLIMSService.java index 07d95e038ab952277e5c5ec7fc496065ed8bd65c..f955a5d60f3ad38506dc0505b87d6c60ad51c6cd 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IETLLIMSService.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IETLLIMSService.java @@ -23,6 +23,7 @@ import java.util.List; import org.springframework.transaction.annotation.Transactional; import ch.systemsx.cisd.common.exceptions.UserFailureException; +import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchCriteria; import ch.systemsx.cisd.openbis.generic.shared.authorization.ISessionProvider; import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.AuthorizationGuard; import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.ReturnValueFilter; @@ -111,7 +112,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider * @param experimentIdentifier an identifier which uniquely identifies the experiment. */ @Transactional(readOnly = true) - @RolesAllowed({RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER}) + @RolesAllowed( + { RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER }) public Experiment tryToGetExperiment( String sessionToken, @AuthorizationGuard(guardClass = ExistingSpaceIdentifierPredicate.class) ExperimentIdentifier experimentIdentifier) @@ -183,7 +185,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider * @return a sorted list of {@link ExternalData}. */ @Transactional(readOnly = true) - @RolesAllowed({RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER}) + @RolesAllowed( + { RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER }) public List<ExternalData> listDataSetsByExperimentID( final String sessionToken, @AuthorizationGuard(guardClass = ExperimentTechIdPredicate.class) final TechId experimentID) @@ -349,7 +352,7 @@ public interface IETLLIMSService extends IServer, ISessionProvider @Transactional(readOnly = true) @RolesAllowed(RoleWithHierarchy.INSTANCE_ADMIN) public void checkInstanceAdminAuthorization(String sessionToken) throws UserFailureException; - + /** * Checks that the user of specified session has SPACE_POWER_USER access rights. */ @@ -428,8 +431,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider */ @Transactional(readOnly = true) @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER) - public List<DataSetShareId> listShareIds(final String sessionToken, - String dataStore) throws UserFailureException; + public List<DataSetShareId> listShareIds(final String sessionToken, String dataStore) + throws UserFailureException; /** * Lists data sets belonging to chosen data store. @@ -438,7 +441,7 @@ public interface IETLLIMSService extends IServer, ISessionProvider @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER) public List<SimpleDataSetInformationDTO> listDataSets(final String sessionToken, String dataStore) throws UserFailureException; - + /** * List data sets deleted after specified date. */ @@ -460,7 +463,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider */ @Transactional(readOnly = true) @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER) - public List<ExternalData> listDataSets(String sessionToken, String dataStoreCode, TrackingDataSetCriteria criteria); + public List<ExternalData> listDataSets(String sessionToken, String dataStoreCode, + TrackingDataSetCriteria criteria); /** * List all experiments for a given project identifier. @@ -480,7 +484,7 @@ public interface IETLLIMSService extends IServer, ISessionProvider { RoleWithHierarchy.SPACE_OBSERVER }) @ReturnValueFilter(validatorClass = ProjectValidator.class) public List<Project> listProjects(String sessionToken); - + /** * Adds specified properties of given data set. Properties defined before will not be updated. */ @@ -677,4 +681,15 @@ public interface IETLLIMSService extends IServer, ISessionProvider public Project tryGetProject( String sessionToken, @AuthorizationGuard(guardClass = ExistingSpaceIdentifierPredicate.class) ProjectIdentifier projectIdentifier); + + /** + * Search for samples matching the provided criteria. + * + * @param sessionToken The user authentication token. Must not be <code>null</code>. + * @param searchCriteria The criteria for samples. + * @return A collection of samples matching the search criteria. + */ + @Transactional(readOnly = true) + @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER) + public List<Sample> searchForSamples(String sessionToken, SearchCriteria searchCriteria); } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/dto/DataSet.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/dto/DataSet.java index 8e0631296b29d41fd910241cb75cc63c5ef55c16..42d4b44ec4ce22bfabc2e5e94d7cbc442a2a1c1b 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/dto/DataSet.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/dto/DataSet.java @@ -281,7 +281,26 @@ public final class DataSet implements Serializable builder.append(getExperimentIdentifier()); builder.append(getSampleIdentifierOrNull()); builder.append(getDataSetTypeCode()); - builder.append(getProperties()); + + // Append properties alphabetically for consistency + HashMap<String, String> props = getProperties(); + ArrayList<String> sortedKeys = new ArrayList<String>(props.size()); + sortedKeys.addAll(props.keySet()); + Collections.sort(sortedKeys); + StringBuilder propString = new StringBuilder(); + propString.append("{"); + for (String key : sortedKeys) + { + propString.append(key); + propString.append("="); + propString.append(props.get(key)); + propString.append(", "); + } + // Get rid of the trailing , + propString.deleteCharAt(propString.length() - 1); + propString.deleteCharAt(propString.length() - 1); + propString.append("}"); + builder.append(propString); if (retrievedConnections.contains(Connections.PARENTS)) { builder.append(getParentCodes()); diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/ETLServiceTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/ETLServiceTest.java index 62e2d313715d917ddaabd33084cca89ede988cf4..3ea32e1518a9226db55cf9883e5ece79e19bf809 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/ETLServiceTest.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/ETLServiceTest.java @@ -39,16 +39,22 @@ import ch.systemsx.cisd.common.exceptions.ConfigurationFailureException; import ch.systemsx.cisd.common.exceptions.UserFailureException; import ch.systemsx.cisd.openbis.generic.server.business.IDataStoreServiceFactory; import ch.systemsx.cisd.openbis.generic.server.business.bo.ICommonBusinessObjectFactory; +import ch.systemsx.cisd.openbis.generic.server.dataaccess.IHibernateSearchDAO; import ch.systemsx.cisd.openbis.generic.shared.AbstractServerTestCase; import ch.systemsx.cisd.openbis.generic.shared.CommonTestUtils; import ch.systemsx.cisd.openbis.generic.shared.IDataStoreService; import ch.systemsx.cisd.openbis.generic.shared.IETLLIMSService; +import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchCriteria; +import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchCriteria.MatchClause; +import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchCriteria.MatchClauseAttribute; import ch.systemsx.cisd.openbis.generic.shared.basic.BasicConstant; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataStoreServiceKind; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataTypeCode; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatastoreServiceDescription; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DetailedSearchCriteria; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Experiment; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ListOrSearchSampleCriteria; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewAttachment; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewExperiment; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.NewProject; @@ -62,6 +68,7 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SourceType; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.builders.DataSetBuilder; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.builders.DataStoreBuilder; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.builders.ExperimentBuilder; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.builders.SampleBuilder; import ch.systemsx.cisd.openbis.generic.shared.dto.AtomicEntityOperationDetails; import ch.systemsx.cisd.openbis.generic.shared.dto.AtomicEntityOperationResult; import ch.systemsx.cisd.openbis.generic.shared.dto.DataPE; @@ -88,6 +95,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.SampleUpdatesDTO; import ch.systemsx.cisd.openbis.generic.shared.dto.SimpleDataSetInformationDTO; import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.DatabaseInstanceIdentifier; import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SampleIdentifier; +import ch.systemsx.cisd.openbis.generic.shared.dto.properties.EntityKind; /** * @author Franz-Josef Elmer @@ -117,6 +125,8 @@ public class ETLServiceTest extends AbstractServerTestCase private IDataStoreService dataStoreService; + private IHibernateSearchDAO hibernateSearchDao; + @Override @BeforeMethod public final void setUp() @@ -125,6 +135,7 @@ public class ETLServiceTest extends AbstractServerTestCase boFactory = context.mock(ICommonBusinessObjectFactory.class); dssfactory = context.mock(IDataStoreServiceFactory.class); dataStoreService = context.mock(IDataStoreService.class); + hibernateSearchDao = context.mock(IHibernateSearchDAO.class); } @Test @@ -1007,6 +1018,48 @@ public class ETLServiceTest extends AbstractServerTestCase context.assertIsSatisfied(); } + @SuppressWarnings("unchecked") + @Test + public void testSearchForSamples() + { + prepareGetSession(); + context.checking(new Expectations() + { + { + one(boFactory).createSampleLister(SESSION); + will(returnValue(sampleLister)); + + one(daoFactory).getHibernateSearchDAO(); + will(returnValue(hibernateSearchDao)); + + one(hibernateSearchDao).searchForEntityIds( + with(aNonNull(DetailedSearchCriteria.class)), + with(equal(EntityKind.SAMPLE)), with(aNonNull(List.class))); + will(returnValue(Arrays.asList(new Long(1), new Long(2)))); + + one(sampleLister).list(with(aNonNull(ListOrSearchSampleCriteria.class))); + SampleBuilder sample1 = new SampleBuilder().id(1); + SampleBuilder sample2 = new SampleBuilder().id(2); + will(returnValue(Arrays.asList(sample1, sample2))); + + } + }); + + List<Sample> sample = + createService().searchForSamples(SESSION_TOKEN, createSearchCriteriaForSample()); + + assertEquals(2, sample.size()); + context.assertIsSatisfied(); + } + + private SearchCriteria createSearchCriteriaForSample() + { + SearchCriteria sc = new SearchCriteria(); + sc.addMatchClause(MatchClause.createAttributeMatch(MatchClauseAttribute.CODE, "a code")); + sc.addMatchClause(MatchClause.createPropertyMatch("MY_PROPERTY2", "a property value")); + return sc; + } + private void prepareRegisterDataSet(final SampleIdentifier sampleIdentifier, final ExperimentPE experiment, final SourceType sourceType, final NewExternalData externalData) diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/IETLLIMSService.java.expected b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/IETLLIMSService.java.expected index 07d95e038ab952277e5c5ec7fc496065ed8bd65c..f955a5d60f3ad38506dc0505b87d6c60ad51c6cd 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/IETLLIMSService.java.expected +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/IETLLIMSService.java.expected @@ -23,6 +23,7 @@ import java.util.List; import org.springframework.transaction.annotation.Transactional; import ch.systemsx.cisd.common.exceptions.UserFailureException; +import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.SearchCriteria; import ch.systemsx.cisd.openbis.generic.shared.authorization.ISessionProvider; import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.AuthorizationGuard; import ch.systemsx.cisd.openbis.generic.shared.authorization.annotation.ReturnValueFilter; @@ -111,7 +112,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider * @param experimentIdentifier an identifier which uniquely identifies the experiment. */ @Transactional(readOnly = true) - @RolesAllowed({RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER}) + @RolesAllowed( + { RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER }) public Experiment tryToGetExperiment( String sessionToken, @AuthorizationGuard(guardClass = ExistingSpaceIdentifierPredicate.class) ExperimentIdentifier experimentIdentifier) @@ -183,7 +185,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider * @return a sorted list of {@link ExternalData}. */ @Transactional(readOnly = true) - @RolesAllowed({RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER}) + @RolesAllowed( + { RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER }) public List<ExternalData> listDataSetsByExperimentID( final String sessionToken, @AuthorizationGuard(guardClass = ExperimentTechIdPredicate.class) final TechId experimentID) @@ -349,7 +352,7 @@ public interface IETLLIMSService extends IServer, ISessionProvider @Transactional(readOnly = true) @RolesAllowed(RoleWithHierarchy.INSTANCE_ADMIN) public void checkInstanceAdminAuthorization(String sessionToken) throws UserFailureException; - + /** * Checks that the user of specified session has SPACE_POWER_USER access rights. */ @@ -428,8 +431,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider */ @Transactional(readOnly = true) @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER) - public List<DataSetShareId> listShareIds(final String sessionToken, - String dataStore) throws UserFailureException; + public List<DataSetShareId> listShareIds(final String sessionToken, String dataStore) + throws UserFailureException; /** * Lists data sets belonging to chosen data store. @@ -438,7 +441,7 @@ public interface IETLLIMSService extends IServer, ISessionProvider @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER) public List<SimpleDataSetInformationDTO> listDataSets(final String sessionToken, String dataStore) throws UserFailureException; - + /** * List data sets deleted after specified date. */ @@ -460,7 +463,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider */ @Transactional(readOnly = true) @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER) - public List<ExternalData> listDataSets(String sessionToken, String dataStoreCode, TrackingDataSetCriteria criteria); + public List<ExternalData> listDataSets(String sessionToken, String dataStoreCode, + TrackingDataSetCriteria criteria); /** * List all experiments for a given project identifier. @@ -480,7 +484,7 @@ public interface IETLLIMSService extends IServer, ISessionProvider { RoleWithHierarchy.SPACE_OBSERVER }) @ReturnValueFilter(validatorClass = ProjectValidator.class) public List<Project> listProjects(String sessionToken); - + /** * Adds specified properties of given data set. Properties defined before will not be updated. */ @@ -677,4 +681,15 @@ public interface IETLLIMSService extends IServer, ISessionProvider public Project tryGetProject( String sessionToken, @AuthorizationGuard(guardClass = ExistingSpaceIdentifierPredicate.class) ProjectIdentifier projectIdentifier); + + /** + * Search for samples matching the provided criteria. + * + * @param sessionToken The user authentication token. Must not be <code>null</code>. + * @param searchCriteria The criteria for samples. + * @return A collection of samples matching the search criteria. + */ + @Transactional(readOnly = true) + @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER) + public List<Sample> searchForSamples(String sessionToken, SearchCriteria searchCriteria); } diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/api/v1/GeneralInformationServiceTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/api/v1/GeneralInformationServiceTest.java index 4d2f07aaf9b1f99566678ac76b3e4a792ebe70b8..50e089de90274b85e6252a507aa7906b5077e43c 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/api/v1/GeneralInformationServiceTest.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/api/v1/GeneralInformationServiceTest.java @@ -470,7 +470,7 @@ public class GeneralInformationServiceTest extends SystemTestCase assertEquals(4, result.size()); assertEquals( "[DataSet[20081105092158673-1,/CISD/NEMO/EXP1,/CISD/3VCP1,HCS_IMAGE,{COMMENT=no comment},[]], " - + "DataSet[20081105092159111-1,/CISD/NEMO/EXP-TEST-1,/CISD/CP-TEST-1,HCS_IMAGE,{ANY_MATERIAL=null, GENDER=null, COMMENT=no comment, BACTERIUM=null},[]], " + + "DataSet[20081105092159111-1,/CISD/NEMO/EXP-TEST-1,/CISD/CP-TEST-1,HCS_IMAGE,{ANY_MATERIAL=null, BACTERIUM=null, COMMENT=no comment, GENDER=null},[]], " + "DataSet[20081105092159222-2,/CISD/NOE/EXP-TEST-2,/CISD/CP-TEST-2,HCS_IMAGE,{COMMENT=no comment},[]], " + "DataSet[20081105092159333-3,/CISD/NEMO/EXP-TEST-2,/CISD/CP-TEST-3,HCS_IMAGE,{COMMENT=no comment},[]]]", result.toString());