Mercurial > hg > release > thermostat-0.11
changeset 160:cc759d53b7e9
RFC: Big Refactoring: new tools subproject
Reviewed-by: rkennke, omajid, vanaltj
Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2012-March/000510.html
author | Mario Torre <neugens.limasoftware@gmail.com> |
---|---|
date | Thu, 29 Mar 2012 17:34:20 +0200 |
parents | c03293472933 |
children | 44740832172e |
files | common/pom.xml distribution/config/agent.properties distribution/config/db.properties distribution/pom.xml distribution/scripts/thermostat-agent distribution/scripts/thermostat-db distribution/scripts/thermostat-init-layout tools/pom.xml tools/src/main/java/com/redhat/thermostat/tools/db/DBConfig.java tools/src/main/java/com/redhat/thermostat/tools/db/DBOptionParser.java tools/src/main/java/com/redhat/thermostat/tools/db/DBService.java tools/src/main/java/com/redhat/thermostat/tools/db/DBStartupConfiguration.java |
diffstat | 12 files changed, 857 insertions(+), 94 deletions(-) [+] |
line wrap: on
line diff
--- a/common/pom.xml Thu Mar 29 17:19:01 2012 +0200 +++ b/common/pom.xml Thu Mar 29 17:34:20 2012 +0200 @@ -101,6 +101,11 @@ <artifactId>easymock</artifactId> <version>3.1</version> </dependency> + <dependency> + <groupId>net.sf.jopt-simple</groupId> + <artifactId>jopt-simple</artifactId> + <version>4.3</version> + </dependency> </dependencies> <properties>
--- a/distribution/config/agent.properties Thu Mar 29 17:19:01 2012 +0200 +++ b/distribution/config/agent.properties Thu Mar 29 17:34:20 2012 +0200 @@ -1,43 +1,5 @@ -## Mongo storage configuration -# To be used when agent is running with --local argument -mongod_port=27518 -mongo_launch_script=@project.build.directory@/scripts/localmongo.sh -# To be used when connecting on localhost without --local argument (cluster) -mongos_port=27517 -### Next few settings are used only by the mongo launch script -config_port=27519 -config_url=mongodb://127.0.0.1 -### End section specific to launch script -### Properties needed by client -agent_launch_script=@project.build.directory@/scripts/thermostat-agent -### End properties needed by client -# ## Backend Configuration -# This must be a comma separated list naming the fully qualified class name for -# each backend that should run -backends= -# Backends may also use their name as prefix for backend-specific configuration. -# For example, if backend foo requires a property called bar, then a line -# containing 'foo.bar=baz' should be included. 'foo' in this case should be -# the human-friendly alias for the backend, ie the string returned by the -# getName() method of the class listed in the backends string. -# -# For each backend, there may be a .active property specified. -# ie: for backend 'foo' there should be a 'foo.active = bar' line. 'bar' -# must be a comma separated list including one or more of: -# 'new' - The backend should attempt to attach to any new java process that -# starts. Existing processes should not be instrumented. -# 'all' - The backend should attempt to attach to all existing java -# java processes currently running on the machine. -# '[lvmid]' - One or more Local Virtual Machine IDs may be specified. These -# are equivalent to the Linux process id. This allows for the case -# of specific existing java processes to be instrumented. -# -# Alternatively, you may specify 'none' and the backend will not begin collecting -# from any VM, but will be available to clients who wish to activate it. -# -# If there is no .active property specified, then 'none' is implied. -# -## Sample backend configuration -#sample-backend.active=none -#sample-backend.myconfiguration=property \ No newline at end of file +# This must be a comma separated list naming the backend +# specific backend configurations will be searched under the +# $THERMOSTAT_HOME/backends/[backend_name.properties] +BACKENDS=system
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/distribution/config/db.properties Thu Mar 29 17:34:20 2012 +0200 @@ -0,0 +1,4 @@ +LOCAL=27518 +CLUSTER=27517 +BIND=127.0.0.1 +URL=mongodb://127.0.0.1
--- a/distribution/pom.xml Thu Mar 29 17:19:01 2012 +0200 +++ b/distribution/pom.xml Thu Mar 29 17:34:20 2012 +0200 @@ -139,5 +139,10 @@ <artifactId>thermostat-common</artifactId> <version>${project.version}</version> </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-tools</artifactId> + <version>${project.version}</version> + </dependency> </dependencies> </project>
--- a/distribution/scripts/thermostat-agent Thu Mar 29 17:19:01 2012 +0200 +++ b/distribution/scripts/thermostat-agent Thu Mar 29 17:34:20 2012 +0200 @@ -39,60 +39,20 @@ # Some necessary variables. JAVA_DIR="@java.dir@" JAVA="@java.home@/bin/java" -JCOMMON_JAR="${JAVA_DIR}/jcommon.jar" -MONGO_JAR="${JAVA_DIR}/mongo.jar" -BSON_JAR="${JAVA_DIR}/bson.jar" + +THERMOSTAT_LIBS="${THERMOSTAT_HOME}/libs" + +JCOMMON_JAR="${THERMOSTAT_LIBS}/jcommon.jar" +MONGO_JAR="${THERMOSTAT_LIBS}/mongo.jar" +BSON_JAR="${THERMOSTAT_LIBS}/bson.jar" +JOPT_JAR="${THERMOSTAT_LIBS}/jopt-simple-4.3.jar" TOOLS_JAR="@java.home@/../lib/tools.jar" -AGENT_CLASSPATH="${JCOMMON_JAR}:${MONGO_JAR}:${BSON_JAR}:${TOOLS_JAR}" -# Find the directory where thermostat is installed. -# Note this will not work if there are symlinks to resolve that -# are not full paths. -SOURCE="${BASH_SOURCE[0]}" -while [ -h "$SOURCE" ] ; do SOURCE="$(readlink "$SOURCE")"; done -THERM_DIR=`dirname "$( cd -P "$( dirname "$SOURCE" )" && pwd )"` -# Some other necessary variables. -AGENT_CLASSPATH="${AGENT_CLASSPATH}:${THERM_DIR}/lib/thermostat-agent-@project.version@.jar:${THERM_DIR}/lib/thermostat-common-@project.version@.jar" -AGENT_MAIN="com.redhat.thermostat.agent.Main" - -AGENT_ARGS="--properties ${THERM_DIR}/config/agent.properties" - -function usage { - echo "Usage:" - echo " thermostat-agent <--local|--remote|--cluster>" -} - -function run_agent { - ${JAVA} -cp ${AGENT_CLASSPATH} ${AGENT_MAIN} ${AGENT_ARGS} -} -function run_local { - AGENT_ARGS="${AGENT_ARGS} --local" - run_agent - exit $? -} +SERVICE_CLASSPATH="${JCOMMON_JAR}:${MONGO_JAR}:${BSON_JAR}:${TOOLS_JAR}:${JOPT_JAR}" -function run_remote { - echo "Remote agent not yet supported." - exit -1 -} - -function run_cluster { - echo "Cluster agent not yet supported." - exit -1 -} +THERM_DIR=${THERMOSTAT_LIBS} -if [ $# != 1 ]; then - usage - exit -1 -fi +SERVICE_CLASSPATH="${SERVICE_CLASSPATH}:${THERM_DIR}/thermostat-agent-@project.version@.jar:${THERM_DIR}/thermostat-common-@project.version@.jar:${THERM_DIR}/thermostat-tools-@project.version@.jar" +SERVICE_MAIN="com.redhat.thermostat.agent.AgentService" -if [ $1 = "--local" ]; then - run_local -elif [ $1 = "--remote" ]; then - run_remote -elif [ $1 = "--cluster" ]; then - run_cluster -else - usage - exit -1 -fi +${JAVA} -cp ${SERVICE_CLASSPATH} ${SERVICE_MAIN} $@
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/distribution/scripts/thermostat-db Thu Mar 29 17:34:20 2012 +0200 @@ -0,0 +1,58 @@ +#!/bin/bash +# +# Copyright 2012 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. +# +##################################################################### +# +# Some necessary variables. +JAVA_DIR="@java.dir@" +JAVA="@java.home@/bin/java" + +THERMOSTAT_LIBS="${THERMOSTAT_HOME}/libs" + +JCOMMON_JAR="${THERMOSTAT_LIBS}/jcommon.jar" +MONGO_JAR="${THERMOSTAT_LIBS}/mongo.jar" +BSON_JAR="${THERMOSTAT_LIBS}/bson.jar" +JOPT_JAR="${THERMOSTAT_LIBS}/jopt-simple-4.3.jar" +TOOLS_JAR="@java.home@/../lib/tools.jar" + +SERVICE_CLASSPATH="${JCOMMON_JAR}:${MONGO_JAR}:${BSON_JAR}:${TOOLS_JAR}:${JOPT_JAR}" + +THERM_DIR=${THERMOSTAT_LIBS} + +SERVICE_CLASSPATH="${SERVICE_CLASSPATH}:${THERM_DIR}/thermostat-agent-@project.version@.jar:${THERM_DIR}/thermostat-common-@project.version@.jar:${THERM_DIR}/thermostat-tools-@project.version@.jar" +SERVICE_MAIN="com.redhat.thermostat.tools.db.DBService" + +${JAVA} -cp ${SERVICE_CLASSPATH} ${SERVICE_MAIN} $@
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/distribution/scripts/thermostat-init-layout Thu Mar 29 17:34:20 2012 +0200 @@ -0,0 +1,76 @@ +#!/bin/bash +# +# Copyright 2012 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. +# +##################################################################### +# +# Some necessary variables. +if [ "$THERMOSTAT_HOME" = "" ]; then + echo "THERMOSTAT_HOME not set!" + +else + THERMOSTAT_STORAGE="${THERMOSTAT_HOME}/storage/db" + THERMOSTAT_LOG="${THERMOSTAT_HOME}/storage/log" + THERMOSTAT_PID="${THERMOSTAT_HOME}/storage/run" + THERMOSTAT_BACKEND="${THERMOSTAT_HOME}/backends/system" + THERMOSTAT_BIN="${THERMOSTAT_HOME}/bin" + THERMOSTAT_AGENT_LOG="${THERMOSTAT_HOME}/agent/log" + THERMOSTAT_AGENT_RUN="${THERMOSTAT_HOME}/agent/run" + THERMOSTAT_LIBS="${THERMOSTAT_HOME}/libs" + + echo "creating $THERMOSTAT_STORAGE" + mkdir -p $THERMOSTAT_STORAGE + + echo "creating $THERMOSTAT_LOG" + mkdir -p $THERMOSTAT_LOG + + echo "creating $THERMOSTAT_PID" + mkdir -p $THERMOSTAT_PID + + echo "creating $THERMOSTAT_BACKEND" + mkdir -p $THERMOSTAT_BACKEND + + echo "creating $THERMOSTAT_BIN" + mkdir -p $THERMOSTAT_BIN + + echo "creating $THERMOSTAT_AGENT_LOG" + mkdir -p $THERMOSTAT_AGENT_LOG + + echo "creating $THERMOSTAT_AGENT_RUN" + mkdir -p $THERMOSTAT_AGENT_RUN + + echo "creating $THERMOSTAT_LIBS" + mkdir -p $THERMOSTAT_LIBS +fi
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/pom.xml Thu Mar 29 17:34:20 2012 +0200 @@ -0,0 +1,80 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + + Copyright 2012 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. + +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat</artifactId> + <version>0.2-SNAPSHOT</version> + <relativePath>..</relativePath> + </parent> + + <artifactId>thermostat-tools</artifactId> + <packaging>jar</packaging> + + <name>Thermostat Tools</name> + + <dependencies> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>4.10</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.mockito</groupId> + <artifactId>mockito-core</artifactId> + <version>1.9.0</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-common</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>com.redhat.thermostat</groupId> + <artifactId>thermostat-agent</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> + +</project>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/src/main/java/com/redhat/thermostat/tools/db/DBConfig.java Thu Mar 29 17:34:20 2012 +0200 @@ -0,0 +1,48 @@ +/* + * Copyright 2012 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.tools.db; + +/** + * Set of configuration option that the {@link DBService} understands. + */ +enum DBConfig { + + BIND, + LOCAL, + CLUSTER, + URL, +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/src/main/java/com/redhat/thermostat/tools/db/DBOptionParser.java Thu Mar 29 17:34:20 2012 +0200 @@ -0,0 +1,160 @@ +/* + * Copyright 2012 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.tools.db; + +import java.io.IOException; +import java.util.List; + +import joptsimple.OptionParser; +import joptsimple.OptionSet; + +import com.redhat.thermostat.common.config.InvalidConfigurationException; +import com.redhat.thermostat.common.config.ThermostatOptionParser; +import com.redhat.thermostat.tools.ApplicationState; + +class DBOptionParser implements ThermostatOptionParser { + + private boolean quiet; + + private DBStartupConfiguration configuration; + + private List<String> args; + private OptionParser parser; + + private DBArgs serviceAction; + + private boolean dryRun; + + DBOptionParser(DBStartupConfiguration configuration, List<String> args) { + this.args = args; + this.configuration = configuration; + parser = new OptionParser(); + } + + @Override + public void parse() throws InvalidConfigurationException { + + parser.accepts(DBArgs.START.option, DBArgs.START.description); + parser.accepts(DBArgs.STOP.option, DBArgs.STOP.description); + + parser.accepts(DBArgs.DRY.option, DBArgs.DRY.description); + + parser.accepts(DBArgs.HELP.option, DBArgs.HELP.description); + parser.accepts(DBArgs.QUIET.option, DBArgs.QUIET.description); + + OptionSet options = parser.parse(args.toArray(new String[0])); + if (!options.hasOptions() || options.has(DBArgs.HELP.option)) { + displayHelp(); + return; + } + + if (options.has(DBArgs.START.option)) { + serviceAction = DBArgs.START; + } else if (options.has(DBArgs.STOP.option)) { + serviceAction = DBArgs.STOP; + + } else { + throw new InvalidConfigurationException("either --start or --stop must be given"); + } + + if (options.has(DBArgs.DRY.option)) { + dryRun = true; + } + + if (options.has(DBArgs.QUIET.option)) { + quiet = true; + } + + // leave at the end, since it depends on the previous settings + String url = configuration.getUrl(); + long port = configuration.getLocalPort(); + configuration.setLocal(true); + if (options.has(DBArgs.CLUSTER.option)) { + port = configuration.getClusterPort(); + configuration.setLocal(false); + } + configuration.setDBConnectionString(url + ":" + port); + } + + boolean isDryRun() { + return dryRun; + } + + @Override + public void displayHelp() { + + if (quiet) return; + + try { + System.out.println("Module [DBService]"); + parser.printHelpOn(System.out); + } catch (IOException ignore) {} + } + + ApplicationState getAction() { + return serviceAction.state; + } + + static enum DBArgs { + + CLUSTER("cluster", "launch the db in cluster mode, if not specified, " + + "local mode is the default", ApplicationState.NONE), + + DRY("dry-run", "run the service in dry run mode", ApplicationState.NONE), + + HELP("help", "print this usage help", ApplicationState.HELP), + + START("start", "start the database", ApplicationState.START), + STOP("stop", "stop the database", ApplicationState.STOP), + + QUIET("quiet", "don't produce any output", ApplicationState.NONE); + + private String option; + private String description; + private ApplicationState state; + + DBArgs(String option, String description, ApplicationState state) { + this.option = option; + this.description = description; + this.state = state; + } + } + + boolean isQuiet() { + return quiet; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/src/main/java/com/redhat/thermostat/tools/db/DBService.java Thu Mar 29 17:34:20 2012 +0200 @@ -0,0 +1,277 @@ +/* + * Copyright 2012 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.tools.db; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Properties; + +import com.redhat.thermostat.common.config.ConfigUtils; +import com.redhat.thermostat.common.config.InvalidConfigurationException; +import com.redhat.thermostat.common.utils.LoggedExternalProcess; +import com.redhat.thermostat.tools.BasicApplication; + +public class DBService extends BasicApplication { + + private DBStartupConfiguration configuration; + private DBOptionParser parser; + + private static final String [] MONGO_BASIC_ARGS = { + "mongod", "--quiet", "--fork", "--nojournal", "--noauth", "--bind_ip" + }; + + private static final String [] MONGO_SHUTDOWN_ARGS = { + "mongod", "--shutdown", "--dbpath" + }; + + @Override + public void parseArguments(List<String> args) throws InvalidConfigurationException { + + this.configuration = new DBStartupConfiguration(); + // configs, read everything that is in the configs + File propertyFile = ConfigUtils.getStorageConfigurationFile(); + if (!propertyFile.exists()) { + throw new InvalidConfigurationException("can't access database configuration file " + + propertyFile); + } + readAndSetProperties(propertyFile); + + parser = new DBOptionParser(configuration, args); + parser.parse(); + + } + + private void readAndSetProperties(File propertyFile) throws InvalidConfigurationException { + + Properties properties = new Properties(); + try { + properties.load(new FileInputStream(propertyFile)); + + } catch (IOException e) { + throw new InvalidConfigurationException(e); + } + + if (properties.containsKey(DBConfig.LOCAL.name())) { + String port = (String) properties.get(DBConfig.LOCAL.name()); + int localPort = Integer.parseInt(port); + configuration.setLocalPort(localPort); + } else { + throw new InvalidConfigurationException(DBConfig.LOCAL + " property missing"); + } + + if (properties.containsKey(DBConfig.CLUSTER.name())) { + String port = (String) properties.get(DBConfig.CLUSTER.name()); + int localPort = Integer.parseInt(port); + configuration.setClusterPort(localPort); + } else { + throw new InvalidConfigurationException(DBConfig.CLUSTER + " property missing"); + } + + if (properties.containsKey(DBConfig.URL.name())) { + String url = (String) properties.get(DBConfig.URL.name()); + configuration.setUrl(url); + } else { + throw new InvalidConfigurationException(DBConfig.URL + " property missing"); + } + + if (properties.containsKey(DBConfig.BIND.name())) { + String ip = (String) properties.get(DBConfig.BIND.name()); + configuration.setBindIP(ip); + } else { + throw new InvalidConfigurationException(DBConfig.BIND + " property missing"); + } + } + + private void startService() throws IOException, InterruptedException { + + String pid = checkPid(); + if (pid != null) { + String message = "cannot start server " + configuration.getDBPath() + + ", found pid file rom previous run, please, cleanup"; + display(message); + notifyFail(); + return; + } + + List<String> commands = new ArrayList<>(Arrays.asList(MONGO_BASIC_ARGS)); + + // check that the db directory exist + display("starting storage server..."); + + commands.add(configuration.getBindIP()); + + commands.add("--dbpath"); + commands.add(configuration.getDBPath().getCanonicalPath()); + + commands.add("--logpath"); + commands.add(configuration.getLogFile().getCanonicalPath()); + + commands.add("--pidfilepath"); + commands.add(configuration.getPidFile().getCanonicalPath()); + + commands.add("--port"); + if (configuration.isLocal()) { + commands.add(Long.toString(configuration.getLocalPort())); + } else { + commands.add(Long.toString(configuration.getClusterPort())); + } + + LoggedExternalProcess process = new LoggedExternalProcess(commands); + int status = process.runAndReturnResult(); + if (status == 0) { + pid = checkPid(); + if (pid == null) status = -1; + } + + if (status == 0) { + display("server listening on ip: " + configuration.getDBConnectionString()); + display("log file is here: " + configuration.getLogFile()); + display("pid: " + pid); + notifySuccess(); + + } else { + + String message = "cannot start server " + configuration.getDBPath() + + ", exit status: " + status + + ". Please check that your configuration is valid"; + display(message); + notifyFail(); + } + } + + private String checkPid() { + String pid = null; + // check the pid to be sure + File pidfile = configuration.getPidFile(); + Charset charset = Charset.defaultCharset(); + if (pidfile.exists()) { + try (BufferedReader reader = Files.newBufferedReader(pidfile.toPath(), charset)) { + pid = reader.readLine(); + if (pid == null || pid.isEmpty()) { + pid = null; + } + } catch (IOException ignore) { + ignore.printStackTrace(); + pid = null; + } + } + + return pid; + } + + private void stopService() throws IOException, InterruptedException, InvalidConfigurationException { + check(); + + List<String> commands = new ArrayList<>(Arrays.asList(MONGO_SHUTDOWN_ARGS)); + commands.add(configuration.getDBPath().getCanonicalPath()); + + LoggedExternalProcess process = new LoggedExternalProcess(commands); + int status = process.runAndReturnResult(); + if (status == 0) { + display("server shutdown complete: " + configuration.getDBPath()); + display("log file is here: " + configuration.getLogFile()); + notifySuccess(); + + } else { + // TODO: check the pid and see if it's running or not + // perhaps was already down + String message = "cannot shutdown server " + configuration.getDBPath() + + ", exit status: " + status + + ". Please check that your configuration is valid"; + display(message); + notifyFail(); + } + } + + @Override + public void run() { + + if (parser.isDryRun()) return; + + try { + switch (parser.getAction()) { + case START: + startService(); + break; + case STOP: + stopService(); + break; + } + } catch (Exception e) { + // TODO: exception should be at least logged + notifyFail(); + } + } + + private void check() throws InvalidConfigurationException { + if (!configuration.getDBPath().exists() || + !configuration.getLogFile().getParentFile().exists() || + !configuration.getPidFile().getParentFile().exists()) + { + throw new InvalidConfigurationException("database directories do not exist..."); + } + } + + @Override + public void printHelp() { + parser.displayHelp(); + } + + @Override + public DBStartupConfiguration getConfiguration() { + return configuration; + } + + private void display(String message) { + if (!parser.isQuiet()) { + System.out.println(message); + } + } + + public static void main(String[] args) throws InvalidConfigurationException { + DBService service = new DBService(); + service.parseArguments(Arrays.asList(args)); + service.run(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tools/src/main/java/com/redhat/thermostat/tools/db/DBStartupConfiguration.java Thu Mar 29 17:34:20 2012 +0200 @@ -0,0 +1,128 @@ +/* + * Copyright 2012 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.tools.db; + +import java.io.File; + +import com.redhat.thermostat.common.config.ConfigUtils; +import com.redhat.thermostat.common.config.InvalidConfigurationException; +import com.redhat.thermostat.common.config.StartupConfiguration; + +class DBStartupConfiguration implements StartupConfiguration { + + private File dbPath; + private File logFile; + private File pidFile; + + private long localPort; + private long clusterPort; + + private String url; + + private String dbConnectionString; + + private String ip; + + private boolean local; + + public DBStartupConfiguration() throws InvalidConfigurationException { + dbPath = ConfigUtils.getStorageDirectory(); + logFile = ConfigUtils.getStorageLogFile(); + pidFile = ConfigUtils.getStoragePidFile(); + } + + public File getDBPath() { + return dbPath; + } + + public File getLogFile() { + return logFile; + } + + public File getPidFile() { + return pidFile; + } + + void setLocalPort(long localPort) { + this.localPort = localPort; + } + + public long getLocalPort() { + return localPort; + } + + public long getClusterPort() { + return clusterPort; + } + + void setClusterPort(long clusterPort) { + this.clusterPort = clusterPort; + } + + void setUrl(String url) { + this.url = url; + } + + public String getUrl() { + return url; + } + + void setDBConnectionString(String dbConnectionString) { + this.dbConnectionString = dbConnectionString; + } + + @Override + public String getDBConnectionString() { + return dbConnectionString; + } + + void setBindIP(String ip) { + this.ip = ip; + } + + public String getBindIP() { + return ip; + } + + void setLocal(boolean local) { + this.local = local; + } + + public boolean isLocal() { + return local; + } +} \ No newline at end of file