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 35cea991e8a0c1cb66d17ca015d58cd8167f393e..048711ff0c150503a780a767d14c6d6dd6590830 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 @@ -277,23 +277,28 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt { private final LastModificationState lastModificationState; + private final IDataStoreServiceRegistrator dataStoreServiceRegistrator; + public CommonServer(final IAuthenticationService authenticationService, final ISessionManager<Session> sessionManager, final IDAOFactory daoFactory, final ICommonBusinessObjectFactory businessObjectFactory, + IDataStoreServiceRegistrator dataStoreServiceRegistrator, final LastModificationState lastModificationState) { this(authenticationService, sessionManager, daoFactory, null, businessObjectFactory, - lastModificationState); + dataStoreServiceRegistrator, lastModificationState); } CommonServer(final IAuthenticationService authenticationService, final ISessionManager<Session> sessionManager, final IDAOFactory daoFactory, IPropertiesBatchManager propertiesBatchManager, final ICommonBusinessObjectFactory businessObjectFactory, + IDataStoreServiceRegistrator dataStoreServiceRegistrator, final LastModificationState lastModificationState) { super(authenticationService, sessionManager, daoFactory, propertiesBatchManager, businessObjectFactory); + this.dataStoreServiceRegistrator = dataStoreServiceRegistrator; this.lastModificationState = lastModificationState; } @@ -1246,6 +1251,7 @@ public final class CommonServer extends AbstractCommonServer<ICommonServerForInt IEntityTypeBO entityTypeBO = businessObjectFactory.createEntityTypeBO(session); entityTypeBO.define(entityType); entityTypeBO.save(); + dataStoreServiceRegistrator.register(entityType); } @Override diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/DataStoreServiceRegistrator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/DataStoreServiceRegistrator.java new file mode 100644 index 0000000000000000000000000000000000000000..3a0bd90e0b3ee0e66a016f2f86e9215a198c2a03 --- /dev/null +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/DataStoreServiceRegistrator.java @@ -0,0 +1,241 @@ +/* + * Copyright 2012 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.openbis.generic.server; + +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.apache.log4j.Logger; + +import ch.systemsx.cisd.common.collections.CollectionUtils; +import ch.systemsx.cisd.common.logging.LogCategory; +import ch.systemsx.cisd.common.logging.LogFactory; +import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory; +import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDataSetTypeDAO; +import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDataStoreDAO; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetType; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataStoreServiceKind; +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatastoreServiceDescription; +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.DataStoreServicePE; +import ch.systemsx.cisd.openbis.generic.shared.dto.DatastoreServiceDescriptions; + +/** + * @author Franz-Josef Elmer + */ +public class DataStoreServiceRegistrator implements IDataStoreServiceRegistrator +{ + private static Logger notificationLog = LogFactory.getLogger(LogCategory.NOTIFY, + DataStoreServiceRegistrator.class); + + private final IDAOFactory daoFactory; + + private final Map<String, Map<DataStoreServiceKind, Map<String, DatastoreServiceDescription>>> dataStoreToServicesMap = + new HashMap<String, Map<DataStoreServiceKind, Map<String, DatastoreServiceDescription>>>(); + + public DataStoreServiceRegistrator(IDAOFactory daoFactory) + { + this.daoFactory = daoFactory; + } + + @Override + public void setServiceDescriptions(DataStorePE dataStore, + DatastoreServiceDescriptions serviceDescriptions) + { + Set<DataStoreServicePE> dataStoreServices = createDataStoreServices(serviceDescriptions); + dataStore.setServices(dataStoreServices); + daoFactory.getDataStoreDAO().createOrUpdateDataStore(dataStore); + Map<DataStoreServiceKind, Map<String, DatastoreServiceDescription>> serviceKindToServicesMap = + new HashMap<DataStoreServiceKind, Map<String, DatastoreServiceDescription>>(); + serviceKindToServicesMap.put(DataStoreServiceKind.QUERIES, + extractMap(serviceDescriptions.getReportingServiceDescriptions())); + serviceKindToServicesMap.put(DataStoreServiceKind.PROCESSING, + extractMap(serviceDescriptions.getProcessingServiceDescriptions())); + dataStoreToServicesMap.put(dataStore.getCode(), serviceKindToServicesMap); + } + + private Map<String, DatastoreServiceDescription> extractMap( + List<DatastoreServiceDescription> descriptions) + { + Map<String, DatastoreServiceDescription> map = + new HashMap<String, DatastoreServiceDescription>(); + for (DatastoreServiceDescription description : descriptions) + { + map.put(description.getKey(), description); + } + return map; + } + + private Set<DataStoreServicePE> createDataStoreServices( + DatastoreServiceDescriptions serviceDescriptions) + { + Set<DataStoreServicePE> services = new HashSet<DataStoreServicePE>(); + + Set<DataStoreServicePE> processing = + createDataStoreServices(serviceDescriptions.getProcessingServiceDescriptions(), + DataStoreServiceKind.PROCESSING); + services.addAll(processing); + + Set<DataStoreServicePE> queries = + createDataStoreServices(serviceDescriptions.getReportingServiceDescriptions(), + DataStoreServiceKind.QUERIES); + services.addAll(queries); + + return services; + } + + private Set<DataStoreServicePE> createDataStoreServices( + List<DatastoreServiceDescription> serviceDescriptions, DataStoreServiceKind serviceKind) + { + Set<DataStoreServicePE> services = new HashSet<DataStoreServicePE>(); + for (DatastoreServiceDescription desc : serviceDescriptions) + { + DataStoreServicePE service = new DataStoreServicePE(); + service.setKey(desc.getKey()); + service.setLabel(desc.getLabel()); + service.setKind(serviceKind); + Set<DataSetTypePE> datasetTypes = extractDatasetTypes(desc.getDatasetTypeCodes(), desc); + service.setDatasetTypes(datasetTypes); + service.setReportingPluginTypeOrNull(desc.tryReportingPluginType()); + services.add(service); + } + return services; + } + + /** + * Find the data set type objects specified by the dataSetTypeCodes. + * + * @return A set of DataSetTypePE objects. + */ + private Set<DataSetTypePE> extractDatasetTypes(String[] dataSetTypeCodes, + DatastoreServiceDescription serviceDescription) + { + Set<DataSetTypePE> dataSetTypes = new HashSet<DataSetTypePE>(); + Set<String> missingCodes = new HashSet<String>(); + IDataSetTypeDAO dataSetTypeDAO = daoFactory.getDataSetTypeDAO(); + List<DataSetTypePE> allDataSetTypes = dataSetTypeDAO.listAllEntities(); + + for (String dataSetTypeCode : dataSetTypeCodes) + { + boolean found = false; + // Try to find the specified data set type + for (DataSetTypePE dataSetType : allDataSetTypes) + { + if (dataSetType.getCode().matches(dataSetTypeCode)) + { + dataSetTypes.add(dataSetType); + found = true; + } + } + if (false == found) + { + missingCodes.add(dataSetTypeCode); + } + } + if (missingCodes.size() > 0) + { + notifyDataStoreServerMisconfiguration(missingCodes, serviceDescription); + } + return dataSetTypes; + } + + private void notifyDataStoreServerMisconfiguration(Set<String> missingCodes, + DatastoreServiceDescription serviceDescription) + { + String missingCodesText = CollectionUtils.abbreviate(missingCodes, -1); + notificationLog.warn(String.format("The Datastore Server Plugin '%s' is misconfigured. " + + "It refers to the dataset types which do not exist in openBIS: %s", + serviceDescription.toString(), missingCodesText)); + } + + @Override + public void register(DataSetType dataSetType) + { + IDataStoreDAO dataStoreDAO = daoFactory.getDataStoreDAO(); + + Set<Entry<String, Map<DataStoreServiceKind, Map<String, DatastoreServiceDescription>>>> entrySet = + dataStoreToServicesMap.entrySet(); + for (Entry<String, Map<DataStoreServiceKind, Map<String, DatastoreServiceDescription>>> entry : entrySet) + { + String dataStoreCode = entry.getKey(); + Map<DataStoreServiceKind, Map<String, DatastoreServiceDescription>> serviceKindToServicesMap = + entry.getValue(); + DataStorePE dataStore = dataStoreDAO.tryToFindDataStoreByCode(dataStoreCode); + Set<DataStoreServicePE> services = dataStore.getServices(); + for (DataStoreServicePE service : services) + { + Set<DataSetTypePE> dataSetTypes = service.getDatasetTypes(); + if (containsDataType(dataSetTypes, dataSetType)) + { + continue; + } + DatastoreServiceDescription description = + serviceKindToServicesMap.get(service.getKind()).get(service.getKey()); + if (description == null) + { + continue; + } + if (matchesPattern(description, dataSetType)) + { + DataSetTypePE newDataSetType = + daoFactory.getDataSetTypeDAO().tryToFindDataSetTypeByCode( + dataSetType.getCode()); + if (newDataSetType != null) + { + Set<DataSetTypePE> extendedDataSetTypes = + new HashSet<DataSetTypePE>(dataSetTypes); + extendedDataSetTypes.add(newDataSetType); + service.setDatasetTypes(extendedDataSetTypes); + } + } + } + dataStoreDAO.createOrUpdateDataStore(dataStore); + } + } + + private boolean matchesPattern(DatastoreServiceDescription description, DataSetType dataSetType) + { + String[] datasetTypeCodePatterns = description.getDatasetTypeCodes(); + for (String pattern : datasetTypeCodePatterns) + { + if (dataSetType.getCode().matches(pattern)) + { + return true; + } + } + return false; + } + + private boolean containsDataType(Collection<DataSetTypePE> dataSetTypes, DataSetType dataSetType) + { + for (DataSetTypePE dataSetTypePE : dataSetTypes) + { + if (dataSetTypePE.getCode().equals(dataSetType.getCode())) + { + return true; + } + } + return false; + } + +} 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 c8cc973ffa1b868150bd993dc1cd5186e16aa461..944baa1c5b5939825801798cacd7df10004f2df8 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 @@ -36,7 +36,6 @@ import ch.systemsx.cisd.authentication.DefaultSessionManager; import ch.systemsx.cisd.authentication.DummyAuthenticationService; import ch.systemsx.cisd.authentication.IAuthenticationService; import ch.systemsx.cisd.authentication.ISessionManager; -import ch.systemsx.cisd.common.collections.CollectionUtils; import ch.systemsx.cisd.common.conversation.IConversationalRmiClient; import ch.systemsx.cisd.common.conversation.IProgressListener; import ch.systemsx.cisd.common.conversation.RmiServiceFactory; @@ -94,9 +93,7 @@ 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; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetTypeWithVocabularyTerms; -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; @@ -143,7 +140,6 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.DataStorePE; import ch.systemsx.cisd.openbis.generic.shared.dto.DataStoreServerInfo; import ch.systemsx.cisd.openbis.generic.shared.dto.DataStoreServicePE; import ch.systemsx.cisd.openbis.generic.shared.dto.DatabaseInstancePE; -import ch.systemsx.cisd.openbis.generic.shared.dto.DatastoreServiceDescriptions; import ch.systemsx.cisd.openbis.generic.shared.dto.EntityCollectionForCreationOrUpdate; import ch.systemsx.cisd.openbis.generic.shared.dto.EntityOperationsLogEntryPE; import ch.systemsx.cisd.openbis.generic.shared.dto.EntityTypePE; @@ -218,14 +214,17 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements private IETLLIMSServiceConversational etlService; + private final IDataStoreServiceRegistrator dataStoreServiceRegistrator; + public ETLService(IAuthenticationService authenticationService, ISessionManager<Session> sessionManager, IDAOFactory daoFactory, ICommonBusinessObjectFactory boFactory, IDataStoreServiceFactory dssFactory, TrustedCrossOriginDomainsProvider trustedOriginDomainProvider, - IETLEntityOperationChecker entityOperationChecker) + IETLEntityOperationChecker entityOperationChecker, + IDataStoreServiceRegistrator dataStoreServiceRegistrator) { this(authenticationService, sessionManager, daoFactory, null, boFactory, dssFactory, - trustedOriginDomainProvider, entityOperationChecker); + trustedOriginDomainProvider, entityOperationChecker, dataStoreServiceRegistrator); } ETLService(IAuthenticationService authenticationService, @@ -233,13 +232,15 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements IPropertiesBatchManager propertiesBatchManager, ICommonBusinessObjectFactory boFactory, IDataStoreServiceFactory dssFactory, TrustedCrossOriginDomainsProvider trustedOriginDomainProvider, - IETLEntityOperationChecker entityOperationChecker) + IETLEntityOperationChecker entityOperationChecker, + IDataStoreServiceRegistrator dataStoreServiceRegistrator) { super(authenticationService, sessionManager, daoFactory, propertiesBatchManager, boFactory); this.daoFactory = daoFactory; this.dssFactory = dssFactory; this.trustedOriginDomainProvider = trustedOriginDomainProvider; this.entityOperationChecker = entityOperationChecker; + this.dataStoreServiceRegistrator = dataStoreServiceRegistrator; sessionManagerForEntityOperation = new DefaultSessionManager<Session>(new SessionFactory(), @@ -332,8 +333,12 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements dataStore.setRemoteUrl(dssURL); dataStore.setSessionToken(dssSessionToken); dataStore.setArchiverConfigured(info.isArchiverConfigured()); - setServices(dataStore, info.getServicesDescriptions(), dataStoreDAO); + dataStore.setServices(new HashSet<DataStoreServicePE>()); // services will be set by the + // dataStoreServiceRegistrator + // setServices(dataStore, info.getServicesDescriptions(), dataStoreDAO); dataStoreDAO.createOrUpdateDataStore(dataStore); + dataStoreServiceRegistrator.setServiceDescriptions(dataStore, + info.getServicesDescriptions()); } private String checkVersion(DataStoreServerInfo info, Session session, String dssSessionToken) @@ -368,105 +373,6 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements } } - private void setServices(DataStorePE dataStore, DatastoreServiceDescriptions serviceDescs, - IDataStoreDAO dataStoreDAO) - { - // Clean services first and save the result. - // In general it should happen automatically, because services are annotated with - // "DELETE_ORPHANS". - // But hibernate does the orphans deletion at the flush time, and insertion of new services - // is performed before. - // So if it happens that services with the same keys are registered, we have a unique - // constraint violation. This is a recognized hibernate bug HHH-2421. - dataStore.setServices(new HashSet<DataStoreServicePE>()); - dataStoreDAO.createOrUpdateDataStore(dataStore); - - Set<DataStoreServicePE> dataStoreServices = createDataStoreServices(serviceDescs); - dataStore.setServices(dataStoreServices); - } - - private Set<DataStoreServicePE> createDataStoreServices( - DatastoreServiceDescriptions serviceDescriptions) - { - Set<DataStoreServicePE> services = new HashSet<DataStoreServicePE>(); - - Set<DataStoreServicePE> processing = - createDataStoreServices(serviceDescriptions.getProcessingServiceDescriptions(), - DataStoreServiceKind.PROCESSING); - services.addAll(processing); - - Set<DataStoreServicePE> queries = - createDataStoreServices(serviceDescriptions.getReportingServiceDescriptions(), - DataStoreServiceKind.QUERIES); - services.addAll(queries); - - return services; - } - - private Set<DataStoreServicePE> createDataStoreServices( - List<DatastoreServiceDescription> serviceDescriptions, DataStoreServiceKind serviceKind) - { - Set<DataStoreServicePE> services = new HashSet<DataStoreServicePE>(); - for (DatastoreServiceDescription desc : serviceDescriptions) - { - DataStoreServicePE service = new DataStoreServicePE(); - service.setKey(desc.getKey()); - service.setLabel(desc.getLabel()); - service.setKind(serviceKind); - Set<DataSetTypePE> datasetTypes = extractDatasetTypes(desc.getDatasetTypeCodes(), desc); - service.setDatasetTypes(datasetTypes); - service.setReportingPluginTypeOrNull(desc.tryReportingPluginType()); - services.add(service); - } - return services; - } - - /** - * Find the data set type objects specified by the dataSetTypeCodes. - * - * @return A set of DataSetTypePE objects. - */ - private Set<DataSetTypePE> extractDatasetTypes(String[] dataSetTypeCodes, - DatastoreServiceDescription serviceDescription) - { - Set<DataSetTypePE> dataSetTypes = new HashSet<DataSetTypePE>(); - Set<String> missingCodes = new HashSet<String>(); - IDataSetTypeDAO dataSetTypeDAO = daoFactory.getDataSetTypeDAO(); - List<DataSetTypePE> allDataSetTypes = dataSetTypeDAO.listAllEntities(); - - for (String dataSetTypeCode : dataSetTypeCodes) - { - boolean found = false; - // Try to find the specified data set type - for (DataSetTypePE dataSetType : allDataSetTypes) - { - if (dataSetType.getCode().matches(dataSetTypeCode)) - { - dataSetTypes.add(dataSetType); - found = true; - } - } - if (false == found) - { - missingCodes.add(dataSetTypeCode); - } - } - if (missingCodes.size() > 0) - { - notifyDataStoreServerMisconfiguration(missingCodes, serviceDescription); - } - return dataSetTypes; - } - - private void notifyDataStoreServerMisconfiguration(Set<String> missingCodes, - DatastoreServiceDescription serviceDescription) - { - String missingCodesText = CollectionUtils.abbreviate(missingCodes, -1); - notificationLog.warn(String.format("The Datastore Server Plugin '%s' is misconfigured. " - + "It refers to the dataset types which do not exist in openBIS: %s", - serviceDescription.toString(), missingCodesText)); - } - @Override public String createPermId(String sessionToken) throws UserFailureException { diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/IDataStoreServiceRegistrator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/IDataStoreServiceRegistrator.java new file mode 100644 index 0000000000000000000000000000000000000000..5067e2f34d333602b6e11cd7dc5460c403695791 --- /dev/null +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/IDataStoreServiceRegistrator.java @@ -0,0 +1,37 @@ +/* + * Copyright 2012 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.openbis.generic.server; + +import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetType; +import ch.systemsx.cisd.openbis.generic.shared.dto.DataStorePE; +import ch.systemsx.cisd.openbis.generic.shared.dto.DatastoreServiceDescriptions; + +/** + * @author Franz-Josef Elmer + */ +public interface IDataStoreServiceRegistrator +{ + public void setServiceDescriptions(DataStorePE dataStore, + DatastoreServiceDescriptions serviceDescriptions); + + /** + * Registers for the specified data set type DSS services where the data set type code matches + * one of the regular expression for which the service is appropriate. + */ + public void register(DataSetType dataSetType); + +} diff --git a/openbis/source/java/genericApplicationContext.xml b/openbis/source/java/genericApplicationContext.xml index cbec61d3330253721f02de438dfabaccd5a7aee2..5bfb0df9c49e92247d150bfe7882eb8f6ea75465 100644 --- a/openbis/source/java/genericApplicationContext.xml +++ b/openbis/source/java/genericApplicationContext.xml @@ -93,6 +93,11 @@ <bean id="last-modification-state" class="ch.systemsx.cisd.openbis.generic.shared.basic.dto.LastModificationState" /> + <bean id="data-store-service-registrator" + class="ch.systemsx.cisd.openbis.generic.server.DataStoreServiceRegistrator"> + <constructor-arg ref="dao-factory" /> + </bean> + <!-- // Common --> @@ -102,6 +107,7 @@ <constructor-arg ref="session-manager" /> <constructor-arg ref="dao-factory" /> <constructor-arg ref="common-business-object-factory" /> + <constructor-arg ref="data-store-service-registrator" /> <constructor-arg ref="last-modification-state" /> <property name="userForAnonymousLogin" value="${user-for-anonymous-login}"/> <property name="CISDHelpdeskEmail" value="cisd.helpdesk@bsse.ethz.ch" /> @@ -158,6 +164,7 @@ <constructor-arg ref="dss-factory" /> <constructor-arg ref="trusted-origin-domain-provider" /> <constructor-arg ref="etl-entity-operation-checker" /> + <constructor-arg ref="data-store-service-registrator" /> <property name = "etlService" ref="etl-service" /> </bean> diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/CommonServerTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/CommonServerTest.java index e06ddf2d1ecfe05d728653b6ab0fff63f228629b..caa1b97a2c5d810a3967badea366ff0de59f175c 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/CommonServerTest.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/CommonServerTest.java @@ -119,12 +119,14 @@ public final class CommonServerTest extends AbstractServerTestCase private IDataSetTypeSlaveServerPlugin dataSetTypeSlaveServerPlugin; + private IDataStoreServiceRegistrator dataStoreServiceRegistrator; + private final ICommonServer createServer() { CommonServer server = new CommonServer(authenticationService, sessionManager, daoFactory, propertiesBatchManager, commonBusinessObjectFactory, - new LastModificationState()); + dataStoreServiceRegistrator, new LastModificationState()); server.setSampleTypeSlaveServerPlugin(sampleTypeSlaveServerPlugin); server.setDataSetTypeSlaveServerPlugin(dataSetTypeSlaveServerPlugin); server.setBaseIndexURL(SESSION_TOKEN, BASE_INDEX_URL); @@ -144,6 +146,7 @@ public final class CommonServerTest extends AbstractServerTestCase commonBusinessObjectFactory = context.mock(ICommonBusinessObjectFactory.class); sampleTypeSlaveServerPlugin = context.mock(ISampleTypeSlaveServerPlugin.class); dataSetTypeSlaveServerPlugin = context.mock(IDataSetTypeSlaveServerPlugin.class); + dataStoreServiceRegistrator = context.mock(IDataStoreServiceRegistrator.class); } @Test @@ -1178,6 +1181,8 @@ public final class CommonServerTest extends AbstractServerTestCase one(entityTypeBO).define(type); one(entityTypeBO).save(); + + one(dataStoreServiceRegistrator).register(type); } }); 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 d395812df69745f362d5143acf87cd2b39f27dd0..9f59d97882fdb9f63dd73c126ec7610e7dfe68ee 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 @@ -30,8 +30,6 @@ import java.util.List; import java.util.Map; import java.util.Set; -import org.hamcrest.BaseMatcher; -import org.hamcrest.Description; import org.jmock.Expectations; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; @@ -39,6 +37,7 @@ import org.testng.annotations.Test; import ch.rinn.restrictions.Friend; import ch.systemsx.cisd.common.exceptions.ConfigurationFailureException; import ch.systemsx.cisd.common.exceptions.UserFailureException; +import ch.systemsx.cisd.common.test.RecordingMatcher; 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.PersistencyResources; @@ -138,6 +137,8 @@ public class ETLServiceTest extends AbstractServerTestCase private IETLEntityOperationChecker entityOperationChecker; + private IDataStoreServiceRegistrator dataStoreServiceRegistrator; + @Override @BeforeMethod public final void setUp() @@ -147,6 +148,7 @@ public class ETLServiceTest extends AbstractServerTestCase dssfactory = context.mock(IDataStoreServiceFactory.class); dataStoreService = context.mock(IDataStoreService.class); entityOperationChecker = context.mock(IETLEntityOperationChecker.class); + dataStoreServiceRegistrator = context.mock(IDataStoreServiceRegistrator.class); MaterialConfigurationProvider.initializeForTesting(false); } @@ -247,10 +249,16 @@ public class ETLServiceTest extends AbstractServerTestCase @Test public void testRegisterDataStoreServer() { + final DataStoreServerInfo info = createDSSInfo(); prepareGetSession(); + final RecordingMatcher<DataStorePE> dataStoreRecordingMatcher = + new RecordingMatcher<DataStorePE>(); context.checking(new Expectations() { { + one(dataStoreServiceRegistrator).setServiceDescriptions( + with(dataStoreRecordingMatcher), with(info.getServicesDescriptions())); + one(dataStoreDAO).tryToFindDataStoreByCode(DSS_CODE); will(returnValue(null)); @@ -260,51 +268,24 @@ public class ETLServiceTest extends AbstractServerTestCase one(dataStoreService).getVersion(DSS_SESSION_TOKEN); will(returnValue(IDataStoreService.VERSION)); - allowing(daoFactory).getPersistencyResources(); - will(returnValue(new PersistencyResources(null, null, null, null))); - - prepareFindDatasetTypes(this); - - allowing(dataStoreDAO).createOrUpdateDataStore( - with(new BaseMatcher<DataStorePE>() - { - @Override - public void describeTo(Description description) - { - } - - @Override - public boolean matches(Object item) - { - if (item instanceof DataStorePE) - { - DataStorePE store = (DataStorePE) item; - return DSS_CODE.equals(store.getCode()) - && URL.equals(store.getRemoteUrl()) - && DOWNLOAD_URL.equals(store.getDownloadUrl()) - && DSS_SESSION_TOKEN.equals(store - .getSessionToken()); - } - return false; - } - - })); + allowing(dataStoreDAO).createOrUpdateDataStore(with(dataStoreRecordingMatcher)); } }); - createService().registerDataStoreServer(SESSION_TOKEN, createDSSInfo()); - + createService().registerDataStoreServer(SESSION_TOKEN, info); + + List<DataStorePE> recordedObjects = dataStoreRecordingMatcher.getRecordedObjects(); + DataStorePE store1 = recordedObjects.get(0); + assertEquals(DSS_CODE, store1.getCode()); + assertEquals(URL, store1.getRemoteUrl()); + assertEquals(DOWNLOAD_URL, store1.getDownloadUrl()); + assertEquals(DSS_SESSION_TOKEN, store1.getSessionToken()); + DataStorePE store2 = recordedObjects.get(1); + assertSame(store1, store2); + assertEquals(2, recordedObjects.size()); context.assertIsSatisfied(); } - private void prepareFindDatasetTypes(Expectations exp) - { - ArrayList<DataSetTypePE> allDataSetTypes = getAllDataSetTypes(); - - exp.allowing(dataSetTypeDAO).listAllEntities(); - exp.will(Expectations.returnValue(allDataSetTypes)); - } - protected ArrayList<DataSetTypePE> getAllDataSetTypes() { // Prepare the collection of data set types @@ -330,103 +311,70 @@ public class ETLServiceTest extends AbstractServerTestCase { final String reportingPluginTypes = ".*"; final String processingPluginTypes = "dataSet.*"; + final DataStoreServerInfo info = + createDSSInfoWithWildcards(reportingPluginTypes, processingPluginTypes); + final RecordingMatcher<DataStorePE> dataStoreRecordingMatcher = + new RecordingMatcher<DataStorePE>(); prepareGetSession(); - prepareGetVersion(); context.checking(new Expectations() { { + one(dataStoreServiceRegistrator).setServiceDescriptions( + with(dataStoreRecordingMatcher), with(info.getServicesDescriptions())); + one(dataStoreDAO).tryToFindDataStoreByCode(DSS_CODE); will(returnValue(new DataStorePE())); - prepareFindDatasetTypes(this); + one(dssfactory).create(URL); + will(returnValue(dataStoreService)); - allowing(daoFactory).getPersistencyResources(); - will(returnValue(new PersistencyResources(null, null, null, null))); + one(dataStoreService).getVersion(DSS_SESSION_TOKEN); + will(returnValue(IDataStoreService.VERSION)); - allowing(dataStoreDAO).createOrUpdateDataStore( - with(new BaseMatcher<DataStorePE>() - { - @Override - public void describeTo(Description description) - { - } - - @Override - public boolean matches(Object item) - { - if (item instanceof DataStorePE) - { - DataStorePE store = (DataStorePE) item; - boolean basicMatch = - DSS_CODE.equals(store.getCode()) - && URL.equals(store.getRemoteUrl()) - && DOWNLOAD_URL.equals(store - .getDownloadUrl()) - && DSS_SESSION_TOKEN.equals(store - .getSessionToken()); - // To workaround a hibernate bug, data stores are once - // registered with no services - if (false == basicMatch - || store.getServices().isEmpty()) - { - return basicMatch; - } - - for (DataStoreServicePE service : store.getServices()) - { - // Check that the types found match those specified - if (service.getKind() == DataStoreServiceKind.PROCESSING) - { - // expect 2 matches - if (false == isDataSetTypeMatch(service, - processingPluginTypes, 2)) - { - return false; - } - } - if (service.getKind() == DataStoreServiceKind.QUERIES) - { - // expect 3 matches - if (false == isDataSetTypeMatch(service, - reportingPluginTypes, 3)) - { - return false; - } - } - } - - return true; - } - return false; - } - - private boolean isDataSetTypeMatch(DataStoreServicePE service, - String typeRegex, int numberExpected) - { - Set<DataSetTypePE> datasetTypes = service.getDatasetTypes(); - if (datasetTypes.isEmpty()) - { - return false; - } - for (DataSetTypePE types : datasetTypes) - { - if (false == types.getCode().matches(typeRegex)) - { - return false; - } - } - return datasetTypes.size() == numberExpected; - } - - })); + allowing(dataStoreDAO).createOrUpdateDataStore(with(dataStoreRecordingMatcher)); } }); - createService().registerDataStoreServer(SESSION_TOKEN, - createDSSInfoWithWildcards(reportingPluginTypes, processingPluginTypes)); + createService().registerDataStoreServer(SESSION_TOKEN, info); + + List<DataStorePE> recordedObjects = dataStoreRecordingMatcher.getRecordedObjects(); + DataStorePE store1 = recordedObjects.get(0); + assertEquals(DSS_CODE, store1.getCode()); + assertEquals(URL, store1.getRemoteUrl()); + assertEquals(DOWNLOAD_URL, store1.getDownloadUrl()); + assertEquals(DSS_SESSION_TOKEN, store1.getSessionToken()); + for (DataStoreServicePE service : store1.getServices()) + { + // Check that the types found match those specified + if (service.getKind() == DataStoreServiceKind.PROCESSING) + { + // expect 2 matches + assertDataSetTypeMatch(service, processingPluginTypes, 2); + } + if (service.getKind() == DataStoreServiceKind.QUERIES) + { + // expect 3 matches + assertDataSetTypeMatch(service, reportingPluginTypes, 3); + } + } + DataStorePE store2 = recordedObjects.get(1); + assertSame(store1, store2); + assertEquals(2, recordedObjects.size()); context.assertIsSatisfied(); } + private void assertDataSetTypeMatch(DataStoreServicePE service, String typeRegex, + int numberExpected) + { + Set<DataSetTypePE> datasetTypes = service.getDatasetTypes(); + for (DataSetTypePE types : datasetTypes) + { + assertEquals("'" + types.getCode() + "' doesnot match '" + typeRegex + "'.", true, + types.getCode().matches(typeRegex)); + } + assertEquals(numberExpected, datasetTypes.size()); + } + @Test public void testRegisterDataStoreServerWithWrongVersion() { @@ -447,11 +395,6 @@ public class ETLServiceTest extends AbstractServerTestCase context.assertIsSatisfied(); } - private void prepareGetVersion() - { - prepareGetVersion(VERSION); - } - private void prepareGetVersion(final int version) { context.checking(new Expectations() @@ -1424,7 +1367,8 @@ public class ETLServiceTest extends AbstractServerTestCase private IETLLIMSService createService() { return new ETLService(authenticationService, sessionManager, daoFactory, - propertiesBatchManager, boFactory, dssfactory, null, entityOperationChecker); + propertiesBatchManager, boFactory, dssfactory, null, entityOperationChecker, + dataStoreServiceRegistrator); } private DataStoreServerInfo createDSSInfo()