Mercurial > hg > release > thermostat-0.6
changeset 13:11f027c26096
Clearly separate configuration used to launch from ongoing configuration changes via storage schema.
- Also included here is a fix that ensures log level is respected globally.
author | Jon VanAlten <jon.vanalten@redhat.com> |
---|---|
date | Tue, 06 Dec 2011 14:28:07 -0500 |
parents | fdec0f43fe00 |
children | e9dbb0bee8d0 |
files | src/com/redhat/thermostat/agent/Agent.java src/com/redhat/thermostat/agent/Main.java src/com/redhat/thermostat/agent/MongoStorage.java src/com/redhat/thermostat/agent/Storage.java src/com/redhat/thermostat/agent/config/Configuration.java src/com/redhat/thermostat/agent/config/ConfigurationWatcher.java src/com/redhat/thermostat/agent/config/StartupConfiguration.java src/com/redhat/thermostat/backend/Backend.java src/com/redhat/thermostat/backend/BackendRegistry.java src/com/redhat/thermostat/backend/sample/SampleBackend.java src/com/redhat/thermostat/backend/system/SystemBackend.java src/com/redhat/thermostat/common/Constants.java src/com/redhat/thermostat/common/utils/LoggingUtils.java |
diffstat | 13 files changed, 390 insertions(+), 303 deletions(-) [+] |
line wrap: on
line diff
--- a/src/com/redhat/thermostat/agent/Agent.java Tue Dec 06 13:39:50 2011 -0500 +++ b/src/com/redhat/thermostat/agent/Agent.java Tue Dec 06 14:28:07 2011 -0500 @@ -1,10 +1,10 @@ package com.redhat.thermostat.agent; import java.util.UUID; -import java.util.logging.Level; import java.util.logging.Logger; -import com.redhat.thermostat.agent.config.Configuration; +import com.redhat.thermostat.agent.config.ConfigurationWatcher; +import com.redhat.thermostat.agent.config.StartupConfiguration; import com.redhat.thermostat.backend.Backend; import com.redhat.thermostat.backend.BackendRegistry; import com.redhat.thermostat.common.LaunchException; @@ -19,15 +19,16 @@ private final UUID id; private final BackendRegistry backendRegistry; - private final Configuration config; + private final StartupConfiguration config; private Storage storage; + private Thread configWatcherThread = null; - public Agent(BackendRegistry backendRegistry, Configuration config, Storage storage) { + public Agent(BackendRegistry backendRegistry, StartupConfiguration config, Storage storage) { this(backendRegistry, UUID.randomUUID(), config, storage); } - public Agent(BackendRegistry registry, UUID agentId, Configuration config, Storage storage) { + public Agent(BackendRegistry registry, UUID agentId, StartupConfiguration config, Storage storage) { this.id = agentId; this.backendRegistry = registry; this.config = config; @@ -36,7 +37,9 @@ private void startBackends() throws LaunchException { for (Backend be : backendRegistry.getAll()) { + logger.fine("Attempting to start backend: " + be.getName()); if (!be.activate()) { + logger.warning("Issue while starting backend: " + be.getName()); // When encountering issues during startup, we should not attempt to continue activating. stopBackends(); throw new LaunchException("Could not activate backend: " + be.getName()); @@ -46,21 +49,41 @@ private void stopBackends() { for (Backend be : backendRegistry.getAll()) { + logger.fine("Attempting to stop backend: " +be.getName()); if (!be.deactivate()) { // When encountering issues during shutdown, we should attempt to shut down remaining backends. - logger.log(Level.WARNING, "Issue while deactivating backend: " + be.getName()); + logger.warning("Issue while deactivating backend: " + be.getName()); } } } - public void start() throws LaunchException { - startBackends(); - config.publish(); + public synchronized void start() throws LaunchException { + if (configWatcherThread == null) { + startBackends(); + storage.addAgentInformation(config); + configWatcherThread = new Thread(new ConfigurationWatcher(storage), "Configuration Watcher"); + configWatcherThread.start(); + } else { + logger.warning("Attempt to start agent when already started."); + } } - public void stop() { - config.unpublish(); - stopBackends(); + public synchronized void stop() { + if (configWatcherThread != null) { + configWatcherThread.interrupt(); // This thread checks for its own interrupted state and ends if interrupted. + while (configWatcherThread.isAlive()) { + try { + configWatcherThread.join(); + } catch (InterruptedException e) { + logger.fine("Interrupted while waiting for ConfigurationWatcher to die."); + } + } + configWatcherThread = null; + storage.removeAgentInformation(); + stopBackends(); + } else { + logger.warning("Attempt to stop agent which is not active"); + } } public UUID getId() {
--- a/src/com/redhat/thermostat/agent/Main.java Tue Dec 06 13:39:50 2011 -0500 +++ b/src/com/redhat/thermostat/agent/Main.java Tue Dec 06 14:28:07 2011 -0500 @@ -5,16 +5,14 @@ import java.net.UnknownHostException; import java.util.Properties; import java.util.logging.Level; -import java.util.logging.LogManager; import java.util.logging.Logger; -import com.redhat.thermostat.agent.config.Configuration; +import com.redhat.thermostat.agent.config.StartupConfiguration; import com.redhat.thermostat.backend.BackendLoadException; import com.redhat.thermostat.backend.BackendRegistry; import com.redhat.thermostat.common.Constants; import com.redhat.thermostat.common.LaunchException; import com.redhat.thermostat.common.utils.LoggingUtils; -import com.redhat.thermostat.common.utils.StringUtils; public final class Main { @@ -25,13 +23,7 @@ public static void main(String[] args) { long startTimestamp = System.currentTimeMillis(); - try { - LogManager.getLogManager().readConfiguration( - StringUtils.toInputStream(Constants.LOGGING_CONFIG)); - } catch (Exception e) { - e.printStackTrace(); - } - + LoggingUtils.setGlobalLogLevel(Level.ALL); LoggingUtils.resetAndGetRootLogger(); Logger logger = LoggingUtils.getLogger(Main.class); @@ -46,9 +38,9 @@ System.exit(Constants.EXIT_UNABLE_TO_READ_PROPERTIES); } - Configuration config = null; + StartupConfiguration config = null; try { - config = new Configuration(startTimestamp, args, props); + config = new StartupConfiguration(startTimestamp, args, props); } catch (LaunchException le) { logger.log(Level.SEVERE, "Unable to instantiate startup configuration.", @@ -57,16 +49,16 @@ } logger.setLevel(config.getLogLevel()); + LoggingUtils.setGlobalLogLevel(config.getLogLevel()); Storage storage = new MongoStorage(); try { storage.connect(config.getDatabaseURIAsString()); - logger.fine("connected"); + logger.fine("Connected to database server."); } catch (UnknownHostException uhe) { logger.log(Level.SEVERE, "Could not initialize storage layer.", uhe); System.exit(Constants.EXIT_UNABLE_TO_CONNECT_TO_DATABASE); } - config.setStorage(storage); BackendRegistry backendRegistry = null; try { @@ -80,6 +72,7 @@ config.setAgent(agent); storage.setAgentId(agent.getId()); try { + logger.fine("Starting agent."); agent.start(); } catch (LaunchException le) { logger.log(Level.SEVERE,
--- a/src/com/redhat/thermostat/agent/MongoStorage.java Tue Dec 06 13:39:50 2011 -0500 +++ b/src/com/redhat/thermostat/agent/MongoStorage.java Tue Dec 06 14:28:07 2011 -0500 @@ -14,7 +14,7 @@ import com.mongodb.Mongo; import com.mongodb.MongoURI; import com.mongodb.WriteConcern; -import com.redhat.thermostat.agent.config.Configuration; +import com.redhat.thermostat.agent.config.StartupConfiguration; import com.redhat.thermostat.common.Constants; import com.redhat.thermostat.common.CpuStat; import com.redhat.thermostat.common.HostInfo; @@ -43,7 +43,7 @@ } @Override - public void addAgentInformation(Configuration config) { + public void addAgentInformation(StartupConfiguration config) { DBCollection configCollection = db.getCollection(StorageConstants.COLLECTION_AGENT_CONFIG); DBObject toInsert = config.toDBObject(); /* cast required to disambiguate between putAll(BSONObject) and putAll(Map) */ @@ -144,5 +144,4 @@ toInsert.put(StorageConstants.KEY_MEMORY_STATS_COMMIT_LIMIT, stat.getCommitLimit()); memoryStatsCollection.insert(toInsert, WriteConcern.NORMAL); } - }
--- a/src/com/redhat/thermostat/agent/Storage.java Tue Dec 06 13:39:50 2011 -0500 +++ b/src/com/redhat/thermostat/agent/Storage.java Tue Dec 06 14:28:07 2011 -0500 @@ -3,7 +3,7 @@ import java.net.UnknownHostException; import java.util.UUID; -import com.redhat.thermostat.agent.config.Configuration; +import com.redhat.thermostat.agent.config.StartupConfiguration; import com.redhat.thermostat.common.CpuStat; import com.redhat.thermostat.common.HostInfo; import com.redhat.thermostat.common.MemoryStat; @@ -13,7 +13,7 @@ public void setAgentId(UUID id); - public void addAgentInformation(Configuration config); + public void addAgentInformation(StartupConfiguration config); public void removeAgentInformation();
--- a/src/com/redhat/thermostat/agent/config/Configuration.java Tue Dec 06 13:39:50 2011 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,242 +0,0 @@ -package com.redhat.thermostat.agent.config; - -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Properties; -import java.util.logging.Level; -import java.util.logging.Logger; - -import com.mongodb.BasicDBObject; -import com.mongodb.DBObject; -import com.redhat.thermostat.agent.Agent; -import com.redhat.thermostat.agent.Defaults; -import com.redhat.thermostat.agent.Storage; -import com.redhat.thermostat.agent.StorageConstants; -import com.redhat.thermostat.common.Constants; -import com.redhat.thermostat.common.LaunchException; -import com.redhat.thermostat.common.utils.LoggingUtils; - -public final class Configuration { - - /* FIXME - * - * This class needs some love. It mixes up startup configuration with runtime configuration, - * while each is handled in very different ways. It probably should be split into separate - * classes, but it makes very little sense to do that before we have a Storage abstraction - * hiding implementation details (ie Mongo API stuff). - */ - private static Logger logger = LoggingUtils.getLogger(Configuration.class); - - private final long startTimestamp; - - private Properties props; - - private Level logLevel; - private boolean localMode; - private int mongodPort; - private int mongosPort; - private String databaseURI; - private String completeDatabaseURI; - - private String hostname; - - private Agent agent; - private Storage storage = null; - - public Configuration(long startTime, String[] args, Properties props) throws LaunchException { - this.props = props; - - initFromDefaults(); - initFromProperties(); - initFromArguments(args); - - if (localMode) { - completeDatabaseURI = databaseURI + ":" + mongodPort; - hostname = Constants.AGENT_LOCAL_HOSTNAME; - } else { - completeDatabaseURI = databaseURI + ":" + mongosPort; - try { - InetAddress addr = InetAddress.getLocalHost(); - hostname = addr.getCanonicalHostName(); - } catch (UnknownHostException e) { - logger.log(Level.FINE, "Error determining local hostname."); - } - } - startTimestamp = startTime; - } - - private void initFromDefaults() { - logLevel = Defaults.LOGGING_LEVEL; - localMode = Defaults.LOCAL_MODE; - mongodPort = Defaults.MONGOD_PORT; - mongosPort = Defaults.MONGOS_PORT; - databaseURI = Defaults.DATABASE_URI; - } - - private void initFromProperties() { - if (props.getProperty(Constants.AGENT_PROPERTY_MONGOD_PORT) != null) { - mongodPort = Integer.valueOf(props.getProperty(Constants.AGENT_PROPERTY_MONGOD_PORT)); - } - if (props.getProperty(Constants.AGENT_PROPERTY_MONGOS_PORT) != null) { - mongosPort = Integer.valueOf(props.getProperty(Constants.AGENT_PROPERTY_MONGOS_PORT)); - } - } - - private void initFromArguments(String[] args) throws LaunchException { - Arguments arguments; - - arguments = new Arguments(args); - if (arguments.isModeSpecified()) { - localMode = arguments.getLocalMode(); - } - if (arguments.isLogLevelSpecified()) { - logLevel = arguments.getLogLevel(); - } - } - - public void setStorage(Storage storage) { - this.storage = storage; - } - - public Level getLogLevel() { - return logLevel; - } - - public String getDatabaseURIAsString() { - return completeDatabaseURI; - } - - public String getHostname() { - return hostname; - } - - // TODO move this into Storage as well - public DBObject toDBObject() { - BasicDBObject result = new BasicDBObject(); - // TODO explicit exception if agent not yet set. - result.put(StorageConstants.KEY_AGENT_ID, agent.getId().toString()); - result.put(StorageConstants.KEY_AGENT_CONFIG_AGENT_START_TIME, startTimestamp); - // TODO create nested backend config parts - return result; - } - - public void setAgent(Agent agent) { - this.agent = agent; - } - - public void publish() { - storage.addAgentInformation(this); - // TODO Start configuration-change-detection thread. - } - - public void unpublish() { - // TODO Stop configuration-change-detection thread. - storage.removeAgentInformation(); - } - - public List<String> getStartupBackendClassNames() { - String fullPropertyString = props.getProperty(Constants.AGENT_PROPERTY_BACKENDS); - if ((fullPropertyString == null) // Avoid NPE - || (fullPropertyString.length() == 0)) { /* If we do the split() on this empty string, - * it will produce an array of size 1 containing - * the empty string, which we do not want. - */ - return new ArrayList<String>(); - } else { - return Arrays.asList(fullPropertyString.trim().split(",")); - } - } - - public Map<String, String> getStartupBackendConfigMap(String backendName) { - String prefix = backendName + "."; - Map<String, String> configMap = new HashMap<String, String>(); - for (Entry<Object, Object> e : props.entrySet()) { - String key = (String) e.getKey(); - if (key.startsWith(prefix)) { - String value = (String) e.getValue(); - String mapKey = key.substring(prefix.length()); - configMap.put(mapKey, value); - } - } - return configMap; - } - - /** - * - * @param backendName - * @param configurationKey - * @return - */ - public String getBackendConfigValue(String backendName, String configurationKey) { - return storage.getBackendConfig(backendName, configurationKey); - } - - /** - * Exposes the command line arguments in a more object-oriented style. - * <p> - * Please check that an option was specified (using the various is*Specified() methods) before using its value. - */ - private static class Arguments { - private final boolean localMode; - private final boolean modeSpecified; - private final Level logLevel; - private final boolean logLevelSpecified; - - public Arguments(String[] args) throws LaunchException { - boolean local = false; - boolean explicitMode = false; - Level level = null; - boolean explicitLogLevel = false; - for (int index = 0; index < args.length; index++) { - if (args[index].equals(Constants.AGENT_ARGUMENT_LOGLEVEL)) { - index++; - if (index < args.length) { - try { - level = Level.parse(args[index].toUpperCase()); - explicitLogLevel = true; - } catch (IllegalArgumentException iae) { - throw new LaunchException("Invalid argument for " + Constants.AGENT_ARGUMENT_LOGLEVEL, iae); - } - } else { - throw new LaunchException("Missing argument for " + Constants.AGENT_ARGUMENT_LOGLEVEL); - } - } else if (args[index].equals(Constants.AGENT_ARGUMENT_LOCAL)) { - explicitMode = true; - local = true; - } - } - logLevel = level; - logLevelSpecified = explicitLogLevel; - localMode = local; - modeSpecified = explicitMode; - } - - public boolean isModeSpecified() { - return modeSpecified; - } - - public boolean getLocalMode() { - if (!isModeSpecified()) { - throw new IllegalStateException("local mode is not valid"); - } - return localMode; - } - - public boolean isLogLevelSpecified() { - return logLevelSpecified; - } - - public Level getLogLevel() { - if (!isLogLevelSpecified()) { - throw new IllegalStateException("log level not explicitly specified"); - } - return logLevel; - } - } -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/com/redhat/thermostat/agent/config/ConfigurationWatcher.java Tue Dec 06 14:28:07 2011 -0500 @@ -0,0 +1,34 @@ +package com.redhat.thermostat.agent.config; + +import java.util.logging.Logger; + +import com.redhat.thermostat.agent.Storage; +import com.redhat.thermostat.common.utils.LoggingUtils; + +public class ConfigurationWatcher implements Runnable { + + private static final Logger logger = LoggingUtils.getLogger(ConfigurationWatcher.class); + + private Storage storage; + + public ConfigurationWatcher(Storage storage) { + this.storage = storage; + } + + @Override + public void run() { + logger.fine("Watching for configuration changes."); + while (!Thread.interrupted()) { + checkConfigUpdates(); + } + logger.fine("No longer watching for configuration changes."); + } + + // TODO It would be best to develop this algorithm when we have a client that can initiate changes, so that it can be tested. + private void checkConfigUpdates() { + try { // THIS IS ONLY TEMPORARY. Until we do implement this algorithm, we don't want this thread busy hogging CPU. + Thread.sleep(2000); + } catch (InterruptedException ignore) { } + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/com/redhat/thermostat/agent/config/StartupConfiguration.java Tue Dec 06 14:28:07 2011 -0500 @@ -0,0 +1,216 @@ +package com.redhat.thermostat.agent.config; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Properties; +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.mongodb.BasicDBObject; +import com.mongodb.DBObject; +import com.redhat.thermostat.agent.Agent; +import com.redhat.thermostat.agent.Defaults; +import com.redhat.thermostat.agent.StorageConstants; +import com.redhat.thermostat.common.Constants; +import com.redhat.thermostat.common.LaunchException; +import com.redhat.thermostat.common.utils.LoggingUtils; + +public final class StartupConfiguration { + + /* FIXME + * + * This class needs some love. It mixes up startup configuration with runtime configuration, + * while each is handled in very different ways. It probably should be split into separate + * classes, but it makes very little sense to do that before we have a Storage abstraction + * hiding implementation details (ie Mongo API stuff). + */ + private static Logger logger = LoggingUtils.getLogger(StartupConfiguration.class); + + private final long startTimestamp; + + private Properties props; + + private Level logLevel; + private boolean localMode; + private int mongodPort; + private int mongosPort; + private String databaseURI; + private String completeDatabaseURI; + + private String hostname; + + private Agent agent; + + public StartupConfiguration(long startTime, String[] args, Properties props) throws LaunchException { + this.props = props; + + initFromDefaults(); + initFromProperties(); + initFromArguments(args); + + if (localMode) { + completeDatabaseURI = databaseURI + ":" + mongodPort; + hostname = Constants.AGENT_LOCAL_HOSTNAME; + } else { + completeDatabaseURI = databaseURI + ":" + mongosPort; + try { + InetAddress addr = InetAddress.getLocalHost(); + hostname = addr.getCanonicalHostName(); + } catch (UnknownHostException e) { + logger.log(Level.FINE, "Error determining local hostname."); + } + } + startTimestamp = startTime; + } + + private void initFromDefaults() { + logLevel = Defaults.LOGGING_LEVEL; + localMode = Defaults.LOCAL_MODE; + mongodPort = Defaults.MONGOD_PORT; + mongosPort = Defaults.MONGOS_PORT; + databaseURI = Defaults.DATABASE_URI; + } + + private void initFromProperties() { + if (props.getProperty(Constants.AGENT_PROPERTY_MONGOD_PORT) != null) { + mongodPort = Integer.valueOf(props.getProperty(Constants.AGENT_PROPERTY_MONGOD_PORT)); + } + if (props.getProperty(Constants.AGENT_PROPERTY_MONGOS_PORT) != null) { + mongosPort = Integer.valueOf(props.getProperty(Constants.AGENT_PROPERTY_MONGOS_PORT)); + } + } + + private void initFromArguments(String[] args) throws LaunchException { + Arguments arguments; + + arguments = new Arguments(args); + if (arguments.isModeSpecified()) { + localMode = arguments.getLocalMode(); + } + if (arguments.isLogLevelSpecified()) { + logLevel = arguments.getLogLevel(); + } + } + + public Level getLogLevel() { + return logLevel; + } + + public String getDatabaseURIAsString() { + return completeDatabaseURI; + } + + public String getHostname() { + return hostname; + } + + // TODO move this into Storage as well + public DBObject toDBObject() { + BasicDBObject result = new BasicDBObject(); + // TODO explicit exception if agent not yet set. + result.put(StorageConstants.KEY_AGENT_ID, agent.getId().toString()); + result.put(StorageConstants.KEY_AGENT_CONFIG_AGENT_START_TIME, startTimestamp); + // TODO create nested backend config parts + return result; + } + + public void setAgent(Agent agent) { + this.agent = agent; + } + + public List<String> getStartupBackendClassNames() { + String fullPropertyString = props.getProperty(Constants.AGENT_PROPERTY_BACKENDS); + if ((fullPropertyString == null) // Avoid NPE + || (fullPropertyString.length() == 0)) { /* If we do the split() on this empty string, + * it will produce an array of size 1 containing + * the empty string, which we do not want. + */ + return new ArrayList<String>(); + } else { + return Arrays.asList(fullPropertyString.trim().split(",")); + } + } + + public Map<String, String> getStartupBackendConfigMap(String backendName) { + String prefix = backendName + "."; + Map<String, String> configMap = new HashMap<String, String>(); + for (Entry<Object, Object> e : props.entrySet()) { + String key = (String) e.getKey(); + if (key.startsWith(prefix)) { + String value = (String) e.getValue(); + String mapKey = key.substring(prefix.length()); + configMap.put(mapKey, value); + } + } + return configMap; + } + + /** + * Exposes the command line arguments in a more object-oriented style. + * <p> + * Please check that an option was specified (using the various is*Specified() methods) before using its value. + */ + private static class Arguments { + private final boolean localMode; + private final boolean modeSpecified; + private final Level logLevel; + private final boolean logLevelSpecified; + + public Arguments(String[] args) throws LaunchException { + boolean local = false; + boolean explicitMode = false; + Level level = null; + boolean explicitLogLevel = false; + for (int index = 0; index < args.length; index++) { + if (args[index].equals(Constants.AGENT_ARGUMENT_LOGLEVEL)) { + index++; + if (index < args.length) { + try { + level = Level.parse(args[index].toUpperCase()); + explicitLogLevel = true; + } catch (IllegalArgumentException iae) { + throw new LaunchException("Invalid argument for " + Constants.AGENT_ARGUMENT_LOGLEVEL, iae); + } + } else { + throw new LaunchException("Missing argument for " + Constants.AGENT_ARGUMENT_LOGLEVEL); + } + } else if (args[index].equals(Constants.AGENT_ARGUMENT_LOCAL)) { + explicitMode = true; + local = true; + } + } + logLevel = level; + logLevelSpecified = explicitLogLevel; + localMode = local; + modeSpecified = explicitMode; + } + + public boolean isModeSpecified() { + return modeSpecified; + } + + public boolean getLocalMode() { + if (!isModeSpecified()) { + throw new IllegalStateException("local mode is not valid"); + } + return localMode; + } + + public boolean isLogLevelSpecified() { + return logLevelSpecified; + } + + public Level getLogLevel() { + if (!isLogLevelSpecified()) { + throw new IllegalStateException("log level not explicitly specified"); + } + return logLevel; + } + } +}
--- a/src/com/redhat/thermostat/backend/Backend.java Tue Dec 06 13:39:50 2011 -0500 +++ b/src/com/redhat/thermostat/backend/Backend.java Tue Dec 06 14:28:07 2011 -0500 @@ -11,42 +11,81 @@ */ public abstract class Backend { + private boolean initialConfigurationComplete = false; protected Storage storage; - public final void setInitialConfiguration(Map<String, String> configMap) { + /** + * + * @param configMap a map containing the settings that this backend has been configured with. + * @throws LaunchException if map contains values that this backend does not accept. + */ + public final void setInitialConfiguration(Map<String, String> configMap) throws BackendLoadException { + if (initialConfigurationComplete) { + throw new BackendLoadException("A backend may only receive intitial configuration once."); + } for (Entry<String, String> e : configMap.entrySet()) { - setConfigurationValue(e.getKey(), e.getValue()); + String key = e.getKey(); + String value = e.getValue(); + try { + setConfigurationValue(key, value); + } catch (IllegalArgumentException iae) { + throw new BackendLoadException("Attempt to set invalid backend configuration for " + getName() + + " backend. Key: " + key + " Value: " + value, iae); + } } + initialConfigurationComplete = true; } - protected abstract void setConfigurationValue(String name, String value); - - - - /** Returns the name of the {@link Backend} */ - public abstract String getName(); - - /** Returns the description of the {@link Backend} */ - public abstract String getDescription(); - - /** Returns the vendor of the {@link Backend} */ - public abstract String getVendor(); - - /** Returns the version of the {@link Backend} */ - public abstract String getVersion(); - - /** - * Returns a map containing the settings of this backend - */ - public abstract Map<String, String> getConfigurationMap(); - protected void setStorage(Storage storage) { this.storage = storage; } /** + * Set the named configuration to the given value. + * @param name + * @param value + * @throws IllegalArgumentException if either the key does not refer to a valid configuration option + * for this backend or the value is not valid for the key + */ + protected abstract void setConfigurationValue(String name, String value); + + /** + * @return the name of the {@link Backend} + */ + public abstract String getName(); + + /** + * @returns the description of the {@link Backend} + */ + public abstract String getDescription(); + + /** + * @return the vendor of the {@link Backend} + */ + public abstract String getVendor(); + + /** + * @return the version of the {@link Backend} + */ + public abstract String getVersion(); + + /** + * @return a map containing the settings of this backend + */ + public abstract Map<String, String> getConfigurationMap(); + + /** + * + * @param key The constant key that corresponds to the desired configuration value + * @return The current value of the configuration value corresponding to the key given. + * @throws IllegalArgumentException if the key does not refer to a valid configuration option for + * this backend + */ + public abstract String getConfigurationValue(String key); + + /** * Activate the {@link Backend}. Based on the current configuration, - * begin pushing data to the Storage layer. If the {@link Backend} is + * begin pushing data to the {@link Storage} layer. If the {@link Backend} is * already active, this method should have no effect * * @return true on success, false if there was an error @@ -64,8 +103,7 @@ public abstract boolean deactivate(); /** - * Returns a boolean indicating if the backend is currently active on this - * host + * @return a boolean indicating whether the backend is currently active on this host */ public abstract boolean isActive();
--- a/src/com/redhat/thermostat/backend/BackendRegistry.java Tue Dec 06 13:39:50 2011 -0500 +++ b/src/com/redhat/thermostat/backend/BackendRegistry.java Tue Dec 06 14:28:07 2011 -0500 @@ -8,7 +8,7 @@ import java.util.logging.Logger; import com.redhat.thermostat.agent.Storage; -import com.redhat.thermostat.agent.config.Configuration; +import com.redhat.thermostat.agent.config.StartupConfiguration; import com.redhat.thermostat.backend.system.SystemBackend; import com.redhat.thermostat.common.utils.LoggingUtils; @@ -22,7 +22,7 @@ private final Map<String, Backend> registeredBackends; - public BackendRegistry(Configuration config, Storage storage) throws BackendLoadException { + public BackendRegistry(StartupConfiguration config, Storage storage) throws BackendLoadException { registeredBackends = new HashMap<String, Backend>(); /*
--- a/src/com/redhat/thermostat/backend/sample/SampleBackend.java Tue Dec 06 13:39:50 2011 -0500 +++ b/src/com/redhat/thermostat/backend/sample/SampleBackend.java Tue Dec 06 14:28:07 2011 -0500 @@ -56,6 +56,11 @@ } @Override + public String getConfigurationValue(String key) { + throw new IllegalArgumentException("SampleBackend does not actually accept any configuration."); + } + + @Override public boolean activate() { currentlyActive = true; return true;
--- a/src/com/redhat/thermostat/backend/system/SystemBackend.java Tue Dec 06 13:39:50 2011 -0500 +++ b/src/com/redhat/thermostat/backend/system/SystemBackend.java Tue Dec 06 14:28:07 2011 -0500 @@ -97,4 +97,10 @@ return (timer != null); } + @Override + public String getConfigurationValue(String key) { + // TODO Auto-generated method stub + return null; + } + }
--- a/src/com/redhat/thermostat/common/Constants.java Tue Dec 06 13:39:50 2011 -0500 +++ b/src/com/redhat/thermostat/common/Constants.java Tue Dec 06 14:28:07 2011 -0500 @@ -6,7 +6,7 @@ */ public class Constants { - public static final String LOGGING_CONFIG = "com.redhat.thermostat.level=ALL"; + public static final String LOG_LEVEL_CONFIG = "com.redhat.thermostat.level="; public static final String AGENT_PROPERTIES_FILE = "config/agent.properties";
--- a/src/com/redhat/thermostat/common/utils/LoggingUtils.java Tue Dec 06 13:39:50 2011 -0500 +++ b/src/com/redhat/thermostat/common/utils/LoggingUtils.java Tue Dec 06 14:28:07 2011 -0500 @@ -6,6 +6,7 @@ import java.util.logging.LogManager; import java.util.logging.Logger; +import com.redhat.thermostat.common.Constants; import com.redhat.thermostat.common.LogFormatter; /** @@ -16,6 +17,8 @@ */ public final class LoggingUtils { + private static Logger root; + private LoggingUtils() { /* should not be instantiated */ } @@ -25,7 +28,7 @@ * works around http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4462908 */ public static Logger resetAndGetRootLogger() { - Logger root = Logger.getLogger(""); + root = Logger.getLogger(""); Handler[] handlers = root.getHandlers(); for (Handler handler : handlers) { root.removeHandler(handler); @@ -39,6 +42,18 @@ return root; } + public static void setGlobalLogLevel(Level level) { + try { + LogManager.getLogManager().readConfiguration(StringUtils.toInputStream(Constants.LOG_LEVEL_CONFIG + level.toString())); + } catch (Exception e) { + if (root != null) { + root.log(Level.WARNING, "Error setting new log level.", e); + } else { + e.printStackTrace(); + } + } + } + /** * Returns an appropriate logger to be used by class klass. */