modules/common/cassandra-common-itests/src/main/java/org/rhq/cassandra/CCMTestNGListener.java | 36 -- modules/common/cassandra-common/pom.xml | 4 modules/common/cassandra-common/src/main/java/org/rhq/cassandra/BootstrapDeployer.java | 18 - modules/common/cassandra-common/src/main/java/org/rhq/cassandra/CassandraClusterManager.java | 171 ++++++++++ modules/common/cassandra-common/src/main/java/org/rhq/cassandra/DeploymentOptions.java | 6 modules/common/cassandra-common/src/main/resources/module/main/module.xml | 2 modules/enterprise/server/appserver/src/main/dev-resources/bin/rhq-ccm.sh | 3 7 files changed, 203 insertions(+), 37 deletions(-)
New commits: commit caa034bdc6acc65ce0b0d871a3cf5348b679bd6e Author: John Sanda jsanda@redhat.com Date: Thu Dec 20 16:45:36 2012 -0500
initial commit for the new CassandraClusterManager
As its name implies CassandraClusterManager (CCM) encapsulates the functionality for managing an embedded cluster. The rhq-ccm.sh script which is executed by the installer in the dev-container now invokes CCM. CCMTestNGListener has been refactored to delegate to CCM. BootstrapDeployer is now just an implementation detail.
diff --git a/modules/common/cassandra-common-itests/src/main/java/org/rhq/cassandra/CCMTestNGListener.java b/modules/common/cassandra-common-itests/src/main/java/org/rhq/cassandra/CCMTestNGListener.java index 750145a..0d6d26f 100644 --- a/modules/common/cassandra-common-itests/src/main/java/org/rhq/cassandra/CCMTestNGListener.java +++ b/modules/common/cassandra-common-itests/src/main/java/org/rhq/cassandra/CCMTestNGListener.java @@ -49,6 +49,8 @@ public class CCMTestNGListener implements IInvokedMethodListener {
private final Log log = LogFactory.getLog(CCMTestNGListener.class);
+ private CassandraClusterManager ccm; + @Override public void beforeInvocation(IInvokedMethod invokedMethod, ITestResult testResult) { Method method = invokedMethod.getTestMethod().getConstructorOrMethod().getMethod(); @@ -87,19 +89,13 @@ public class CCMTestNGListener implements IInvokedMethodListener { deploymentOptions.setNumNodes(numNodes); deploymentOptions.setUsername(annotation.username()); deploymentOptions.setPassword(annotation.password()); - try { - deploymentOptions.load(); - } catch (IOException e) { - throw new RuntimeException("Unable to load deployment options.", e); - } - - BootstrapDeployer deployer = new BootstrapDeployer(); - deployer.setDeploymentOptions(deploymentOptions);
- deployer.deploy(); + ccm = new CassandraClusterManager(deploymentOptions); + List<File> nodeDirs = ccm.installCluster(); + ccm.startCluster(nodeDirs);
ClusterInitService clusterInitService = new ClusterInitService(); - List<CassandraNode> cassandraHosts = getCassandraHosts(deployer.getCassandraHosts()); + List<CassandraNode> cassandraHosts = getCassandraHosts(ccm.getHostNames());
if (annotation.waitForClusterToStart()) { clusterInitService.waitForClusterToStart(cassandraHosts); @@ -116,8 +112,8 @@ public class CCMTestNGListener implements IInvokedMethodListener { clusterInitService.waitForSchemaAgreement("rhq", cassandraHosts); }
- String[] hostNames = getHostNames(deployer.getCassandraHosts()); - SchemaManager schemaManager = new SchemaManager(annotation.username(), annotation.password(), hostNames); + SchemaManager schemaManager = new SchemaManager(annotation.username(), annotation.password(), + ccm.getHostNames().toArray(new String[] {})); if (!schemaManager.schemaExists()) { schemaManager.createSchema(); } @@ -145,23 +141,13 @@ public class CCMTestNGListener implements IInvokedMethodListener { return Long.parseLong(writer.getBuffer().toString()); }
- private List<CassandraNode> getCassandraHosts(String hosts) { + private List<CassandraNode> getCassandraHosts(List<String> hostNames) { List<CassandraNode> cassandraHosts = new ArrayList<CassandraNode>();
- for (String s : hosts.split(",")) { - String[] params = s.split(":"); - cassandraHosts.add(new CassandraNode(params[0], Integer.parseInt(params[1]))); - + for (String hostName : hostNames) { + cassandraHosts.add(new CassandraNode(hostName, 9160)); } return cassandraHosts; }
- private String[] getHostNames(String hosts) { - List<String> hostNames = new ArrayList<String>(); - for (String s : hosts.split(",")) { - String[] params = s.split(":"); - hostNames.add(params[0]); - } - return hostNames.toArray(new String[hostNames.size()]); - } } diff --git a/modules/common/cassandra-common/pom.xml b/modules/common/cassandra-common/pom.xml index c2a7e22..a3d1918 100644 --- a/modules/common/cassandra-common/pom.xml +++ b/modules/common/cassandra-common/pom.xml @@ -191,10 +191,6 @@ <groupId>${project.groupId}</groupId> <artifactId>rhq-core-plugin-api</artifactId> </artifactItem> - <!--<artifactItem>--> - <!--<groupId>org.apache.cassandra</groupId>--> - <!--<artifactId>cassandra-clientutil</artifactId>--> - <!--</artifactItem>--> <artifactItem> <groupId>org.apache.cassandra</groupId> <artifactId>cassandra-thrift</artifactId> diff --git a/modules/common/cassandra-common/src/main/java/org/rhq/cassandra/BootstrapDeployer.java b/modules/common/cassandra-common/src/main/java/org/rhq/cassandra/BootstrapDeployer.java index 0bda778..73015c7 100644 --- a/modules/common/cassandra-common/src/main/java/org/rhq/cassandra/BootstrapDeployer.java +++ b/modules/common/cassandra-common/src/main/java/org/rhq/cassandra/BootstrapDeployer.java @@ -35,8 +35,10 @@ import java.io.IOException; import java.io.InputStream; import java.math.BigInteger; import java.util.ArrayList; +import java.util.Collections; import java.util.Date; import java.util.HashSet; +import java.util.LinkedList; import java.util.List; import java.util.Properties; import java.util.Set; @@ -81,19 +83,20 @@ public class BootstrapDeployer { return hosts.toString(); }
- public void deploy() throws CassandraException { + public List<File> deploy() throws CassandraException { Set<String> ipAddresses = calculateLocalIPAddresses(deploymentOptions.getNumNodes()); File clusterDir = new File(deploymentOptions.getClusterDir()); File installedMarker = new File(clusterDir, ".installed");
if (isClusterInstalled()) { - return; + return Collections.emptyList(); }
FileUtil.purge(clusterDir, false);
File bundleZipeFile = null; File bundleDir = null; + List<File> nodeDirs = new LinkedList<File>();
try { deploymentOptions.load(); @@ -105,6 +108,7 @@ public class BootstrapDeployer { int jmxPort = 7200 + i; String address = getLocalIPAddress(i + 1); File nodeBasedir = new File(clusterDir, "node" + i); + nodeDirs.add(nodeBasedir);
Properties props = new Properties(); props.put("cluster.name", "rhq"); @@ -137,10 +141,10 @@ public class BootstrapDeployer { props.put("rhq.cassandra.authorizer", deploymentOptions.getAuthorizer());
doLocalDeploy(props, bundleDir); - startNode(nodeBasedir); - if (i == 0) { - waitForNodeToStart(10, address); - } +// startNode(nodeBasedir); +// if (i == 0) { +// waitForNodeToStart(10, address); +// } } FileUtil.writeFile(new ByteArrayInputStream(new byte[] {0}), installedMarker); } catch (IOException e) { @@ -154,6 +158,8 @@ public class BootstrapDeployer { FileUtil.purge(bundleDir, true); } } + + return nodeDirs; }
public static void main(String[] args) { diff --git a/modules/common/cassandra-common/src/main/java/org/rhq/cassandra/CassandraClusterManager.java b/modules/common/cassandra-common/src/main/java/org/rhq/cassandra/CassandraClusterManager.java new file mode 100644 index 0000000..6b6fd31 --- /dev/null +++ b/modules/common/cassandra-common/src/main/java/org/rhq/cassandra/CassandraClusterManager.java @@ -0,0 +1,171 @@ +/* + * + * * RHQ Management Platform + * * Copyright (C) 2005-2012 Red Hat, Inc. + * * All rights reserved. + * * + * * This program is free software; you can redistribute it and/or modify + * * it under the terms of the GNU General Public License, version 2, as + * * published by the Free Software Foundation, and/or the GNU Lesser + * * General Public License, version 2.1, also as published by the Free + * * Software Foundation. + * * + * * This program 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 and the GNU Lesser General Public License + * * for more details. + * * + * * You should have received a copy of the GNU General Public License + * * and the GNU Lesser General Public License along with this program; + * * if not, write to the Free Software Foundation, Inc., + * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +package org.rhq.cassandra; + +import static java.util.Arrays.asList; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import org.rhq.core.pluginapi.util.ProcessExecutionUtility; +import org.rhq.core.system.OperatingSystemType; +import org.rhq.core.system.ProcessExecution; +import org.rhq.core.system.ProcessExecutionResults; +import org.rhq.core.system.SystemInfo; +import org.rhq.core.system.SystemInfoFactory; +import org.rhq.core.util.PropertiesFileUpdate; +import org.rhq.core.util.StringUtil; + +/** + * @author John Sanda + */ +public class CassandraClusterManager { + + private final Log log = LogFactory.getLog(CassandraClusterManager.class); + + private DeploymentOptions deploymentOptions; + + public CassandraClusterManager() { + this(new DeploymentOptions()); + } + + public CassandraClusterManager(DeploymentOptions deploymentOptions) { + this.deploymentOptions = deploymentOptions; + try { + this.deploymentOptions.load(); + } catch (IOException e) { + log.error("Failed to load deployment options", e); + throw new IllegalStateException("An initialization error occurred.", e); + } + } + + public List<File> installCluster() { + if (log.isDebugEnabled()) { + log.debug("Installing embedded " + deploymentOptions.getNumNodes() + " node cluster to " + + deploymentOptions.getClusterDir()); + } else { + log.info("Installing embedded cluster"); + } + + BootstrapDeployer deployer = new BootstrapDeployer(); + deployer.setDeploymentOptions(deploymentOptions); + try { + return deployer.deploy(); + } catch (CassandraException e) { + String msg = "Failed to install cluster."; + log.error(msg, e); + throw new RuntimeException(msg, e); + } + } + + public void startCluster(List<File> nodeDirs) { + long start = System.currentTimeMillis(); + log.info("Starting embedded cluster"); + for (File dir : nodeDirs) { + ProcessExecutionResults results = startNode(dir); + if (results.getError() != null) { + log.warn("An unexpected error occurred while starting the node at " + dir, results.getError()); + } + } + long end = System.currentTimeMillis(); + log.info("Started embedded cluster in " + (end - start) + " ms"); + } + + private ProcessExecutionResults startNode(File basedir) { + if (log.isDebugEnabled()) { + log.debug("Starting node at " + basedir); + } + File binDir = new File(basedir, "bin"); + File startScript; + SystemInfo systemInfo = SystemInfoFactory.createSystemInfo(); + + if (systemInfo.getOperatingSystemType() == OperatingSystemType.WINDOWS) { + startScript = new File(binDir, "cassandra.bat"); + } else { + startScript = new File(binDir, "cassandra"); + } + + ProcessExecution startScriptExe = ProcessExecutionUtility.createProcessExecution(startScript); + startScriptExe.setArguments(asList("-p", "cassandra.pid")); + + ProcessExecutionResults results = systemInfo.executeProcess(startScriptExe); + if (log.isDebugEnabled()) { + log.debug(startScript + " returned with exit code [" + results.getExitCode() + "]"); + } + + return results; + } + + public void shutdownCluster() { + } + + public List<String> getHostNames() { + List<String> hosts = new ArrayList<String>(deploymentOptions.getNumNodes()); + for (int i = 0; i < deploymentOptions.getNumNodes(); ++i) { + hosts.add("127.0.0." + (i + 1)); + } + return hosts; + } + + public InputStream loadBundle() { + return null; + } + + public static void main(String[] args) { + CassandraClusterManager ccm = new CassandraClusterManager(); + List<File> nodeDirs = ccm.installCluster(); + ccm.startCluster(nodeDirs); + + PropertiesFileUpdate serverPropertiesUpdater = getServerProperties(); + try { + serverPropertiesUpdater.update("rhq.cassandra.cluster.seeds", + StringUtil.collectionToString(ccm.getHostNames())); + } catch (IOException e) { + throw new RuntimeException("An error occurred while trying to update RHQ server properties", e); + } + } + + private static PropertiesFileUpdate getServerProperties() { + String sysprop = System.getProperty("rhq.server.properties-file"); + if (sysprop == null) { + throw new RuntimeException("The required system property [rhq.server.properties] is not defined."); + } + + File file = new File(sysprop); + if (!(file.exists() && file.isFile())) { + throw new RuntimeException("System property [" + sysprop + "] points to in invalid file."); + } + + return new PropertiesFileUpdate(file.getAbsolutePath()); + } + +} diff --git a/modules/common/cassandra-common/src/main/java/org/rhq/cassandra/DeploymentOptions.java b/modules/common/cassandra-common/src/main/java/org/rhq/cassandra/DeploymentOptions.java index 96211f3..098b1b0 100644 --- a/modules/common/cassandra-common/src/main/java/org/rhq/cassandra/DeploymentOptions.java +++ b/modules/common/cassandra-common/src/main/java/org/rhq/cassandra/DeploymentOptions.java @@ -39,6 +39,8 @@ public class DeploymentOptions {
private final Log log = LogFactory.getLog(DeploymentOptions.class);
+ private boolean loaded; + private String bundleFileName; private String bundleName; private String bundleVersion; @@ -60,6 +62,9 @@ public class DeploymentOptions { }
public void load() throws IOException { + if (loaded) { + return; + } InputStream stream = null; try { stream = getClass().getResourceAsStream("/cassandra.properties"); @@ -67,6 +72,7 @@ public class DeploymentOptions { props.load(stream);
init(props); + loaded = true; } catch (IOException e) { log.warn("Unable to load deployment options from cassandra.properties."); log.info("The following error occurred while trying to load options.", e); diff --git a/modules/common/cassandra-common/src/main/resources/module/main/module.xml b/modules/common/cassandra-common/src/main/resources/module/main/module.xml index 2b842ed..0f5af62 100644 --- a/modules/common/cassandra-common/src/main/resources/module/main/module.xml +++ b/modules/common/cassandra-common/src/main/resources/module/main/module.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.0" name="${moduleName}"> - <main-class name="org.rhq.cassandra.BootstrapDeployer"/> + <main-class name="org.rhq.cassandra.CassandraClusterManager"/>
<resources> <resource-root path="${project.build.finalName}.jar"/> diff --git a/modules/enterprise/server/appserver/src/main/dev-resources/bin/rhq-ccm.sh b/modules/enterprise/server/appserver/src/main/dev-resources/bin/rhq-ccm.sh index fd67c48..033ea44 100755 --- a/modules/enterprise/server/appserver/src/main/dev-resources/bin/rhq-ccm.sh +++ b/modules/enterprise/server/appserver/src/main/dev-resources/bin/rhq-ccm.sh @@ -213,7 +213,8 @@ else _RHQ_LOGLEVEL="INFO" fi
-RHQ_CCM_JAVA_OPTS="${RHQ_CCM_JAVA_OPTS} -Djava.awt.headless=true -Drhq.server.properties-file=${RHQ_SERVER_HOME}/bin/rhq-server.properties -Drhq.ccm.logdir=${RHQ_SERVER_HOME}/logs -Drhq.ccm.loglevel=${_RHQ_LOGLEVEL}" +# debugging the logging level now for development/testing +RHQ_CCM_JAVA_OPTS="${RHQ_CCM_JAVA_OPTS} -Djava.awt.headless=true -Drhq.server.properties-file=${RHQ_SERVER_HOME}/bin/rhq-server.properties -Drhq.ccm.logdir=${RHQ_SERVER_HOME}/logs -Drhq.ccm.loglevel=DEBUG"
# Sample JPDA settings for remote socket debugging #RHQ_CCM_JAVA_OPTS="${RHQ_CCM_JAVA_OPTS} -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y"
rhq-commits@lists.fedorahosted.org