modules/plugins/rhq-storage/pom.xml
| 2
modules/plugins/rhq-storage/src/main/java/org/rhq/plugins/storage/StorageNodeComponent.java
| 167 ++++++++++
modules/plugins/rhq-storage/src/main/resources/META-INF/rhq-plugin.xml
| 113 ++++++
3 files changed, 278 insertions(+), 4 deletions(-)
New commits:
commit 7ed79ce3c8ae87d81d09793c9149b9eac3522923
Author: John Sanda <jsanda(a)redhat.com>
Date: Sun Jun 2 07:40:29 2013 -0400
Initial commit for StorageNodeComponent and new addNodeMaintenance operation
So far addNodeMaintenance does the following,
* runs repair on system_auth keyspace
* run cleanup on system_auth keyspace
* run repair on rhq keyspace
* run cleanup on rhq keysapce
Since I could not add an operation to existing resource type definition that we
are extending, I had to copy the top-level type definition from the cassandra
plugin.
diff --git a/modules/plugins/rhq-storage/pom.xml b/modules/plugins/rhq-storage/pom.xml
index 4a88e0f..e3b3282 100644
--- a/modules/plugins/rhq-storage/pom.xml
+++ b/modules/plugins/rhq-storage/pom.xml
@@ -27,7 +27,7 @@
<groupId>${rhq.groupId}</groupId>
<artifactId>rhq-cassandra-plugin</artifactId>
<version>${project.version}</version>
- <scope>provided</scope>
+ <!--<scope>provided</scope>-->
</dependency>
<dependency>
diff --git
a/modules/plugins/rhq-storage/src/main/java/org/rhq/plugins/storage/StorageNodeComponent.java
b/modules/plugins/rhq-storage/src/main/java/org/rhq/plugins/storage/StorageNodeComponent.java
new file mode 100644
index 0000000..9672a37
--- /dev/null
+++
b/modules/plugins/rhq-storage/src/main/java/org/rhq/plugins/storage/StorageNodeComponent.java
@@ -0,0 +1,167 @@
+/*
+ *
+ * * 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.plugins.storage;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.mc4j.ems.connection.EmsConnection;
+
+import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.configuration.PropertyList;
+import org.rhq.core.domain.configuration.PropertyMap;
+import org.rhq.core.domain.configuration.PropertySimple;
+import org.rhq.core.pluginapi.operation.OperationFacet;
+import org.rhq.core.pluginapi.operation.OperationResult;
+import org.rhq.core.util.exception.ThrowableUtil;
+import org.rhq.plugins.cassandra.CassandraNodeComponent;
+import org.rhq.plugins.cassandra.util.KeyspaceService;
+
+/**
+ * @author John Sanda
+ */
+public class StorageNodeComponent extends CassandraNodeComponent implements
OperationFacet {
+
+ private Log log = LogFactory.getLog(StorageNodeComponent.class);
+
+ private static final String SYSTEM_AUTH_KEYSPACE = " system_auth";
+
+ private static final String RHQ_KEYSPACE = "rhq";
+
+ @Override
+ public OperationResult invokeOperation(String name, Configuration parameters) throws
Exception {
+ if (name.equals("addNodeMaintenance")) {
+ return nodeAdded();
+ } else {
+ return super.invokeOperation(name, parameters);
+ }
+ }
+
+ private OperationResult nodeAdded() {
+ EmsConnection emsConnection = getEmsConnection();
+ KeyspaceService keyspaceService = new KeyspaceService(emsConnection);
+ boolean hasErrors = false;
+ OperationResult result = new OperationResult();
+ Configuration resultConfig = result.getComplexResults();
+ PropertyList resultsList = new PropertyList("results");
+
+ OpResult opResult = repairKeyspace(keyspaceService, SYSTEM_AUTH_KEYSPACE);
+ if (!opResult.succeeded) {
+ hasErrors = true;
+ }
+ resultsList.add(toPropertyMap(opResult));
+
+ opResult = cleanupKeyspace(keyspaceService, SYSTEM_AUTH_KEYSPACE);
+ if (!opResult.succeeded) {
+ hasErrors = true;
+ }
+ resultsList.add(toPropertyMap(opResult));
+
+ opResult = repairKeyspace(keyspaceService, RHQ_KEYSPACE);
+ if (!opResult.succeeded) {
+ hasErrors = true;
+ }
+ resultsList.add(toPropertyMap(opResult));
+
+ opResult = cleanupKeyspace(keyspaceService, RHQ_KEYSPACE);
+ if (!opResult.succeeded) {
+ hasErrors = true;
+ }
+ resultsList.add(toPropertyMap(opResult));
+
+ resultConfig.put(resultsList);
+
+ if (hasErrors) {
+ result.setErrorMessage("One or more tasks failed to complete
successfully.");
+ }
+ return result;
+ }
+
+ private OpResult repairKeyspace(KeyspaceService keyspaceService, String keyspace) {
+ OpResult result = new OpResult();
+ result.operation = "repair " + keyspace + " keyspace";
+ try {
+ if (log.isDebugEnabled()) {
+ log.debug("Running repair on " + keyspace + "
keyspace");
+ }
+ long start = System.currentTimeMillis();
+ keyspaceService.repairPrimaryRange(keyspace);
+ long end = System.currentTimeMillis();
+ if (log.isDebugEnabled()) {
+ log.debug("Finsihed repair on " + keyspace + " keyspace in
" + (end - start) + " ms");
+ }
+ result.succeeded = true;
+ } catch (Exception e) {
+ log.error("An error occurred while running repair on " + keyspace,
e);
+ Throwable rootCause = ThrowableUtil.getRootCause(e);
+
+ result.succeeded = false;
+ result.details = "An error occurred while running repair: " +
ThrowableUtil.getStackAsString(rootCause);
+ }
+ return result;
+ }
+
+ private OpResult cleanupKeyspace(KeyspaceService keyspaceService, String keyspace) {
+ OpResult result = new OpResult();
+ result.operation = "cleanup " + keyspace + " keyspace";
+
+ long start;
+ long end;
+ if (log.isDebugEnabled()) {
+ log.debug("Running cleanup on " + keyspace + "
keyspace");
+ }
+ start = System.currentTimeMillis();
+ try {
+ keyspaceService.cleanup(keyspace);
+ end = System.currentTimeMillis();
+ if (log.isDebugEnabled()) {
+ log.debug("Finished cleanup on " + keyspace + " keyspace
in " + (end - start) + " ms");
+ }
+ result.succeeded = true;
+ } catch (Exception e) {
+ log.error("An error occurred while running cleanup on " + keyspace
+ " keyspace", e);
+ Throwable rootCause = ThrowableUtil.getRootCause(e);
+
+ result.succeeded = false;
+ result.details = "An error occurred while running cleanup: " +
ThrowableUtil.getStackAsString(rootCause);
+ }
+ return result;
+ }
+
+ private PropertyMap toPropertyMap(OpResult opResult) {
+ PropertyMap map = new PropertyMap("resultsMap");
+ map.put(new PropertySimple("task", opResult.operation));
+ map.put(new PropertySimple("succeeded", opResult.succeeded));
+ map.put(new PropertySimple("details", opResult.details));
+
+ return map;
+ }
+
+ private static class OpResult {
+ String operation;
+ boolean succeeded;
+ String details;
+ }
+}
diff --git a/modules/plugins/rhq-storage/src/main/resources/META-INF/rhq-plugin.xml
b/modules/plugins/rhq-storage/src/main/resources/META-INF/rhq-plugin.xml
index 0d015ff..11c56c6 100644
--- a/modules/plugins/rhq-storage/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/rhq-storage/src/main/resources/META-INF/rhq-plugin.xml
@@ -11,10 +11,117 @@
<server
name="RHQ Storage Node"
discovery="StorageNodeDiscoveryComponent"
- class="org.rhq.plugins.cassandra.CassandraNodeComponent"
- description="RHQ Storage Node" sourcePlugin="Cassandra"
sourceType="Cassandra Node">
+ class="StorageNodeComponent"
+ description="RHQ Storage Node">
- </server>
+ <subcategories>
+ <subcategory name="Client Request Metrics" description="Client
Request Metrics"/>
+ <subcategory name="Server Request Metrics" description="Server
Request Metrics"/>
+ <subcategory name="Internal Server Metrics" description="Internal
Server Metrics"/>
+ <subcategory name="Database Management Services"
description="Database Management Services"/>
+ <subcategory name="Network Services" description="Network
Services"/>
+ </subcategories>
+
+ <plugin-configuration>
+ <c:simple-property name="connectorAddress" displayName="Manager
URL" default="service:jmx:rmi:///jndi/rmi://localhost:7199/jmxrmi"
+ description="The RMI URL with which to connect to the
Cassandra node (e.g. service:jmx:rmi:///jndi/rmi://localhost:7199/jmxrmi)."/>
+ <c:simple-property name="type" readOnly="true"
default="org.mc4j.ems.connection.support.metadata.J2SE5ConnectionTypeDescriptor"
+ description="The type used to establish the EMS connection
to the Cassandra node."/>
+ <c:simple-property name="username" default="cassandra"
required="true" description="The login username"/>
+ <c:simple-property name="password" default="cassandra"
required="true" type="password" description="The login
password"/>
+ <c:simple-property name="baseDir" displayName="Base
Directory" description="The base directory from which the Cassandra Daemon was
launched." required="false"/>
+ <c:simple-property name="yamlConfiguration" displayName="YAML
Configuration File" description="YAML Configuration File"/>
+ <c:simple-property name="nativeTransportPort" description="The
port on which Cassandra listens for CQL client connections." default="9042"
type="integer"/>
+ <c:simple-property name="host" description="The host on which
cassandra listens to CQL client connections" default="localhost"/>
+ <c:simple-property name="clusterName" description="Cluster
name" default="localhost"/>
+ <c:simple-property name="authenticator" required="true"
default="org.apache.cassandra.auth.AllowAllAuthenticator"
description="Cassandra client authenticator">
+ <c:property-options>
+ <c:option name="org.apache.cassandra.auth.AllowAllAuthenticator"
value="org.apache.cassandra.auth.AllowAllAuthenticator"/>
+ <c:option name="org.apache.cassandra.auth.PasswordAuthenticator"
value="org.apache.cassandra.auth.PasswordAuthenticator"/>
+ </c:property-options>
+ </c:simple-property>
+ <c:simple-property name="commandLine" required="false"
type="string" description="the command line of the JVM at the time it was
discovered - only used by JVMs with type Local; if the command line of the JVM changes,
this property's value will need to be updated accordingly in order for RHQ to connect
to the JVM"/>
+ </plugin-configuration>
+
+ <process-scan name="CassandraDaemon"
query="process|basename|match=^java.*,arg|org.apache.cassandra.service.CassandraDaemon|match=.*"/>
+
+ <operation name="shutdown" description="Shuts down the Cassandra
daemon">
+ <results>
+ <c:simple-property name="shutdownResult" description="Shutdown
the Cassandra daemon"/>
+ </results>
+ </operation>
+
+ <operation name="start" description="Starts the Cassandra
daemon">
+ <results>
+ <c:simple-property name="startResult" description="Start the
Cassandra daemon"/>
+ </results>
+ </operation>
+ <operation name="restart" description="Restarts the Cassandra
daemon">
+ <results>
+ <c:simple-property name="startResult" description="Restart the
Cassandra daemon"/>
+ </results>
+ </operation>
+
+ <operation name="addNodeMaintenance">
+ <results>
+ <c:list-property name="results">
+ <c:map-property name="resultsMap">
+ <c:simple-property name="task" type="string"/>
+ <c:simple-property name="succeeded"
type="boolean"/>
+ <c:simple-property name="details" type="string"/>
+ </c:map-property>
+ </c:list-property>
+ </results>
+ </operation>
+
+ <server name="Cassandra Server JVM"
+ sourcePlugin="JMX" sourceType="JMX Server"
+
discovery="org.rhq.plugins.jmx.EmbeddedJMXServerDiscoveryComponent"
+ class="org.rhq.plugins.jmx.EmbeddedJMXServerComponent"
+ description="The JVM of the Cassandra node"
+ singleton="true">
+
+ <plugin-configuration>
+ <c:simple-property name="type" type="string"
default="PARENT" readOnly="true" description="The EMS connection
type for this JVM (cannot be modified)"/>
+ </plugin-configuration>
+ </server>
+
+ <service name="StorageProxy" sourcePlugin="Cassandra"
sourceType="StorageProxy" singleton="true"/>
+
+ <service name="StorageService" sourcePlugin="Cassandra"
sourceType="StorageService" singleton="true"/>
+
+ <service name="CommitLog" sourcePlugin="Cassandra"
sourceType="CommitLog" singleton="true"/>
+
+ <service name="ReadTimeouts" sourcePlugin="Cassandra"
sourceType="ReadTimeouts" singleton="true"/>
+
+ <service name="ReadUnavailables" sourcePlugin="Cassandra"
sourceType="ReadUnavailables" singleton="true"/>
+ <service name="WriteTimeouts" sourcePlugin="Cassandra"
sourceType="WriteTimeouts" singleton="true"/>
+ <service name="WriteUnavailables" sourcePlugin="Cassandra"
sourceType="WriteUnavailables" singleton="true"/>
+
+ <service name="CompactionManager" sourcePlugin="Cassandra"
sourceType="CompactionManager" singleton="true"/>
+
+ <service name="CacheService" sourcePlugin="Cassandra"
sourceType="CacheService" singleton="true"/>
+
+ <service name="ConfigurableStages" sourcePlugin="Cassandra"
sourceType="ConfigurableStages" singleton="true"/>
+
+ <service name="EnabledStages" sourcePlugin="Cassandra"
sourceType="EnabledStages" singleton="true"/>
+
+ <service name="ConfigurableInternalServerMetrics"
sourcePlugin="Cassandra"
sourceType="ConfigurableInternalServerMetrics"
+ singleton="true"/>
+
+ <service name="EnabledInternalServerMetrics"
sourcePlugin="Cassandra" sourceType="EnabledInternalServerMetrics"
+ singleton="true"/>
+
+ <service name="FailureDetector" sourcePlugin="Cassandra"
sourceType="FailureDetector" singleton="true"/>
+
+ <service name="Gossiper" sourcePlugin="Cassandra"
sourceType="Gossiper" singleton="true"/>
+
+ <service name="StreamingService" sourcePlugin="Cassandra"
sourceType="StreamingService" singleton="true"/>
+
+ <service name="MessagingService" sourcePlugin="Cassandra"
sourceType="MessagingService" singleton="true"/>
+
+ <service name="Keyspace" sourcePlugin="Cassandra"
sourceType="Keyspace"/>
+ </server>
</plugin>
Show replies by date