From bdbde4d9ae9ed0850f689681e30972f2c899a5a9 Mon Sep 17 00:00:00 2001
From: pkupczyk <piotr.kupczyk@id.ethz.ch>
Date: Sun, 27 May 2018 11:46:28 +0200
Subject: [PATCH] SSDM-6207 : V3 AS API Batch Imports - UploadServiceServlet
 Refactoring - make the upload servlet work only with a valid openBIS session
 and always use the new session workspace mechanism

---
 .../systemtest/api/v3/UploadServletTest.java  | 261 +++++++++++-------
 .../web/server/UploadServiceServlet.java      |  25 +-
 .../client/web/server/UploadedFilesBean.java  |  22 +-
 .../web/server/UploadServiceServletTest.java  |  24 +-
 .../web/server/GenericClientServiceTest.java  |  79 ++++--
 .../systemtest/AttachmentUploadTest.java      |   6 +-
 ...atchMaterialRegistrationAndUpdateTest.java |  27 +-
 .../systemtest/CodeGenerationTest.java        |   2 +-
 .../systemtest/PersistentSystemTestCase.java  |  13 -
 .../openbis/systemtest/SystemTestCase.java    |  10 +-
 ...GeneralInformationChangingServiceTest.java |   6 +-
 .../generic/ExperimentRegistrationTest.java   |  84 +++---
 .../plugin/generic/GenericSystemTestCase.java |   8 +-
 13 files changed, 332 insertions(+), 235 deletions(-)

diff --git a/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/UploadServletTest.java b/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/UploadServletTest.java
index d81b844f018..0c090af2f63 100644
--- a/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/UploadServletTest.java
+++ b/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/UploadServletTest.java
@@ -29,6 +29,7 @@ import org.eclipse.jetty.client.api.Request;
 import org.eclipse.jetty.client.util.MultiPartContentProvider;
 import org.eclipse.jetty.client.util.StringContentProvider;
 import org.eclipse.jetty.http.HttpMethod;
+import org.testng.annotations.AfterMethod;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.DataProvider;
@@ -69,32 +70,37 @@ public class UploadServletTest extends SystemTestCase
     }
 
     @BeforeMethod
-    private void beforeMethod()
+    private void beforeMethod() throws Exception
     {
         JettyHttpClientFactory.getHttpClient().getCookieStore().removeAll();
+        cleanOSTempFolder();
+    }
+
+    @AfterMethod
+    private void afterMethod() throws Exception
+    {
+        assertOSTempFolderFiles();
     }
 
     @Test(dataProvider = FALSE_TRUE_PROVIDER)
-    public void testUploadSingleFile(boolean withSessionToken) throws Exception
+    public void testUploadSingleFile(boolean withSessionTokenParam) throws Exception
     {
         String sessionToken = as.login(USER, PASSWORD);
 
-        if (withSessionToken)
-        {
-            cleanSessionWorkspace(sessionToken);
-        } else
+        if (false == withSessionTokenParam)
         {
             initHttpSession(sessionToken);
-            cleanOSTempFolder();
         }
 
+        cleanSessionWorkspace(sessionToken);
+
         MultiPartContentProvider multipart = new MultiPartContentProvider();
         multipart.addFilePart("testFieldName", "testFileName", new StringContentProvider("testContent"), null);
         multipart.close();
 
         HttpClient client = JettyHttpClientFactory.getHttpClient();
         Request request = client.newRequest(SERVICE_URL).method(HttpMethod.POST);
-        if (withSessionToken)
+        if (withSessionTokenParam)
         {
             request.param(PARAM_SESSION_ID, sessionToken);
         }
@@ -104,29 +110,21 @@ public class UploadServletTest extends SystemTestCase
 
         request.send();
 
-        if (withSessionToken)
-        {
-            assertSessionWorkspaceFiles(sessionToken, "testContent");
-        } else
-        {
-            assertOSTempFolderFiles("testContent");
-        }
+        assertSessionWorkspaceFiles(sessionToken, "testContent");
     }
 
     @Test(dataProvider = FALSE_TRUE_PROVIDER)
-    public void testUploadMultipleFilesUnderOneSessionKey(boolean withSessionToken) throws Exception
+    public void testUploadMultipleFilesUnderOneSessionKey(boolean withSessionTokenParam) throws Exception
     {
         String sessionToken = as.login(USER, PASSWORD);
 
-        if (withSessionToken)
-        {
-            cleanSessionWorkspace(sessionToken);
-        } else
+        if (false == withSessionTokenParam)
         {
             initHttpSession(sessionToken);
-            cleanOSTempFolder();
         }
 
+        cleanSessionWorkspace(sessionToken);
+
         MultiPartContentProvider multipart = new MultiPartContentProvider();
         multipart.addFilePart("testFieldName1", "testFileName1", new StringContentProvider("testContent1"), null);
         multipart.addFilePart("testFieldName2", "testFileName2", new StringContentProvider("testContent2"), null);
@@ -134,7 +132,7 @@ public class UploadServletTest extends SystemTestCase
 
         HttpClient client = JettyHttpClientFactory.getHttpClient();
         Request request = client.newRequest(SERVICE_URL).method(HttpMethod.POST);
-        if (withSessionToken)
+        if (withSessionTokenParam)
         {
             request.param(PARAM_SESSION_ID, sessionToken);
         }
@@ -144,29 +142,21 @@ public class UploadServletTest extends SystemTestCase
 
         request.send();
 
-        if (withSessionToken)
-        {
-            assertSessionWorkspaceFiles(sessionToken, "testContent1", "testContent2");
-        } else
-        {
-            assertOSTempFolderFiles("testContent1", "testContent2");
-        }
+        assertSessionWorkspaceFiles(sessionToken, "testContent1", "testContent2");
     }
 
     @Test(dataProvider = FALSE_TRUE_PROVIDER)
-    public void testUploadMultipleFilesUnderMultipleSessionKeys(boolean withSessionToken) throws Exception
+    public void testUploadMultipleFilesUnderMultipleSessionKeys(boolean withSessionTokenParam) throws Exception
     {
         String sessionToken = as.login(USER, PASSWORD);
 
-        if (withSessionToken)
-        {
-            cleanSessionWorkspace(sessionToken);
-        } else
+        if (false == withSessionTokenParam)
         {
             initHttpSession(sessionToken);
-            cleanOSTempFolder();
         }
 
+        cleanSessionWorkspace(sessionToken);
+
         MultiPartContentProvider multipart = new MultiPartContentProvider();
         multipart.addFilePart("testFieldName1", "testFileName1", new StringContentProvider("testContent1"), null);
         multipart.addFilePart("testFieldName2", "testFileName2", new StringContentProvider("testContent2"), null);
@@ -174,7 +164,7 @@ public class UploadServletTest extends SystemTestCase
 
         HttpClient client = JettyHttpClientFactory.getHttpClient();
         Request request = client.newRequest(SERVICE_URL).method(HttpMethod.POST);
-        if (withSessionToken)
+        if (withSessionTokenParam)
         {
             request.param(PARAM_SESSION_ID, sessionToken);
         }
@@ -185,83 +175,156 @@ public class UploadServletTest extends SystemTestCase
 
         request.send();
 
-        if (withSessionToken)
-        {
-            assertSessionWorkspaceFiles(sessionToken, "testContent1", "testContent2");
-        } else
-        {
-            assertOSTempFolderFiles("testContent1", "testContent2");
-        }
+        assertSessionWorkspaceFiles(sessionToken, "testContent1", "testContent2");
     }
 
     @Test
-    public void testUploadWithHttpSessionAndWithoutSessionToken() throws Exception
+    public void testUploadWithHttpSessionValidAndWithoutSessionTokenParam() throws Exception
+    {
+        String sessionToken = as.login(USER, PASSWORD);
+        initHttpSession(sessionToken);
+        cleanSessionWorkspace(sessionToken);
+        upload(null, "testContent");
+        assertSessionWorkspaceFiles(sessionToken, "testContent");
+    }
+
+    @Test
+    public void testUploadWithHttpSessionValidAndWithSessionTokenParamInvalid() throws Exception
+    {
+        String sessionToken1 = as.login(USER, PASSWORD);
+
+        initHttpSession(sessionToken1);
+
+        String sessionToken2 = "admin-invalidtoken";
+
+        cleanSessionWorkspace(sessionToken1);
+        cleanSessionWorkspace(sessionToken2);
+
+        ContentResponse response = upload(sessionToken2, "testContent");
+
+        assertEquals("<message type=\"error\">Session token '" + sessionToken2 + "' is invalid: user is not logged in.</message>",
+                response.getContentAsString());
+
+        assertSessionWorkspaceFiles(sessionToken1);
+        assertSessionWorkspaceFiles(sessionToken2);
+    }
+
+    @Test
+    public void testUploadWithHttpSessionValidAndWithSessionTokenParamValid() throws Exception
+    {
+        String sessionToken1 = as.login(USER, PASSWORD);
+
+        initHttpSession(sessionToken1);
+
+        String sessionToken2 = as.login(USER, PASSWORD);
+
+        cleanSessionWorkspace(sessionToken1);
+        cleanSessionWorkspace(sessionToken2);
+
+        upload(sessionToken2, "testContent");
+
+        assertSessionWorkspaceFiles(sessionToken1);
+        assertSessionWorkspaceFiles(sessionToken2, "testContent");
+    }
+
+    @Test
+    public void testUploadWithHttpSessionInvalidAndWithoutSessionTokenParam() throws Exception
     {
         String sessionToken = as.login(USER, PASSWORD);
 
         initHttpSession(sessionToken);
 
-        cleanSessionWorkspace(sessionToken);
-        cleanOSTempFolder();
+        // invalidate the session
+        as.logout(sessionToken);
 
-        MultiPartContentProvider multipart = new MultiPartContentProvider();
-        multipart.addFilePart("testFieldName", "testFileName", new StringContentProvider("testContent"), null);
-        multipart.close();
+        cleanSessionWorkspace(sessionToken);
 
-        HttpClient client = JettyHttpClientFactory.getHttpClient();
-        Request request = client.newRequest(SERVICE_URL).method(HttpMethod.POST);
-        request.param(PARAM_SESSION_KEYS_NUMBER, "1");
-        request.param(PARAM_SESSION_KEY_PREFIX + "0", "testFieldName");
-        request.content(multipart);
+        ContentResponse response = upload(null, "testContent");
 
-        request.send();
+        assertEquals("<message type=\"error\">Session token '" + sessionToken + "' is invalid: user is not logged in.</message>",
+                response.getContentAsString());
 
         assertSessionWorkspaceFiles(sessionToken);
-        assertOSTempFolderFiles("testContent");
     }
 
     @Test
