# HG changeset patch # User Omair Majid # Date 1374856147 14400 # Node ID d448210350bf204048483542ff290514080db9aa # Parent 9ec44cd389463d9d85c5b0909e84a8289e00b8d0 Make thermostat work with a read-only $THERMOSTAT_HOME Revewied-by: jerboaa, neugens Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2013-July/007592.html PR1333 diff -r 9ec44cd38946 -r d448210350bf agent/cli/src/main/java/com/redhat/thermostat/agent/cli/impl/db/DBStartupConfiguration.java --- a/agent/cli/src/main/java/com/redhat/thermostat/agent/cli/impl/db/DBStartupConfiguration.java Mon Jul 22 20:01:46 2013 +0200 +++ b/agent/cli/src/main/java/com/redhat/thermostat/agent/cli/impl/db/DBStartupConfiguration.java Fri Jul 26 12:29:07 2013 -0400 @@ -63,12 +63,12 @@ private String ip; - public DBStartupConfiguration(File properties, File dbPath, File logFile, - File pidFile) throws InvalidConfigurationException { + public DBStartupConfiguration(File systemProperties, File userProperties, + File dbPath, File logFile, File pidFile) throws InvalidConfigurationException { this.dbPath = dbPath; this.logFile = logFile; this.pidFile = pidFile; - readAndSetProperties(properties); + readAndSetProperties(systemProperties, userProperties); } public File getDBPath() { @@ -142,26 +142,36 @@ this.sslKeyPassphrase = sslKeyPassphrase; } - private void readAndSetProperties(File propertyFile) throws InvalidConfigurationException { + private void readAndSetProperties(File systemPropertiesFile, File userPropertiesFile) throws InvalidConfigurationException { - Properties properties = new Properties(); + Properties systemProperties = new Properties(); try { - properties.load(new FileInputStream(propertyFile)); - + systemProperties.load(new FileInputStream(systemPropertiesFile)); } catch (IOException e) { - throw new InvalidConfigurationException(e); + throw new InvalidConfigurationException(/* "Could not find system configuration", */e); } - if (properties.containsKey(DBConfig.PORT.name())) { - String port = (String) properties.get(DBConfig.PORT.name()); + Properties properties = new Properties(systemProperties); + try { + properties.load(new FileInputStream(userPropertiesFile)); + } catch (IOException e) { + // that's fine. we will just rely on system properties + } + + readAndSetProperties(properties); + } + + private void readAndSetProperties(Properties properties) { + String port = properties.getProperty(DBConfig.PORT.name()); + if (port != null) { int localPort = Integer.parseInt(port); setPort(localPort); } else { throw new InvalidConfigurationException(t.localize(LocaleResources.MISSING_PROPERTY, DBConfig.PORT.toString())); } - if (properties.containsKey(DBConfig.BIND.name())) { - String ip = (String) properties.get(DBConfig.BIND.name()); + String ip = properties.getProperty(DBConfig.BIND.name()); + if (ip != null) { setBindIP(ip); } else { throw new InvalidConfigurationException(t.localize(LocaleResources.MISSING_PROPERTY, DBConfig.BIND.toString())); diff -r 9ec44cd38946 -r d448210350bf agent/cli/src/main/java/com/redhat/thermostat/agent/cli/impl/db/StorageCommand.java --- a/agent/cli/src/main/java/com/redhat/thermostat/agent/cli/impl/db/StorageCommand.java Mon Jul 22 20:01:46 2013 +0200 +++ b/agent/cli/src/main/java/com/redhat/thermostat/agent/cli/impl/db/StorageCommand.java Fri Jul 26 12:29:07 2013 -0400 @@ -68,15 +68,16 @@ private void parseArguments(Arguments args) throws InvalidConfigurationException { Configuration thermostatConfiguration = new Configuration(); - File dbPath = thermostatConfiguration.getStorageDirectory(); - File logFile = thermostatConfiguration.getStorageLogFile(); - File pidFile = thermostatConfiguration.getStoragePidFile(); - File propertyFile = thermostatConfiguration.getStorageConfigurationFile(); - if (!propertyFile.exists()) { - throw new InvalidConfigurationException(t.localize(LocaleResources.MISSING_DB_CONFIG, propertyFile.toString())); + File dbPath = thermostatConfiguration.getUserStorageDirectory(); + File logFile = thermostatConfiguration.getUserStorageLogFile(); + File pidFile = thermostatConfiguration.getUserStoragePidFile(); + File systemPropertyFile = thermostatConfiguration.getSystemStorageConfigurationFile(); + if (!systemPropertyFile.exists()) { + throw new InvalidConfigurationException(t.localize(LocaleResources.MISSING_DB_CONFIG, systemPropertyFile.toString())); } + File userPropertyFile = thermostatConfiguration.getUserStorageConfigurationFile(); // read everything that is in the configs - this.configuration = new DBStartupConfiguration(propertyFile, dbPath, logFile, pidFile); + this.configuration = new DBStartupConfiguration(systemPropertyFile, userPropertyFile, dbPath, logFile, pidFile); parser = new DBOptionParser(configuration, args); parser.parse(); } @@ -119,6 +120,7 @@ private void startService() throws IOException, InterruptedException, InvalidConfigurationException, ApplicationException { try { + createNeededDirectories(); runner.startService(); } catch (ApplicationException | InvalidConfigurationException | IOException e) { // something went wrong set status appropriately. This makes sure @@ -130,6 +132,29 @@ getNotifier().fireAction(ApplicationState.START); } + private void createNeededDirectories() throws InvalidConfigurationException { + File[] requiredDirectories = new File[] { + configuration.getDBPath(), + }; + + for (File directory : requiredDirectories) { + if (!directory.isDirectory() && !directory.mkdirs()) { + throw new InvalidConfigurationException(t.localize(LocaleResources.MISSING_DB_DIR)); + } + } + + File[] requiredFiles = new File[] { + configuration.getLogFile(), + configuration.getPidFile(), + }; + + for (File file : requiredFiles) { + File directory = file.getParentFile(); + if (!directory.isDirectory() && !directory.mkdirs()) { + throw new InvalidConfigurationException(t.localize(LocaleResources.MISSING_DB_DIR)); + } + } + } private void stopService() throws IOException, InterruptedException, InvalidConfigurationException, ApplicationException { try { @@ -144,6 +169,15 @@ getNotifier().fireAction(ApplicationState.STOP); } + private void check() throws InvalidConfigurationException { + if (!configuration.getDBPath().exists() || + !configuration.getLogFile().getParentFile().exists() || + !configuration.getPidFile().getParentFile().exists()) + { + throw new InvalidConfigurationException(t.localize(LocaleResources.MISSING_DB_DIR)); + } + } + private void printServiceStatus(CommandContext ctx) { if (runner.isStorageRunning()) { ctx.getConsole().getOutput().println(t.localize(LocaleResources.STORAGE_RUNNING).getContents()); @@ -156,15 +190,6 @@ return new MongoProcessRunner(configuration, parser.isQuiet()); } - private void check() throws InvalidConfigurationException { - if (!configuration.getDBPath().exists() || - !configuration.getLogFile().getParentFile().exists() || - !configuration.getPidFile().getParentFile().exists()) - { - throw new InvalidConfigurationException(t.localize(LocaleResources.MISSING_DB_DIR)); - } - } - public DBStartupConfiguration getConfiguration() { return configuration; } diff -r 9ec44cd38946 -r d448210350bf agent/cli/src/test/java/com/redhat/thermostat/agent/cli/impl/db/DBStartupConfigurationTest.java --- a/agent/cli/src/test/java/com/redhat/thermostat/agent/cli/impl/db/DBStartupConfigurationTest.java Mon Jul 22 20:01:46 2013 +0200 +++ b/agent/cli/src/test/java/com/redhat/thermostat/agent/cli/impl/db/DBStartupConfigurationTest.java Fri Jul 26 12:29:07 2013 -0400 @@ -71,7 +71,8 @@ @Test public void canGetConfigFromPropertiesFile() throws Exception { File dbProps = new File(this.getClass().getResource("/testDbConfig.properties").getFile()); - DBStartupConfiguration dbConfig = new DBStartupConfiguration(dbProps, dbPath, dbLogFile, dbPidFile); + File canNotBeFoundFile = new File(""); + DBStartupConfiguration dbConfig = new DBStartupConfiguration(dbProps, canNotBeFoundFile, dbPath, dbLogFile, dbPidFile); assertEquals(dbLogFile.getAbsolutePath(), dbConfig.getLogFile().getAbsolutePath()); assertEquals(dbPidFile.getAbsolutePath(), dbConfig.getPidFile().getAbsolutePath()); @@ -86,7 +87,8 @@ @Test public void canGetConfigFromPropertiesFile2() throws Exception { File dbProps = new File(this.getClass().getResource("/testDbConfig2.properties").getFile()); - DBStartupConfiguration dbConfig = new DBStartupConfiguration(dbProps, dbPath, dbLogFile, dbPidFile); + File canNotBeFoundFile = new File(""); + DBStartupConfiguration dbConfig = new DBStartupConfiguration(dbProps, canNotBeFoundFile, dbPath, dbLogFile, dbPidFile); assertEquals(dbLogFile.getAbsolutePath(), dbConfig.getLogFile().getAbsolutePath()); assertEquals(dbPidFile.getAbsolutePath(), dbConfig.getPidFile().getAbsolutePath()); @@ -101,8 +103,9 @@ @Test public void missingBindThrowsConfigException() throws Exception { File dbProps = new File(this.getClass().getResource("/brokenDbConfig.properties").getFile()); + File canNotBeFoundFile = new File(""); try { - new DBStartupConfiguration(dbProps, dbPath, dbLogFile, dbPidFile); + new DBStartupConfiguration(dbProps, canNotBeFoundFile, dbPath, dbLogFile, dbPidFile); fail("BIND was not specified in properties file"); } catch (InvalidConfigurationException e) { assertEquals("BIND property missing", e.getMessage()); @@ -112,8 +115,9 @@ @Test public void missingPortThrowsConfigException() throws Exception { File dbProps = new File(this.getClass().getResource("/brokenDbConfig2.properties").getFile()); + File canNotBeFoundFile = new File(""); try { - new DBStartupConfiguration(dbProps, dbPath, dbLogFile, dbPidFile); + new DBStartupConfiguration(dbProps, canNotBeFoundFile, dbPath, dbLogFile, dbPidFile); fail("PORT was not specified in properties file"); } catch (InvalidConfigurationException e) { assertEquals("PORT property missing", e.getMessage()); diff -r 9ec44cd38946 -r d448210350bf agent/cli/src/test/java/com/redhat/thermostat/agent/cli/impl/db/StorageCommandTest.java --- a/agent/cli/src/test/java/com/redhat/thermostat/agent/cli/impl/db/StorageCommandTest.java Mon Jul 22 20:01:46 2013 +0200 +++ b/agent/cli/src/test/java/com/redhat/thermostat/agent/cli/impl/db/StorageCommandTest.java Fri Jul 26 12:29:07 2013 -0400 @@ -64,12 +64,13 @@ import com.redhat.thermostat.common.tools.ApplicationException; import com.redhat.thermostat.common.tools.ApplicationState; import com.redhat.thermostat.shared.config.InvalidConfigurationException; +import com.redhat.thermostat.testutils.TestUtils; public class StorageCommandTest { private static final String PORT = "27518"; private static final String BIND = "127.0.0.1"; - private static final String DB = "storage/db"; + private static final String DB = "data/db"; private String tmpDir; private ExitStatus exitStatus; @@ -79,28 +80,12 @@ exitStatus = mock(ExitStatus.class); // need to create a dummy config file for the test try { - Random random = new Random(); - - tmpDir = System.getProperty("java.io.tmpdir") + File.separatorChar + - Math.abs(random.nextInt()) + File.separatorChar; - - System.setProperty("THERMOSTAT_HOME", tmpDir); - File base = new File(tmpDir + "storage"); - base.mkdirs(); - - File tmpConfigs = new File(base, "db.properties"); - - new File(base, "run").mkdirs(); - new File(base, "logs").mkdirs(); - new File(base, "db").mkdirs(); - Properties props = new Properties(); props.setProperty(DBConfig.BIND.name(), BIND); props.setProperty(DBConfig.PORT.name(), PORT); - props.store(new FileOutputStream(tmpConfigs), "thermostat test properties"); - + tmpDir = TestUtils.setupStorageConfigs(props); } catch (IOException e) { Assert.fail("cannot setup tests: " + e); } diff -r 9ec44cd38946 -r d448210350bf agent/core/src/main/java/com/redhat/thermostat/agent/config/AgentConfigsUtils.java --- a/agent/core/src/main/java/com/redhat/thermostat/agent/config/AgentConfigsUtils.java Mon Jul 22 20:01:46 2013 +0200 +++ b/agent/core/src/main/java/com/redhat/thermostat/agent/config/AgentConfigsUtils.java Fri Jul 26 12:29:07 2013 -0400 @@ -62,26 +62,33 @@ AgentStartupConfiguration config = new AgentStartupConfiguration(); Configuration mainConfig = new Configuration(); - File propertyFile = mainConfig.getAgentConfigurationFile(); - readAndSetProperties(propertyFile, config); - File agentAuthFile = mainConfig.getAgentAuthConfigFile(); + File systemConfiguration = mainConfig.getSystemAgentConfigurationFile(); + File userConfiguration = mainConfig.getUserAgentConfigurationFile(); + readAndSetProperties(systemConfiguration, userConfiguration, config); + File agentAuthFile = mainConfig.getUserAgentAuthConfigFile(); setAuthConfigFromFile(agentAuthFile, config); return config; } - private static void readAndSetProperties(File propertyFile, AgentStartupConfiguration configuration) + private static void readAndSetProperties(File systemConfigFile, File userConfigFile, AgentStartupConfiguration configuration) throws InvalidConfigurationException { - Properties properties = new Properties(); + Properties systemConfig = new Properties(); try { - properties.load(new FileInputStream(propertyFile)); - + systemConfig.load(new FileInputStream(systemConfigFile)); } catch (IOException e) { throw new InvalidConfigurationException(e); } - - if (properties.containsKey(AgentProperties.DB_URL.name())) { - String db = properties.getProperty(AgentProperties.DB_URL.name()); + + Properties properties = new Properties(systemConfig); + try { + properties.load(new FileInputStream(userConfigFile)); + } catch (IOException e) { + // that's okay. just use system config + } + + String db = properties.getProperty(AgentProperties.DB_URL.name()); + if (db != null) { configuration.setDatabaseURL(db); } diff -r 9ec44cd38946 -r d448210350bf agent/core/src/test/java/com/redhat/thermostat/agent/config/AgentConfigsUtilsTest.java --- a/agent/core/src/test/java/com/redhat/thermostat/agent/config/AgentConfigsUtilsTest.java Mon Jul 22 20:01:46 2013 +0200 +++ b/agent/core/src/test/java/com/redhat/thermostat/agent/config/AgentConfigsUtilsTest.java Fri Jul 26 12:29:07 2013 -0400 @@ -39,6 +39,7 @@ import java.io.File; import java.io.FileWriter; import java.io.IOException; +import java.util.Properties; import java.util.Random; import org.junit.Assert; @@ -53,13 +54,22 @@ private static Random random; @BeforeClass - public static void setUpRandom() { + public static void setUpOnce() { random = new Random(); + + Properties agentProperties = new Properties(); + agentProperties.setProperty("SAVE_ON_EXIT", "true"); + agentProperties.setProperty("CONFIG_LISTEN_ADDRESS", "42.42.42.42:42"); + + try { + TestUtils.setupAgentConfigs(agentProperties); + } catch (IOException e) { + throw new AssertionError("Unable to create agent configuration", e); + } } @Test public void testCreateAgentConfigs() throws InvalidConfigurationException, IOException { - TestUtils.setupAgentConfigs(); AgentStartupConfiguration config = AgentConfigsUtils.createAgentConfigs(); Assert.assertFalse(config.purge()); diff -r 9ec44cd38946 -r d448210350bf agent/core/src/test/java/com/redhat/thermostat/agent/config/AgentOptionParserTest.java --- a/agent/core/src/test/java/com/redhat/thermostat/agent/config/AgentOptionParserTest.java Mon Jul 22 20:01:46 2013 +0200 +++ b/agent/core/src/test/java/com/redhat/thermostat/agent/config/AgentOptionParserTest.java Fri Jul 26 12:29:07 2013 -0400 @@ -38,6 +38,7 @@ import java.io.File; import java.io.IOException; +import java.util.Properties; import junit.framework.Assert; @@ -55,7 +56,12 @@ @BeforeClass public static void setup() throws IOException { - tmpFile = new File(TestUtils.setupAgentConfigs()); + + Properties agentProperties = new Properties(); + agentProperties.setProperty("SAVE_ON_EXIT", "true"); + agentProperties.setProperty("CONFIG_LISTEN_ADDRESS", "42.42.42.42:42"); + + tmpFile = new File(TestUtils.setupAgentConfigs(agentProperties)); } @AfterClass diff -r 9ec44cd38946 -r d448210350bf client/cli/src/main/java/com/redhat/thermostat/client/cli/internal/ShellCommand.java --- a/client/cli/src/main/java/com/redhat/thermostat/client/cli/internal/ShellCommand.java Mon Jul 22 20:01:46 2013 +0200 +++ b/client/cli/src/main/java/com/redhat/thermostat/client/cli/internal/ShellCommand.java Fri Jul 26 12:29:07 2013 -0400 @@ -81,7 +81,7 @@ public PersistentHistory get() { PersistentHistory history = null; try { - history = new FileHistory(new Configuration().getHistoryFile()); + history = new FileHistory(new Configuration().getUserHistoryFile()); } catch (InvalidConfigurationException | IOException e) { /* no history available */ } diff -r 9ec44cd38946 -r d448210350bf client/core/src/main/java/com/redhat/thermostat/client/ui/ClientConfigurationController.java --- a/client/core/src/main/java/com/redhat/thermostat/client/ui/ClientConfigurationController.java Mon Jul 22 20:01:46 2013 +0200 +++ b/client/core/src/main/java/com/redhat/thermostat/client/ui/ClientConfigurationController.java Fri Jul 26 12:29:07 2013 -0400 @@ -36,6 +36,7 @@ package com.redhat.thermostat.client.ui; +import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; import java.util.prefs.BackingStoreException; @@ -87,7 +88,7 @@ try { model.flush(); - } catch (BackingStoreException e) { + } catch (IOException e) { logger.log(Level.WARNING, "error saving client preferences", e); } } diff -r 9ec44cd38946 -r d448210350bf common/core/src/main/java/com/redhat/thermostat/common/config/ClientPreferences.java --- a/common/core/src/main/java/com/redhat/thermostat/common/config/ClientPreferences.java Mon Jul 22 20:01:46 2013 +0200 +++ b/common/core/src/main/java/com/redhat/thermostat/common/config/ClientPreferences.java Fri Jul 26 12:29:07 2013 -0400 @@ -36,9 +36,19 @@ package com.redhat.thermostat.common.config; -import java.util.prefs.BackingStoreException; -import java.util.prefs.Preferences; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; +import java.util.logging.Level; +import java.util.logging.Logger; +import com.redhat.thermostat.common.utils.LoggingUtils; +import com.redhat.thermostat.shared.config.Configuration; +import com.redhat.thermostat.shared.config.InvalidConfigurationException; import com.redhat.thermostat.utils.keyring.Credentials; import com.redhat.thermostat.utils.keyring.Keyring; @@ -49,26 +59,47 @@ static final String CONNECTION_URL = "connection-url"; static final String SAVE_ENTITLEMENTS = "save-entitlements"; static final String DEFAULT_CONNECTION_URL = "mongodb://127.0.0.1:27518"; + + private static final Logger logger = LoggingUtils.getLogger(ClientPreferences.class); - private final Preferences prefs; + private Properties prefs; private Keyring keyring; private Credentials userCredentials; public ClientPreferences(Keyring keyring) { - this(Preferences.userRoot().node("thermostat"), keyring); + Properties props = new Properties(); + try { + File userConfig = new Configuration().getUserClientConfigurationFile(); + if (userConfig.isFile()) { + try { + try (InputStream fis = new FileInputStream(userConfig)) { + props.load(fis); + } + } catch (IOException e) { + logger.log(Level.CONFIG, "unable to load client configuration", e); + } + } + } catch (InvalidConfigurationException e) { + logger.log(Level.CONFIG, "unable to load configuration", e); + } + init(props, keyring); } - // Testing hook with injectable j.u.p.Preferences - ClientPreferences(Preferences prefs, Keyring keyring) { - this.prefs = prefs; + // Testing hook with injectable j.u.Properties + ClientPreferences(Properties properties, Keyring keyring) { + init(properties, keyring); + } + + private void init(Properties properties, Keyring keyring) { + this.prefs = properties; this.keyring = keyring; this.userCredentials = new Credentials(); userCredentials.setDescription("thermostat keychain"); // load the initial defaults - userCredentials.setUserName(prefs.get(USERNAME, "")); + userCredentials.setUserName(prefs.getProperty(USERNAME, "")); this.userCredentials.setPassword(""); if (getSaveEntitlements()) { keyring.loadPassword(userCredentials); @@ -76,15 +107,15 @@ } public boolean getSaveEntitlements() { - return prefs.getBoolean(SAVE_ENTITLEMENTS, false); + return Boolean.valueOf(prefs.getProperty(SAVE_ENTITLEMENTS, "false")); } public void setSaveEntitlements(boolean save) { - prefs.putBoolean(SAVE_ENTITLEMENTS, save); + prefs.setProperty(SAVE_ENTITLEMENTS, Boolean.toString(save)); } public String getConnectionUrl() { - return prefs.get(CONNECTION_URL, DEFAULT_CONNECTION_URL); + return prefs.getProperty(CONNECTION_URL, DEFAULT_CONNECTION_URL); } public String getPassword() { @@ -95,7 +126,7 @@ } public String getUserName() { - return prefs.get(USERNAME, ""); + return prefs.getProperty(USERNAME, ""); } public void setConnectionUrl(String url) { @@ -113,8 +144,8 @@ } } - public void flush() throws BackingStoreException { - prefs.flush(); + public void flush() throws IOException { + prefs.store(new FileWriter(new Configuration().getUserClientConfigurationFile()), ""); userCredentials.setUserName(getUserName()); if (getSaveEntitlements()) { keyring.loadPassword(userCredentials); diff -r 9ec44cd38946 -r d448210350bf common/core/src/main/java/com/redhat/thermostat/common/ssl/SSLConfiguration.java --- a/common/core/src/main/java/com/redhat/thermostat/common/ssl/SSLConfiguration.java Mon Jul 22 20:01:46 2013 +0200 +++ b/common/core/src/main/java/com/redhat/thermostat/common/ssl/SSLConfiguration.java Fri Jul 26 12:29:07 2013 -0400 @@ -157,7 +157,7 @@ private static void loadClientProperties() throws InvalidConfigurationException { if (clientProps == null) { - File clientPropertiesFile = new File(new Configuration().getConfigurationDir(), + File clientPropertiesFile = new File(new Configuration().getUserConfigurationDirectory(), "ssl.properties"); initClientProperties(clientPropertiesFile); } diff -r 9ec44cd38946 -r d448210350bf common/core/src/main/java/com/redhat/thermostat/common/utils/LoggingUtils.java --- a/common/core/src/main/java/com/redhat/thermostat/common/utils/LoggingUtils.java Mon Jul 22 20:01:46 2013 +0200 +++ b/common/core/src/main/java/com/redhat/thermostat/common/utils/LoggingUtils.java Fri Jul 26 12:29:07 2013 -0400 @@ -125,15 +125,15 @@ } public static void loadGlobalLoggingConfig() throws InvalidConfigurationException { - File thermostatConfigurationDir = new File(new Configuration().getConfigurationDir()); - File loggingPropertiesFile = new File(thermostatConfigurationDir, "logging.properties"); + File systemConfigurationDir = new Configuration().getSystemConfigurationDirectory(); + File loggingPropertiesFile = new File(systemConfigurationDir, "logging.properties"); loadConfig(loggingPropertiesFile); } public static void loadUserLoggingConfig() throws InvalidConfigurationException { - File thermostatUserDir = new File(new Configuration().getThermostatUserHome()); - File loggingPropertiesFile = new File(thermostatUserDir, "logging.properties"); + File userConfigurationDir = new Configuration().getUserConfigurationDirectory(); + File loggingPropertiesFile = new File(userConfigurationDir, "logging.properties"); loadConfig(loggingPropertiesFile); } diff -r 9ec44cd38946 -r d448210350bf common/core/src/test/java/com/redhat/thermostat/common/config/ClientPreferencesTest.java --- a/common/core/src/test/java/com/redhat/thermostat/common/config/ClientPreferencesTest.java Mon Jul 22 20:01:46 2013 +0200 +++ b/common/core/src/test/java/com/redhat/thermostat/common/config/ClientPreferencesTest.java Fri Jul 26 12:29:07 2013 -0400 @@ -38,7 +38,6 @@ import static org.junit.Assert.assertEquals; import static org.mockito.Matchers.any; -import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.mock; @@ -46,7 +45,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import java.util.prefs.Preferences; +import java.util.Properties; import org.junit.Test; @@ -59,21 +58,21 @@ public void testGetConnectionUrl() { Keyring keyring = mock(Keyring.class); - Preferences prefs = mock(Preferences.class); - when(prefs.get(eq(ClientPreferences.CONNECTION_URL), any(String.class))).thenReturn("mock-value"); + Properties prefs = mock(Properties.class); + when(prefs.getProperty(eq(ClientPreferences.CONNECTION_URL), any(String.class))).thenReturn("mock-value"); ClientPreferences clientPrefs = new ClientPreferences(prefs, keyring); String value = clientPrefs.getConnectionUrl(); assertEquals("mock-value", value); - verify(prefs).get(eq(ClientPreferences.CONNECTION_URL), any(String.class)); + verify(prefs).getProperty(eq(ClientPreferences.CONNECTION_URL), any(String.class)); } @Test public void testSetConnectionUrl() { Keyring keyring = mock(Keyring.class); - Preferences prefs = mock(Preferences.class); + Properties prefs = mock(Properties.class); ClientPreferences clientPrefs = new ClientPreferences(prefs, keyring); clientPrefs.setConnectionUrl("test"); @@ -85,28 +84,28 @@ public void testSetUsernamePassowrd() { Keyring keyring = mock(Keyring.class); - Preferences prefs = mock(Preferences.class); - when(prefs.getBoolean(eq(ClientPreferences.SAVE_ENTITLEMENTS), any(boolean.class))).thenReturn(true); + Properties prefs = mock(Properties.class); + when(prefs.getProperty(eq(ClientPreferences.SAVE_ENTITLEMENTS), any(String.class))).thenReturn("true"); ClientPreferences clientPrefs = new ClientPreferences(prefs, keyring); clientPrefs.setCredentials("fluff", "fluffPassword"); verify(prefs).put(eq(ClientPreferences.USERNAME), eq("fluff")); - verify(prefs, times(0)).put(eq(ClientPreferences.PASSWORD), anyString()); + verify(prefs, times(0)).put(eq(ClientPreferences.PASSWORD), any(String.class)); } @Test public void testGetUsername() { Keyring keyring = mock(Keyring.class); - Preferences prefs = mock(Preferences.class); - when(prefs.get(eq(ClientPreferences.USERNAME), any(String.class))).thenReturn("mock-value"); + Properties prefs = mock(Properties.class); + when(prefs.getProperty(eq(ClientPreferences.USERNAME), any(String.class))).thenReturn("mock-value"); ClientPreferences clientPrefs = new ClientPreferences(prefs, keyring); String username = clientPrefs.getUserName(); assertEquals("mock-value", username); - verify(prefs, atLeastOnce()).get(eq(ClientPreferences.USERNAME), any(String.class)); + verify(prefs, atLeastOnce()).getProperty(eq(ClientPreferences.USERNAME), any(String.class)); } @Test @@ -114,14 +113,14 @@ Keyring keyring = mock(Keyring.class); - Preferences prefs = mock(Preferences.class); - when(prefs.get(eq(ClientPreferences.USERNAME), any(String.class))).thenReturn("mock-value"); - when(prefs.getBoolean(eq(ClientPreferences.SAVE_ENTITLEMENTS), any(boolean.class))). - thenReturn(false).thenReturn(false).thenReturn(true); + Properties prefs = mock(Properties.class); + when(prefs.getProperty(eq(ClientPreferences.USERNAME), any(String.class))).thenReturn("mock-value"); + when(prefs.getProperty(eq(ClientPreferences.SAVE_ENTITLEMENTS), any(String.class))). + thenReturn("false").thenReturn("false").thenReturn("true"); ClientPreferences clientPrefs = new ClientPreferences(prefs, keyring); String password = clientPrefs.getPassword(); - verify(prefs, times(0)).get(eq(ClientPreferences.PASSWORD), any(String.class)); + verify(prefs, times(0)).getProperty(eq(ClientPreferences.PASSWORD), any(String.class)); verify(keyring, times(0)).loadPassword(any(Credentials.class)); assertEquals("", password); @@ -134,29 +133,29 @@ public void testGetSaveEntitlements() { Keyring keyring = mock(Keyring.class); - Preferences prefs = mock(Preferences.class); - when(prefs.getBoolean(eq(ClientPreferences.SAVE_ENTITLEMENTS), any(boolean.class))).thenReturn(true); + Properties prefs = mock(Properties.class); + when(prefs.getProperty(eq(ClientPreferences.SAVE_ENTITLEMENTS), any(String.class))).thenReturn("true"); ClientPreferences clientPrefs = new ClientPreferences(prefs, keyring); boolean saveEntitlements = clientPrefs.getSaveEntitlements(); assertEquals(true, saveEntitlements); - verify(prefs, atLeastOnce()).getBoolean(eq(ClientPreferences.SAVE_ENTITLEMENTS), any(boolean.class)); + verify(prefs, atLeastOnce()).getProperty(eq(ClientPreferences.SAVE_ENTITLEMENTS), any(String.class)); } @Test public void testSetSaveEntitlements() { Keyring keyring = mock(Keyring.class); - Preferences prefs = mock(Preferences.class); + Properties prefs = mock(Properties.class); ClientPreferences clientPrefs = new ClientPreferences(prefs, keyring); clientPrefs.setSaveEntitlements(false); - verify(prefs).putBoolean(eq(ClientPreferences.SAVE_ENTITLEMENTS), eq(false)); + verify(prefs).setProperty(eq(ClientPreferences.SAVE_ENTITLEMENTS), eq("false")); clientPrefs.setSaveEntitlements(true); - verify(prefs).putBoolean(eq(ClientPreferences.SAVE_ENTITLEMENTS), eq(true)); + verify(prefs).setProperty(eq(ClientPreferences.SAVE_ENTITLEMENTS), eq("true")); } @Test @@ -164,8 +163,8 @@ // Default preferences for GUI is mongodb:// since this is accomodates // more use cases Keyring keyring = mock(Keyring.class); - Preferences prefs = mock(Preferences.class); - when(prefs.get(eq("connection-url"), any(String.class))).thenReturn(ClientPreferences.DEFAULT_CONNECTION_URL); + Properties prefs = mock(Properties.class); + when(prefs.getProperty(eq("connection-url"), any(String.class))).thenReturn(ClientPreferences.DEFAULT_CONNECTION_URL); ClientPreferences clientPrefs = new ClientPreferences(prefs, keyring); assertEquals("mongodb://127.0.0.1:27518", clientPrefs.getConnectionUrl()); } diff -r 9ec44cd38946 -r d448210350bf common/test/src/main/java/com/redhat/thermostat/testutils/TestUtils.java --- a/common/test/src/main/java/com/redhat/thermostat/testutils/TestUtils.java Mon Jul 22 20:01:46 2013 +0200 +++ b/common/test/src/main/java/com/redhat/thermostat/testutils/TestUtils.java Fri Jul 26 12:29:07 2013 -0400 @@ -37,6 +37,7 @@ package com.redhat.thermostat.testutils; import java.io.File; +import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; @@ -65,47 +66,86 @@ } /** + * Creates and initializes a directory suitable for use as the storage's + * configuration directory + */ + public static String setupStorageConfigs(Properties dbConfig) throws IOException { + Random random = new Random(); + + String tmpDir = System.getProperty("java.io.tmpdir") + File.separatorChar + + Math.abs(random.nextInt()) + File.separatorChar; + + setupSystemStorageConfig(tmpDir, dbConfig); + setupUserStorageConfig(tmpDir); + + return tmpDir; + } + + private static void setupSystemStorageConfig(String root, Properties dbConfig) throws FileNotFoundException, IOException { + System.setProperty("THERMOSTAT_HOME", root); + + File config = new File(root, "etc"); + config.mkdirs(); + File tmpConfigs = new File(config, "db.properties"); + + dbConfig.store(new FileOutputStream(tmpConfigs), "thermostat test properties"); + } + + private static void setupUserStorageConfig(String root) { + System.setProperty("USER_THERMOSTAT_HOME", root); + + new File(root, "run").mkdirs(); + new File(root, "logs").mkdirs(); + + File data = new File(root + "data"); + data.mkdirs(); + new File(data, "db").mkdirs(); + } + + /** * Creates and initializes a directory suitable for use as the agent's * configuration directory - * - * @return a String containing the path to the temporary configuration directory - * @throws IOException */ - public static String setupAgentConfigs() throws IOException { + public static String setupAgentConfigs(Properties agentProperties) throws IOException { // need to create dummy config files for the tests Random random = new Random(); String tmpDir = System.getProperty("java.io.tmpdir") + File.separatorChar + Math.abs(random.nextInt()) + File.separatorChar; - System.setProperty("THERMOSTAT_HOME", tmpDir); - File agent = new File(tmpDir, "agent"); + setupSystemAgentConfig(tmpDir, agentProperties); + setupUserAgentConfig(tmpDir); + + return tmpDir; + } + + private static void setupSystemAgentConfig(String root, Properties agentProperties) throws FileNotFoundException, IOException { + System.setProperty("THERMOSTAT_HOME", root); + + File etc = new File(root, "etc"); + etc.mkdirs(); + File tmpConfigs = new File(etc, "agent.properties"); + + try (OutputStream propsOutputStream = new FileOutputStream(tmpConfigs)) { + agentProperties.store(propsOutputStream, "thermostat agent test properties"); + } + + File tmpAuth = new File(etc, "agent.auth"); + FileWriter authWriter = new FileWriter(tmpAuth); + authWriter.append("username=user\npassword=pass\n"); + authWriter.flush(); + authWriter.close(); + } + + private static void setupUserAgentConfig(String root) throws IOException { + System.setProperty("USER_THERMOSTAT_HOME", root); + + File agent = new File(root, "agent"); agent.mkdirs(); - File tmpConfigs = new File(agent, "agent.properties"); - new File(agent, "run").mkdirs(); new File(agent, "logs").mkdirs(); - File backends = new File(tmpDir, "backends"); - File system = new File(backends, "system"); - system.mkdirs(); - - Properties props = new Properties(); - - props.setProperty("SAVE_ON_EXIT", "true"); - props.setProperty("CONFIG_LISTEN_ADDRESS", "42.42.42.42:42"); - - try (OutputStream propsOutputStream = new FileOutputStream(tmpConfigs)) { - props.store(propsOutputStream, "thermostat agent test properties"); - } - - File tmpAuth = new File(agent, "agent.auth"); - FileWriter authWriter = new FileWriter(tmpAuth); - authWriter.append("username=user\npassword=pass\n"); - authWriter.flush(); - authWriter.close(); - return tmpDir; } } diff -r 9ec44cd38946 -r d448210350bf config/src/main/java/com/redhat/thermostat/shared/config/Configuration.java --- a/config/src/main/java/com/redhat/thermostat/shared/config/Configuration.java Mon Jul 22 20:01:46 2013 +0200 +++ b/config/src/main/java/com/redhat/thermostat/shared/config/Configuration.java Fri Jul 26 12:29:07 2013 -0400 @@ -41,107 +41,170 @@ import com.redhat.thermostat.shared.locale.LocaleResources; import com.redhat.thermostat.shared.locale.Translate; +/** + * Contains locations to various files and directories used by thermostat + * components. + *

