From bebfc40f767be832480928926115154ee743fbfe Mon Sep 17 00:00:00 2001
From: cramakri <cramakri>
Date: Thu, 21 Feb 2013 09:56:48 +0000
Subject: [PATCH] BIS-329 SP-500 : Fixed implementation that gets a session
 URL.

SVN: 28405
---
 .../dss/client/api/v1/IDataSetDss.java        | 23 ++++++++++
 .../dss/client/api/v1/impl/DataSetDss.java    | 20 ++++++++-
 .../dss/client/api/v1/impl/DssComponent.java  | 40 ++++++++++++++++--
 .../api/v1/DataStoreApiUrlUtilities.java      | 22 ++++++++++
 .../systemtests/DssComponentTest.java         | 42 +++++++++++++++++++
 5 files changed, 142 insertions(+), 5 deletions(-)

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 e76369099ea..31583e77257 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
@@ -59,6 +59,29 @@ public interface IDataSetDss
     public InputStream getFile(String path) throws IllegalArgumentException,
             InvalidSessionException;
 
+    /**
+     * Get a URL that will return the contents of a file contained in this data set. The URL will be
+     * valid for the lifetime of the session.
+     * 
+     * @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 String getSessionURLForFile(String path) throws IllegalArgumentException,
+            InvalidSessionException;
+
+    /**
+     * Get a URL that will return the contents of a file contained in this data set. The URL will be
+     * valid for specified time duration.
+     * 
+     * @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}.
+     * @param validityDurationInSeconds The number of seconds for which the URL is valid.
+     */
+    @Retry
+    public String getURLForFileWithTimeout(String path, long validityDurationInSeconds)
+            throws IllegalArgumentException, InvalidSessionException;
+
     /**
      * Returns a {@link File}, if possible, that directly references the contents of a data set in
      * the data store server. This is only possible if the file system used by the DSS is also
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/impl/DataSetDss.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/impl/DataSetDss.java
index ec6e95bce77..41d8f2f20a6 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/impl/DataSetDss.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/client/api/v1/impl/DataSetDss.java
@@ -22,6 +22,7 @@ import java.io.InputStream;
 import org.apache.commons.lang.builder.ToStringBuilder;
 import org.apache.commons.lang.builder.ToStringStyle;
 
+import ch.systemsx.cisd.common.api.retry.Retry;
 import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException;
 import ch.systemsx.cisd.common.exceptions.InvalidSessionException;
 import ch.systemsx.cisd.openbis.dss.client.api.v1.IDataSetDss;
@@ -91,7 +92,8 @@ public class DataSetDss implements IDataSetDss
     public File getLinkOrCopyOfContent(String overrideStoreRootPathOrNull, File downloadDir,
             String pathInDataSet) throws IllegalArgumentException, InvalidSessionException
     {
-        return parent.getLinkOrCopyOfContents(this, overrideStoreRootPathOrNull, downloadDir, pathInDataSet);
+        return parent.getLinkOrCopyOfContents(this, overrideStoreRootPathOrNull, downloadDir,
+                pathInDataSet);
     }
 
     public AuthenticatedState getParent()
@@ -111,4 +113,20 @@ public class DataSetDss implements IDataSetDss
         builder.append("code", code);
         return builder.toString();
     }
+
+    @Override
+    @Retry
+    public String getSessionURLForFile(String path) throws IllegalArgumentException,
+            InvalidSessionException
+    {
+        return parent.getSessionURLForFile(this, path);
+    }
+
+    @Override
+    @Retry
+    public String getURLForFileWithTimeout(String path, long validityDurationInSeconds)
+            throws IllegalArgumentException, InvalidSessionException
+    {
+        return parent.getURLForFileWithTimeout(this, path, validityDurationInSeconds);
+    }
 }
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 061a9411cf9..4e04a87c48b 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
@@ -605,8 +605,8 @@ 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 one file contained in this data
+     * set.
      */
     InputStream getFile(DataSetDss dataSet, String path) throws InvalidSessionException
     {
@@ -633,6 +633,38 @@ class AuthenticatedState extends AbstractDssComponentState
         }
     }
 
