From 09a807d3ce346eead1bec8d0ef8f7fd305204d52 Mon Sep 17 00:00:00 2001 From: pkupczyk <pkupczyk> Date: Mon, 5 Dec 2011 14:38:45 +0000 Subject: [PATCH] LMS-2675 - InfectX: retry API methods when they fail SVN: 23876 --- common/.classpath | 2 + .../ch/systemsx/cisd/common/retry/Retry.java | 34 ++++++ .../cisd/common/retry/RetryCaller.java | 78 ++++++++++++++ .../cisd/common/retry/RetryInterceptor.java | 50 +++++++++ .../cisd/common/retry/RetryProxy.java | 25 +++++ .../cisd/common/retry/RetryProxyFactory.java | 50 +++++++++ .../openbis/dss/client/api/v1/DataSet.java | 27 ++++- .../dss/client/api/v1/IDataSetDss.java | 15 ++- .../client/api/v1/IOpenbisServiceFacade.java | 5 + .../api/v1/ISimpleOpenbisServiceFacade.java | 19 ++++ .../api/v1/impl/OpenbisServiceFacade.java | 101 ++++++++++++------ .../query/client/api/v1/FacadeFactory.java | 54 +++++++--- .../query/client/api/v1/IQueryApiFacade.java | 7 ++ .../client/api/v1/FacadeFactory.java | 70 ++++++++---- .../api/v1/IProteomicsDataApiFacade.java | 9 +- .../v1/IScreeningOpenbisServiceFacade.java | 55 ++++++++++ .../api/v1/ScreeningOpenbisServiceFacade.java | 74 +++++++++---- 17 files changed, 584 insertions(+), 91 deletions(-) create mode 100644 common/source/java/ch/systemsx/cisd/common/retry/Retry.java create mode 100644 common/source/java/ch/systemsx/cisd/common/retry/RetryCaller.java create mode 100644 common/source/java/ch/systemsx/cisd/common/retry/RetryInterceptor.java create mode 100644 common/source/java/ch/systemsx/cisd/common/retry/RetryProxy.java create mode 100644 common/source/java/ch/systemsx/cisd/common/retry/RetryProxyFactory.java diff --git a/common/.classpath b/common/.classpath index 59700dbbbd9..8a265b51de0 100644 --- a/common/.classpath +++ b/common/.classpath @@ -31,5 +31,7 @@ <classpathentry kind="lib" path="/libraries/poi/poi-3.7-20101029.jar"/> <classpathentry kind="lib" path="/libraries/poi/poi-ooxml-3.7-20101029.jar"/> <classpathentry kind="lib" path="/libraries/poi/poi-ooxml-schemas-3.7-20101029.jar"/> + <classpathentry kind="lib" path="/libraries/spring/spring.jar" sourcepath="/libraries/spring/src.jar"/> + <classpathentry kind="lib" path="/libraries/commons-collections/commons-collections.jar" sourcepath="/libraries/commons-collections/src.jar"/> <classpathentry kind="output" path="targets/classes"/> </classpath> diff --git a/common/source/java/ch/systemsx/cisd/common/retry/Retry.java b/common/source/java/ch/systemsx/cisd/common/retry/Retry.java new file mode 100644 index 00000000000..04cc1ebb3f9 --- /dev/null +++ b/common/source/java/ch/systemsx/cisd/common/retry/Retry.java @@ -0,0 +1,34 @@ +/* + * Copyright 2007 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.retry; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * @author Piotr Kupczyk + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +@Inherited +public @interface Retry +{ + +} diff --git a/common/source/java/ch/systemsx/cisd/common/retry/RetryCaller.java b/common/source/java/ch/systemsx/cisd/common/retry/RetryCaller.java new file mode 100644 index 00000000000..762decc8df2 --- /dev/null +++ b/common/source/java/ch/systemsx/cisd/common/retry/RetryCaller.java @@ -0,0 +1,78 @@ +/* + * 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.common.retry; + +import org.springframework.remoting.RemoteConnectFailureException; + +/** + * @author pkupczyk + */ +public abstract class RetryCaller<T, E extends Throwable> +{ + + private int retryCounter = 1; + + private int retryMaxCounter = 5; + + private int retryWaitingTime = 1000; + + private int retryWaitingTimeFactor = 2; + + protected abstract T call() throws E; + + public T callWithRetry() throws E + { + while (true) + { + try + { + T result = call(); + return result; + } catch (RemoteConnectFailureException e) + { + if (shouldRetry()) + { + System.err.println("Call failed - will retry"); + waitForRetry(); + } else + { + System.err.println("Call failed - will NOT retry"); + throw e; + } + } + } + } + + private boolean shouldRetry() + { + return retryCounter < retryMaxCounter; + } + + private void waitForRetry() + { + try + { + Thread.sleep(retryWaitingTime); + retryWaitingTime *= retryWaitingTimeFactor; + retryCounter++; + } catch (InterruptedException e) + { + Thread.currentThread().interrupt(); + } + } + +} diff --git a/common/source/java/ch/systemsx/cisd/common/retry/RetryInterceptor.java b/common/source/java/ch/systemsx/cisd/common/retry/RetryInterceptor.java new file mode 100644 index 00000000000..dfc99b971e9 --- /dev/null +++ b/common/source/java/ch/systemsx/cisd/common/retry/RetryInterceptor.java @@ -0,0 +1,50 @@ +/* + * 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.common.retry; + +import java.lang.reflect.Method; + +import org.aopalliance.intercept.MethodInterceptor; +import org.aopalliance.intercept.MethodInvocation; + +/** + * @author pkupczyk + */ +public class RetryInterceptor implements MethodInterceptor +{ + + public Object invoke(final MethodInvocation invocation) throws Throwable + { + Method method = invocation.getMethod(); + if (method.isAnnotationPresent(Retry.class)) + { + RetryCaller<Object, Throwable> caller = new RetryCaller<Object, Throwable>() + { + @Override + protected Object call() throws Throwable + { + return invocation.proceed(); + } + }; + return caller.callWithRetry(); + } else + { + return invocation.proceed(); + } + } + +} diff --git a/common/source/java/ch/systemsx/cisd/common/retry/RetryProxy.java b/common/source/java/ch/systemsx/cisd/common/retry/RetryProxy.java new file mode 100644 index 00000000000..2bfd76fde44 --- /dev/null +++ b/common/source/java/ch/systemsx/cisd/common/retry/RetryProxy.java @@ -0,0 +1,25 @@ +/* + * 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.common.retry; + +/** + * @author pkupczyk + */ +public interface RetryProxy +{ + +} diff --git a/common/source/java/ch/systemsx/cisd/common/retry/RetryProxyFactory.java b/common/source/java/ch/systemsx/cisd/common/retry/RetryProxyFactory.java new file mode 100644 index 00000000000..e6308ea47ff --- /dev/null +++ b/common/source/java/ch/systemsx/cisd/common/retry/RetryProxyFactory.java @@ -0,0 +1,50 @@ +/* + * 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.common.retry; + +import org.springframework.aop.framework.ProxyFactory; +import org.springframework.util.ClassUtils; + +/** + * @author pkupczyk + */ +public class RetryProxyFactory +{ + + @SuppressWarnings("unchecked") + public static <T> T createProxy(T proxyTarget) + { + if (proxyTarget == null) + { + return null; + } + if (proxyTarget instanceof RetryProxy) + { + return proxyTarget; + } else + { + Class<?>[] proxyTargetInterfaces = ClassUtils.getAllInterfaces(proxyTarget); + ProxyFactory proxyFactory = new ProxyFactory(proxyTarget); + proxyFactory.addInterface(RetryProxy.class); + proxyFactory.addAdvice(new RetryInterceptor()); + proxyFactory.setProxyTargetClass(proxyTargetInterfaces == null + || proxyTargetInterfaces.length == 0); + return (T) proxyFactory.getProxy(); + } + } + +} diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/DataSet.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/DataSet.java index 0bb8c76e25f..ef4e2f85661 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/DataSet.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/DataSet.java @@ -24,6 +24,7 @@ import java.util.HashMap; import java.util.List; import ch.systemsx.cisd.common.exceptions.InvalidSessionException; +import ch.systemsx.cisd.common.retry.Retry; import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.FileInfoDssDTO; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataSet.Connections; @@ -43,6 +44,13 @@ public class DataSet private IDataSetDss dataSetDss; + /* Default constructor needed to create a retry-proxy */ + protected DataSet() + { + facade = null; + dssComponent = null; + } + /** * Constructor. * @@ -66,6 +74,7 @@ public class DataSet /** * @see ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataSet#getCode() */ + @Retry public String getCode() { return (metadata == null) ? dataSetDss.getCode() : metadata.getCode(); @@ -74,6 +83,7 @@ public class DataSet /** * @see ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataSet#getExperimentIdentifier() */ + @Retry public String getExperimentIdentifier() { return getMetadata().getExperimentIdentifier(); @@ -82,6 +92,7 @@ public class DataSet /** * @see ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataSet#getSampleIdentifierOrNull() */ + @Retry public String getSampleIdentifierOrNull() { return getMetadata().getSampleIdentifierOrNull(); @@ -90,6 +101,7 @@ public class DataSet /** * @see ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataSet#getDataSetTypeCode() */ + @Retry public String getDataSetTypeCode() { return getMetadata().getDataSetTypeCode(); @@ -98,6 +110,7 @@ public class DataSet /** * @see ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataSet#getRegistrationDate() */ + @Retry public Date getRegistrationDate() { return getMetadata().getRegistrationDate(); @@ -106,6 +119,7 @@ public class DataSet /** * @see ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataSet#getProperties() */ + @Retry public HashMap<String, String> getProperties() { return getMetadata().getProperties(); @@ -114,6 +128,7 @@ public class DataSet /** * @see ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataSet#getRetrievedConnections() */ + @Retry public EnumSet<Connections> getRetrievedConnections() { return getMetadata().getRetrievedConnections(); @@ -122,6 +137,7 @@ public class DataSet /** * @see ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataSet#getParentCodes() */ + @Retry public List<String> getParentCodes() { return getMetadata().getParentCodes(); @@ -130,15 +146,17 @@ public class DataSet /** * @see ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataSet#getChildrenCodes() */ + @Retry public List<String> getChildrenCodes() { return getMetadata().getChildrenCodes(); } - + /** * @see ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataSet#equals(java.lang.Object) */ @Override + @Retry public boolean equals(Object obj) { return getMetadata().equals(obj); @@ -148,6 +166,7 @@ public class DataSet * @see ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataSet#hashCode() */ @Override + @Retry public int hashCode() { return getMetadata().hashCode(); @@ -157,6 +176,7 @@ public class DataSet * @see ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataSet#toString() */ @Override + @Retry public String toString() { return getMetadata().toString(); @@ -170,6 +190,7 @@ public class DataSet * @see ch.systemsx.cisd.openbis.dss.client.api.v1.IDataSetDss#listFiles(java.lang.String, * boolean) */ + @Retry public FileInfoDssDTO[] listFiles(String startPath, boolean isRecursive) throws IllegalArgumentException, InvalidSessionException { @@ -182,6 +203,7 @@ public class DataSet * @throws InvalidSessionException * @see ch.systemsx.cisd.openbis.dss.client.api.v1.IDataSetDss#getFile(java.lang.String) */ + @Retry public InputStream getFile(String path) throws IllegalArgumentException, InvalidSessionException { @@ -194,6 +216,7 @@ public class DataSet * @throws InvalidSessionException * @see ch.systemsx.cisd.openbis.dss.client.api.v1.IDataSetDss#tryLinkToContents(java.lang.String) */ + @Retry public File tryLinkToContents(String overrideStoreRootPathOrNull) throws IllegalArgumentException, InvalidSessionException { @@ -208,6 +231,7 @@ public class DataSet * @see ch.systemsx.cisd.openbis.dss.client.api.v1.IDataSetDss#getLinkOrCopyOfContents(java.lang.String, * java.io.File) */ + @Retry public File getLinkOrCopyOfContents(String overrideStoreRootPathOrNull, File downloadDir) throws IllegalArgumentException, InvalidSessionException { @@ -223,6 +247,7 @@ public class DataSet * @see ch.systemsx.cisd.openbis.dss.client.api.v1.IDataSetDss#getLinkOrCopyOfContent(java.lang.String, * java.io.File, java.lang.String) */ + @Retry public File getLinkOrCopyOfContent(String overrideStoreRootPathOrNull, File downloadDir, String pathInDataSet) throws IllegalArgumentException, InvalidSessionException { diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/IDataSetDss.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/IDataSetDss.java index 22543b7d1a8..87bd879c563 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/IDataSetDss.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/IDataSetDss.java @@ -20,6 +20,7 @@ import java.io.File; import java.io.InputStream; import ch.systemsx.cisd.common.exceptions.InvalidSessionException; +import ch.systemsx.cisd.common.retry.Retry; import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.FileInfoDssDTO; /** @@ -33,6 +34,7 @@ public interface IDataSetDss /** * The code of this data set. */ + @Retry public String getCode(); /** @@ -43,6 +45,7 @@ public interface IDataSetDss * or "" for the root of the hierarchy for this data set. * @param isRecursive If true, the contents of any subdirectories will be listed as well. */ + @Retry public FileInfoDssDTO[] listFiles(String startPath, boolean isRecursive) throws IllegalArgumentException, InvalidSessionException; @@ -52,6 +55,7 @@ public interface IDataSetDss * @param path The path of the file to retrieve. The path must be relative with respect to the * data set, such as the path returned by {@link FileInfoDssDTO#getPathInDataSet}. */ + @Retry public InputStream getFile(String path) throws IllegalArgumentException, InvalidSessionException; @@ -67,6 +71,7 @@ public interface IDataSetDss * container), a File that references the contents of the data set otherwise. * @since 1.1 */ + @Retry public File tryLinkToContents(String overrideStoreRootPathOrNull) throws IllegalArgumentException, InvalidSessionException; @@ -82,13 +87,14 @@ public interface IDataSetDss * @return A File containing the contents of the data set. * @since 1.1 */ + @Retry public File getLinkOrCopyOfContents(String overrideStoreRootPathOrNull, File downloadDir) throws IllegalArgumentException, InvalidSessionException; - + /** - * Returns a {@link File}, if possible, that directly references some specified content of a data set in - * the data store server. If not possible, downloads that content and returns a File in - * the downloadDir containing that content. + * Returns a {@link File}, if possible, that directly references some specified content of a + * data set in the data store server. If not possible, downloads that content and returns a File + * in the downloadDir containing that content. * * @param overrideStoreRootPathOrNull A path, in the context of the local file system mounts, to * the DSS' store root. If null, datasets are copied to the downloadDir folder. @@ -97,6 +103,7 @@ public interface IDataSetDss * @param pathInDataSet Path of requested content inside the data set. * @return A File containing the requested content. */ + @Retry public File getLinkOrCopyOfContent(String overrideStoreRootPathOrNull, File downloadDir, String pathInDataSet) throws IllegalArgumentException, InvalidSessionException; diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/IOpenbisServiceFacade.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/IOpenbisServiceFacade.java index db2b9c30442..ccb32fcddc4 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/IOpenbisServiceFacade.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/IOpenbisServiceFacade.java @@ -20,6 +20,7 @@ import java.util.EnumSet; import java.util.HashMap; import java.util.List; +import ch.systemsx.cisd.common.retry.Retry; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.ControlledVocabularyPropertyType; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataSet.Connections; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.NewVocabularyTerm; @@ -47,6 +48,7 @@ public interface IOpenbisServiceFacade extends ISimpleOpenbisServiceFacade * * @param searchCriteria The sample metadata values to be matched against. */ + @Retry public List<Sample> searchForSamples(SearchCriteria searchCriteria); /** @@ -54,6 +56,7 @@ public interface IOpenbisServiceFacade extends ISimpleOpenbisServiceFacade * * @param searchCriteria the criteria used for searching. */ + @Retry public List<DataSet> searchForDataSets(SearchCriteria searchCriteria); /** @@ -61,6 +64,7 @@ public interface IOpenbisServiceFacade extends ISimpleOpenbisServiceFacade * * @param samples The samples for which we return attached data sets. */ + @Retry public List<DataSet> listDataSets(List<Sample> samples, EnumSet<Connections> connectionsToGet); /** @@ -93,5 +97,6 @@ public interface IOpenbisServiceFacade extends ISimpleOpenbisServiceFacade * @deprecated Please use the {@link #listVocabularies()} method instead. */ @Deprecated + @Retry public HashMap<Vocabulary, List<ControlledVocabularyPropertyType.VocabularyTerm>> getVocabularyTermsMap(); } diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/ISimpleOpenbisServiceFacade.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/ISimpleOpenbisServiceFacade.java index e5cb91ee449..efbb764ee11 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/ISimpleOpenbisServiceFacade.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/ISimpleOpenbisServiceFacade.java @@ -22,6 +22,7 @@ import java.util.Map; import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException; import ch.systemsx.cisd.common.exceptions.InvalidSessionException; +import ch.systemsx.cisd.common.retry.Retry; import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.NewDataSetDTO; import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.validation.ValidationError; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataSetType; @@ -48,53 +49,62 @@ public interface ISimpleOpenbisServiceFacade /** * Returns all available projects. */ + @Retry List<Project> listProjects(); /** * Return all spaces enriched with their projects and role assignments. */ + @Retry List<SpaceWithProjectsAndRoleAssignments> getSpacesWithProjects(); /** * Return {@link Experiment} objects for a set of given experiment identifiers. If some of the * specified experiment identifiers does not exist in openBIS it will be silently ignored. */ + @Retry List<Experiment> getExperiments(List<String> experimentIdentifiers); /** * Return all experiments for a given list of project identifiers. If some of the specified * project identifiers does not exist in openBIS it will be silently ignored. */ + @Retry List<Experiment> listExperimentsForProjects(List<String> projectIdentifiers); /** * Return all experiments having samples for a given list of project identifiers. If some of the * specified project identifiers does not exist in openBIS it will be silently ignored. */ + @Retry List<Experiment> listExperimentsHavingSamplesForProjects(List<String> projectIdentifiers); /** * Return all experiments having data sets for a given list of project identifiers. If some of * the specified project identifiers does not exist in openBIS it will be silently ignored. */ + @Retry List<Experiment> listExperimentsHavingDataSetsForProjects(List<String> projectIdentifiers); /** * Return {@link Sample} objects for a set of given sample identifiers. If some of the specified * sample identifiers does not exist in openBIS it will be silently ignored. */ + @Retry List<Sample> getSamples(List<String> sampleIdentifiers); /** * Return all samples for a given list of experiments identifiers. If some of the specified * experiment identifiers does not exist in openBIS it will be silently ignored. */ + @Retry List<Sample> listSamplesForExperiments(List<String> experimentIdentifiers); /** * Return all samples for a given list of project identifiers. If some of the specified project * identifiers does not exist in openBIS it will be silently ignored. */ + @Retry public List<Sample> listSamplesForProjects(List<String> projectIdentifiers); /** @@ -103,34 +113,40 @@ public interface ISimpleOpenbisServiceFacade * * @return The requested data set, or null if it does not exist. */ + @Retry DataSet getDataSet(String dataSetCodes); /** * Return {@link DataSet} objects for given a set of codes. If some of the specified data set * codes does not exist in openBIS it will be silently ignored. */ + @Retry List<DataSet> getDataSets(List<String> dataSetCodes); /** * Return all data sets for a given list of experiments identifiers. If some of the specified * experiment identifiers does not exist in openBIS it will be silently ignored. */ + @Retry List<DataSet> listDataSetsForExperiments(List<String> experimentIdentifiers); /** * Return all data sets for a given list of sample identifiers. If some of the specified sample * identifiers does not exist in openBIS it will be silently ignored. */ + @Retry List<DataSet> listDataSetsForSamples(List<String> sampleIdentifiers); /** * Returns all data set types available in openBIS. */ + @Retry List<DataSetType> listDataSetTypes(); /** * Return all vocabularies available in openBIS together with the contained vocabulary terms. */ + @Retry List<Vocabulary> listVocabularies(); /** @@ -152,6 +168,7 @@ public interface ISimpleOpenbisServiceFacade * @throws EnvironmentFailureException Thrown in cases where it is not possible to connect to * the server. */ + @Retry public List<ValidationError> validateDataSet(NewDataSetDTO newDataset, File dataSetFile) throws IllegalStateException, EnvironmentFailureException; @@ -165,6 +182,7 @@ public interface ISimpleOpenbisServiceFacade * @throws EnvironmentFailureException Thrown in cases where it is not possible to connect to * the server. */ + @Retry public Map<String, String> extractMetadata(NewDataSetDTO newDataset, File dataSetFile) throws IllegalStateException, EnvironmentFailureException; @@ -173,6 +191,7 @@ public interface ISimpleOpenbisServiceFacade * * @throws InvalidSessionException If the session is not alive. */ + @Retry public void checkSession() throws InvalidSessionException; /** diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/impl/OpenbisServiceFacade.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/impl/OpenbisServiceFacade.java index 352a4a38fe6..ec62cf79363 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/impl/OpenbisServiceFacade.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/impl/OpenbisServiceFacade.java @@ -30,6 +30,8 @@ import ch.systemsx.cisd.common.collections.CollectionUtils; import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException; import ch.systemsx.cisd.common.exceptions.InvalidSessionException; import ch.systemsx.cisd.common.exceptions.UserFailureException; +import ch.systemsx.cisd.common.retry.RetryCaller; +import ch.systemsx.cisd.common.retry.RetryProxyFactory; import ch.systemsx.cisd.openbis.dss.client.api.v1.DataSet; import ch.systemsx.cisd.openbis.dss.client.api.v1.DssComponentFactory; import ch.systemsx.cisd.openbis.dss.client.api.v1.IDataSetDss; @@ -70,41 +72,74 @@ public class OpenbisServiceFacade implements IOpenbisServiceFacade { @Private - public static OpenbisServiceFacade tryCreate(String username, String password, - String openbisUrl, long timeoutInMillis) + public static IOpenbisServiceFacade tryCreate(final String username, final String password, + final String openbisUrl, final long timeoutInMillis) { - IGeneralInformationService service = - createGeneralInformationService(openbisUrl, timeoutInMillis); - IGeneralInformationChangingService changingService = - createGeneralInformationChangingService(openbisUrl, timeoutInMillis); - - // TODO KE: wrap the facade into a re-authenticating java.lang.reflect.Proxy - // this will hide any re-authentication complexity from the clients - String token = service.tryToAuthenticateForAllServices(username, password); - if (token == null) - { - throw UserFailureException.fromTemplate( - "Failed to authenticate user '%s' against the openBIS at '%s'.", username, - openbisUrl); - } - - IDssComponent dssComponent = - DssComponentFactory.tryCreate(token, openbisUrl, timeoutInMillis); - return new OpenbisServiceFacade(token, service, changingService, dssComponent); + RetryCaller<IOpenbisServiceFacade, RuntimeException> caller = + new RetryCaller<IOpenbisServiceFacade, RuntimeException>() + { + @Override + protected IOpenbisServiceFacade call() + { + IGeneralInformationService service = + createGeneralInformationService(openbisUrl, timeoutInMillis); + IGeneralInformationChangingService changingService = + createGeneralInformationChangingService(openbisUrl, + timeoutInMillis); + + // TODO KE: wrap the facade into a re-authenticating + // java.lang.reflect.Proxy + // this will hide any re-authentication complexity from the clients + String token = + service.tryToAuthenticateForAllServices(username, password); + if (token == null) + { + throw UserFailureException + .fromTemplate( + "Failed to authenticate user '%s' against the openBIS at '%s'.", + username, openbisUrl); + } + + IDssComponent dssComponent = + DssComponentFactory.tryCreate(token, openbisUrl, + timeoutInMillis); + IOpenbisServiceFacade facade = + new OpenbisServiceFacade(token, service, changingService, + dssComponent); + + return RetryProxyFactory.createProxy(facade); + } + }; + return caller.callWithRetry(); } @Private - public static IOpenbisServiceFacade tryCreate(String sessionToken, String openbisUrl, - long timeoutInMillis) + public static IOpenbisServiceFacade tryCreate(final String sessionToken, + final String openbisUrl, final long timeoutInMillis) { - IGeneralInformationService service = - createGeneralInformationService(openbisUrl, timeoutInMillis); - IGeneralInformationChangingService changingService = - createGeneralInformationChangingService(openbisUrl, timeoutInMillis); - - IDssComponent dssComponent = - DssComponentFactory.tryCreate(sessionToken, openbisUrl, timeoutInMillis); - return new OpenbisServiceFacade(sessionToken, service, changingService, dssComponent); + RetryCaller<IOpenbisServiceFacade, RuntimeException> caller = + new RetryCaller<IOpenbisServiceFacade, RuntimeException>() + { + @Override + protected IOpenbisServiceFacade call() + { + IGeneralInformationService service = + createGeneralInformationService(openbisUrl, timeoutInMillis); + IGeneralInformationChangingService changingService = + createGeneralInformationChangingService(openbisUrl, + timeoutInMillis); + + IDssComponent dssComponent = + DssComponentFactory.tryCreate(sessionToken, openbisUrl, + timeoutInMillis); + IOpenbisServiceFacade facade = + new OpenbisServiceFacade(sessionToken, service, + changingService, dssComponent); + + return RetryProxyFactory.createProxy(facade); + } + }; + return caller.callWithRetry(); } private static IGeneralInformationService createGeneralInformationService(String openbisUrl, @@ -332,14 +367,14 @@ public class OpenbisServiceFacade implements IOpenbisServiceFacade public IDataSetDss getDataSetDss(String code) throws EnvironmentFailureException { - return dssComponent.getDataSet(code); + return RetryProxyFactory.createProxy(dssComponent.getDataSet(code)); } public DataSet putDataSet(NewDataSetDTO newDataset, File dataSetFile) throws EnvironmentFailureException { IDataSetDss dataSetDss = dssComponent.putDataSet(newDataset, dataSetFile); - return new DataSet(this, dssComponent, null, dataSetDss); + return RetryProxyFactory.createProxy(new DataSet(this, dssComponent, null, dataSetDss)); } public List<ValidationError> validateDataSet(NewDataSetDTO newDataset, File dataSetFile) @@ -460,7 +495,7 @@ public class OpenbisServiceFacade implements IOpenbisServiceFacade for (ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.DataSet dataSet : internalDataSets) { DataSet converted = new DataSet(this, dssComponent, dataSet, null); - convertedDataSets.add(converted); + convertedDataSets.add(RetryProxyFactory.createProxy(converted)); } return convertedDataSets; diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/query/client/api/v1/FacadeFactory.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/query/client/api/v1/FacadeFactory.java index 38983c1c333..6e4704a6463 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/query/client/api/v1/FacadeFactory.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/query/client/api/v1/FacadeFactory.java @@ -17,6 +17,8 @@ package ch.systemsx.cisd.openbis.plugin.query.client.api.v1; import ch.systemsx.cisd.common.api.client.ServiceFinder; +import ch.systemsx.cisd.common.retry.RetryCaller; +import ch.systemsx.cisd.common.retry.RetryProxyFactory; import ch.systemsx.cisd.openbis.generic.shared.api.v1.IGeneralInformationService; import ch.systemsx.cisd.openbis.plugin.query.shared.api.v1.IQueryApiServer; @@ -36,25 +38,53 @@ public class FacadeFactory /** * Creates a facade for specified server URL, user Id, and password. */ - public static IQueryApiFacade create(String serverURL, String userID, String password) + public static IQueryApiFacade create(final String serverURL, final String userID, + final String password) { - IQueryApiServer service = createQueryService(serverURL); - String sessionToken = service.tryToAuthenticateAtQueryServer(userID, password); - if (sessionToken == null) - { - throw new IllegalArgumentException("User " + userID + " couldn't be authenticated"); - } - // Login at one service is enough - return new QueryApiFacade(service, createGeneralInfoService(serverURL), sessionToken); + RetryCaller<IQueryApiFacade, RuntimeException> caller = + new RetryCaller<IQueryApiFacade, RuntimeException>() + { + @Override + protected IQueryApiFacade call() + { + IQueryApiServer service = createQueryService(serverURL); + String sessionToken = + service.tryToAuthenticateAtQueryServer(userID, password); + if (sessionToken == null) + { + throw new IllegalArgumentException("User " + userID + + " couldn't be authenticated"); + } + // Login at one service is enough + IQueryApiFacade facade = + new QueryApiFacade(service, + createGeneralInfoService(serverURL), sessionToken); + + return RetryProxyFactory.createProxy(facade); + } + }; + return caller.callWithRetry(); } /** * Creates a facade for specified url and sessionToken. */ - public static IQueryApiFacade create(String serverURL, String sessionToken) + public static IQueryApiFacade create(final String serverURL, final String sessionToken) { - return new QueryApiFacade(createQueryService(serverURL), - createGeneralInfoService(serverURL), sessionToken); + RetryCaller<IQueryApiFacade, RuntimeException> caller = + new RetryCaller<IQueryApiFacade, RuntimeException>() + { + @Override + protected IQueryApiFacade call() + { + IQueryApiFacade facade = + new QueryApiFacade(createQueryService(serverURL), + createGeneralInfoService(serverURL), sessionToken); + + return RetryProxyFactory.createProxy(facade); + } + }; + return caller.callWithRetry(); } private static IQueryApiServer createQueryService(String serverURL) diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/query/client/api/v1/IQueryApiFacade.java b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/query/client/api/v1/IQueryApiFacade.java index 84d4afa457f..a8fe7e136ca 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/plugin/query/client/api/v1/IQueryApiFacade.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/plugin/query/client/api/v1/IQueryApiFacade.java @@ -19,6 +19,7 @@ package ch.systemsx.cisd.openbis.plugin.query.client.api.v1; import java.util.List; import java.util.Map; +import ch.systemsx.cisd.common.retry.Retry; import ch.systemsx.cisd.openbis.generic.shared.api.v1.IGeneralInformationService; import ch.systemsx.cisd.openbis.plugin.query.shared.api.v1.dto.QueryDescription; import ch.systemsx.cisd.openbis.plugin.query.shared.api.v1.dto.QueryTableModel; @@ -34,33 +35,39 @@ public interface IQueryApiFacade /** * Return the session token for the logged-in user. */ + @Retry public String getSessionToken(); /** * Lists all queries the user has access rights. */ + @Retry public List<QueryDescription> listQueries(); /** * Executes specified query by using specified parameter bindings. */ + @Retry public QueryTableModel executeQuery(long queryID, Map<String, String> parameterBindings); /** * Returns meta data for all reporting plugins which deliver a table. */ + @Retry public List<ReportDescription> listTableReportDescriptions(); /** * Creates for the specified data sets and specified report description a report. Available * report descriptions can be obtained by {@link #listTableReportDescriptions()}. */ + @Retry public QueryTableModel createReportFromDataSets(ReportDescription reportDescription, List<String> dataSetCodes); /** * Returns a remote access to the {@link IGeneralInformationService}. */ + @Retry public IGeneralInformationService getGeneralInformationService(); /** diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/client/api/v1/FacadeFactory.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/client/api/v1/FacadeFactory.java index 1819982a8bd..59a2228d89f 100644 --- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/client/api/v1/FacadeFactory.java +++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/client/api/v1/FacadeFactory.java @@ -17,6 +17,8 @@ package ch.systemsx.cisd.openbis.plugin.proteomics.client.api.v1; import ch.systemsx.cisd.common.api.client.ServiceFinder; +import ch.systemsx.cisd.common.retry.RetryCaller; +import ch.systemsx.cisd.common.retry.RetryProxyFactory; import ch.systemsx.cisd.openbis.generic.shared.api.v1.IGeneralInformationService; import ch.systemsx.cisd.openbis.plugin.proteomics.shared.api.v1.IProteomicsDataService; @@ -27,35 +29,64 @@ import ch.systemsx.cisd.openbis.plugin.proteomics.shared.api.v1.IProteomicsDataS */ public class FacadeFactory { - private static final ServiceFinder SERVICE_FINDER = - new ServiceFinder("openbis", IProteomicsDataService.SERVER_URL); + private static final ServiceFinder SERVICE_FINDER = new ServiceFinder("openbis", + IProteomicsDataService.SERVER_URL); - private static final ServiceFinder GENERIC_INFO_SERVICE_FINDER = - new ServiceFinder("openbis", IGeneralInformationService.SERVICE_URL); + private static final ServiceFinder GENERIC_INFO_SERVICE_FINDER = new ServiceFinder("openbis", + IGeneralInformationService.SERVICE_URL); /** * Creates a facade for specified server URL, user Id, and password. */ - public static IProteomicsDataApiFacade create(String serverURL, String userID, String password) + public static IProteomicsDataApiFacade create(final String serverURL, final String userID, + final String password) { - IGeneralInformationService infoService = createGenericInfoService(serverURL); - IProteomicsDataService service = createService(serverURL); - String sessionToken = infoService.tryToAuthenticateForAllServices(userID, password); - if (sessionToken == null) - { - throw new IllegalArgumentException("User " + userID + " couldn't be authenticated"); - } - return new ProteomicsDataApiFacade(service, infoService, sessionToken); + RetryCaller<IProteomicsDataApiFacade, RuntimeException> caller = + new RetryCaller<IProteomicsDataApiFacade, RuntimeException>() + { + @Override + protected IProteomicsDataApiFacade call() + { + IGeneralInformationService infoService = + createGenericInfoService(serverURL); + IProteomicsDataService service = createService(serverURL); + String sessionToken = + infoService.tryToAuthenticateForAllServices(userID, password); + if (sessionToken == null) + { + throw new IllegalArgumentException("User " + userID + + " couldn't be authenticated"); + } + + IProteomicsDataApiFacade facade = + new ProteomicsDataApiFacade(service, infoService, sessionToken); + return RetryProxyFactory.createProxy(facade); + } + }; + return caller.callWithRetry(); } /** * Creates a facade for specified url and sessionToken. */ - public static IProteomicsDataApiFacade create(String serverURL, String sessionToken) + public static IProteomicsDataApiFacade create(final String serverURL, final String sessionToken) { - IProteomicsDataService service = createService(serverURL); - IGeneralInformationService infoService = createGenericInfoService(serverURL); - return new ProteomicsDataApiFacade(service, infoService, sessionToken); + RetryCaller<IProteomicsDataApiFacade, RuntimeException> caller = + new RetryCaller<IProteomicsDataApiFacade, RuntimeException>() + { + @Override + protected IProteomicsDataApiFacade call() + { + IProteomicsDataService service = createService(serverURL); + IGeneralInformationService infoService = + createGenericInfoService(serverURL); + + IProteomicsDataApiFacade facade = + new ProteomicsDataApiFacade(service, infoService, sessionToken); + return RetryProxyFactory.createProxy(facade); + } + }; + return caller.callWithRetry(); } private static IProteomicsDataService createService(String serverURL) @@ -65,7 +96,8 @@ public class FacadeFactory private static IGeneralInformationService createGenericInfoService(String serverURL) { - return GENERIC_INFO_SERVICE_FINDER.createService(IGeneralInformationService.class, serverURL); + return GENERIC_INFO_SERVICE_FINDER.createService(IGeneralInformationService.class, + serverURL); } - + } diff --git a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/client/api/v1/IProteomicsDataApiFacade.java b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/client/api/v1/IProteomicsDataApiFacade.java index c9f5902adc0..4383823c790 100644 --- a/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/client/api/v1/IProteomicsDataApiFacade.java +++ b/rtd_phosphonetx/source/java/ch/systemsx/cisd/openbis/plugin/proteomics/client/api/v1/IProteomicsDataApiFacade.java @@ -18,6 +18,7 @@ package ch.systemsx.cisd.openbis.plugin.proteomics.client.api.v1; import java.util.List; +import ch.systemsx.cisd.common.retry.Retry; import ch.systemsx.cisd.openbis.generic.shared.api.v1.dto.Project; import ch.systemsx.cisd.openbis.plugin.proteomics.shared.api.v1.dto.DataSet; import ch.systemsx.cisd.openbis.plugin.proteomics.shared.api.v1.dto.DataStoreServerProcessingPluginInfo; @@ -34,17 +35,20 @@ public interface IProteomicsDataApiFacade /** * Return the session token for the logged-in user. */ + @Retry public String getSessionToken(); /** * Returns all samples of type MS_INJECTION in space MS_DATA which have a parent sample which * the specified user is allow to read. */ + @Retry public List<MsInjectionDataInfo> listRawDataSamples(String userID); /** * Lists all processing plugins on DSS. */ + @Retry public List<DataStoreServerProcessingPluginInfo> listDataStoreServerProcessingPluginInfos(); /** @@ -65,23 +69,26 @@ public interface IProteomicsDataApiFacade /** * Returns all projects where the specified user has USER access rights. */ + @Retry public List<Project> listProjects(String userID); /** * Returns all experiments of type <tt>MS_SEARCH</tt> which the specified user is allowed to * read. */ - @Deprecated + @Retry public List<Experiment> listSearchExperiments(String userID); /** * Returns all experiments of specified type which the specified user is allowed to read. */ + @Retry public List<Experiment> listExperiments(String sessionToken, String userID, String experimentTypeCode); /** * Returns all data sets of specified experiment which the specified user is allowed to read. */ + @Retry public List<DataSet> listDataSetsByExperiment(String userID, long experimentID); /** diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/IScreeningOpenbisServiceFacade.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/IScreeningOpenbisServiceFacade.java index a11d268bde9..e4ed62feda9 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/IScreeningOpenbisServiceFacade.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/IScreeningOpenbisServiceFacade.java @@ -23,6 +23,7 @@ import java.util.Map; import ch.systemsx.cisd.base.image.IImageTransformerFactory; import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException; +import ch.systemsx.cisd.common.retry.Retry; import ch.systemsx.cisd.openbis.dss.client.api.v1.DataSet; import ch.systemsx.cisd.openbis.dss.client.api.v1.IDataSetDss; import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.NewDataSetMetadataDTO; @@ -65,6 +66,7 @@ public interface IScreeningOpenbisServiceFacade /** * Return the session token for this authenticated user. */ + @Retry public String getSessionToken(); /** Closes connection with the server. After calling this method this facade cannot be used. */ @@ -81,29 +83,34 @@ public interface IScreeningOpenbisServiceFacade * Return the list of all visible plates assigned to any experiment, along with their * hierarchical context (space, project, experiment). */ + @Retry public List<Plate> listPlates(); /** * Return full metadata for each specified plate, including wells and their properties. If a * well contains a material, its properties are also available. */ + @Retry public List<PlateMetadata> getPlateMetadataList(List<? extends PlateIdentifier> plateIdentifiers); /** * Return the list of all plates for the given <var>experiment</var>. */ + @Retry public List<Plate> listPlates(ExperimentIdentifier experiment); /** * Return the list of all plates for the given <var>experiment</var> and analysis procedure. * Each returned plate has at least one data set with the specified analysis procedure. */ + @Retry public List<Plate> listPlates(ExperimentIdentifier experiment, String analysisProcedure); /** * Return the list of all visible experiments, along with their hierarchical context (space, * project). */ + @Retry public List<ExperimentIdentifier> listExperiments(); /** @@ -115,12 +122,14 @@ public interface IScreeningOpenbisServiceFacade * * @since 1.6 */ + @Retry public List<ExperimentIdentifier> listExperiments(String userId); /** * For a given set of plates provides the list of all connected data sets containing feature * vectors. */ + @Retry public List<FeatureVectorDatasetReference> listFeatureVectorDatasets( List<? extends PlateIdentifier> plates); @@ -131,6 +140,7 @@ public interface IScreeningOpenbisServiceFacade * @param analysisProcedureOrNull If <code>null</code> returned list isn't filtered on analysis * procedure property. */ + @Retry public List<FeatureVectorDatasetReference> listFeatureVectorDatasets( List<? extends PlateIdentifier> plates, String analysisProcedureOrNull); @@ -140,18 +150,21 @@ public interface IScreeningOpenbisServiceFacade * * @deprecated Use {@link #listRawImageDatasets(List)} instead. */ + @Retry @Deprecated public List<ImageDatasetReference> listImageDatasets(List<? extends PlateIdentifier> plates); /** * For a given set of plates provides the list of all connected data sets containing raw images. */ + @Retry public List<ImageDatasetReference> listRawImageDatasets(List<? extends PlateIdentifier> plates); /** * For a given set of plates provides the list of all connected data sets containing * segmentation images (overlays). */ + @Retry public List<ImageDatasetReference> listSegmentationImageDatasets( List<? extends PlateIdentifier> plates); @@ -161,6 +174,7 @@ public interface IScreeningOpenbisServiceFacade * * @param analysisProcedureOrNull If <code>null</code> no restriction applies. */ + @Retry public List<ImageDatasetReference> listSegmentationImageDatasets( List<? extends PlateIdentifier> plates, String analysisProcedureOrNull); @@ -172,6 +186,7 @@ public interface IScreeningOpenbisServiceFacade * For how to get the feature vectors, see * {@link #convertToFeatureVectorDatasetWellIdentifier(List)}. */ + @Retry public List<PlateWellReferenceWithDatasets> listPlateWells( ExperimentIdentifier experimentIdentifer, MaterialIdentifier materialIdentifier, boolean findDatasets); @@ -181,17 +196,20 @@ public interface IScreeningOpenbisServiceFacade * it. If <code>findDatasets == true</code>, find also the connected image and image analysis * data sets for the relevant plates. */ + @Retry public List<PlateWellReferenceWithDatasets> listPlateWells( MaterialIdentifier materialIdentifier, boolean findDatasets); /** * For the given <var>plateIdentifier</var> find all wells that are connected to it. */ + @Retry public List<WellIdentifier> listPlateWells(PlateIdentifier plateIdentifier); /** * Returns all properties of specified well as a map. */ + @Retry public Map<String, String> getWellProperties(WellIdentifier wellIdentifier); /** @@ -211,6 +229,7 @@ public interface IScreeningOpenbisServiceFacade * the server. */ @Deprecated + @Retry public List<IDataSetDss> getDataSets(WellIdentifier wellIdentifier, String datasetTypeCodePattern) throws IllegalStateException, EnvironmentFailureException; @@ -222,9 +241,11 @@ public interface IScreeningOpenbisServiceFacade * @throws EnvironmentFailureException Thrown in cases where it is not possible to connect to * the server. */ + @Retry public List<IDataSetDss> getDataSets(WellIdentifier wellIdentifier, IDataSetFilter dataSetFilter) throws IllegalStateException, EnvironmentFailureException; + @Retry public IDataSetDss getDataSet(String dataSetCode) throws IllegalStateException, EnvironmentFailureException; @@ -257,6 +278,7 @@ public interface IScreeningOpenbisServiceFacade * the server. */ @Deprecated + @Retry public List<IDataSetDss> getDataSets(PlateIdentifier plateIdentifier, String datasetTypeCodePattern) throws IllegalStateException, EnvironmentFailureException; @@ -268,6 +290,7 @@ public interface IScreeningOpenbisServiceFacade * @throws EnvironmentFailureException Thrown in cases where it is not possible to connect to * the server. */ + @Retry public List<IDataSetDss> getDataSets(PlateIdentifier plateIdentifier, IDataSetFilter dataSetFilter) throws IllegalStateException, EnvironmentFailureException; @@ -280,6 +303,7 @@ public interface IScreeningOpenbisServiceFacade * @throws EnvironmentFailureException Thrown in cases where it is not possible to connect to * the server. */ + @Retry public List<DataSet> getFullDataSets(PlateIdentifier plateIdentifier, IDataSetFilter dataSetFilter) throws IllegalStateException, EnvironmentFailureException; @@ -290,6 +314,7 @@ public interface IScreeningOpenbisServiceFacade * @throws EnvironmentFailureException Thrown in cases where it is not possible to connect to * the server. */ + @Retry public List<IDataSetDss> getDataSets(ExperimentIdentifier plateIdentifier, IDataSetFilter dataSetFilter) throws IllegalStateException, EnvironmentFailureException; @@ -302,6 +327,7 @@ public interface IScreeningOpenbisServiceFacade * @throws EnvironmentFailureException Thrown in cases where it is not possible to connect to * the server. */ + @Retry public List<DataSet> getFullDataSets(ExperimentIdentifier experimentIdentifier, IDataSetFilter dataSetFilter) throws IllegalStateException, EnvironmentFailureException; @@ -314,6 +340,7 @@ public interface IScreeningOpenbisServiceFacade * @throws EnvironmentFailureException Thrown in cases where it is not possible to connect to * the server. */ + @Retry public List<DataSet> getDataSetMetaData(List<String> dataSetCodes) throws IllegalStateException, EnvironmentFailureException; @@ -359,6 +386,7 @@ public interface IScreeningOpenbisServiceFacade * @see #listPlateWells(ExperimentIdentifier, MaterialIdentifier, boolean) * @see #loadFeaturesForDatasetWellReferences(List, List) */ + @Retry public List<FeatureVectorDatasetWellReference> convertToFeatureVectorDatasetWellIdentifier( List<PlateWellReferenceWithDatasets> plateWellReferenceWithDataSets); @@ -366,6 +394,7 @@ public interface IScreeningOpenbisServiceFacade * Converts a given list of dataset codes to dataset identifiers which can be used in other API * calls. */ + @Retry public List<IDatasetIdentifier> getDatasetIdentifiers(List<String> datasetCodes); /** @@ -381,6 +410,7 @@ public interface IScreeningOpenbisServiceFacade * {@link FeatureVectorDataset} will provide feature codes and feature labels. */ @Deprecated + @Retry public List<String> listAvailableFeatureNames( List<? extends IFeatureVectorDatasetIdentifier> featureDatasets); @@ -389,6 +419,7 @@ public interface IScreeningOpenbisServiceFacade * is just the code of the feature. If for different data sets different sets of features are * available, provides the union of the feature names of all data sets. */ + @Retry public List<String> listAvailableFeatureCodes( List<? extends IFeatureVectorDatasetIdentifier> featureDatasets); @@ -398,6 +429,7 @@ public interface IScreeningOpenbisServiceFacade * sets of features are available, provide the union of the features of all data sets. Only * available when all data store services have minor version 9 or newer. */ + @Retry public List<FeatureInformation> listAvailableFeatures( List<? extends IFeatureVectorDatasetIdentifier> featureDatasets); @@ -411,6 +443,7 @@ public interface IScreeningOpenbisServiceFacade * @return The list of {@link FeatureVectorDataset}s, each element corresponds to one of the * <var>featureDatasets</var>. */ + @Retry public List<FeatureVectorDataset> loadFeaturesForPlates(List<? extends PlateIdentifier> plates, final List<String> featureCodesOrNull); @@ -426,6 +459,7 @@ public interface IScreeningOpenbisServiceFacade * @return The list of {@link FeatureVectorDataset}s, each element corresponds to one of the * <var>featureDatasets</var>. */ + @Retry public List<FeatureVectorDataset> loadFeaturesForPlates(List<? extends PlateIdentifier> plates, final List<String> featureCodesOrNull, String analysisProcedureOrNull); @@ -439,6 +473,7 @@ public interface IScreeningOpenbisServiceFacade * @return The list of {@link FeatureVectorDataset}s, each element corresponds to one of the * <var>featureDatasets</var>. */ + @Retry public List<FeatureVectorDataset> loadFeatures( List<FeatureVectorDatasetReference> featureDatasets, List<String> featureCodesOrNull); @@ -462,6 +497,7 @@ public interface IScreeningOpenbisServiceFacade * {@link FeatureVectorWithDescription#getDatasetWellReference()} to find the * corresponding dataset / well.</b> */ + @Retry public List<FeatureVectorWithDescription> loadFeaturesForDatasetWellReferences( List<FeatureVectorDatasetWellReference> datasetWellReferences, List<String> featureCodesOrNull); @@ -485,6 +521,7 @@ public interface IScreeningOpenbisServiceFacade * <var>materialIdentifier</var>. */ @Deprecated + @Retry public List<FeatureVectorWithDescription> loadFeaturesForPlateWells( ExperimentIdentifier experimentIdentifer, MaterialIdentifier materialIdentifier, List<String> featureCodesOrNull); @@ -508,6 +545,7 @@ public interface IScreeningOpenbisServiceFacade * <var>experimentIdentifer</var> and connected with the given * <var>materialIdentifier</var>. */ + @Retry public List<FeatureVectorWithDescription> loadFeaturesForPlateWells( ExperimentIdentifier experimentIdentifer, MaterialIdentifier materialIdentifier, String analysisProcedureOrNull, List<String> featureCodesOrNull); @@ -529,6 +567,7 @@ public interface IScreeningOpenbisServiceFacade * <var>materialIdentifier</var>. */ @Deprecated + @Retry public List<FeatureVectorWithDescription> loadFeaturesForPlateWells( MaterialIdentifier materialIdentifier, List<String> featureCodesOrNull); @@ -549,6 +588,7 @@ public interface IScreeningOpenbisServiceFacade * <var>experimentIdentifer</var> and connected with the given * <var>materialIdentifier</var>. */ + @Retry public List<FeatureVectorWithDescription> loadFeaturesForPlateWells( MaterialIdentifier materialIdentifier, String analysisProcedureOrNull, List<String> featureCodesOrNull); @@ -556,11 +596,13 @@ public interface IScreeningOpenbisServiceFacade /** * Converts the given <var>WellIdentifiers</var> to <var>WellPositions</var> */ + @Retry public List<WellPosition> convertToWellPositions(List<WellIdentifier> wellIds); /** * Returns the list of all plate image references for the given <var>imageDatasetRef</var>. */ + @Retry public List<PlateImageReference> createPlateImageReferences( ImageDatasetReference imageDatasetRef); @@ -573,6 +615,7 @@ public interface IScreeningOpenbisServiceFacade * @param wellsOrNull The wells to create image references for. If <code>null</code> or empty, * references for all wells will be created. */ + @Retry public List<PlateImageReference> createPlateImageReferences( ImageDatasetReference imageDatasetRef, List<String> channelCodesOrNull, List<WellPosition> wellsOrNull); @@ -588,6 +631,7 @@ public interface IScreeningOpenbisServiceFacade * @param wellsOrNull The wells to create image references for. If <code>null</code> or empty, * references for all wells will be created. */ + @Retry public List<PlateImageReference> createPlateImageReferences( ImageDatasetReference imageDatasetRef, ImageDatasetMetadata metadataOrNull, List<String> channelCodesOrNull, List<WellPosition> wellsOrNull); @@ -600,6 +644,7 @@ public interface IScreeningOpenbisServiceFacade * <code>null</code> or empty, references for all channels will be created. * @param wellsToUse The wells to create image references for. Must not be <code>null</code>. */ + @Retry public List<PlateImageReference> createPlateImageReferences( IImageDatasetIdentifier imageDatasetRef, List<String> channelCodesOrNull, List<WellPosition> wellsToUse); @@ -614,6 +659,7 @@ public interface IScreeningOpenbisServiceFacade * <code>null</code> or empty, references for all channels will be created. * @param wellsToUse The wells to create image references for. Must not be <code>null</code>. */ + @Retry public List<PlateImageReference> createPlateImageReferences( IImageDatasetIdentifier imageDatasetRef, ImageDatasetMetadata metadataOrNull, List<String> channelCodesOrNull, List<WellPosition> wellsToUse); @@ -667,6 +713,7 @@ public interface IScreeningOpenbisServiceFacade * * @return a list of byte arrays where each array contains a PNG encoded image. */ + @Retry public List<byte[]> loadImages(IDatasetIdentifier dataSetIdentifier, List<WellPosition> wellPositions, String channel, ImageSize thumbnailSizeOrNull) throws IOException; @@ -689,6 +736,7 @@ public interface IScreeningOpenbisServiceFacade * with same aspect ratio as the original image but which fits into specified size will be * delivered. */ + @Retry public byte[] loadImageWellCaching(final PlateImageReference imageReference, final ImageSize imageSizeOrNull) throws IOException; @@ -723,6 +771,7 @@ public interface IScreeningOpenbisServiceFacade * a time but eventually needs all images for a well and can increase performance of image * loading considerably. */ + @Retry public byte[] loadThumbnailImageWellCaching(final PlateImageReference imageReference) throws IOException; @@ -763,6 +812,7 @@ public interface IScreeningOpenbisServiceFacade * * @return <code>null</code> if such a factory has been defined yet. */ + @Retry public IImageTransformerFactory getImageTransformerFactoryOrNull( List<IDatasetIdentifier> dataSetIdentifiers, String channel); @@ -770,12 +820,14 @@ public interface IScreeningOpenbisServiceFacade * For a given image data set, provide meta like like which image channels have been acquired, * what is the tile geometry, the available (natural) image size(s) and the like. */ + @Retry public ImageDatasetMetadata listImageMetadata(IImageDatasetIdentifier imageDataset); /** * For a given set of image data sets, provide meta like like which image channels have been * acquired, what is the tile geometry, the available (natural) image size(s) and the like. */ + @Retry public List<ImageDatasetMetadata> listImageMetadata( List<? extends IImageDatasetIdentifier> imageDatasets); @@ -788,6 +840,7 @@ public interface IScreeningOpenbisServiceFacade * given type for the mapping. * @return A list of well to material mappings, one element for each plate. */ + @Retry public List<PlateWellMaterialMapping> listPlateMaterialMapping( List<? extends PlateIdentifier> plates, MaterialTypeIdentifier materialTypeIdentifierOrNull); @@ -796,11 +849,13 @@ public interface IScreeningOpenbisServiceFacade * Returns an alphabetically sorted list of analysis procedure codes of all data sets of the * specified experiment. */ + @Retry public List<String> listAnalysisProcedures(ExperimentIdentifier experimentIdentifier); /** * Returns aggregated metadata for all images/plates within one experiment. */ + @Retry public ExperimentImageMetadata getExperimentImageMetadata( ExperimentIdentifier experimentIdentifier); diff --git a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/ScreeningOpenbisServiceFacade.java b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/ScreeningOpenbisServiceFacade.java index 3d13170305b..1e78b28538d 100644 --- a/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/ScreeningOpenbisServiceFacade.java +++ b/screening/source/java/ch/systemsx/cisd/openbis/plugin/screening/client/api/v1/ScreeningOpenbisServiceFacade.java @@ -27,6 +27,8 @@ import ch.systemsx.cisd.common.api.client.ServiceFinder; import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException; import ch.systemsx.cisd.common.exceptions.UserFailureException; import ch.systemsx.cisd.common.io.ConcatenatedFileOutputStreamWriter; +import ch.systemsx.cisd.common.retry.RetryCaller; +import ch.systemsx.cisd.common.retry.RetryProxyFactory; import ch.systemsx.cisd.openbis.dss.client.api.v1.DssComponentFactory; import ch.systemsx.cisd.openbis.dss.client.api.v1.IDataSetDss; import ch.systemsx.cisd.openbis.dss.client.api.v1.IDssComponent; @@ -145,16 +147,27 @@ public class ScreeningOpenbisServiceFacade implements IScreeningOpenbisServiceFa * * @return null if the user could not be authenticated. */ - public static IScreeningOpenbisServiceFacade tryCreate(String userId, String userPassword, - String serverUrl) + public static IScreeningOpenbisServiceFacade tryCreate(final String userId, + final String userPassword, final String serverUrl) { - final IScreeningApiServer openbisServer = createScreeningOpenbisServer(serverUrl); - final String sessionToken = openbisServer.tryLoginScreening(userId, userPassword); - if (sessionToken == null) - { - return null; - } - return tryCreate(sessionToken, serverUrl, openbisServer); + RetryCaller<IScreeningOpenbisServiceFacade, RuntimeException> caller = + new RetryCaller<IScreeningOpenbisServiceFacade, RuntimeException>() + { + @Override + protected IScreeningOpenbisServiceFacade call() + { + final IScreeningApiServer openbisServer = + createScreeningOpenbisServer(serverUrl); + final String sessionToken = + openbisServer.tryLoginScreening(userId, userPassword); + if (sessionToken == null) + { + return null; + } + return tryCreate(sessionToken, serverUrl, openbisServer); + } + }; + return caller.callWithRetry(); } /** @@ -164,9 +177,20 @@ public class ScreeningOpenbisServiceFacade implements IScreeningOpenbisServiceFa * @param sessionToken The session token for the authenticated user * @param serverUrl The URL for the openBIS application server */ - public static IScreeningOpenbisServiceFacade tryCreate(String sessionToken, String serverUrl) + public static IScreeningOpenbisServiceFacade tryCreate(final String sessionToken, + final String serverUrl) { - return tryCreate(sessionToken, serverUrl, createScreeningOpenbisServer(serverUrl)); + RetryCaller<IScreeningOpenbisServiceFacade, RuntimeException> caller = + new RetryCaller<IScreeningOpenbisServiceFacade, RuntimeException>() + { + @Override + protected IScreeningOpenbisServiceFacade call() + { + return tryCreate(sessionToken, serverUrl, + createScreeningOpenbisServer(serverUrl)); + } + }; + return caller.callWithRetry(); } private static IScreeningOpenbisServiceFacade tryCreate(String sessionToken, String serverUrl, @@ -179,9 +203,13 @@ public class ScreeningOpenbisServiceFacade implements IScreeningOpenbisServiceFa final int minorVersion = openbisServer.getMinorVersion(); final IDssComponent dssComponent = DssComponentFactory.tryCreate(sessionToken, serverUrl, SERVER_TIMEOUT_MILLIS); - return new ScreeningOpenbisServiceFacade(sessionToken, openbisServer, minorVersion, - DSS_SERVICE_FACTORY, dssComponent, generalInformationService, - generalInformationChangingService); + + IScreeningOpenbisServiceFacade facade = + new ScreeningOpenbisServiceFacade(sessionToken, openbisServer, minorVersion, + DSS_SERVICE_FACTORY, dssComponent, generalInformationService, + generalInformationChangingService); + + return RetryProxyFactory.createProxy(facade); } private static IScreeningApiServer createScreeningOpenbisServer(String serverUrl) @@ -531,7 +559,7 @@ public class ScreeningOpenbisServiceFacade implements IScreeningOpenbisServiceFa public IDataSetDss getDataSet(String dataSetCode) throws IllegalStateException, EnvironmentFailureException { - return dssComponent.getDataSet(dataSetCode); + return RetryProxyFactory.createProxy(dssComponent.getDataSet(dataSetCode)); } /** @@ -565,7 +593,8 @@ public class ScreeningOpenbisServiceFacade implements IScreeningOpenbisServiceFa { if (filter.pass(dataSet)) { - result.add(dssComponent.getDataSet(dataSet.getCode())); + IDataSetDss dataSetDss = dssComponent.getDataSet(dataSet.getCode()); + result.add(RetryProxyFactory.createProxy(dataSetDss)); } } return result; @@ -596,7 +625,7 @@ public class ScreeningOpenbisServiceFacade implements IScreeningOpenbisServiceFa new ch.systemsx.cisd.openbis.dss.client.api.v1.DataSet( openbisServiceFacade, dssComponent, dataSet, null); - result.add(fullDataset); + result.add(RetryProxyFactory.createProxy(fullDataset)); } } return result; @@ -618,7 +647,8 @@ public class ScreeningOpenbisServiceFacade implements IScreeningOpenbisServiceFa { if (filter.pass(dataSet)) { - result.add(dssComponent.getDataSet(dataSet.getCode())); + IDataSetDss dataSetDss = dssComponent.getDataSet(dataSet.getCode()); + result.add(RetryProxyFactory.createProxy(dataSetDss)); } } return result; @@ -655,7 +685,7 @@ public class ScreeningOpenbisServiceFacade implements IScreeningOpenbisServiceFa new ch.systemsx.cisd.openbis.dss.client.api.v1.DataSet( openbisServiceFacade, dssComponent, dataSet, null); - result.add(fullDataset); + result.add(RetryProxyFactory.createProxy(fullDataset)); } } return result; @@ -673,7 +703,7 @@ public class ScreeningOpenbisServiceFacade implements IScreeningOpenbisServiceFa ch.systemsx.cisd.openbis.dss.client.api.v1.DataSet fullDataset = new ch.systemsx.cisd.openbis.dss.client.api.v1.DataSet(openbisServiceFacade, dssComponent, dataSet, null); - result.add(fullDataset); + result.add(RetryProxyFactory.createProxy(fullDataset)); } return result; } @@ -734,6 +764,7 @@ public class ScreeningOpenbisServiceFacade implements IScreeningOpenbisServiceFa final NewDataSetMetadataDTO dataSetMetadata = (dataSetMetadataOrNull == null) ? new NewDataSetMetadataDTO() : dataSetMetadataOrNull; + return createDatasetDss(dataSetMetadata, dataSetFile, dataSetOwner); } @@ -745,7 +776,8 @@ public class ScreeningOpenbisServiceFacade implements IScreeningOpenbisServiceFa final List<FileInfoDssDTO> fileInfos = getFileInfosForPath(dataSetFile); final NewDataSetDTO newDataSet = new NewDataSetDTO(dataSetMetadata, dataSetOwner, dataSetFolderNameOrNull, fileInfos); - return dssComponent.putDataSet(newDataSet, dataSetFile); + IDataSetDss dataSetDss = dssComponent.putDataSet(newDataSet, dataSetFile); + return RetryProxyFactory.createProxy(dataSetDss); } private List<FileInfoDssDTO> getFileInfosForPath(File file) throws IOException -- GitLab