From f45467675a2ec221a132556f73b2a10da6d98b70 Mon Sep 17 00:00:00 2001
From: pkupczyk <pkupczyk>
Date: Thu, 8 Aug 2013 15:01:06 +0000
Subject: [PATCH] SP-789 / BIS-503 : SOB-125 exception logged when calling load
 data sets.

SVN: 29614
---
 .../dss/client/api/v1/impl/DssComponent.java  |  58 ++++-----
 .../server/api/v1/DssServiceRpcGeneric.java   |  44 ++++---
 .../api/v1/DssServiceRpcGenericLogger.java    |  13 +-
 .../shared/api/v1/IDssServiceRpcGeneric.java  | 111 ++++++++++--------
 .../client/api/v1/impl/DssComponentTest.java  |  20 +++-
 5 files changed, 147 insertions(+), 99 deletions(-)

diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/impl/DssComponent.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/impl/DssComponent.java
index 4e04a87c48b..ba5c63bb2d1 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/impl/DssComponent.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/impl/DssComponent.java
@@ -63,11 +63,10 @@ import ch.systemsx.cisd.openbis.dss.generic.shared.api.v1.validation.ValidationS
 import ch.systemsx.cisd.openbis.generic.shared.api.v1.IGeneralInformationService;
 
 /**
- * Implementation of the IDssComponent interface. It is a facade for interacting with openBIS and
- * multiple DSS servers.
+ * Implementation of the IDssComponent interface. It is a facade for interacting with openBIS and multiple DSS servers.
  * <p>
- * The DssComponent manages a connection to openBIS (IETLLIMSService) as well as connections to data
- * store servers (IDssServiceRpc) to present a simplified interface to downloading datasets.
+ * The DssComponent manages a connection to openBIS (IETLLIMSService) as well as connections to data store servers (IDssServiceRpc) to present a
+ * simplified interface to downloading datasets.
  * 
  * @author Chandrasekhar Ramakrishnan
  */
@@ -103,8 +102,7 @@ public class DssComponent implements IDssComponent
     }
 
     /**
-     * Public factory method for creating a DssComponent for a user that has already been
-     * authenticated.
+     * Public factory method for creating a DssComponent for a user that has already been authenticated.
      * 
      * @param sessionToken The session token provided by authentication
      * @param openBISUrl The URL to openBIS
@@ -139,12 +137,11 @@ public class DssComponent implements IDssComponent
     /**
      * Create a DSS component that connects to the openBIS instance specified by the URL.
      * <p>
-     * The DSS component needs to connect to openBIS to find out which DSS manages a given data set.
-     * Once it has a connection to openBIS, it can figure out how to connect to DSS servers itself.
+     * The DSS component needs to connect to openBIS to find out which DSS manages a given data set. Once it has a connection to openBIS, it can
+     * figure out how to connect to DSS servers itself.
      * 
      * @param openBISURL The url to connect to openBIS
-     * @param sessionTokenOrNull A session token; If null is passed in, then login needs to be
-     *            called.
+     * @param sessionTokenOrNull A session token; If null is passed in, then login needs to be called.
      * @param timeoutInMillis a timeout for network operations
      */
     private DssComponent(String openBISURL, String sessionTokenOrNull, long timeoutInMillis)
@@ -158,8 +155,7 @@ public class DssComponent implements IDssComponent
      * 
      * @param service A proxy to the openBIS application server.
      * @param dssServiceFactory A proxy to the DSS server.
-     * @param sessionTokenOrNull A session token, if the user has already logged in, or null
-     *            otherwise.
+     * @param sessionTokenOrNull A session token, if the user has already logged in, or null otherwise.
      */
     public DssComponent(IGeneralInformationService service, IRpcServiceFactory dssServiceFactory,
             String sessionTokenOrNull)
@@ -206,8 +202,7 @@ public class DssComponent implements IDssComponent
      * Authenticates the <code>user</code> with given <code>password</code>.
      * 
      * @throws AuthorizationFailureException Thrown if the username / password do not authenticate.
-     * @throws EnvironmentFailureException Thrown in cases where it is not possible to connect to
-     *             the server.
+     * @throws EnvironmentFailureException Thrown in cases where it is not possible to connect to the server.
      */
     void login(String user, String password) throws AuthorizationFailureException,
             EnvironmentFailureException
