Mercurial > hg > release > thermostat-1.2
changeset 1342:17897c533dff
Configuration now is CommonPaths and a service
reviewed-by: omajid, jerboaa, ebaron
review-thread: http://icedtea.classpath.org/pipermail/thermostat/2013-November/008729.html
line wrap: on
line diff
--- a/agent/cli/src/main/java/com/redhat/thermostat/agent/cli/impl/Activator.java Fri Nov 15 17:28:05 2013 -0700 +++ b/agent/cli/src/main/java/com/redhat/thermostat/agent/cli/impl/Activator.java Mon Nov 18 08:22:15 2013 -0700 @@ -47,6 +47,7 @@ import com.redhat.thermostat.common.MultipleServiceTracker.Action; import com.redhat.thermostat.common.cli.CommandRegistry; import com.redhat.thermostat.common.cli.CommandRegistryImpl; +import com.redhat.thermostat.shared.config.CommonPaths; import com.redhat.thermostat.storage.core.WriterID; public class Activator implements BundleActivator { @@ -61,6 +62,7 @@ Class<?>[] deps = new Class<?>[] { ExitStatus.class, + CommonPaths.class, WriterID.class // agent app uses it }; tracker = new MultipleServiceTracker(context, deps, new Action() { @@ -68,10 +70,11 @@ @Override public void dependenciesAvailable(Map<String, Object> services) { ExitStatus exitStatus = (ExitStatus) services.get(ExitStatus.class.getName()); + CommonPaths paths = (CommonPaths) services.get(CommonPaths.class.getName()); WriterID writerID = (WriterID) services.get(WriterID.class.getName()); agentApplication = new AgentApplication(context, exitStatus, writerID); reg.registerCommand("service", new ServiceCommand(context)); - reg.registerCommand("storage", new StorageCommand(exitStatus)); + reg.registerCommand("storage", new StorageCommand(exitStatus, paths)); reg.registerCommand("agent", agentApplication); }
--- a/agent/cli/src/main/java/com/redhat/thermostat/agent/cli/impl/db/StorageCommand.java Fri Nov 15 17:28:05 2013 -0700 +++ b/agent/cli/src/main/java/com/redhat/thermostat/agent/cli/impl/db/StorageCommand.java Mon Nov 18 08:22:15 2013 -0700 @@ -50,7 +50,7 @@ import com.redhat.thermostat.common.tools.ApplicationException; import com.redhat.thermostat.common.tools.ApplicationState; import com.redhat.thermostat.common.utils.LoggingUtils; -import com.redhat.thermostat.shared.config.Configuration; +import com.redhat.thermostat.shared.config.CommonPaths; import com.redhat.thermostat.shared.config.InvalidConfigurationException; import com.redhat.thermostat.shared.locale.Translate; @@ -62,24 +62,24 @@ private DBStartupConfiguration configuration; private DBOptionParser parser; private final ExitStatus exitStatus; + private final CommonPaths paths; private MongoProcessRunner runner; - public StorageCommand(ExitStatus exitStatus) { + public StorageCommand(ExitStatus exitStatus, CommonPaths paths) { this.exitStatus = exitStatus; + this.paths = paths; } private void parseArguments(Arguments args) throws InvalidConfigurationException { - - Configuration thermostatConfiguration = new Configuration(); - File dbPath = thermostatConfiguration.getUserStorageDirectory(); - File logFile = thermostatConfiguration.getUserStorageLogFile(); - File pidFile = thermostatConfiguration.getUserStoragePidFile(); - File systemPropertyFile = thermostatConfiguration.getSystemStorageConfigurationFile(); + File dbPath = paths.getUserStorageDirectory(); + File logFile = paths.getUserStorageLogFile(); + File pidFile = paths.getUserStoragePidFile(); + File systemPropertyFile = paths.getSystemStorageConfigurationFile(); if (!systemPropertyFile.exists()) { throw new InvalidConfigurationException(t.localize(LocaleResources.MISSING_DB_CONFIG, systemPropertyFile.toString())); } - File userPropertyFile = thermostatConfiguration.getUserStorageConfigurationFile(); + File userPropertyFile = paths.getUserStorageConfigurationFile(); // read everything that is in the configs this.configuration = new DBStartupConfiguration(systemPropertyFile, userPropertyFile, dbPath, logFile, pidFile); parser = new DBOptionParser(configuration, args);
--- a/agent/cli/src/test/java/com/redhat/thermostat/agent/cli/impl/ActivatorTest.java Fri Nov 15 17:28:05 2013 -0700 +++ b/agent/cli/src/test/java/com/redhat/thermostat/agent/cli/impl/ActivatorTest.java Mon Nov 18 08:22:15 2013 -0700 @@ -44,6 +44,7 @@ import com.redhat.thermostat.agent.cli.impl.db.StorageCommand; import com.redhat.thermostat.common.ExitStatus; +import com.redhat.thermostat.shared.config.CommonPaths; import com.redhat.thermostat.storage.core.WriterID; import com.redhat.thermostat.testutils.StubBundleContext; @@ -55,8 +56,10 @@ ExitStatus exitStatus = mock(ExitStatus.class); WriterID writerID = mock(WriterID.class); + CommonPaths paths = mock(CommonPaths.class); bundleContext.registerService(WriterID.class, writerID, null); bundleContext.registerService(ExitStatus.class, exitStatus, null); + bundleContext.registerService(CommonPaths.class, paths, null); Activator activator = new Activator(); @@ -64,7 +67,7 @@ activator.start(bundleContext); - assertEquals(2, bundleContext.getServiceListeners().size()); + assertEquals(3, bundleContext.getServiceListeners().size()); assertCommandIsRegistered(bundleContext, "agent", AgentApplication.class); assertCommandIsRegistered(bundleContext, "service", ServiceCommand.class); @@ -73,7 +76,7 @@ activator.stop(bundleContext); assertEquals(0, bundleContext.getServiceListeners().size()); - assertEquals(2, bundleContext.getAllServices().size()); + assertEquals(3, bundleContext.getAllServices().size()); } }
--- a/agent/cli/src/test/java/com/redhat/thermostat/agent/cli/impl/db/StorageCommandTest.java Fri Nov 15 17:28:05 2013 -0700 +++ b/agent/cli/src/test/java/com/redhat/thermostat/agent/cli/impl/db/StorageCommandTest.java Mon Nov 18 08:22:15 2013 -0700 @@ -43,10 +43,8 @@ import static org.mockito.Mockito.when; import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; import java.util.Properties; -import java.util.Random; import java.util.concurrent.CountDownLatch; import junit.framework.Assert; @@ -63,7 +61,9 @@ import com.redhat.thermostat.common.cli.SimpleArguments; import com.redhat.thermostat.common.tools.ApplicationException; import com.redhat.thermostat.common.tools.ApplicationState; +import com.redhat.thermostat.shared.config.CommonPaths; import com.redhat.thermostat.shared.config.InvalidConfigurationException; +import com.redhat.thermostat.shared.config.internal.CommonPathsImpl; import com.redhat.thermostat.testutils.TestUtils; public class StorageCommandTest { @@ -74,6 +74,7 @@ private String tmpDir; private ExitStatus exitStatus; + private CommonPaths paths; @Before public void setup() { @@ -89,6 +90,27 @@ } catch (IOException e) { Assert.fail("cannot setup tests: " + e); } + + paths = mock(CommonPathsImpl.class); + File baseDir = new File(tmpDir); + File userRuntimeDir = new File(baseDir, "run"); + File userDataDir = new File(baseDir, "data"); + File logsDir = new File(baseDir, "logs"); + File confDir = new File(baseDir, "etc"); + + when(paths.getUserThermostatHome()).thenReturn(baseDir); + when(paths.getUserRuntimeDataDirectory()).thenReturn(userRuntimeDir); + when(paths.getUserPersistentDataDirectory()).thenReturn(userDataDir); + when(paths.getUserConfigurationDirectory()).thenReturn(confDir); + when(paths.getUserStorageDirectory()).thenCallRealMethod(); + when(paths.getUserStorageConfigurationFile()).thenCallRealMethod(); + when(paths.getUserLogDirectory()).thenReturn(logsDir); + when(paths.getUserStorageLogFile()).thenCallRealMethod(); + when(paths.getUserStoragePidFile()).thenCallRealMethod(); + + when(paths.getSystemThermostatHome()).thenReturn(baseDir); + when(paths.getSystemConfigurationDirectory()).thenCallRealMethod(); + when(paths.getSystemStorageConfigurationFile()).thenCallRealMethod(); } @After @@ -105,7 +127,7 @@ CommandContext ctx = mock(CommandContext.class); when(ctx.getArguments()).thenReturn(args); - StorageCommand service = new StorageCommand(exitStatus) { + StorageCommand service = new StorageCommand(exitStatus, paths) { @Override MongoProcessRunner createRunner() { throw new AssertionError("dry run should never create an actual runner"); @@ -132,7 +154,7 @@ // TODO: stop not tested yet, but be sure it's not called from the code doThrow(new ApplicationException("mock exception")).when(runner).stopService(); - StorageCommand service = new StorageCommand(exitStatus) { + StorageCommand service = new StorageCommand(exitStatus, paths) { @Override MongoProcessRunner createRunner() { return runner;
--- a/agent/core/src/main/java/com/redhat/thermostat/agent/config/AgentConfigsUtils.java Fri Nov 15 17:28:05 2013 -0700 +++ b/agent/core/src/main/java/com/redhat/thermostat/agent/config/AgentConfigsUtils.java Mon Nov 18 08:22:15 2013 -0700 @@ -46,28 +46,29 @@ import java.util.Properties; import com.redhat.thermostat.agent.locale.LocaleResources; -import com.redhat.thermostat.shared.config.Configuration; import com.redhat.thermostat.shared.config.InvalidConfigurationException; import com.redhat.thermostat.shared.locale.Translate; public class AgentConfigsUtils { private static final Translate<LocaleResources> t = LocaleResources.createLocalizer(); + private static File systemConfiguration, userConfiguration, agentAuthFile; private static char[] pw = {'p', 'a', 's', 's', 'w', 'o', 'r', 'd'}; private static char[] user = {'u', 's', 'e', 'r', 'n', 'a', 'm', 'e'}; private static String newLine = System.lineSeparator(); private static char comment = '#'; + public static void setConfigFiles(File systemConfigFile, File userConfigFile, File agentAuthFile) { + AgentConfigsUtils.systemConfiguration = systemConfigFile; + AgentConfigsUtils.userConfiguration = userConfigFile; + AgentConfigsUtils.agentAuthFile = agentAuthFile; + } + public static AgentStartupConfiguration createAgentConfigs() throws InvalidConfigurationException { AgentStartupConfiguration config = new AgentStartupConfiguration(); - - Configuration mainConfig = new Configuration(); - File systemConfiguration = mainConfig.getSystemAgentConfigurationFile(); - File userConfiguration = mainConfig.getUserAgentConfigurationFile(); readAndSetProperties(systemConfiguration, userConfiguration, config); - File agentAuthFile = mainConfig.getUserAgentAuthConfigFile(); setAuthConfigFromFile(agentAuthFile, config); return config; } @@ -76,17 +77,21 @@ throws InvalidConfigurationException { Properties systemConfig = new Properties(); - try { - systemConfig.load(new FileInputStream(systemConfigFile)); - } catch (IOException e) { - throw new InvalidConfigurationException(e); + if (systemConfigFile != null) { + try { + systemConfig.load(new FileInputStream(systemConfigFile)); + } catch (IOException e) { + throw new InvalidConfigurationException(e); + } } Properties properties = new Properties(systemConfig); - try { - properties.load(new FileInputStream(userConfigFile)); - } catch (IOException e) { - // that's okay. just use system config + if (userConfigFile != null) { + try { + properties.load(new FileInputStream(userConfigFile)); + } catch (IOException e) { + // that's okay. just use system config + } } String db = properties.getProperty(AgentProperties.DB_URL.name()); @@ -114,7 +119,7 @@ // Default values will be enough if storage configured with not auth necessary. config.setUsername(""); config.setPassword(""); - if (authFile.canRead() && authFile.isFile()) { + if (authFile != null && authFile.canRead() && authFile.isFile()) { long length = authFile.length(); char[] authData = null; try (Reader reader = new InputStreamReader(new FileInputStream(authFile), StandardCharsets.US_ASCII)) {
--- a/agent/core/src/main/java/com/redhat/thermostat/agent/internal/Activator.java Fri Nov 15 17:28:05 2013 -0700 +++ b/agent/core/src/main/java/com/redhat/thermostat/agent/internal/Activator.java Mon Nov 18 08:22:15 2013 -0700 @@ -38,8 +38,12 @@ import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceReference; import com.redhat.thermostat.agent.VmBlacklist; + +import com.redhat.thermostat.agent.config.AgentConfigsUtils; +import com.redhat.thermostat.shared.config.CommonPaths; import com.redhat.thermostat.utils.management.MXBeanConnectionPool; import com.redhat.thermostat.utils.management.internal.AgentProxyFilter; import com.redhat.thermostat.utils.management.internal.MXBeanConnectionPoolImpl; @@ -48,19 +52,18 @@ public class Activator implements BundleActivator { - private final MXBeanConnectionPoolImpl pool; - - public Activator() { - this(new MXBeanConnectionPoolImpl()); - } - - Activator(MXBeanConnectionPoolImpl pool) { - this.pool = pool; - } + private MXBeanConnectionPoolImpl pool; @Override public void start(BundleContext context) throws Exception { + ServiceReference<CommonPaths> pathsRef = context.getServiceReference(CommonPaths.class); + CommonPaths paths = context.getService(pathsRef); + pool = new MXBeanConnectionPoolImpl(paths.getSystemBinRoot()); context.registerService(MXBeanConnectionPool.class, pool, null); + AgentConfigsUtils.setConfigFiles(paths.getSystemAgentConfigurationFile(), paths.getUserAgentConfigurationFile(), + paths.getUserAgentAuthConfigFile()); + paths = null; + context.ungetService(pathsRef); context.registerService(UserNameUtil.class, new UserNameUtilImpl(), null); VmBlacklistImpl blacklist = new VmBlacklistImpl(); blacklist.addVmFilter(new AgentProxyFilter()); @@ -70,7 +73,15 @@ @Override public void stop(BundleContext context) throws Exception { // Services automatically unregistered by framework - pool.shutdown(); + if (pool != null) { + pool.shutdown(); + pool = null; + } + } + + // Testing hook. + void setPool(MXBeanConnectionPoolImpl pool) { + this.pool = pool; } }
--- a/agent/core/src/main/java/com/redhat/thermostat/utils/management/internal/AgentProxyClient.java Fri Nov 15 17:28:05 2013 -0700 +++ b/agent/core/src/main/java/com/redhat/thermostat/utils/management/internal/AgentProxyClient.java Mon Nov 18 08:22:15 2013 -0700 @@ -51,7 +51,6 @@ import com.redhat.thermostat.common.tools.ApplicationException; import com.redhat.thermostat.common.utils.LoggedExternalProcess; import com.redhat.thermostat.common.utils.LoggingUtils; -import com.redhat.thermostat.shared.config.Configuration; class AgentProxyClient implements AgentProxyListener { @@ -62,22 +61,22 @@ private final RMIRegistry registry; private final int pid; private final ProcessCreator procCreator; - private final Configuration config; + private final File binPath; private final CountDownLatch started; private AgentProxyControl proxy; private Exception serverError; - AgentProxyClient(RMIRegistry registry, int pid) { - this(registry, pid, new Configuration(), new CountDownLatch(1), + AgentProxyClient(RMIRegistry registry, int pid, File binPath) { + this(registry, pid, binPath, new CountDownLatch(1), new ProcessCreator()); } - AgentProxyClient(RMIRegistry registry, int pid, Configuration config, + AgentProxyClient(RMIRegistry registry, int pid, File binPath, CountDownLatch started, ProcessCreator procCreator) { this.registry = registry; this.pid = pid; - this.config = config; + this.binPath = binPath; this.started = started; this.procCreator = procCreator; } @@ -120,7 +119,7 @@ } private void startProcess() throws IOException, ApplicationException { - String serverPath = config.getSystemBinRoot() + File.separator + SERVER_NAME; + String serverPath = binPath + File.separator + SERVER_NAME; procCreator.createAndRunProcess(new String[] { serverPath, String.valueOf(pid) }); try { boolean result = started.await(SERVER_TIMEOUT_MS, TimeUnit.MILLISECONDS);
--- a/agent/core/src/main/java/com/redhat/thermostat/utils/management/internal/MXBeanConnectionPoolImpl.java Fri Nov 15 17:28:05 2013 -0700 +++ b/agent/core/src/main/java/com/redhat/thermostat/utils/management/internal/MXBeanConnectionPoolImpl.java Mon Nov 18 08:22:15 2013 -0700 @@ -36,6 +36,7 @@ package com.redhat.thermostat.utils.management.internal; +import java.io.File; import java.io.IOException; import java.rmi.RemoteException; import java.util.HashMap; @@ -58,19 +59,21 @@ private final ConnectorCreator creator; private final RMIRegistry registry; + private final File binPath; - public MXBeanConnectionPoolImpl() { - this(new ConnectorCreator(), new RMIRegistry()); + public MXBeanConnectionPoolImpl(File binPath) { + this(new ConnectorCreator(), new RMIRegistry(), binPath); } // For testing purposes only - public MXBeanConnectionPoolImpl(RMIRegistry registry) { - this(new ConnectorCreator(), registry); + public MXBeanConnectionPoolImpl(RMIRegistry registry, File binPath) { + this(new ConnectorCreator(), registry, binPath); } - MXBeanConnectionPoolImpl(ConnectorCreator connectorCreator, RMIRegistry registry) { + MXBeanConnectionPoolImpl(ConnectorCreator connectorCreator, RMIRegistry registry, File binPath) { this.creator = connectorCreator; this.registry = registry; + this.binPath = binPath; // Start RMI registry try { @@ -86,7 +89,7 @@ if (data == null) { MXBeanConnector connector = null; try { - connector = creator.create(registry, pid); + connector = creator.create(registry, pid, binPath); connector.attach(); MXBeanConnectionImpl connection = connector.connect(); data = new Pair<Integer, MXBeanConnectionImpl>(1, connection); @@ -126,8 +129,8 @@ } static class ConnectorCreator { - public MXBeanConnector create(RMIRegistry registry, int pid) throws IOException, ApplicationException { - MXBeanConnector connector = new MXBeanConnector(registry, pid); + public MXBeanConnector create(RMIRegistry registry, int pid, File binPath) throws IOException, ApplicationException { + MXBeanConnector connector = new MXBeanConnector(registry, pid, binPath); return connector; } }
--- a/agent/core/src/main/java/com/redhat/thermostat/utils/management/internal/MXBeanConnector.java Fri Nov 15 17:28:05 2013 -0700 +++ b/agent/core/src/main/java/com/redhat/thermostat/utils/management/internal/MXBeanConnector.java Mon Nov 18 08:22:15 2013 -0700 @@ -37,6 +37,7 @@ package com.redhat.thermostat.utils.management.internal; import java.io.Closeable; +import java.io.File; import java.io.IOException; import java.rmi.RemoteException; @@ -52,8 +53,8 @@ private final AgentProxyClient client; private final JMXConnectionCreator jmxCreator; - public MXBeanConnector(RMIRegistry registry, int pid) throws IOException, ApplicationException { - this(new AgentProxyClient(registry, pid), new JMXConnectionCreator()); + public MXBeanConnector(RMIRegistry registry, int pid, File binPath) throws IOException, ApplicationException { + this(new AgentProxyClient(registry, pid, binPath), new JMXConnectionCreator()); } MXBeanConnector(AgentProxyClient client, JMXConnectionCreator jmxCreator) throws IOException, ApplicationException {
--- a/agent/core/src/test/java/com/redhat/thermostat/agent/config/AgentConfigsUtilsTest.java Fri Nov 15 17:28:05 2013 -0700 +++ b/agent/core/src/test/java/com/redhat/thermostat/agent/config/AgentConfigsUtilsTest.java Mon Nov 18 08:22:15 2013 -0700 @@ -63,6 +63,10 @@ try { TestUtils.setupAgentConfigs(agentProperties); + File agentConf = TestUtils.getAgentConfFile(); + File agentAuth = TestUtils.getAgentAuthFile(); + // By default system config == user config + AgentConfigsUtils.setConfigFiles(agentConf, agentConf, agentAuth); } catch (IOException e) { throw new AssertionError("Unable to create agent configuration", e); } @@ -96,6 +100,8 @@ Assert.assertEquals("", config.getPassword()); } + // TODO add test to ensure user agent config overrides system agent config. + @Test public void testAuthConfigWithConfigCommentedOut() throws IOException { File tmpAuth = createTempAuthFile("#username=user\n#password=pass\n");
--- a/agent/core/src/test/java/com/redhat/thermostat/agent/config/AgentOptionParserTest.java Fri Nov 15 17:28:05 2013 -0700 +++ b/agent/core/src/test/java/com/redhat/thermostat/agent/config/AgentOptionParserTest.java Mon Nov 18 08:22:15 2013 -0700 @@ -75,12 +75,14 @@ SimpleArguments args = new SimpleArguments(); args.addArgument("dbUrl", "testURL"); - AgentStartupConfiguration configs = AgentConfigsUtils.createAgentConfigs(); + AgentStartupConfiguration configs = new AgentStartupConfiguration(); + configs.setDatabaseURL("Not the right URL"); + configs.setPurge(true); AgentOptionParser parser = new AgentOptionParser(configs, args); parser.parse(); Assert.assertEquals("testURL", configs.getDBConnectionString()); - Assert.assertFalse(configs.purge()); + Assert.assertTrue(configs.purge()); } @Test
--- a/agent/core/src/test/java/com/redhat/thermostat/agent/internal/ActivatorTest.java Fri Nov 15 17:28:05 2013 -0700 +++ b/agent/core/src/test/java/com/redhat/thermostat/agent/internal/ActivatorTest.java Mon Nov 18 08:22:15 2013 -0700 @@ -39,14 +39,18 @@ import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import java.io.File; import org.junit.Test; import com.redhat.thermostat.agent.VmBlacklist; +import com.redhat.thermostat.shared.config.CommonPaths; +import com.redhat.thermostat.shared.config.NativeLibraryResolver; import com.redhat.thermostat.testutils.StubBundleContext; import com.redhat.thermostat.utils.management.MXBeanConnectionPool; import com.redhat.thermostat.utils.management.internal.MXBeanConnectionPoolImpl; -import com.redhat.thermostat.utils.management.internal.RMIRegistry; import com.redhat.thermostat.utils.username.UserNameUtil; import com.redhat.thermostat.utils.username.internal.UserNameUtilImpl; @@ -54,11 +58,16 @@ @Test public void verifyServiceIsRegistered() throws Exception { - StubBundleContext context = new StubBundleContext(); + CommonPaths paths = mock(CommonPaths.class); + when(paths.getSystemNativeLibsRoot()).thenReturn(new File("target")); + NativeLibraryResolver.setCommonPaths(paths); - RMIRegistry registry = mock(RMIRegistry.class); - MXBeanConnectionPoolImpl pool = new MXBeanConnectionPoolImpl(registry); - Activator activator = new Activator(pool); + StubBundleContext context = new StubBundleContext(); + context.registerService(CommonPaths.class.getName(), paths, null); + + //RMIRegistry registry = mock(RMIRegistry.class); + //MXBeanConnectionPoolImpl pool = new MXBeanConnectionPoolImpl(registry); + Activator activator = new Activator(); activator.start(context); @@ -73,7 +82,8 @@ StubBundleContext context = new StubBundleContext(); MXBeanConnectionPoolImpl pool = mock(MXBeanConnectionPoolImpl.class); - Activator activator = new Activator(pool); + Activator activator = new Activator(); + activator.setPool(pool); activator.stop(context);
--- a/agent/core/src/test/java/com/redhat/thermostat/utils/management/internal/AgentProxyClientTest.java Fri Nov 15 17:28:05 2013 -0700 +++ b/agent/core/src/test/java/com/redhat/thermostat/utils/management/internal/AgentProxyClientTest.java Mon Nov 18 08:22:15 2013 -0700 @@ -61,7 +61,6 @@ import com.redhat.thermostat.agent.proxy.common.AgentProxyListener; import com.redhat.thermostat.agent.proxy.common.AgentProxyLogin; import com.redhat.thermostat.common.tools.ApplicationException; -import com.redhat.thermostat.shared.config.Configuration; import com.redhat.thermostat.utils.management.internal.AgentProxyClient.ProcessCreator; public class AgentProxyClientTest { @@ -70,11 +69,11 @@ private RMIRegistry rmi; private Registry registry; private ProcessCreator procCreator; - private Configuration config; private CountDownLatch latch; private AgentProxyListener listenerStub; private AgentProxyLogin proxyLogin; private AgentProxyControl proxyControl; + private File binPath; @Before public void setup() throws Exception { @@ -89,9 +88,7 @@ when(proxyLogin.login()).thenReturn(proxyControl); procCreator = mock(ProcessCreator.class); - config = mock(Configuration.class); - String binPath = "/path/to/thermostat/bin"; - when(config.getSystemBinRoot()).thenReturn(new File(binPath)); + binPath = new File("/path/to/thermostat/bin"); latch = mock(CountDownLatch.class); } @@ -122,7 +119,7 @@ private void createClient() throws InterruptedException, IOException, ApplicationException { - client = new AgentProxyClient(rmi, 0, config, latch, procCreator); + client = new AgentProxyClient(rmi, 0, binPath, latch, procCreator); doAnswer(new Answer<Boolean>() { @Override @@ -138,7 +135,7 @@ @Test public void testCreateProxyFailed() throws Exception { - client = new AgentProxyClient(rmi, 0, config, latch, procCreator); + client = new AgentProxyClient(rmi, 0, binPath, latch, procCreator); final Exception error = mock(Exception.class); doAnswer(new Answer<Boolean>() { @@ -174,7 +171,7 @@ @Test public void testCreateProxyTimeout() throws Exception { when(latch.await(any(Long.class), any(TimeUnit.class))).thenReturn(false); - client = new AgentProxyClient(rmi, 0, config, latch, procCreator); + client = new AgentProxyClient(rmi, 0, binPath, latch, procCreator); try { client.createProxy();
--- a/agent/core/src/test/java/com/redhat/thermostat/utils/management/internal/MXBeanConnectionPoolImplTest.java Fri Nov 15 17:28:05 2013 -0700 +++ b/agent/core/src/test/java/com/redhat/thermostat/utils/management/internal/MXBeanConnectionPoolImplTest.java Mon Nov 18 08:22:15 2013 -0700 @@ -46,6 +46,8 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; +import java.io.File; + import org.junit.Test; import com.redhat.thermostat.utils.management.MXBeanConnection; @@ -53,17 +55,19 @@ public class MXBeanConnectionPoolImplTest { + private File binDir = mock(File.class); + @Test public void testAcquire() throws Exception { MXBeanConnectionImpl toReturn = mock(MXBeanConnectionImpl.class); MXBeanConnector connector = mock(MXBeanConnector.class); ConnectorCreator creator = mock(ConnectorCreator.class); - when(creator.create(any(RMIRegistry.class), anyInt())).thenReturn(connector); + when(creator.create(any(RMIRegistry.class), anyInt(), any(File.class))).thenReturn(connector); when(connector.connect()).thenReturn(toReturn); RMIRegistry registry = mock(RMIRegistry.class); - MXBeanConnectionPoolImpl pool = new MXBeanConnectionPoolImpl(creator, registry); + MXBeanConnectionPoolImpl pool = new MXBeanConnectionPoolImpl(creator, registry, binDir); MXBeanConnection connection = pool.acquire(0); @@ -81,11 +85,11 @@ MXBeanConnector connector = mock(MXBeanConnector.class); ConnectorCreator creator = mock(ConnectorCreator.class); - when(creator.create(any(RMIRegistry.class), anyInt())).thenReturn(connector); + when(creator.create(any(RMIRegistry.class), anyInt(), any(File.class))).thenReturn(connector); when(connector.connect()).thenReturn(toReturn); RMIRegistry registry = mock(RMIRegistry.class); - MXBeanConnectionPoolImpl pool = new MXBeanConnectionPoolImpl(creator, registry); + MXBeanConnectionPoolImpl pool = new MXBeanConnectionPoolImpl(creator, registry, binDir); MXBeanConnection connection1 = pool.acquire(0); @@ -107,11 +111,11 @@ MXBeanConnector connector = mock(MXBeanConnector.class); ConnectorCreator creator = mock(ConnectorCreator.class); - when(creator.create(any(RMIRegistry.class), anyInt())).thenReturn(connector); + when(creator.create(any(RMIRegistry.class), anyInt(), any(File.class))).thenReturn(connector); when(connector.connect()).thenReturn(actualConnection); RMIRegistry registry = mock(RMIRegistry.class); - MXBeanConnectionPoolImpl pool = new MXBeanConnectionPoolImpl(creator, registry); + MXBeanConnectionPoolImpl pool = new MXBeanConnectionPoolImpl(creator, registry, binDir); MXBeanConnection connection = pool.acquire(0); @@ -128,11 +132,11 @@ MXBeanConnector connector = mock(MXBeanConnector.class); ConnectorCreator creator = mock(ConnectorCreator.class); - when(creator.create(any(RMIRegistry.class), anyInt())).thenReturn(connector); + when(creator.create(any(RMIRegistry.class), anyInt(), any(File.class))).thenReturn(connector); when(connector.connect()).thenReturn(actualConnection); RMIRegistry registry = mock(RMIRegistry.class); - MXBeanConnectionPoolImpl pool = new MXBeanConnectionPoolImpl(creator, registry); + MXBeanConnectionPoolImpl pool = new MXBeanConnectionPoolImpl(creator, registry, binDir); // connection1 == connection1 == actualConnection MXBeanConnection connection1 = pool.acquire(0); @@ -152,7 +156,7 @@ public void testShutdown() throws Exception { RMIRegistry registry = mock(RMIRegistry.class); ConnectorCreator creator = mock(ConnectorCreator.class); - MXBeanConnectionPoolImpl pool = new MXBeanConnectionPoolImpl(creator, registry); + MXBeanConnectionPoolImpl pool = new MXBeanConnectionPoolImpl(creator, registry, binDir); verify(registry).start(); pool.shutdown();
--- a/client/cli/src/main/java/com/redhat/thermostat/client/cli/internal/Activator.java Fri Nov 15 17:28:05 2013 -0700 +++ b/client/cli/src/main/java/com/redhat/thermostat/client/cli/internal/Activator.java Mon Nov 18 08:22:15 2013 -0700 @@ -36,31 +36,61 @@ package com.redhat.thermostat.client.cli.internal; +import java.util.Map; + import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; +import com.redhat.thermostat.common.MultipleServiceTracker; +import com.redhat.thermostat.common.MultipleServiceTracker.Action; import com.redhat.thermostat.common.cli.CommandRegistry; import com.redhat.thermostat.common.cli.CommandRegistryImpl; +import com.redhat.thermostat.common.config.ClientPreferences; +import com.redhat.thermostat.shared.config.CommonPaths; +import com.redhat.thermostat.utils.keyring.Keyring; public class Activator implements BundleActivator { - private CommandRegistry reg; + private CommandRegistry reg = null; + private MultipleServiceTracker tracker; @Override - public void start(BundleContext context) throws Exception { + public void start(final BundleContext context) throws Exception { reg = new CommandRegistryImpl(context); reg.registerCommand("list-vms", new ListVMsCommand()); - reg.registerCommand("shell", new ShellCommand()); reg.registerCommand("vm-info", new VMInfoCommand()); reg.registerCommand("vm-stat", new VMStatCommand()); reg.registerCommand("disconnect", new DisconnectCommand()); - reg.registerCommand("connect", new ConnectCommand()); reg.registerCommand("clean-data", new CleanDataCommand(context)); + + Class<?>[] classes = new Class[] { + Keyring.class, + CommonPaths.class, + }; + tracker = new MultipleServiceTracker(context, classes, new Action() { + + @Override + public void dependenciesAvailable(Map<String, Object> services) { + Keyring keyring = (Keyring) services.get(Keyring.class.getName()); + CommonPaths paths = (CommonPaths) services.get(CommonPaths.class.getName()); + ClientPreferences prefs = new ClientPreferences(keyring, paths); + reg.registerCommand("connect", new ConnectCommand(prefs)); + reg.registerCommand("shell", new ShellCommand(context, paths)); + } + + @Override + public void dependenciesUnavailable() { + reg.unregisterCommand("connect"); + } + + }); + tracker.open(); } @Override public void stop(BundleContext context) throws Exception { + tracker.close(); reg.unregisterCommands(); }
--- a/client/cli/src/main/java/com/redhat/thermostat/client/cli/internal/ConnectCommand.java Fri Nov 15 17:28:05 2013 -0700 +++ b/client/cli/src/main/java/com/redhat/thermostat/client/cli/internal/ConnectCommand.java Mon Nov 18 08:22:15 2013 -0700 @@ -48,6 +48,7 @@ import com.redhat.thermostat.common.cli.CommandException; import com.redhat.thermostat.common.config.ClientPreferences; import com.redhat.thermostat.common.tools.StorageAuthInfoGetter; +import com.redhat.thermostat.shared.config.CommonPaths; import com.redhat.thermostat.shared.locale.Translate; import com.redhat.thermostat.storage.core.ConnectionException; import com.redhat.thermostat.storage.core.DbService; @@ -73,13 +74,14 @@ private BundleContext context; private DbServiceFactory dbServiceFactory; - public ConnectCommand() { - this(FrameworkUtil.getBundle(ConnectCommand.class).getBundleContext(), new DbServiceFactory()); + public ConnectCommand(ClientPreferences prefs) { + this(FrameworkUtil.getBundle(ConnectCommand.class).getBundleContext(), new DbServiceFactory(), prefs); } - ConnectCommand(BundleContext context, DbServiceFactory dbServiceFactory) { + ConnectCommand(BundleContext context, DbServiceFactory dbServiceFactory, ClientPreferences prefs) { this.context = context; this.dbServiceFactory = dbServiceFactory; + this.prefs = prefs; } @Override @@ -92,15 +94,6 @@ // Already connected, bail out throw new CommandException(translator.localize(LocaleResources.COMMAND_CONNECT_ALREADY_CONNECTED, connectionUrl)); } - if (prefs == null) { - ServiceReference keyringRef = context.getServiceReference(Keyring.class); - if (keyringRef == null) { - throw new CommandException(translator.localize(LocaleResources.COMMAND_CONNECT_NO_KEYRING)); - } - Keyring keyring = (Keyring) context.getService(keyringRef); - prefs = new ClientPreferences(keyring); - context.ungetService(keyringRef); - } String dbUrl = ctx.getArguments().getArgument(DB_URL_ARG); // This argument is considered "required" so option parsing should mean this is impossible. Objects.requireNonNull(dbUrl);
--- a/client/cli/src/main/java/com/redhat/thermostat/client/cli/internal/ShellCommand.java Fri Nov 15 17:28:05 2013 -0700 +++ b/client/cli/src/main/java/com/redhat/thermostat/client/cli/internal/ShellCommand.java Mon Nov 18 08:22:15 2013 -0700 @@ -59,7 +59,7 @@ import com.redhat.thermostat.common.cli.Console; import com.redhat.thermostat.common.utils.LoggingUtils; import com.redhat.thermostat.launcher.Launcher; -import com.redhat.thermostat.shared.config.Configuration; +import com.redhat.thermostat.shared.config.CommonPaths; import com.redhat.thermostat.shared.config.InvalidConfigurationException; import com.redhat.thermostat.shared.locale.Translate; @@ -78,10 +78,17 @@ private BundleContext bundleContext; static class HistoryProvider { + + private CommonPaths paths; + + HistoryProvider(CommonPaths paths) { + this.paths = paths; + } + public PersistentHistory get() { PersistentHistory history = null; try { - history = new FileHistory(new Configuration().getUserHistoryFile()); + history = new FileHistory(paths.getUserHistoryFile()); } catch (InvalidConfigurationException | IOException e) { /* no history available */ } @@ -89,8 +96,8 @@ } } - public ShellCommand() { - this(FrameworkUtil.getBundle(ShellCommand.class).getBundleContext(), new Version(), new HistoryProvider()); + public ShellCommand(BundleContext context, CommonPaths paths) { + this(context, new Version(), new HistoryProvider(paths)); } ShellCommand(BundleContext context, Version version, HistoryProvider provider) { @@ -171,6 +178,7 @@ if (launcherRef != null) { Launcher launcher = (Launcher) bundleContext.getService(launcherRef); launcher.run(parsed, true); + bundleContext.ungetService(launcherRef); } else { throw new CommandException(t.localize(LocaleResources.MISSING_LAUNCHER)); }
--- a/client/cli/src/test/java/com/redhat/thermostat/client/cli/internal/ActivatorTest.java Fri Nov 15 17:28:05 2013 -0700 +++ b/client/cli/src/test/java/com/redhat/thermostat/client/cli/internal/ActivatorTest.java Mon Nov 18 08:22:15 2013 -0700 @@ -37,21 +37,27 @@ package com.redhat.thermostat.client.cli.internal; import static com.redhat.thermostat.testutils.Asserts.assertCommandIsRegistered; +import static com.redhat.thermostat.testutils.Asserts.assertCommandIsNotRegistered; import static org.junit.Assert.assertEquals; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import java.io.File; + import org.junit.Test; import org.junit.runner.RunWith; import org.osgi.framework.Bundle; import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceRegistration; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; +import com.redhat.thermostat.shared.config.CommonPaths; import com.redhat.thermostat.testutils.StubBundleContext; +import com.redhat.thermostat.utils.keyring.Keyring; @RunWith(PowerMockRunner.class) @PrepareForTest(FrameworkUtil.class) @@ -68,6 +74,14 @@ StubBundleContext ctx = new StubBundleContext(); when(mockBundle.getBundleContext()).thenReturn(ctx); + + Keyring keyring = mock(Keyring.class); + ctx.registerService(Keyring.class, keyring, null); + CommonPaths paths = mock(CommonPaths.class); + File userConfig = mock(File.class); + when(userConfig.isFile()).thenReturn(false); + when(paths.getUserClientConfigurationFile()).thenReturn(userConfig); + ctx.registerService(CommonPaths.class, paths, null); Activator activator = new Activator(); @@ -79,10 +93,45 @@ assertCommandIsRegistered(ctx, "shell", ShellCommand.class); assertCommandIsRegistered(ctx, "vm-info", VMInfoCommand.class); assertCommandIsRegistered(ctx, "vm-stat", VMStatCommand.class); - + activator.stop(ctx); + + assertEquals(2, ctx.getAllServices().size()); + } + + @Test + public void testConnectCommandUnregisteredWhenDepsDisappear() throws Exception { + // Need to mock FrameworkUtil to avoid NPE in commands' no-arg constructors + PowerMockito.mockStatic(FrameworkUtil.class); + Bundle mockBundle = mock(Bundle.class); + when(FrameworkUtil.getBundle(any(Class.class))).thenReturn(mockBundle); + // When we call createFilter, we need a real return value + when(FrameworkUtil.createFilter(anyString())).thenCallRealMethod(); + + StubBundleContext ctx = new StubBundleContext(); + when(mockBundle.getBundleContext()).thenReturn(ctx); - assertEquals(0, ctx.getAllServices().size()); + Activator activator = new Activator(); + + activator.start(ctx); + + assertCommandIsNotRegistered(ctx, "connect", ConnectCommand.class); + + Keyring keyring = mock(Keyring.class); + ServiceRegistration keyringReg = ctx.registerService(Keyring.class, keyring, null); + CommonPaths paths = mock(CommonPaths.class); + File userConfig = mock(File.class); + when(userConfig.isFile()).thenReturn(false); + when(paths.getUserClientConfigurationFile()).thenReturn(userConfig); + ctx.registerService(CommonPaths.class, paths, null); + + assertCommandIsRegistered(ctx, "connect", ConnectCommand.class); + + keyringReg.unregister(); + + assertCommandIsNotRegistered(ctx, "connect", ConnectCommand.class); + + activator.stop(ctx); } }
--- a/client/cli/src/test/java/com/redhat/thermostat/client/cli/internal/ConnectCommandTest.java Fri Nov 15 17:28:05 2013 -0700 +++ b/client/cli/src/test/java/com/redhat/thermostat/client/cli/internal/ConnectCommandTest.java Mon Nov 18 08:22:15 2013 -0700 @@ -38,11 +38,8 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -55,12 +52,12 @@ import com.redhat.thermostat.common.cli.CommandContext; import com.redhat.thermostat.common.cli.CommandException; import com.redhat.thermostat.common.cli.SimpleArguments; +import com.redhat.thermostat.common.config.ClientPreferences; import com.redhat.thermostat.shared.locale.Translate; import com.redhat.thermostat.storage.core.DbService; import com.redhat.thermostat.storage.core.DbServiceFactory; import com.redhat.thermostat.test.TestCommandContextFactory; import com.redhat.thermostat.testutils.StubBundleContext; -import com.redhat.thermostat.utils.keyring.Keyring; public class ConnectCommandTest { @@ -78,7 +75,9 @@ context = new StubBundleContext(); dbServiceFactory = mock(DbServiceFactory.class); - cmd = new ConnectCommand(context, dbServiceFactory); + ClientPreferences prefs = mock(ClientPreferences.class); + when(prefs.getConnectionUrl()).thenReturn("http://localhost"); + cmd = new ConnectCommand(context, dbServiceFactory, prefs); } private void setupCommandContextFactory() { @@ -86,7 +85,6 @@ bundleContext = mock(BundleContext.class); when(bundleContext.getBundle(0)).thenReturn(sysBundle); cmdCtxFactory = new TestCommandContextFactory(bundleContext); - } @After @@ -97,8 +95,6 @@ @Test public void verifyConnectedThrowsExceptionWithDiagnosticMessage() { - Keyring keyring = mock(Keyring.class); - context.registerService(Keyring.class, keyring, null); String dbUrl = "fluff"; DbService dbService = mock(DbService.class); when(dbService.getConnectionUrl()).thenReturn(dbUrl); @@ -115,8 +111,6 @@ @Test public void verifyNotConnectedConnects() throws CommandException { - Keyring keyring = mock(Keyring.class); - context.registerService(Keyring.class, keyring, null); DbService dbService = mock(DbService.class); String username = "testuser"; @@ -132,25 +126,6 @@ } @Test - public void verifyNoKeyring() throws CommandException { - DbService dbService = mock(DbService.class); - - String dbUrl = "mongodb://10.23.122.1:12578"; - SimpleArguments args = new SimpleArguments(); - args.addArgument("dbUrl", dbUrl); - CommandContext ctx = cmdCtxFactory.createContext(args); - - try { - cmd.run(ctx); - fail(); - } catch (CommandException e) { - assertEquals(translator.localize(LocaleResources.COMMAND_CONNECT_NO_KEYRING).getContents(), e.getMessage()); - } - - verify(dbService, never()).connect(); - } - - @Test public void testIsStorageRequired() { assertFalse(cmd.isStorageRequired()); }
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/Main.java Fri Nov 15 17:28:05 2013 -0700 +++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/Main.java Mon Nov 18 08:22:15 2013 -0700 @@ -59,6 +59,7 @@ import com.redhat.thermostat.common.config.ClientPreferences; import com.redhat.thermostat.common.utils.LoggingUtils; import com.redhat.thermostat.internal.utils.laf.ThemeManager; +import com.redhat.thermostat.shared.config.CommonPaths; import com.redhat.thermostat.shared.locale.Translate; import com.redhat.thermostat.storage.core.Connection.ConnectionListener; import com.redhat.thermostat.storage.core.Connection.ConnectionStatus; @@ -77,35 +78,37 @@ private ApplicationService appSvc; private DbServiceFactory dbServiceFactory; private Keyring keyring; + private CommonPaths paths; private CountDownLatch shutdown; private MainWindowControllerImpl mainController; private MainWindowRunnable mainWindowRunnable; - public Main(BundleContext context, Keyring keyring, + public Main(BundleContext context, Keyring keyring, CommonPaths paths, ApplicationService appSvc, String[] args) { DbServiceFactory dbServiceFactory = new DbServiceFactory(); CountDownLatch shutdown = new CountDownLatch(1); MainWindowRunnable mainWindowRunnable = new MainWindowRunnable(); - init(context, appSvc, dbServiceFactory, keyring, shutdown, + init(context, appSvc, dbServiceFactory, keyring, paths, shutdown, mainWindowRunnable); } Main(BundleContext context, ApplicationService appSvc, - DbServiceFactory dbServiceFactory, Keyring keyring, + DbServiceFactory dbServiceFactory, Keyring keyring, CommonPaths paths, CountDownLatch shutdown, MainWindowRunnable mainWindowRunnable) { - init(context, appSvc, dbServiceFactory, keyring, shutdown, + init(context, appSvc, dbServiceFactory, keyring, paths, shutdown, mainWindowRunnable); } private void init(BundleContext context, ApplicationService appSvc, - DbServiceFactory dbServiceFactory, Keyring keyring, + DbServiceFactory dbServiceFactory, Keyring keyring, CommonPaths paths, CountDownLatch shutdown, MainWindowRunnable mainWindowRunnable) { this.context = context; this.appSvc = appSvc; this.dbServiceFactory = dbServiceFactory; this.keyring = keyring; + this.paths = paths; this.shutdown = shutdown; this.mainWindowRunnable = mainWindowRunnable; } @@ -151,7 +154,7 @@ private void tryConnecting() { final ExecutorService service = appSvc.getApplicationExecutor(); - ClientPreferences prefs = new ClientPreferences(keyring); + ClientPreferences prefs = new ClientPreferences(keyring, paths); connect(prefs, service); } @@ -237,7 +240,7 @@ } private void createPreferencesDialog(final ExecutorService service) { - ClientPreferences prefs = new ClientPreferences(keyring); + ClientPreferences prefs = new ClientPreferences(keyring, paths); ClientConfigurationView configDialog = new ClientConfigurationSwing(); ClientConfigurationController controller = new ClientConfigurationController(prefs, configDialog, new MainClientConfigReconnector(service));
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/MainWindowControllerImpl.java Fri Nov 15 17:28:05 2013 -0700 +++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/MainWindowControllerImpl.java Mon Nov 18 08:22:15 2013 -0700 @@ -83,6 +83,7 @@ import com.redhat.thermostat.common.ThermostatExtensionRegistry; import com.redhat.thermostat.common.config.ClientPreferences; import com.redhat.thermostat.common.utils.LoggingUtils; +import com.redhat.thermostat.shared.config.CommonPaths; import com.redhat.thermostat.shared.locale.Translate; import com.redhat.thermostat.storage.core.HostRef; import com.redhat.thermostat.storage.core.Ref; @@ -107,6 +108,7 @@ private MainView view; private Keyring keyring; + private CommonPaths paths; private HostInfoDAO hostInfoDAO; private VmInfoDAO vmInfoDAO; @@ -210,6 +212,7 @@ Class<?>[] deps = new Class<?>[] { Keyring.class, + CommonPaths.class, HostInfoDAO.class, VmInfoDAO.class, AgentInfoDAO.class, @@ -228,6 +231,8 @@ public void dependenciesAvailable(Map<String, Object> services) { keyring = (Keyring) services.get(Keyring.class.getName()); Objects.requireNonNull(keyring); + paths = (CommonPaths) services.get(CommonPaths.class.getName()); + Objects.requireNonNull(paths); hostInfoDAO = (HostInfoDAO) services.get(HostInfoDAO.class.getName()); Objects.requireNonNull(hostInfoDAO); vmInfoDAO = (VmInfoDAO) services.get(VmInfoDAO.class.getName()); @@ -438,7 +443,7 @@ } private void showConfigureClientPreferences() { - ClientPreferences prefs = new ClientPreferences(keyring); + ClientPreferences prefs = new ClientPreferences(keyring, paths); ClientConfigurationView view = clientConfigViewProvider.createView(); ClientConfigurationController controller = new ClientConfigurationController(prefs, view); controller.showDialog();
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/osgi/ThermostatActivator.java Fri Nov 15 17:28:05 2013 -0700 +++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/osgi/ThermostatActivator.java Mon Nov 18 08:22:15 2013 -0700 @@ -61,7 +61,7 @@ import com.redhat.thermostat.common.cli.CommandRegistry; import com.redhat.thermostat.common.cli.CommandRegistryImpl; - +import com.redhat.thermostat.shared.config.CommonPaths; import com.redhat.thermostat.utils.keyring.Keyring; public class ThermostatActivator implements BundleActivator { @@ -92,6 +92,7 @@ Class<?>[] deps = new Class<?>[] { Keyring.class, + CommonPaths.class, ApplicationService.class, }; dependencyTracker = new MultipleServiceTracker(context, deps, new Action() { @@ -101,9 +102,10 @@ @Override public void dependenciesAvailable(Map<String, Object> services) { Keyring keyring = (Keyring) services.get(Keyring.class.getName()); + CommonPaths paths = (CommonPaths) services.get(CommonPaths.class.getName()); ApplicationService appSvc = (ApplicationService) services.get(ApplicationService.class.getName()); cmdReg = new CommandRegistryImpl(context); - main = new Main(context, keyring, appSvc, new String[0]); + main = new Main(context, keyring, paths, appSvc, new String[0]); GUIClientCommand cmd = new GUIClientCommand(main); cmdReg.registerCommand("gui", cmd);
--- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/MainTest.java Fri Nov 15 17:28:05 2013 -0700 +++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/MainTest.java Mon Nov 18 08:22:15 2013 -0700 @@ -44,6 +44,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import java.io.File; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; @@ -59,6 +60,7 @@ import com.redhat.thermostat.client.swing.internal.Main.MainWindowRunnable; import com.redhat.thermostat.common.ApplicationService; import com.redhat.thermostat.common.TimerFactory; +import com.redhat.thermostat.shared.config.CommonPaths; import com.redhat.thermostat.storage.core.Connection.ConnectionListener; import com.redhat.thermostat.storage.core.Connection.ConnectionStatus; import com.redhat.thermostat.storage.core.DbService; @@ -83,6 +85,7 @@ private StubBundleContext context; private ApplicationService appService; private Keyring keyring; + private CommonPaths paths; private CountDownLatch shutdown; @Before @@ -116,6 +119,11 @@ when(appService.getTimerFactory()).thenReturn(timerFactory); keyring = mock(Keyring.class); + paths = mock(CommonPaths.class); + File userConfig = mock(File.class); + when(userConfig.isFile()).thenReturn(false); + when(paths.getUserClientConfigurationFile()).thenReturn(userConfig); + shutdown = mock(CountDownLatch.class); } @@ -134,7 +142,7 @@ @Test public void verifyRunWaitsForShutdown() throws Exception { - Main main = new Main(context, appService, dbServiceFactory, keyring, shutdown, mainWindowRunnable); + Main main = new Main(context, appService, dbServiceFactory, keyring, paths, shutdown, mainWindowRunnable); main.run(); @@ -145,7 +153,7 @@ @Test public void verifyConnectionIsMade() throws Exception { - Main main = new Main(context, appService, dbServiceFactory, keyring, shutdown, mainWindowRunnable); + Main main = new Main(context, appService, dbServiceFactory, keyring, paths, shutdown, mainWindowRunnable); main.run(); @@ -161,7 +169,7 @@ context.registerService(HostInfoDAO.class, hostInfoDAO, null); VmInfoDAO vmInfoDAO = mock(VmInfoDAO.class); context.registerService(VmInfoDAO.class, vmInfoDAO, null); - Main main = new Main(context, appService, dbServiceFactory, keyring, shutdown, mainWindowRunnable); + Main main = new Main(context, appService, dbServiceFactory, keyring, paths, shutdown, mainWindowRunnable); main.run(); @@ -179,7 +187,7 @@ @Test public void verifyFailedConnectionTriggersShutdown() throws Exception { - Main main = new Main(context, appService, dbServiceFactory, keyring, shutdown, mainWindowRunnable); + Main main = new Main(context, appService, dbServiceFactory, keyring, paths, shutdown, mainWindowRunnable); main.run();
--- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/MainWindowControllerImplTest.java Fri Nov 15 17:28:05 2013 -0700 +++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/MainWindowControllerImplTest.java Mon Nov 18 08:22:15 2013 -0700 @@ -75,6 +75,7 @@ import com.redhat.thermostat.common.ThermostatExtensionRegistry.Action; import com.redhat.thermostat.common.Timer; import com.redhat.thermostat.common.TimerFactory; +import com.redhat.thermostat.shared.config.CommonPaths; import com.redhat.thermostat.shared.locale.LocalizedString; import com.redhat.thermostat.storage.dao.AgentInfoDAO; import com.redhat.thermostat.storage.dao.BackendInfoDAO; @@ -135,6 +136,8 @@ Keyring keyring = mock(Keyring.class); context.registerService(Keyring.class, keyring, null); + CommonPaths paths = mock(CommonPaths.class); + context.registerService(CommonPaths.class, paths, null); mockHostsDAO = mock(HostInfoDAO.class); context.registerService(HostInfoDAO.class, mockHostsDAO, null);
--- a/common/core/src/main/java/com/redhat/thermostat/common/cli/CommandRegistry.java Fri Nov 15 17:28:05 2013 -0700 +++ b/common/core/src/main/java/com/redhat/thermostat/common/cli/CommandRegistry.java Mon Nov 18 08:22:15 2013 -0700 @@ -40,6 +40,8 @@ public void registerCommand(String name, Command cmd); + public void unregisterCommand(String name); + public void unregisterCommands(); }
--- a/common/core/src/main/java/com/redhat/thermostat/common/cli/CommandRegistryImpl.java Fri Nov 15 17:28:05 2013 -0700 +++ b/common/core/src/main/java/com/redhat/thermostat/common/cli/CommandRegistryImpl.java Mon Nov 18 08:22:15 2013 -0700 @@ -36,9 +36,9 @@ package com.redhat.thermostat.common.cli; -import java.util.ArrayList; -import java.util.Collection; +import java.util.HashMap; import java.util.Hashtable; +import java.util.Map; import java.util.Objects; import org.osgi.framework.BundleContext; @@ -50,31 +50,39 @@ public class CommandRegistryImpl implements CommandRegistry { private BundleContext context; - private Collection<ServiceRegistration<?>> myRegisteredCommands; + private Map<String, ServiceRegistration<?>> regMapping; public CommandRegistryImpl(BundleContext ctx) { context = ctx; - myRegisteredCommands = new ArrayList<>(); + regMapping = new HashMap<>(); } @Override - public void registerCommand(String name, Command cmd) { + public synchronized void registerCommand(String name, Command cmd) { Objects.requireNonNull(name); Objects.requireNonNull(cmd); Hashtable<String,String> props = new Hashtable<>(); props.put(Command.NAME, name); ServiceRegistration<?> registration = context.registerService(Command.class.getName(), cmd, props); - myRegisteredCommands.add(registration); + regMapping.put(name, registration); } @Override - public void unregisterCommands() { - for (ServiceRegistration<?> reg : myRegisteredCommands) { + public synchronized void unregisterCommand(String name) { + Objects.requireNonNull(name); + ServiceRegistration reg = regMapping.remove(name); + if (reg != null) { + reg.unregister(); + } + } + + @Override + public synchronized void unregisterCommands() { + for (ServiceRegistration<?> reg : regMapping.values()) { reg.unregister(); } - // we've just unregistered commands - myRegisteredCommands.clear(); + regMapping.clear(); } }
--- a/common/core/src/main/java/com/redhat/thermostat/common/config/ClientPreferences.java Fri Nov 15 17:28:05 2013 -0700 +++ b/common/core/src/main/java/com/redhat/thermostat/common/config/ClientPreferences.java Mon Nov 18 08:22:15 2013 -0700 @@ -38,7 +38,6 @@ import java.io.File; import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; @@ -47,7 +46,7 @@ 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.CommonPaths; import com.redhat.thermostat.shared.config.InvalidConfigurationException; import com.redhat.thermostat.utils.keyring.Credentials; import com.redhat.thermostat.utils.keyring.Keyring; @@ -63,15 +62,20 @@ private static final Logger logger = LoggingUtils.getLogger(ClientPreferences.class); private Properties prefs; - private Keyring keyring; + private File userConfig; private Credentials userCredentials; - public ClientPreferences(Keyring keyring) { + public ClientPreferences(Keyring keyring, CommonPaths files) { + userConfig = files.getUserClientConfigurationFile(); Properties props = new Properties(); + loadPrefs(props); + init(props, keyring); + } + + private void loadPrefs(Properties props) { try { - File userConfig = new Configuration().getUserClientConfigurationFile(); if (userConfig.isFile()) { try { try (InputStream fis = new FileInputStream(userConfig)) { @@ -84,7 +88,6 @@ } catch (InvalidConfigurationException e) { logger.log(Level.CONFIG, "unable to load configuration", e); } - init(props, keyring); } // Testing hook with injectable j.u.Properties @@ -145,7 +148,7 @@ } public void flush() throws IOException { - prefs.store(new FileWriter(new Configuration().getUserClientConfigurationFile()), ""); + prefs.store(new FileWriter(userConfig), ""); userCredentials.setUserName(getUserName()); if (getSaveEntitlements()) { keyring.loadPassword(userCredentials);
--- a/common/core/src/main/java/com/redhat/thermostat/common/utils/LoggingUtils.java Fri Nov 15 17:28:05 2013 -0700 +++ b/common/core/src/main/java/com/redhat/thermostat/common/utils/LoggingUtils.java Mon Nov 18 08:22:15 2013 -0700 @@ -48,7 +48,7 @@ import com.redhat.thermostat.common.LogFormatter; import com.redhat.thermostat.common.locale.LocaleResources; -import com.redhat.thermostat.shared.config.Configuration; +import com.redhat.thermostat.shared.config.CommonPaths; import com.redhat.thermostat.shared.config.InvalidConfigurationException; import com.redhat.thermostat.shared.locale.Translate; @@ -124,15 +124,15 @@ root.removeHandler(handler); } - public static void loadGlobalLoggingConfig() throws InvalidConfigurationException { - File systemConfigurationDir = new Configuration().getSystemConfigurationDirectory(); + public static void loadGlobalLoggingConfig(CommonPaths paths) throws InvalidConfigurationException { + File systemConfigurationDir = paths.getSystemConfigurationDirectory(); File loggingPropertiesFile = new File(systemConfigurationDir, "logging.properties"); loadConfig(loggingPropertiesFile); } - public static void loadUserLoggingConfig() throws InvalidConfigurationException { - File userConfigurationDir = new Configuration().getUserConfigurationDirectory(); + public static void loadUserLoggingConfig(CommonPaths paths) throws InvalidConfigurationException { + File userConfigurationDir = paths.getUserConfigurationDirectory(); File loggingPropertiesFile = new File(userConfigurationDir, "logging.properties"); loadConfig(loggingPropertiesFile); }
--- a/common/core/src/main/java/com/redhat/thermostat/test/TestCommandContextFactory.java Fri Nov 15 17:28:05 2013 -0700 +++ b/common/core/src/main/java/com/redhat/thermostat/test/TestCommandContextFactory.java Mon Nov 18 08:22:15 2013 -0700 @@ -115,6 +115,11 @@ } public String getOutput() { + try { + out.flush(); + } catch (IOException e) { + // ignore + } return new String(out.toByteArray()); }
--- a/common/core/src/main/java/com/redhat/thermostat/test/TestCommandRegistry.java Fri Nov 15 17:28:05 2013 -0700 +++ b/common/core/src/main/java/com/redhat/thermostat/test/TestCommandRegistry.java Mon Nov 18 08:22:15 2013 -0700 @@ -64,5 +64,10 @@ commands.clear(); } + @Override + public void unregisterCommand(String name) { + commands.remove(name); + } + }
--- a/common/test/src/main/java/com/redhat/thermostat/testutils/Asserts.java Fri Nov 15 17:28:05 2013 -0700 +++ b/common/test/src/main/java/com/redhat/thermostat/testutils/Asserts.java Mon Nov 18 08:22:15 2013 -0700 @@ -41,12 +41,24 @@ public class Asserts { public static void assertCommandIsRegistered(StubBundleContext context, String name, Class<?> klass) { + assertCommandRegistration(context, name, klass, true); + } + + public static void assertCommandIsNotRegistered(StubBundleContext context, String name, Class<?> klass) { + assertCommandRegistration(context, name, klass, false); + } + + private static void assertCommandRegistration(StubBundleContext context, String name, Class<?> klass, boolean wantRegistered) { // The Command class is not visible to this module, so we have to live // with hardcoding some details here Hashtable<String,String> props = new Hashtable<>(); props.put("COMMAND_NAME", name); - if (!context.isServiceRegistered("com.redhat.thermostat.common.cli.Command", klass, props)) { - throw new AssertionError("Command " + name + " is not registered"); + boolean isRegistered = context.isServiceRegistered("com.redhat.thermostat.common.cli.Command", klass, props); + if (!isRegistered && wantRegistered) { + throw new AssertionError("Command " + name + " is not registered but should be"); + } + if (isRegistered && !wantRegistered) { + throw new AssertionError("Command " + name + " is registered but should not be"); } } }
--- a/common/test/src/main/java/com/redhat/thermostat/testutils/StubServiceReference.java Fri Nov 15 17:28:05 2013 -0700 +++ b/common/test/src/main/java/com/redhat/thermostat/testutils/StubServiceReference.java Mon Nov 18 08:22:15 2013 -0700 @@ -40,6 +40,7 @@ import java.util.Dictionary; import java.util.Enumeration; import java.util.List; +import java.util.Objects; import org.osgi.framework.Bundle; import org.osgi.framework.Constants; @@ -125,5 +126,25 @@ return information; } + @Override + public int hashCode() { + Integer ranking = (Integer) getProperty(Constants.SERVICE_RANKING); + Integer serviceId = (Integer) getProperty(Constants.SERVICE_ID); + return Objects.hash(ranking, serviceId); + } + + @Override + public boolean equals(Object other) { + if ((other == null) || !(other instanceof ServiceReference)) { + return false; + } + ServiceReference ref = (ServiceReference) other; + + int myRanking = ((Integer) getProperty(Constants.SERVICE_RANKING)).intValue(); + int otherRanking = ((Integer) ref.getProperty(Constants.SERVICE_RANKING)).intValue(); + int myServiceId = ((Integer) getProperty(Constants.SERVICE_ID)).intValue(); + int otherServiceId = ((Integer) ref.getProperty(Constants.SERVICE_ID)).intValue(); + return myRanking == otherRanking && myServiceId == otherServiceId; + } }
--- a/common/test/src/main/java/com/redhat/thermostat/testutils/TestUtils.java Fri Nov 15 17:28:05 2013 -0700 +++ b/common/test/src/main/java/com/redhat/thermostat/testutils/TestUtils.java Mon Nov 18 08:22:15 2013 -0700 @@ -49,6 +49,8 @@ // FIXME the methods in this class can probably be split more sanely public class TestUtils { + private static File agentConf, agentAuth; + /** * @return the process id of the current process */ @@ -113,31 +115,62 @@ String tmpDir = System.getProperty("java.io.tmpdir") + File.separatorChar + Math.abs(random.nextInt()) + File.separatorChar; - setupSystemAgentConfig(tmpDir, agentProperties); + System.setProperty("THERMOSTAT_HOME", tmpDir); + File etc = makeEtc(tmpDir); + setupSystemAgentConfig(etc, agentProperties); setupUserAgentConfig(tmpDir); + setupAgentAuth(etc); return tmpDir; } - private static void setupSystemAgentConfig(String root, Properties agentProperties) throws FileNotFoundException, IOException { - System.setProperty("THERMOSTAT_HOME", root); + public static File getAgentConfFile() { + return agentConf; + } + + public static File getAgentAuthFile() { + return agentAuth; + } + public static void deleteRecursively(File root) throws IOException { + if (root.isFile()) { + root.delete(); + return; + } else if (root.isDirectory()) { + File[] children = root.listFiles(); + for (File child : children) { + deleteRecursively(child); + } + root.delete(); + return; + } else { + throw new IOException("Asked to delete but not file or directory" + root.getPath()); + } + } + + private static File makeEtc(String root) { File etc = new File(root, "etc"); etc.mkdirs(); - File tmpConfigs = new File(etc, "agent.properties"); + return etc; + } - try (OutputStream propsOutputStream = new FileOutputStream(tmpConfigs)) { + private static void setupSystemAgentConfig(File etc, Properties agentProperties) throws FileNotFoundException, IOException { + agentConf = new File(etc, "agent.properties"); + + try (OutputStream propsOutputStream = new FileOutputStream(agentConf)) { agentProperties.store(propsOutputStream, "thermostat agent test properties"); } + } - File tmpAuth = new File(etc, "agent.auth"); - FileWriter authWriter = new FileWriter(tmpAuth); + private static void setupAgentAuth(File etc) throws IOException { + agentAuth = new File(etc, "agent.auth"); + FileWriter authWriter = new FileWriter(agentAuth); authWriter.append("username=user\npassword=pass\n"); authWriter.flush(); authWriter.close(); } - private static void setupUserAgentConfig(String root) throws IOException { + private static File setupUserAgentConfig(String root) throws IOException { System.setProperty("USER_THERMOSTAT_HOME", root); File agent = new File(root, "agent"); @@ -145,6 +178,7 @@ new File(agent, "run").mkdirs(); new File(agent, "logs").mkdirs(); + return agent; } }
--- a/config/pom.xml Fri Nov 15 17:28:05 2013 -0700 +++ b/config/pom.xml Mon Nov 18 08:22:15 2013 -0700 @@ -28,6 +28,7 @@ </Export-Package> <Private-Package> com.redhat.thermostat.shared.config.internal, + com.redhat.thermostat.shared.locale.internal, </Private-Package> <!-- Do not autogenerate uses clauses in Manifests --> <_nouses>true</_nouses>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/config/src/main/java/com/redhat/thermostat/shared/config/CommonPaths.java Mon Nov 18 08:22:15 2013 -0700 @@ -0,0 +1,109 @@ +/* + * 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 + * <http://www.gnu.org/licenses/>. + * + * 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 java.io.File; + +/** + * Contains locations to various files and directories used by thermostat + * components. + * <p> + * 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. + * <p> + * The directories are split according to functionality, along the lines of + * Filesystem Hierarchy Standard (FHS). + */ +public interface CommonPaths { + + public File getSystemThermostatHome() throws InvalidConfigurationException; + + public File getUserThermostatHome() throws InvalidConfigurationException; + + public File getSystemPluginRoot() throws InvalidConfigurationException; + + public File getSystemLibRoot() throws InvalidConfigurationException; + + public File getSystemBinRoot() throws InvalidConfigurationException; + + public File getSystemNativeLibsRoot() throws InvalidConfigurationException; + + public File getSystemConfigurationDirectory() throws InvalidConfigurationException; + + public File getUserConfigurationDirectory() throws InvalidConfigurationException; + + /** A location that contains data that is persisted */ + public File getUserPersistentDataDirectory() throws InvalidConfigurationException; + + /** Contains data that is only useful for the duration that thermostat is running */ + public File getUserRuntimeDataDirectory() throws InvalidConfigurationException; + + public File getUserLogDirectory() throws InvalidConfigurationException; + + public File getUserCacheDirectory() throws InvalidConfigurationException; + + public File getUserPluginRoot() throws InvalidConfigurationException; + + public File getUserStorageDirectory() throws InvalidConfigurationException; + + public File getSystemStorageConfigurationFile() throws InvalidConfigurationException; + + public File getUserStorageConfigurationFile() throws InvalidConfigurationException; + + public File getUserStorageLogFile() throws InvalidConfigurationException; + + public File getUserStoragePidFile() throws InvalidConfigurationException; + + public File getSystemAgentConfigurationFile() throws InvalidConfigurationException; + + public File getUserAgentConfigurationFile() throws InvalidConfigurationException; + + public File getSystemAgentAuthConfigFile() throws InvalidConfigurationException; + + public File getUserAgentAuthConfigFile() throws InvalidConfigurationException; + + public File getUserClientConfigurationFile() throws InvalidConfigurationException; + + public File getUserHistoryFile() throws InvalidConfigurationException; + +} \ No newline at end of file
--- a/config/src/main/java/com/redhat/thermostat/shared/config/Configuration.java Fri Nov 15 17:28:05 2013 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,374 +0,0 @@ -/* - * 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 - * <http://www.gnu.org/licenses/>. - * - * 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 java.io.File; - -/** - * Contains locations to various files and directories used by thermostat - * components. - * <p> - * 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. - * <p> - * The directories are split according to functionality, along the lines of - * Filesystem Hierarchy Standard (FHS). - * <p> - * The behaviour of this class is affected by the following environment - * variables: - * <dl> - * <di>{@code THERMOSTAT_HOME}</di> - * <dd>Specifies the location thermostat uses for it's read-only data, - * such as jars.</dd> - * <di>{@code THERMOSTAT_SYSTEM_USER}</di> - * <dd>If set, indicates that thermostat is running as a system user. - * In this mode, it reads configuration from system paths and places - * data in system writeable locations.</dd> - * <di>{@code USER_THERMOSTAT_HOME}</di> - * <dd>The meaning of this varies depending on whether thermostat is - * running as a system user or not. In normal mode, this controls - * where thermostat places it's data and where configuration files - * are searched for. In system mode, this is treated as a prefix - * writing system data.</dd> - * </dl> - */ -public class Configuration { - - // Note: these paths are used by the integration tests too. Please update - // them whenever you change this class. - - // environment variables (also system properties for convenience): - private static final String THERMOSTAT_HOME = "THERMOSTAT_HOME"; - private static final String USER_THERMOSTAT_HOME = "USER_THERMOSTAT_HOME"; - private static final String THERMOSTAT_SYSTEM_USER = "THERMOSTAT_SYSTEM_USER"; - - - private static final String THERMOSTAT_USER_DIR = ".thermostat"; - - private final File systemHome; - private final UserDirectories userDirectories; - - private static File defaultSystemUserPrefix; - - public Configuration() throws InvalidConfigurationException { - this(makeDir(null, "/")); - } - - Configuration(String altTestingPrefix) { - this(makeDir(null, altTestingPrefix)); - } - - private Configuration(File defaultPrefix) { - Configuration.defaultSystemUserPrefix = defaultPrefix; - // allow this to be specified also as a property, especially for - // tests, this overrides the env setting - String home = System.getProperty(THERMOSTAT_HOME); - if (home == null) { - home = System.getenv(THERMOSTAT_HOME); - } - - if (home == null) { - throw new InvalidConfigurationException(THERMOSTAT_HOME + " not defined..."); - } - this.systemHome = new File(home); - if (!systemHome.exists()) { - systemHome.mkdirs(); - } - if (!systemHome.isDirectory()) { - throw new InvalidConfigurationException(THERMOSTAT_HOME + " is not a directory: " + home); - } - - String systemUser = System.getProperty(THERMOSTAT_SYSTEM_USER); - if (systemUser == null) { - systemUser = System.getenv(THERMOSTAT_SYSTEM_USER); - } - - if (systemUser != null) { - userDirectories = new SystemUserDirectories(); - } else { - userDirectories = new UnprivilegedUserDirectories(); - } - } - - /* - * Overall hierarchy - */ - - public File getSystemThermostatHome() throws InvalidConfigurationException { - return systemHome; - } - - public File getUserThermostatHome() throws InvalidConfigurationException { - return userDirectories.getSystemRoot(); - } - - public File getSystemPluginRoot() throws InvalidConfigurationException { - return makeDir(systemHome, "plugins"); - } - - public File getSystemLibRoot() throws InvalidConfigurationException { - return makeDir(systemHome, "libs"); - } - - public File getSystemBinRoot() throws InvalidConfigurationException { - return makeDir(systemHome, "bin"); - } - - public File getSystemNativeLibsRoot() throws InvalidConfigurationException { - return makeDir(getSystemLibRoot(), "native"); - } - - public File getSystemConfigurationDirectory() throws InvalidConfigurationException { - return makeDir(getSystemThermostatHome(), "etc"); - } - - public File getUserConfigurationDirectory() throws InvalidConfigurationException { - return userDirectories.getUserConfigurationDirectory(); - } - - /** A location that contains data that is persisted */ - public File getUserPersistentDataDirectory() throws InvalidConfigurationException { - return userDirectories.getUserPersistentDataDirectory(); - } - - /** - * Contains data that is only useful for the duration that thermostat is - * running - */ - public File getUserRuntimeDataDirectory() throws InvalidConfigurationException { - return userDirectories.getUserRuntimeDataDirectory(); - } - - public File getUserLogDirectory() throws InvalidConfigurationException { - return userDirectories.getUserLogDirectory(); - - } - - public File getUserCacheDirectory() throws InvalidConfigurationException { - return userDirectories.getUserCacheDirectory(); - } - - /* Specific files and directories. All these methods should use the directories defined above */ - - public File getUserPluginRoot() throws InvalidConfigurationException { - return new File(getUserPersistentDataDirectory(), "plugins"); - } - - public File getUserStorageDirectory() throws InvalidConfigurationException { - return makeDir(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 getUserStoragePidFile() throws InvalidConfigurationException { - File logFile = new File(getUserRuntimeDataDirectory(), "db.pid"); - return logFile; - } - - public File getSystemAgentConfigurationFile() throws InvalidConfigurationException { - return new File(getSystemConfigurationDirectory(), "agent.properties"); - } - - public File getUserAgentConfigurationFile() throws InvalidConfigurationException { - return new File(getUserConfigurationDirectory(), "agent.properties"); - } - - public File getSystemAgentAuthConfigFile() throws InvalidConfigurationException { - return new File(getSystemConfigurationDirectory(), "agent.auth"); - } - - 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 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) - - private interface UserDirectories { - - public File getSystemRoot(); - - public File getUserConfigurationDirectory(); - - public File getUserPersistentDataDirectory(); - - public File getUserRuntimeDataDirectory(); - - public File getUserLogDirectory(); - - public File getUserCacheDirectory(); - - } - - private static File makeDir(File parent, String name) { - File dir = new File(parent, name); - boolean exists = dir.exists(); - if (!exists) { - exists = dir.mkdirs(); - } - if (!exists) { - throw new InvalidConfigurationException("Directory could not be created: " + dir.getAbsolutePath()); - } - if (!dir.isDirectory()) { - throw new InvalidConfigurationException("File already exists but is not a directory: " + dir.getAbsolutePath()); - } - return dir; - } - - /* - * We need two different implementations because the paths are different. We - * can't get clean paths by simply changing the prefix. - * - * user path: $USER/.thermostat/{etc,log,...} - * system path: /{etc,var/log,var/lib}/thermostat - * - * Notice how 'thermostat' comes first in one set of paths and later in the second set. - */ - - private static class UnprivilegedUserDirectories implements UserDirectories { - - private File userHome; - - public UnprivilegedUserDirectories() { - // 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 = makeDir(null, userHome); - } - - public File getSystemRoot() throws InvalidConfigurationException { - return userHome; - } - - - public File getUserConfigurationDirectory() throws InvalidConfigurationException { - return makeDir(getSystemRoot(), "etc"); - } - - public File getUserPersistentDataDirectory() throws InvalidConfigurationException { - return makeDir(getSystemRoot(), "data"); - } - - public File getUserRuntimeDataDirectory() throws InvalidConfigurationException { - return makeDir(getSystemRoot(), "run"); - } - - public File getUserLogDirectory() throws InvalidConfigurationException { - return makeDir(getSystemRoot(), "logs"); - } - - public File getUserCacheDirectory() throws InvalidConfigurationException { - return makeDir(getSystemRoot(), "cache"); - } - } - - private static class SystemUserDirectories implements UserDirectories { - - private File prefix; - - public SystemUserDirectories() { - // 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) { - this.prefix = defaultSystemUserPrefix; - } else { - this.prefix = makeDir(null, userHome); - } - } - - public File getSystemRoot() throws InvalidConfigurationException { - return prefix; - } - - - public File getUserConfigurationDirectory() throws InvalidConfigurationException { - return makeDir(getSystemRoot(), "etc/thermostat"); - } - - public File getUserPersistentDataDirectory() throws InvalidConfigurationException { - return makeDir(getSystemRoot(), "var/lib/thermostat"); - } - - public File getUserRuntimeDataDirectory() throws InvalidConfigurationException { - return makeDir(getSystemRoot(), "var/run/thermostat"); - } - - public File getUserLogDirectory() throws InvalidConfigurationException { - return makeDir(getSystemRoot(), "var/log/thermostat"); - } - - public File getUserCacheDirectory() throws InvalidConfigurationException { - return makeDir(getSystemRoot(), "var/cache/thermostat"); - } - } - -}
--- a/config/src/main/java/com/redhat/thermostat/shared/config/NativeLibraryResolver.java Fri Nov 15 17:28:05 2013 -0700 +++ b/config/src/main/java/com/redhat/thermostat/shared/config/NativeLibraryResolver.java Mon Nov 18 08:22:15 2013 -0700 @@ -38,17 +38,26 @@ import java.io.File; +import com.redhat.thermostat.shared.config.internal.CommonPathsImpl; + /** * Class which enables resolving of native libraries placed in - * {@link Configuration#getNativeLibsRoot()}. + * {@link CommonPaths#getNativeLibsRoot()}. * */ public class NativeLibraryResolver { + private static CommonPaths paths; + + // Set in Activator.start() to prevent IllegalStateException below. + public static void setCommonPaths(CommonPaths paths) { + NativeLibraryResolver.paths = paths; + } + /** * Gets the absolute path of a native library. The native library must be - * placed in directory as returned by {@link Configuration#getNativeLibsRoot()}. + * placed in directory as returned by {@link CommonPathsImpl#getNativeLibsRoot()}. * * @param libraryName * The name of the library. Specified in the same fashion as for @@ -63,9 +72,11 @@ if (nativeLibsRoot != null) { return doResolve(nativeLibsRoot, libraryName); } + if (paths == null) { + throw new IllegalStateException("NativeLibraryResolver does not yet know about CommonPaths."); + } try { - Configuration config = new Configuration(); - nativeLibsRoot = config.getSystemNativeLibsRoot().getPath(); + nativeLibsRoot = paths.getSystemNativeLibsRoot().getPath(); } catch (InvalidConfigurationException e) { throw new AssertionError(e); }
--- a/config/src/main/java/com/redhat/thermostat/shared/config/internal/Activator.java Fri Nov 15 17:28:05 2013 -0700 +++ b/config/src/main/java/com/redhat/thermostat/shared/config/internal/Activator.java Mon Nov 18 08:22:15 2013 -0700 @@ -39,19 +39,25 @@ import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; +import com.redhat.thermostat.shared.config.CommonPaths; import com.redhat.thermostat.shared.config.SSLConfiguration; +import com.redhat.thermostat.shared.config.NativeLibraryResolver; public class Activator implements BundleActivator { @Override public void start(BundleContext context) throws Exception { - SSLConfiguration sslConf = new SSLConfigurationImpl(); + CommonPaths paths = new CommonPathsImpl(); + // Prevents IllegalStateException when external dependencies attempt to resolve native libraries. + NativeLibraryResolver.setCommonPaths(paths); + context.registerService(CommonPaths.class.getName(), paths, null); + SSLConfiguration sslConf = new SSLConfigurationImpl(paths); context.registerService(SSLConfiguration.class.getName(), sslConf, null); } @Override public void stop(BundleContext context) throws Exception { - // Nothing to do + NativeLibraryResolver.setCommonPaths(null); } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/config/src/main/java/com/redhat/thermostat/shared/config/internal/CommonPathsImpl.java Mon Nov 18 08:22:15 2013 -0700 @@ -0,0 +1,405 @@ +/* + * 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 + * <http://www.gnu.org/licenses/>. + * + * 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.internal; + +import java.io.File; + +import com.redhat.thermostat.shared.config.CommonPaths; +import com.redhat.thermostat.shared.config.InvalidConfigurationException; +import com.redhat.thermostat.shared.locale.Translate; +import com.redhat.thermostat.shared.locale.internal.LocaleResources; + +/** + * Contains locations to various files and directories used by thermostat + * components. + * <p> + * 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. + * <p> + * The directories are split according to functionality, along the lines of + * Filesystem Hierarchy Standard (FHS). + * <p> + * The behaviour of this class is affected by the following environment + * variables: + * <dl> + * <di>{@code THERMOSTAT_HOME}</di> + * <dd>Specifies the location thermostat uses for it's read-only data, + * such as jars.</dd> + * <di>{@code THERMOSTAT_SYSTEM_USER}</di> + * <dd>If set, indicates that thermostat is running as a system user. + * In this mode, it reads configuration from system paths and places + * data in system writeable locations.</dd> + * <di>{@code USER_THERMOSTAT_HOME}</di> + * <dd>The meaning of this varies depending on whether thermostat is + * running as a system user or not. In normal mode, this controls + * where thermostat places it's data and where configuration files + * are searched for. In system mode, this is treated as a prefix + * writing system data.</dd> + * </dl> + */ +public class CommonPathsImpl implements CommonPaths { + + // Note: these paths are used by the integration tests too. Please update + // them whenever you change this class. + + // environment variables (also system properties for convenience): + private static final String THERMOSTAT_HOME = "THERMOSTAT_HOME"; + private static final String USER_THERMOSTAT_HOME = "USER_THERMOSTAT_HOME"; + private static final String THERMOSTAT_SYSTEM_USER = "THERMOSTAT_SYSTEM_USER"; + + + private static final String THERMOSTAT_USER_DIR = ".thermostat"; + + private static final Translate<LocaleResources> t = LocaleResources.createLocalizer(); + + private final File systemHome; + private final UserDirectories userDirectories; + + private static File defaultSystemUserPrefix; + + public CommonPathsImpl() throws InvalidConfigurationException { + this(makeDir(null, "/")); + } + + CommonPathsImpl(String altTestingPrefix) { + this(makeDir(null, altTestingPrefix)); + } + + private CommonPathsImpl(File defaultPrefix) { + CommonPathsImpl.defaultSystemUserPrefix = defaultPrefix; + // allow this to be specified also as a property, especially for + // tests, this overrides the env setting + String home = System.getProperty(THERMOSTAT_HOME); + if (home == null) { + home = System.getenv(THERMOSTAT_HOME); + } + + if (home == null) { + throw new InvalidConfigurationException(t.localize(LocaleResources.SYSHOME_NO_HOME)); + } + this.systemHome = new File(home); + if (!systemHome.exists()) { + systemHome.mkdirs(); + } + if (!systemHome.isDirectory()) { + throw new InvalidConfigurationException(t.localize(LocaleResources.SYSHOME_NOT_A_DIR, home)); + } + + String systemUser = System.getProperty(THERMOSTAT_SYSTEM_USER); + if (systemUser == null) { + systemUser = System.getenv(THERMOSTAT_SYSTEM_USER); + } + + if (systemUser != null) { + userDirectories = new SystemUserDirectories(); + } else { + userDirectories = new UnprivilegedUserDirectories(); + } + } + + /* + * Overall hierarchy + */ + + @Override + public File getSystemThermostatHome() throws InvalidConfigurationException { + return systemHome; + } + + @Override + public File getUserThermostatHome() throws InvalidConfigurationException { + return userDirectories.getSystemRoot(); + } + + @Override + public File getSystemPluginRoot() throws InvalidConfigurationException { + return makeDir(systemHome, "plugins"); + } + + @Override + public File getSystemLibRoot() throws InvalidConfigurationException { + return makeDir(systemHome, "libs"); + } + + @Override + public File getSystemBinRoot() throws InvalidConfigurationException { + return makeDir(systemHome, "bin"); + } + + @Override + public File getSystemNativeLibsRoot() throws InvalidConfigurationException { + return makeDir(getSystemLibRoot(), "native"); + } + + @Override + public File getSystemConfigurationDirectory() throws InvalidConfigurationException { + return makeDir(getSystemThermostatHome(), "etc"); + } + + @Override + public File getUserConfigurationDirectory() throws InvalidConfigurationException { + return userDirectories.getUserConfigurationDirectory(); + } + + /** A location that contains data that is persisted */ + @Override + public File getUserPersistentDataDirectory() throws InvalidConfigurationException { + return userDirectories.getUserPersistentDataDirectory(); + } + + /** + * Contains data that is only useful for the duration that thermostat is + * running + */ + @Override + public File getUserRuntimeDataDirectory() throws InvalidConfigurationException { + return userDirectories.getUserRuntimeDataDirectory(); + } + + @Override + public File getUserLogDirectory() throws InvalidConfigurationException { + return userDirectories.getUserLogDirectory(); + + } + + @Override + public File getUserCacheDirectory() throws InvalidConfigurationException { + return userDirectories.getUserCacheDirectory(); + } + + /* Specific files and directories. All these methods should use the directories defined above */ + + @Override + public File getUserPluginRoot() throws InvalidConfigurationException { + return new File(getUserPersistentDataDirectory(), "plugins"); + } + + @Override + public File getUserStorageDirectory() throws InvalidConfigurationException { + return makeDir(getUserPersistentDataDirectory(), "db"); + } + + @Override + public File getSystemStorageConfigurationFile() throws InvalidConfigurationException { + return new File(getSystemConfigurationDirectory(), "db.properties"); + } + + @Override + public File getUserStorageConfigurationFile() throws InvalidConfigurationException { + return new File(getUserConfigurationDirectory(), "db.properties"); + } + + @Override + public File getUserStorageLogFile() throws InvalidConfigurationException { + File logFile = new File(getUserLogDirectory(), "db.log"); + return logFile; + } + + @Override + public File getUserStoragePidFile() throws InvalidConfigurationException { + File logFile = new File(getUserRuntimeDataDirectory(), "db.pid"); + return logFile; + } + + @Override + public File getSystemAgentConfigurationFile() throws InvalidConfigurationException { + return new File(getSystemConfigurationDirectory(), "agent.properties"); + } + + @Override + public File getUserAgentConfigurationFile() throws InvalidConfigurationException { + return new File(getUserConfigurationDirectory(), "agent.properties"); + } + + @Override + public File getSystemAgentAuthConfigFile() throws InvalidConfigurationException { + return new File(getSystemConfigurationDirectory(), "agent.auth"); + } + + @Override + public File getUserAgentAuthConfigFile() throws InvalidConfigurationException { + return new File(getUserConfigurationDirectory(), "agent.auth"); + } + + @Override + public File getUserClientConfigurationFile() throws InvalidConfigurationException { + File client = new File(getUserConfigurationDirectory(), "client.properties"); + return client; + } + + @Override + 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) + + private interface UserDirectories { + + public File getSystemRoot(); + + public File getUserConfigurationDirectory(); + + public File getUserPersistentDataDirectory(); + + public File getUserRuntimeDataDirectory(); + + public File getUserLogDirectory(); + + public File getUserCacheDirectory(); + + } + + private static File makeDir(File parent, String name) { + File dir = new File(parent, name); + boolean exists = dir.exists(); + if (!exists) { + exists = dir.mkdirs(); + } + if (!exists) { + throw new InvalidConfigurationException("Directory could not be created: " + dir.getAbsolutePath()); + } + if (!dir.isDirectory()) { + throw new InvalidConfigurationException(t.localize(LocaleResources.GENERAL_NOT_A_DIR, dir.getAbsolutePath())); + } + return dir; + } + + /* + * We need two different implementations because the paths are different. We + * can't get clean paths by simply changing the prefix. + * + * user path: $USER/.thermostat/{etc,log,...} + * system path: /{etc,var/log,var/lib}/thermostat + * + * Notice how 'thermostat' comes first in one set of paths and later in the second set. + */ + + private static class UnprivilegedUserDirectories implements UserDirectories { + + private File userHome; + + public UnprivilegedUserDirectories() { + // 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 = makeDir(null, userHome); + } + + public File getSystemRoot() throws InvalidConfigurationException { + return userHome; + } + + + public File getUserConfigurationDirectory() throws InvalidConfigurationException { + return makeDir(getSystemRoot(), "etc"); + } + + public File getUserPersistentDataDirectory() throws InvalidConfigurationException { + return makeDir(getSystemRoot(), "data"); + } + + public File getUserRuntimeDataDirectory() throws InvalidConfigurationException { + return makeDir(getSystemRoot(), "run"); + } + + public File getUserLogDirectory() throws InvalidConfigurationException { + return makeDir(getSystemRoot(), "logs"); + } + + public File getUserCacheDirectory() throws InvalidConfigurationException { + return makeDir(getSystemRoot(), "cache"); + } + } + + private static class SystemUserDirectories implements UserDirectories { + + private File prefix; + + public SystemUserDirectories() { + // 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) { + this.prefix = defaultSystemUserPrefix; + } else { + this.prefix = makeDir(null, userHome); + } + } + + public File getSystemRoot() throws InvalidConfigurationException { + return prefix; + } + + + public File getUserConfigurationDirectory() throws InvalidConfigurationException { + return makeDir(getSystemRoot(), "etc/thermostat"); + } + + public File getUserPersistentDataDirectory() throws InvalidConfigurationException { + return makeDir(getSystemRoot(), "var/lib/thermostat"); + } + + public File getUserRuntimeDataDirectory() throws InvalidConfigurationException { + return makeDir(getSystemRoot(), "var/run/thermostat"); + } + + public File getUserLogDirectory() throws InvalidConfigurationException { + return makeDir(getSystemRoot(), "var/log/thermostat"); + } + + public File getUserCacheDirectory() throws InvalidConfigurationException { + return makeDir(getSystemRoot(), "var/cache/thermostat"); + } + } + +}
--- a/config/src/main/java/com/redhat/thermostat/shared/config/internal/SSLConfigurationImpl.java Fri Nov 15 17:28:05 2013 -0700 +++ b/config/src/main/java/com/redhat/thermostat/shared/config/internal/SSLConfigurationImpl.java Mon Nov 18 08:22:15 2013 -0700 @@ -43,12 +43,13 @@ import java.util.logging.Level; import java.util.logging.Logger; -import com.redhat.thermostat.shared.config.Configuration; +import com.redhat.thermostat.shared.config.CommonPaths; import com.redhat.thermostat.shared.config.InvalidConfigurationException; import com.redhat.thermostat.shared.config.SSLConfiguration; public class SSLConfigurationImpl implements SSLConfiguration { + private CommonPaths paths; private Properties clientProps = null; private static final String KEYSTORE_FILE_KEY = "KEYSTORE_FILE"; private static final String KEYSTORE_FILE_PWD_KEY = "KEYSTORE_PASSWORD"; @@ -57,6 +58,10 @@ private static final String DISABLE_HOSTNAME_VERIFICATION = "DISABLE_HOSTNAME_VERIFICATION"; private static final Logger logger = Logger.getLogger(SSLConfigurationImpl.class.getName()); + public SSLConfigurationImpl(CommonPaths paths) { + this.paths = paths; + } + @Override public File getKeystoreFile() { try { @@ -132,7 +137,7 @@ private void loadClientProperties() throws InvalidConfigurationException { if (clientProps == null) { - File clientPropertiesFile = new File(new Configuration().getUserConfigurationDirectory(), + File clientPropertiesFile = new File(paths.getUserConfigurationDirectory(), "ssl.properties"); initClientProperties(clientPropertiesFile); }
--- a/config/src/main/java/com/redhat/thermostat/shared/locale/LocaleResources.java Fri Nov 15 17:28:05 2013 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,53 +0,0 @@ -/* - * 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 - * <http://www.gnu.org/licenses/>. - * - * 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.locale; - -import com.redhat.thermostat.shared.locale.Translate; - -public enum LocaleResources { - - ENV_NO_HOME, - ; - - public static final String RESOURCE_BUNDLE = - "com.redhat.thermostat.shared.locale.strings"; - - public static Translate<LocaleResources> createLocalizer() { - return new Translate<>(RESOURCE_BUNDLE, LocaleResources.class); - } -} -
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/config/src/main/java/com/redhat/thermostat/shared/locale/internal/LocaleResources.java Mon Nov 18 08:22:15 2013 -0700 @@ -0,0 +1,56 @@ +/* + * 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 + * <http://www.gnu.org/licenses/>. + * + * 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.locale.internal; + +import com.redhat.thermostat.shared.locale.Translate; + +public enum LocaleResources { + + SYSHOME_NO_HOME, + SYSHOME_NOT_A_DIR, + USERHOME_NOT_A_DIR, + GENERAL_NOT_A_DIR, + ; + + public static final String RESOURCE_BUNDLE = + "com.redhat.thermostat.shared.locale.internal.strings"; + + public static Translate<LocaleResources> createLocalizer() { + return new Translate<>(RESOURCE_BUNDLE, LocaleResources.class); + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/config/src/main/resources/com/redhat/thermostat/shared/locale/internal/strings.properties Mon Nov 18 08:22:15 2013 -0700 @@ -0,0 +1,4 @@ +SYSHOME_NO_HOME = THERMOSTAT_HOME not defined... +SYSHOME_NOT_A_DIR = THERMOSTAT_HOME is defined but not a directory: {0} +USERHOME_NOT_A_DIR = USER_THERMOSTAT_HOME is defined but not a directory: {0} +GENERAL_NOT_A_DIR = Expecting directory, got other: {0}
--- a/config/src/main/resources/com/redhat/thermostat/shared/locale/strings.properties Fri Nov 15 17:28:05 2013 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -ENV_NO_HOME = THERMOSTAT_HOME not defined...
--- a/config/src/test/java/com/redhat/thermostat/shared/config/ConfigurationTest.java Fri Nov 15 17:28:05 2013 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,162 +0,0 @@ -/* - * 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 - * <http://www.gnu.org/licenses/>. - * - * 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.fail; - -import java.io.File; -import java.io.IOException; - -import junit.framework.Assert; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -public class ConfigurationTest { - - @Before - public void setUp() { - System.clearProperty("THERMOSTAT_HOME"); - System.clearProperty("USER_THERMOSTAT_HOME"); - System.clearProperty("THERMOSTAT_SYSTEM_USER"); - } - - @After - public void tearDown() { - System.clearProperty("THERMOSTAT_HOME"); - System.clearProperty("USER_THERMOSTAT_HOME"); - System.clearProperty("THERMOSTAT_SYSTEM_USER"); - } - - @Test - 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.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()); - } - - @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()); - - Assert.assertEquals(userHome + s + "data" + s + "plugins", - config.getUserPluginRoot().getCanonicalPath()); - } - - @Test - public void testPrivilegedUserLocations() throws InvalidConfigurationException, IOException { - String thermostatHome = "/tmp/thermostat_test"; - System.setProperty("THERMOSTAT_HOME", thermostatHome); - System.setProperty("THERMOSTAT_SYSTEM_USER", ""); - Configuration config = new Configuration(thermostatHome); - - // the paths are unix specific, but so are the paths in Configuration - - Assert.assertEquals("/tmp/thermostat_test/etc/thermostat/agent.properties", config.getUserAgentConfigurationFile().getCanonicalPath()); - Assert.assertEquals("/tmp/thermostat_test/etc/thermostat/agent.auth", config.getUserAgentAuthConfigFile().getCanonicalPath()); - Assert.assertEquals("/tmp/thermostat_test/etc/thermostat/db.properties", config.getUserStorageConfigurationFile().getCanonicalPath()); - - Assert.assertEquals("/tmp/thermostat_test/var/lib/thermostat/db", config.getUserStorageDirectory().getCanonicalPath()); - Assert.assertEquals("/tmp/thermostat_test/var/run/thermostat/db.pid", config.getUserStoragePidFile().getAbsolutePath()); - Assert.assertEquals("/tmp/thermostat_test/var/log/thermostat/db.log", config.getUserStorageLogFile().getCanonicalPath()); - - Assert.assertEquals("/tmp/thermostat_test/var/lib/thermostat/plugins", config.getUserPluginRoot().getCanonicalPath()); - } - - @Test - public void testPrivilegedUserLocationsWithPrefix() throws InvalidConfigurationException, IOException { - String thermostatHome = "/tmp"; - String prefix = "/tmp/opt/custom/prefix"; - System.setProperty("THERMOSTAT_HOME", thermostatHome); - System.setProperty("USER_THERMOSTAT_HOME", prefix); - System.setProperty("THERMOSTAT_SYSTEM_USER", ""); - Configuration config = new Configuration(); - - // the paths are unix specific, but so are the paths in Configuration - - Assert.assertEquals(prefix + "/etc/thermostat/agent.properties", config.getUserAgentConfigurationFile().getCanonicalPath()); - Assert.assertEquals(prefix + "/etc/thermostat/agent.auth", config.getUserAgentAuthConfigFile().getCanonicalPath()); - Assert.assertEquals(prefix + "/etc/thermostat/db.properties", config.getUserStorageConfigurationFile().getCanonicalPath()); - - Assert.assertEquals(prefix + "/var/lib/thermostat/db", config.getUserStorageDirectory().getCanonicalPath()); - Assert.assertEquals(prefix + "/var/run/thermostat/db.pid", config.getUserStoragePidFile().getAbsolutePath()); - Assert.assertEquals(prefix + "/var/log/thermostat/db.log", config.getUserStorageLogFile().getCanonicalPath()); - - Assert.assertEquals(prefix + "/var/lib/thermostat/plugins", config.getUserPluginRoot().getCanonicalPath()); - } - - @Test - public void instantiationThrowsException() { - try { - new Configuration(); - // The web archive uses this. See WebStorageEndPoint#init(); - fail("Should have thrown InvalidConfigurationException"); - } catch (InvalidConfigurationException e) { - // pass - } - } -}
--- a/config/src/test/java/com/redhat/thermostat/shared/config/NativeLibrayResolverTest.java Fri Nov 15 17:28:05 2013 -0700 +++ b/config/src/test/java/com/redhat/thermostat/shared/config/NativeLibrayResolverTest.java Mon Nov 18 08:22:15 2013 -0700 @@ -42,6 +42,8 @@ import org.junit.Before; import org.junit.Test; +import com.redhat.thermostat.shared.config.internal.CommonPathsImpl; + public class NativeLibrayResolverTest { private static final String THERMOSTAT_HOME = "THERMOSTAT_HOME"; @@ -51,6 +53,7 @@ @Before public void setUp() { saved = System.setProperty(THERMOSTAT_HOME, "../foo/"); + NativeLibraryResolver.setCommonPaths(new CommonPathsImpl()); } @After
--- a/config/src/test/java/com/redhat/thermostat/shared/config/internal/ActivatorTest.java Fri Nov 15 17:28:05 2013 -0700 +++ b/config/src/test/java/com/redhat/thermostat/shared/config/internal/ActivatorTest.java Mon Nov 18 08:22:15 2013 -0700 @@ -39,22 +39,61 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; + +import org.junit.After; +import org.junit.Before; import org.junit.Test; +import com.redhat.thermostat.shared.config.CommonPaths; import com.redhat.thermostat.shared.config.SSLConfiguration; import com.redhat.thermostat.testutils.StubBundleContext; +import com.redhat.thermostat.testutils.TestUtils; public class ActivatorTest { + private String originalThermostatHomeProperty; + private File testHome; + + @Before + public void setUp() { + Path testHomePath = null; + try { + testHomePath = Files.createTempDirectory("ActivatorTest_THERMOSTAT_HOME"); + } catch (IOException e) { + e.printStackTrace(); + } + File testHome = testHomePath.toFile(); + originalThermostatHomeProperty = System.getProperty("THERMOSTAT_HOME"); + System.setProperty("THERMOSTAT_HOME", testHome.getAbsolutePath()); + } + + @After + public void tearDown() throws IOException { + if (testHome != null) { + TestUtils.deleteRecursively(testHome); + } + if (originalThermostatHomeProperty != null) { + System.setProperty("THERMOSTAT_HOME", originalThermostatHomeProperty); + } else { + System.clearProperty("THERMOSTAT_HOME"); + } + } + @Test - public void verifyServiceRegistered() throws Exception { + public void verifyServicesRegistered() throws Exception { StubBundleContext ctx = new StubBundleContext(); Activator activator = new Activator(); activator.start(ctx); assertTrue(ctx.isServiceRegistered(SSLConfiguration.class.getName(), SSLConfigurationImpl.class)); - assertEquals(1, ctx.getAllServices().size()); + assertTrue(ctx.isServiceRegistered(CommonPaths.class.getName(), + CommonPathsImpl.class)); + assertEquals(2, ctx.getAllServices().size()); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/config/src/test/java/com/redhat/thermostat/shared/config/internal/CommonPathsImplTest.java Mon Nov 18 08:22:15 2013 -0700 @@ -0,0 +1,165 @@ +/* + * 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 + * <http://www.gnu.org/licenses/>. + * + * 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.internal; + +import static org.junit.Assert.fail; + +import java.io.File; +import java.io.IOException; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.redhat.thermostat.shared.config.CommonPaths; +import com.redhat.thermostat.shared.config.InvalidConfigurationException; + +public class CommonPathsImplTest { + + @Before + public void setUp() { + System.clearProperty("THERMOSTAT_HOME"); + System.clearProperty("USER_THERMOSTAT_HOME"); + System.clearProperty("THERMOSTAT_SYSTEM_USER"); + } + + @After + public void tearDown() { + System.clearProperty("THERMOSTAT_HOME"); + System.clearProperty("USER_THERMOSTAT_HOME"); + System.clearProperty("THERMOSTAT_SYSTEM_USER"); + } + + @Test + public void testSystemLocations() throws InvalidConfigurationException, IOException { + String thermostatHome = "/tmp"; + System.setProperty("THERMOSTAT_HOME", thermostatHome); + + char s = File.separatorChar; + + CommonPaths config = new CommonPathsImpl(); + + 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()); + } + + @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"; + CommonPaths config = new CommonPathsImpl(); + + 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()); + + Assert.assertEquals(userHome + s + "data" + s + "plugins", + config.getUserPluginRoot().getCanonicalPath()); + } + + @Test + public void testPrivilegedUserLocations() throws InvalidConfigurationException, IOException { + String thermostatHome = "/tmp/thermostat_test"; + System.setProperty("THERMOSTAT_HOME", thermostatHome); + System.setProperty("THERMOSTAT_SYSTEM_USER", ""); + CommonPaths config = new CommonPathsImpl(thermostatHome); + + // the paths are unix specific, but so are the paths in Configuration + + Assert.assertEquals("/tmp/thermostat_test/etc/thermostat/agent.properties", config.getUserAgentConfigurationFile().getCanonicalPath()); + Assert.assertEquals("/tmp/thermostat_test/etc/thermostat/agent.auth", config.getUserAgentAuthConfigFile().getCanonicalPath()); + Assert.assertEquals("/tmp/thermostat_test/etc/thermostat/db.properties", config.getUserStorageConfigurationFile().getCanonicalPath()); + + Assert.assertEquals("/tmp/thermostat_test/var/lib/thermostat/db", config.getUserStorageDirectory().getCanonicalPath()); + Assert.assertEquals("/tmp/thermostat_test/var/run/thermostat/db.pid", config.getUserStoragePidFile().getAbsolutePath()); + Assert.assertEquals("/tmp/thermostat_test/var/log/thermostat/db.log", config.getUserStorageLogFile().getCanonicalPath()); + + Assert.assertEquals("/tmp/thermostat_test/var/lib/thermostat/plugins", config.getUserPluginRoot().getCanonicalPath()); + } + + @Test + public void testPrivilegedUserLocationsWithPrefix() throws InvalidConfigurationException, IOException { + String thermostatHome = "/tmp"; + String prefix = "/tmp/opt/custom/prefix"; + System.setProperty("THERMOSTAT_HOME", thermostatHome); + System.setProperty("USER_THERMOSTAT_HOME", prefix); + System.setProperty("THERMOSTAT_SYSTEM_USER", ""); + CommonPaths config = new CommonPathsImpl(); + + // the paths are unix specific, but so are the paths in Configuration + + Assert.assertEquals(prefix + "/etc/thermostat/agent.properties", config.getUserAgentConfigurationFile().getCanonicalPath()); + Assert.assertEquals(prefix + "/etc/thermostat/agent.auth", config.getUserAgentAuthConfigFile().getCanonicalPath()); + Assert.assertEquals(prefix + "/etc/thermostat/db.properties", config.getUserStorageConfigurationFile().getCanonicalPath()); + + Assert.assertEquals(prefix + "/var/lib/thermostat/db", config.getUserStorageDirectory().getCanonicalPath()); + Assert.assertEquals(prefix + "/var/run/thermostat/db.pid", config.getUserStoragePidFile().getAbsolutePath()); + Assert.assertEquals(prefix + "/var/log/thermostat/db.log", config.getUserStorageLogFile().getCanonicalPath()); + + Assert.assertEquals(prefix + "/var/lib/thermostat/plugins", config.getUserPluginRoot().getCanonicalPath()); + } + + @Test + public void instantiationThrowsException() { + try { + new CommonPathsImpl(); + // The web archive uses this. See WebStorageEndPoint#init(); + fail("Should have thrown InvalidConfigurationException"); + } catch (InvalidConfigurationException e) { + // pass + } + } +}
--- a/config/src/test/java/com/redhat/thermostat/shared/config/internal/SSLConfigurationImplTest.java Fri Nov 15 17:28:05 2013 -0700 +++ b/config/src/test/java/com/redhat/thermostat/shared/config/internal/SSLConfigurationImplTest.java Mon Nov 18 08:22:15 2013 -0700 @@ -53,7 +53,7 @@ @Before public void setUp() { - sslConf = new SSLConfigurationImpl(); + sslConf = new SSLConfigurationImpl(null); File clientProps = new File(this.getClass().getResource("/client.properties").getFile()); sslConf.initClientProperties(clientProps); } @@ -68,7 +68,7 @@ @Test public void notExistingPropertiesFileReturnsNull() throws Exception { - SSLConfigurationImpl badSSLConf = new SSLConfigurationImpl(); + SSLConfigurationImpl badSSLConf = new SSLConfigurationImpl(null); File clientProps = new File("i/am/not/there/file.txt"); badSSLConf.initClientProperties(clientProps); assertTrue(badSSLConf.getKeystoreFile() == null); @@ -81,7 +81,7 @@ assertTrue(sslConf.enableForBackingStorage()); assertTrue(sslConf.disableHostnameVerification()); File disabledSSLProps = new File(this.getClass().getResource("/ssl.properties").getFile()); - SSLConfigurationImpl disabledSSLConf = new SSLConfigurationImpl(); + SSLConfigurationImpl disabledSSLConf = new SSLConfigurationImpl(null); disabledSSLConf.initClientProperties(disabledSSLProps); assertFalse(disabledSSLConf.enableForCmdChannel()); assertFalse(disabledSSLConf.enableForBackingStorage());
--- a/config/src/test/java/com/redhat/thermostat/shared/locale/LocaleResourcesTest.java Fri Nov 15 17:28:05 2013 -0700 +++ b/config/src/test/java/com/redhat/thermostat/shared/locale/LocaleResourcesTest.java Mon Nov 18 08:22:15 2013 -0700 @@ -46,6 +46,8 @@ import org.junit.Test; +import com.redhat.thermostat.shared.locale.internal.LocaleResources; + public class LocaleResourcesTest { @Test public void testLocalizedStringsArePresent() throws IOException {
--- a/eclipse/com.redhat.thermostat.client.feature/build.properties Fri Nov 15 17:28:05 2013 -0700 +++ b/eclipse/com.redhat.thermostat.client.feature/build.properties Mon Nov 18 08:22:15 2013 -0700 @@ -1,4 +1,5 @@ bin.includes = feature.xml -forceContextQualifier = SNAPSHOT + root.linux.gtk.x86=linux_x86 root.linux.gtk.x86_64=linux_x86_64 +forceContextQualifier = SNAPSHOT
--- a/eclipse/com.redhat.thermostat.eclipse/META-INF/MANIFEST.MF Fri Nov 15 17:28:05 2013 -0700 +++ b/eclipse/com.redhat.thermostat.eclipse/META-INF/MANIFEST.MF Mon Nov 18 08:22:15 2013 -0700 @@ -16,6 +16,7 @@ com.redhat.thermostat.client.locale, com.redhat.thermostat.client.ui, com.redhat.thermostat.common, + com.redhat.thermostat.shared.config, com.redhat.thermostat.shared.locale, com.redhat.thermostat.common.utils, com.redhat.thermostat.host.overview.client.core,
--- a/eclipse/com.redhat.thermostat.eclipse/src/com/redhat/thermostat/eclipse/internal/Activator.java Fri Nov 15 17:28:05 2013 -0700 +++ b/eclipse/com.redhat.thermostat.eclipse/src/com/redhat/thermostat/eclipse/internal/Activator.java Mon Nov 18 08:22:15 2013 -0700 @@ -49,6 +49,7 @@ import com.redhat.thermostat.eclipse.LoggerFacility; import com.redhat.thermostat.eclipse.internal.views.SWTHostOverviewViewProvider; import com.redhat.thermostat.host.overview.client.core.HostOverviewViewProvider; +import com.redhat.thermostat.shared.config.CommonPaths; import com.redhat.thermostat.storage.core.ConnectionException; import com.redhat.thermostat.storage.core.DbService; import com.redhat.thermostat.utils.keyring.Keyring; @@ -68,6 +69,10 @@ @SuppressWarnings({ "rawtypes" }) private ServiceTracker keyringTracker; + private CommonPaths paths; + @SuppressWarnings({ "rawtypes" }) + private ServiceTracker pathsTracker; + /** * The constructor */ @@ -89,7 +94,7 @@ // Register ViewProvider context.registerService(HostOverviewViewProvider.class, new SWTHostOverviewViewProvider(), null); - + keyringTracker = new ServiceTracker(context, Keyring.class, null) { @Override public Object addingService(ServiceReference reference) { @@ -105,8 +110,24 @@ } }; - // Track for Keyring service. + pathsTracker = new ServiceTracker(context, CommonPaths.class, null) { + @Override + public Object addingService(ServiceReference reference) { + CommonPaths paths = (CommonPaths) context.getService(reference); + Activator.this.paths = paths; + return keyring; + } + + @Override + public void removedService(ServiceReference reference, Object service) { + Activator.this.paths = null; + context.ungetService(reference); + } + + }; + // Track Keyring and CommonPaths services. keyringTracker.open(); + pathsTracker.open(); } /* @@ -197,5 +218,8 @@ return keyring; } + public CommonPaths getCommonPaths() { + return paths; + } }
--- a/eclipse/com.redhat.thermostat.eclipse/src/com/redhat/thermostat/eclipse/internal/preferences/MainPreferencePage.java Fri Nov 15 17:28:05 2013 -0700 +++ b/eclipse/com.redhat.thermostat.eclipse/src/com/redhat/thermostat/eclipse/internal/preferences/MainPreferencePage.java Mon Nov 18 08:22:15 2013 -0700 @@ -174,7 +174,7 @@ addField(passwordEditor); addField(saveEntitlementsEditor); updateMargins(generalGroup); - this.clientPrefs = new ClientPreferences(Activator.getDefault().getKeyring()); + this.clientPrefs = new ClientPreferences(Activator.getDefault().getKeyring(), Activator.getDefault().getCommonPaths()); synchronizeValues(); }
--- a/eclipse/com.redhat.thermostat.eclipse/src/com/redhat/thermostat/eclipse/internal/views/HostsVmsTreeViewPart.java Fri Nov 15 17:28:05 2013 -0700 +++ b/eclipse/com.redhat.thermostat.eclipse/src/com/redhat/thermostat/eclipse/internal/views/HostsVmsTreeViewPart.java Mon Nov 18 08:22:15 2013 -0700 @@ -97,7 +97,8 @@ private Timer timer; public HostsVmsTreeViewPart() { - ClientPreferences clientPrefs = new ClientPreferences(Activator.getDefault().getKeyring()); + ClientPreferences clientPrefs = new ClientPreferences(Activator.getDefault().getKeyring(), + Activator.getDefault().getCommonPaths()); ConnectionConfiguration configuration = new ConnectionConfiguration( clientPrefs.getUserName(), clientPrefs.getPassword(), clientPrefs.getConnectionUrl());
--- a/integration-tests/itest-run/src/test/java/com/redhat/thermostat/itest/MongoQueriesTest.java Fri Nov 15 17:28:05 2013 -0700 +++ b/integration-tests/itest-run/src/test/java/com/redhat/thermostat/itest/MongoQueriesTest.java Mon Nov 18 08:22:15 2013 -0700 @@ -42,6 +42,7 @@ import static org.junit.Assert.assertTrue; import java.io.ByteArrayInputStream; +import java.io.File; import java.io.InputStream; import java.util.Arrays; import java.util.HashSet; @@ -55,6 +56,8 @@ import com.redhat.thermostat.host.cpu.common.CpuStatDAO; import com.redhat.thermostat.host.cpu.common.model.CpuStat; +import com.redhat.thermostat.shared.config.CommonPaths; +import com.redhat.thermostat.shared.config.InvalidConfigurationException; import com.redhat.thermostat.shared.config.SSLConfiguration; import com.redhat.thermostat.shared.config.internal.SSLConfigurationImpl; import com.redhat.thermostat.storage.config.StartupConfiguration; @@ -144,7 +147,129 @@ } }; - SSLConfiguration sslConf = new SSLConfigurationImpl(); + SSLConfiguration sslConf = new SSLConfigurationImpl(new CommonPaths() { + + @Override + public File getSystemThermostatHome() throws InvalidConfigurationException { + return null; + } + + @Override + public File getUserThermostatHome() throws InvalidConfigurationException { + return null; + } + + @Override + public File getSystemPluginRoot() throws InvalidConfigurationException { + return null; + } + + @Override + public File getSystemLibRoot() throws InvalidConfigurationException { + return null; + } + + @Override + public File getSystemNativeLibsRoot() throws InvalidConfigurationException { + return null; + } + + @Override + public File getSystemBinRoot() throws InvalidConfigurationException { + return null; + } + + @Override + public File getSystemConfigurationDirectory() throws InvalidConfigurationException { + return null; + } + + @Override + public File getUserConfigurationDirectory() throws InvalidConfigurationException { + return new File("/tmp"); + } + + @Override + public File getUserPersistentDataDirectory() throws InvalidConfigurationException { + return null; + } + + @Override + public File getUserRuntimeDataDirectory() throws InvalidConfigurationException { + return null; + } + + @Override + public File getUserLogDirectory() throws InvalidConfigurationException { + return null; + } + + @Override + public File getUserCacheDirectory() throws InvalidConfigurationException { + return null; + } + + @Override + public File getUserPluginRoot() throws InvalidConfigurationException { + return null; + } + + @Override + public File getUserStorageDirectory() throws InvalidConfigurationException { + return null; + } + + @Override + public File getSystemStorageConfigurationFile() throws InvalidConfigurationException { + return null; + } + + @Override + public File getUserStorageConfigurationFile() throws InvalidConfigurationException { + return null; + } + + @Override + public File getUserStorageLogFile() throws InvalidConfigurationException { + return null; + } + + @Override + public File getUserStoragePidFile() throws InvalidConfigurationException { + return null; + } + + @Override + public File getSystemAgentConfigurationFile() throws InvalidConfigurationException { + return null; + } + + @Override + public File getUserAgentConfigurationFile() throws InvalidConfigurationException { + return null; + } + + @Override + public File getSystemAgentAuthConfigFile() throws InvalidConfigurationException { + return null; + } + + @Override + public File getUserAgentAuthConfigFile() throws InvalidConfigurationException { + return null; + } + + @Override + public File getUserClientConfigurationFile() throws InvalidConfigurationException { + return null; + } + + @Override + public File getUserHistoryFile() throws InvalidConfigurationException { + return null; + } + + }); BackingStorage storage = new MongoStorage(config, sslConf); if (listener != null) { storage.getConnection().addListener(listener);
--- a/integration-tests/itest-run/src/test/java/com/redhat/thermostat/itest/WebAppTest.java Fri Nov 15 17:28:05 2013 -0700 +++ b/integration-tests/itest-run/src/test/java/com/redhat/thermostat/itest/WebAppTest.java Mon Nov 18 08:22:15 2013 -0700 @@ -76,6 +76,7 @@ import com.redhat.thermostat.host.cpu.common.CpuStatDAO; import com.redhat.thermostat.host.cpu.common.model.CpuStat; import com.redhat.thermostat.shared.config.SSLConfiguration; +import com.redhat.thermostat.shared.config.internal.CommonPathsImpl; import com.redhat.thermostat.shared.config.internal.SSLConfigurationImpl; import com.redhat.thermostat.storage.config.ConnectionConfiguration; import com.redhat.thermostat.storage.config.StartupConfiguration; @@ -357,7 +358,7 @@ setupJAASForUser(roleNames, username, password); String url = "http://localhost:" + port + "/thermostat/storage"; StartupConfiguration config = new ConnectionConfiguration(url, username, password); - SSLConfiguration sslConf = new SSLConfigurationImpl(); + SSLConfiguration sslConf = new SSLConfigurationImpl(new CommonPathsImpl()); Storage storage = new WebStorage(config, sslConf); if (listener != null) { storage.getConnection().addListener(listener);
--- a/launcher/src/main/java/com/redhat/thermostat/launcher/BundleManager.java Fri Nov 15 17:28:05 2013 -0700 +++ b/launcher/src/main/java/com/redhat/thermostat/launcher/BundleManager.java Mon Nov 18 08:22:15 2013 -0700 @@ -44,7 +44,7 @@ import com.redhat.thermostat.annotations.Service; import com.redhat.thermostat.launcher.internal.BundleLoader; -import com.redhat.thermostat.shared.config.Configuration; +import com.redhat.thermostat.shared.config.CommonPaths; /** * A Service that provides features to load bundles for given command names. @@ -67,7 +67,7 @@ loader.installAndStartBundles(framework, bundleLocations); } - public abstract Configuration getConfiguration(); + public abstract CommonPaths getCommonPaths(); }
--- a/launcher/src/main/java/com/redhat/thermostat/launcher/internal/Activator.java Fri Nov 15 17:28:05 2013 -0700 +++ b/launcher/src/main/java/com/redhat/thermostat/launcher/internal/Activator.java Mon Nov 18 08:22:15 2013 -0700 @@ -37,90 +37,93 @@ package com.redhat.thermostat.launcher.internal; import java.io.File; +import java.io.IOException; +import java.util.Map; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; import org.osgi.framework.ServiceRegistration; import org.osgi.util.tracker.ServiceTracker; -import org.osgi.util.tracker.ServiceTrackerCustomizer; import com.redhat.thermostat.common.ExitStatus; +import com.redhat.thermostat.common.MultipleServiceTracker; +import com.redhat.thermostat.common.MultipleServiceTracker.Action; import com.redhat.thermostat.common.cli.CommandContextFactory; import com.redhat.thermostat.common.cli.CommandRegistry; import com.redhat.thermostat.common.cli.CommandRegistryImpl; +import com.redhat.thermostat.common.config.ClientPreferences; import com.redhat.thermostat.launcher.BundleManager; import com.redhat.thermostat.launcher.Launcher; import com.redhat.thermostat.launcher.internal.CurrentEnvironment.CurrentEnvironmentChangeListener; -import com.redhat.thermostat.shared.config.Configuration; +import com.redhat.thermostat.shared.config.CommonPaths; import com.redhat.thermostat.utils.keyring.Keyring; public class Activator implements BundleActivator { - @SuppressWarnings({"rawtypes", "unchecked"}) - class RegisterLauncherCustomizer implements ServiceTrackerCustomizer { + @SuppressWarnings({ "rawtypes" }) + class RegisterLauncherAction implements Action { private ServiceRegistration launcherReg; private ServiceRegistration bundleManReg; private ServiceRegistration cmdInfoReg; private ServiceRegistration exitStatusReg; private BundleContext context; - private BundleManager bundleService; - private CurrentEnvironment currentEnvironment; + private CurrentEnvironment env; - RegisterLauncherCustomizer(BundleContext context, BundleManager bundleService, CurrentEnvironment env) { + RegisterLauncherAction(BundleContext context, CurrentEnvironment env) { this.context = context; - this.bundleService = bundleService; - this.currentEnvironment = env; + this.env = env; } @Override - public Object addingService(ServiceReference reference) { - // keyring is now ready - Keyring keyring = (Keyring)context.getService(reference); - Configuration config = bundleService.getConfiguration(); + public void dependenciesAvailable(Map<String, Object> services) { + CommonPaths paths = (CommonPaths) services.get(CommonPaths.class.getName()); + Keyring keyring = (Keyring) services.get(Keyring.class.getName()); + ClientPreferences prefs = new ClientPreferences(keyring, paths); - String commandsDir = new File(config.getSystemConfigurationDirectory(), "commands").toString(); + String commandsDir = new File(paths.getSystemConfigurationDirectory(), "commands").toString(); CommandInfoSource builtInCommandSource = - new BuiltInCommandInfoSource(commandsDir, config.getSystemLibRoot().toString()); + new BuiltInCommandInfoSource(commandsDir, paths.getSystemLibRoot().toString()); CommandInfoSource pluginCommandSource = new PluginCommandInfoSource( - config.getSystemLibRoot().toString(), config.getSystemPluginRoot().toString(), - config.getUserPluginRoot().toString()); + paths.getSystemLibRoot().toString(), paths.getSystemPluginRoot().toString(), + paths.getUserPluginRoot().toString()); CommandInfoSource commands = new CompoundCommandInfoSource(builtInCommandSource, pluginCommandSource); cmdInfoReg = context.registerService(CommandInfoSource.class, commands, null); + BundleManager bundleService = null; + try { + bundleService = new BundleManagerImpl(paths); + } catch (IOException e) { + throw new RuntimeException("Could not initialize launcher.", e); + } + // Register Launcher service since FrameworkProvider is waiting for it blockingly. - LauncherImpl launcher = new LauncherImpl(context, - new CommandContextFactory(context), bundleService, commands, currentEnvironment); + LauncherImpl launcher = new LauncherImpl(context, new CommandContextFactory(context), + bundleService, commands, env, prefs, paths); launcherReg = context.registerService(Launcher.class.getName(), launcher, null); bundleManReg = context.registerService(BundleManager.class, bundleService, null); ExitStatus exitStatus = new ExitStatusImpl(ExitStatus.EXIT_SUCCESS); exitStatusReg = context.registerService(ExitStatus.class, exitStatus, null); - return keyring; } @Override - public void modifiedService(ServiceReference reference, Object service) { - // nothing - } - - @Override - public void removedService(ServiceReference reference, Object service) { - // Keyring is gone, remove launcher, et. al. as well + public void dependenciesUnavailable() { + // Keyring or CommonPaths are gone, remove launcher, et. al. as well launcherReg.unregister(); bundleManReg.unregister(); cmdInfoReg.unregister(); exitStatusReg.unregister(); } - + } - @SuppressWarnings("rawtypes") - private ServiceTracker serviceTracker; + private MultipleServiceTracker launcherDepsTracker; private CommandRegistry registry; + @SuppressWarnings("rawtypes") private ServiceTracker commandInfoSourceTracker; @SuppressWarnings({ "rawtypes", "unchecked" }) @@ -128,11 +131,13 @@ public void start(final BundleContext context) throws Exception { CurrentEnvironment environment = new CurrentEnvironment(Environment.CLI); - BundleManager bundleService = new BundleManagerImpl(new Configuration()); - ServiceTrackerCustomizer customizer = new RegisterLauncherCustomizer(context, bundleService, environment); - serviceTracker = new ServiceTracker(context, Keyring.class, customizer); - // Track for Keyring service. - serviceTracker.open(); + Class[] launcherDeps = new Class[]{ + Keyring.class, + CommonPaths.class, + }; + launcherDepsTracker = new MultipleServiceTracker(context, launcherDeps, + new RegisterLauncherAction(context, environment)); + launcherDepsTracker.open(); final HelpCommand helpCommand = new HelpCommand(); environment.addListener(new CurrentEnvironmentChangeListener() { @@ -165,10 +170,12 @@ @Override public void stop(BundleContext context) throws Exception { - if (serviceTracker != null) { - serviceTracker.close(); + if (launcherDepsTracker != null) { + launcherDepsTracker.close(); } - commandInfoSourceTracker.close(); + if (commandInfoSourceTracker != null) { + commandInfoSourceTracker.close(); + } registry.unregisterCommands(); } }
--- a/launcher/src/main/java/com/redhat/thermostat/launcher/internal/BundleManagerImpl.java Fri Nov 15 17:28:05 2013 -0700 +++ b/launcher/src/main/java/com/redhat/thermostat/launcher/internal/BundleManagerImpl.java Mon Nov 18 08:22:15 2013 -0700 @@ -54,8 +54,6 @@ import java.util.logging.Level; import java.util.logging.Logger; -import javax.naming.ConfigurationException; - import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleException; @@ -67,7 +65,7 @@ import com.redhat.thermostat.common.utils.LoggingUtils; import com.redhat.thermostat.launcher.BundleInformation; import com.redhat.thermostat.launcher.BundleManager; -import com.redhat.thermostat.shared.config.Configuration; +import com.redhat.thermostat.shared.config.CommonPaths; public class BundleManagerImpl extends BundleManager { @@ -80,15 +78,15 @@ // name/version. See // http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=1514 private final Map<BundleInformation, Path> known; - private Configuration configuration; + private CommonPaths paths; private boolean printOSGiInfo = false; private boolean ignoreBundleVersions = false; private BundleLoader loader; - BundleManagerImpl(Configuration configuration) throws ConfigurationException, FileNotFoundException, IOException { + BundleManagerImpl(CommonPaths paths) throws FileNotFoundException, IOException { known = new HashMap<>(); - this.configuration = configuration; + this.paths = paths; loader = new BundleLoader(); scanForBundles(); @@ -98,7 +96,7 @@ long t1 = System.nanoTime(); try { - for (File root : new File[] { configuration.getSystemLibRoot(), configuration.getSystemPluginRoot() }) { + for (File root : new File[] { paths.getSystemLibRoot(), paths.getSystemPluginRoot() }) { Files.walkFileTree(root.toPath(), new SimpleFileVisitor<Path>() { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { @@ -245,8 +243,8 @@ } @Override - public Configuration getConfiguration() { - return configuration; + public CommonPaths getCommonPaths() { + return paths; } }
--- a/launcher/src/main/java/com/redhat/thermostat/launcher/internal/LauncherImpl.java Fri Nov 15 17:28:05 2013 -0700 +++ b/launcher/src/main/java/com/redhat/thermostat/launcher/internal/LauncherImpl.java Mon Nov 18 08:22:15 2013 -0700 @@ -68,6 +68,7 @@ import com.redhat.thermostat.common.utils.LoggingUtils; import com.redhat.thermostat.launcher.BundleManager; import com.redhat.thermostat.launcher.Launcher; +import com.redhat.thermostat.shared.config.CommonPaths; import com.redhat.thermostat.shared.config.InvalidConfigurationException; import com.redhat.thermostat.shared.locale.LocalizedString; import com.redhat.thermostat.shared.locale.Translate; @@ -76,7 +77,6 @@ import com.redhat.thermostat.storage.core.DbServiceFactory; import com.redhat.thermostat.storage.core.Storage; import com.redhat.thermostat.storage.core.StorageException; -import com.redhat.thermostat.utils.keyring.Keyring; /** * This class is thread-safe. @@ -98,20 +98,20 @@ private final CommandInfoSource commandInfoSource; private final CurrentEnvironment currentEnvironment; - /** MUST be mutated in a 'synchronized (this)' block */ - private ClientPreferences prefs; + private final ClientPreferences prefs; - public LauncherImpl(BundleContext context, CommandContextFactory cmdCtxFactory, BundleManager registry, CommandInfoSource infoSource, CurrentEnvironment env) { - this(context, cmdCtxFactory, registry, infoSource, - new CommandSource(context), env, new LoggingInitializer(), new DbServiceFactory(), new Version()); + public LauncherImpl(BundleContext context, CommandContextFactory cmdCtxFactory, BundleManager registry, + CommandInfoSource infoSource, CurrentEnvironment env, ClientPreferences prefs, CommonPaths paths) { + this(context, cmdCtxFactory, registry, infoSource, new CommandSource(context), env, + new DbServiceFactory(), new Version(), prefs, paths, new LoggingInitializer(paths)); } LauncherImpl(BundleContext context, CommandContextFactory cmdCtxFactory, BundleManager registry, CommandInfoSource commandInfoSource, CommandSource commandSource, - CurrentEnvironment currentEnvironment, - LoggingInitializer loggingInitializer, DbServiceFactory dbServiceFactory, Version version) { + CurrentEnvironment currentEnvironment, DbServiceFactory dbServiceFactory, Version version, + ClientPreferences prefs, CommonPaths paths, LoggingInitializer loggingInitializer) { this.context = context; this.cmdCtxFactory = cmdCtxFactory; this.registry = registry; @@ -120,6 +120,7 @@ this.commandSource = commandSource; this.commandInfoSource = commandInfoSource; this.currentEnvironment = currentEnvironment; + this.prefs = prefs; loggingInitializer.initialize(); logger = LoggingUtils.getLogger(LauncherImpl.class); @@ -204,10 +205,6 @@ } } - synchronized void setPreferences(ClientPreferences prefs) { - this.prefs = prefs; - } - private boolean hasNoArguments(String[] args) { return args == null || args.length == 0; } @@ -333,16 +330,8 @@ CommandContext ctx = cmdCtxFactory.createContext(args); - synchronized (this) { - if (prefs == null) { - ServiceReference keyringReference = context.getServiceReference(Keyring.class); - @SuppressWarnings("unchecked") - Keyring keyring = (Keyring) context.getService(keyringReference); - prefs = new ClientPreferences(keyring); - } - } - if (cmd.isStorageRequired()) { + ServiceReference dbServiceReference = context.getServiceReference(DbService.class); if (dbServiceReference == null) { String dbUrl = ctx.getArguments().getArgument(CommonOptions.DB_URL_ARG); @@ -389,14 +378,21 @@ } static class LoggingInitializer { + + private CommonPaths paths; + + LoggingInitializer(CommonPaths paths) { + this.paths = paths; + } + public void initialize() { try { - LoggingUtils.loadGlobalLoggingConfig(); + LoggingUtils.loadGlobalLoggingConfig(paths); } catch (InvalidConfigurationException e) { System.err.println("WARNING: Could not read global Thermostat logging configuration."); } try { - LoggingUtils.loadUserLoggingConfig(); + LoggingUtils.loadUserLoggingConfig(paths); } catch (InvalidConfigurationException e) { // We intentionally ignore this. }
--- a/launcher/src/test/java/com/redhat/thermostat/launcher/internal/ActivatorTest.java Fri Nov 15 17:28:05 2013 -0700 +++ b/launcher/src/test/java/com/redhat/thermostat/launcher/internal/ActivatorTest.java Mon Nov 18 08:22:15 2013 -0700 @@ -53,7 +53,9 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; +import java.util.HashMap; import java.util.Hashtable; +import java.util.Map; import org.junit.Before; import org.junit.Test; @@ -63,10 +65,8 @@ import org.osgi.framework.BundleContext; import org.osgi.framework.FrameworkUtil; import org.osgi.framework.InvalidSyntaxException; -import org.osgi.framework.ServiceReference; +import org.osgi.framework.ServiceRegistration; import org.osgi.framework.launch.Framework; -import org.osgi.util.tracker.ServiceTracker; -import org.osgi.util.tracker.ServiceTrackerCustomizer; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; @@ -77,13 +77,12 @@ import com.redhat.thermostat.common.cli.Command; import com.redhat.thermostat.launcher.BundleManager; import com.redhat.thermostat.launcher.Launcher; -import com.redhat.thermostat.launcher.internal.Activator.RegisterLauncherCustomizer; -import com.redhat.thermostat.shared.config.Configuration; +import com.redhat.thermostat.shared.config.CommonPaths; import com.redhat.thermostat.testutils.StubBundleContext; import com.redhat.thermostat.utils.keyring.Keyring; @RunWith(PowerMockRunner.class) -@PrepareForTest({Activator.class, Activator.RegisterLauncherCustomizer.class, FrameworkUtil.class}) +@PrepareForTest({Activator.class, Activator.RegisterLauncherAction.class, FrameworkUtil.class}) public class ActivatorTest { private StubBundleContext context; @@ -107,9 +106,9 @@ props.put(Command.NAME, "help"); context.registerService(Command.class, helpCommand, props); - Configuration config = mock(Configuration.class); + CommonPaths config = mock(CommonPaths.class); when(config.getSystemThermostatHome()).thenReturn(new File("")); - when(registryService.getConfiguration()).thenReturn(config); + when(registryService.getCommonPaths()).thenReturn(config); BuiltInCommandInfoSource source1 = mock(BuiltInCommandInfoSource.class); when(source1.getCommandInfos()).thenReturn(new ArrayList<CommandInfo>()); @@ -139,10 +138,12 @@ @Test public void testActivatorLifecycle() throws Exception { - ArgumentCaptor<RegisterLauncherCustomizer> customizerCaptor = ArgumentCaptor.forClass(RegisterLauncherCustomizer.class); - ServiceTracker mockTracker = mock(ServiceTracker.class); - whenNew(ServiceTracker.class).withParameterTypes(BundleContext.class, Class.class, ServiceTrackerCustomizer.class).withArguments(eq(context), - any(Keyring.class), customizerCaptor.capture()).thenReturn(mockTracker); + ArgumentCaptor<Action> actionCaptor = ArgumentCaptor.forClass(Action.class); + MultipleServiceTracker mockTracker = mock(MultipleServiceTracker.class); + whenNew(MultipleServiceTracker.class) + .withParameterTypes(BundleContext.class, Class[].class, Action.class) + .withArguments(eq(context), any(Class[].class), actionCaptor.capture()) + .thenReturn(mockTracker); Activator activator = new Activator(); activator.start(context); @@ -151,8 +152,8 @@ verify(mockTracker).open(); - RegisterLauncherCustomizer customizer = customizerCaptor.getValue(); - assertNotNull(customizer); + Action action = actionCaptor.getValue(); + assertNotNull(action); activator.stop(context); verify(mockTracker).close(); } @@ -160,10 +161,10 @@ @Test public void testServiceTrackerCustomizer() throws Exception { StubBundleContext context = new StubBundleContext(); - ArgumentCaptor<RegisterLauncherCustomizer> customizerCaptor = ArgumentCaptor.forClass(RegisterLauncherCustomizer.class); - ServiceTracker mockTracker = mock(ServiceTracker.class); - whenNew(ServiceTracker.class).withParameterTypes(BundleContext.class, Class.class, ServiceTrackerCustomizer.class).withArguments(eq(context), - any(Keyring.class), customizerCaptor.capture()).thenReturn(mockTracker); + ArgumentCaptor<Action> actionCaptor = ArgumentCaptor.forClass(Action.class); + MultipleServiceTracker mockTracker = mock(MultipleServiceTracker.class); + whenNew(MultipleServiceTracker.class).withParameterTypes(BundleContext.class, Class[].class, Action.class).withArguments(eq(context), + any(Class[].class), actionCaptor.capture()).thenReturn(mockTracker); Activator activator = new Activator(); context.registerService(Keyring.class, mock(Keyring.class), null); @@ -171,19 +172,31 @@ assertTrue(context.isServiceRegistered(Command.class.getName(), HelpCommand.class)); - RegisterLauncherCustomizer customizer = customizerCaptor.getValue(); - assertNotNull(customizer); + Action action = actionCaptor.getValue(); + assertNotNull(action); Keyring keyringService = mock(Keyring.class); - context.registerService(Keyring.class, keyringService, null); - ServiceReference ref = context.getServiceReference(Keyring.class); - customizer.addingService(ref); + CommonPaths paths = mock(CommonPaths.class); + when(paths.getSystemLibRoot()).thenReturn(new File("")); + when(paths.getSystemPluginRoot()).thenReturn(new File("")); + when(paths.getUserPluginRoot()).thenReturn(new File("")); + when(paths.getUserClientConfigurationFile()).thenReturn(new File("")); + @SuppressWarnings("rawtypes") + ServiceRegistration keyringReg = context.registerService(Keyring.class, keyringService, null); + @SuppressWarnings("rawtypes") + ServiceRegistration pathsReg = context.registerService(CommonPaths.class, paths, null); + Map<String, Object> services = new HashMap<>(); + services.put(Keyring.class.getName(), keyringService); + services.put(CommonPaths.class.getName(), paths); + action.dependenciesAvailable(services); assertTrue(context.isServiceRegistered(CommandInfoSource.class.getName(), mock(CompoundCommandInfoSource.class).getClass())); assertTrue(context.isServiceRegistered(BundleManager.class.getName(), BundleManagerImpl.class)); assertTrue(context.isServiceRegistered(Launcher.class.getName(), LauncherImpl.class)); assertTrue(context.isServiceRegistered(ExitStatus.class.getName(), ExitStatusImpl.class)); - customizer.removedService(null, null); + action.dependenciesUnavailable(); + keyringReg.unregister(); + pathsReg.unregister(); assertFalse(context.isServiceRegistered(CommandInfoSource.class.getName(), CompoundCommandInfoSource.class)); assertFalse(context.isServiceRegistered(BundleManager.class.getName(), BundleManagerImpl.class));
--- a/launcher/src/test/java/com/redhat/thermostat/launcher/internal/BundleManagerImplTest.java Fri Nov 15 17:28:05 2013 -0700 +++ b/launcher/src/test/java/com/redhat/thermostat/launcher/internal/BundleManagerImplTest.java Mon Nov 18 08:22:15 2013 -0700 @@ -71,7 +71,7 @@ import org.powermock.modules.junit4.PowerMockRunner; import com.redhat.thermostat.launcher.BundleInformation; -import com.redhat.thermostat.shared.config.Configuration; +import com.redhat.thermostat.shared.config.CommonPaths; @RunWith(PowerMockRunner.class) @PrepareForTest({BundleManagerImpl.class, FrameworkUtil.class}) @@ -88,7 +88,7 @@ private BundleContext theContext; private BundleLoader loader; - private Configuration conf; + private CommonPaths paths; private Path testRoot; @@ -100,9 +100,9 @@ Path jarRootDir = testRoot.resolve("libs"); Files.createDirectories(jarRootDir); - conf = mock(Configuration.class); - when(conf.getSystemLibRoot()).thenReturn(jarRootDir.toFile()); - when(conf.getSystemPluginRoot()).thenReturn(pluginRootDir.toFile()); + paths = mock(CommonPaths.class); + when(paths.getSystemLibRoot()).thenReturn(jarRootDir.toFile()); + when(paths.getSystemPluginRoot()).thenReturn(pluginRootDir.toFile()); theContext = mock(BundleContext.class); theFramework = mock(Framework.class); @@ -159,7 +159,7 @@ when(FrameworkUtil.getBundle(any(Class.class))).thenReturn(theBundle); - BundleManagerImpl registry = new BundleManagerImpl(conf); + BundleManagerImpl registry = new BundleManagerImpl(paths); registry.loadBundlesByPath(bundleLocs); verify(loader).installAndStartBundles(any(Framework.class), eq(bundleLocs)); } @@ -174,7 +174,7 @@ when(FrameworkUtil.getBundle(any(Class.class))).thenReturn(theBundle); - BundleManagerImpl registry = new BundleManagerImpl(conf); + BundleManagerImpl registry = new BundleManagerImpl(paths); Map<BundleInformation, Path> bundleToPath = new HashMap<>(); registry.setKnownBundles(bundleToPath); @@ -195,7 +195,7 @@ when(FrameworkUtil.getBundle(any(Class.class))).thenReturn(theBundle); - BundleManagerImpl registry = new BundleManagerImpl(conf); + BundleManagerImpl registry = new BundleManagerImpl(paths); Map<BundleInformation, Path> bundleToPath = new HashMap<>(); bundleToPath.put(new BundleInformation("foo", "1.0"), Paths.get(jar1Name)); registry.setKnownBundles(bundleToPath); @@ -216,7 +216,7 @@ when(FrameworkUtil.getBundle(any(Class.class))).thenReturn(theBundle); - BundleManagerImpl registry = new BundleManagerImpl(conf); + BundleManagerImpl registry = new BundleManagerImpl(paths); registry.setIgnoreBundleVersions(true); Map<BundleInformation, Path> bundleToPath = new HashMap<>(); bundleToPath.put(new BundleInformation("foo", "1.0"), Paths.get(jar1Name)); @@ -240,7 +240,7 @@ when(FrameworkUtil.getBundle(any(Class.class))).thenReturn(theBundle); - BundleManagerImpl registry = new BundleManagerImpl(conf); + BundleManagerImpl registry = new BundleManagerImpl(paths); Map<BundleInformation, Path> bundleToPath = new HashMap<>(); bundleToPath.put(new BundleInformation("foo", "1.0"), Paths.get(jar1Name)); bundleToPath.put(new BundleInformation("foo", "2.0"), Paths.get(jar2Name)); @@ -264,7 +264,7 @@ mockStatic(FrameworkUtil.class); when(FrameworkUtil.getBundle(any(Class.class))).thenReturn(theBundle); - BundleManagerImpl registry = new BundleManagerImpl(conf); + BundleManagerImpl registry = new BundleManagerImpl(paths); registry.loadBundlesByPath(bundleLocs); verify(loader).installAndStartBundles(theFramework, Arrays.asList(jar3Name)); } @@ -283,7 +283,7 @@ mockStatic(FrameworkUtil.class); when(FrameworkUtil.getBundle(any(Class.class))).thenReturn(theBundle); - Object registry = new BundleManagerImpl(conf); + Object registry = new BundleManagerImpl(paths); Class<?> clazz = registry.getClass(); Method m = clazz.getMethod("setPrintOSGiInfo", Boolean.TYPE); m.invoke(registry, true); // If this fails, then API has changed in ways that break FrameworkProvider.
--- a/launcher/src/test/java/com/redhat/thermostat/launcher/internal/LauncherImplTest.java Fri Nov 15 17:28:05 2013 -0700 +++ b/launcher/src/test/java/com/redhat/thermostat/launcher/internal/LauncherImplTest.java Mon Nov 18 08:22:15 2013 -0700 @@ -45,6 +45,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; @@ -80,6 +81,7 @@ import com.redhat.thermostat.launcher.BundleManager; import com.redhat.thermostat.launcher.internal.DisallowSystemExitSecurityManager.ExitException; import com.redhat.thermostat.launcher.internal.LauncherImpl.LoggingInitializer; +import com.redhat.thermostat.shared.config.CommonPaths; import com.redhat.thermostat.shared.locale.LocalizedString; import com.redhat.thermostat.storage.core.DbService; import com.redhat.thermostat.storage.core.DbServiceFactory; @@ -147,6 +149,9 @@ private LauncherImpl launcher; + private CurrentEnvironment environment; + private CommonPaths paths; + @Before public void setUp() throws CommandInfoNotFoundException, BundleException, IOException { setupCommandContextFactory(); @@ -259,15 +264,20 @@ when(appSvc.getApplicationExecutor()).thenReturn(exec); bundleContext.registerService(ApplicationService.class, appSvc, null); - CurrentEnvironment environment = mock(CurrentEnvironment.class); + environment = mock(CurrentEnvironment.class); loggingInitializer = mock(LoggingInitializer.class); dbServiceFactory = mock(DbServiceFactory.class); version = mock(Version.class); - launcher = new LauncherImpl(bundleContext, ctxFactory, registry, infos, new CommandSource(bundleContext), environment, loggingInitializer, dbServiceFactory, version); + Keyring keyring = mock(Keyring.class); + paths = mock(CommonPaths.class); + File userConfigFile = mock(File.class); + when(userConfigFile.isFile()).thenReturn(false); + when(paths.getUserClientConfigurationFile()).thenReturn(userConfigFile); + ClientPreferences prefs = new ClientPreferences(keyring, paths); - Keyring keyring = mock(Keyring.class); - launcher.setPreferences(new ClientPreferences(keyring)); + launcher = new LauncherImpl(bundleContext, ctxFactory, registry, infos, new CommandSource(bundleContext), + environment, dbServiceFactory, version, prefs, paths, loggingInitializer); } private void setupCommandContextFactory() { @@ -473,10 +483,12 @@ when(prefs.getUserName()).thenReturn("user"); when(prefs.getPassword()).thenReturn("password"); + LauncherImpl launcher = new LauncherImpl(bundleContext, ctxFactory, registry, infos, new CommandSource(bundleContext), + environment, dbServiceFactory, version, prefs, paths, loggingInitializer); + DbService dbService = mock(DbService.class); ArgumentCaptor<String> dbUrlCaptor = ArgumentCaptor.forClass(String.class); when(dbServiceFactory.createDbService(eq("user"), eq("password"), dbUrlCaptor.capture())).thenReturn(dbService); - launcher.setPreferences(prefs); wrappedRun(launcher, new String[] { "test3" }, false); verify(dbService).connect(); verify(prefs).getConnectionUrl(); @@ -488,11 +500,12 @@ ClientPreferences prefs = mock(ClientPreferences.class); String dbUrl = "mongo://fluff:12345"; when(prefs.getConnectionUrl()).thenReturn(dbUrl); + LauncherImpl launcher = new LauncherImpl(bundleContext, ctxFactory, registry, infos, new CommandSource(bundleContext), + environment, dbServiceFactory, version, prefs, paths, loggingInitializer); DbService dbService = mock(DbService.class); ArgumentCaptor<String> dbUrlCaptor = ArgumentCaptor.forClass(String.class); when(dbServiceFactory.createDbService(eq("user"), eq("pass"), dbUrlCaptor.capture())).thenReturn(dbService); - launcher.setPreferences(prefs); ctxFactory.setInput("user\rpass\r"); wrappedRun(launcher, new String[] { "test3" }, false); verify(dbService).connect();
--- a/main/src/main/java/com/redhat/thermostat/main/Thermostat.java Fri Nov 15 17:28:05 2013 -0700 +++ b/main/src/main/java/com/redhat/thermostat/main/Thermostat.java Mon Nov 18 08:22:15 2013 -0700 @@ -42,7 +42,8 @@ import java.util.List; import com.redhat.thermostat.main.impl.FrameworkProvider; -import com.redhat.thermostat.shared.config.Configuration; +import com.redhat.thermostat.shared.config.CommonPaths; +import com.redhat.thermostat.shared.config.internal.CommonPathsImpl; public class Thermostat { @@ -68,8 +69,8 @@ } } - Configuration config = new Configuration(); - FrameworkProvider frameworkProvider = new FrameworkProvider(config, printOSGiInfo, ignoreBundleVersions); + CommonPaths paths = new CommonPathsImpl(); + FrameworkProvider frameworkProvider = new FrameworkProvider(paths, printOSGiInfo, ignoreBundleVersions); frameworkProvider.start(toProcess.toArray(new String[0])); }
--- a/main/src/main/java/com/redhat/thermostat/main/impl/FrameworkProvider.java Fri Nov 15 17:28:05 2013 -0700 +++ b/main/src/main/java/com/redhat/thermostat/main/impl/FrameworkProvider.java Mon Nov 18 08:22:15 2013 -0700 @@ -61,8 +61,7 @@ import com.redhat.thermostat.launcher.BundleManager; import com.redhat.thermostat.launcher.Launcher; -import com.redhat.thermostat.shared.config.Configuration; -import com.redhat.thermostat.shared.config.InvalidConfigurationException; +import com.redhat.thermostat.shared.config.CommonPaths; public class FrameworkProvider { @@ -70,15 +69,15 @@ private static final String PROPS_FILE = "/com/redhat/thermostat/main/impl/bootstrapbundles.properties"; private static final String BUNDLELIST = "bundles"; - private Configuration configuration; + private CommonPaths paths; private boolean printOSGiInfo; private boolean ignoreBundleVersions; // The framework cache location; Must not be shared between apps! private Path osgiCacheStorage; - public FrameworkProvider(Configuration config, boolean printOSGiInfo, boolean ignoreBundleVersions) { - this.configuration = config; + public FrameworkProvider(CommonPaths paths, boolean printOSGiInfo, boolean ignoreBundleVersions) { + this.paths = paths; this.printOSGiInfo = printOSGiInfo; this.ignoreBundleVersions = ignoreBundleVersions; @@ -101,7 +100,7 @@ } private String getOSGiPublicPackages() throws FileNotFoundException, IOException { - File osgiBundleDefinitions = new File(configuration.getSystemConfigurationDirectory(), "osgi-export.properties"); + File osgiBundleDefinitions = new File(paths.getSystemConfigurationDirectory(), "osgi-export.properties"); Properties bundles = new Properties(); bundles.load(new FileInputStream(osgiBundleDefinitions)); @@ -167,7 +166,7 @@ } private Framework makeFramework() throws FileNotFoundException, IOException { - File osgiCacheDir = new File(configuration.getUserCacheDirectory(), "osgi-cache"); + File osgiCacheDir = new File(paths.getUserCacheDirectory(), "osgi-cache"); if (!osgiCacheDir.isDirectory() && !osgiCacheDir.mkdirs()) { throw new RuntimeException("Unable to create " + osgiCacheDir); } @@ -299,7 +298,7 @@ // files across bootstrap and later code provide the same bundle symbolic // name version private String actualLocation(String resourceName) { - File file = new File(configuration.getSystemLibRoot(), resourceName); + File file = new File(paths.getSystemLibRoot(), resourceName); try { return file.getCanonicalFile().toURI().toString(); } catch (IOException e) {
--- a/main/src/main/resources/com/redhat/thermostat/main/impl/bootstrapbundles.properties Fri Nov 15 17:28:05 2013 -0700 +++ b/main/src/main/resources/com/redhat/thermostat/main/impl/bootstrapbundles.properties Mon Nov 18 08:22:15 2013 -0700 @@ -4,7 +4,6 @@ thermostat-common-core-${project.version}.jar, \ thermostat-plugin-validator-${project.version}.jar, \ thermostat-launcher-${project.version}.jar, \ - thermostat-main-${project.version}.jar, \ jline-${jline.version}.jar, \ commons-cli-${commons-cli.version}.jar, \ org.apache.servicemix.bundles.lucene-${lucene.version}.jar
--- a/web/server/src/main/java/com/redhat/thermostat/web/server/StorageFactory.java Fri Nov 15 17:28:05 2013 -0700 +++ b/web/server/src/main/java/com/redhat/thermostat/web/server/StorageFactory.java Mon Nov 18 08:22:15 2013 -0700 @@ -37,6 +37,7 @@ package com.redhat.thermostat.web.server; +import com.redhat.thermostat.shared.config.CommonPaths; import com.redhat.thermostat.shared.config.SSLConfiguration; import com.redhat.thermostat.shared.config.internal.SSLConfigurationImpl; import com.redhat.thermostat.storage.config.ConnectionConfiguration; @@ -50,12 +51,13 @@ private static Storage storage; // Web server is not OSGi, this factory method is workaround. - static Storage getStorage(String storageClass, final String storageEndpoint, final String username, final String password) { + static Storage getStorage(String storageClass, final String storageEndpoint, final String username, + final String password, final CommonPaths paths) { if (storage != null) { return storage; } StartupConfiguration conf = new ConnectionConfiguration(storageEndpoint, username, password); - SSLConfiguration sslConf = new SSLConfigurationImpl(); + SSLConfiguration sslConf = new SSLConfigurationImpl(paths); try { StorageProvider provider = (StorageProvider) Class.forName(storageClass).newInstance(); provider.setConfig(conf, sslConf);
--- a/web/server/src/main/java/com/redhat/thermostat/web/server/WebStorageEndPoint.java Fri Nov 15 17:28:05 2013 -0700 +++ b/web/server/src/main/java/com/redhat/thermostat/web/server/WebStorageEndPoint.java Mon Nov 18 08:22:15 2013 -0700 @@ -70,8 +70,9 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.redhat.thermostat.common.utils.LoggingUtils; -import com.redhat.thermostat.shared.config.Configuration; +import com.redhat.thermostat.shared.config.CommonPaths; import com.redhat.thermostat.shared.config.InvalidConfigurationException; +import com.redhat.thermostat.shared.config.internal.CommonPathsImpl; import com.redhat.thermostat.storage.core.Categories; import com.redhat.thermostat.storage.core.Category; import com.redhat.thermostat.storage.core.CategoryAdapter; @@ -128,6 +129,7 @@ private Storage storage; private Gson gson; + private CommonPaths paths; public static final String STORAGE_ENDPOINT = "storage.endpoint"; public static final String STORAGE_USERNAME = "storage.username"; @@ -158,6 +160,7 @@ logger.log(Level.INFO, "Initializing web service"); // check if thermostat home is set and readable + // Side effect: sets this.paths checkThermostatHome(); gson = new GsonBuilder() @@ -213,7 +216,7 @@ String storageEndpoint = getServletConfig().getInitParameter(STORAGE_ENDPOINT); String username = getServletConfig().getInitParameter(STORAGE_USERNAME); String password = getServletConfig().getInitParameter(STORAGE_PASSWORD); - storage = StorageFactory.getStorage(storageClass, storageEndpoint, username, password); + storage = StorageFactory.getStorage(storageClass, storageEndpoint, username, password, paths); } String uri = req.getRequestURI(); int lastPartIdx = uri.lastIndexOf("/"); @@ -240,18 +243,20 @@ verifyToken(req, resp); } } - + + // Side effect: sets this.paths private boolean isThermostatHomeSet() { try { // this throws config exception if neither the property // nor the env var is set - new Configuration(); + paths = new CommonPathsImpl(); return true; } catch (InvalidConfigurationException e) { return false; } } - + + // Side effect: sets this.paths private void checkThermostatHome() { if (!isThermostatHomeSet()) { String msg = "THERMOSTAT_HOME context parameter not set!"; @@ -274,8 +279,7 @@ private File getThermostatHome() { try { - Configuration config = new Configuration(); - return config.getSystemThermostatHome(); + return paths.getSystemThermostatHome(); } catch (InvalidConfigurationException e) { // we should have just checked if this throws any exception logger.log(Level.SEVERE, "Illegal configuration!", e);
--- a/web/server/src/main/java/com/redhat/thermostat/web/server/auth/spi/PropertiesUserValidator.java Fri Nov 15 17:28:05 2013 -0700 +++ b/web/server/src/main/java/com/redhat/thermostat/web/server/auth/spi/PropertiesUserValidator.java Mon Nov 18 08:22:15 2013 -0700 @@ -46,8 +46,8 @@ 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.shared.config.internal.CommonPathsImpl; /** * @@ -63,7 +63,7 @@ PropertiesUserValidator() { // 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)); + this((new CommonPathsImpl().getSystemConfigurationDirectory() + File.separator + DEFAULT_USERS_FILE)); } PropertiesUserValidator(String usersFile) {
--- a/web/server/src/main/java/com/redhat/thermostat/web/server/auth/spi/RolesAmender.java Fri Nov 15 17:28:05 2013 -0700 +++ b/web/server/src/main/java/com/redhat/thermostat/web/server/auth/spi/RolesAmender.java Mon Nov 18 08:22:15 2013 -0700 @@ -50,8 +50,8 @@ 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.shared.config.internal.CommonPathsImpl; import com.redhat.thermostat.web.server.auth.BasicRole; import com.redhat.thermostat.web.server.auth.RolePrincipal; @@ -74,7 +74,7 @@ // 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); + this((new CommonPathsImpl().getSystemConfigurationDirectory() + File.separator + DEFAULT_ROLES_FILE), users); } RolesAmender(String rolesFile, Set<Object> users) {
--- a/web/server/src/test/java/com/redhat/thermostat/web/server/WebStorageEndpointTest.java Fri Nov 15 17:28:05 2013 -0700 +++ b/web/server/src/test/java/com/redhat/thermostat/web/server/WebStorageEndpointTest.java Mon Nov 18 08:22:15 2013 -0700 @@ -48,7 +48,6 @@ import static org.mockito.Mockito.when; import java.io.ByteArrayInputStream; -import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -63,8 +62,6 @@ import java.net.URL; import java.net.URLEncoder; import java.security.Principal; -import java.nio.file.Files; -import java.nio.file.Path; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; @@ -184,22 +181,6 @@ private static Key<Integer> key2; private static Category<TestClass> category; private static String categoryName = "test"; - private static String originalThermostatHome; - - @BeforeClass - public static void setupThermostatHome() { - Path tempHomePath = null; - try { - tempHomePath = Files.createTempDirectory("WebStorageEndpointTest_THERMOSTAT_HOME"); - } catch (IOException e) { - e.printStackTrace(); - } - File fakeHome = tempHomePath.toFile(); - fakeHome.deleteOnExit(); - assertTrue(fakeHome.canRead()); - originalThermostatHome = System.getProperty("THERMOSTAT_HOME"); - System.setProperty("THERMOSTAT_HOME", fakeHome.getAbsolutePath()); - } @BeforeClass public static void setupCategory() { @@ -209,15 +190,6 @@ } @AfterClass - public static void cleanupThermostatHome() { - if (originalThermostatHome != null) { - System.setProperty("THERMOSTAT_HOME", originalThermostatHome); - } else { - System.clearProperty("THERMOSTAT_HOME"); - } - } - - @AfterClass public static void cleanupCategory() { Categories.remove(category); category = null;