-    public void testUploadWithoutHttpSessionAndWithoutSessionToken() throws Exception
+    public void testUploadWithHttpSessionInvalidAndWithSessionTokenParamValid() throws Exception
     {
-        MultiPartContentProvider multipart = new MultiPartContentProvider();
-        multipart.addFilePart("testFieldName", "testFileName", new StringContentProvider("testContent"), null);
-        multipart.close();
+        String sessionToken1 = as.login(USER, PASSWORD);
 
-        HttpClient client = JettyHttpClientFactory.getHttpClient();
-        Request request = client.newRequest(SERVICE_URL).method(HttpMethod.POST);
-        request.param(PARAM_SESSION_KEYS_NUMBER, "1");
-        request.param(PARAM_SESSION_KEY_PREFIX + "0", "testFieldName");
-        request.content(multipart);
+        initHttpSession(sessionToken1);
 
-        ContentResponse response = request.send();
+        // invalidate the session
+        as.logout(sessionToken1);
+
+        String sessionToken2 = as.login(USER, PASSWORD);
+
+        cleanSessionWorkspace(sessionToken1);
+        cleanSessionWorkspace(sessionToken2);
+
+        upload(sessionToken2, "testContent");
+
+        assertSessionWorkspaceFiles(sessionToken1);
+        assertSessionWorkspaceFiles(sessionToken2, "testContent");
+    }
+
+    @Test
+    public void testUploadWithHttpSessionInvalidAndWithSessionTokenParamInvalid() throws Exception
+    {
+        String sessionToken1 = as.login(USER, PASSWORD);
+
+        initHttpSession(sessionToken1);
+
+        // invalidate the session
+        as.logout(sessionToken1);
+
+        String sessionToken2 = "admin-invalidtoken";
+
+        cleanSessionWorkspace(sessionToken1);
+        cleanSessionWorkspace(sessionToken2);
+
+        ContentResponse response = upload(sessionToken2, "testContent");
+
+        assertEquals("<message type=\"error\">Session token '" + sessionToken2 + "' is invalid: user is not logged in.</message>",
+                response.getContentAsString());
+
+        assertSessionWorkspaceFiles(sessionToken1);
+        assertSessionWorkspaceFiles(sessionToken2);
+    }
+
+    @Test
+    public void testUploadWithoutHttpSessionAndWithoutSessionTokenParam() throws Exception
+    {
+        ContentResponse response = upload(null, "testContent");
         assertEquals("<message type=\"error\">Pre-existing session required but none found</message>", response.getContentAsString());
     }
 
     @Test
-    public void testUploadWithoutHttpSessionAndWithSessionToken() throws Exception
+    public void testUploadWithoutHttpSessionAndWithSessionTokenParamValid() throws Exception
     {
         String sessionToken = as.login(USER, PASSWORD);
-
         cleanSessionWorkspace(sessionToken);
+        upload(sessionToken, "testContent");
+        assertSessionWorkspaceFiles(sessionToken, "testContent");
+    }
 
-        MultiPartContentProvider multipart = new MultiPartContentProvider();
-        multipart.addFilePart("testFieldName", "testFileName", new StringContentProvider("testContent"), null);
-        multipart.close();
+    @Test
+    public void testUploadWithoutHttpSessionAndWithSessionTokenParamInvalid() throws Exception
+    {
+        String sessionToken = "admin-invalidtoken";
 
-        HttpClient client = JettyHttpClientFactory.getHttpClient();
-        Request request = client.newRequest(SERVICE_URL).method(HttpMethod.POST);
-        request.param(PARAM_SESSION_ID, sessionToken);
-        request.param(PARAM_SESSION_KEYS_NUMBER, "1");
-        request.param(PARAM_SESSION_KEY_PREFIX + "0", "testFieldName");
-        request.content(multipart);
+        cleanSessionWorkspace(sessionToken);
 
-        request.send();
+        ContentResponse response = upload(sessionToken, "testContent");
 
-        assertSessionWorkspaceFiles(sessionToken, "testContent");
+        assertEquals("<message type=\"error\">Session token '" + sessionToken + "' is invalid: user is not logged in.</message>",
+                response.getContentAsString());
+
+        assertSessionWorkspaceFiles(sessionToken);
     }
 
     @Test
-    public void testUploadWithoutSessionKeysNumber() throws Exception
+    public void testUploadWithoutSessionKeysNumberParam() throws Exception
     {
         String sessionToken = as.login(USER, PASSWORD);
 
@@ -281,7 +344,7 @@ public class UploadServletTest extends SystemTestCase
     }
 
     @Test
-    public void testUploadWithIncorrectSessionKeysNumberFormat() throws Exception
+    public void testUploadWithIncorrectSessionKeysNumberParamFormat() throws Exception
     {
         String sessionToken = as.login(USER, PASSWORD);
 
@@ -302,7 +365,7 @@ public class UploadServletTest extends SystemTestCase
     }
 
     @Test
-    public void testUploadWithoutSessionKeyPrefix() throws Exception
+    public void testUploadWithoutSessionKeyPrefixParam() throws Exception
     {
         String sessionToken = as.login(USER, PASSWORD);
 
@@ -323,7 +386,7 @@ public class UploadServletTest extends SystemTestCase
     }
 
     @Test