+ * Some configuration files or directories are system-wide while + * others are per-user. System-wide file or directories are indicated + * by the word System in the name. These should contain non-mutable + * data that is meant to be used by all instances of thermostat + * running on one machine. Per-user directories will normally contain + * configuration and data specific for a different instance of + * thermostat. Per-user files and directories indicated by the word + * "User" in the method name. + *

+ * The directories are split according to functionality, along the lines of + * Filesystem Hierarchy Standard (FHS). + */ public class Configuration { + // Note: these paths are used by the integration tests too. Please update + // them whenever you change this class. + + private static final String THERMOSTAT_HOME = "THERMOSTAT_HOME"; + private static final String USER_THERMOSTAT_HOME = "USER_THERMOSTAT_HOME"; private static final String THERMOSTAT_USER_DIR = ".thermostat"; private static final Translate t = LocaleResources.createLocalizer(); - private String home; + private final String home; + private final File userHome; + private boolean printOsgiInfo = false; public Configuration() throws InvalidConfigurationException { // allow this to be specified also as a property, especially for // tests, this overrides the env setting - String home = System.getProperty("THERMOSTAT_HOME"); + String home = System.getProperty(THERMOSTAT_HOME); if (home == null) { - home = System.getenv("THERMOSTAT_HOME"); + home = System.getenv(THERMOSTAT_HOME); } if (home == null) { - throw new InvalidConfigurationException(t.localize(LocaleResources.ENV_NO_HOME)); + throw new InvalidConfigurationException(THERMOSTAT_HOME + " not defined..."); } this.home = home; - } - public String getThermostatHome() throws InvalidConfigurationException { - return home; + // allow this to be specified also as a special property, meant for tests + String userHome = System.getProperty(USER_THERMOSTAT_HOME); + if (userHome == null) { + userHome = System.getenv(USER_THERMOSTAT_HOME); + } + if (userHome == null) { + userHome = System.getProperty("user.home") + File.separatorChar + THERMOSTAT_USER_DIR; + } + this.userHome = new File(userHome); } - public String getThermostatUserHome() { - String home = System.getProperty("user.home"); - return home + File.separator + THERMOSTAT_USER_DIR; + /* + * Overall hierarchy + * + * TODO: these might have to be different for 'root' or 'thermostat' users + */ + + public File getSystemThermostatHome() throws InvalidConfigurationException { + return new File(home); } - public String getPluginRoot() throws InvalidConfigurationException { - return home + File.separator + "plugins"; + public File getUserThermostatHome() throws InvalidConfigurationException { + return userHome; } - public File getBackendsBaseDirectory() throws InvalidConfigurationException { - String loc = getThermostatHome() + File.separatorChar + "backends"; - File file = new File(loc); - return file; + public File getSystemPluginRoot() throws InvalidConfigurationException { + return new File(home, "plugins"); + } + + public File getSystemLibRoot() throws InvalidConfigurationException { + return new File(home, "libs"); + } + + public File getSystemNativeLibsRoot() throws InvalidConfigurationException { + return new File(getSystemLibRoot(), "native"); } - public String getLibRoot() throws InvalidConfigurationException { - return home + File.separator + "libs"; + public File getSystemConfigurationDirectory() throws InvalidConfigurationException { + return new File(getSystemThermostatHome(), "etc"); } - - public String getNativeLibsRoot() throws InvalidConfigurationException { - return getLibRoot() + File.separator + "native"; + + public File getUserConfigurationDirectory() throws InvalidConfigurationException { + return new File(getUserThermostatHome(), "etc"); } - public String getConfigurationDir() throws InvalidConfigurationException { - return home + File.separator + "etc"; + /** A location that contains data that is persisted */ + public File getUserPersistentDataDirectory() throws InvalidConfigurationException { + File dataDir = new File(getUserThermostatHome(), "data"); + return dataDir; + } + + /** Contains data that is only useful for the duration that thermostat is running */ + public File getUserRuntimeDataDirectory() throws InvalidConfigurationException { + File runDir = new File(getUserThermostatHome(), "run"); + return runDir; } - public File getStorageBaseDirectory() throws InvalidConfigurationException { - String loc = getThermostatHome() + File.separatorChar + "storage"; - File file = new File(loc); - return file; + public File getUserLogDirectory() throws InvalidConfigurationException { + File logDir = new File(getUserThermostatHome(), "logs"); + return logDir; } - - public File getStorageDirectory() throws InvalidConfigurationException { - return new File(getStorageBaseDirectory(), "db"); - } - - public File getStorageConfigurationFile() throws InvalidConfigurationException { - return new File(getStorageBaseDirectory(), "db.properties"); + + public File getUserCacheDirectory() throws InvalidConfigurationException { + File cacheDir = new File(getUserThermostatHome(), "cache"); + return cacheDir; } - public File getStorageLogFile() throws InvalidConfigurationException { - File logDir = new File(getStorageBaseDirectory(), "logs"); - File logFile = new File(logDir, "db.log"); - + /* Specific files and directories */ + + public File getUserStorageDirectory() throws InvalidConfigurationException { + return new File(getUserPersistentDataDirectory(), "db"); + } + + public File getSystemStorageConfigurationFile() throws InvalidConfigurationException { + return new File(getSystemConfigurationDirectory(), "db.properties"); + } + + public File getUserStorageConfigurationFile() throws InvalidConfigurationException { + return new File(getUserConfigurationDirectory(), "db.properties"); + } + + public File getUserStorageLogFile() throws InvalidConfigurationException { + File logFile = new File(getUserLogDirectory(), "db.log"); return logFile; } - public File getStoragePidFile() throws InvalidConfigurationException { - File logDir = new File(getStorageBaseDirectory(), "run"); - File logFile = new File(logDir, "db.pid"); - + public File getUserStoragePidFile() throws InvalidConfigurationException { + File logFile = new File(getUserRuntimeDataDirectory(), "db.pid"); return logFile; } - public File getAgentConfigurationFile() throws InvalidConfigurationException { - File agent = new File(getThermostatHome(), "agent"); - return new File(agent, "agent.properties"); + public File getSystemAgentConfigurationFile() throws InvalidConfigurationException { + return new File(getSystemConfigurationDirectory(), "agent.properties"); + } + + public File getUserAgentConfigurationFile() throws InvalidConfigurationException { + return new File(getUserConfigurationDirectory(), "agent.properties"); } - public File getAgentAuthConfigFile() throws InvalidConfigurationException { - File agent = new File(getThermostatHome(), "agent"); - return new File(agent, "agent.auth"); + public File getSystemAgentAuthConfigFile() throws InvalidConfigurationException { + return new File(getSystemConfigurationDirectory(), "agent.auth"); } - public File getClientConfigurationDirectory() throws InvalidConfigurationException { - File client = new File(getThermostatHome(), "client"); + public File getUserAgentAuthConfigFile() throws InvalidConfigurationException { + return new File(getUserConfigurationDirectory(), "agent.auth"); + } + + public File getUserClientConfigurationFile() throws InvalidConfigurationException { + File client = new File(getUserConfigurationDirectory(), "client.properties"); return client; } - public File getHistoryFile() throws InvalidConfigurationException { - File history = new File(getClientConfigurationDirectory(), "cli-history"); + public File getUserHistoryFile() throws InvalidConfigurationException { + File history = new File(getUserPersistentDataDirectory(), "cli-history"); return history; } + // TODO add logging files here (see LoggingUtils) + // TODO add ssl.properties file here (see SSLConfiguration) + public boolean getPrintOSGiInfo() { return printOsgiInfo; } diff -r 9ec44cd38946 -r d448210350bf config/src/main/java/com/redhat/thermostat/shared/config/NativeLibraryResolver.java --- a/config/src/main/java/com/redhat/thermostat/shared/config/NativeLibraryResolver.java Mon Jul 22 20:01:46 2013 +0200 +++ b/config/src/main/java/com/redhat/thermostat/shared/config/NativeLibraryResolver.java Fri Jul 26 12:29:07 2013 -0400 @@ -65,7 +65,7 @@ } try { Configuration config = new Configuration(); - nativeLibsRoot = config.getNativeLibsRoot(); + nativeLibsRoot = config.getSystemNativeLibsRoot().getPath(); } catch (InvalidConfigurationException e) { throw new AssertionError(e); } @@ -73,6 +73,6 @@ } private static String doResolve(String root, String libraryName) { - return root + File.separator + System.mapLibraryName(libraryName); + return new File(root, System.mapLibraryName(libraryName)).getAbsolutePath(); } } diff -r 9ec44cd38946 -r d448210350bf config/src/test/java/com/redhat/thermostat/shared/config/ConfigurationTest.java --- a/config/src/test/java/com/redhat/thermostat/shared/config/ConfigurationTest.java Mon Jul 22 20:01:46 2013 +0200 +++ b/config/src/test/java/com/redhat/thermostat/shared/config/ConfigurationTest.java Fri Jul 26 12:29:07 2013 -0400 @@ -57,7 +57,7 @@ // remove THERMOSTAT_HOME system property for a clean slate Properties props = System.getProperties(); Properties newProps = new Properties(); - for (Object key: props.keySet()) { + for (Object key : props.keySet()) { if (!key.equals("THERMOSTAT_HOME")) { newProps.put(key, props.get(key)); } @@ -66,35 +66,46 @@ } @Test - public void testLocations() throws InvalidConfigurationException, IOException { + public void testSystemLocations() throws InvalidConfigurationException, IOException { String thermostatHome = "/tmp"; System.setProperty("THERMOSTAT_HOME", thermostatHome); - + char s = File.separatorChar; Configuration config = new Configuration(); - Assert.assertEquals(thermostatHome, config.getThermostatHome()); + Assert.assertEquals(thermostatHome, config.getSystemThermostatHome().getCanonicalPath()); + + Assert.assertEquals(thermostatHome + s + "libs" + s + "native", + config.getSystemNativeLibsRoot().getCanonicalPath()); + Assert.assertEquals(thermostatHome + s + "etc", config.getSystemConfigurationDirectory().getCanonicalPath()); + Assert.assertEquals(thermostatHome + s + "libs", config.getSystemLibRoot().getCanonicalPath()); + Assert.assertEquals(thermostatHome + s + "plugins", config.getSystemPluginRoot().getCanonicalPath()); + } - Assert.assertEquals(thermostatHome + s + "agent" + s + "agent.properties", - config.getAgentConfigurationFile().getCanonicalPath()); - Assert.assertEquals(thermostatHome + s + "agent" + s + "agent.auth", - config.getAgentAuthConfigFile().getCanonicalPath()); - Assert.assertEquals(thermostatHome + s + "storage", config.getStorageBaseDirectory().getCanonicalPath()); - Assert.assertEquals(thermostatHome + s + "storage" + s + "db.properties", - config.getStorageConfigurationFile().getCanonicalPath()); - Assert.assertEquals(thermostatHome + s + "storage" + s + "db", - config.getStorageDirectory().getCanonicalPath()); - Assert.assertEquals(thermostatHome + s + "storage" + s + "logs" + s + "db.log", - config.getStorageLogFile().getCanonicalPath()); - Assert.assertEquals(thermostatHome + s + "storage" + s + "run" + s + "db.pid", - config.getStoragePidFile().getCanonicalPath()); - Assert.assertEquals(thermostatHome + s + "libs" + s + "native", - config.getNativeLibsRoot()); - Assert.assertEquals(thermostatHome + s + "libs", config.getLibRoot()); - Assert.assertEquals(thermostatHome + s + "plugins", config.getPluginRoot()); + @Test + public void testUserLocations() throws InvalidConfigurationException, IOException { + String thermostatHome = "/tmp"; + System.setProperty("THERMOSTAT_HOME", thermostatHome); + char s = File.separatorChar; + String userHome = System.getProperty("user.home") + s + ".thermostat"; + Configuration config = new Configuration(); + + Assert.assertEquals(userHome + s + "etc" + s + "agent.properties", + config.getUserAgentConfigurationFile().getCanonicalPath()); + Assert.assertEquals(userHome + s + "etc" + s + "agent.auth", + config.getUserAgentAuthConfigFile().getCanonicalPath()); + Assert.assertEquals(userHome + s + "etc" + s + "db.properties", + config.getUserStorageConfigurationFile().getCanonicalPath()); + + Assert.assertEquals(userHome + s + "data" + s + "db", + config.getUserStorageDirectory().getCanonicalPath()); + Assert.assertEquals(userHome + s + "run" + s + "db.pid", + config.getUserStoragePidFile().getCanonicalPath()); + Assert.assertEquals(userHome + s + "logs" + s + "db.log", + config.getUserStorageLogFile().getCanonicalPath()); } - + @Test public void instantiationThrowsException() { try { @@ -106,4 +117,3 @@ } } } - diff -r 9ec44cd38946 -r d448210350bf config/src/test/java/com/redhat/thermostat/shared/config/NativeLibrayResolverTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/config/src/test/java/com/redhat/thermostat/shared/config/NativeLibrayResolverTest.java Fri Jul 26 12:29:07 2013 -0400 @@ -0,0 +1,70 @@ +/* + * Copyright 2012, 2013 Red Hat, Inc. + * + * This file is part of Thermostat. + * + * Thermostat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published + * by the Free Software Foundation; either version 2, or (at your + * option) any later version. + * + * Thermostat is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Thermostat; see the file COPYING. If not see + * . + * + * Linking this code with other modules is making a combined work + * based on this code. Thus, the terms and conditions of the GNU + * General Public License cover the whole combination. + * + * As a special exception, the copyright holders of this code give + * you permission to link this code with independent modules to + * produce an executable, regardless of the license terms of these + * independent modules, and to copy and distribute the resulting + * executable under terms of your choice, provided that you also + * meet, for each linked independent module, the terms and conditions + * of the license of that module. An independent module is a module + * which is not derived from or based on this code. If you modify + * this code, you may extend this exception to your version of the + * library, but you are not obligated to do so. If you do not wish + * to do so, delete this exception statement from your version. + */ + +package com.redhat.thermostat.shared.config; + +import static org.junit.Assert.assertFalse; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class NativeLibrayResolverTest { + + private static final String THERMOSTAT_HOME = "THERMOSTAT_HOME"; + + private String saved; + + @Before + public void setUp() { + saved = System.setProperty(THERMOSTAT_HOME, "../foo/"); + } + + @After + public void tearDown() { + if (saved == null) { + System.clearProperty(THERMOSTAT_HOME); + } else { + System.setProperty(THERMOSTAT_HOME, null); + } + } + + @Test + public void testGetAbsoluteLibraryPath() { + String absPath = NativeLibraryResolver.getAbsoluteLibraryPath("foo"); + assertFalse(absPath.startsWith("..")); + } +} diff -r 9ec44cd38946 -r d448210350bf distribution/pom.xml --- a/distribution/pom.xml Mon Jul 22 20:01:46 2013 +0200 +++ b/distribution/pom.xml Fri Jul 26 12:29:07 2013 -0400 @@ -144,7 +144,7 @@ config - agent + etc true agent.properties @@ -164,7 +164,7 @@ config - storage + etc true db.properties diff -r 9ec44cd38946 -r d448210350bf distribution/scripts/thermostat --- a/distribution/scripts/thermostat Mon Jul 22 20:01:46 2013 +0200 +++ b/distribution/scripts/thermostat Fri Jul 26 12:29:07 2013 -0400 @@ -45,8 +45,10 @@ fi # Not always are installation directory and thermostat home one and # the same location. -THERMOSTAT_HOME=${THERMOSTAT_INSTALL_DIR} -export THERMOSTAT_HOME +if [ x"$THERMOSTAT_HOME" = x ] ; then + THERMOSTAT_HOME=${THERMOSTAT_INSTALL_DIR} + export THERMOSTAT_HOME +fi THERMOSTAT_LIBS="${THERMOSTAT_HOME}/libs" # need tools from the JVM diff -r 9ec44cd38946 -r d448210350bf eclipse/com.redhat.thermostat.eclipse/src/com/redhat/thermostat/eclipse/internal/preferences/MainPreferencePage.java --- a/eclipse/com.redhat.thermostat.eclipse/src/com/redhat/thermostat/eclipse/internal/preferences/MainPreferencePage.java Mon Jul 22 20:01:46 2013 +0200 +++ b/eclipse/com.redhat.thermostat.eclipse/src/com/redhat/thermostat/eclipse/internal/preferences/MainPreferencePage.java Fri Jul 26 12:29:07 2013 -0400 @@ -36,7 +36,7 @@ package com.redhat.thermostat.eclipse.internal.preferences; -import java.util.prefs.BackingStoreException; +import java.io.IOException; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.preferences.DefaultScope; @@ -113,7 +113,7 @@ clientPrefs.setCredentials(usernameEditor.getStringValue(), passwordEditor.getStringValue()); try { clientPrefs.flush(); - } catch (BackingStoreException e) { + } catch (IOException e) { LoggerFacility.getInstance().log(IStatus.ERROR, "Failed to save preferences", e); } } diff -r 9ec44cd38946 -r d448210350bf integration-tests/src/test/java/com/redhat/thermostat/itest/IntegrationTest.java --- a/integration-tests/src/test/java/com/redhat/thermostat/itest/IntegrationTest.java Mon Jul 22 20:01:46 2013 +0200 +++ b/integration-tests/src/test/java/com/redhat/thermostat/itest/IntegrationTest.java Fri Jul 26 12:29:07 2013 -0400 @@ -44,6 +44,7 @@ import java.lang.reflect.Field; import java.nio.file.Files; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import com.redhat.thermostat.common.utils.StreamUtils; @@ -55,14 +56,36 @@ /** * Helper methods to support writing an integration test. + *

+ * This class should be used by all integration tests to start + * thermostat and to obtain paths to various locations. Starting + * thermostat manually will cause issues with wrong paths being + * used. */ public class IntegrationTest { + public static class SpawnResult { + final Process process; + final Spawn spawn; + + public SpawnResult(Process process, Spawn spawn) { + this.process = process; + this.spawn = spawn; + } + } + + // FIXME Make sure all methods are using a sane environment that's set up correctly + public static final long TIMEOUT_IN_SECONDS = 30; public static final String SHELL_PROMPT = "Thermostat >"; - public static String getThermostatExecutable() { + private static final String THERMOSTAT_HOME = "THERMOSTAT_HOME"; + private static final String USER_THERMOSTAT_HOME = "USER_THERMOSTAT_HOME"; + + /* This is a mirror of paths from c.r.t.shared.Configuration */ + + private static String getThermostatExecutable() { return "../distribution/target/bin/thermostat"; } @@ -70,8 +93,20 @@ return "../distribution/target"; } + public static String getPluginHome() { + return getThermostatHome() + "/plugins"; + } + + public static String getConfigurationDir() { + return getThermostatHome() + "/etc"; + } + + public static String getUserThermostatHome() { + return "../distribution/target/user-home"; + } + public static String getStorageDataDirectory() { - return "../distribution/target/storage/db"; + return getUserThermostatHome() + "/data/db"; } public static void clearStorageDataDirectory() throws IOException { @@ -79,6 +114,15 @@ deleteFilesRecursivelyUnder(storageDir); } + public static Process runThermostat(String... args) throws IOException { + List completeArgs = new ArrayList(args.length+1); + completeArgs.add(getThermostatExecutable()); + completeArgs.addAll(Arrays.asList(args)); + ProcessBuilder builder = buildThermostatProcess(completeArgs); + + return builder.start(); + } + public static Spawn spawnThermostat(String... args) throws IOException { return spawnThermostat(false, args); } @@ -92,14 +136,52 @@ } } String toExecute = result.toString(); + Executor exec = null; if (localeDependent) { - Executor exec = new LocaleExecutor(toExecute); - return expect.spawn(exec); + exec = new LocaleExecutor(toExecute); } else { - return expect.spawn(toExecute); + exec = new SimpleExecutor(toExecute); } + return expect.spawn(exec); } + public static SpawnResult spawnThermostatAndGetProcess(String... args) throws IOException { + final List completeArgs = new ArrayList(args.length+1); + completeArgs.add(getThermostatExecutable()); + completeArgs.addAll(Arrays.asList(args)); + + final Process[] process = new Process[1]; + + ExpectJ expect = new ExpectJ(TIMEOUT_IN_SECONDS); + + Spawn spawn = expect.spawn(new Executor() { + @Override + public Process execute() throws IOException { + ProcessBuilder builder = buildThermostatProcess(completeArgs); + Process service = builder.start(); + process[0] = service; + return service; + } + }); + + return new SpawnResult(process[0], spawn); + } + + private static ProcessBuilder buildThermostatProcess(List args) { + ProcessBuilder builder = new ProcessBuilder(args); + builder.environment().put(THERMOSTAT_HOME, getThermostatHome()); + builder.environment().put(USER_THERMOSTAT_HOME, getUserThermostatHome()); + + return builder; + } + + /** + * Generic method to run a program. + *

+ * DO NOT USE THIS TO RUN THERMOSTAT ITSELF. It does not set up the + * environment correctly, using incorrect data and possibly overwriting + * important data. + */ public static Spawn spawn(List args) throws IOException { ExpectJ expect = new ExpectJ(TIMEOUT_IN_SECONDS); StringBuilder result = new StringBuilder(); @@ -109,11 +191,6 @@ return expect.spawn(result.substring(0, result.length() - 1)); } - public static Spawn spawn(Executor executor) throws IOException { - ExpectJ expect = new ExpectJ(TIMEOUT_IN_SECONDS); - return expect.spawn(executor); - } - /** * Kill the process and all its children, recursively. Sends SIGTERM. */ @@ -202,18 +279,45 @@ spawn.send(password + "\r"); } - private static class LocaleExecutor implements Executor { + private static class LocaleExecutor extends EnvironmentExecutor { - public static final String[] LANG_C = { "LANG=C " }; - private String process; + public static final String[] ENV_WITH_LANG_C = { + THERMOSTAT_HOME + "=" + getThermostatHome(), + USER_THERMOSTAT_HOME + "=" + getUserThermostatHome(), + "LANG=C" + }; public LocaleExecutor(String process) { + super(process, ENV_WITH_LANG_C); + } + + } + + private static class SimpleExecutor extends EnvironmentExecutor { + + public static final String[] ENV_WITH = { + THERMOSTAT_HOME + "=" + getThermostatHome(), + USER_THERMOSTAT_HOME + "=" + getUserThermostatHome(), + }; + + public SimpleExecutor(String process) { + super(process, ENV_WITH); + } + } + + private static class EnvironmentExecutor implements Executor { + + private final String[] env; + private final String process; + + public EnvironmentExecutor(String process, String[] env) { this.process = process; + this.env = env; } @Override public Process execute() throws IOException { - return Runtime.getRuntime().exec(process, LANG_C); + return Runtime.getRuntime().exec(process, env); } @Override diff -r 9ec44cd38946 -r d448210350bf integration-tests/src/test/java/com/redhat/thermostat/itest/PluginTest.java --- a/integration-tests/src/test/java/com/redhat/thermostat/itest/PluginTest.java Mon Jul 22 20:01:46 2013 +0200 +++ b/integration-tests/src/test/java/com/redhat/thermostat/itest/PluginTest.java Fri Jul 26 12:29:07 2013 -0400 @@ -51,7 +51,7 @@ public class PluginTest extends IntegrationTest { - private static final String PLUGIN_HOME = getThermostatHome() + File.separator + "plugins"; + private static final String PLUGIN_HOME = getPluginHome(); private static NewCommandPlugin newPlugin = new NewCommandPlugin(PLUGIN_HOME + File.separator + "new"); private static UnknownExtendsPlugin unknownExtension = new UnknownExtendsPlugin(PLUGIN_HOME + File.separator + "unknown"); diff -r 9ec44cd38946 -r d448210350bf integration-tests/src/test/java/com/redhat/thermostat/itest/StorageTest.java --- a/integration-tests/src/test/java/com/redhat/thermostat/itest/StorageTest.java Mon Jul 22 20:01:46 2013 +0200 +++ b/integration-tests/src/test/java/com/redhat/thermostat/itest/StorageTest.java Fri Jul 26 12:29:07 2013 -0400 @@ -36,11 +36,8 @@ package com.redhat.thermostat.itest; -import java.io.IOException; - import org.junit.Test; -import expectj.Executor; import expectj.Spawn; public class StorageTest extends IntegrationTest { @@ -76,25 +73,17 @@ @Test public void testServiceStartAndKilling() throws Exception { - Spawn storage; - final Process[] process = new Process[1]; - storage = spawn(new Executor() { - @Override - public Process execute() throws IOException { - ProcessBuilder builder = new ProcessBuilder(getThermostatExecutable(), "service"); - Process service = builder.start(); - process[0] = service; - return service; - } - }); + SpawnResult spawnResult = spawnThermostatAndGetProcess("service"); + Spawn storage = spawnResult.spawn; try { storage.expectErr("agent started"); } finally { - killRecursively(process[0]); + killRecursively(spawnResult.process); } + } } diff -r 9ec44cd38946 -r d448210350bf integration-tests/src/test/java/com/redhat/thermostat/itest/VmCommandsTest.java --- a/integration-tests/src/test/java/com/redhat/thermostat/itest/VmCommandsTest.java Mon Jul 22 20:01:46 2013 +0200 +++ b/integration-tests/src/test/java/com/redhat/thermostat/itest/VmCommandsTest.java Fri Jul 26 12:29:07 2013 -0400 @@ -55,7 +55,7 @@ public static void setUpOnce() throws IOException, InterruptedException { clearStorageDataDirectory(); - Process startStorage = new ProcessBuilder(getThermostatExecutable(), "storage", "--start").start(); + Process startStorage = runThermostat("storage", "--start"); startStorage.waitFor(); // TODO insert actual data into the database and test that @@ -63,7 +63,7 @@ @AfterClass public static void tearDownOnce() throws InterruptedException, IOException { - Process stopStorage = new ProcessBuilder(getThermostatExecutable(), "storage", "--stop").start(); + Process stopStorage = runThermostat("storage", "--stop"); stopStorage.waitFor(); } diff -r 9ec44cd38946 -r d448210350bf integration-tests/src/test/java/com/redhat/thermostat/itest/WebAppTest.java --- a/integration-tests/src/test/java/com/redhat/thermostat/itest/WebAppTest.java Mon Jul 22 20:01:46 2013 +0200 +++ b/integration-tests/src/test/java/com/redhat/thermostat/itest/WebAppTest.java Fri Jul 26 12:29:07 2013 -0400 @@ -95,7 +95,7 @@ import expectj.Spawn; -/* +/** * This test class starts up a mongod instance and a web storage instance * (in jetty container) in front of that. Tests should make their own * connection to the web storage, probably by making use of one of the @@ -217,10 +217,8 @@ private static final String PREP_USER = "prepuser"; private static final String PREP_PASSWORD = "preppassword"; private static final double EQUALS_DELTA = 0.00000000000001; - private static final String THERMOSTAT_USERS_FILE = getThermostatHome() + - "/etc/thermostat-users.properties"; - private static final String THERMOSTAT_ROLES_FILE = getThermostatHome() + - "/etc/thermostat-roles.properties"; + private static final String THERMOSTAT_USERS_FILE = getConfigurationDir() + "/thermostat-users.properties"; + private static final String THERMOSTAT_ROLES_FILE = getConfigurationDir() + "/thermostat-roles.properties"; private static final String VM_ID1 = "vmId1"; private static final String VM_ID2 = "vmId2"; private static final String VM_ID3 = "vmId3"; diff -r 9ec44cd38946 -r d448210350bf launcher/src/main/java/com/redhat/thermostat/launcher/internal/Activator.java --- a/launcher/src/main/java/com/redhat/thermostat/launcher/internal/Activator.java Mon Jul 22 20:01:46 2013 +0200 +++ b/launcher/src/main/java/com/redhat/thermostat/launcher/internal/Activator.java Fri Jul 26 12:29:07 2013 -0400 @@ -80,11 +80,11 @@ Keyring keyring = (Keyring)context.getService(reference); Configuration config = bundleService.getConfiguration(); - String commandsDir = config.getConfigurationDir() + File.separator + "commands"; + String commandsDir = new File(config.getSystemConfigurationDirectory(), "commands").toString(); CommandInfoSource builtInCommandSource = - new BuiltInCommandInfoSource(commandsDir, config.getLibRoot()); + new BuiltInCommandInfoSource(commandsDir, config.getSystemLibRoot().toString()); CommandInfoSource pluginCommandSource = new PluginCommandInfoSource( - config.getLibRoot(), config.getPluginRoot()); + config.getSystemLibRoot().toString(), config.getSystemPluginRoot().toString()); CommandInfoSource commands = new CompoundCommandInfoSource(builtInCommandSource, pluginCommandSource); cmdInfoReg = context.registerService(CommandInfoSource.class, commands, null); diff -r 9ec44cd38946 -r d448210350bf launcher/src/main/java/com/redhat/thermostat/launcher/internal/BundleManagerImpl.java --- a/launcher/src/main/java/com/redhat/thermostat/launcher/internal/BundleManagerImpl.java Mon Jul 22 20:01:46 2013 +0200 +++ b/launcher/src/main/java/com/redhat/thermostat/launcher/internal/BundleManagerImpl.java Fri Jul 26 12:29:07 2013 -0400 @@ -36,12 +36,12 @@ package com.redhat.thermostat.launcher.internal; +import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; import java.nio.file.SimpleFileVisitor; import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; @@ -90,8 +90,8 @@ long t1 = System.nanoTime(); try { - for (String root : new String[] { configuration.getLibRoot(), configuration.getPluginRoot() }) { - Files.walkFileTree(Paths.get(root), new SimpleFileVisitor() { + for (File root : new File[] { configuration.getSystemLibRoot(), configuration.getSystemPluginRoot() }) { + Files.walkFileTree(root.toPath(), new SimpleFileVisitor() { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { if (file.toFile().getName().endsWith(".jar")) { diff -r 9ec44cd38946 -r d448210350bf launcher/src/test/java/com/redhat/thermostat/launcher/internal/ActivatorTest.java --- a/launcher/src/test/java/com/redhat/thermostat/launcher/internal/ActivatorTest.java Mon Jul 22 20:01:46 2013 +0200 +++ b/launcher/src/test/java/com/redhat/thermostat/launcher/internal/ActivatorTest.java Fri Jul 26 12:29:07 2013 -0400 @@ -108,7 +108,7 @@ context.registerService(Command.class, helpCommand, props); Configuration config = mock(Configuration.class); - when(config.getThermostatHome()).thenReturn(""); + when(config.getSystemThermostatHome()).thenReturn(new File("")); when(registryService.getConfiguration()).thenReturn(config); BuiltInCommandInfoSource source1 = mock(BuiltInCommandInfoSource.class); diff -r 9ec44cd38946 -r d448210350bf launcher/src/test/java/com/redhat/thermostat/launcher/internal/BundleManagerImplTest.java --- a/launcher/src/test/java/com/redhat/thermostat/launcher/internal/BundleManagerImplTest.java Mon Jul 22 20:01:46 2013 +0200 +++ b/launcher/src/test/java/com/redhat/thermostat/launcher/internal/BundleManagerImplTest.java Fri Jul 26 12:29:07 2013 -0400 @@ -38,14 +38,12 @@ import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; -import static org.mockito.Matchers.isA; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.powermock.api.mockito.PowerMockito.mockStatic; import static org.powermock.api.mockito.PowerMockito.whenNew; -import java.io.File; import java.io.IOException; import java.lang.reflect.Method; import java.nio.file.FileVisitResult; @@ -67,15 +65,12 @@ import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; -import com.redhat.thermostat.plugin.validator.PluginConfigurationValidatorException; import com.redhat.thermostat.shared.config.Configuration; @RunWith(PowerMockRunner.class) @PrepareForTest({BundleManagerImpl.class, FrameworkUtil.class}) public class BundleManagerImplTest { - private static final String cmdName = "one"; - private static final String jar1Name = "/one.jar"; private static final String jar2Name = "/two.jar"; private static final String jar3Name = "/three.jar"; @@ -100,8 +95,8 @@ Files.createDirectories(jarRootDir); conf = mock(Configuration.class); - when(conf.getLibRoot()).thenReturn(jarRootDir.toFile().getPath()); - when(conf.getPluginRoot()).thenReturn(pluginRootDir.toFile().getPath()); + when(conf.getSystemLibRoot()).thenReturn(jarRootDir.toFile()); + when(conf.getSystemPluginRoot()).thenReturn(pluginRootDir.toFile()); theContext = mock(BundleContext.class); theFramework = mock(Framework.class); diff -r 9ec44cd38946 -r d448210350bf main/src/main/java/com/redhat/thermostat/main/impl/FrameworkProvider.java --- a/main/src/main/java/com/redhat/thermostat/main/impl/FrameworkProvider.java Mon Jul 22 20:01:46 2013 +0200 +++ b/main/src/main/java/com/redhat/thermostat/main/impl/FrameworkProvider.java Fri Jul 26 12:29:07 2013 -0400 @@ -95,7 +95,7 @@ } private String getOSGiPublicPackages() throws FileNotFoundException, IOException { - File osgiBundleDefinitions = new File(configuration.getConfigurationDir(), "osgi-export.properties"); + File osgiBundleDefinitions = new File(configuration.getSystemConfigurationDirectory(), "osgi-export.properties"); Properties bundles = new Properties(); bundles.load(new FileInputStream(osgiBundleDefinitions)); @@ -161,7 +161,10 @@ } private Framework makeFramework() throws FileNotFoundException, IOException { - File osgiCacheDir = new File(configuration.getThermostatHome(), "osgi-cache"); + File osgiCacheDir = new File(configuration.getUserCacheDirectory(), "osgi-cache"); + if (!osgiCacheDir.isDirectory() && !osgiCacheDir.mkdirs()) { + throw new RuntimeException("Unable to create " + osgiCacheDir); + } // Create temporary directory which will be used as cache for OSGi bundles. See // http://www.osgi.org/javadoc/r4v43/core/org/osgi/framework/Constants.html#FRAMEWORK_STORAGE @@ -281,7 +284,7 @@ } private String actualLocation(String resourceName) { - return new File(configuration.getLibRoot(), resourceName).toURI().toString(); + return new File(configuration.getSystemLibRoot(), resourceName).toURI().toString(); } } diff -r 9ec44cd38946 -r d448210350bf main/src/test/java/com/redhat/thermostat/main/ThermostatTest.java --- a/main/src/test/java/com/redhat/thermostat/main/ThermostatTest.java Mon Jul 22 20:01:46 2013 +0200 +++ b/main/src/test/java/com/redhat/thermostat/main/ThermostatTest.java Fri Jul 26 12:29:07 2013 -0400 @@ -80,6 +80,7 @@ tempDir = Files.createTempDirectory("test"); tempDir.toFile().deleteOnExit(); System.setProperty("THERMOSTAT_HOME", tempDir.toString()); + System.setProperty("USER_THERMOSTAT_HOME", tempDir.toString()); File tempEtc = new File(tempDir.toFile(), "etc"); tempEtc.mkdirs(); diff -r 9ec44cd38946 -r d448210350bf web/server/src/main/java/com/redhat/thermostat/web/server/WebStorageEndPoint.java --- a/web/server/src/main/java/com/redhat/thermostat/web/server/WebStorageEndPoint.java Mon Jul 22 20:01:46 2013 +0200 +++ b/web/server/src/main/java/com/redhat/thermostat/web/server/WebStorageEndPoint.java Fri Jul 26 12:29:07 2013 -0400 @@ -270,7 +270,7 @@ private File getThermostatHome() { try { Configuration config = new Configuration(); - return new File(config.getThermostatHome()); + return config.getSystemThermostatHome(); } catch (InvalidConfigurationException e) { // we should have just checked if this throws any exception logger.log(Level.SEVERE, "Illegal configuration!", e); diff -r 9ec44cd38946 -r d448210350bf web/server/src/main/java/com/redhat/thermostat/web/server/auth/spi/PropertiesUserValidator.java --- a/web/server/src/main/java/com/redhat/thermostat/web/server/auth/spi/PropertiesUserValidator.java Mon Jul 22 20:01:46 2013 +0200 +++ b/web/server/src/main/java/com/redhat/thermostat/web/server/auth/spi/PropertiesUserValidator.java Fri Jul 26 12:29:07 2013 -0400 @@ -61,7 +61,9 @@ private Properties users; PropertiesUserValidator() { - this((new Configuration().getConfigurationDir() + File.separator + DEFAULT_USERS_FILE)); + // this is the default configuration. it should be overriden through different means + // see javadoc of PropertiesUsernameRolesLoginModule + this((new Configuration().getSystemConfigurationDirectory() + File.separator + DEFAULT_USERS_FILE)); } PropertiesUserValidator(String usersFile) { diff -r 9ec44cd38946 -r d448210350bf web/server/src/main/java/com/redhat/thermostat/web/server/auth/spi/RolesAmender.java --- a/web/server/src/main/java/com/redhat/thermostat/web/server/auth/spi/RolesAmender.java Mon Jul 22 20:01:46 2013 +0200 +++ b/web/server/src/main/java/com/redhat/thermostat/web/server/auth/spi/RolesAmender.java Fri Jul 26 12:29:07 2013 -0400 @@ -71,7 +71,10 @@ private final Set users; RolesAmender(Set users) { - this((new Configuration().getConfigurationDir() + File.separator + DEFAULT_ROLES_FILE), users); + // this is the default configuration supplied with thermostat + // it should not be overriden by editing this configuraton file + // see javadocs of PropertiesUsernameRolesLoginModule + this((new Configuration().getSystemConfigurationDirectory() + File.separator + DEFAULT_ROLES_FILE), users); } RolesAmender(String rolesFile, Set users) {