From 98148d2ed98d2aac80954a968aaaba70b5dbb540 Mon Sep 17 00:00:00 2001 From: felmer <felmer> Date: Wed, 18 Jan 2012 09:05:35 +0000 Subject: [PATCH] LMS-2737 getDssInternalTempDir() and getDssRegistrationLogDir() refactored. Tests written. Check added that these directories are on local file system. SVN: 24217 --- .../utils/DssPropertyParametersUtil.java | 110 ++++-- .../utils/DssPropertyParametersUtilTest.java | 320 ++++++++++++++++++ 2 files changed, 404 insertions(+), 26 deletions(-) create mode 100644 datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/DssPropertyParametersUtilTest.java diff --git a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/DssPropertyParametersUtil.java b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/DssPropertyParametersUtil.java index 61d8266422a..6fe9a4707e1 100644 --- a/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/DssPropertyParametersUtil.java +++ b/datastore_server/source/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/DssPropertyParametersUtil.java @@ -21,10 +21,14 @@ import java.util.Map.Entry; import java.util.Properties; import java.util.Set; +import ch.rinn.restrictions.Private; import ch.systemsx.cisd.common.exceptions.ConfigurationFailureException; +import ch.systemsx.cisd.common.filesystem.FileOperations; import ch.systemsx.cisd.common.filesystem.FileUtilities; +import ch.systemsx.cisd.common.filesystem.IFileOperations; import ch.systemsx.cisd.common.utilities.ExtendedProperties; import ch.systemsx.cisd.common.utilities.PropertyUtils; +import ch.systemsx.cisd.common.utilities.Template; /** * Utility class to load properties. @@ -33,6 +37,7 @@ import ch.systemsx.cisd.common.utilities.PropertyUtils; */ public class DssPropertyParametersUtil { + /** Prefix of system properties which may override service.properties. */ public static final String OPENBIS_DSS_SYSTEM_PROPERTIES_PREFIX = "openbis.dss."; @@ -49,6 +54,8 @@ public class DssPropertyParametersUtil */ static final String DSS_TEMP_DIR_PATH = "dss-temp-dir"; + @Private static final File EMPTY_TEST_FILE = new File("an-empty-test-file"); + /** * Directory for registration log files. */ @@ -57,6 +64,17 @@ public class DssPropertyParametersUtil /** Location of service properties file. */ public static final String SERVICE_PROPERTIES_FILE = "etc/service.properties"; + private static final String EXPLANATION = + "Please make sure this directory exists on the local file system and is writable " + + "by the data store server or provide such a directory " + + "by the configuration parameter '${path-key}'."; + + private static final Template NON_EXISTING_DIR_TEMPLATE = new Template( + "Could not create ${dir-description} at path: ${path}. " + EXPLANATION); + + private static final Template NON_LOCAL_DIR_TEMPLATE = new Template( + "Directory at path '${path}' is not on the local file system. " + EXPLANATION); + /** loads server configuration */ public static ExtendedProperties loadServiceProperties() { @@ -98,43 +116,83 @@ public class DssPropertyParametersUtil { return PropertyUtils.getMandatoryProperty(serviceProperties, DOWNLOAD_URL_KEY); } - + public static File getDssInternalTempDir(final Properties properties) { - String defaultTempDirPath = - new File(System.getProperty("user.dir"), "dss-tmp").getAbsolutePath(); - String tempDirPath = - PropertyUtils.getProperty(properties, DSS_TEMP_DIR_PATH, defaultTempDirPath); - File tempDir = new File(tempDirPath); - tempDir.mkdirs(); - if (false == tempDir.exists()) - { - throw new ConfigurationFailureException( - "Could not create an internal temp directory for the data store server at path: " - + tempDir.getPath() - + ". Please make sure this directory exists and is writable by the data store server or provide an alternate using directory for the " - + DSS_TEMP_DIR_PATH + " configuration setting"); - } - return tempDir; + return getDssInternalTempDir(FileOperations.getInstance(), properties); + } + + @Private + static File getDssInternalTempDir(IFileOperations fileOperations, final Properties properties) + { + return getDir(fileOperations, properties, "dss-tmp", + "an internal temp directory for the data store server", DSS_TEMP_DIR_PATH); } public static File getDssRegistrationLogDir(final Properties properties) + { + return getDssRegistrationLogDir(FileOperations.getInstance(), properties); + } + + @Private + static File getDssRegistrationLogDir(IFileOperations fileOperations, final Properties properties) + { + return getDir(fileOperations, properties, "log-registrations", + "a directory for storing registration logs", DSS_REGISTRATION_LOG_DIR_PATH); + } + + private static File getDir(IFileOperations fileOperations, final Properties properties, + String defaultDirName, String dirDescription, String pathKey) { String defaultRegistrationLogDirPath = - new File(System.getProperty("user.dir"), "log-registrations").getAbsolutePath(); + new File(System.getProperty("user.dir"), defaultDirName).getAbsolutePath(); String registrationLogDirPath = - PropertyUtils.getProperty(properties, DSS_REGISTRATION_LOG_DIR_PATH, + PropertyUtils.getProperty(properties, pathKey, defaultRegistrationLogDirPath); File registrationLogDir = new File(registrationLogDirPath); - registrationLogDir.mkdirs(); - if (false == registrationLogDir.exists()) + fileOperations.mkdirs(registrationLogDir); + assertDirExistsAndIsLocal(fileOperations, registrationLogDir, + dirDescription, pathKey); + return registrationLogDir; + } + + private static void assertDirExistsAndIsLocal(IFileOperations fileOperations, File dir, + String dirDescription, String pathKey) + { + assertDirExists(fileOperations, dir, dirDescription, pathKey); + File emptyTestFileInDir = new File(dir, EMPTY_TEST_FILE.getName()); + try + { + fileOperations.createNewFile(EMPTY_TEST_FILE); + if (fileOperations.rename(EMPTY_TEST_FILE, emptyTestFileInDir) == false) + { + throw createException(NON_LOCAL_DIR_TEMPLATE.createFreshCopy(), dir, dirDescription, + pathKey); + } + } finally { - throw new ConfigurationFailureException( - "Could not create a directory for storing for registration logs at path: " - + registrationLogDir.getPath() - + ". Please make sure this directory exists and is writable by the data store server or provide an alternate using directory for the " - + DSS_REGISTRATION_LOG_DIR_PATH + " configuration setting"); + fileOperations.delete(EMPTY_TEST_FILE); + fileOperations.delete(emptyTestFileInDir); } - return registrationLogDir; + } + + private static void assertDirExists(IFileOperations fileOperations, File dir, String dirDescription, + String pathKey) + { + if (fileOperations.exists(dir) == false) + { + throw createException(NON_EXISTING_DIR_TEMPLATE.createFreshCopy(), dir, dirDescription, + pathKey); + } + } + + private static ConfigurationFailureException createException(Template template, File dir, + String dirName, String pathKey) + { + template.attemptToBind("dir-description", dirName); + template.bind("path", dir.getPath()); + template.bind("path-key", pathKey); + ConfigurationFailureException e = new ConfigurationFailureException(template.createText()); + return e; } } diff --git a/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/DssPropertyParametersUtilTest.java b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/DssPropertyParametersUtilTest.java new file mode 100644 index 00000000000..f861d825a8c --- /dev/null +++ b/datastore_server/sourceTest/java/ch/systemsx/cisd/openbis/dss/generic/shared/utils/DssPropertyParametersUtilTest.java @@ -0,0 +1,320 @@ +/* + * Copyright 2012 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.dss.generic.shared.utils; + +import static ch.systemsx.cisd.openbis.dss.generic.shared.utils.DssPropertyParametersUtil.EMPTY_TEST_FILE; + +import java.io.File; +import java.util.Properties; + +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.rinn.restrictions.Friend; +import ch.systemsx.cisd.common.exceptions.ConfigurationFailureException; +import ch.systemsx.cisd.common.filesystem.IFileOperations; + +/** + * @author Franz-Josef Elmer + */ +@Friend(toClasses = DssPropertyParametersUtil.class) +public class DssPropertyParametersUtilTest extends AssertJUnit +{ + + private Mockery context; + + private IFileOperations fileOperations; + + @BeforeMethod + public void setUp() + { + context = new Mockery(); + fileOperations = context.mock(IFileOperations.class); + } + + @AfterMethod + public void tearDown() + { + // To following line of code should also be called at the end of each test method. + // Otherwise one do not known which test failed. + context.assertIsSatisfied(); + } + + @Test + public void testGetDssInternalTempDirWithDefaultValue() + { + File expectedDir = new File(System.getProperty("user.dir"), "dss-tmp"); + prepareForMkdirs(expectedDir); + prepareForExists(expectedDir); + prepareForCreateNewFile(EMPTY_TEST_FILE); + File movedEmptyTestFile = new File(expectedDir, EMPTY_TEST_FILE.getName()); + prepareForRenameFile(EMPTY_TEST_FILE, movedEmptyTestFile, true); + prepareForDeleteFile(EMPTY_TEST_FILE); + prepareForDeleteFile(movedEmptyTestFile); + + File tempDir = + DssPropertyParametersUtil.getDssInternalTempDir(fileOperations, new Properties()); + + assertEquals(expectedDir, tempDir); + context.assertIsSatisfied(); + } + + @Test + public void testGetDssInternalTempDirWithValidValue() + { + File expectedDir = new File("my-dss-tmp"); + Properties properties = new Properties(); + properties.setProperty(DssPropertyParametersUtil.DSS_TEMP_DIR_PATH, expectedDir.getPath()); + prepareForMkdirs(expectedDir); + prepareForExists(expectedDir); + prepareForCreateNewFile(EMPTY_TEST_FILE); + File movedEmptyTestFile = new File(expectedDir, EMPTY_TEST_FILE.getName()); + prepareForRenameFile(EMPTY_TEST_FILE, movedEmptyTestFile, true); + prepareForDeleteFile(EMPTY_TEST_FILE); + prepareForDeleteFile(movedEmptyTestFile); + + File tempDir = DssPropertyParametersUtil.getDssInternalTempDir(fileOperations, properties); + + assertEquals(expectedDir, tempDir); + context.assertIsSatisfied(); + } + + @Test + public void testGetDssInternalTempDirWhichDoesNotExists() + { + File expectedDir = new File("my-dss-tmp"); + Properties properties = new Properties(); + properties.setProperty(DssPropertyParametersUtil.DSS_TEMP_DIR_PATH, expectedDir.getPath()); + prepareForMkdirs(expectedDir); + prepareForNonExists(expectedDir); + + try + { + DssPropertyParametersUtil.getDssInternalTempDir(fileOperations, properties); + fail("ConfigurationFailureException expected"); + } catch (ConfigurationFailureException ex) + { + assertEquals("Could not create an internal temp directory for " + + "the data store server at path: my-dss-tmp. " + + "Please make sure this directory exists on the local file system and " + + "is writable by the data store server or provide such a directory " + + "by the configuration parameter 'dss-temp-dir'.", ex.getMessage()); + } + + context.assertIsSatisfied(); + } + + @Test + public void testGetDssInternalTempDirWhichIsNotLocal() + { + File expectedDir = new File("my-dss-tmp"); + Properties properties = new Properties(); + properties.setProperty(DssPropertyParametersUtil.DSS_TEMP_DIR_PATH, expectedDir.getPath()); + prepareForMkdirs(expectedDir); + prepareForExists(expectedDir); + prepareForCreateNewFile(EMPTY_TEST_FILE); + File movedEmptyTestFile = new File(expectedDir, EMPTY_TEST_FILE.getName()); + prepareForRenameFile(EMPTY_TEST_FILE, movedEmptyTestFile, false); + prepareForDeleteFile(EMPTY_TEST_FILE); + prepareForDeleteFile(movedEmptyTestFile); + + try + { + DssPropertyParametersUtil.getDssInternalTempDir(fileOperations, properties); + fail("ConfigurationFailureException expected"); + } catch (ConfigurationFailureException ex) + { + assertEquals("Directory at path 'my-dss-tmp' is not on the local file system. " + + "Please make sure this directory exists on the local file system and " + + "is writable by the data store server or provide such a directory " + + "by the configuration parameter 'dss-temp-dir'.", ex.getMessage()); + } + + context.assertIsSatisfied(); + } + + @Test + public void testGetDssRegistrationLogDirWithDefaultValue() + { + File expectedDir = new File(System.getProperty("user.dir"), "log-registrations"); + prepareForMkdirs(expectedDir); + prepareForExists(expectedDir); + prepareForCreateNewFile(EMPTY_TEST_FILE); + File movedEmptyTestFile = new File(expectedDir, EMPTY_TEST_FILE.getName()); + prepareForRenameFile(EMPTY_TEST_FILE, movedEmptyTestFile, true); + prepareForDeleteFile(EMPTY_TEST_FILE); + prepareForDeleteFile(movedEmptyTestFile); + + File tempDir = + DssPropertyParametersUtil + .getDssRegistrationLogDir(fileOperations, new Properties()); + + assertEquals(expectedDir, tempDir); + context.assertIsSatisfied(); + } + + @Test + public void testGetDssRegistrationLogDirWithValidValue() + { + File expectedDir = new File("my-dss-log"); + Properties properties = new Properties(); + properties.setProperty(DssPropertyParametersUtil.DSS_REGISTRATION_LOG_DIR_PATH, + expectedDir.getPath()); + prepareForMkdirs(expectedDir); + prepareForExists(expectedDir); + prepareForCreateNewFile(EMPTY_TEST_FILE); + File movedEmptyTestFile = new File(expectedDir, EMPTY_TEST_FILE.getName()); + prepareForRenameFile(EMPTY_TEST_FILE, movedEmptyTestFile, true); + prepareForDeleteFile(EMPTY_TEST_FILE); + prepareForDeleteFile(movedEmptyTestFile); + + File tempDir = + DssPropertyParametersUtil.getDssRegistrationLogDir(fileOperations, properties); + + assertEquals(expectedDir, tempDir); + context.assertIsSatisfied(); + } + + @Test + public void testGetDssRegistrationLogDirWhichDoesNotExists() + { + File expectedDir = new File("my-dss-log"); + Properties properties = new Properties(); + properties.setProperty(DssPropertyParametersUtil.DSS_REGISTRATION_LOG_DIR_PATH, + expectedDir.getPath()); + prepareForMkdirs(expectedDir); + prepareForNonExists(expectedDir); + + try + { + DssPropertyParametersUtil.getDssRegistrationLogDir(fileOperations, properties); + fail("ConfigurationFailureException expected"); + } catch (ConfigurationFailureException ex) + { + assertEquals("Could not create a directory for storing " + + "registration logs at path: my-dss-log. " + + "Please make sure this directory exists on the local file system and " + + "is writable by the data store server or provide such a directory " + + "by the configuration parameter 'dss-registration-log-dir'.", ex.getMessage()); + } + + context.assertIsSatisfied(); + } + + @Test + public void testGetDssRegistrationLogDirWhichIsNotLocal() + { + File expectedDir = new File("my-dss-log"); + Properties properties = new Properties(); + properties.setProperty(DssPropertyParametersUtil.DSS_REGISTRATION_LOG_DIR_PATH, + expectedDir.getPath()); + prepareForMkdirs(expectedDir); + prepareForExists(expectedDir); + prepareForCreateNewFile(EMPTY_TEST_FILE); + File movedEmptyTestFile = new File(expectedDir, EMPTY_TEST_FILE.getName()); + prepareForRenameFile(EMPTY_TEST_FILE, movedEmptyTestFile, false); + prepareForDeleteFile(EMPTY_TEST_FILE); + prepareForDeleteFile(movedEmptyTestFile); + + try + { + DssPropertyParametersUtil.getDssRegistrationLogDir(fileOperations, properties); + fail("ConfigurationFailureException expected"); + } catch (ConfigurationFailureException ex) + { + assertEquals("Directory at path 'my-dss-log' is not on the local file system. " + + "Please make sure this directory exists on the local file system and " + + "is writable by the data store server or provide such a directory " + + "by the configuration parameter 'dss-registration-log-dir'.", ex.getMessage()); + } + + context.assertIsSatisfied(); + } + + private void prepareForMkdirs(final File dir) + { + context.checking(new Expectations() + { + { + one(fileOperations).mkdirs(dir); + will(returnValue(true)); + } + }); + + } + + private void prepareForExists(final File dir) + { + context.checking(new Expectations() + { + { + one(fileOperations).exists(dir); + will(returnValue(true)); + } + }); + } + + private void prepareForNonExists(final File dir) + { + context.checking(new Expectations() + { + { + one(fileOperations).exists(dir); + will(returnValue(false)); + } + }); + } + + private void prepareForCreateNewFile(final File file) + { + context.checking(new Expectations() + { + { + one(fileOperations).createNewFile(file); + will(returnValue(true)); + } + }); + } + + private void prepareForRenameFile(final File source, final File destination, + final boolean success) + { + context.checking(new Expectations() + { + { + one(fileOperations).rename(source, destination); + will(returnValue(success)); + } + }); + } + + private void prepareForDeleteFile(final File file) + { + context.checking(new Expectations() + { + { + one(fileOperations).delete(file); + will(returnValue(true)); + } + }); + } + +} -- GitLab