@@ -277,8 +272,7 @@ public class DssComponent implements IDssComponent
 /**
  * Superclass for component states, which make the state machine of the DSS component explicit.
  * <p>
- * By default, all methods just throw an exception. Subclasses should override the methods they
- * accept.
+ * By default, all methods just throw an exception. Subclasses should override the methods they accept.
  * 
  * @author Chandrasekhar Ramakrishnan
  */
@@ -360,8 +354,7 @@ abstract class AbstractDssComponentState implements IDssComponent
      * Authenticates the <code>user</code> with given <code>password</code>.
      * 
      * @throws AuthorizationFailureException Thrown if the username / password do not authenticate.
-     * @throws EnvironmentFailureException Thrown in cases where it is not possible to connect to
-     *             the server.
+     * @throws EnvironmentFailureException Thrown in cases where it is not possible to connect to the server.
      */
     abstract void login(final String user, final String password)
             throws AuthorizationFailureException, EnvironmentFailureException;
@@ -374,8 +367,8 @@ abstract class AbstractDssComponentState implements IDssComponent
 }
 
 /**
- * An object representing an unauthenticated state. Being in this state implies that the user has
- * not yet logged in. Only login and logout are allowed in this state.
+ * An object representing an unauthenticated state. Being in this state implies that the user has not yet logged in. Only login and logout are allowed
+ * in this state.
  * 
  * @author Chandrasekhar Ramakrishnan
  */
@@ -420,8 +413,8 @@ class UnauthenticatedState extends AbstractDssComponentState
 }
 
 /**
- * An object representing an authenticated state. Being in this state means that the user has logged
- * in and all operations are available, except login.
+ * An object representing an authenticated state. Being in this state means that the user has logged in and all operations are available, except
+ * login.
  * 
  * @author Chandrasekhar Ramakrishnan
  */
@@ -594,8 +587,7 @@ class AuthenticatedState extends AbstractDssComponentState
     }
 
     /**
-     * Package visible method to communicate with the server and get a list of files contained in
-     * this data set.
+     * Package visible method to communicate with the server and get a list of files contained in this data set.
      */
     FileInfoDssDTO[] listFiles(DataSetDss dataSetDss, String startPath, boolean isRecursive)
             throws InvalidSessionException
@@ -605,8 +597,7 @@ class AuthenticatedState extends AbstractDssComponentState
     }
 
     /**
-     * Package visible method to communicate with the server and get one file contained in this data
-     * set.
+     * Package visible method to communicate with the server and get one file contained in this data set.
      */
     InputStream getFile(DataSetDss dataSet, String path) throws InvalidSessionException
     {
@@ -666,9 +657,8 @@ class AuthenticatedState extends AbstractDssComponentState
     }
 
     /**
-     * Package visible method to communicate with the server and get a link to the file in the DSS.
-     * Returns null if link couldn't be retrieved (e.g. when the <var>dataSetDss</var> is a
-     * container).
+     * Package visible method to communicate with the server and get a link to the file in the DSS. Returns null if link couldn't be retrieved (e.g.
+     * when the <var>dataSetDss</var> is a container).
      */
     File tryLinkToContents(DataSetDss dataSetDss, String overrideStoreRootPathOrNull)
             throws InvalidSessionException, EnvironmentFailureException
@@ -693,9 +683,8 @@ class AuthenticatedState extends AbstractDssComponentState
     }
 
     /**
-     * Package visible method to communicate with the server and get a link to the file in the DSS.
-     * Returns null if link couldn't be retrieved (e.g. when the <var>dataSetDss</var> is a
-     * container).
+     * Package visible method to communicate with the server and get a link to the file in the DSS. Returns null if link couldn't be retrieved (e.g.
+     * when the <var>dataSetDss</var> is a container).
      */
     String tryGetInternalPathInDataStore(DataSetDss dataSetDss, String overrideStoreRootPathOrNull)
             throws InvalidSessionException, EnvironmentFailureException