+    /**
+     * Package visible method that returns a URL valid for the duration of the session.
+     */
+    String getSessionURLForFile(DataSetDss dataSet, String path) throws InvalidSessionException
+    {
+        String baseDownloadUrl =
+                service.tryGetDataStoreBaseURL(getSessionToken(), dataSet.getCode());
+
+        StringBuilder sb = new StringBuilder();
+        sb.append(DataStoreApiUrlUtilities.getDownloadUrlFromDataStoreUrl(baseDownloadUrl));
+        sb.append("/");
+        sb.append(dataSet.getCode());
+        sb.append("/");
+        sb.append(path);
+        sb.append("?sessionID=");
+        sb.append(getSessionToken());
+        return sb.toString();
+    }
+
+    /**
+     * Package visible method that returns a URL valid for the specified duration.
+     */
+    String getURLForFileWithTimeout(DataSetDss dataSet, String path, long validityInSeconds)
+            throws InvalidSessionException
+    {
+        String url =
+                dataSet.getService().getDownloadUrlForFileForDataSetWithTimeout(getSessionToken(),
+                        dataSet.getCode(), path, validityInSeconds);
+
+        return url;
+    }
+
     /**
      * 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
@@ -642,7 +674,7 @@ class AuthenticatedState extends AbstractDssComponentState
             throws InvalidSessionException, EnvironmentFailureException
     {
         final String path = tryGetInternalPathInDataStore(dataSetDss, overrideStoreRootPathOrNull);
-        
+
         if (path == null)
         {
             return null;
@@ -677,7 +709,7 @@ class AuthenticatedState extends AbstractDssComponentState
         try
         {
             return dataSetDss.getService().getPathToDataSet(getSessionToken(),
-                            dataSetDss.getCode(), overrideStoreRootPathOrNull);
+                    dataSetDss.getCode(), overrideStoreRootPathOrNull);
         } catch (IllegalArgumentException e)
         {
             // We could not create a link, return null
diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/v1/DataStoreApiUrlUtilities.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/v1/DataStoreApiUrlUtilities.java
index c2ffa321974..bd9908e215f 100644
--- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/v1/DataStoreApiUrlUtilities.java
+++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/api/v1/DataStoreApiUrlUtilities.java
@@ -52,6 +52,28 @@ public class DataStoreApiUrlUtilities
         return datastoreUrl;
     }
 
+    /**
+     * Converts a data store server URL to a URL that can be used to download files.
+     */
+    public static String getDownloadUrlFromDataStoreUrl(String dataStoreUrl)
+    {
+        String downloadUrl = dataStoreUrl;
+
+        // The url objained form a DataStore object is the url of the server. Convert this to a
+        // download URL
+        if (downloadUrl.endsWith("/"))
+        {
+            downloadUrl = downloadUrl.substring(0, downloadUrl.length() - 1);
+        }
+
+        if (false == downloadUrl.endsWith(DATA_STORE_SERVER_WEB_APPLICATION_NAME))
+        {
+            downloadUrl = downloadUrl + "/" + DATA_STORE_SERVER_WEB_APPLICATION_NAME;
+        }
+
+        return downloadUrl;
+    }
+
     public static String getUrlForRpcService(String serviceUrlSuffix)
     {
         return "/" + DATA_STORE_SERVER_WEB_APPLICATION_NAME + serviceUrlSuffix;
diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/datastoreserver/systemtests/DssComponentTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/datastoreserver/systemtests/DssComponentTest.java
index 5470eceee81..e70cf7c8a82 100644
--- a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/datastoreserver/systemtests/DssComponentTest.java
+++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/datastoreserver/systemtests/DssComponentTest.java
@@ -19,8 +19,10 @@ package ch.systemsx.cisd.openbis.datastoreserver.systemtests;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileFilter;
+import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.net.URL;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -299,6 +301,46 @@ public class DssComponentTest extends SystemTestCase
                 files[6].toString());
     }
 
+    @Test(dependsOnMethods = "testPutDataSet")
+    public void testGetFileWithSessionURL() throws Exception
+    {
+        String code = latestDataSetInfo.getDataSetCode();
+
+        IDataSetDss ds = dss.getDataSet(code);
+
+        String topLevelFolder = "original/" + PUT_DATA_SET_NAME;
+        String path = topLevelFolder + "/data";
+        FileInfoDssDTO[] files = ds.listFiles(path, false);
+        Arrays.sort(files, FILE_INFO_COMPARATOR);
+        String url = ds.getSessionURLForFile(files[0].getPathInDataSet());
+
+        InputStream input = new URL(url).openStream();
+        File file = new File(workingDirectory, "output");
+        FileOutputStream output = new FileOutputStream(file);
+        IOUtils.copyLarge(input, output);
+        assertEquals(file.length(), files[0].getFileSize());
+    }
+
+    @Test(dependsOnMethods = "testPutDataSet")
+    public void testGetFileWithTimeLimitedURL() throws Exception
+    {
+        String code = latestDataSetInfo.getDataSetCode();
+
+        IDataSetDss ds = dss.getDataSet(code);
+
+        String topLevelFolder = "original/" + PUT_DATA_SET_NAME;
+        String path = topLevelFolder + "/data";
+        FileInfoDssDTO[] files = ds.listFiles(path, false);
+        Arrays.sort(files, FILE_INFO_COMPARATOR);
+        String url = ds.getURLForFileWithTimeout(files[0].getPathInDataSet(), 20);
+
+        InputStream input = new URL(url).openStream();
+        File file = new File(workingDirectory, "output");
+        FileOutputStream output = new FileOutputStream(file);
+        IOUtils.copyLarge(input, output);
+        assertEquals(file.length(), files[0].getFileSize());
+    }
+
     private static String fileInfoString(String startPath, String pathInListing, long length,
             String checksum)
     {
-- 
GitLab