From 929dba92cd105bbb4c52cfddb3b9bb444d43ddbd Mon Sep 17 00:00:00 2001 From: anttil <anttil> Date: Fri, 4 May 2012 13:57:46 +0000 Subject: [PATCH] SP-13: Change ch.systemsx.cisd.openbis.dss.generic.server.EncapsulatedOpenBISService.performEntityOperations() to use service conversation framework in AS/DSS communication SVN: 25182 --- common/.classpath | 5 + .../ConversationalClient.java | 25 +++++ .../ConversationalServer.java | 23 ++++ .../serviceconversation/MethodCall.java | 76 +++++++++++++ .../RpcMessageTransport.java | 30 +++++ .../common/serviceconversation/RpcProxy.java | 55 +++++++++ .../RpcServiceFactory.java | 84 ++++++++++++++ .../dss/generic/server/DataStoreService.java | 55 +++++++++ .../server/DataStoreServiceLogger.java | 13 +++ .../server/EncapsulatedOpenBISService.java | 18 ++- .../source/java/dssApplicationContext.xml | 4 + .../TransferredDataSetHandlerTest.java | 5 +- .../EncapsulatedOpenBISServiceTest.java | 10 +- .../openbis/generic/server/ETLService.java | 32 ++++++ .../generic/server/ETLServiceLogger.java | 18 ++- .../generic/shared/IDataStoreService.java | 3 +- .../generic/shared/IETLLIMSService.java | 105 ++++++++++++------ .../generic/server/ETLServiceTest.java | 36 ++++++ .../shared/api/v1/dto/SearchCriteria.java | 8 ++ 19 files changed, 561 insertions(+), 44 deletions(-) create mode 100644 common/source/java/ch/systemsx/cisd/common/serviceconversation/ConversationalClient.java create mode 100644 common/source/java/ch/systemsx/cisd/common/serviceconversation/ConversationalServer.java create mode 100644 common/source/java/ch/systemsx/cisd/common/serviceconversation/MethodCall.java create mode 100644 common/source/java/ch/systemsx/cisd/common/serviceconversation/RpcMessageTransport.java create mode 100644 common/source/java/ch/systemsx/cisd/common/serviceconversation/RpcProxy.java create mode 100644 common/source/java/ch/systemsx/cisd/common/serviceconversation/RpcServiceFactory.java diff --git a/common/.classpath b/common/.classpath index 66fbbdbc5cc..c147fa5b451 100644 --- a/common/.classpath +++ b/common/.classpath @@ -35,5 +35,10 @@ <classpathentry kind="lib" path="/libraries/spring/spring-context.jar"/> <classpathentry kind="lib" path="/libraries/spring/spring-aop.jar" sourcepath="/libraries/spring/src.jar"/> <classpathentry kind="lib" path="/libraries/spring/third-party/aopalliance.jar"/> + <classpathentry kind="lib" path="/libraries/spring/spring-beans.jar"/> + <classpathentry kind="lib" path="/libraries/spring/spring-jdbc.jar"/> + <classpathentry kind="lib" path="/libraries/spring/spring-web.jar"/> + <classpathentry kind="lib" path="/libraries/spring/spring.jar"/> + <classpathentry kind="lib" path="/libraries/hibernate-core/hibernate-core.jar"/> <classpathentry kind="output" path="targets/classes"/> </classpath> diff --git a/common/source/java/ch/systemsx/cisd/common/serviceconversation/ConversationalClient.java b/common/source/java/ch/systemsx/cisd/common/serviceconversation/ConversationalClient.java new file mode 100644 index 00000000000..a5ae65de34e --- /dev/null +++ b/common/source/java/ch/systemsx/cisd/common/serviceconversation/ConversationalClient.java @@ -0,0 +1,25 @@ +/* + * 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.common.serviceconversation; + +public interface ConversationalClient +{ + public void send(ServiceMessage message); + + public <T extends ConversationalServer, U extends T> T getConversationClient(String sessionToken, U service, Class<T> reference); + +} diff --git a/common/source/java/ch/systemsx/cisd/common/serviceconversation/ConversationalServer.java b/common/source/java/ch/systemsx/cisd/common/serviceconversation/ConversationalServer.java new file mode 100644 index 00000000000..83f80c5f914 --- /dev/null +++ b/common/source/java/ch/systemsx/cisd/common/serviceconversation/ConversationalServer.java @@ -0,0 +1,23 @@ +/* + * 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.common.serviceconversation; + +public interface ConversationalServer extends IServiceMessageTransport +{ + public ServiceConversationDTO startConversation(String sessionToken, String clientUrl, String typeId); + +} diff --git a/common/source/java/ch/systemsx/cisd/common/serviceconversation/MethodCall.java b/common/source/java/ch/systemsx/cisd/common/serviceconversation/MethodCall.java new file mode 100644 index 00000000000..c44a6c227b4 --- /dev/null +++ b/common/source/java/ch/systemsx/cisd/common/serviceconversation/MethodCall.java @@ -0,0 +1,76 @@ +/* + * 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.common.serviceconversation; + +import java.io.Serializable; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class MethodCall implements Serializable +{ + private static final long serialVersionUID = 8679256131459236150L; + + private String methodName; + private Object[] arguments; + + public MethodCall(String methodName, Object[] arguments) { + this.methodName = methodName; + this.arguments = arguments; + } + + public Serializable executeOn(Object o) { + + List<Class<?>> argClasses = new ArrayList<Class<?>>(); + for (Object s : this.arguments) { + argClasses.add(s.getClass()); + } + Exception ex; + try + { + Method m = o.getClass().getMethod(this.methodName, argClasses.toArray(new Class<?>[0])); + try + { + return (Serializable)m.invoke(o, this.arguments); + } catch (IllegalArgumentException e) + { + ex = e; + } catch (IllegalAccessException e) + { + ex = e; + } catch (InvocationTargetException e) + { + ex = e; + } + } catch (SecurityException e) + { + ex = e; + } catch (NoSuchMethodException e) + { + ex = e; + } + throw new RuntimeException("Method call failed", ex); + } + + @Override + public String toString() { + return "MethodCall "+this.methodName+"("+Arrays.asList(this.arguments)+")"; + } + +} diff --git a/common/source/java/ch/systemsx/cisd/common/serviceconversation/RpcMessageTransport.java b/common/source/java/ch/systemsx/cisd/common/serviceconversation/RpcMessageTransport.java new file mode 100644 index 00000000000..ea2a19ccd46 --- /dev/null +++ b/common/source/java/ch/systemsx/cisd/common/serviceconversation/RpcMessageTransport.java @@ -0,0 +1,30 @@ +/* + * 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.common.serviceconversation; + +public class RpcMessageTransport implements IServiceMessageTransport +{ + private ConversationalClient client; + public RpcMessageTransport(ConversationalClient client) { + this.client = client; + } + + public void send(ServiceMessage message) + { + this.client.send(message); + } +} diff --git a/common/source/java/ch/systemsx/cisd/common/serviceconversation/RpcProxy.java b/common/source/java/ch/systemsx/cisd/common/serviceconversation/RpcProxy.java new file mode 100644 index 00000000000..8132c41312c --- /dev/null +++ b/common/source/java/ch/systemsx/cisd/common/serviceconversation/RpcProxy.java @@ -0,0 +1,55 @@ +/* + * 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.common.serviceconversation; + +import java.io.Serializable; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.util.Collection; +import java.util.HashSet; + +import ch.systemsx.cisd.common.serviceconversation.client.IServiceConversation; +import ch.systemsx.cisd.common.serviceconversation.client.ServiceConversationClient; + +public class RpcProxy implements InvocationHandler +{ + private ServiceConversationClient client; + private String typeId; + + @SuppressWarnings("unchecked") + public static <T> T newInstance(Class<T> clazz, ServiceConversationClient client) { + + Collection<Class<?>> interfaces = new HashSet<Class<?>>(); + interfaces.add(clazz); + return (T)java.lang.reflect.Proxy.newProxyInstance( + clazz.getClassLoader(), + interfaces.toArray(new Class<?>[0]), + new RpcProxy(client, clazz.getName())); + } + + private RpcProxy(ServiceConversationClient client, String typeId) { + this.client = client; + this.typeId = typeId; + } + + public Object invoke(Object proxy, Method m, Object[] args) throws Throwable + { + IServiceConversation conversation = this.client.startConversation(this.typeId); + conversation.send(new MethodCall(m.getName(), args)); + return conversation.receive(Serializable.class); + } +} diff --git a/common/source/java/ch/systemsx/cisd/common/serviceconversation/RpcServiceFactory.java b/common/source/java/ch/systemsx/cisd/common/serviceconversation/RpcServiceFactory.java new file mode 100644 index 00000000000..30ef7bcda0f --- /dev/null +++ b/common/source/java/ch/systemsx/cisd/common/serviceconversation/RpcServiceFactory.java @@ -0,0 +1,84 @@ +/* + * 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.common.serviceconversation; + +import java.io.Serializable; + +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.Transaction; +import org.springframework.orm.hibernate3.SessionFactoryUtils; +import org.springframework.orm.hibernate3.SessionHolder; +import org.springframework.transaction.support.TransactionSynchronizationManager; + + +import ch.systemsx.cisd.common.serviceconversation.server.IService; +import ch.systemsx.cisd.common.serviceconversation.server.IServiceFactory; + +public final class RpcServiceFactory<T extends ConversationalServer> implements IServiceFactory +{ + + private T service; + private SessionFactory factory; + private Class<?> providedInterface; + private int timeout; + + public RpcServiceFactory(T service, Class<?> providedInterface, int clientTimeoutInMillis, SessionFactory factory) { + this.service = service; + this.providedInterface = providedInterface; + this.timeout = clientTimeoutInMillis; + this.factory = factory; + } + + public final String getServiceTypeId() { + return this.providedInterface.getName(); + } + + public IService create() + { + return new IService() + { + + public void run(IServiceMessenger messenger) + { + + MethodCall call = + (MethodCall) messenger.receive(Serializable.class); + + Session s = SessionFactoryUtils.doGetSession(factory, true); + TransactionSynchronizationManager.bindResource(factory, new SessionHolder(s)); + Transaction tx = s.beginTransaction(); + + Serializable result; + try { + result = call.executeOn(service); + } finally { + tx.commit(); + s.close(); + TransactionSynchronizationManager.unbindResource(factory); + } + messenger.send(result); + } + + }; + } + + public int getClientTimeoutMillis() + { + return this.timeout; + } +} diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/DataStoreService.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/DataStoreService.java index 6e747d7c4a0..56b838e49d4 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/DataStoreService.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/DataStoreService.java @@ -34,6 +34,13 @@ import ch.systemsx.cisd.common.exceptions.ConfigurationFailureException; import ch.systemsx.cisd.common.exceptions.InvalidAuthenticationException; import ch.systemsx.cisd.common.exceptions.InvalidSessionException; import ch.systemsx.cisd.common.mail.MailClientParameters; +import ch.systemsx.cisd.common.serviceconversation.ConversationalServer; +import ch.systemsx.cisd.common.serviceconversation.IServiceMessageTransport; +import ch.systemsx.cisd.common.serviceconversation.RpcProxy; +import ch.systemsx.cisd.common.serviceconversation.ServiceConversationDTO; +import ch.systemsx.cisd.common.serviceconversation.ServiceMessage; +import ch.systemsx.cisd.common.serviceconversation.client.IRemoteServiceConversationServer; +import ch.systemsx.cisd.common.serviceconversation.client.ServiceConversationClient; import ch.systemsx.cisd.common.spring.AbstractServiceWithLogger; import ch.systemsx.cisd.common.spring.IInvocationLoggerContext; import ch.systemsx.cisd.openbis.dss.generic.server.plugins.tasks.ArchiverPluginFactory; @@ -93,6 +100,8 @@ public class DataStoreService extends AbstractServiceWithLogger<IDataStoreServic private File commandQueueDirOrNull; private IDataSetCommandExecutor commandExecutor; + + private String ownUrl; public DataStoreService(SessionTokenManager sessionTokenManager, MailClientParameters mailClientParameters, PluginTaskProviders pluginTaskParameters) @@ -117,6 +126,47 @@ public class DataStoreService extends AbstractServiceWithLogger<IDataStoreServic storeRoot = pluginTaskParameters.getStoreRoot(); } + public static class RpcServerStub implements IRemoteServiceConversationServer, IServiceMessageTransport { + + private ConversationalServer server; + private String callbackUrl; + private String sessionToken; + + public RpcServerStub(String sessionToken, ConversationalServer server, String callbackUrl) { + this.sessionToken = sessionToken; + this.server = server; + this.callbackUrl = callbackUrl; + } + + public ServiceConversationDTO startConversation(String typeId) + { + return this.server.startConversation(sessionToken, callbackUrl, typeId); + } + + public void send(ServiceMessage message) + { + this.server.send(message); + } + } + + + private ServiceConversationClient client; + + public synchronized <T extends ConversationalServer, U extends T> T getConversationClient(String sessionToken, U service, Class<T> reference) { + + RpcServerStub server = new RpcServerStub(sessionToken, service, this.ownUrl); + if (this.client == null) { + client = new ServiceConversationClient(server, server); + } + return RpcProxy.newInstance(reference, client); + } + + public void send(ServiceMessage message) + { + client.getIncomingResponseMessageTransport().send(message); + } + + void setShareIdManager(IShareIdManager shareIdManager) { this.shareIdManager = shareIdManager; @@ -466,4 +516,9 @@ public class DataStoreService extends AbstractServiceWithLogger<IDataStoreServic } return hierarchicalContentProvider; } + + public void setOwnUrl(String ownUrl) { + this.ownUrl = ownUrl; + } + } diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/DataStoreServiceLogger.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/DataStoreServiceLogger.java index 52b65ac64ad..642d7e049eb 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/DataStoreServiceLogger.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/DataStoreServiceLogger.java @@ -22,6 +22,8 @@ import java.util.Map; import org.apache.log4j.Logger; import ch.systemsx.cisd.common.exceptions.InvalidAuthenticationException; +import ch.systemsx.cisd.common.serviceconversation.ConversationalServer; +import ch.systemsx.cisd.common.serviceconversation.ServiceMessage; import ch.systemsx.cisd.common.spring.IInvocationLoggerContext; import ch.systemsx.cisd.common.utilities.IInitializable; import ch.systemsx.cisd.openbis.generic.shared.IDataStoreService; @@ -84,6 +86,11 @@ class DataStoreServiceLogger implements IDataStoreService, IInitializable log("getVersion", "SESSION(%s)", sessionToken); return 0; } + + public void send(ServiceMessage message) + { + log("send", "", message); + } public List<String> getKnownDataSets(String sessionToken, List<? extends IDatasetLocation> dataSetLocations) @@ -158,4 +165,10 @@ class DataStoreServiceLogger implements IDataStoreService, IInitializable return null; } + public <T extends ConversationalServer, U extends T> T getConversationClient( + String sessionToken, U service, Class<T> reference) + { + log("getConversationClient", "REFERENCE(%s)", reference); + return null; + } } diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/EncapsulatedOpenBISService.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/EncapsulatedOpenBISService.java index 057ccc1531c..360e24b5467 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/EncapsulatedOpenBISService.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/EncapsulatedOpenBISService.java @@ -28,11 +28,13 @@ import ch.systemsx.cisd.common.api.client.ServiceFinder; import ch.systemsx.cisd.common.exceptions.UserFailureException; import ch.systemsx.cisd.common.logging.LogCategory; import ch.systemsx.cisd.common.logging.LogFactory; + import ch.systemsx.cisd.openbis.dss.generic.server.openbisauth.OpenBISSessionHolder; import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService; import ch.systemsx.cisd.openbis.dss.generic.shared.IShareIdManager; import ch.systemsx.cisd.openbis.dss.generic.shared.ServiceProvider; import ch.systemsx.cisd.openbis.dss.generic.shared.dto.DataSetInformation; +import ch.systemsx.cisd.openbis.generic.shared.IDataStoreService; import ch.systemsx.cisd.openbis.generic.shared.IETLLIMSService; import ch.systemsx.cisd.openbis.generic.shared.ResourceNames; import ch.systemsx.cisd.openbis.generic.shared.api.v1.IGeneralInformationService; @@ -98,6 +100,8 @@ public final class EncapsulatedOpenBISService implements IEncapsulatedOpenBISSer private OpenBISSessionHolder session; private IShareIdManager shareIdManager; + + private IDataStoreService dataStoreService; public static IETLLIMSService createOpenBisService(String openBISURL, String timeout) { @@ -131,19 +135,20 @@ public final class EncapsulatedOpenBISService implements IEncapsulatedOpenBISSer return Integer.parseInt(timeout) * DateUtils.MILLIS_PER_MINUTE; } - public EncapsulatedOpenBISService(IETLLIMSService service, OpenBISSessionHolder sessionHolder) + public EncapsulatedOpenBISService(IETLLIMSService service, OpenBISSessionHolder sessionHolder, IDataStoreService dataStoreService) { - this(service, sessionHolder, null); + this(service, sessionHolder, dataStoreService, null); } public EncapsulatedOpenBISService(IETLLIMSService service, OpenBISSessionHolder sessionHolder, - IShareIdManager shareIdManager) + IDataStoreService dataStoreService, IShareIdManager shareIdManager) { this.shareIdManager = shareIdManager; assert service != null : "Given IETLLIMSService implementation can not be null."; assert sessionHolder != null : "Given OpenBISSessionHolder can not be null."; this.service = service; this.session = sessionHolder; + this.dataStoreService = dataStoreService; } private IShareIdManager getShareIdManager() @@ -546,12 +551,15 @@ public final class EncapsulatedOpenBISService implements IEncapsulatedOpenBISSer setShareId(externalData); return sample; } - + public AtomicEntityOperationResult performEntityOperations( AtomicEntityOperationDetails operationDetails) { + + IETLLIMSService conversationalService = dataStoreService.getConversationClient(session.getToken(), service, IETLLIMSService.class); + AtomicEntityOperationResult operations = - service.performEntityOperations(session.getToken(), operationDetails); + conversationalService.performEntityOperations(session.getToken(), operationDetails); List<? extends NewExternalData> dataSets = operationDetails.getDataSetRegistrations(); for (NewExternalData dataSet : dataSets) { diff --git a/datastore_server/source/java/dssApplicationContext.xml b/datastore_server/source/java/dssApplicationContext.xml index 8e936f5a5dc..f19a78f04bc 100644 --- a/datastore_server/source/java/dssApplicationContext.xml +++ b/datastore_server/source/java/dssApplicationContext.xml @@ -67,6 +67,7 @@ <bean id="openBIS-service" class="ch.systemsx.cisd.openbis.dss.generic.server.EncapsulatedOpenBISService"> <constructor-arg ref="etl-lims-service"/> <constructor-arg ref="sessionHolder"/> + <constructor-arg ref="data-store-service"/> </bean> <bean id="query-service" class="ch.systemsx.cisd.etlserver.registrator.api.v1.impl.DataSourceQueryService"/> @@ -91,9 +92,12 @@ </bean> </constructor-arg> <constructor-arg ref="plugin-tasks" /> + <property name="cifexAdminUserOrNull" value="${cifex-admin-username}" /> <property name="cifexAdminPasswordOrNull" value="${cifex-admin-password}" /> <property name="commandQueueDir" value="${commandqueue-dir}"/> + <property name="ownUrl" value="${download-url}"/> + </bean> <bean id="data-store-server" diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/TransferredDataSetHandlerTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/TransferredDataSetHandlerTest.java index f607f96ca81..747fb938a3e 100644 --- a/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/TransferredDataSetHandlerTest.java +++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/etlserver/TransferredDataSetHandlerTest.java @@ -61,6 +61,7 @@ import ch.systemsx.cisd.openbis.dss.generic.shared.IEncapsulatedOpenBISService; import ch.systemsx.cisd.openbis.dss.generic.shared.IShareIdManager; import ch.systemsx.cisd.openbis.dss.generic.shared.dto.DataSetInformation; import ch.systemsx.cisd.openbis.dss.generic.shared.utils.DssPropertyParametersUtil; +import ch.systemsx.cisd.openbis.generic.shared.IDataStoreService; import ch.systemsx.cisd.openbis.generic.shared.IETLLIMSService; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DataSetType; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseInstance; @@ -271,10 +272,12 @@ public final class TransferredDataSetHandlerTest extends AbstractFileSystemTestC new ETLServerPlugin(new MockDataSetInfoExtractor(dataSetInfoExtractor), typeExtractor, storageProcessor); + IDataStoreService dataStoreService = context.mock(IDataStoreService.class); + OpenBISSessionHolder sessionHolder = new OpenBISSessionHolder(); sessionHolder.setToken(SESSION_TOKEN); authorizedLimsService = - new EncapsulatedOpenBISService(limsService, sessionHolder, shareIdManager); + new EncapsulatedOpenBISService(limsService, sessionHolder, dataStoreService, shareIdManager); dataSetValidator = context.mock(IDataSetValidator.class); Properties threadProperties = new Properties(); diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/EncapsulatedOpenBISServiceTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/EncapsulatedOpenBISServiceTest.java index e6dd35f7bcb..62e17512692 100644 --- a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/EncapsulatedOpenBISServiceTest.java +++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/server/EncapsulatedOpenBISServiceTest.java @@ -27,9 +27,11 @@ import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; +import ch.systemsx.cisd.common.serviceconversation.ConversationalServer; import ch.systemsx.cisd.openbis.dss.generic.server.openbisauth.OpenBISSessionHolder; import ch.systemsx.cisd.openbis.dss.generic.shared.IShareIdManager; import ch.systemsx.cisd.openbis.dss.generic.shared.dto.DataSetInformation; +import ch.systemsx.cisd.openbis.generic.shared.IDataStoreService; import ch.systemsx.cisd.openbis.generic.shared.IETLLIMSService; import ch.systemsx.cisd.openbis.generic.shared.basic.TechId; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty; @@ -63,6 +65,8 @@ public class EncapsulatedOpenBISServiceTest private OpenBISSessionHolder session; private IShareIdManager shareIdManager; + + private IDataStoreService dataStoreService; @BeforeMethod public void setUp() @@ -70,9 +74,10 @@ public class EncapsulatedOpenBISServiceTest context = new Mockery(); limsService = context.mock(IETLLIMSService.class); shareIdManager = context.mock(IShareIdManager.class); + dataStoreService = context.mock(IDataStoreService.class); session = new OpenBISSessionHolder(); session.setToken(SESSION_TOKEN); - encapsulatedLimsService = new EncapsulatedOpenBISService(limsService, session, shareIdManager); + encapsulatedLimsService = new EncapsulatedOpenBISService(limsService, session, dataStoreService, shareIdManager); } @AfterMethod @@ -171,6 +176,9 @@ public class EncapsulatedOpenBISServiceTest { one(limsService).performEntityOperations(SESSION_TOKEN, operationDetails); one(shareIdManager).setShareId("ds1", "42"); + + allowing(dataStoreService).getConversationClient(with(any(String.class)),with(any(ConversationalServer.class)),with(any(Class.class))); + will(returnValue(limsService)); } }); encapsulatedLimsService.performEntityOperations(operationDetails); 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 29aa3f5dfdd..ae1447d2292 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 @@ -34,6 +34,11 @@ import ch.systemsx.cisd.authentication.ISessionManager; 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.serviceconversation.RpcMessageTransport; +import ch.systemsx.cisd.common.serviceconversation.RpcServiceFactory; +import ch.systemsx.cisd.common.serviceconversation.ServiceConversationDTO; +import ch.systemsx.cisd.common.serviceconversation.ServiceMessage; +import ch.systemsx.cisd.common.serviceconversation.server.ServiceConversationServer; 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; @@ -176,6 +181,8 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements private final TrustedCrossOriginDomainsProvider trustedOriginDomainProvider; + private final ServiceConversationServer server; + public ETLService(IAuthenticationService authenticationService, ISessionManager<Session> sessionManager, IDAOFactory daoFactory, ICommonBusinessObjectFactory boFactory, IDataStoreServiceFactory dssFactory, @@ -195,6 +202,13 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements this.daoFactory = daoFactory; this.dssFactory = dssFactory; this.trustedOriginDomainProvider = trustedOriginDomainProvider; + + org.hibernate.SessionFactory sessionFactory = + daoFactory.getPersistencyResources().getSessionFactoryOrNull(); + + server = new ServiceConversationServer(); + server.addServiceType(new RpcServiceFactory<IETLLIMSService>(this, IETLLIMSService.class, + 3600000, sessionFactory)); } public IETLLIMSService createLogger(IInvocationLoggerContext context) @@ -208,6 +222,22 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements return IServer.VERSION; } + public ServiceConversationDTO startConversation(String sessionToken, String clientUrl, + String typeId) + { + getSession(sessionToken); + + final IDataStoreService service = dssFactory.create(clientUrl); + String clientId = sessionToken; + server.addClientResponseTransport(clientId, new RpcMessageTransport(service)); + return server.startConversation(typeId, clientId); + } + + public void send(ServiceMessage message) + { + server.getIncomingMessageTransport().send(message); + } + public DatabaseInstance getHomeDatabaseInstance(String sessionToken) { return DatabaseInstanceTranslator.translate(getHomeDatabaseInstance()); @@ -1215,6 +1245,7 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements public AtomicEntityOperationResult performEntityOperations(String sessionToken, AtomicEntityOperationDetails operationDetails) { + final Session session = getSession(sessionToken); List<Space> spacesCreated = createSpaces(session, operationDetails); @@ -1643,4 +1674,5 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements } return result; } + } 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 fef6c5b6e7f..25d9d77f383 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 @@ -25,6 +25,8 @@ import org.apache.log4j.Level; import ch.systemsx.cisd.authentication.ISessionManager; import ch.systemsx.cisd.common.collections.CollectionUtils; import ch.systemsx.cisd.common.exceptions.UserFailureException; +import ch.systemsx.cisd.common.serviceconversation.ServiceConversationDTO; +import ch.systemsx.cisd.common.serviceconversation.ServiceMessage; import ch.systemsx.cisd.common.spring.IInvocationLoggerContext; import ch.systemsx.cisd.openbis.generic.shared.AbstractServerLogger; import ch.systemsx.cisd.openbis.generic.shared.IETLLIMSService; @@ -86,6 +88,18 @@ public class ETLServiceLogger extends AbstractServerLogger implements IETLLIMSSe super(sessionManager, context); } + public ServiceConversationDTO startConversation(String sessionToken, String clientUrl, + String typeId) + { + logTracking(typeId, "startConversation", ""); + return null; + } + + public void send(ServiceMessage message) + { + logTracking(message.toString(), "send", ""); + } + public String createDataSetCode(String sessionToken) throws UserFailureException { logTracking(sessionToken, "createDataSetCode", ""); @@ -562,7 +576,9 @@ public class ETLServiceLogger extends AbstractServerLogger implements IETLLIMSSe public List<ExternalData> listDataSetsForPostRegistration(String sessionToken, String dataStoreCode) { - logAccess(Level.DEBUG, sessionToken, "listDataSetsForPostRegistration", "DATA_STORE(%s)", dataStoreCode); + logAccess(Level.DEBUG, sessionToken, "listDataSetsForPostRegistration", "DATA_STORE(%s)", + dataStoreCode); return null; } + } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IDataStoreService.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IDataStoreService.java index ca4de7bfa9f..46c04b2b77a 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IDataStoreService.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/IDataStoreService.java @@ -20,6 +20,7 @@ import java.util.List; import java.util.Map; import ch.systemsx.cisd.common.exceptions.InvalidAuthenticationException; +import ch.systemsx.cisd.common.serviceconversation.ConversationalClient; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.ExternalData; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IDatasetLocation; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.LinkModel; @@ -32,7 +33,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.DatasetDescription; * * @author Franz-Josef Elmer */ -public interface IDataStoreService +public interface IDataStoreService extends ConversationalClient { /** 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 0266a1b05b0..4a0afad5945 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.common.serviceconversation.ConversationalServer; 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; @@ -95,7 +96,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.identifier.SpaceIdentifier; * * @author Christian Ribeaud */ -public interface IETLLIMSService extends IServer, ISessionProvider +public interface IETLLIMSService extends IServer, ISessionProvider, ConversationalServer { /** * Returns the home database instance. @@ -122,7 +123,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider { RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER }) public Experiment tryToGetExperiment( String sessionToken, - @AuthorizationGuard(guardClass = ExistingSpaceIdentifierPredicate.class) ExperimentIdentifier experimentIdentifier) + @AuthorizationGuard(guardClass = ExistingSpaceIdentifierPredicate.class) + ExperimentIdentifier experimentIdentifier) throws UserFailureException; /** @@ -164,7 +166,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER) public Sample tryGetSampleWithExperiment( final String sessionToken, - @AuthorizationGuard(guardClass = ExistingSampleOwnerIdentifierPredicate.class) final SampleIdentifier sampleIdentifier) + @AuthorizationGuard(guardClass = ExistingSampleOwnerIdentifierPredicate.class) + final SampleIdentifier sampleIdentifier) throws UserFailureException; /** @@ -202,7 +205,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider { RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER }) public List<ExternalData> listDataSetsByExperimentID( final String sessionToken, - @AuthorizationGuard(guardClass = ExperimentTechIdPredicate.class) final TechId experimentID) + @AuthorizationGuard(guardClass = ExperimentTechIdPredicate.class) + final TechId experimentID) throws UserFailureException; /** @@ -214,7 +218,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider @RolesAllowed( { RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER }) public List<ExternalData> listDataSetsBySampleID(final String sessionToken, - @AuthorizationGuard(guardClass = SampleTechIdPredicate.class) final TechId sampleId, + @AuthorizationGuard(guardClass = SampleTechIdPredicate.class) + final TechId sampleId, final boolean showOnlyDirectlyConnected) throws UserFailureException; /** @@ -227,7 +232,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider { RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER }) public List<ExternalData> listDataSetsByCode( String sessionToken, - @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class) List<String> dataSetCodes) + @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class) + List<String> dataSetCodes) throws UserFailureException; /** @@ -241,7 +247,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider @ReturnValueFilter(validatorClass = SampleValidator.class) public List<Sample> listSamples( final String sessionToken, - @AuthorizationGuard(guardClass = ListSampleCriteriaPredicate.class) final ListSampleCriteria criteria); + @AuthorizationGuard(guardClass = ListSampleCriteriaPredicate.class) + final ListSampleCriteria criteria); /** * Tries to return the properties of the top sample (e.g. master plate) registered for the @@ -257,7 +264,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider { RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER }) public IEntityProperty[] tryToGetPropertiesOfTopSampleRegisteredFor( final String sessionToken, - @AuthorizationGuard(guardClass = SampleOwnerIdentifierPredicate.class) final SampleIdentifier sampleIdentifier) + @AuthorizationGuard(guardClass = SampleOwnerIdentifierPredicate.class) + final SampleIdentifier sampleIdentifier) throws UserFailureException; /** @@ -277,7 +285,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER) @DatabaseCreateOrDeleteModification(value = ObjectKind.EXPERIMENT) public long registerExperiment(String sessionToken, - @AuthorizationGuard(guardClass = NewExperimentPredicate.class) NewExperiment experiment) + @AuthorizationGuard(guardClass = NewExperimentPredicate.class) + NewExperiment experiment) throws UserFailureException; /** @@ -288,7 +297,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider @DatabaseUpdateModification(value = ObjectKind.SAMPLE) public void registerSamples( final String sessionToken, - @AuthorizationGuard(guardClass = NewSamplesWithTypePredicate.class) final List<NewSamplesWithTypes> newSamplesWithType, + @AuthorizationGuard(guardClass = NewSamplesWithTypePredicate.class) + final List<NewSamplesWithTypes> newSamplesWithType, String userIdOrNull) throws UserFailureException; /** @@ -298,7 +308,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER) @DatabaseCreateOrDeleteModification(value = ObjectKind.SAMPLE) public long registerSample(final String sessionToken, - @AuthorizationGuard(guardClass = NewSamplePredicate.class) final NewSample newSample, + @AuthorizationGuard(guardClass = NewSamplePredicate.class) + final NewSample newSample, String userIDOrNull) throws UserFailureException; /** @@ -308,7 +319,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER) @DatabaseUpdateModification(value = ObjectKind.SAMPLE) public void updateSample(String sessionToken, - @AuthorizationGuard(guardClass = SampleUpdatesPredicate.class) SampleUpdatesDTO updates); + @AuthorizationGuard(guardClass = SampleUpdatesPredicate.class) + SampleUpdatesDTO updates); /** * Registers the specified data connected to a sample. @@ -326,7 +338,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider @DatabaseCreateOrDeleteModification(value = ObjectKind.DATA_SET) public void registerDataSet( final String sessionToken, - @AuthorizationGuard(guardClass = SampleOwnerIdentifierPredicate.class) final SampleIdentifier sampleIdentifier, + @AuthorizationGuard(guardClass = SampleOwnerIdentifierPredicate.class) + final SampleIdentifier sampleIdentifier, final NewExternalData externalData) throws UserFailureException; /** @@ -345,7 +358,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider @DatabaseCreateOrDeleteModification(value = ObjectKind.DATA_SET) public void registerDataSet( final String sessionToken, - @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class) final ExperimentIdentifier experimentIdentifier, + @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class) + final ExperimentIdentifier experimentIdentifier, final NewExternalData externalData) throws UserFailureException; /** @@ -369,7 +383,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider @Transactional(readOnly = true) @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER) public void checkDataSetAccess(String sessionToken, - @AuthorizationGuard(guardClass = DataSetCodePredicate.class) String dataSetCode) + @AuthorizationGuard(guardClass = DataSetCodePredicate.class) + String dataSetCode) throws UserFailureException; /** @@ -382,7 +397,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider @RolesAllowed(RoleWithHierarchy.SPACE_OBSERVER) public void checkDataSetCollectionAccess( String sessionToken, - @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class) List<String> dataSetCodes); + @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class) + List<String> dataSetCodes); /** * Tries to return the data set specified by its code. @@ -391,7 +407,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider @RolesAllowed(value = { RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER }) public ExternalData tryGetDataSet(String sessionToken, - @AuthorizationGuard(guardClass = DataSetCodePredicate.class) String dataSetCode) + @AuthorizationGuard(guardClass = DataSetCodePredicate.class) + String dataSetCode) throws UserFailureException; /** @@ -426,7 +443,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider { RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER }) public List<Sample> listSamplesByCriteria( final String sessionToken, - @AuthorizationGuard(guardClass = ListSamplesByPropertyPredicate.class) final ListSamplesByPropertyCriteria criteria) + @AuthorizationGuard(guardClass = ListSamplesByPropertyPredicate.class) + final ListSamplesByPropertyCriteria criteria) throws UserFailureException; /** @@ -477,7 +495,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider { RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER }) public List<Experiment> listExperiments( String sessionToken, - @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class) ProjectIdentifier projectIdentifier); + @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class) + ProjectIdentifier projectIdentifier); /** * List experiments for a given list of experiment identifiers. @@ -487,7 +506,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider { RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER }) public List<Experiment> listExperiments( String sessionToken, - @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class) List<ExperimentIdentifier> experimentIdentifiers, + @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class) + List<ExperimentIdentifier> experimentIdentifiers, ExperimentFetchOptions experimentFetchOptions); /** @@ -498,7 +518,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider { RoleWithHierarchy.SPACE_OBSERVER, RoleWithHierarchy.SPACE_ETL_SERVER }) public List<Experiment> listExperimentsForProjects( String sessionToken, - @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class) List<ProjectIdentifier> projectIdentifiers, + @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class) + List<ProjectIdentifier> projectIdentifiers, ExperimentFetchOptions experimentFetchOptions); /** @@ -531,7 +552,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider String sessionToken, List<NewProperty> properties, String dataSetCode, - @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class) final SpaceIdentifier identifier) + @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class) + final SpaceIdentifier identifier) throws UserFailureException; /** @@ -541,7 +563,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER) @DatabaseUpdateModification(value = ObjectKind.DATA_SET) public void updateShareIdAndSize(String sessionToken, - @AuthorizationGuard(guardClass = DataSetCodePredicate.class) String dataSetCode, + @AuthorizationGuard(guardClass = DataSetCodePredicate.class) + String dataSetCode, String shareId, long size) throws UserFailureException; /** @@ -552,7 +575,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider @DatabaseUpdateModification(value = ObjectKind.DATA_SET) public void updateDataSetStatuses( String sessionToken, - @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class) List<String> dataSetCodes, + @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class) + List<String> dataSetCodes, final DataSetArchivingStatus newStatus, boolean presentInArchive) throws UserFailureException; @@ -582,7 +606,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider @DatabaseUpdateModification(value = ObjectKind.DATA_SET) public int archiveDatasets( String sessionToken, - @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class) List<String> datasetCodes, + @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class) + List<String> datasetCodes, boolean removeFromDataStore); /** @@ -595,7 +620,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider @DatabaseUpdateModification(value = ObjectKind.DATA_SET) public int unarchiveDatasets( String sessionToken, - @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class) List<String> datasetCodes); + @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class) + List<String> datasetCodes); /** * Check if the user has USER access on the space @@ -606,7 +632,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider @Transactional(readOnly = true) @RolesAllowed(RoleWithHierarchy.SPACE_USER) public void checkSpaceAccess(String sessionToken, - @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class) SpaceIdentifier spaceId); + @AuthorizationGuard(guardClass = SpaceIdentifierPredicate.class) + SpaceIdentifier spaceId); /** * For the ETL Server to get data sets. @@ -614,7 +641,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider @Transactional(readOnly = true) @RolesAllowed(RoleWithHierarchy.SPACE_ETL_SERVER) public ExternalData tryGetDataSetForServer(String sessionToken, - @AuthorizationGuard(guardClass = DataSetCodePredicate.class) String dataSetCode) + @AuthorizationGuard(guardClass = DataSetCodePredicate.class) + String dataSetCode) throws UserFailureException; /** @@ -656,7 +684,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider @DatabaseCreateOrDeleteModification(value = { ObjectKind.SAMPLE, ObjectKind.DATA_SET }) public Sample registerSampleAndDataSet(final String sessionToken, - @AuthorizationGuard(guardClass = NewSamplePredicate.class) final NewSample newSample, + @AuthorizationGuard(guardClass = NewSamplePredicate.class) + final NewSample newSample, final NewExternalData externalData, String userIdOrNull) throws UserFailureException; /** @@ -676,7 +705,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider @DatabaseCreateOrDeleteModification(value = ObjectKind.DATA_SET) public Sample updateSampleAndRegisterDataSet( String sessionToken, - @AuthorizationGuard(guardClass = SampleUpdatesPredicate.class) SampleUpdatesDTO updates, + @AuthorizationGuard(guardClass = SampleUpdatesPredicate.class) + SampleUpdatesDTO updates, NewExternalData externalData); /** @@ -696,7 +726,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider ObjectKind.DATA_SET }) public AtomicEntityOperationResult performEntityOperations( String sessionToken, - @AuthorizationGuard(guardClass = AtomicOperationsPredicate.class) AtomicEntityOperationDetails operationDetails); + @AuthorizationGuard(guardClass = AtomicOperationsPredicate.class) + AtomicEntityOperationDetails operationDetails); /** * Tries to return the space specified by its identifier. @@ -706,7 +737,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider { RoleWithHierarchy.SPACE_ETL_SERVER }) public Space tryGetSpace( String sessionToken, - @AuthorizationGuard(guardClass = ExistingSpaceIdentifierPredicate.class) SpaceIdentifier spaceIdentifier); + @AuthorizationGuard(guardClass = ExistingSpaceIdentifierPredicate.class) + SpaceIdentifier spaceIdentifier); /** * Tries to return the project specified by its identifier. @@ -716,7 +748,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider { RoleWithHierarchy.SPACE_ETL_SERVER }) public Project tryGetProject( String sessionToken, - @AuthorizationGuard(guardClass = ExistingSpaceIdentifierPredicate.class) ProjectIdentifier projectIdentifier); + @AuthorizationGuard(guardClass = ExistingSpaceIdentifierPredicate.class) + ProjectIdentifier projectIdentifier); /** * Search for samples matching the provided criteria. @@ -751,7 +784,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider { ObjectKind.DATA_SET }) public void removeDataSetsPermanently( String sessionToken, - @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class) List<String> dataSetCodes, + @AuthorizationGuard(guardClass = DataSetCodeCollectionPredicate.class) + List<String> dataSetCodes, String reason); /** @@ -763,7 +797,8 @@ public interface IETLLIMSService extends IServer, ISessionProvider { ObjectKind.EXPERIMENT, ObjectKind.SAMPLE, ObjectKind.DATA_SET }) public void updateDataSet( String sessionToken, - @AuthorizationGuard(guardClass = DataSetUpdatesPredicate.class) DataSetUpdatesDTO dataSetUpdates); + @AuthorizationGuard(guardClass = DataSetUpdatesPredicate.class) + DataSetUpdatesDTO dataSetUpdates); /** * Returns a list of configured trusted domains which can host external shared web resources. 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 7ea609be025..f737c2e1998 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 @@ -41,6 +41,7 @@ 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.PersistencyResources; import ch.systemsx.cisd.openbis.generic.shared.AbstractServerTestCase; import ch.systemsx.cisd.openbis.generic.shared.CommonTestUtils; import ch.systemsx.cisd.openbis.generic.shared.IDataStoreService; @@ -172,6 +173,9 @@ public class ETLServiceTest extends AbstractServerTestCase new ExperimentBuilder().identifier("DB:/G1/P/EXP1") .getExperiment()); will(returnValue(Arrays.asList(ds1.getDataSet()))); + allowing(daoFactory).getPersistencyResources(); + will(returnValue(new PersistencyResources(null, null, null, null))); + } }); @@ -214,6 +218,10 @@ public class ETLServiceTest extends AbstractServerTestCase one(datasetLister).listAllDataSetShareIdsByDataStore(DSS_ID); will(returnValue(list)); + + allowing(daoFactory).getPersistencyResources(); + will(returnValue(new PersistencyResources(null, null, null, null))); + } }); @@ -246,6 +254,9 @@ 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( @@ -299,6 +310,9 @@ public class ETLServiceTest extends AbstractServerTestCase prepareFindDatasetTypes(this); + allowing(daoFactory).getPersistencyResources(); + will(returnValue(new PersistencyResources(null, null, null, null))); + allowing(dataStoreDAO).createOrUpdateDataStore( with(new BaseMatcher<DataStorePE>() { @@ -381,6 +395,9 @@ public class ETLServiceTest extends AbstractServerTestCase one(permIdDAO).createPermId(); will(returnValue("abc")); + + allowing(daoFactory).getPersistencyResources(); + will(returnValue(new PersistencyResources(null, null, null, null))); } }); @@ -403,6 +420,10 @@ public class ETLServiceTest extends AbstractServerTestCase one(permIdDAO).createPermId(); will(returnValue("permId")); + + allowing(daoFactory).getPersistencyResources(); + will(returnValue(new PersistencyResources(null, null, null, null))); + } }); @@ -470,6 +491,9 @@ public class ETLServiceTest extends AbstractServerTestCase SamplePE sample = new SamplePE(); sample.setCode("S42"); will(returnValue(sample)); + allowing(daoFactory).getPersistencyResources(); + will(returnValue(new PersistencyResources(null, null, null, null))); + } }); @@ -496,6 +520,9 @@ public class ETLServiceTest extends AbstractServerTestCase sampleTypePE.setAutoGeneratedCode(Boolean.FALSE); sampleTypePE.setSubcodeUnique(Boolean.FALSE); will(returnValue(sampleTypePE)); + allowing(daoFactory).getPersistencyResources(); + will(returnValue(new PersistencyResources(null, null, null, null))); + } }); SampleType sampleType = createService().getSampleType(SESSION_TOKEN, "MY_TYPE"); @@ -795,6 +822,9 @@ public class ETLServiceTest extends AbstractServerTestCase assignRoles(personPE); one(personDAO).listPersons(); will(returnValue(Arrays.asList(personPE))); + allowing(daoFactory).getPersistencyResources(); + will(returnValue(new PersistencyResources(null, null, null, null))); + } }); @@ -929,6 +959,9 @@ public class ETLServiceTest extends AbstractServerTestCase ExternalDataPE externalDataPE = new ExternalDataPE(); externalDataPE.setCode(externalData.getCode()); will(returnValue(externalDataPE)); + + allowing(daoFactory).getPersistencyResources(); + will(returnValue(new PersistencyResources(null, null, null, null))); } }); @@ -1212,6 +1245,9 @@ public class ETLServiceTest extends AbstractServerTestCase one(sampleBO).tryToLoadBySampleIdentifier(identifier); one(sampleBO).tryToGetSample(); will(returnValue(sample)); + allowing(daoFactory).getPersistencyResources(); + will(returnValue(new PersistencyResources(null, null, null, null))); + } }); } diff --git a/openbis_api/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/dto/SearchCriteria.java b/openbis_api/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/dto/SearchCriteria.java index fb448b9cd49..3f7fef7fdab 100644 --- a/openbis_api/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/dto/SearchCriteria.java +++ b/openbis_api/source/java/ch/systemsx/cisd/openbis/generic/shared/api/v1/dto/SearchCriteria.java @@ -166,6 +166,14 @@ public class SearchCriteria implements Serializable return new AttributeMatchClause(attribute, desiredValue); } + /** + * Factory method to create a MatchClause matching against registration or modification date. + * + * @param attribute The attribute to compare against + * @param mode The kind of comparison (<=, ==, >=) + * @param date The date to compare against, format YYYY-MM-DD + * @timezone The time zone of the date ("+1", "-5", "0", etc.) + */ public static MatchClause createTimeAttributeMatch(MatchClauseTimeAttribute attribute, CompareMode mode, String date, String timezone) { -- GitLab