-    public void testUploadWithTooFewSessionKeyPrefixes() throws Exception
+    public void testUploadWithTooFewSessionKeyPrefixParams() throws Exception
     {
         String sessionToken = as.login(USER, PASSWORD);
 
@@ -349,18 +412,7 @@ public class UploadServletTest extends SystemTestCase
     {
         String sessionToken = as.login(USER, PASSWORD);
 
-        MultiPartContentProvider multipart = new MultiPartContentProvider();
-        multipart.addFilePart("testFieldName", "testFileName", new StringContentProvider("testContent"), null);
-        multipart.close();
-
-        HttpClient client = JettyHttpClientFactory.getHttpClient();
-        Request request = client.newRequest(SERVICE_URL).method(HttpMethod.POST);
-        request.param(PARAM_SESSION_ID, sessionToken);
-        request.param(PARAM_SESSION_KEYS_NUMBER, "1");
-        request.param(PARAM_SESSION_KEY_PREFIX + "0", "testFieldName");
-        request.content(multipart);
-
-        request.send();
+        upload(sessionToken, "testContent");
 
         assertSessionWorkspaceFiles(sessionToken, "testContent");
 
@@ -409,6 +461,25 @@ public class UploadServletTest extends SystemTestCase
         request.send();
     }
 
+    private ContentResponse upload(String sessionToken, String fileContent) throws Exception
+    {
+        MultiPartContentProvider multipart = new MultiPartContentProvider();
+        multipart.addFilePart("testFieldName", "testFileName", new StringContentProvider(fileContent), null);
+        multipart.close();
+
+        HttpClient client = JettyHttpClientFactory.getHttpClient();
+        Request request = client.newRequest(SERVICE_URL).method(HttpMethod.POST);
+        if (sessionToken != null)
+        {
+            request.param(PARAM_SESSION_ID, sessionToken);
+        }
+        request.param(PARAM_SESSION_KEYS_NUMBER, "1");
+        request.param(PARAM_SESSION_KEY_PREFIX + "0", "testFieldName");
+        request.content(multipart);
+
+        return request.send();
+    }
+
     private File getOSTempFolder() throws Exception
     {
         return new File(System.getProperty("java.io.tmpdir"));
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/UploadServiceServlet.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/UploadServiceServlet.java
index 660b9952ab3..7e20bdb794b 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/UploadServiceServlet.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/UploadServiceServlet.java
@@ -82,17 +82,20 @@ public final class UploadServiceServlet extends AbstractController
     private ISessionWorkspaceProvider sessionWorkspaceProvider;
 
     @Private
-    UploadServiceServlet(ISessionFilesSetter sessionFilesSetter)
+    UploadServiceServlet(ISessionFilesSetter sessionFilesSetter, IOpenBisSessionManager sessionManager,
+            ISessionWorkspaceProvider sessionWorkspaceProvider)
     {
         // super(UploadedFilesBean.class);
         setSynchronizeOnSession(true);
         setRequireSession(false); // To allow upload a file for usage from an API given a session token.
         this.sessionFilesSetter = sessionFilesSetter;
+        this.sessionManager = sessionManager;
+        this.sessionWorkspaceProvider = sessionWorkspaceProvider;
     }
 
     public UploadServiceServlet()
     {
-        this(new SessionFilesSetter());
+        this(new SessionFilesSetter(), null, null);
     }
 
     @SuppressWarnings({ "unchecked", "rawtypes" })
@@ -195,6 +198,11 @@ public final class UploadServiceServlet extends AbstractController
             {
                 response.setStatus(500);
                 throw new HttpSessionRequiredException("Pre-existing session required but none found");
+            } else
+            {
+                sessionToken = (String) session.getAttribute(SessionConstants.OPENBIS_SESSION_TOKEN_ATTRIBUTE_KEY);
+                // check and touch the session
+                getSession(sessionToken);
             }
 
             final MultipartHttpServletRequest multipartRequest =
@@ -211,7 +219,7 @@ public final class UploadServiceServlet extends AbstractController
             {
                 // Note: addFilesToSession has a side effect - adds extracted files to the session
                 boolean fileExtracted =
-                        sessionFilesSetter.addFilesToSession(sessionToken, session, multipartRequest, sessionKey, sessionWorkspaceProvider);
+                        sessionFilesSetter.addFilesToSession(session, multipartRequest, sessionKey, sessionWorkspaceProvider);
                 atLeastOneFileUploaded = atLeastOneFileUploaded || fileExtracted;
             }
             if (atLeastOneFileUploaded == false)
@@ -249,7 +257,7 @@ public final class UploadServiceServlet extends AbstractController
          * 
          * @return <code>true</code> if at least one file has been found and added
          */
-        public boolean addFilesToSession(String sessionToken, final HttpSession session,
+        public boolean addFilesToSession(final HttpSession session,
                 final MultipartHttpServletRequest multipartRequest, String sessionKey, ISessionWorkspaceProvider sessionWorkspaceProvider);
     }
 
@@ -257,20 +265,23 @@ public final class UploadServiceServlet extends AbstractController
     static class SessionFilesSetter implements ISessionFilesSetter
     {
         @Override
-        public boolean addFilesToSession(String sessionToken, final HttpSession session,
+        public boolean addFilesToSession(final HttpSession session,
                 final MultipartHttpServletRequest multipartRequest, String sessionKey, ISessionWorkspaceProvider sessionWorkspaceProvider)
         {
-            return addFilesToSessionUsingBean(sessionToken, session, multipartRequest, sessionKey,
+            return addFilesToSessionUsingBean(session, multipartRequest, sessionKey,
                     new UploadedFilesBean(), sessionWorkspaceProvider);
         }
 
         @Private
-        boolean addFilesToSessionUsingBean(String sessionToken, final HttpSession session,
+        boolean addFilesToSessionUsingBean(final HttpSession session,
                 final MultipartHttpServletRequest multipartRequest, String sessionKey,
                 final UploadedFilesBean uploadedFiles, ISessionWorkspaceProvider sessionWorkspaceProvider)
         {
             assert StringUtils.isBlank(sessionKey) == false;
             boolean fileUploaded = false;
+
+            String sessionToken = (String) session.getAttribute(SessionConstants.OPENBIS_SESSION_TOKEN_ATTRIBUTE_KEY);
+
             for (final Iterator<String> iterator = cast(multipartRequest.getFileNames()); iterator
                     .hasNext(); /**/)
             {
diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/UploadedFilesBean.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/UploadedFilesBean.java
index 408d55ee7cb..56487c00fd0 100644
--- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/UploadedFilesBean.java
+++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/UploadedFilesBean.java
@@ -23,9 +23,12 @@ import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.commons.io.FileUtils;
+import org.apache.log4j.Logger;
 import org.springframework.web.multipart.MultipartFile;
 
 import ch.systemsx.cisd.base.exceptions.IOExceptionUnchecked;
+import ch.systemsx.cisd.common.logging.LogCategory;
+import ch.systemsx.cisd.common.logging.LogFactory;
 import ch.systemsx.cisd.common.shared.basic.string.StringUtils;
 import ch.systemsx.cisd.openbis.common.spring.IUncheckedMultipartFile;
 import ch.systemsx.cisd.openbis.common.spring.MultipartFileAdapter;
@@ -38,29 +41,21 @@ import ch.systemsx.cisd.openbis.generic.server.ISessionWorkspaceProvider;
  */
 public final class UploadedFilesBean
 {
+
+    private static final Logger operationLog = LogFactory.getLogger(LogCategory.OPERATION, UploadedFilesBean.class);
+
     private static final String CLASS_SIMPLE_NAME = UploadedFilesBean.class.getSimpleName();
 
     private List<IUncheckedMultipartFile> multipartFiles = new ArrayList<IUncheckedMultipartFile>();
 
     private final File createTempFile(String sessionToken, ISessionWorkspaceProvider sessionWorkspaceProvider) throws IOException
     {
-        File tempFolder = null;
-
-        if (false == StringUtils.isBlank(sessionToken) && sessionWorkspaceProvider != null)
-        {
-            tempFolder = sessionWorkspaceProvider.getSessionWorkspace(sessionToken);
-        }
-
+        File tempFolder = sessionWorkspaceProvider.getSessionWorkspace(sessionToken);
         final File tempFile = File.createTempFile(CLASS_SIMPLE_NAME, null, tempFolder);
         tempFile.deleteOnExit();
         return tempFile;
     }
 
-    public final void addMultipartFile(final MultipartFile multipartFile)
-    {
-        addMultipartFile(null, multipartFile, null);
-    }
-
     public final void addMultipartFile(String sessionToken, final MultipartFile multipartFile, ISessionWorkspaceProvider sessionWorkspaceProvider)
     {
         assert multipartFile != null : "Unspecified multipart file.";
@@ -68,6 +63,9 @@ public final class UploadedFilesBean
         {
             final File tempFile = createTempFile(sessionToken, sessionWorkspaceProvider);
             multipartFile.transferTo(tempFile);
+
+            operationLog.info("Uploaded file '" + multipartFile.getOriginalFilename() + "' to '" + tempFile.getCanonicalPath() + "'");
+
             final FileMultipartFileAdapter multipartFileAdapter =
                     new FileMultipartFileAdapter(multipartFile, tempFile);
             multipartFiles.add(multipartFileAdapter);
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/server/UploadServiceServletTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/server/UploadServiceServletTest.java
index 18884125e7b..798db131177 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/server/UploadServiceServletTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/client/web/server/UploadServiceServletTest.java
@@ -33,6 +33,8 @@ import ch.systemsx.cisd.common.exceptions.UserFailureException;
 import ch.systemsx.cisd.common.servlet.IRequestContextProvider;
 import ch.systemsx.cisd.openbis.generic.client.web.server.UploadServiceServlet.ISessionFilesSetter;
 import ch.systemsx.cisd.openbis.generic.client.web.server.UploadServiceServlet.SessionFilesSetter;
+import ch.systemsx.cisd.openbis.generic.server.ISessionWorkspaceProvider;
+import ch.systemsx.cisd.openbis.generic.shared.IOpenBisSessionManager;
 
 /**
  * Tests for {@link UploadServiceServlet}.
@@ -49,6 +51,8 @@ public final class UploadServiceServletTest extends AssertJUnit
 
     private static final String SESSION_KEYS_NUMBER = "sessionKeysNumber";
 
+    private static final String SESSION_TOKEN_KEY = "openbis-session-token";
+
     private static final String SESSION_TOKEN = "sessionID";
 
     protected Mockery context;
@@ -61,8 +65,12 @@ public final class UploadServiceServletTest extends AssertJUnit
 
     protected HttpSession httpSession;
 
+    protected IOpenBisSessionManager sessionManager;
+
     protected ISessionFilesSetter sessionFilesSetter;
 
+    protected ISessionWorkspaceProvider sessionWorkspaceProvider;
+
     @BeforeMethod
     public void setUp()
     {
@@ -71,7 +79,9 @@ public final class UploadServiceServletTest extends AssertJUnit
         multipartHttpServletRequest = context.mock(MultipartHttpServletRequest.class);
         servletResponse = context.mock(HttpServletResponse.class);
         httpSession = context.mock(HttpSession.class);
+        sessionManager = context.mock(IOpenBisSessionManager.class);
         sessionFilesSetter = context.mock(ISessionFilesSetter.class);
+        sessionWorkspaceProvider = context.mock(ISessionWorkspaceProvider.class);
     }
 
     @AfterMethod
@@ -84,7 +94,7 @@ public final class UploadServiceServletTest extends AssertJUnit
 
     private UploadServiceServlet createServlet()
     {
-        return new UploadServiceServlet(sessionFilesSetter);
+        return new UploadServiceServlet(sessionFilesSetter, sessionManager, sessionWorkspaceProvider);
     }
 
     private void expectSendResponse(Expectations exp)
@@ -97,6 +107,9 @@ public final class UploadServiceServletTest extends AssertJUnit
     {
         exp.one(multipartHttpServletRequest).getSession(false);
         exp.will(Expectations.returnValue(httpSession));
+        exp.one(httpSession).getAttribute(SESSION_TOKEN_KEY);
+        exp.will(Expectations.returnValue(SESSION_TOKEN));
+        exp.one(sessionManager).getSession(SESSION_TOKEN);
     }
 
     @Test
@@ -230,8 +243,7 @@ public final class UploadServiceServletTest extends AssertJUnit
                         one(multipartHttpServletRequest).getParameter(SESSION_KEY_PREFIX + i);
                         will(returnValue(sessionKey));
 
-                        one(sessionFilesSetter).addFilesToSession("", httpSession,
-                                multipartHttpServletRequest, sessionKey, null);
+                        one(sessionFilesSetter).addFilesToSession(httpSession, multipartHttpServletRequest, sessionKey, sessionWorkspaceProvider);
                         will(returnValue(false));
                     }
 
@@ -268,8 +280,7 @@ public final class UploadServiceServletTest extends AssertJUnit
                         one(multipartHttpServletRequest).getParameter(SESSION_KEY_PREFIX + i);
                         will(returnValue(sessionKey));
 
-                        one(sessionFilesSetter).addFilesToSession("", httpSession,
-                                multipartHttpServletRequest, sessionKey, null);
+                        one(sessionFilesSetter).addFilesToSession(httpSession, multipartHttpServletRequest, sessionKey, sessionWorkspaceProvider);
                         will(returnValue(true));
                     }
                     expectSendResponse(this);
@@ -298,8 +309,7 @@ public final class UploadServiceServletTest extends AssertJUnit
                         one(multipartHttpServletRequest).getParameter(SESSION_KEY_PREFIX + i);
                         will(returnValue(sessionKey));
 
-                        one(sessionFilesSetter).addFilesToSession("", httpSession,
-                                multipartHttpServletRequest, sessionKey, null);
+                        one(sessionFilesSetter).addFilesToSession(httpSession, multipartHttpServletRequest, sessionKey, sessionWorkspaceProvider);
                         will(returnValue(i != numberOfSessionKeys - 1));
                     }
                     expectSendResponse(this);
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/server/GenericClientServiceTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/server/GenericClientServiceTest.java
index 353a2e618a2..10d8b19159f 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/server/GenericClientServiceTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/plugin/generic/client/web/server/GenericClientServiceTest.java
@@ -40,6 +40,7 @@ import ch.rinn.restrictions.Friend;
 import ch.systemsx.cisd.common.filesystem.FileUtilities;
 import ch.systemsx.cisd.openbis.generic.client.web.server.AbstractClientServiceTest;
 import ch.systemsx.cisd.openbis.generic.client.web.server.UploadedFilesBean;
+import ch.systemsx.cisd.openbis.generic.server.ISessionWorkspaceProvider;
 import ch.systemsx.cisd.openbis.generic.shared.CommonTestUtils;
 import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.AbstractExternalData;
@@ -66,7 +67,6 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.UpdatedBasicExperiment;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.UpdatedExperimentsWithType;
 import ch.systemsx.cisd.openbis.generic.shared.dto.MaterialTypePE;
 import ch.systemsx.cisd.openbis.generic.shared.translator.MaterialTypeTranslator;
-import ch.systemsx.cisd.openbis.plugin.generic.shared.IGenericServer;
 import ch.systemsx.cisd.openbis.plugin.generic.shared.IGenericServerInternal;
 
 /**
@@ -86,6 +86,8 @@ public final class GenericClientServiceTest extends AbstractClientServiceTest
 
     private GenericClientService genericClientService;
 
+    private ISessionWorkspaceProvider sessionWorkspaceProvider;
+
     private final static NewSample createNewSample(final String sampleIdentifier,
             final String sampleTypeCode, final IEntityProperty[] properties)
     {
@@ -133,6 +135,7 @@ public final class GenericClientServiceTest extends AbstractClientServiceTest
         super.setUp();
         genericServer = context.mock(IGenericServerInternal.class);
         multipartFile = context.mock(MultipartFile.class);
+        sessionWorkspaceProvider = context.mock(ISessionWorkspaceProvider.class);
         genericClientService = new GenericClientService(genericServer, requestContextProvider);
     }
 
@@ -272,8 +275,7 @@ public final class GenericClientServiceTest extends AbstractClientServiceTest
         newSample.setIdentifier("MP1");
         newSample.setContainerIdentifier("MP2");
         newSample.setParentIdentifier("MP3");
-        newSample.setProperties(new IEntityProperty[]
-        { createSampleProperty("prop1", "RED"), createSampleProperty("prop2", "1") });
+        newSample.setProperties(new IEntityProperty[] { createSampleProperty("prop1", "RED"), createSampleProperty("prop2", "1") });
         final SampleType sampleType = createSampleType("MASTER_PLATE");
         final String fileName = "originalFileName.txt";
 
@@ -287,12 +289,15 @@ public final class GenericClientServiceTest extends AbstractClientServiceTest
                     prepareGetHttpSession(this);
                     prepareGetSessionToken(this);
 
+                    allowing(sessionWorkspaceProvider).getSessionWorkspace(SESSION_TOKEN);
+                    will(returnValue(getSessionWorkspaceDir()));
+
                     allowing(httpSession).getAttribute(sessionKey);
                     will(returnValue(uploadedFilesBean));
 
                     allowing(httpSession).removeAttribute(sessionKey);
 
-                    exactly(1).of(multipartFile).getOriginalFilename();
+                    allowing(multipartFile).getOriginalFilename();
                     will(returnValue(fileName));
 
                     one(multipartFile).transferTo(with(any(File.class)));
@@ -315,8 +320,7 @@ public final class GenericClientServiceTest extends AbstractClientServiceTest
                         {
 
                             @Override
-                            @SuppressWarnings(
-                            { "unchecked" })
+                            @SuppressWarnings({ "unchecked" })
                             public Object invoke(Invocation invocation) throws Throwable
                             {
                                 final List<NewSamplesWithTypes> samplesSecions =
@@ -342,7 +346,7 @@ public final class GenericClientServiceTest extends AbstractClientServiceTest
                         });
                 }
             });
-        uploadedFilesBean.addMultipartFile(multipartFile);
+        uploadedFilesBean.addMultipartFile(SESSION_TOKEN, multipartFile, sessionWorkspaceProvider);
         final List<BatchRegistrationResult> result =
                 genericClientService.registerSamples(sampleType, sessionKey, false, null, null, false);
         assertEquals(1, result.size());
@@ -360,8 +364,7 @@ public final class GenericClientServiceTest extends AbstractClientServiceTest
         final String sessionKey = "uploaded-files";
         final NewSample newSample = new NewSample();
         newSample.setIdentifier("MP");
-        newSample.setParentsOrNull(new String[]
-        { "MP_1", "MP_2" });
+        newSample.setParentsOrNull(new String[] { "MP_1", "MP_2" });
         newSample.setProperties(new IEntityProperty[0]);
         final SampleType sampleType = createSampleType("MASTER_PLATE");
         final String fileName = "originalFileName.txt";
@@ -375,13 +378,16 @@ public final class GenericClientServiceTest extends AbstractClientServiceTest
                 {
                     prepareGetHttpSession(this);
                     prepareGetSessionToken(this);
+                    
+                    allowing(sessionWorkspaceProvider).getSessionWorkspace(SESSION_TOKEN);
+                    will(returnValue(getSessionWorkspaceDir()));
 
                     allowing(httpSession).getAttribute(sessionKey);
                     will(returnValue(uploadedFilesBean));
 
                     allowing(httpSession).removeAttribute(sessionKey);
 
-                    exactly(1).of(multipartFile).getOriginalFilename();
+                    allowing(multipartFile).getOriginalFilename();
                     will(returnValue(fileName));
 
                     one(multipartFile).transferTo(with(any(File.class)));
@@ -403,8 +409,7 @@ public final class GenericClientServiceTest extends AbstractClientServiceTest
                         {
 
                             @Override
-                            @SuppressWarnings(
-                            { "unchecked" })
+                            @SuppressWarnings({ "unchecked" })
                             public Object invoke(Invocation invocation) throws Throwable
                             {
                                 final List<NewSamplesWithTypes> samplesSecions =
@@ -427,7 +432,7 @@ public final class GenericClientServiceTest extends AbstractClientServiceTest
                         });
                 }
             });
-        uploadedFilesBean.addMultipartFile(multipartFile);
+        uploadedFilesBean.addMultipartFile(SESSION_TOKEN, multipartFile, sessionWorkspaceProvider);
         final List<BatchRegistrationResult> result =
                 genericClientService.registerSamples(sampleType, sessionKey, false, null, null, false);
         assertEquals(1, result.size());
@@ -453,13 +458,16 @@ public final class GenericClientServiceTest extends AbstractClientServiceTest
                 {
                     prepareGetHttpSession(this);
                     prepareGetSessionToken(this);
+                    
+                    allowing(sessionWorkspaceProvider).getSessionWorkspace(SESSION_TOKEN);
+                    will(returnValue(getSessionWorkspaceDir()));
 
                     allowing(httpSession).getAttribute(sessionKey);
                     will(returnValue(uploadedFilesBean));
 
                     allowing(httpSession).removeAttribute(sessionKey);
 
-                    exactly(1).of(multipartFile).getOriginalFilename();
+                    allowing(multipartFile).getOriginalFilename();
                     will(returnValue(fileName));
 
                     one(multipartFile).transferTo(with(any(File.class)));
@@ -483,8 +491,7 @@ public final class GenericClientServiceTest extends AbstractClientServiceTest
                         {
 
                             @Override
-                            @SuppressWarnings(
-                            { "unchecked", "deprecation" })
+                            @SuppressWarnings({ "unchecked", "deprecation" })
                             public Object invoke(Invocation invocation) throws Throwable
                             {
                                 final List<NewSamplesWithTypes> samplesSecions =
@@ -517,7 +524,7 @@ public final class GenericClientServiceTest extends AbstractClientServiceTest
                         });
                 }
             });
-        uploadedFilesBean.addMultipartFile(multipartFile);
+        uploadedFilesBean.addMultipartFile(SESSION_TOKEN, multipartFile, sessionWorkspaceProvider);
         final List<BatchRegistrationResult> result =
                 genericClientService.updateSamples(sampleType, sessionKey, false, null, defaultGroupIdentifier);
         assertEquals(1, result.size());
@@ -542,13 +549,16 @@ public final class GenericClientServiceTest extends AbstractClientServiceTest
                 {
                     prepareGetHttpSession(this);
                     prepareGetSessionToken(this);
+                    
+                    allowing(sessionWorkspaceProvider).getSessionWorkspace(SESSION_TOKEN);
+                    will(returnValue(getSessionWorkspaceDir()));
 
                     allowing(httpSession).getAttribute(sessionKey);
                     will(returnValue(uploadedFilesBean));
 
                     allowing(httpSession).removeAttribute(sessionKey);
 
-                    exactly(1).of(multipartFile).getOriginalFilename();
+                    allowing(multipartFile).getOriginalFilename();
                     will(returnValue(fileName));
 
                     one(multipartFile).transferTo(with(any(File.class)));
@@ -596,7 +606,7 @@ public final class GenericClientServiceTest extends AbstractClientServiceTest
                         });
                 }
             });
-        uploadedFilesBean.addMultipartFile(multipartFile);
+        uploadedFilesBean.addMultipartFile(SESSION_TOKEN, multipartFile, sessionWorkspaceProvider);
         final List<BatchRegistrationResult> result =
                 genericClientService.updateSamples(sampleType, sessionKey, false, null, defaultGroupIdentifier);
         assertEquals(1, result.size());
@@ -672,11 +682,14 @@ public final class GenericClientServiceTest extends AbstractClientServiceTest
             {
                 {
                     prepareGetSessionToken(this);
+                    
+                    allowing(sessionWorkspaceProvider).getSessionWorkspace(SESSION_TOKEN);
+                    will(returnValue(getSessionWorkspaceDir()));
 
                     allowing(httpSession).getAttribute(sessionKey);
                     will(returnValue(uploadedFilesBean));
 
-                    one(multipartFile).getOriginalFilename();
+                    allowing(multipartFile).getOriginalFilename();
                     will(returnValue("file name"));
 
                     one(multipartFile).transferTo(with(any(File.class)));
@@ -699,7 +712,7 @@ public final class GenericClientServiceTest extends AbstractClientServiceTest
                     will(returnValue(updateCount));
                 }
             });
-        uploadedFilesBean.addMultipartFile(multipartFile);
+        uploadedFilesBean.addMultipartFile(SESSION_TOKEN, multipartFile, sessionWorkspaceProvider);
     }
 
     @Test
@@ -768,13 +781,16 @@ public final class GenericClientServiceTest extends AbstractClientServiceTest
                 {
                     prepareGetHttpSession(this);
                     prepareGetSessionToken(this);
+                    
+                    allowing(sessionWorkspaceProvider).getSessionWorkspace(SESSION_TOKEN);
+                    will(returnValue(getSessionWorkspaceDir()));
 
                     allowing(httpSession).getAttribute(sessionKey);
                     will(returnValue(uploadedFilesBean));
 
                     allowing(httpSession).removeAttribute(sessionKey);
 
-                    exactly(1).of(multipartFile).getOriginalFilename();
+                    allowing(multipartFile).getOriginalFilename();
                     will(returnValue(fileName));
 
                     one(multipartFile).transferTo(with(any(File.class)));
@@ -825,7 +841,7 @@ public final class GenericClientServiceTest extends AbstractClientServiceTest
                         });
                 }
             });
-        uploadedFilesBean.addMultipartFile(multipartFile);
+        uploadedFilesBean.addMultipartFile(SESSION_TOKEN, multipartFile, sessionWorkspaceProvider);
         final List<BatchRegistrationResult> result =
                 genericClientService.updateExperiments(experimentType, sessionKey, false, null);
         assertEquals(1, result.size());
@@ -849,13 +865,16 @@ public final class GenericClientServiceTest extends AbstractClientServiceTest
                 {
                     prepareGetHttpSession(this);
                     prepareGetSessionToken(this);
+                    
+                    allowing(sessionWorkspaceProvider).getSessionWorkspace(SESSION_TOKEN);
+                    will(returnValue(getSessionWorkspaceDir()));
 
                     allowing(httpSession).getAttribute(sessionKey);
                     will(returnValue(uploadedFilesBean));
 
                     allowing(httpSession).removeAttribute(sessionKey);
 
-                    exactly(1).of(multipartFile).getOriginalFilename();
+                    allowing(multipartFile).getOriginalFilename();
                     will(returnValue(fileName));
 
                     one(multipartFile).transferTo(with(any(File.class)));
@@ -911,7 +930,7 @@ public final class GenericClientServiceTest extends AbstractClientServiceTest
                         });
                 }
             });
-        uploadedFilesBean.addMultipartFile(multipartFile);
+        uploadedFilesBean.addMultipartFile(SESSION_TOKEN, multipartFile, sessionWorkspaceProvider);
         final List<BatchRegistrationResult> result =
                 genericClientService.updateExperiments(experimentType, sessionKey, false, null);
         assertEquals(1, result.size());
@@ -1033,4 +1052,14 @@ public final class GenericClientServiceTest extends AbstractClientServiceTest
             return true;
         }
     }
+
+    private File getSessionWorkspaceDir()
+    {
+        File dir = new File("targets/sessionWorkspace");
+        if (false == dir.exists())
+        {
+            dir.mkdirs();
+        }
+        return dir;
+    }
 }
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/AttachmentUploadTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/AttachmentUploadTest.java
index a6520506bad..14494385d0c 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/AttachmentUploadTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/AttachmentUploadTest.java
@@ -54,7 +54,7 @@ public class AttachmentUploadTest extends SystemTestCase
         Project project = projects.getResultSet().getList().extractOriginalObjects().get(0).getObjectOrNull();
         TechId projectID = TechId.create(project);
 
-        uploadFile(FILE_NAME, FILE_CONTENT);
+        uploadFile(sessionContext.getSessionID(), FILE_NAME, FILE_CONTENT);
         commonClientService.addAttachment(projectID, SESSION_KEY, AttachmentHolderKind.PROJECT,
                 new NewAttachment(FILE_NAME, "my file", "example file"));
 
@@ -70,7 +70,7 @@ public class AttachmentUploadTest extends SystemTestCase
         SessionContext sessionContext = logIntoCommonClientService();
         TechId experimentID = new TechId(2);
 
-        uploadFile(FILE_NAME, FILE_CONTENT);
+        uploadFile(sessionContext.getSessionID(), FILE_NAME, FILE_CONTENT);
         commonClientService.addAttachment(experimentID, SESSION_KEY, AttachmentHolderKind.EXPERIMENT,
                 new NewAttachment(FILE_NAME, "my file", "example file"));
 
@@ -86,7 +86,7 @@ public class AttachmentUploadTest extends SystemTestCase
         SessionContext sessionContext = logIntoCommonClientService();
         TechId sampleID = new TechId(1);
 
-        uploadFile(FILE_NAME, FILE_CONTENT);
+        uploadFile(sessionContext.getSessionID(), FILE_NAME, FILE_CONTENT);
         commonClientService.addAttachment(sampleID, SESSION_KEY, AttachmentHolderKind.SAMPLE,
                 new NewAttachment(FILE_NAME, "my file", "example file"));
 
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/BatchMaterialRegistrationAndUpdateTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/BatchMaterialRegistrationAndUpdateTest.java
index ebe26ec25ff..aef43906311 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/BatchMaterialRegistrationAndUpdateTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/BatchMaterialRegistrationAndUpdateTest.java
@@ -36,6 +36,7 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.lang.
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.DisplayedOrSelectedIdHolderCriteria;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.GridRowModels;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListMaterialDisplayCriteria;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.SessionContext;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.TypedTableResultSet;
 import ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException;
 import ch.systemsx.cisd.openbis.generic.shared.basic.GridRowModel;
@@ -73,7 +74,7 @@ public class BatchMaterialRegistrationAndUpdateTest extends SystemTestCase
     @Test(groups = "slow")
     public void testBatchRegistrationWithManagedProperty()
     {
-        logIntoCommonClientService().getSessionID();
+        SessionContext session = logIntoCommonClientService();
         deleteTestMaterials();
         Script script = new Script();
         script.setScriptType(ScriptType.MANAGED_PROPERTY);
@@ -96,7 +97,7 @@ public class BatchMaterialRegistrationAndUpdateTest extends SystemTestCase
                 "code\tdescription\tsize\tcomment:a\tcomment:b\n" + "c1\tcompound 1\t42\tx\ty\n"
                         + "c2\tcompound 2\t43\ta\tb";
 
-        List<BatchRegistrationResult> result = registerMaterials(materialBatchData, MATERIAL_TYPE);
+        List<BatchRegistrationResult> result = registerMaterials(session.getSessionID(), materialBatchData, MATERIAL_TYPE);
 
         assertEquals("Registration/update of 2 material(s) is complete.", result.get(0)
                 .getMessage());
@@ -109,7 +110,7 @@ public class BatchMaterialRegistrationAndUpdateTest extends SystemTestCase
     @Test(groups = "slow")
     public void testUpdateOfPropertiesOfVariousTypes()
     {
-        logIntoCommonClientService();
+        SessionContext session = logIntoCommonClientService();
         deleteTestMaterials();
 
         NewETPTAssignment assignment = new NewETPTAssignment();
@@ -124,12 +125,12 @@ public class BatchMaterialRegistrationAndUpdateTest extends SystemTestCase
                 "code\tdescription\tsize\tgender\tbacterium\n"
                         + "c1\tcompound 1\t42\tfemale\tbacterium1\n"
                         + "c2\tcompound 2\t43\tmale\tbacterium-x";
-        registerMaterials(materialBatchData, MATERIAL_TYPE);
+        registerMaterials(session.getSessionID(), materialBatchData, MATERIAL_TYPE);
 
         long timeBeforeUpdate = System.currentTimeMillis();
 
         List<BatchRegistrationResult> result =
-                updateMaterials("code\tdescription\tgender\tbacterium\n"
+                updateMaterials(session.getSessionID(), "code\tdescription\tgender\tbacterium\n"
                         + "c1\tnew description\tmale\tbacterium2\n" + "c2\t\tmale\tbacterium-y",
                         MATERIAL_TYPE, false);
 
@@ -157,7 +158,7 @@ public class BatchMaterialRegistrationAndUpdateTest extends SystemTestCase
         assertEquals("[BACTERIUM: material:BACTERIUM-X [BACTERIUM]<a:2>]",
                 getMaterialPropertiesHistory(getMaterialOrNull("C2").getId()).toString());
 
-        updateMaterials("code\tdescription\tgender\tbacterium\n"
+        updateMaterials(session.getSessionID(), "code\tdescription\tgender\tbacterium\n"
                 + "c2\t--DELETE--\tfemale\tbacterium2\n", MATERIAL_TYPE, false);
 
         assertEquals(
@@ -169,14 +170,14 @@ public class BatchMaterialRegistrationAndUpdateTest extends SystemTestCase
     @Test
     public void testUpdateIgnoreUnregistered()
     {
-        logIntoCommonClientService();
+        SessionContext session = logIntoCommonClientService();
         deleteTestMaterials();
         String materialBatchData =
                 "code\tdescription\tsize\n" + "c1\tcompound 1\t42\n" + "c2\tcompound 2\t43";
-        registerMaterials(materialBatchData, MATERIAL_TYPE);
+        registerMaterials(session.getSessionID(), materialBatchData, MATERIAL_TYPE);
 
         List<BatchRegistrationResult> result =
-                updateMaterials("code\tdescription\tsize\n" + "c1\tcompound one\t\n"
+                updateMaterials(session.getSessionID(), "code\tdescription\tsize\n" + "c1\tcompound one\t\n"
                         + "c2\tcompound two\t4711\n" + "c3\t3\t\n", MATERIAL_TYPE, true);
 
         assertEquals("2 material(s) updated, 1 ignored.", result.get(0).getMessage());
@@ -259,20 +260,20 @@ public class BatchMaterialRegistrationAndUpdateTest extends SystemTestCase
         }
     }
 
-    private List<BatchRegistrationResult> registerMaterials(String materialBatchData,
+    private List<BatchRegistrationResult> registerMaterials(String sessionToken, String materialBatchData,
             String materialTypeCode)
     {
-        uploadFile("my-file", materialBatchData);
+        uploadFile(sessionToken, "my-file", materialBatchData);
         MaterialType materialType = new MaterialType();
         materialType.setCode(materialTypeCode);
         return genericClientService
                 .registerMaterials(materialType, false, SESSION_KEY, false, null);
     }
 
-    private List<BatchRegistrationResult> updateMaterials(String materialBatchData,
+    private List<BatchRegistrationResult> updateMaterials(String sessionToken, String materialBatchData,
             String materialTypeCode, boolean ignoreUnregistered)
     {
-        uploadFile("my-file", materialBatchData);
+        uploadFile(sessionToken, "my-file", materialBatchData);
         MaterialType materialType = new MaterialType();
         materialType.setCode(materialTypeCode);
         return genericClientService.updateMaterials(materialType, SESSION_KEY, ignoreUnregistered,
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/CodeGenerationTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/CodeGenerationTest.java
index 95fb668d1f0..3bafe97a7f7 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/CodeGenerationTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/CodeGenerationTest.java
@@ -155,7 +155,7 @@ public class CodeGenerationTest extends SystemTestCase
         setSampleCodeSequence(10);
 
         String sessionID = logIntoCommonClientService().getSessionID();
-        uploadFile("testAutomaticCreationOfSampleCodesInBatchSampleRegistration.txt",
+        uploadFile(sessionID, "testAutomaticCreationOfSampleCodesInBatchSampleRegistration.txt",
                 "experiment\tCOMMENT\n" + "/CISD/NEMO/EXP1\tA\n" + "/CISD/NEMO/EXP1\tB\n");
         SampleType sampleType = new SampleType();
         sampleType.setGeneratedCodePrefix("A");
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/PersistentSystemTestCase.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/PersistentSystemTestCase.java
index 0601e65dc65..5b4a5fa5601 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/PersistentSystemTestCase.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/PersistentSystemTestCase.java
@@ -16,11 +16,8 @@
 
 package ch.systemsx.cisd.openbis.systemtest;
 
-import javax.servlet.http.HttpSession;
-
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.mock.web.MockHttpServletRequest;
-import org.springframework.mock.web.MockMultipartFile;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
 import org.springframework.transaction.annotation.Transactional;
@@ -31,7 +28,6 @@ import org.testng.annotations.BeforeSuite;
 import ch.systemsx.cisd.common.servlet.SpringRequestContextProvider;
 import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientService;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.SessionContext;
-import ch.systemsx.cisd.openbis.generic.client.web.server.UploadedFilesBean;
 import ch.systemsx.cisd.openbis.generic.server.ICommonServerForInternalUse;
 import ch.systemsx.cisd.openbis.generic.server.util.TestInitializer;
 import ch.systemsx.cisd.openbis.generic.shared.IServiceForDataStoreServer;
@@ -201,13 +197,4 @@ public abstract class PersistentSystemTestCase extends AbstractTestNGSpringConte
         return commonServer.tryAuthenticate(user, "password").getSessionToken();
     }
 
-    protected void uploadFile(String fileName, String fileContent)
-    {
-        UploadedFilesBean bean = new UploadedFilesBean();
-        bean.addMultipartFile(new MockMultipartFile(fileName, fileName, null, fileContent
-                .getBytes()));
-        HttpSession session = request.getSession();
-        session.setAttribute(SESSION_KEY, bean);
-    }
-
 }
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/SystemTestCase.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/SystemTestCase.java
index 135f56f85ab..d47554cc9aa 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/SystemTestCase.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/SystemTestCase.java
@@ -46,6 +46,7 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.dto.SessionContext;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.TypedTableResultSet;
 import ch.systemsx.cisd.openbis.generic.client.web.server.UploadedFilesBean;
 import ch.systemsx.cisd.openbis.generic.server.ICommonServerForInternalUse;
+import ch.systemsx.cisd.openbis.generic.server.ISessionWorkspaceProvider;
 import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
 import ch.systemsx.cisd.openbis.generic.server.util.TestInitializer;
 import ch.systemsx.cisd.openbis.generic.shared.Constants;
@@ -135,6 +136,9 @@ public abstract class SystemTestCase extends AbstractTransactionalTestNGSpringCo
 
     protected String systemSessionToken;
 
+    @Autowired
+    protected ISessionWorkspaceProvider sessionWorkspaceProvider;
+
     @BeforeSuite
     public void beforeSuite()
     {
@@ -371,11 +375,11 @@ public abstract class SystemTestCase extends AbstractTransactionalTestNGSpringCo
         return new NewSampleBuilder(identifier);
     }
 
-    protected void uploadFile(String fileName, String fileContent)
+    protected void uploadFile(String sessionToken, String fileName, String fileContent)
     {
         UploadedFilesBean bean = new UploadedFilesBean();
-        bean.addMultipartFile(new MockMultipartFile(fileName, fileName, null, fileContent
-                .getBytes()));
+        bean.addMultipartFile(sessionToken, new MockMultipartFile(fileName, fileName, null, fileContent
+                .getBytes()), sessionWorkspaceProvider);
         HttpSession session = request.getSession();
         session.setAttribute(SESSION_KEY, bean);
     }
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/api/v1/GeneralInformationChangingServiceTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/api/v1/GeneralInformationChangingServiceTest.java
index d06610e9194..246e6529c89 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/api/v1/GeneralInformationChangingServiceTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/api/v1/GeneralInformationChangingServiceTest.java
@@ -834,7 +834,7 @@ public class GeneralInformationChangingServiceTest extends SystemTestCase
 
         String sampleType = "CELL_PLATE";
 
-        uploadFile("testRegisterSamplesWithProjectAuthorization.txt",
+        uploadFile(session.getSessionID(), "testRegisterSamplesWithProjectAuthorization.txt",
                 "identifier\texperiment\tCOMMENT\n"
                         + "/TEST-SPACE/PA_UPLOAD\t/TEST-SPACE/TEST-PROJECT/EXP-SPACE-TEST\ttest comment\n");
 
@@ -871,7 +871,7 @@ public class GeneralInformationChangingServiceTest extends SystemTestCase
 
         String sampleType = "CELL_PLATE";
 
-        uploadFile("testUpdateSamplesWithProjectAuthorization.txt",
+        uploadFile(session.getSessionID(), "testUpdateSamplesWithProjectAuthorization.txt",
                 "identifier\tCOMMENT\n"
                         + "/TEST-SPACE/FV-TEST\tupdated comment\n");
 
@@ -908,7 +908,7 @@ public class GeneralInformationChangingServiceTest extends SystemTestCase
 
         String sampleType = "CELL_PLATE";
 
-        uploadFile("testUploadedSamplesInfoWithProjectAuthorization.txt",
+        uploadFile(session.getSessionID(), "testUploadedSamplesInfoWithProjectAuthorization.txt",
                 "identifier\texperiment\tCOMMENT\n"
                         + "/TEST-SPACE/PA_UPLOAD\t/TEST-SPACE/TEST-PROJECT/EXP-SPACE-TEST\ttest comment\n");
 
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/plugin/generic/ExperimentRegistrationTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/plugin/generic/ExperimentRegistrationTest.java
index 2ef60a6778b..ddedfc5255e 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/plugin/generic/ExperimentRegistrationTest.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/plugin/generic/ExperimentRegistrationTest.java
@@ -32,6 +32,7 @@ import org.testng.annotations.Test;
 import ch.systemsx.cisd.common.string.UnicodeUtils;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ListSampleDisplayCriteria;
 import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ResultSetWithEntityTypes;
+import ch.systemsx.cisd.openbis.generic.client.web.client.dto.SessionContext;
 import ch.systemsx.cisd.openbis.generic.client.web.client.exception.UserFailureException;
 import ch.systemsx.cisd.openbis.generic.shared.basic.GridRowModel;
 import ch.systemsx.cisd.openbis.generic.shared.basic.TechId;
@@ -89,8 +90,7 @@ public class ExperimentRegistrationTest extends GenericSystemTestCase
         String experimentCode = commonClientService.generateCode("EXP", EntityKind.EXPERIMENT);
         String experimentIdentifier = "/cisd/default/" + experimentCode;
         NewExperiment newExperiment = new NewExperiment(experimentIdentifier, "SIRNA_HCS");
-        newExperiment.setProperties(new IEntityProperty[]
-        { property("DESCRIPTION", "my éxpériment") });
+        newExperiment.setProperties(new IEntityProperty[] { property("DESCRIPTION", "my éxpériment") });
         genericClientService.registerExperiment(ATTACHMENTS_SESSION_KEY, SAMPLES_SESSION_KEY,
                 newExperiment);
 
@@ -113,10 +113,8 @@ public class ExperimentRegistrationTest extends GenericSystemTestCase
         String experimentCode = commonClientService.generateCode("EXP", EntityKind.EXPERIMENT);
         String experimentIdentifier = "/cisd/default/" + experimentCode;
         NewExperiment newExperiment = new NewExperiment(experimentIdentifier, "SIRNA_HCS");
-        newExperiment.setProperties(new IEntityProperty[]
-        { property("DESCRIPTION", "my experiment") });
-        newExperiment.setSamples(new String[]
-        { "3vcp8" });
+        newExperiment.setProperties(new IEntityProperty[] { property("DESCRIPTION", "my experiment") });
+        newExperiment.setSamples(new String[] { "3vcp8" });
         genericClientService.registerExperiment(ATTACHMENTS_SESSION_KEY, SAMPLES_SESSION_KEY,
                 newExperiment);
 
@@ -136,15 +134,14 @@ public class ExperimentRegistrationTest extends GenericSystemTestCase
     @Test
     public void testRegisterExperimentAndSamples()
     {
-        logIntoCommonClientService();
+        SessionContext session = logIntoCommonClientService();
 
         String batchSamplesFileContent = "identifier\torganism\n" + "S1001\tfly\n" + "S1002\tdog\n";
-        addMultiPartFile(SAMPLES_SESSION_KEY, "samples.txt", batchSamplesFileContent.getBytes());
+        addMultiPartFile(session.getSessionID(), SAMPLES_SESSION_KEY, "samples.txt", batchSamplesFileContent.getBytes());
         String experimentCode = commonClientService.generateCode("EXP", EntityKind.EXPERIMENT);
         String experimentIdentifier = "/cisd/default/" + experimentCode;
         NewExperiment newExperiment = new NewExperiment(experimentIdentifier, "SIRNA_HCS");
-        newExperiment.setProperties(new IEntityProperty[]
-        { property("DESCRIPTION", "my experiment") });
+        newExperiment.setProperties(new IEntityProperty[] { property("DESCRIPTION", "my experiment") });
         newExperiment.setRegisterSamples(true);
         SampleType sampleType = new SampleType();
         sampleType.setCode("CELL_PLATE");
@@ -186,12 +183,11 @@ public class ExperimentRegistrationTest extends GenericSystemTestCase
     {
         String sessionToken = logIntoCommonClientService().getSessionID();
 
-        addMultiPartFile(ATTACHMENTS_SESSION_KEY, "hello.txt", "hello world".getBytes());
+        addMultiPartFile(sessionToken, ATTACHMENTS_SESSION_KEY, "hello.txt", "hello world".getBytes());
         String experimentCode = commonClientService.generateCode("EXP", EntityKind.EXPERIMENT);
         String experimentIdentifier = "/cisd/default/" + experimentCode;
         NewExperiment newExperiment = new NewExperiment(experimentIdentifier, "SIRNA_HCS");
-        newExperiment.setProperties(new IEntityProperty[]
-        { property("DESCRIPTION", "my experiment") });
+        newExperiment.setProperties(new IEntityProperty[] { property("DESCRIPTION", "my experiment") });
         newExperiment.setAttachments(Arrays.asList(new NewAttachment("hello.txt", "hello",
                 "test attachment")));
         genericClientService.registerExperiment(ATTACHMENTS_SESSION_KEY, SAMPLES_SESSION_KEY,
@@ -220,19 +216,17 @@ public class ExperimentRegistrationTest extends GenericSystemTestCase
     @Test(groups = "slow")
     public void testBulkUpdateExperiments() throws UnsupportedEncodingException
     {
-        logIntoCommonClientService();
+        SessionContext session = logIntoCommonClientService();
 
         int expCount = 10;
         // Create some experiments to update
         ArrayList<String> expIds = registerNewExperiments(expCount);
-        String[] codes = new String[]
-        { "DESCRIPTION" };
-        String[] values = new String[]
-        { "New déscription" };
+        String[] codes = new String[] { "DESCRIPTION" };
+        String[] values = new String[] { "New déscription" };
         String bulkUpdateString = createBulkUpdateString(expIds, codes, values);
 
         // Update the experiments
-        addMultiPartFile(EXPERIMENTS_SESSION_KEY, "experiments.txt",
+        addMultiPartFile(session.getSessionID(), EXPERIMENTS_SESSION_KEY, "experiments.txt",
                 bulkUpdateString.getBytes(UnicodeUtils.DEFAULT_UNICODE_CHARSET));
         ExperimentType experimentType = new ExperimentType();
         experimentType.setCode("SIRNA_HCS");
@@ -251,19 +245,17 @@ public class ExperimentRegistrationTest extends GenericSystemTestCase
     @Test
     public void testBulkUpdateExperimentsWithProjectChanges() throws UnsupportedEncodingException
     {
-        logIntoCommonClientService();
+        SessionContext session = logIntoCommonClientService();
 
         int expCount = 10;
         // Create some experiments to update
         ArrayList<String> expIds = registerNewExperiments(expCount);
-        String[] codes = new String[]
-        { "DESCRIPTION" };
-        String[] values = new String[]
-        { "New déscription" };
+        String[] codes = new String[] { "DESCRIPTION" };
+        String[] values = new String[] { "New déscription" };
         String bulkUpdateString = createBulkUpdateString(expIds, "/cisd/nemo", codes, values);
 
         // Update the experiments
-        addMultiPartFile(EXPERIMENTS_SESSION_KEY, "experiments.txt",
+        addMultiPartFile(session.getSessionID(), EXPERIMENTS_SESSION_KEY, "experiments.txt",
                 bulkUpdateString.getBytes(UnicodeUtils.DEFAULT_UNICODE_CHARSET));
         ExperimentType experimentType = new ExperimentType();
         experimentType.setCode("SIRNA_HCS");
@@ -287,18 +279,17 @@ public class ExperimentRegistrationTest extends GenericSystemTestCase
     @Test
     public void testBulkUpdateExperimentWithSamplesWithProjectChanges()
     {
-        logIntoCommonClientService();
+        SessionContext session = logIntoCommonClientService();
 
         // Create an experiment with samples
         String batchSamplesFileContent = "identifier\torganism\n" + "S2001\tfly\n" + "S2002\tdog\n";
-        addMultiPartFile(SAMPLES_SESSION_KEY, "samples.txt", batchSamplesFileContent.getBytes());
+        addMultiPartFile(session.getSessionID(), SAMPLES_SESSION_KEY, "samples.txt", batchSamplesFileContent.getBytes());
         String experimentCode =
                 commonClientService.generateCode("EXP-WITH-PROJ", EntityKind.EXPERIMENT);
         String experimentIdentifier = "/cisd/default/" + experimentCode;
         List<String> expIds = Collections.singletonList(experimentIdentifier);
         NewExperiment newExperiment = new NewExperiment(experimentIdentifier, "SIRNA_HCS");
-        newExperiment.setProperties(new IEntityProperty[]
-        { property("DESCRIPTION", "my experiment") });
+        newExperiment.setProperties(new IEntityProperty[] { property("DESCRIPTION", "my experiment") });
         newExperiment.setRegisterSamples(true);
         SampleType sampleType = new SampleType();
         sampleType.setCode("CELL_PLATE");
@@ -313,7 +304,7 @@ public class ExperimentRegistrationTest extends GenericSystemTestCase
                 createBulkUpdateString(expIds, "/testgroup/testproj", codes, values);
 
         // Update the experiments
-        addMultiPartFile(EXPERIMENTS_SESSION_KEY, "experiments.txt", bulkUpdateString.getBytes());
+        addMultiPartFile(session.getSessionID(), EXPERIMENTS_SESSION_KEY, "experiments.txt", bulkUpdateString.getBytes());
         ExperimentType experimentType = new ExperimentType();
         experimentType.setCode("SIRNA_HCS");
         List<BatchRegistrationResult> results =
@@ -355,17 +346,15 @@ public class ExperimentRegistrationTest extends GenericSystemTestCase
     @Test
     public void testBulkUpdateExperimentsDeletingMandatoryProperty()
     {
-        logIntoCommonClientService();
+        SessionContext session = logIntoCommonClientService();
 
         int expCount = 10;
         // Create some experiments to update
         ArrayList<String> expIds = registerNewExperiments(expCount);
-        String bulkUpdateString = createBulkUpdateString(expIds, new String[]
-        { "DESCRIPTION" }, new String[]
-        { "--DELETE--" });
+        String bulkUpdateString = createBulkUpdateString(expIds, new String[] { "DESCRIPTION" }, new String[] { "--DELETE--" });
 
         // Update the experiments
-        addMultiPartFile(EXPERIMENTS_SESSION_KEY, "experiments.txt", bulkUpdateString.getBytes());
+        addMultiPartFile(session.getSessionID(), EXPERIMENTS_SESSION_KEY, "experiments.txt", bulkUpdateString.getBytes());
         ExperimentType experimentType = new ExperimentType();
         experimentType.setCode("SIRNA_HCS");
         try
@@ -383,19 +372,17 @@ public class ExperimentRegistrationTest extends GenericSystemTestCase
     public void testBulkUpdateExperimentsDeletingNonMandatoryProperty()
             throws UnsupportedEncodingException
     {
-        logIntoCommonClientService();
+        SessionContext session = logIntoCommonClientService();
 
         int expCount = 10;
         // Create some experiments to update
         ArrayList<String> expIds = registerNewExperiments(expCount);
-        String[] codes = new String[]
-        { "DESCRIPTION", "GENDER" };
-        String[] values = new String[]
-        { "New déscription", "MALE" };
+        String[] codes = new String[] { "DESCRIPTION", "GENDER" };
+        String[] values = new String[] { "New déscription", "MALE" };
         String bulkUpdateString = createBulkUpdateString(expIds, codes, values);
 
         // Add/Modify some properties
-        addMultiPartFile(EXPERIMENTS_SESSION_KEY, "experiments.txt",
+        addMultiPartFile(session.getSessionID(), EXPERIMENTS_SESSION_KEY, "experiments.txt",
                 bulkUpdateString.getBytes(UnicodeUtils.DEFAULT_UNICODE_CHARSET));
         ExperimentType experimentType = new ExperimentType();
         experimentType.setCode("SIRNA_HCS");
@@ -404,19 +391,15 @@ public class ExperimentRegistrationTest extends GenericSystemTestCase
         verifyBulkUpdate(expIds, codes, values);
 
         // Delete some properties
-        codes = new String[]
-        { "GENDER" };
-        values = new String[]
-        { "__DELETE__" };
+        codes = new String[] { "GENDER" };
+        values = new String[] { "__DELETE__" };
         bulkUpdateString = createBulkUpdateString(expIds, codes, values);
 
-        addMultiPartFile(EXPERIMENTS_SESSION_KEY, "experiments.txt",
+        addMultiPartFile(session.getSessionID(), EXPERIMENTS_SESSION_KEY, "experiments.txt",
                 bulkUpdateString.getBytes(UnicodeUtils.DEFAULT_UNICODE_CHARSET));
         genericClientService.updateExperiments(experimentType, EXPERIMENTS_SESSION_KEY, false, null);
 
-        verifyBulkUpdate(expIds, new String[]
-        { "DESCRIPTION" }, new String[]
-        { "New déscription" });
+        verifyBulkUpdate(expIds, new String[] { "DESCRIPTION" }, new String[] { "New déscription" });
     }
 
     /**
@@ -431,8 +414,7 @@ public class ExperimentRegistrationTest extends GenericSystemTestCase
                     commonClientService.generateCode("BULK-EXP", EntityKind.EXPERIMENT);
             String experimentIdentifier = "/cisd/default/" + experimentCode;
             NewExperiment newExperiment = new NewExperiment(experimentIdentifier, "SIRNA_HCS");
-            newExperiment.setProperties(new IEntityProperty[]
-            { property("DESCRIPTION", "my éxpériment") });
+            newExperiment.setProperties(new IEntityProperty[] { property("DESCRIPTION", "my éxpériment") });
             genericClientService.registerExperiment(ATTACHMENTS_SESSION_KEY, SAMPLES_SESSION_KEY,
                     newExperiment);
             expIds.add(experimentIdentifier);
diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/plugin/generic/GenericSystemTestCase.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/plugin/generic/GenericSystemTestCase.java
index eef627556d4..395ea326784 100644
--- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/plugin/generic/GenericSystemTestCase.java
+++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/plugin/generic/GenericSystemTestCase.java
@@ -22,6 +22,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.mock.web.MockMultipartFile;
 
 import ch.systemsx.cisd.openbis.generic.client.web.server.UploadedFilesBean;
+import ch.systemsx.cisd.openbis.generic.server.ISessionWorkspaceProvider;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.EntityProperty;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.IEntityProperty;
 import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType;
@@ -41,8 +42,11 @@ public class GenericSystemTestCase extends SystemTestCase
     @SuppressWarnings("hiding")
     @Autowired
     protected IGenericServer genericServer;
+    
+    @Autowired
+    protected ISessionWorkspaceProvider sessionWorkspaceProvider;
 
-    protected void addMultiPartFile(String sessionAttributeKey, String fileName, byte[] data)
+    protected void addMultiPartFile(String sessionToken, String sessionAttributeKey, String fileName, byte[] data)
     {
         HttpSession session = request.getSession();
         UploadedFilesBean uploadedFilesBean =
@@ -53,7 +57,7 @@ public class GenericSystemTestCase extends SystemTestCase
             session.setAttribute(sessionAttributeKey, uploadedFilesBean);
         }
         MockMultipartFile multipartFile = new MockMultipartFile(fileName, fileName, "", data);
-        uploadedFilesBean.addMultipartFile(multipartFile);
+        uploadedFilesBean.addMultipartFile(sessionToken, multipartFile, sessionWorkspaceProvider);
     }
 
     protected IEntityProperty property(String type, String value)
-- 
GitLab