@@ -708,7 +697,7 @@ class AuthenticatedState extends AbstractDssComponentState
 
         try
         {
-            return dataSetDss.getService().getPathToDataSet(getSessionToken(),
+            return dataSetDss.getService().tryGetPathToDataSet(getSessionToken(),
                     dataSetDss.getCode(), overrideStoreRootPathOrNull);
         } catch (IllegalArgumentException e)
         {
@@ -718,8 +707,7 @@ class AuthenticatedState extends AbstractDssComponentState
     }
 
     /**
-     * Package visible method to get a link to the contents of the data set in DSS', if possible,
-     * otherwise copy the contents locally.
+     * Package visible method to get a link to the contents of the data set in DSS', if possible, otherwise copy the contents locally.
      */
     File getLinkOrCopyOfContents(DataSetDss dataSetDss, String overrideStoreRootPathOrNull,
             File downloadDir, String pathInDataSetOrNull) throws InvalidSessionException
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/api/v1/DssServiceRpcGeneric.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/api/v1/DssServiceRpcGeneric.java
index 5636ed4d4dc..e7833e54ce0 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/api/v1/DssServiceRpcGeneric.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/api/v1/DssServiceRpcGeneric.java
@@ -87,8 +87,7 @@ public class DssServiceRpcGeneric extends AbstractDssServiceRpc<IDssServiceRpcGe
         implements IDssServiceRpcGenericInternal
 {
     /**
-     * Logger with {@link LogCategory#OPERATION} with name of the concrete class, needs to be static
-     * for our purpose.
+     * Logger with {@link LogCategory#OPERATION} with name of the concrete class, needs to be static for our purpose.
      */
     @SuppressWarnings("hiding")
     protected static Logger operationLog = LogFactory.getLogger(LogCategory.OPERATION,
@@ -349,18 +348,15 @@ public class DssServiceRpcGeneric extends AbstractDssServiceRpc<IDssServiceRpcGe
     @Override
     public int getMinorVersion()
     {
-        return 7;
+        return 8;
     }
 
     /**
-     * Append file info for the requested node of a file or file hierarchy. Assumes that the
-     * parameters have been verified already.
+     * Append file info for the requested node of a file or file hierarchy. Assumes that the parameters have been verified already.
      * 
      * @param requestedFile A file known to be accessible by the user
-     * @param dataSetRoot The root of the file hierarchy; used to determine the absolute path of the
-     *            file
-     * @param listingRootNode The node which is a root of the list hierarchy; used to determine the
-     *            relative path of the file
+     * @param dataSetRoot The root of the file hierarchy; used to determine the absolute path of the file
+     * @param listingRootNode The node which is a root of the list hierarchy; used to determine the relative path of the file
      * @param list The list the files infos are appended to
      * @param isRecursive If true, directories will be recursively appended to the list
      */
@@ -418,19 +414,39 @@ public class DssServiceRpcGeneric extends AbstractDssServiceRpc<IDssServiceRpcGe
             String overrideStoreRootPathOrNull) throws IOExceptionUnchecked,
             IllegalArgumentException
     {
-        final File dataSetRootDirectory =
-                DatasetLocationUtil.getDatasetLocationPath(getStoreDirectory(), dataSetCode,
-                        getShareIdManager().getShareId(dataSetCode), getHomeDatabaseInstance()
-                                .getUuid());
-        // see NOTE in interface documentation
+        final File dataSetRootDirectory = tryGetDataSetRootDirectory(dataSetCode);
+
+        // if container data set - see NOTE in interface documentation
         if (dataSetRootDirectory.exists() == false)
         {
             throw new IllegalArgumentException("Path to dataset '" + dataSetCode
                     + "' not available: this is a container dataset.");
         }
+
         return convertPath(getStoreDirectory(), dataSetRootDirectory, overrideStoreRootPathOrNull);
     }
 
+    @Override
+    public String tryGetPathToDataSet(String sessionToken, String dataSetCode, String overrideStoreRootPathOrNull) throws IOExceptionUnchecked
+    {
+        final File dataSetRootDirectory = tryGetDataSetRootDirectory(dataSetCode);
+
+        // if container data set - see NOTE in interface documentation
+        if (dataSetRootDirectory.exists() == false)
+        {
+            return null;
+        }
+
+        return convertPath(getStoreDirectory(), dataSetRootDirectory, overrideStoreRootPathOrNull);
+    }
+
+    private File tryGetDataSetRootDirectory(String dataSetCode)
+    {
+        return DatasetLocationUtil.getDatasetLocationPath(getStoreDirectory(), dataSetCode,
+                getShareIdManager().getShareId(dataSetCode), getHomeDatabaseInstance()
+                        .getUuid());
+    }
+
     @Override
     public List<ShareInfo> listAllShares(String sessionToken)
     {
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/api/v1/DssServiceRpcGenericLogger.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/api/v1/DssServiceRpcGenericLogger.java
index e3a27c4f221..fffe480f9f2 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/api/v1/DssServiceRpcGenericLogger.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/server/api/v1/DssServiceRpcGenericLogger.java
@@ -162,6 +162,16 @@ public class DssServiceRpcGenericLogger extends AbstractServerLogger implements
         return null;
     }
 
+    @Override
+    public String tryGetPathToDataSet(String sessionToken, String dataSetCode,
+            String overrideStoreRootPathOrNull) throws IOExceptionUnchecked,
+            IllegalArgumentException
+    {
+        logAccess(sessionToken, "try_get_path_to_data_set", "DATA_SET(%s) STORE_ROOT_PATH(%s)",
+                dataSetCode, overrideStoreRootPathOrNull);
+        return null;
+    }
+
     @Override
     public List<ShareInfo> listAllShares(String sessionToken)
     {
@@ -238,7 +248,8 @@ public class DssServiceRpcGenericLogger extends AbstractServerLogger implements
     @DataSetAccessGuard
     public String getDownloadUrlForFileForDataSetWithTimeout(
             String sessionToken,
-            @AuthorizationGuard(guardClass = DataSetFileDTOPredicate.class) DataSetFileDTO fileOrFolder,
+            @AuthorizationGuard(guardClass = DataSetFileDTOPredicate.class)
+            DataSetFileDTO fileOrFolder,
             long validityDurationInSeconds) throws IOExceptionUnchecked, IllegalArgumentException
     {
         logAccess(sessionToken, "get_download_url_for_file_for_data_set",
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/v1/IDssServiceRpcGeneric.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/v1/IDssServiceRpcGeneric.java
index 4563c1e5302..308ac0d1b22 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/v1/IDssServiceRpcGeneric.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/v1/IDssServiceRpcGeneric.java
@@ -53,7 +53,8 @@ public interface IDssServiceRpcGeneric extends IRpcService
     @DataSetAccessGuard
     public FileInfoDssDTO[] listFilesForDataSet(
             String sessionToken,
-            @AuthorizationGuard(guardClass = DataSetFileDTOPredicate.class) DataSetFileDTO fileOrFolder)
+            @AuthorizationGuard(guardClass = DataSetFileDTOPredicate.class)
+            DataSetFileDTO fileOrFolder)
             throws IOExceptionUnchecked, IllegalArgumentException;
 
     /**
@@ -69,7 +70,8 @@ public interface IDssServiceRpcGeneric extends IRpcService
     @Deprecated
     public InputStream getFileForDataSet(
             String sessionToken,
-            @AuthorizationGuard(guardClass = DataSetFileDTOPredicate.class) DataSetFileDTO fileOrFolder)
+            @AuthorizationGuard(guardClass = DataSetFileDTOPredicate.class)
+            DataSetFileDTO fileOrFolder)
             throws IOExceptionUnchecked, IllegalArgumentException;
 
     /**
@@ -84,19 +86,18 @@ public interface IDssServiceRpcGeneric extends IRpcService
     @DataSetAccessGuard
     public String getDownloadUrlForFileForDataSet(
             String sessionToken,
-            @AuthorizationGuard(guardClass = DataSetFileDTOPredicate.class) DataSetFileDTO fileOrFolder)
+            @AuthorizationGuard(guardClass = DataSetFileDTOPredicate.class)
+            DataSetFileDTO fileOrFolder)
             throws IOExceptionUnchecked, IllegalArgumentException;
 
     /**
-     * Returns an URL from which the requested file. The URL is valid for a caller-specified amount
-     * of time.
+     * Returns an URL from which the requested file. The URL is valid for a caller-specified amount of time.
      * 
      * @param sessionToken The session token
      * @param fileOrFolder The file or folder to retrieve
-     * @param validityDurationInSeconds The number of seconds for which the download URL should be
-     *            valid. The validity is clipped to the durations defined in the properties
-     *            <i>data-stream-timeout</i> and <i>data-stream-max-timeout</i>, which default
-     *            to 5 seconds and 4 hours, respectively.
+     * @param validityDurationInSeconds The number of seconds for which the download URL should be valid. The validity is clipped to the durations
+     *            defined in the properties <i>data-stream-timeout</i> and <i>data-stream-max-timeout</i>, which default to 5 seconds and 4 hours,
+     *            respectively.
      * @throws IOExceptionUnchecked Thrown if an IOException occurs when listing the files
      * @throws IllegalArgumentException Thrown if the dataSetCode or startPath are not valid
      * @since 1.7
@@ -104,7 +105,8 @@ public interface IDssServiceRpcGeneric extends IRpcService
     @DataSetAccessGuard
     public String getDownloadUrlForFileForDataSetWithTimeout(
             String sessionToken,
-            @AuthorizationGuard(guardClass = DataSetFileDTOPredicate.class) DataSetFileDTO fileOrFolder,
+            @AuthorizationGuard(guardClass = DataSetFileDTOPredicate.class)
+            DataSetFileDTO fileOrFolder,
             long validityDurationInSeconds) throws IOExceptionUnchecked, IllegalArgumentException;
 
     /**
@@ -119,7 +121,8 @@ public interface IDssServiceRpcGeneric extends IRpcService
      */
     @DataSetAccessGuard
     public FileInfoDssDTO[] listFilesForDataSet(String sessionToken,
-            @AuthorizationGuard(guardClass = DataSetCodeStringPredicate.class) String dataSetCode,
+            @AuthorizationGuard(guardClass = DataSetCodeStringPredicate.class)
+            String dataSetCode,
             String path, boolean isRecursive) throws IOExceptionUnchecked, IllegalArgumentException;
 
     /**
@@ -135,12 +138,12 @@ public interface IDssServiceRpcGeneric extends IRpcService
     @DataSetAccessGuard
     @Deprecated
     public InputStream getFileForDataSet(String sessionToken,
-            @AuthorizationGuard(guardClass = DataSetCodeStringPredicate.class) String dataSetCode,
+            @AuthorizationGuard(guardClass = DataSetCodeStringPredicate.class)
+            String dataSetCode,
             String path) throws IOExceptionUnchecked, IllegalArgumentException;
 
     /**
-     * Returns an URL from which the requested file of the specified data set can be downloaded. The
-     * URL is valid only for a short time.
+     * Returns an URL from which the requested file of the specified data set can be downloaded. The URL is valid only for a short time.
      * 
      * @param sessionToken The session token
      * @param dataSetCode The data set to retrieve file from
@@ -151,25 +154,26 @@ public interface IDssServiceRpcGeneric extends IRpcService
      */
     @DataSetAccessGuard
     public String getDownloadUrlForFileForDataSet(String sessionToken,
-            @AuthorizationGuard(guardClass = DataSetCodeStringPredicate.class) String dataSetCode,
+            @AuthorizationGuard(guardClass = DataSetCodeStringPredicate.class)
+            String dataSetCode,
             String path) throws IOExceptionUnchecked, IllegalArgumentException;
 
     /**
-     * Returns an URL from which the requested file of the specified data set can be downloaded. The
-     * URL is valid for a caller-specified amount of time.
+     * Returns an URL from which the requested file of the specified data set can be downloaded. The URL is valid for a caller-specified amount of
+     * time.
      * 
      * @param sessionToken The session token
      * @param dataSetCode The data set to retrieve file from
      * @param path The path within the data set to retrieve file information about
-     * @param validityDurationInSeconds The number of seconds for which the download URL should be
-     *            valid.
+     * @param validityDurationInSeconds The number of seconds for which the download URL should be valid.
      * @throws IOExceptionUnchecked Thrown if an IOException occurs when listing the files
      * @throws IllegalArgumentException Thrown if the dataSetCode or startPath are not valid
      * @since 1.7
      */
     @DataSetAccessGuard
     public String getDownloadUrlForFileForDataSetWithTimeout(String sessionToken,
-            @AuthorizationGuard(guardClass = DataSetCodeStringPredicate.class) String dataSetCode,
+            @AuthorizationGuard(guardClass = DataSetCodeStringPredicate.class)
+            String dataSetCode,
             String path, long validityDurationInSeconds) throws IOExceptionUnchecked,
             IllegalArgumentException;
 
@@ -185,7 +189,8 @@ public interface IDssServiceRpcGeneric extends IRpcService
      */
     @DataSetAccessGuard
     public String putDataSet(String sessionToken,
-            @AuthorizationGuard(guardClass = NewDataSetPredicate.class) NewDataSetDTO newDataset,
+            @AuthorizationGuard(guardClass = NewDataSetPredicate.class)
+            NewDataSetDTO newDataset,
             InputStream inputStream) throws IOExceptionUnchecked, IllegalArgumentException;
 
     /**
@@ -201,8 +206,7 @@ public interface IDssServiceRpcGeneric extends IRpcService
             InputStream inputStream) throws IOExceptionUnchecked;
 
     /**
-     * Upload a file slice to the user's session workspace. If the file does not exist then it will
-     * created.
+     * Upload a file slice to the user's session workspace. If the file does not exist then it will created.
      * 
      * @param sessionToken The session token.
      * @param filePath The file path (including the sub-directory) to upload the slice to.
@@ -233,41 +237,61 @@ public interface IDssServiceRpcGeneric extends IRpcService
     public boolean deleteSessionWorkspaceFile(String sessionToken, String path);
 
     /**
-     * Get a path to the data set. This can be used by clients that run on the same machine as the
-     * DSS for more efficient access to a data set.
+     * Get a path to the data set. This can be used by clients that run on the same machine as the DSS for more efficient access to a data set.
      * <p>
-     * NOTE: This method shouldn't be called for a container data set. No file would exist with the
-     * returned path.
+     * NOTE: This method shouldn't be called for a container data set. No file would exist with the returned path.
+     * </p>
      * 
      * @param sessionToken The session token
      * @param dataSetCode The data set to retrieve file from
      * @param overrideStoreRootPathOrNull The path to replace the store path (see return comment).
-     * @return An absolute path to the data set. If overrideStorePathOrNull is specified, it
-     *         replaces the DSS's notion of the store path. Otherwise the return value will begin
-     *         with the DSS's storeRootPath.
+     * @return An absolute path to the data set. If overrideStorePathOrNull is specified, it replaces the DSS's notion of the store path. Otherwise
+     *         the return value will begin with the DSS's storeRootPath.
      * @throws IOExceptionUnchecked if an IOException occurs when listing the files.
      * @throws IllegalArgumentException if <var>dataSetCode</var> is a container dataset.
+     * @see IDssServiceRpcGeneric#tryGetPathToDataSet(String, String, String)
      * @since 1.1
      */
     @DataSetAccessGuard(releaseDataSetLocks = false)
     public String getPathToDataSet(String sessionToken,
-            @AuthorizationGuard(guardClass = DataSetCodeStringPredicate.class) String dataSetCode,
+            @AuthorizationGuard(guardClass = DataSetCodeStringPredicate.class)
+            String dataSetCode,
             String overrideStoreRootPathOrNull) throws IOExceptionUnchecked,
             IllegalArgumentException;
-    
+
+    /**
+     * Get a path to the data set. This can be used by clients that run on the same machine as the DSS for more efficient access to a data set.
+     * <p>
+     * NOTE: This method returns null for a container data set.
+     * </p>
+     * 
+     * @param sessionToken The session token
+     * @param dataSetCode The data set to retrieve file from
+     * @param overrideStoreRootPathOrNull The path to replace the store path (see return comment).
+     * @return An absolute path to the data set. If overrideStorePathOrNull is specified, it replaces the DSS's notion of the store path. Otherwise
+     *         the return value will begin with the DSS's storeRootPath. For a container data set returns null.
+     * @throws IOExceptionUnchecked if an IOException occurs when listing the files.
+     * @see IDssServiceRpcGeneric#getPathToDataSet(String, String, String)
+     * @since 1.8
+     */
+    @DataSetAccessGuard(releaseDataSetLocks = false)
+    public String tryGetPathToDataSet(String sessionToken,
+            @AuthorizationGuard(guardClass = DataSetCodeStringPredicate.class)
+            String dataSetCode,
+            String overrideStoreRootPathOrNull) throws IOExceptionUnchecked;
+
     /**
-     * Lists all shares. 
+     * Lists all shares.
      * 
      * @since 1.7
      */
     @DataSetAccessGuard(privilegeLevel = PrivilegeLevel.INSTANCE_ADMIN)
     public List<ShareInfo> listAllShares(String sessionToken);
-    
+
     /**
      * Moves specified data set to specified share.
      * 
-     * @throws IllegalArgumentException if data set does not exit or is a container data set or
-     *             share does not exist.
+     * @throws IllegalArgumentException if data set does not exit or is a container data set or share does not exist.
      * @since 1.7
      */
     @DataSetAccessGuard(privilegeLevel = PrivilegeLevel.INSTANCE_ADMIN)
@@ -279,10 +303,8 @@ public interface IDssServiceRpcGeneric extends IRpcService
      * Get the validation script for the specified data set type.
      * 
      * @param sessionToken The session token
-     * @param dataSetTypeOrNull The data set type the script should validate, or null to request the
-     *            generic validation script.
-     * @return The string of the python (jython) script for the validation or null if there is no
-     *         applicable validation script.
+     * @param dataSetTypeOrNull The data set type the script should validate, or null to request the generic validation script.
+     * @return The string of the python (jython) script for the validation or null if there is no applicable validation script.
      * @throws IOExceptionUnchecked Thrown if an IOException occurs when accessing the script
      * @throws IllegalArgumentException Thrown if the data set type or startPath are not valid
      * @since 1.2
@@ -291,8 +313,7 @@ public interface IDssServiceRpcGeneric extends IRpcService
             throws IOExceptionUnchecked, IllegalArgumentException;
 
     /**
-     * Returns metadata for all aggregation services. See
-     * {@link IQueryApiServer#listAggregationServices(String)}
+     * Returns metadata for all aggregation services. See {@link IQueryApiServer#listAggregationServices(String)}
      * 
      * @since 1.6
      */
@@ -308,16 +329,14 @@ public interface IDssServiceRpcGeneric extends IRpcService
             String aggregationServiceName, Map<String, Object> parameters);
 
     /**
-     * Returns meta data for all reporting plugins which deliver a table. See
-     * {@link IQueryApiServer#listTableReportDescriptions(String)}
+     * Returns meta data for all reporting plugins which deliver a table. See {@link IQueryApiServer#listTableReportDescriptions(String)}
      * 
      * @since 1.6
      */
     public List<ReportDescription> listTableReportDescriptions(String sessionToken);
 
     /**
-     * Creates for the specified data sets a report. See
-     * {@link IQueryApiServer#createReportFromDataSets(String, String, String, List)}
+     * Creates for the specified data sets a report. See {@link IQueryApiServer#createReportFromDataSets(String, String, String, List)}
      * 
      * @since 1.6
      */
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/client/api/v1/impl/DssComponentTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/client/api/v1/impl/DssComponentTest.java
index d97bce606a6..ec7278d9a1b 100644
--- a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/client/api/v1/impl/DssComponentTest.java
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/client/api/v1/impl/DssComponentTest.java
@@ -132,11 +132,12 @@ public class DssComponentTest extends AbstractFileSystemTestCase
                 //
                 @Override
                 protected final Object[] getAdvicesAndAdvisorsForBean(
-                        @SuppressWarnings("rawtypes") final Class beanClass, final String beanName,
+                        @SuppressWarnings("rawtypes")
+                        final Class beanClass, final String beanName,
                         final TargetSource customTargetSource) throws BeansException
                 {
                     return new Object[]
-                        { advisor };
+                    { advisor };
                 }
             };
         final Object proxy =
@@ -666,6 +667,12 @@ public class DssComponentTest extends AbstractFileSystemTestCase
             throw new IllegalArgumentException("Unimplemented in v1.0");
         }
 
+        @Override
+        public String tryGetPathToDataSet(String sessionToken, String dataSetCode, String overrideStoreRootPathOrNull) throws IOExceptionUnchecked
+        {
+            return getPathToDataSet(sessionToken, dataSetCode, overrideStoreRootPathOrNull);
+        }
+
         @Override
         public List<ShareInfo> listAllShares(String sessionToken)
         {
@@ -741,7 +748,8 @@ public class DssComponentTest extends AbstractFileSystemTestCase
         @DataSetAccessGuard
         public String getDownloadUrlForFileForDataSetWithTimeout(
                 String sessionToken,
-                @AuthorizationGuard(guardClass = DataSetFileDTOPredicate.class) DataSetFileDTO fileOrFolder,
+                @AuthorizationGuard(guardClass = DataSetFileDTOPredicate.class)
+                DataSetFileDTO fileOrFolder,
                 long validityDurationInSeconds) throws IOExceptionUnchecked,
                 IllegalArgumentException
         {
@@ -777,6 +785,12 @@ public class DssComponentTest extends AbstractFileSystemTestCase
                     overrideStoreRootPathOrNull);
         }
 
+        @Override
+        public String tryGetPathToDataSet(String sessionToken, String dataSetCode, String overrideStoreRootPathOrNull) throws IOExceptionUnchecked
+        {
+            return getPathToDataSet(sessionToken, dataSetCode, overrideStoreRootPathOrNull);
+        }
+
     }
 
     private class MockDssServiceRpcV1_2 extends MockDssServiceRpcV1_1
-- 
GitLab