diff --git a/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/CreateExperimentsImportTest.java b/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/CreateExperimentsImportTest.java index 8c5d208d9315b38a73e7ae4070d706f722305d35..546641eb42349436365226e481cd0c853a134c02 100644 --- a/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/CreateExperimentsImportTest.java +++ b/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/CreateExperimentsImportTest.java @@ -46,6 +46,7 @@ public class CreateExperimentsImportTest extends ObjectsImportTest ImportFile file = new ImportFile("identifier", "DESCRIPTION"); file.addLine(experimentIdentifier.getIdentifier(), "imported description"); uploadFiles(sessionToken, TEST_UPLOAD_KEY, file.toString()); + assertUploadedFiles(sessionToken, file.toString()); Experiment experiment = getObject(sessionToken, experimentIdentifier); assertNull(experiment); @@ -75,6 +76,9 @@ public class CreateExperimentsImportTest extends ObjectsImportTest assertEquals("1 experiment(s) found and registered.", message); assertNoEmails(timestamp); } + + assertUploadedFiles(sessionToken); + } finally { ExperimentDeletionOptions options = new ExperimentDeletionOptions(); diff --git a/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/CreateMaterialsImportTest.java b/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/CreateMaterialsImportTest.java index c507327c7ba2d5ee66cb616ce2d6995a4adb54e0..4c842d79324e13a949f1b8506aa00ff306a4ae72 100644 --- a/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/CreateMaterialsImportTest.java +++ b/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/CreateMaterialsImportTest.java @@ -45,6 +45,7 @@ public class CreateMaterialsImportTest extends ObjectsImportTest ImportFile file = new ImportFile("code", "DESCRIPTION"); file.addLine(materialPermId.getCode(), "imported description"); uploadFiles(sessionToken, TEST_UPLOAD_KEY, file.toString()); + assertUploadedFiles(sessionToken, file.toString()); Material material = getObject(sessionToken, materialPermId); assertNull(material); @@ -75,6 +76,9 @@ public class CreateMaterialsImportTest extends ObjectsImportTest assertEquals("Registration/update of 1 material(s) is complete.", message); assertNoEmails(timestamp); } + + assertUploadedFiles(sessionToken); + } finally { MaterialDeletionOptions options = new MaterialDeletionOptions(); diff --git a/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/CreateSamplesImportTest.java b/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/CreateSamplesImportTest.java index 83f7a31f810f3ed06dbb1bc185b63938514e760b..c4f23a444ec89d79d23d61c2f577d5ad52ef0696 100644 --- a/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/CreateSamplesImportTest.java +++ b/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/CreateSamplesImportTest.java @@ -46,6 +46,7 @@ public class CreateSamplesImportTest extends ObjectsImportTest ImportFile file = new ImportFile("identifier", "COMMENT"); file.addLine(sampleIdentifier.getIdentifier(), "imported comment"); uploadFiles(sessionToken, TEST_UPLOAD_KEY, file.toString()); + assertUploadedFiles(sessionToken, file.toString()); Sample sample = getObject(sessionToken, sampleIdentifier); assertNull(sample); @@ -76,6 +77,9 @@ public class CreateSamplesImportTest extends ObjectsImportTest assertEquals("Registration of 1 sample(s) is complete.", message); assertNoEmails(timestamp); } + + assertUploadedFiles(sessionToken); + } finally { SampleDeletionOptions options = new SampleDeletionOptions(); diff --git a/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/CustomImportTest.java b/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/CustomImportTest.java index ce545c8b938569d0ae08b3810deda520d9bea72e..165a7af966d64fde122f84897ddb8d97302b8206 100644 --- a/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/CustomImportTest.java +++ b/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/CustomImportTest.java @@ -51,6 +51,7 @@ public class CustomImportTest extends ObjectsImportTest multiPart.close(); uploadFiles(sessionToken, TEST_UPLOAD_KEY, multiPart); + assertUploadedFiles(sessionToken, "test-file-content"); DataSet dataSet = getObject(sessionToken, dataSetPermId); assertNull(dataSet); @@ -80,6 +81,9 @@ public class CustomImportTest extends ObjectsImportTest assertEquals("Import successfully completed.", message); assertNoEmails(timestamp); } + + assertUploadedFiles(sessionToken); + } finally { DataSetDeletionOptions options = new DataSetDeletionOptions(); diff --git a/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/GeneralImportTest.java b/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/GeneralImportTest.java index 8fa63d6701d77a658909327040888fdbc5ac23e0..ac838263e91c24f98e2329e7db079634bc02a69f 100644 --- a/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/GeneralImportTest.java +++ b/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/GeneralImportTest.java @@ -66,6 +66,7 @@ public class GeneralImportTest extends ObjectsImportTest multiPart.close(); uploadFiles(sessionToken, TEST_UPLOAD_KEY, multiPart); + assertUploadedFiles(sessionToken, FileUtils.readFileToString(materialsFile)); Map<String, Object> parameters = new HashMap<String, Object>(); parameters.put(PARAM_UPLOAD_KEY, TEST_UPLOAD_KEY); @@ -95,6 +96,9 @@ public class GeneralImportTest extends ObjectsImportTest assertEquals("Registration/update of 2 material(s) is complete.\nRegistration of 0 sample(s) is complete.", message); assertNoEmails(timestamp); } + + assertUploadedFiles(sessionToken); + } finally { deleteMaterials(sessionToken, materialPermId1, materialPermId2); diff --git a/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/ObjectsImportTest.java b/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/ObjectsImportTest.java index b41d7e9b67760a962e23299bd4b5fa35e374b9dd..97808fd9202e1384d5b135864bd8ab5a2968892e 100644 --- a/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/ObjectsImportTest.java +++ b/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/ObjectsImportTest.java @@ -16,6 +16,7 @@ package ch.ethz.sis.openbis.generic.dss.systemtest.api.v3; +import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -23,6 +24,7 @@ import java.util.Map; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeoutException; +import org.apache.commons.io.FileUtils; import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.api.ContentProvider; import org.eclipse.jetty.client.api.ContentResponse; @@ -85,7 +87,7 @@ public class ObjectsImportTest extends AbstractFileTest protected static final String PARAM_UPDATE_EXISTING = "updateExisting"; protected static final String PARAM_IGNORE_UNREGISTERED = "ignoreUnregistered"; - + protected static final String PARAM_CUSTOM_IMPORT_CODE = "customImportCode"; protected IApplicationServerApi as; @@ -129,6 +131,29 @@ public class ObjectsImportTest extends AbstractFileTest return uploadFiles(sessionToken, uploadSessionKey, multiPart); } + protected void assertUploadedFiles(String sessionToken, String... fileContents) throws Exception + { + File sessionWorkspaceRootDir = new File("targets/sessionWorkspace"); + File sessionWorkspace = new File(sessionWorkspaceRootDir, sessionToken); + File[] files = sessionWorkspace.listFiles(); + + List<String> expectedContents = new ArrayList<String>(Arrays.asList(fileContents)); + List<String> actualContents = new ArrayList<String>(); + + if (files != null) + { + for (File file : files) + { + actualContents.add(FileUtils.readFileToString(file)); + } + } + + expectedContents.sort(String.CASE_INSENSITIVE_ORDER); + actualContents.sort(String.CASE_INSENSITIVE_ORDER); + + assertEquals(expectedContents, actualContents); + } + protected String executeImport(String sessionToken, String operation, Map<String, Object> parameters) { CustomASServiceCode serviceId = new CustomASServiceCode("import-test"); diff --git a/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/UpdateDataSetsImportTest.java b/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/UpdateDataSetsImportTest.java index a18bb9e0d9a33481bfe57cdab1ec9b3b05c2f3e2..5c86b06f0f6478a81e9b1143e7fc46a37b3da2c2 100644 --- a/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/UpdateDataSetsImportTest.java +++ b/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/UpdateDataSetsImportTest.java @@ -78,6 +78,7 @@ public class UpdateDataSetsImportTest extends ObjectsImportTest ImportFile file = new ImportFile("code", "COMMENT"); file.addLine(dataSetPermId.getPermId(), "imported comment"); uploadFiles(sessionToken, TEST_UPLOAD_KEY, file.toString()); + assertUploadedFiles(sessionToken, file.toString()); Map<String, Object> parameters = new HashMap<String, Object>(); parameters.put(PARAM_UPLOAD_KEY, TEST_UPLOAD_KEY); @@ -104,6 +105,9 @@ public class UpdateDataSetsImportTest extends ObjectsImportTest assertEquals("1 data set(s) found and registered.", message); assertNoEmails(timestamp); } + + assertUploadedFiles(sessionToken); + } finally { DataSetDeletionOptions options = new DataSetDeletionOptions(); diff --git a/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/UpdateExperimentsImportTest.java b/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/UpdateExperimentsImportTest.java index 094fb142295cb166a518c6c46e84675cc41e9b2f..c907b907b6c980fc6a73b6c076a0a48883705b0e 100644 --- a/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/UpdateExperimentsImportTest.java +++ b/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/UpdateExperimentsImportTest.java @@ -63,6 +63,7 @@ public class UpdateExperimentsImportTest extends ObjectsImportTest ImportFile file = new ImportFile("identifier", "DESCRIPTION"); file.addLine(experimentIdentifier.getIdentifier(), "imported description"); uploadFiles(sessionToken, TEST_UPLOAD_KEY, file.toString()); + assertUploadedFiles(sessionToken, file.toString()); Map<String, Object> parameters = new HashMap<String, Object>(); parameters.put(PARAM_UPLOAD_KEY, TEST_UPLOAD_KEY); @@ -89,6 +90,9 @@ public class UpdateExperimentsImportTest extends ObjectsImportTest assertEquals("Update of 1 experiment(s) is complete.", message); assertNoEmails(timestamp); } + + assertUploadedFiles(sessionToken); + } finally { ExperimentDeletionOptions options = new ExperimentDeletionOptions(); diff --git a/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/UpdateMaterialsImportTest.java b/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/UpdateMaterialsImportTest.java index d3a8e817b86e00a179ef5b34b786fd0f4906ae87..07f9e790eab3a082cc926c487c954cc433513928 100644 --- a/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/UpdateMaterialsImportTest.java +++ b/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/UpdateMaterialsImportTest.java @@ -60,6 +60,7 @@ public class UpdateMaterialsImportTest extends ObjectsImportTest ImportFile file = new ImportFile("code", "DESCRIPTION"); file.addLine(materialPermId.getCode(), "imported description"); uploadFiles(sessionToken, TEST_UPLOAD_KEY, file.toString()); + assertUploadedFiles(sessionToken, file.toString()); Map<String, Object> parameters = new HashMap<String, Object>(); parameters.put(PARAM_UPLOAD_KEY, TEST_UPLOAD_KEY); @@ -87,6 +88,9 @@ public class UpdateMaterialsImportTest extends ObjectsImportTest assertEquals("1 material(s) updated.", message); assertNoEmails(timestamp); } + + assertUploadedFiles(sessionToken); + } finally { MaterialDeletionOptions options = new MaterialDeletionOptions(); diff --git a/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/UpdateSamplesImportTest.java b/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/UpdateSamplesImportTest.java index 01effa654c52b8463219e950b899f07bffea1540..1c873ede7468a7a63e20b14b4c1506507a2aa7d3 100644 --- a/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/UpdateSamplesImportTest.java +++ b/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/UpdateSamplesImportTest.java @@ -63,6 +63,7 @@ public class UpdateSamplesImportTest extends ObjectsImportTest ImportFile file = new ImportFile("identifier", "COMMENT"); file.addLine(sampleIdentifier.getIdentifier(), "imported comment"); uploadFiles(sessionToken, TEST_UPLOAD_KEY, file.toString()); + assertUploadedFiles(sessionToken, file.toString()); Map<String, Object> parameters = new HashMap<String, Object>(); parameters.put(PARAM_UPLOAD_KEY, TEST_UPLOAD_KEY); @@ -90,6 +91,9 @@ public class UpdateSamplesImportTest extends ObjectsImportTest assertEquals("Update of 1 sample(s) is complete.", message); assertNoEmails(timestamp); } + + assertUploadedFiles(sessionToken); + } finally { SampleDeletionOptions options = new SampleDeletionOptions(); 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 new file mode 100644 index 0000000000000000000000000000000000000000..0c090af2f6305d9a23e6f116ac09b53521b1d495 --- /dev/null +++ b/datastore_server/sourceTest/java/ch/ethz/sis/openbis/generic/dss/systemtest/api/v3/UploadServletTest.java @@ -0,0 +1,546 @@ +/* + * Copyright 2018 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.ethz.sis.openbis.generic.dss.systemtest.api.v3; + +import java.io.File; +import java.io.FileFilter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.apache.commons.io.FileUtils; +import org.eclipse.jetty.client.HttpClient; +import org.eclipse.jetty.client.api.ContentResponse; +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; +import org.testng.annotations.Test; + +import ch.ethz.sis.openbis.generic.asapi.v3.IApplicationServerApi; +import ch.systemsx.cisd.common.http.JettyHttpClientFactory; +import ch.systemsx.cisd.openbis.datastoreserver.systemtests.SystemTestCase; +import ch.systemsx.cisd.openbis.generic.client.web.server.UploadedFilesBean; +import ch.systemsx.cisd.openbis.generic.shared.util.TestInstanceHostUtils; + +/** + * @author pkupczyk + */ +public class UploadServletTest extends SystemTestCase +{ + + private static final String SERVICE_URL = TestInstanceHostUtils.getOpenBISUrl() + "/openbis/upload"; + + private static final String PARAM_SESSION_ID = "sessionID"; + + private static final String PARAM_SESSION_KEY_PREFIX = "sessionKey_"; + + private static final String PARAM_SESSION_KEYS_NUMBER = "sessionKeysNumber"; + + private static final String USER = "test"; + + private static final String PASSWORD = "password"; + + private static final String FALSE_TRUE_PROVIDER = "false-true-provider"; + + private IApplicationServerApi as; + + @BeforeClass + private void beforeClass() throws Exception + { + as = applicationContext.getBean(IApplicationServerApi.class); + } + + @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 withSessionTokenParam) throws Exception + { + String sessionToken = as.login(USER, PASSWORD); + + if (false == withSessionTokenParam) + { + initHttpSession(sessionToken); + } + + 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 (withSessionTokenParam) + { + 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(); + + assertSessionWorkspaceFiles(sessionToken, "testContent"); + } + + @Test(dataProvider = FALSE_TRUE_PROVIDER) + public void testUploadMultipleFilesUnderOneSessionKey(boolean withSessionTokenParam) throws Exception + { + String sessionToken = as.login(USER, PASSWORD); + + if (false == withSessionTokenParam) + { + initHttpSession(sessionToken); + } + + cleanSessionWorkspace(sessionToken); + + MultiPartContentProvider multipart = new MultiPartContentProvider(); + multipart.addFilePart("testFieldName1", "testFileName1", new StringContentProvider("testContent1"), null); + multipart.addFilePart("testFieldName2", "testFileName2", new StringContentProvider("testContent2"), null); + multipart.close(); + + HttpClient client = JettyHttpClientFactory.getHttpClient(); + Request request = client.newRequest(SERVICE_URL).method(HttpMethod.POST); + if (withSessionTokenParam) + { + 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(); + + assertSessionWorkspaceFiles(sessionToken, "testContent1", "testContent2"); + } + + @Test(dataProvider = FALSE_TRUE_PROVIDER) + public void testUploadMultipleFilesUnderMultipleSessionKeys(boolean withSessionTokenParam) throws Exception + { + String sessionToken = as.login(USER, PASSWORD); + + if (false == withSessionTokenParam) + { + initHttpSession(sessionToken); + } + + cleanSessionWorkspace(sessionToken); + + MultiPartContentProvider multipart = new MultiPartContentProvider(); + multipart.addFilePart("testFieldName1", "testFileName1", new StringContentProvider("testContent1"), null); + multipart.addFilePart("testFieldName2", "testFileName2", new StringContentProvider("testContent2"), null); + multipart.close(); + + HttpClient client = JettyHttpClientFactory.getHttpClient(); + Request request = client.newRequest(SERVICE_URL).method(HttpMethod.POST); + if (withSessionTokenParam) + { + request.param(PARAM_SESSION_ID, sessionToken); + } + request.param(PARAM_SESSION_KEYS_NUMBER, "2"); + request.param(PARAM_SESSION_KEY_PREFIX + "0", "testFieldName1"); + request.param(PARAM_SESSION_KEY_PREFIX + "1", "testFieldName2"); + request.content(multipart); + + request.send(); + + assertSessionWorkspaceFiles(sessionToken, "testContent1", "testContent2"); + } + + @Test + 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); + + // invalidate the session + as.logout(sessionToken); + + cleanSessionWorkspace(sessionToken); + + ContentResponse response = upload(null, "testContent"); + + assertEquals("<message type=\"error\">Session token '" + sessionToken + "' is invalid: user is not logged in.</message>", + response.getContentAsString()); + + assertSessionWorkspaceFiles(sessionToken); + } + + @Test + public void testUploadWithHttpSessionInvalidAndWithSessionTokenParamValid() throws Exception + { + String sessionToken1 = as.login(USER, PASSWORD); + + initHttpSession(sessionToken1); + + // 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 testUploadWithoutHttpSessionAndWithSessionTokenParamValid() throws Exception + { + String sessionToken = as.login(USER, PASSWORD); + cleanSessionWorkspace(sessionToken); + upload(sessionToken, "testContent"); + assertSessionWorkspaceFiles(sessionToken, "testContent"); + } + + @Test + public void testUploadWithoutHttpSessionAndWithSessionTokenParamInvalid() throws Exception + { + String sessionToken = "admin-invalidtoken"; + + cleanSessionWorkspace(sessionToken); + + ContentResponse response = upload(sessionToken, "testContent"); + + assertEquals("<message type=\"error\">Session token '" + sessionToken + "' is invalid: user is not logged in.</message>", + response.getContentAsString()); + + assertSessionWorkspaceFiles(sessionToken); + } + + @Test + public void testUploadWithoutSessionKeysNumberParam() throws Exception + { + 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_KEY_PREFIX + "0", "testFieldName"); + request.content(multipart); + + ContentResponse response = request.send(); + assertEquals("<message type=\"error\">No form field 'sessionKeysNumber' could be found in the transmitted form.</message>", + response.getContentAsString()); + } + + @Test + public void testUploadWithIncorrectSessionKeysNumberParamFormat() throws Exception + { + 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, "thisShouldBeANumber"); + request.param(PARAM_SESSION_KEY_PREFIX + "0", "testFieldName"); + request.content(multipart); + + ContentResponse response = request.send(); + assertEquals("<message type=\"error\">For input string: \"thisShouldBeANumber\"</message>", + response.getContentAsString()); + } + + @Test + public void testUploadWithoutSessionKeyPrefixParam() throws Exception + { + 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.content(multipart); + + ContentResponse response = request.send(); + + assertEquals("<message type=\"error\">No field '" + PARAM_SESSION_KEY_PREFIX + "0' could be found in the transmitted form.</message>", + response.getContentAsString()); + } + + @Test + public void testUploadWithTooFewSessionKeyPrefixParams() throws Exception + { + 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, "2"); + request.param(PARAM_SESSION_KEY_PREFIX + "0", "testFieldName"); + request.content(multipart); + + ContentResponse response = request.send(); + + assertEquals("<message type=\"error\">No field '" + PARAM_SESSION_KEY_PREFIX + "1' could be found in the transmitted form.</message>", + response.getContentAsString()); + } + + @Test + public void testUploadWithLogout() throws Exception + { + String sessionToken = as.login(USER, PASSWORD); + + upload(sessionToken, "testContent"); + + assertSessionWorkspaceFiles(sessionToken, "testContent"); + + as.logout(sessionToken); + + assertSessionWorkspaceFiles(sessionToken); + } + + private File getSessionWorkspace(String sessionToken) throws Exception + { + File sessionWorkspaceRootDir = new File("targets/sessionWorkspace"); + return new File(sessionWorkspaceRootDir, sessionToken); + } + + private void cleanSessionWorkspace(String sessionToken) throws Exception + { + File sessionWorkspace = getSessionWorkspace(sessionToken); + + if (sessionWorkspace.exists()) + { + FileUtils.deleteQuietly(sessionWorkspace); + } + + assertSessionWorkspaceFiles(sessionToken); + } + + private void assertSessionWorkspaceFiles(String sessionToken, String... fileContents) throws Exception + { + assertFiles(getSessionWorkspace(sessionToken).listFiles(), fileContents); + } + + private void initHttpSession(String sessionToken) throws Exception + { + // upload a dummy file to initialize HTTP session + MultiPartContentProvider multipart = new MultiPartContentProvider(); + multipart.addFilePart("initHttpSession", "initHttpSession", new StringContentProvider("initHttpSession"), 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", "initHttpSession"); + request.content(multipart); + + 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")); + } + + private void cleanOSTempFolder() throws Exception + { + File tempFolder = getOSTempFolder(); + + if (tempFolder.exists()) + { + File[] files = tempFolder.listFiles(new OSTempFolderFileFilter()); + + for (File file : files) + { + FileUtils.deleteQuietly(file); + } + } + + assertOSTempFolderFiles(); + } + + private void assertOSTempFolderFiles(String... fileContents) throws Exception + { + assertFiles(getOSTempFolder().listFiles(new OSTempFolderFileFilter()), fileContents); + } + + private void assertFiles(File[] files, String... fileContents) throws Exception + { + List<String> expectedContents = new ArrayList<String>(Arrays.asList(fileContents)); + List<String> actualContents = new ArrayList<String>(); + + if (files != null) + { + for (File file : files) + { + actualContents.add(FileUtils.readFileToString(file)); + } + } + + expectedContents.sort(String.CASE_INSENSITIVE_ORDER); + actualContents.sort(String.CASE_INSENSITIVE_ORDER); + + assertEquals(expectedContents, actualContents); + } + + private static class OSTempFolderFileFilter implements FileFilter + { + + @Override + public boolean accept(File file) + { + return file.getName().startsWith(UploadedFilesBean.class.getSimpleName()); + } + + } + + @DataProvider(name = FALSE_TRUE_PROVIDER) + public static Object[][] provideFalseTrue() + { + return new Object[][] { { false }, { true } }; + } + +} 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 2653065254d88b053deb7b3d32fb5970588fb8b7..ec75339114fc6280248e7d3527d9e0327048ffa9 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 @@ -29,6 +29,7 @@ import javax.servlet.http.HttpSession; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.HttpSessionRequiredException; import org.springframework.web.bind.annotation.RequestMapping; @@ -45,6 +46,7 @@ import ch.systemsx.cisd.common.logging.LogFactory; import ch.systemsx.cisd.openbis.generic.server.ComponentNames; import ch.systemsx.cisd.openbis.generic.server.SessionConstants; import ch.systemsx.cisd.openbis.generic.shared.IOpenBisSessionManager; +import ch.systemsx.cisd.openbis.generic.shared.ISessionWorkspaceProvider; import ch.systemsx.cisd.openbis.generic.shared.dto.Session; /** @@ -65,8 +67,7 @@ import ch.systemsx.cisd.openbis.generic.shared.dto.Session; * @author Christian Ribeaud */ @Controller -@RequestMapping( -{ "/upload", "/openbis/upload" }) +@RequestMapping({ "/upload", "/openbis/upload" }) public final class UploadServiceServlet extends AbstractController { private static final Logger operationLog = LogFactory.getLogger(LogCategory.OPERATION, @@ -77,22 +78,27 @@ public final class UploadServiceServlet extends AbstractController @Resource(name = ComponentNames.SESSION_MANAGER) protected IOpenBisSessionManager sessionManager; + @Autowired + 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" }) + @SuppressWarnings({ "unchecked", "rawtypes" }) private final static Iterator<String> cast(final Iterator iterator) { return iterator; @@ -192,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 = @@ -208,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(session, multipartRequest, sessionKey); + sessionFilesSetter.addFilesToSession(session, multipartRequest, sessionKey, sessionWorkspaceProvider); atLeastOneFileUploaded = atLeastOneFileUploaded || fileExtracted; } if (atLeastOneFileUploaded == false) @@ -247,7 +258,7 @@ public final class UploadServiceServlet extends AbstractController * @return <code>true</code> if at least one file has been found and added */ public boolean addFilesToSession(final HttpSession session, - final MultipartHttpServletRequest multipartRequest, String sessionKey); + final MultipartHttpServletRequest multipartRequest, String sessionKey, ISessionWorkspaceProvider sessionWorkspaceProvider); } @Private @@ -255,19 +266,22 @@ public final class UploadServiceServlet extends AbstractController { @Override public boolean addFilesToSession(final HttpSession session, - final MultipartHttpServletRequest multipartRequest, String sessionKey) + final MultipartHttpServletRequest multipartRequest, String sessionKey, ISessionWorkspaceProvider sessionWorkspaceProvider) { return addFilesToSessionUsingBean(session, multipartRequest, sessionKey, - new UploadedFilesBean()); + new UploadedFilesBean(), sessionWorkspaceProvider); } @Private boolean addFilesToSessionUsingBean(final HttpSession session, final MultipartHttpServletRequest multipartRequest, String sessionKey, - final UploadedFilesBean uploadedFiles) + 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(); /**/) { @@ -277,7 +291,7 @@ public final class UploadServiceServlet extends AbstractController final MultipartFile multipartFile = multipartRequest.getFile(fileName); if (multipartFile.isEmpty() == false) { - uploadedFiles.addMultipartFile(multipartFile); + uploadedFiles.addMultipartFile(sessionToken, multipartFile, sessionWorkspaceProvider); fileUploaded = true; } } 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 37d717f34299111e7e1b91a92463df1ac1e51e20..ff6bddbe40a5366f903772bc5e1ba65123cc0735 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,11 +23,15 @@ 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.openbis.common.spring.IUncheckedMultipartFile; import ch.systemsx.cisd.openbis.common.spring.MultipartFileAdapter; +import ch.systemsx.cisd.openbis.generic.shared.ISessionWorkspaceProvider; /** * A bean that contains the uploaded files. @@ -36,24 +40,31 @@ import ch.systemsx.cisd.openbis.common.spring.MultipartFileAdapter; */ 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() throws IOException + private final File createTempFile(String sessionToken, ISessionWorkspaceProvider sessionWorkspaceProvider) throws IOException { - final File tempFile = File.createTempFile(CLASS_SIMPLE_NAME, null); + 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) + public final void addMultipartFile(String sessionToken, final MultipartFile multipartFile, ISessionWorkspaceProvider sessionWorkspaceProvider) { assert multipartFile != null : "Unspecified multipart file."; try { - final File tempFile = createTempFile(); + final File tempFile = createTempFile(sessionToken, sessionWorkspaceProvider); multipartFile.transferTo(tempFile); + + operationLog.info("Uploaded file '" + multipartFile.getOriginalFilename() + "' to session workspace"); + final FileMultipartFileAdapter multipartFileAdapter = new FileMultipartFileAdapter(multipartFile, tempFile); multipartFiles.add(multipartFileAdapter); diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/AbstractServer.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/AbstractServer.java index 8a889f811abcf6e6680d812240c5043e607707a6..70bc7cac8f3539fb391f5f37b9d89eec72c122eb 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/AbstractServer.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/AbstractServer.java @@ -65,6 +65,7 @@ import ch.systemsx.cisd.openbis.generic.server.plugin.SampleServerPluginRegistry import ch.systemsx.cisd.openbis.generic.shared.IOpenBisSessionManager; import ch.systemsx.cisd.openbis.generic.shared.IRemoteHostValidator; import ch.systemsx.cisd.openbis.generic.shared.IServer; +import ch.systemsx.cisd.openbis.generic.shared.ISessionWorkspaceProvider; import ch.systemsx.cisd.openbis.generic.shared.ResourceNames; import ch.systemsx.cisd.openbis.generic.shared.authorization.IAuthorizationConfig; import ch.systemsx.cisd.openbis.generic.shared.basic.EntityVisitComparatorByTimeStamp; @@ -171,6 +172,9 @@ public abstract class AbstractServer<T> extends AbstractServiceWithLogger<T> imp @Autowired private IAuthorizationConfig authorizationConfig; + @Autowired + private ISessionWorkspaceProvider sessionWorkspaceProvider; + private IApplicationServerApi v3Api; protected String CISDHelpdeskEmail; @@ -207,6 +211,12 @@ public abstract class AbstractServer<T> extends AbstractServiceWithLogger<T> imp this.displaySettingsProvider = displaySettingsProvider; } + // For unit tests - in production Spring will inject this object. + public void setSessionWorkspaceProvider(ISessionWorkspaceProvider sessionWorkspaceProvider) + { + this.sessionWorkspaceProvider = sessionWorkspaceProvider; + } + // For unit tests - in production Spring will inject this object. public void setDssFactory(IDataStoreServiceFactory dssFactory) { @@ -407,6 +417,7 @@ public abstract class AbstractServer<T> extends AbstractServiceWithLogger<T> imp try { sessionManager.closeSession(sessionToken); + sessionWorkspaceProvider.deleteSessionWorkspace(sessionToken); SessionFactory.cleanUpSessionOnDataStoreServers(sessionToken, daoFactory.getDataStoreDAO(), dssFactory); } catch (InvalidSessionException e) @@ -422,6 +433,7 @@ public abstract class AbstractServer<T> extends AbstractServiceWithLogger<T> imp try { sessionManager.expireSession(sessionToken); + sessionWorkspaceProvider.deleteSessionWorkspace(sessionToken); SessionFactory.cleanUpSessionOnDataStoreServers(sessionToken, daoFactory.getDataStoreDAO(), dssFactory); } catch (InvalidSessionException e) @@ -929,8 +941,9 @@ public abstract class AbstractServer<T> extends AbstractServiceWithLogger<T> imp if (person != null) { SpacePE homeGroup = - groupIdOrNull == null ? null : getDAOFactory().getSpaceDAO().getByTechId( - groupIdOrNull); + groupIdOrNull == null ? null + : getDAOFactory().getSpaceDAO().getByTechId( + groupIdOrNull); person.setHomeSpace(homeGroup); getDAOFactory().getPersonDAO().updatePerson(person); } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServerLogger.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServerLogger.java index 3dd15b719ba57b9ed7d79ce21161b72eb05b3d34..7b7c8d83a92fa5673decdc6818fa67409be80af6 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServerLogger.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/CommonServerLogger.java @@ -1636,7 +1636,7 @@ final class CommonServerLogger extends AbstractServerLogger implements ICommonSe DatastoreServiceDescription serviceDescription, Map<String, Object> parameters) { logAccess(sessionToken, "createReportFromAggregationService", - "SERVICE(%s), PARAMETERS(%s)", serviceDescription, parameters); + "SERVICE(%s), PARAMETERS(%s)", serviceDescription, parameters != null ? parameters.keySet() : "[]"); return null; } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/MaintenanceTaskStarter.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/MaintenanceTaskStarter.java index 72d100cc90bcc7dff3c84acb1860ac814b1e3d90..82c2ccae73a9f6e73efc5ecac1d139005d24c693 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/MaintenanceTaskStarter.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/MaintenanceTaskStarter.java @@ -42,6 +42,7 @@ import ch.systemsx.cisd.common.maintenance.MaintenancePlugin; import ch.systemsx.cisd.common.maintenance.MaintenanceTaskParameters; import ch.systemsx.cisd.common.maintenance.MaintenanceTaskUtils; import ch.systemsx.cisd.common.spring.ExposablePropertyPlaceholderConfigurer; +import ch.systemsx.cisd.openbis.generic.server.task.SessionWorkspaceCleanUpMaintenanceTask; /** * Configures and starts maintenance tasks. @@ -101,6 +102,15 @@ public class MaintenanceTaskStarter implements ApplicationContextAware, Initiali operationExecutionConfig.getMarkTimedOutOrDeletedTaskInterval()); } + if (false == isTaskConfigured(tasks, SessionWorkspaceCleanUpMaintenanceTask.class)) + { + tasks = addTask(tasks, + SessionWorkspaceCleanUpMaintenanceTask.class, + SessionWorkspaceCleanUpMaintenanceTask.DEFAULT_MAINTENANCE_TASK_NAME, + false, + SessionWorkspaceCleanUpMaintenanceTask.DEFAULT_MAINTENANCE_TASK_INTERVAL); + } + plugins = MaintenanceTaskUtils.startupMaintenancePlugins(tasks); } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/SessionFactory.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/SessionFactory.java index 501d80455368bc449752077e05016f23a8869b95..ecf7550f724b28afd3655fa249c41608eea07c30 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/SessionFactory.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/SessionFactory.java @@ -27,6 +27,7 @@ import ch.systemsx.cisd.common.shared.basic.string.StringUtils; import ch.systemsx.cisd.openbis.generic.server.business.IDataStoreServiceFactory; import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory; import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDataStoreDAO; +import ch.systemsx.cisd.openbis.generic.shared.ISessionWorkspaceProvider; import ch.systemsx.cisd.openbis.generic.shared.dto.DataStorePE; import ch.systemsx.cisd.openbis.generic.shared.dto.Session; import ch.systemsx.cisd.openbis.generic.shared.dto.Session.ISessionCleaner; @@ -45,15 +46,18 @@ public final class SessionFactory implements ISessionFactory<Session> private final IDataStoreServiceFactory dssFactory; + private final ISessionWorkspaceProvider sessionWorkspaceProvider; + public SessionFactory() { - this(null, null); + this(null, null, null); } - public SessionFactory(IDAOFactory daoFactory, IDataStoreServiceFactory dssFactory) + public SessionFactory(IDAOFactory daoFactory, IDataStoreServiceFactory dssFactory, ISessionWorkspaceProvider sessionWorkspaceProvider) { this.datastoreDAO = (daoFactory != null) ? daoFactory.getDataStoreDAO() : null; this.dssFactory = dssFactory; + this.sessionWorkspaceProvider = sessionWorkspaceProvider; } // @@ -75,6 +79,7 @@ public final class SessionFactory implements ISessionFactory<Session> @Override public void cleanup() { + sessionWorkspaceProvider.deleteSessionWorkspace(sessionToken); cleanUpSessionOnDataStoreServers(sessionToken, datastoreDAO, dssFactory); } }); diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/task/SessionWorkspaceCleanUpMaintenanceTask.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/task/SessionWorkspaceCleanUpMaintenanceTask.java new file mode 100644 index 0000000000000000000000000000000000000000..61f78fbc6a39675a2524b340ea2f1cd6f3571cc7 --- /dev/null +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/server/task/SessionWorkspaceCleanUpMaintenanceTask.java @@ -0,0 +1,87 @@ +/* + * Copyright 2018 ETH Zuerich, SIS + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.openbis.generic.server.task; + +import java.io.File; +import java.util.Map; +import java.util.Properties; + +import org.apache.log4j.Logger; + +import ch.ethz.sis.openbis.generic.asapi.v3.IApplicationServerApi; +import ch.systemsx.cisd.common.logging.LogCategory; +import ch.systemsx.cisd.common.logging.LogFactory; +import ch.systemsx.cisd.common.maintenance.IMaintenanceTask; +import ch.systemsx.cisd.openbis.generic.server.CommonServiceProvider; +import ch.systemsx.cisd.openbis.generic.shared.ISessionWorkspaceProvider; +import ch.systemsx.cisd.openbis.generic.shared.SessionWorkspaceProvider; + +/** + * @author pkupczyk + */ +public class SessionWorkspaceCleanUpMaintenanceTask implements IMaintenanceTask +{ + + public static final String DEFAULT_MAINTENANCE_TASK_NAME = "session-workspace-clean-up-task"; + + public static final int DEFAULT_MAINTENANCE_TASK_INTERVAL = 3600; + + private static final Logger operationLog = LogFactory.getLogger(LogCategory.OPERATION, + SessionWorkspaceCleanUpMaintenanceTask.class); + + private IApplicationServerApi applicationServerApi; + + private ISessionWorkspaceProvider sessionWorkspaceProvider; + + public SessionWorkspaceCleanUpMaintenanceTask() + { + this(CommonServiceProvider.getApplicationServerApi(), + (ISessionWorkspaceProvider) CommonServiceProvider.tryToGetBean(SessionWorkspaceProvider.INTERNAL_SERVICE_NAME)); + } + + SessionWorkspaceCleanUpMaintenanceTask(IApplicationServerApi applicationServerApi, ISessionWorkspaceProvider sessionWorkspaceProvider) + { + this.applicationServerApi = applicationServerApi; + this.sessionWorkspaceProvider = sessionWorkspaceProvider; + } + + @Override + public void setUp(String pluginName, Properties properties) + { + operationLog.info("Setup plugin " + pluginName); + } + + @Override + public void execute() + { + Map<String, File> sessionWorkspaces = sessionWorkspaceProvider.getSessionWorkspaces(); + int count = 0; + + for (String sessionToken : sessionWorkspaces.keySet()) + { + if (false == applicationServerApi.isSessionActive(sessionToken)) + { + operationLog.info("Session '" + sessionToken + "' is no longer active. Its session workspace will be removed."); + sessionWorkspaceProvider.deleteSessionWorkspace(sessionToken); + count++; + } + } + + operationLog.info("Session workspace clean up finished. Removed " + count + " workspace(s) of inactive session(s)."); + } + +} diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/ISessionWorkspaceProvider.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/ISessionWorkspaceProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..f56cb5851b5827ce9e9b9887e96c8a4bb0f13ccb --- /dev/null +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/ISessionWorkspaceProvider.java @@ -0,0 +1,34 @@ +/* + * Copyright 2018 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.openbis.generic.shared; + +import java.io.File; +import java.util.Map; + +/** + * @author pkupczyk + */ +public interface ISessionWorkspaceProvider +{ + + Map<String, File> getSessionWorkspaces(); + + File getSessionWorkspace(String sessionToken); + + void deleteSessionWorkspace(String sessionToken); + +} diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/SessionWorkspaceProvider.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/SessionWorkspaceProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..6c87f705aa22dfb68bc613035d07b55e616f9984 --- /dev/null +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/shared/SessionWorkspaceProvider.java @@ -0,0 +1,149 @@ +/* + * Copyright 2018 ETH Zuerich, CISD + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.openbis.generic.shared; + +import java.io.File; +import java.io.FileFilter; +import java.util.Map; +import java.util.Properties; +import java.util.TreeMap; + +import javax.annotation.PostConstruct; +import javax.annotation.Resource; + +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + +import ch.systemsx.cisd.common.filesystem.QueueingPathRemoverService; +import ch.systemsx.cisd.common.logging.LogCategory; +import ch.systemsx.cisd.common.logging.LogFactory; +import ch.systemsx.cisd.common.properties.PropertyUtils; +import ch.systemsx.cisd.common.spring.ExposablePropertyPlaceholderConfigurer; + +/** + * @author pkupczyk + */ +@Component(value = SessionWorkspaceProvider.INTERNAL_SERVICE_NAME) +public class SessionWorkspaceProvider implements ISessionWorkspaceProvider +{ + + public static final String INTERNAL_SERVICE_NAME = "session-workspace-provider"; + + public static final String SESSION_WORKSPACE_ROOT_DIR_KEY = "session-workspace-root-dir"; + + public static final String SESSION_WORKSPACE_ROOT_DIR_DEFAULT = "sessionWorkspace"; + + public static final String SESSION_WORKSPACE_SHREDDER_QUEUE_FILE = ".shredder"; + + private static final Logger operationLog = LogFactory.getLogger(LogCategory.OPERATION, SessionWorkspaceProvider.class); + + private Properties serviceProperties; + + private File sessionWorkspaceRootDir; + + public SessionWorkspaceProvider() + { + } + + SessionWorkspaceProvider(Properties serviceProperties) + { + this.serviceProperties = serviceProperties; + } + + @PostConstruct + void init() throws Exception + { + String sessionWorkspaceRootDirString = + PropertyUtils.getProperty(serviceProperties, SESSION_WORKSPACE_ROOT_DIR_KEY, SESSION_WORKSPACE_ROOT_DIR_DEFAULT); + sessionWorkspaceRootDir = new File(sessionWorkspaceRootDirString); + + operationLog.info("Session workspace root dir '" + sessionWorkspaceRootDir.getCanonicalPath() + "'"); + + if (false == sessionWorkspaceRootDir.exists()) + { + sessionWorkspaceRootDir.mkdirs(); + } + + QueueingPathRemoverService.start(sessionWorkspaceRootDir, new File(SESSION_WORKSPACE_SHREDDER_QUEUE_FILE)); + + operationLog.info("Session workspace shredder service started"); + } + + @Override + public Map<String, File> getSessionWorkspaces() + { + File[] sessionWorkspaces = sessionWorkspaceRootDir.listFiles(new FileFilter() + { + @Override + public boolean accept(File file) + { + return false == file.isHidden(); + } + }); + + Map<String, File> map = new TreeMap<String, File>(); + + if (sessionWorkspaces != null) + { + for (File sessionWorkspace : sessionWorkspaces) + { + map.put(sessionWorkspace.getName(), sessionWorkspace); + } + } + + return map; + } + + @Override + public File getSessionWorkspace(String sessionToken) + { + File sessionWorkspace = new File(sessionWorkspaceRootDir, sessionToken); + + if (false == sessionWorkspace.exists()) + { + sessionWorkspace.mkdirs(); + operationLog.info("Session workspace created"); + } + + return sessionWorkspace; + } + + @Override + public void deleteSessionWorkspace(String sessionToken) + { + try + { + File sessionWorkspace = new File(sessionWorkspaceRootDir, sessionToken); + + if (sessionWorkspace.exists()) + { + QueueingPathRemoverService.removeRecursively(sessionWorkspace); + operationLog.info("Session workspace added to shredder queue"); + } + } catch (Exception e) + { + operationLog.warn("Session workspace could not be shredded", e); + } + } + + @Resource(name = ExposablePropertyPlaceholderConfigurer.PROPERTY_CONFIGURER_BEAN_NAME) + private void setServicePropertiesPlaceholder(ExposablePropertyPlaceholderConfigurer servicePropertiesPlaceholder) + { + serviceProperties = servicePropertiesPlaceholder.getResolvedProps(); + } + +} diff --git a/openbis/source/java/genericApplicationContext.xml b/openbis/source/java/genericApplicationContext.xml index 362ea3aeb071cef72f782074b3846b749201c9cb..331b13663100be01b1589ba339f0d0e9f69c4e11 100644 --- a/openbis/source/java/genericApplicationContext.xml +++ b/openbis/source/java/genericApplicationContext.xml @@ -130,6 +130,7 @@ <bean class="ch.systemsx.cisd.openbis.generic.server.SessionFactory"> <constructor-arg ref="dao-factory" /> <constructor-arg ref="dss-factory" /> + <constructor-arg ref="session-workspace-provider" /> </bean> </constructor-arg> <constructor-arg> diff --git a/openbis/source/java/service.properties b/openbis/source/java/service.properties index 568792007cb475125e82621cc4091c25f46bd520..3aa53d026290fa8be24873ec2ed1efa38c7c405e 100644 --- a/openbis/source/java/service.properties +++ b/openbis/source/java/service.properties @@ -20,6 +20,8 @@ create-continuous-sample-codes = false data-set-types-with-no-experiment-needed = (?!REQUIRES\\_EXPERIMENT).* +session-workspace-root-dir = targets/sessionWorkspace + # Supported: currently only 'postgresql' is supported database.engine = postgresql database.create-from-scratch = false 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 24d96d6c23b126b885e10d5fa7412a2551bf0ede..9cc20a3e906aff4497c65c8519feaed561b93c4b 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,14 +33,15 @@ 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.shared.IOpenBisSessionManager; +import ch.systemsx.cisd.openbis.generic.shared.ISessionWorkspaceProvider; /** * Tests for {@link UploadServiceServlet}. * * @author Izabela Adamczyk */ -@Friend(toClasses = -{ UploadServiceServlet.class, ISessionFilesSetter.class, SessionFilesSetter.class }) +@Friend(toClasses = { UploadServiceServlet.class, ISessionFilesSetter.class, SessionFilesSetter.class }) public final class UploadServiceServletTest extends AssertJUnit { @@ -50,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; @@ -62,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() { @@ -72,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 @@ -85,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) @@ -98,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 @@ -231,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); + one(sessionFilesSetter).addFilesToSession(httpSession, multipartHttpServletRequest, sessionKey, sessionWorkspaceProvider); will(returnValue(false)); } @@ -269,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); + one(sessionFilesSetter).addFilesToSession(httpSession, multipartHttpServletRequest, sessionKey, sessionWorkspaceProvider); will(returnValue(true)); } expectSendResponse(this); @@ -299,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); + one(sessionFilesSetter).addFilesToSession(httpSession, multipartHttpServletRequest, sessionKey, sessionWorkspaceProvider); will(returnValue(i != numberOfSessionKeys - 1)); } expectSendResponse(this); diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/CommonServerTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/CommonServerTest.java index 743befe3899775a2d2ea1063c23ceec7fa2dfbb1..0b29a6d131cc16cfafedcc6206b5b4f4aedaa638 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/CommonServerTest.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/CommonServerTest.java @@ -52,6 +52,7 @@ import ch.systemsx.cisd.openbis.generic.server.plugin.ISampleTypeSlaveServerPlug import ch.systemsx.cisd.openbis.generic.shared.AbstractServerTestCase; import ch.systemsx.cisd.openbis.generic.shared.CommonTestUtils; import ch.systemsx.cisd.openbis.generic.shared.IDataStoreService; +import ch.systemsx.cisd.openbis.generic.shared.ISessionWorkspaceProvider; import ch.systemsx.cisd.openbis.generic.shared.basic.TechId; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.AbstractExternalData; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.BatchOperationKind; @@ -165,6 +166,8 @@ public final class CommonServerTest extends AbstractServerTestCase private org.hibernate.Session hibernateSession; + private ISessionWorkspaceProvider sessionWorkspaceProvider; + private final CommonServer createServer() { CommonServer server = @@ -189,6 +192,7 @@ public final class CommonServerTest extends AbstractServerTestCase server.setDataSetTypeSlaveServerPlugin(dataSetTypeSlaveServerPlugin); server.setBaseIndexURL(SESSION_TOKEN, BASE_INDEX_URL); server.setDisplaySettingsProvider(new DisplaySettingsProvider()); + server.setSessionWorkspaceProvider(sessionWorkspaceProvider); return server; } @@ -215,6 +219,7 @@ public final class CommonServerTest extends AbstractServerTestCase hotDeploymentController = context.mock(IHotDeploymentController.class); hibernateSessionFactory = context.mock(SessionFactory.class); hibernateSession = context.mock(org.hibernate.Session.class); + sessionWorkspaceProvider = context.mock(ISessionWorkspaceProvider.class); } @Test @@ -275,6 +280,8 @@ public final class CommonServerTest extends AbstractServerTestCase will(returnValue(dataStoreService)); one(dataStoreService).cleanupSession(SESSION_TOKEN); + + one(sessionWorkspaceProvider).deleteSessionWorkspace(SESSION_TOKEN); } }); diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/task/SessionWorkspaceCleanUpMaintenanceTaskTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/task/SessionWorkspaceCleanUpMaintenanceTaskTest.java new file mode 100644 index 0000000000000000000000000000000000000000..8b4ec62971e0ea1029a2a9bdb9e8ba2a41fa68e1 --- /dev/null +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/server/task/SessionWorkspaceCleanUpMaintenanceTaskTest.java @@ -0,0 +1,123 @@ +/* + * Copyright 2018 ETH Zuerich, SIS + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ch.systemsx.cisd.openbis.generic.server.task; + +import java.io.File; +import java.util.HashMap; +import java.util.Map; + +import org.apache.log4j.Level; +import org.jmock.Expectations; +import org.jmock.Mockery; +import org.testng.AssertJUnit; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import ch.ethz.sis.openbis.generic.asapi.v3.IApplicationServerApi; +import ch.systemsx.cisd.common.logging.BufferedAppender; +import ch.systemsx.cisd.common.test.AssertionUtil; +import ch.systemsx.cisd.openbis.generic.shared.ISessionWorkspaceProvider; +import ch.systemsx.cisd.openbis.util.LogRecordingUtils; + +/** + * @author pkupczyk + */ +public class SessionWorkspaceCleanUpMaintenanceTaskTest extends AssertJUnit +{ + + private BufferedAppender logRecorder; + + private Mockery context; + + private IApplicationServerApi applicationServerApi; + + private ISessionWorkspaceProvider sessionWorkspaceProvider; + + @BeforeMethod + public void setUp() + { + logRecorder = LogRecordingUtils.createRecorder("%-5p %c - %m%n", Level.INFO); + + context = new Mockery(); + applicationServerApi = context.mock(IApplicationServerApi.class); + sessionWorkspaceProvider = context.mock(ISessionWorkspaceProvider.class); + } + + @AfterMethod + public void tearDown() + { + context.assertIsSatisfied(); + } + + @Test + public void testExecuteWithNoWorkspaces() + { + Map<String, File> sessionWorkspaces = new HashMap<String, File>(); + + context.checking(new Expectations() + { + { + one(sessionWorkspaceProvider).getSessionWorkspaces(); + will(returnValue(sessionWorkspaces)); + } + }); + + SessionWorkspaceCleanUpMaintenanceTask task = new SessionWorkspaceCleanUpMaintenanceTask(applicationServerApi, sessionWorkspaceProvider); + task.execute(); + + AssertionUtil.assertContainsLines( + "INFO OPERATION.SessionWorkspaceCleanUpMaintenanceTask - Session workspace clean up finished. Removed 0 workspace(s) of inactive session(s).", + logRecorder.getLogContent()); + } + + @Test + public void testExecuteWithMultipleWorkspaces() + { + Map<String, File> sessionWorkspaces = new HashMap<String, File>(); + sessionWorkspaces.put("token1", new File("workspace1")); + sessionWorkspaces.put("token2", new File("workspace2")); + + context.checking(new Expectations() + { + { + one(sessionWorkspaceProvider).getSessionWorkspaces(); + will(returnValue(sessionWorkspaces)); + + one(applicationServerApi).isSessionActive("token1"); + will(returnValue(true)); + + one(applicationServerApi).isSessionActive("token2"); + will(returnValue(false)); + + one(sessionWorkspaceProvider).deleteSessionWorkspace("token2"); + } + }); + + SessionWorkspaceCleanUpMaintenanceTask task = new SessionWorkspaceCleanUpMaintenanceTask(applicationServerApi, sessionWorkspaceProvider); + task.execute(); + + AssertionUtil.assertContainsLines( + "INFO OPERATION.SessionWorkspaceCleanUpMaintenanceTask - Session 'token2' is no longer active. Its session workspace will be removed.", + logRecorder.getLogContent()); + + AssertionUtil.assertContainsLines( + "INFO OPERATION.SessionWorkspaceCleanUpMaintenanceTask - Session workspace clean up finished. Removed 1 workspace(s) of inactive session(s).", + logRecorder.getLogContent()); + } + +} diff --git a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/SessionWorkspaceProviderTest.java b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/SessionWorkspaceProviderTest.java new file mode 100644 index 0000000000000000000000000000000000000000..fa093842df0e0735b460425e32b119238fe22926 --- /dev/null +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/generic/shared/SessionWorkspaceProviderTest.java @@ -0,0 +1,96 @@ +package ch.systemsx.cisd.openbis.generic.shared; + +import java.io.File; +import java.util.Map; +import java.util.Properties; + +import org.apache.commons.io.FileUtils; +import org.testng.annotations.Test; + +import ch.systemsx.cisd.base.tests.AbstractFileSystemTestCase; +import ch.systemsx.cisd.openbis.generic.shared.SessionWorkspaceProvider; + +public class SessionWorkspaceProviderTest extends AbstractFileSystemTestCase +{ + + @Test + public void testGetSessionWorkspace() throws Exception + { + Properties properties = new Properties(); + properties.setProperty(SessionWorkspaceProvider.SESSION_WORKSPACE_ROOT_DIR_KEY, workingDirectory.getPath()); + + SessionWorkspaceProvider provider = new SessionWorkspaceProvider(properties); + provider.init(); + + Map<String, File> sessionWorkspaces = provider.getSessionWorkspaces(); + assertEquals("[]", sessionWorkspaces.keySet().toString()); + + File sessionWorkspace = provider.getSessionWorkspace("token"); + + sessionWorkspaces = provider.getSessionWorkspaces(); + assertEquals("[token]", sessionWorkspaces.keySet().toString()); + + assertEquals(true, sessionWorkspace.exists()); + assertEquals(workingDirectory, sessionWorkspace.getParentFile()); + } + + @Test + public void testGetSessionWorkspaces() throws Exception + { + Properties properties = new Properties(); + properties.setProperty(SessionWorkspaceProvider.SESSION_WORKSPACE_ROOT_DIR_KEY, workingDirectory.getPath()); + + SessionWorkspaceProvider provider = new SessionWorkspaceProvider(properties); + provider.init(); + + Map<String, File> sessionWorkspaces = provider.getSessionWorkspaces(); + assertEquals("[]", sessionWorkspaces.keySet().toString()); + + provider.getSessionWorkspace("token1"); + provider.getSessionWorkspace("token2"); + + sessionWorkspaces = provider.getSessionWorkspaces(); + assertEquals("[token1, token2]", sessionWorkspaces.keySet().toString()); + + provider.deleteSessionWorkspace("token1"); + + sessionWorkspaces = provider.getSessionWorkspaces(); + assertEquals("[token2]", sessionWorkspaces.keySet().toString()); + } + + @Test + public void testDeleteSessionWorkspace() throws Exception + { + Properties properties = new Properties(); + properties.setProperty(SessionWorkspaceProvider.SESSION_WORKSPACE_ROOT_DIR_KEY, workingDirectory.getPath()); + + SessionWorkspaceProvider provider = new SessionWorkspaceProvider(properties); + provider.init(); + + File workspace1 = provider.getSessionWorkspace("token1"); + File workspace2 = provider.getSessionWorkspace("token2"); + + FileUtils.writeStringToFile(new File(workspace1, "file1A"), "1A"); + FileUtils.writeStringToFile(new File(workspace1, "file1B"), "1B"); + FileUtils.writeStringToFile(new File(workspace2, "file2"), "2"); + + Map<String, File> sessionWorkspaces = provider.getSessionWorkspaces(); + assertEquals("[token1, token2]", sessionWorkspaces.keySet().toString()); + + provider.deleteSessionWorkspace("token1"); + + sessionWorkspaces = provider.getSessionWorkspaces(); + assertEquals("[token2]", sessionWorkspaces.keySet().toString()); + + provider.deleteSessionWorkspace("token2"); + + sessionWorkspaces = provider.getSessionWorkspaces(); + assertEquals("[]", sessionWorkspaces.keySet().toString()); + + provider.deleteSessionWorkspace("token3"); + + sessionWorkspaces = provider.getSessionWorkspaces(); + assertEquals("[]", sessionWorkspaces.keySet().toString()); + } + +} 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 353a2e618a25c4121c5833e61815ecf7c4fdcd40..2edd89dc413ba15bbf179fe38766bf15f5967e3c 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 @@ -41,6 +41,7 @@ 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.shared.CommonTestUtils; +import ch.systemsx.cisd.openbis.generic.shared.ISessionWorkspaceProvider; import ch.systemsx.cisd.openbis.generic.shared.basic.TechId; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.AbstractExternalData; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.BatchRegistrationResult; @@ -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 a6520506bad7a202ec2954b545791b72b7f4e054..14494385d0ce07a21b0fbe68abba4e069596840e 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 ebe26ec25ff0c10683e47ad4aa0cd512a5cc6c7b..aef439063117011566a41d734ee26ff208fb3b5a 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 95fb668d1f06cf59f34e42e6cf24986fc6aacb00..3bafe97a7f7b21c1b77f3495c53e1e8b845692d0 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 0601e65dc652c56efbc3d56a0a2cc716ab517e54..5b4a5fa56010cfc21b822c7dfb5a907f1e2ea016 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 135f56f85ab26cf9175d166c1d42c79c83ea000a..1f4800368191a8af689941b4cea0910d700a1b67 100644 --- a/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/SystemTestCase.java +++ b/openbis/sourceTest/java/ch/systemsx/cisd/openbis/systemtest/SystemTestCase.java @@ -50,6 +50,7 @@ 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; import ch.systemsx.cisd.openbis.generic.shared.IServiceForDataStoreServer; +import ch.systemsx.cisd.openbis.generic.shared.ISessionWorkspaceProvider; import ch.systemsx.cisd.openbis.generic.shared.basic.GridRowModel; import ch.systemsx.cisd.openbis.generic.shared.basic.IIdentifierHolder; import ch.systemsx.cisd.openbis.generic.shared.basic.TechId; @@ -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 d06610e91943c90bba173a62cab38b53c0b8eb88..246e6529c892a2118d59aecef8a73986b2b979fd 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 2ef60a6778b5962d4c9ef38a741d11193885182a..ddedfc5255e04a669e319b939d5975eb5989cf10 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 eef627556d4dfdf082db7145059839204af7b123..3b1aa94e4d86061d08231b3ce475bb0c27889ca8 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.shared.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; @@ -42,7 +43,10 @@ public class GenericSystemTestCase extends SystemTestCase @Autowired protected IGenericServer genericServer; - protected void addMultiPartFile(String sessionAttributeKey, String fileName, byte[] data) + @Autowired + protected ISessionWorkspaceProvider sessionWorkspaceProvider; + + 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) diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/query/execute/QueryExecutionOptions.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/query/execute/QueryExecutionOptions.java index ffc081b0b72ef2681222fb2e4cfc8d58f64a81a6..167e5d46825f86243b99b3c6893e4c92a0a5d3d5 100644 --- a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/query/execute/QueryExecutionOptions.java +++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/query/execute/QueryExecutionOptions.java @@ -52,7 +52,7 @@ public class QueryExecutionOptions implements Serializable @Override public String toString() { - return getClass().getSimpleName() + ": parameters=" + parameters; + return getClass().getSimpleName() + ": parameterKeys=" + (parameters != null ? parameters.keySet() : "[]"); } } diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/query/execute/SqlExecutionOptions.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/query/execute/SqlExecutionOptions.java index 194b346df97a7d5d69632a0eaa16e5a13523e7bb..670e6047231d4bfcdb06517655224556558a23e9 100644 --- a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/query/execute/SqlExecutionOptions.java +++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/query/execute/SqlExecutionOptions.java @@ -66,7 +66,7 @@ public class SqlExecutionOptions implements Serializable @Override public String toString() { - return getClass().getSimpleName() + ": databaseId=" + databaseId + ", parameters=" + parameters; + return getClass().getSimpleName() + ": databaseId=" + databaseId + ", parameterKeys=" + (parameters != null ? parameters.keySet() : "[]"); } } diff --git a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/service/execute/AbstractExecutionOptionsWithParameters.java b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/service/execute/AbstractExecutionOptionsWithParameters.java index a3b8efc0c5bb6088f3d3502feb23356afa5a9110..3251822892c7b3c98b272e76564ff533d3bb7490 100644 --- a/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/service/execute/AbstractExecutionOptionsWithParameters.java +++ b/openbis_api/source/java/ch/ethz/sis/openbis/generic/asapi/v3/dto/service/execute/AbstractExecutionOptionsWithParameters.java @@ -47,7 +47,7 @@ public abstract class AbstractExecutionOptionsWithParameters<EO extends Abstract @Override public String toString() { - return getClass().getSimpleName() + ": parameterKeys=" + parameters.keySet(); + return getClass().getSimpleName() + ": parameterKeys=" + (parameters != null ? parameters.keySet() : "[]"); } } diff --git a/openbis_standard_technologies/build.gradle b/openbis_standard_technologies/build.gradle index 259f97a04f4770f66d1795c6320598f98d43b0de..02faf2b53280bda1eb1e69fe3f2711b5ff007aaf 100644 --- a/openbis_standard_technologies/build.gradle +++ b/openbis_standard_technologies/build.gradle @@ -272,9 +272,9 @@ def downloadFile(url, filename) { task zipCorePlugins(type: Zip) { archiveName 'core-plugins.zip' - downloadFile('https://github.com/aarpon/obit_flow_core_technology/archive/master.zip', 'flow.zip') - downloadFile('https://github.com/aarpon/obit_microscopy_core_technology/archive/master.zip', 'microscopy.zip') - downloadFile('https://github.com/aarpon/obit_shared_core_technology/archive/master.zip', 'shared.zip') + downloadFile('https://github.com/aarpon/obit_flow_core_technology/archive/release/18.x.zip', 'flow.zip') + downloadFile('https://github.com/aarpon/obit_microscopy_core_technology/archive/release/18.x.zip', 'microscopy.zip') + downloadFile('https://github.com/aarpon/obit_shared_core_technology/archive/release/18.x.zip', 'shared.zip') from project(':rtd_phosphonetx').fileTree(dir: 'source/core-plugins', includes:['proteomics/**', 'proteomics-optional/**'], excludes:['**/dss/**', '**/package-to-dist']) from project(':screening').fileTree(dir: 'source/core-plugins', includes:['screening/**', 'screening-optional/**'], excludes:['**/dss/**', '**/package-to-dist']) from project(':deep_sequencing_unit').fileTree(dir: 'source/core-plugins', includes:['illumina-ngs/**'], excludes:['**/dss/**', '**/package-to-dist'])