[rhq] modules/enterprise
by John Sanda
modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/cloud/StorageNodeManagerBeanTest.java | 20 ---
modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/test/AbstractEJB3Test.java | 7 +
modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/test/StrippedDownStartupBean.java | 58 +++-------
modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/test/StrippedDownStartupBeanPreparation.java | 43 +++++++
4 files changed, 71 insertions(+), 57 deletions(-)
New commits:
commit 9f02dd2fa407518ba64ecad2409f368364d017f4
Author: John Sanda <jsanda(a)redhat.com>
Date: Tue Jul 9 15:26:04 2013 -0400
fixing broken tests caused from change to persist seed nodes during install
Previously seed storage nodes were persisted at start up. That has been changed
so that seed nodes are now persisted by the installer. This caused the storage
client subsystem to fail to properly initialize. Seed nodes are now persisted
at deployment time (for tests) by StrippedDownStartupBeanPreparation.
diff --git a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/cloud/StorageNodeManagerBeanTest.java b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/cloud/StorageNodeManagerBeanTest.java
index 4e04447..78c0cff 100644
--- a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/cloud/StorageNodeManagerBeanTest.java
+++ b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/cloud/StorageNodeManagerBeanTest.java
@@ -148,26 +148,6 @@ public class StorageNodeManagerBeanTest extends AbstractEJB3Test {
// this method is still needed, because tests calls SLSB methods that are executed in their own transaction
// and the rollback performed once the TransactionCallback is finished just wont clean everything
- // We can only filter on the group name because the resource type info might not exist in the test
- // database.
- ResourceGroupCriteria criteria = new ResourceGroupCriteria();
- criteria.addFilterName(STORAGE_NODE_GROUP_NAME);
-
- List<ResourceGroup> groups = resourceGroupManager.findResourceGroupsByCriteria(subjectManager.getOverlord(),
- criteria);
-
- if (!groups.isEmpty()) {
- resourceGroupManager.deleteResourceGroup(subjectManager.getOverlord(), groups.get(0).getId());
- }
-
-// for (ResourceGroup group : groups) {
-// if (group.getName().equals(STORAGE_NODE_GROUP_NAME)) {
-// resourceGroupManager.deleteResourceGroup(subjectManager.getOverlord(), group.getId());
-// break;
-// }
-// }
-
-
// pause the currently running TX
Transaction runningTransaction = getTransactionManager().suspend();
getTransactionManager().begin();
diff --git a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/test/AbstractEJB3Test.java b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/test/AbstractEJB3Test.java
index ea7ac6b..9ddba97 100644
--- a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/test/AbstractEJB3Test.java
+++ b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/test/AbstractEJB3Test.java
@@ -37,6 +37,7 @@ import java.util.List;
import java.util.Properties;
import java.util.regex.Pattern;
+import javax.ejb.EJB;
import javax.management.MBeanServer;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
@@ -87,6 +88,7 @@ import org.rhq.enterprise.server.plugin.pc.ServerPluginService;
import org.rhq.enterprise.server.plugin.pc.ServerPluginServiceMBean;
import org.rhq.enterprise.server.scheduler.SchedulerService;
import org.rhq.enterprise.server.scheduler.SchedulerServiceMBean;
+import org.rhq.enterprise.server.storage.StorageClientManagerBean;
import org.rhq.enterprise.server.util.LookupUtil;
import org.rhq.test.AssertUtils;
import org.rhq.test.MatchResult;
@@ -114,6 +116,9 @@ public abstract class AbstractEJB3Test extends Arquillian {
@ArquillianResource
protected InitialContext initialContext;
+ @EJB
+ private StorageClientManagerBean storageClientManager;
+
// We originally (in 4.2.3 days) ran these tests as "unit" tests in the server/jar module using
// the embedded container. With Arquillian it makes sense to actually deploy an EAR because
// we need a way to deploy dependent ears needed to support the server/jar classes. But
@@ -518,7 +523,7 @@ public abstract class AbstractEJB3Test extends Arquillian {
}
}
}
-
+ storageClientManager.init();
beforeMethod();
beforeMethod(method);
diff --git a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/test/StrippedDownStartupBean.java b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/test/StrippedDownStartupBean.java
index 2e654ab..58273d8 100644
--- a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/test/StrippedDownStartupBean.java
+++ b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/test/StrippedDownStartupBean.java
@@ -20,21 +20,26 @@
package org.rhq.enterprise.server.test;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Properties;
+import static org.rhq.enterprise.server.cloud.StorageNodeManagerLocal.STORAGE_NODE_GROUP_NAME;
+
+import java.util.List;
import javax.ejb.EJB;
import javax.ejb.Singleton;
+import javax.ejb.TransactionAttribute;
+import javax.ejb.TransactionAttributeType;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.rhq.core.domain.cloud.Server;
import org.rhq.core.domain.cloud.StorageNode;
+import org.rhq.core.domain.criteria.ResourceGroupCriteria;
+import org.rhq.core.domain.resource.group.ResourceGroup;
import org.rhq.enterprise.server.RHQConstants;
-import org.rhq.enterprise.server.storage.StorageClientManagerBean;
+import org.rhq.enterprise.server.auth.SubjectManagerLocal;
import org.rhq.enterprise.server.core.StartupBean;
import org.rhq.enterprise.server.naming.NamingHack;
+import org.rhq.enterprise.server.resource.group.ResourceGroupManagerLocal;
/**
* This is a replacement for the fullblown {@link StartupBean} of the actual RHQ server.
@@ -45,9 +50,6 @@ public class StrippedDownStartupBean {
public static final String RHQ_SERVER_NAME_PROPERTY = "rhq.server.high-availability.name";
- @EJB
- StorageClientManagerBean storageClientManager;
-
@PersistenceContext(unitName = RHQConstants.PERSISTENCE_UNIT_NAME)
private EntityManager entityManager;
@@ -55,46 +57,30 @@ public class StrippedDownStartupBean {
NamingHack.bruteForceInitialContextFactoryBuilder();
}
+ @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void init() {
secureNaming();
- // TODO Find a better way to load system properties
- // Cassandra connection info is currently obtained from system properties. I have
- // yet to find a good way to set system properties for the deployment under test.
- // https://github.com/arquillian/arquillian-showcase/tree/master/extensions/...
- // might be worth looking at.
- //
- // jsanda
- loadCassandraConnectionProps();
- storageClientManager.init();
}
/**
- * Purges the test server and any storage nodes created during server initialization
+ * <p>
+ * Purges the storage node resource group, test server, and any storage nodes created during server initialization
* from a prior test run.
+ * </p>
+ * <p>
+ * Note that the storage node group deletion simply removes the entity from the rhq_resource_group table. At this
+ * point in the deployment, {@link ResourceGroupManagerLocal#deleteResourceGroup(org.rhq.core.domain.auth.Subject, int)}
+ * cannot be used; therefore, any test that added storage node resources to the group should take care of removing
+ * them as well.
+ * </p>
*/
public void purgeTestServerAndStorageNodes() {
+ entityManager.createQuery("DELETE FROM " + ResourceGroup.class.getName() + " WHERE name = :storageNodeGroup")
+ .setParameter("storageNodeGroup", STORAGE_NODE_GROUP_NAME)
+ .executeUpdate();
entityManager.createQuery("DELETE FROM " + StorageNode.class.getName()).executeUpdate();
entityManager.createQuery("DELETE FROM " + Server.class.getName() + " WHERE name = :serverName")
.setParameter("serverName", TestConstants.RHQ_TEST_SERVER_NAME)
.executeUpdate();
}
-
- public void loadCassandraConnectionProps() {
- InputStream stream = null;
- try {
- stream = getClass().getResourceAsStream("/cassandra-test.properties");
- Properties props = new Properties();
- props.load(stream);
-
- // DO NOT use System.setProperties(Properties). I previously tried that and it
- // caused some arquillian deployment exception.
- //
- // jsanda
- System.setProperty("rhq.cassandra.username", props.getProperty("rhq.cassandra.username"));
- System.setProperty("rhq.cassandra.password", props.getProperty("rhq.cassandra.password"));
- System.setProperty("rhq.cassandra.seeds", props.getProperty("rhq.cassandra.seeds"));
- } catch (IOException e) {
- throw new RuntimeException(("Failed to load cassandra-test.properties"));
- }
- }
}
diff --git a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/test/StrippedDownStartupBeanPreparation.java b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/test/StrippedDownStartupBeanPreparation.java
index c272afe..5f67888 100644
--- a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/test/StrippedDownStartupBeanPreparation.java
+++ b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/test/StrippedDownStartupBeanPreparation.java
@@ -20,6 +20,10 @@
package org.rhq.enterprise.server.test;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.ejb.EJB;
@@ -28,11 +32,15 @@ import javax.ejb.Startup;
import javax.ejb.Timeout;
import javax.ejb.TimerConfig;
import javax.ejb.TimerService;
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.rhq.core.domain.cloud.Server;
+import org.rhq.core.domain.cloud.StorageNode;
+import org.rhq.enterprise.server.RHQConstants;
import org.rhq.enterprise.server.cloud.instance.ServerManagerLocal;
/**
@@ -56,6 +64,9 @@ public class StrippedDownStartupBeanPreparation {
@EJB
private ServerManagerLocal serverManager;
+ @PersistenceContext(unitName = RHQConstants.PERSISTENCE_UNIT_NAME)
+ private EntityManager entityManager;
+
@Resource
private TimerService timerService; // needed to schedule our startup bean init call
@@ -66,6 +77,8 @@ public class StrippedDownStartupBeanPreparation {
startupBean.purgeTestServerAndStorageNodes();
createTestServer();
+ loadCassandraConnectionProps();
+ createStorageNodes();
}
/**
@@ -86,11 +99,41 @@ public class StrippedDownStartupBeanPreparation {
System.setProperty(TestConstants.RHQ_SERVER_NAME_PROPERTY, TestConstants.RHQ_TEST_SERVER_NAME);
}
+ private void createStorageNodes() {
+ String[] seedsInfo = System.getProperty("rhq.cassandra.seeds").split(",");
+ for (String seedInfo : seedsInfo) {
+ StorageNode storageNode = new StorageNode();
+ storageNode.parseNodeInformation(seedInfo);
+ storageNode.setOperationMode(StorageNode.OperationMode.INSTALLED);
+ entityManager.persist(storageNode);
+ }
+ }
+
+ public void loadCassandraConnectionProps() {
+ InputStream stream = null;
+ try {
+ stream = getClass().getResourceAsStream("/cassandra-test.properties");
+ Properties props = new Properties();
+ props.load(stream);
+
+ // DO NOT use System.setProperties(Properties). I previously tried that and it
+ // caused some arquillian deployment exception.
+ //
+ // jsanda
+ System.setProperty("rhq.cassandra.username", props.getProperty("rhq.cassandra.username"));
+ System.setProperty("rhq.cassandra.password", props.getProperty("rhq.cassandra.password"));
+ System.setProperty("rhq.cassandra.seeds", props.getProperty("rhq.cassandra.seeds"));
+ } catch (IOException e) {
+ throw new RuntimeException(("Failed to load cassandra-test.properties"));
+ }
+ }
+
@Timeout
public void initializeServer() throws RuntimeException {
try {
log.info("Initializing the testing RHQ deployment");
this.startupBean.init();
+ log.info("Initialization complete");
} catch (Throwable t) {
// do NOT allow exceptions to bubble out of our method because then
// the EJB container would simply re-trigger the timer and call us again
10 years, 11 months
[rhq] 2 commits - modules/core
by Jiri Kremser
modules/core/domain/src/main/java/org/rhq/core/domain/cloud/StorageNode.java | 5
modules/core/domain/src/test/java/org/rhq/core/domain/cloud/StorageNodeTest.java | 111 ++++++++++
2 files changed, 111 insertions(+), 5 deletions(-)
New commits:
commit 4dc0ec58446ea00d82a13e3fd797f4ff05580cb6
Author: Jirka Kremser <jkremser(a)redhat.com>
Date: Tue Jul 9 19:03:57 2013 +0200
Unit test for StorageNode entity.
diff --git a/modules/core/domain/src/test/java/org/rhq/core/domain/cloud/StorageNodeTest.java b/modules/core/domain/src/test/java/org/rhq/core/domain/cloud/StorageNodeTest.java
new file mode 100644
index 0000000..ce4dbbd
--- /dev/null
+++ b/modules/core/domain/src/test/java/org/rhq/core/domain/cloud/StorageNodeTest.java
@@ -0,0 +1,111 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2013 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.core.domain.cloud;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import org.rhq.core.domain.cloud.StorageNode.OperationMode;
+
+@Test
+public class StorageNodeTest {
+ public void testEquals() {
+ StorageNode localhost1 = new StorageNode();
+ assert localhost1 != null;
+ assert !localhost1.equals(null);
+
+ StorageNode localhost2 = new StorageNode();
+ assert localhost2 != null;
+ assert localhost1.equals(localhost2);
+ assert localhost2.equals(localhost1);
+
+ localhost1.setAddress("127.0.0.1");
+ assert !localhost1.equals(localhost2);
+ assert !localhost2.equals(localhost1);
+
+ localhost2.setAddress("127.0.0.1");
+ assert localhost1.equals(localhost2);
+ assert localhost2.equals(localhost1);
+
+ StorageNode localhost3 = new StorageNode(42);
+ localhost3.setAddress("sn.com");
+ assert !localhost3.equals(null);
+ assert !localhost3.equals(localhost1);
+ assert localhost3.hashCode() != localhost1.hashCode();
+ assert localhost2.hashCode() == localhost1.hashCode();
+
+ localhost3.setAddress("127.0.0.1");
+ assert localhost3.equals(localhost1);
+ assert localhost3.hashCode() == localhost1.hashCode();
+ }
+
+ public void testParseNodeInformation1() {
+ StorageNode localhost1 = new StorageNode();
+ localhost1.parseNodeInformation("127.0.0.1|1234|4321");
+ assert "127.0.0.1".equals(localhost1.getAddress());
+ assert localhost1.getJmxPort() == 1234;
+ assert localhost1.getCqlPort() == 4321;
+ assert "service:jmx:rmi:///jndi/rmi://127.0.0.1:1234/jmxrmi".equals(localhost1.getJMXConnectionURL());
+
+ localhost1.setOperationMode(OperationMode.INSTALLED);
+ assert localhost1.getOperationMode() == OperationMode.INSTALLED;
+ assert localhost1.getOperationMode().getMessage() != null;
+ assert localhost1.getOperationMode().getMessage() != null;
+ localhost1.setMtime(42);
+ assert localhost1.getMtime() == 42;
+
+ StorageNode localhost2 = new StorageNode();
+ localhost2.parseNodeInformation("127.0.0.1|1235|5321");
+ assert localhost1.equals(localhost2);
+ assert !localhost1.getJMXConnectionURL().equals(localhost2.getJMXConnectionURL());
+ }
+
+ public void testParseNodeInformation2() {
+ StorageNode localhost1 = new StorageNode();
+ try {
+ localhost1.parseNodeInformation("127.0.0.1|1234|4321|foo");
+ Assert.fail("The exception (IllegalArgumentException) should be thrown!");
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ localhost1.parseNodeInformation("127.0.0.1|1234");
+ Assert.fail("The exception (IllegalArgumentException) should be thrown!");
+ } catch (IllegalArgumentException e) {
+ }
+ try {
+ localhost1.parseNodeInformation("127.0.0.1|aaaa|4321");
+ Assert.fail("The exception (NumberFormatException) should be thrown!");
+ } catch (NumberFormatException e) {
+ }
+ try {
+ localhost1.parseNodeInformation("127.0.0.1|1234|bbbb");
+ Assert.fail("The exception (NumberFormatException) should be thrown!");
+ } catch (NumberFormatException e) {
+ }
+ try {
+ localhost1.parseNodeInformation(null);
+ Assert.fail("The exception (NullPointerException) should be thrown!");
+ } catch (NullPointerException e) {
+ }
+ }
+}
commit a10a8a6c63cf8f980cf0e657d5349ed42547c2c2
Author: Jirka Kremser <jkremser(a)redhat.com>
Date: Tue Jul 9 18:55:45 2013 +0200
StorageNode: hashCode() should be consistent with equals().
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/cloud/StorageNode.java b/modules/core/domain/src/main/java/org/rhq/core/domain/cloud/StorageNode.java
index 1d39bcd..14043db 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/cloud/StorageNode.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/cloud/StorageNode.java
@@ -238,7 +238,6 @@ public class StorageNode implements Serializable {
public int hashCode() {
final int prime = 31;
int result = 1;
- result = prime * result + (int) (ctime ^ (ctime >>> 32));
result = prime * result + ((address == null) ? 0 : address.hashCode());
return result;
}
@@ -255,10 +254,6 @@ public class StorageNode implements Serializable {
final StorageNode other = (StorageNode) obj;
- //if (ctime != other.ctime) {
- // return false;
- //}
-
if (address == null) {
if (other.address != null) {
return false;
10 years, 11 months
[rhq] modules/core
by Jiri Kremser
modules/core/domain/intentional-api-changes-since-4.8.0.xml | 3 +
modules/core/domain/src/main/java/org/rhq/core/domain/cloud/StorageNodeLoadComposite.java | 18 ++++++++++
2 files changed, 21 insertions(+)
New commits:
commit 19facfd1591445b491f155303e083d731dd06f61
Author: Jirka Kremser <jkremser(a)redhat.com>
Date: Tue Jul 9 18:25:09 2013 +0200
Fixing the api-checks jenkins build. Adding the setDiskSpacePercentageUsed() and getDiskSpacePercentageUsed() methods back to StorageNodeLoadComposite, and marking them as deprecated.
diff --git a/modules/core/domain/intentional-api-changes-since-4.8.0.xml b/modules/core/domain/intentional-api-changes-since-4.8.0.xml
new file mode 100644
index 0000000..f21a45f
--- /dev/null
+++ b/modules/core/domain/intentional-api-changes-since-4.8.0.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0"?>
+<differences>
+</differences>
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/cloud/StorageNodeLoadComposite.java b/modules/core/domain/src/main/java/org/rhq/core/domain/cloud/StorageNodeLoadComposite.java
index 0913f1d..80bfdd6 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/cloud/StorageNodeLoadComposite.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/cloud/StorageNodeLoadComposite.java
@@ -113,6 +113,24 @@ public class StorageNodeLoadComposite implements Serializable {
public void setHeapPercentageUsed(MeasurementAggregateWithUnits heapPercentageUsed) {
this.heapPercentageUsed = heapPercentageUsed;
}
+
+ /**
+ * @deprecated use {@link #getPartitionDiskUsedPercentage() getPartitionDiskUsedPercentage()} instead
+ *
+ * @return partitionDiskUsedPercentage
+ */
+ public MeasurementAggregateWithUnits getDiskSpacePercentageUsed() {
+ return getPartitionDiskUsedPercentage();
+ }
+
+ /**
+ * @deprecated use {@link #setPartitionDiskUsedPercentage() setPartitionDiskUsedPercentage()} instead
+ *
+ * @param partitionDiskUsedPercentage
+ */
+ public void setDiskSpacePercentageUsed(MeasurementAggregateWithUnits partitionDiskUsedPercentage) {
+ setPartitionDiskUsedPercentage(partitionDiskUsedPercentage);
+ }
/**
* @return A computed metric for the percentage of disk space used on the partition that contains the SSTables.
10 years, 11 months
[rhq] 2 commits - modules/enterprise modules/integration-tests
by Heiko W. Rupp
modules/enterprise/server/appserver/src/main/resources/etc/RHQ-mib.txt | 94 ++++++----
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSender.java | 13 -
modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpInfo.java | 12 +
modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpSender.java | 10 -
modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpTrapSender.java | 42 +++-
modules/enterprise/server/plugins/alert-snmp/src/main/resources/META-INF/rhq-serverplugin.xml | 42 +++-
modules/enterprise/server/plugins/alert-snmp/src/test/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpInfoTest.java | 24 ++
modules/integration-tests/rest-api/pom.xml | 2
8 files changed, 173 insertions(+), 66 deletions(-)
New commits:
commit 4381d307b87bb8ca5e7cba265633aa585adcf27f
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Tue Jul 9 17:13:00 2013 +0200
BZ 966294 Fix mib file and related code. Also fix some other smaller issues.
diff --git a/modules/enterprise/server/appserver/src/main/resources/etc/RHQ-mib.txt b/modules/enterprise/server/appserver/src/main/resources/etc/RHQ-mib.txt
index ced6071..5586ac0 100644
--- a/modules/enterprise/server/appserver/src/main/resources/etc/RHQ-mib.txt
+++ b/modules/enterprise/server/appserver/src/main/resources/etc/RHQ-mib.txt
@@ -3,39 +3,51 @@ RHQ-MIB DEFINITIONS ::= BEGIN
IMPORTS
MODULE-IDENTITY, OBJECT-TYPE, NOTIFICATION-TYPE, snmpModules, enterprises
FROM SNMPv2-SMI
- coldStart
- FROM SNMPv2-MIB
OBJECT-GROUP, NOTIFICATION-GROUP, MODULE-COMPLIANCE
FROM SNMPv2-CONF
DisplayString
FROM SNMPv2-TC;
rhqMIB MODULE-IDENTITY
- LAST-UPDATED "201112200000Z"
+ LAST-UPDATED "201307020000Z"
ORGANIZATION "RHQ-Project"
CONTACT-INFO "http://www.jboss.org/rhq"
DESCRIPTION
"The MIB module for RHQ alerts.
This file is part of the RHQ management platform
- Copyright (C) 2005-2012 Red Hat, Inc.
+ Copyright (C) 2005-2013 Red Hat, Inc.
All rights reserved.
"
- REVISION "200807110000Z"
- DESCRIPTION "Initial version"
- REVISION "201010180000Z"
- DESCRIPTION "Better trap support"
+ REVISION "201307020000Z"
+ DESCRIPTION "Bug fixes"
REVISION "201112200000Z"
DESCRIPTION "Also emit resource lineage"
+ REVISION "201010180000Z"
+ DESCRIPTION "Better trap support"
+ REVISION "200807110000Z"
+ DESCRIPTION "Initial version"
::= { snmpModules 1 }
+-- 1.3.6.1.4.1.18016
jboss OBJECT IDENTIFIER ::= {enterprises 18016 }
+-- 1.3.6.1.4.1.18016.2
rhq OBJECT IDENTIFIER ::= {jboss 2 }
+-- 1.3.6.1.4.1.18016.2.1
alert OBJECT IDENTIFIER ::= {rhq 1 }
+-- 1.3.6.1.4.1.18016.2.1.2
+alertNotifications OBJECT IDENTIFIER ::= {rhq 2}
+
+-- 1.3.6.1.4.1.18016.2.3
+rhqServer OBJECT IDENTIFIER ::= {rhq 3}
+
+
+-- 1.3.6.1.4.1.18016.2.1.2.0
+alertNotifPrefix OBJECT IDENTIFIER ::= {alertNotifications 0 }
alertName OBJECT-TYPE
SYNTAX DisplayString (SIZE (0..255))
@@ -93,28 +105,10 @@ alertHierarchy OBJECT-TYPE
STATUS current
DESCRIPTION
"The hierarchy of the resource that triggered the alert"
- ::= { alert 6 }
-
--- conformance information
-
-snmpMIBConformance
- OBJECT IDENTIFIER ::= { rhqMIB 2 }
-
-snmpMIBCompliances
- OBJECT IDENTIFIER ::= { snmpMIBConformance 1 }
-snmpMIBGroups OBJECT IDENTIFIER ::= { snmpMIBConformance 2 }
-
--- compliance statements
-
-snmpBasicCompliance MODULE-COMPLIANCE
- STATUS current
- DESCRIPTION "TODO"
- MODULE
- MANDATORY-GROUPS { alertGroup, trapGroup }
-
- ::= { snmpMIBCompliances 2 }
+ ::= { alert 7 }
-alertGroup OBJECT-GROUP
+-- 1.3.6.1.4.1.18016.2.1.2.0.1
+alertNotification NOTIFICATION-TYPE
OBJECTS { alertName,
alertResourceName,
alertPlatformName,
@@ -124,12 +118,46 @@ alertGroup OBJECT-GROUP
alertHierarchy }
STATUS current
DESCRIPTION "A collection of objects providing information about an alert"
- ::= { snmpMIBGroups 1 }
+ ::= { alertNotifPrefix 1 }
+
+
+-- conformance information
+
+rhqMIBConformance OBJECT IDENTIFIER ::= { rhqMIB 2 }
+rhqTraps OBJECT IDENTIFIER ::= { rhqMIB 3 }
+rhqTrapPrefix OBJECT IDENTIFIER ::= { rhqTraps 0 }
-trapGroup NOTIFICATION-GROUP
- NOTIFICATIONS { coldStart }
+rhqMIBCompliances OBJECT IDENTIFIER ::= { rhqMIBConformance 1 }
+rhqMIBGroups OBJECT IDENTIFIER ::= { rhqMIBConformance 2 }
+
+-- compliance statements
+
+rhqMibBasicCompliance MODULE-COMPLIANCE
+ STATUS current
+ DESCRIPTION "Module compliance definition for the RHQ-MIB extension module"
+ MODULE
+ MANDATORY-GROUPS { rhqAlertGroup, rhqNotificationGroup }
+
+ ::= { rhqMIBCompliances 2 }
+
+rhqAlertGroup OBJECT-GROUP
+ OBJECTS { alertName,
+ alertResourceName,
+ alertPlatformName,
+ alertCondition,
+ alertSeverity,
+ alertUrl,
+ alertHierarchy
+ }
+ STATUS current
+ DESCRIPTION "A collection of entries for a notifications for alerts"
+ ::= { rhqMIBGroups 2 }
+
+rhqNotificationGroup NOTIFICATION-GROUP
+ NOTIFICATIONS { alertNotification }
STATUS current
DESCRIPTION "A collection of notifications for alerts"
- ::= { snmpMIBGroups 2 }
+ ::= { rhqMIBGroups 3 }
+
END
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSender.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSender.java
index 88c140f..bda7f99 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSender.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/AlertSender.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2009 Red Hat, Inc.
+ * Copyright (C) 2005-2013 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -13,8 +13,8 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * 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.enterprise.server.plugin.pc.alert;
@@ -30,7 +30,6 @@ import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.Property;
import org.rhq.core.domain.configuration.PropertyMap;
import org.rhq.core.domain.configuration.PropertySimple;
-import org.rhq.enterprise.server.plugin.pc.ControlResults;
import org.rhq.enterprise.server.plugin.pc.ServerPluginComponent;
import org.rhq.enterprise.server.plugin.pc.ServerPluginEnvironment;
@@ -103,7 +102,7 @@ public abstract class AlertSender<T extends ServerPluginComponent> {
/**
* Validates the alert and extra parameters. The results should be initialized with the current
- * parameters of this alert sender and the erroneous properties should have their
+ * parameters of this alert sender and the erroneous properties should have their
* {@link Property#getErrorMessage() error messages} set.
* <p>
* The implementation is free to change (add/update/delete) properties in either of the configurations
@@ -111,14 +110,14 @@ public abstract class AlertSender<T extends ServerPluginComponent> {
* further processed in an alert sender specific way before they get stored into the database.
* <p>
* The default implementation makes no changes to the configurations.
- *
+ *
* @param subject the subject requesting the changes in the configuration
* @return the validation results
*/
public AlertSenderValidationResults validateAndFinalizeConfiguration(Subject subject) {
return new AlertSenderValidationResults(alertParameters, extraParameters);
}
-
+
private String printProperty(Property property) {
if (property instanceof PropertySimple) {
return ((PropertySimple) property).getStringValue();
diff --git a/modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpInfo.java b/modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpInfo.java
index c92daae..7b174cc 100644
--- a/modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpInfo.java
+++ b/modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpInfo.java
@@ -79,6 +79,18 @@ public class SnmpInfo {
return new SnmpInfo(host, port, oid, trapOid);
}
+ protected static SnmpInfo load(Configuration configuration, Configuration preferences) {
+ String host = configuration.getSimpleValue(PARAM_HOST, null); // optional
+ if (host==null || host.isEmpty()) {
+ host = preferences.getSimpleValue("defaultTargetHost",null);
+ }
+ String port = configuration.getSimpleValue(PARAM_PORT, DEFAULT_PORT);
+ String oid = configuration.getSimpleValue(PARAM_VARIABLE_BINDING_PREFIX, null); // required
+ String trapOid = configuration.getSimpleValue(PARAM_TRAP_OID, null);
+ return new SnmpInfo(host, port, oid, trapOid);
+
+ }
+
@Override
public String toString() {
String hostString = (host == null ? "UnknownHost" : host);
diff --git a/modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpSender.java b/modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpSender.java
index 5c6d1e7..521589d 100644
--- a/modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpSender.java
+++ b/modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpSender.java
@@ -45,7 +45,7 @@ public class SnmpSender extends AlertSender {
private AlertManagerLocal alertManager;
/**
- * Default constructor needed for instanciation by server plugin container
+ * Default constructor needed for instantiation by server plugin container
*/
public SnmpSender() {
this(LookupUtil.getResourceManager(), LookupUtil.getAlertManager());
@@ -59,7 +59,7 @@ public class SnmpSender extends AlertSender {
@Override
public SenderResult send(Alert alert) {
- SnmpInfo info = SnmpInfo.load(alertParameters);
+ SnmpInfo info = SnmpInfo.load(alertParameters, preferences);
if (info.error != null) {
return SenderResult.getSimpleFailure(info.error);
}
@@ -75,8 +75,8 @@ public class SnmpSender extends AlertSender {
String platformName = lineage.get(0).getName();
String conditions = alertManager.prettyPrintAlertConditions(alert, false);
String alertUrl = alertManager.prettyPrintAlertURL(alert);
-
-
+
+
String hierarchy = getResourceHierarchyAsString(lineage);
Date bootTime = new Date(); // TODO: want to use LookupUtil.getCoreServer().getBootTime() but ServiceMBean is not visible
@@ -102,7 +102,7 @@ public class SnmpSender extends AlertSender {
@Override
public String previewConfiguration() {
- SnmpInfo info = SnmpInfo.load(alertParameters);
+ SnmpInfo info = SnmpInfo.load(alertParameters, preferences);
return info.toString();
}
}
diff --git a/modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpTrapSender.java b/modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpTrapSender.java
index 2556b38..ea3d985 100644
--- a/modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpTrapSender.java
+++ b/modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpTrapSender.java
@@ -76,7 +76,9 @@ import org.rhq.core.util.StringUtil;
/**
* @author Ian Springer
+ * @author Heiko W. Rupp
*/
+@SuppressWarnings("unused")
public class SnmpTrapSender implements PDUFactory {
public static final int DEFAULT = 0;
private static final String UDP_TRANSPORT = "udp";
@@ -104,7 +106,10 @@ public class SnmpTrapSender implements PDUFactory {
private TimeTicks sysUpTime = new TimeTicks(0);
- private OID trapOID = SnmpConstants.coldStart;
+ public static final OID enterpriseSpecificTrap =
+ new OID(new int[] { 1,3,6,1,6,3,1,1,5,6 });
+
+ private OID trapOID = enterpriseSpecificTrap;
private PDUv1 v1TrapPDU = new PDUv1();
@@ -338,14 +343,33 @@ public class SnmpTrapSender implements PDUFactory {
return octetString;
}
- private static Address createAddress(Configuration properties) {
- // TODO: Make transport configurable (ips, 09/12/07).
+ private Address createAddress(Configuration properties) {
String host = properties.getSimpleValue("host",null);
- String portS = properties.getSimpleValue("port","162");
+ String portS = properties.getSimpleValue("port",null);
+
+
+ if (host==null) {
+ String tmp = systemConfig.getSimpleValue("defaultTargetHost",null);
+ if ((tmp != null) && (tmp.length() > 0)) {
+ host=tmp;
+ }
+ }
+
+ if (portS==null) {
+ String tmp = systemConfig.getSimpleValue("defaultPort","162");
+ if ((tmp != null) && (tmp.length() > 0)) {
+ portS = tmp;
+ }
+ }
Integer port = Integer.valueOf(portS);
+ if (port==0) {
+ port = 162; // just to make sure
+ }
+
+ String transport = systemConfig.getSimpleValue("transport","UDP");
+
- final String transport = UDP_TRANSPORT;
String address = host + "/" + port;
if (transport.equalsIgnoreCase(UDP_TRANSPORT)) {
return new UdpAddress(address);
@@ -357,7 +381,7 @@ public class SnmpTrapSender implements PDUFactory {
}
protected String getVariableBindings(PDU response) {
- StringBuffer strBuf = new StringBuffer();
+ StringBuilder strBuf = new StringBuilder();
for (int i = 0; i < response.size(); i++) {
VariableBinding vb = response.get(i);
strBuf.append(vb.toString());
@@ -473,7 +497,7 @@ public class SnmpTrapSender implements PDUFactory {
String variableBindingPrefix = alertParameters.getSimpleValue(SnmpInfo.PARAM_VARIABLE_BINDING_PREFIX, null);
- // TODO add a request id and a timestamp
+ // request id and a timestamp are added below in setSysUpTime..
this.address = createAddress(alertParameters);
// bind the alert definitions name on the oid set in the alert
@@ -532,7 +556,7 @@ public class SnmpTrapSender implements PDUFactory {
delta = now - bootTime.getTime();
} else
delta = 0;
- setSysUpTime(new TimeTicks(delta / 1000)); // TT is 100th of a second TODO : fix this !!!
+ setSysUpTime(new TimeTicks(delta / 100)); // TT is 100th of a second
}
@@ -571,6 +595,8 @@ public class SnmpTrapSender implements PDUFactory {
this.authProtocol = AuthMD5.ID;
} else if (tmp.equals("SHA")) {
this.authProtocol = AuthSHA.ID;
+ } else if (tmp.equals("none")) {
+ this.authProtocol=null;
} else {
throw new IllegalStateException("SNMP authentication protocol unsupported: " + tmp);
}
diff --git a/modules/enterprise/server/plugins/alert-snmp/src/main/resources/META-INF/rhq-serverplugin.xml b/modules/enterprise/server/plugins/alert-snmp/src/main/resources/META-INF/rhq-serverplugin.xml
index 83a55e9..3f7a35c 100644
--- a/modules/enterprise/server/plugins/alert-snmp/src/main/resources/META-INF/rhq-serverplugin.xml
+++ b/modules/enterprise/server/plugins/alert-snmp/src/main/resources/META-INF/rhq-serverplugin.xml
@@ -25,15 +25,29 @@
</c:property-options>
</c:simple-property>
- <c:simple-property name="trapOid" displayName="Trap OID" description="OID for the trap sent" type="string" />
+ <c:simple-property name="defaultTargetHost" displayName="Default trap target host" required="false"/>
+ <c:simple-property name="defaultPort" displayName="Default trap target port" required="false" type="integer"
+ default="162" defaultValue="162"/>
+ <c:simple-property name="transport" defaultValue="UDP">
+ <c:property-options allowCustomValue="false">
+ <c:option value="UDP" name="UDP"/>
+ <c:option value="TCP" name="TCP"/>
+ </c:property-options>
+ </c:simple-property>
+
+ <c:simple-property name="trapOid" displayName="Trap OID" description="OID for the trap sent" type="string"
+ default="1.3.6.1.4.1.18016.2.1.2.0.1"/>
<c:simple-property name="community" type="string" default="public" description="Community - v1 and v2c only" required="false"/>
<c:group name="1" displayName="SNMP version 1 properties" hiddenByDefault="true" >
- <c:simple-property name="engineId" required="false"/>
- <c:simple-property name="genericId" required="false"/>
- <c:simple-property name="enterpriseOid" required="false"/>
- <c:simple-property name="specificId" required="false"/>
- <c:simple-property name="agentAddress" description="Address of our SNMP agent" required="false"/>
+
+ <c:simple-property name="genericId" required="false" default="6" type="integer"
+ description="Set the generic trap type. Default is 6 (=Enterprise specific)."/>
+ <c:simple-property name="enterpriseOid" required="false" default="1.3.6.1.4.1.18016.2.3"
+ description="OID of the sender, identifies the type of managed object generating the trap. Default is enterprise.jboss.rhq.rhqServer"/>
+ <c:simple-property name="specificId" required="false" default="0" type="integer"
+ description="Enterprise-specific ID of the trap. If this is set, the generic ID must be set to 6."/>
+ <c:simple-property name="agentAddress" description="Address of our SNMP agent (=the RHQ server)" required="false"/>
</c:group>
<!--
<c:group name="2c" displayName="SNMP version 2c properties" hiddenByDefault="true">
@@ -41,14 +55,15 @@
</c:group>
-->
<c:group name="3" displayName="SNMP version 3 properties" hiddenByDefault="true">
- <c:simple-property name="authProtocol" type="string" default="MD5">
+ <c:simple-property name="authProtocol" type="string" default="MD5"
+ description="Authorization protocol to use. If no Auth Passphrase is given, this must be set to 'none'.">
<c:property-options>
<c:option value="none"/>
<c:option value="MD5"/>
<c:option value="SHA"/>
</c:property-options>
</c:simple-property>
- <c:simple-property name="privacyProtocol" default="AES">
+ <c:simple-property name="privacyProtocol" default="AES" description="The privacy protocol to use in conjunction when the auth protocol is set">
<c:property-options>
<c:option value="DES"/>
<c:option value="AES"/>
@@ -56,8 +71,9 @@
<c:option value="AES256"/>
</c:property-options>
</c:simple-property>
+ <c:simple-property name="engineId" required="false"/> <!-- TODO this was not here before, but in v1, where it is wrong -->
<c:simple-property name="targetContext" displayName="Target Context Name" type="string" required="false"/>
- <c:simple-property name="authPassphrase" description="Auto Passphrase is required with autorization enabled" type="password" required="false"/>
+ <c:simple-property name="authPassphrase" description="Auto Passphrase is required with authorization enabled. If this is not set, authProtocol must be not set as well. Length must be > 8." type="password" required="false"/>
<c:simple-property name="privacyPassphrase" description="Privacy Passphrase is required with privacy enabled" type="password" required="false"/>
<c:simple-property name="securityName" type="string" required="false"/>
@@ -71,13 +87,15 @@
<a:plugin-class>SnmpSender</a:plugin-class>
<a:alert-configuration>
- <c:simple-property name="host" type="string" required="true" description="Trap target host"/>
+ <c:simple-property name="host" type="string" required="false" description="Trap target host. Required if not yet set in the
+ sender-wide preferences"/>
<c:simple-property name="port" type="integer" required="false" default="162" description="Trap target port"/>
- <c:simple-property name="oid" displayName="Variable bindings prefix" type="string" required="true">
+ <c:simple-property name="oid" displayName="Variable bindings prefix" type="string" required="true"
+ defaultValue="1.3.6.1.4.1.18016.2.1">
<c:description>
<![CDATA[
<p>RHQ will send alert notification details as a list of variable bindings in the
- SNMP trap PDU.</p>
+ SNMP trap PDU. This OID is the common prefix of those bindings.</p>
<p><strong>Do not confuse this paramater with 'Trap Oid'.</strong></p>
]]>
</c:description>
diff --git a/modules/enterprise/server/plugins/alert-snmp/src/test/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpInfoTest.java b/modules/enterprise/server/plugins/alert-snmp/src/test/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpInfoTest.java
index c46c8b6..97b9a05 100644
--- a/modules/enterprise/server/plugins/alert-snmp/src/test/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpInfoTest.java
+++ b/modules/enterprise/server/plugins/alert-snmp/src/test/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpInfoTest.java
@@ -29,6 +29,7 @@ import static org.testng.Assert.*;
import org.testng.annotations.Test;
import org.rhq.core.domain.configuration.Configuration;
+import org.rhq.core.domain.configuration.PropertySimple;
/**
* @author Thomas Segismont
@@ -69,6 +70,29 @@ public class SnmpInfoTest {
}
@Test
+ public void fallBackToGlobalValues() throws Exception {
+ Configuration configuration = new Configuration();
+ configuration.setSimpleValue(PARAM_VARIABLE_BINDING_PREFIX, "molo");
+
+ Configuration preferences = new Configuration();
+ preferences.put(new PropertySimple("defaultTargetHost","hugo"));
+ SnmpInfo snmpInfo = SnmpInfo.load(configuration,preferences);
+ assertNull(snmpInfo.error, "SnmpInfo#load should not have detected an error");
+ assertEquals(snmpInfo.host, "hugo");
+ assertEquals(snmpInfo.oid, "molo");
+ assertEquals(snmpInfo.port, SnmpInfo.DEFAULT_PORT);
+
+
+ configuration.setSimpleValue(PARAM_HOST, "pipo");
+
+ snmpInfo = SnmpInfo.load(configuration,preferences);
+ assertNull(snmpInfo.error, "SnmpInfo#load should not have detected an error");
+ assertEquals(snmpInfo.host, "pipo");
+ assertEquals(snmpInfo.oid, "molo");
+ assertEquals(snmpInfo.port, SnmpInfo.DEFAULT_PORT);
+ }
+
+ @Test
public void shouldExposeAllParams() throws Exception {
Configuration configuration = new Configuration();
configuration.setSimpleValue(PARAM_HOST, "pipo");
commit 44e927da01ac1d6fb0252c71615c675815787408
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Mon Jul 8 10:01:47 2013 +0200
Bump rest-assured version.
diff --git a/modules/integration-tests/rest-api/pom.xml b/modules/integration-tests/rest-api/pom.xml
index 7b42b45..47bfe18 100644
--- a/modules/integration-tests/rest-api/pom.xml
+++ b/modules/integration-tests/rest-api/pom.xml
@@ -19,7 +19,7 @@
<properties>
<surefire-plugin.version>2.10</surefire-plugin.version>
<jackson.version>1.9.5</jackson.version>
- <rest-assured.version>1.7.2</rest-assured.version>
+ <rest-assured.version>1.8.1</rest-assured.version>
</properties>
<build>
10 years, 11 months
[rhq] Branch 'mtho11/d3-multiline-graph' - modules/enterprise
by mike thompson
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/summary/AbstractActivityView.java | 2
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/graph/graphtype/StackedBarMetricGraphImpl.java | 8 -
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/monitoring/table/CompositeGroupD3GraphListView.java | 6 -
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/monitoring/table/CompositeGroupD3MultiLineGraph.java | 48 ++++++----
4 files changed, 38 insertions(+), 26 deletions(-)
New commits:
commit 5b4eafbed316217c2355e4d2a564917df12aef13
Author: Mike Thompson <mithomps(a)redhat.com>
Date: Mon Jul 8 13:48:42 2013 -0700
Fix new d3 multi-line graph scaling issues.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/summary/AbstractActivityView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/summary/AbstractActivityView.java
index 31b1667..b22907e 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/summary/AbstractActivityView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/detail/summary/AbstractActivityView.java
@@ -634,7 +634,7 @@ public abstract class AbstractActivityView extends EnhancedVLayout implements Re
setIsModal(true);
setShowModalMask(true);
setWidth(950);
- setHeight(390);
+ setHeight(420);
setShowResizer(true);
setCanDragResize(true);
centerInPage();
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/graph/graphtype/StackedBarMetricGraphImpl.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/graph/graphtype/StackedBarMetricGraphImpl.java
index b8c63f4..9058ea5 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/graph/graphtype/StackedBarMetricGraphImpl.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/graph/graphtype/StackedBarMetricGraphImpl.java
@@ -251,7 +251,7 @@ public class StackedBarMetricGraphImpl extends AbstractMetricGraph {
.attr("y", yBase)
.text(highLabel + " - ");
- if(highValue !== undefined){
+ if(typeof highValue !== 'undefined'){
chart.append("text")
.attr("class", "highText")
.attr("x", xValue)
@@ -267,7 +267,7 @@ public class StackedBarMetricGraphImpl extends AbstractMetricGraph {
.attr("y", yBase + yInc)
.text(avgLabel + " - ");
- if(avgValue !== undefined){
+ if(typeof avgValue !== 'undefined'){
chart.append("text")
.attr("class", "avgText")
.attr("x", xValue)
@@ -282,7 +282,7 @@ public class StackedBarMetricGraphImpl extends AbstractMetricGraph {
.attr("y", yBase + 2 * yInc)
.text(minLabel + " - ");
- if(minValue !== undefined){
+ if(typeof minValue !== 'undefined'){
chart.append("text")
.attr("class", "minText")
.attr("x", xValue)
@@ -606,7 +606,7 @@ public class StackedBarMetricGraphImpl extends AbstractMetricGraph {
function formatHovers(chartContext, d) {
var hoverString,
- xValue = (d.x == undefined) ? 0 : +d.x,
+ xValue = (typeof d.x === 'undefined') ? 0 : +d.x,
date = new Date(+xValue),
barDuration = d.barDuration,
timeFormatter = $wnd.d3.time.format(chartContext.chartHoverTimeFormat),
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/monitoring/table/CompositeGroupD3GraphListView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/monitoring/table/CompositeGroupD3GraphListView.java
index 7ade3f7..3ac3758 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/monitoring/table/CompositeGroupD3GraphListView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/monitoring/table/CompositeGroupD3GraphListView.java
@@ -249,9 +249,8 @@ public abstract class CompositeGroupD3GraphListView extends EnhancedVLayout impl
@Override
public void redrawGraphs() {
- drawGraph();
populateData();
- markForRedraw();
+ drawGraph();
}
private void drawGraph() {
@@ -281,7 +280,6 @@ public abstract class CompositeGroupD3GraphListView extends EnhancedVLayout impl
@Override
public void run() {
- //markForRedraw();
drawJsniChart();
}
}.schedule(200);
@@ -375,7 +373,7 @@ public abstract class CompositeGroupD3GraphListView extends EnhancedVLayout impl
}
sb.setLength(sb.length() - 1); // delete the last ','
sb.append("]");
- Log.debug("*** Multi-resource Graph json: "+ sb.toString());
+ Log.debug("Multi-resource Graph json: "+ sb.toString());
return sb.toString();
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/monitoring/table/CompositeGroupD3MultiLineGraph.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/monitoring/table/CompositeGroupD3MultiLineGraph.java
index 42e5f0c..31f5b8b 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/monitoring/table/CompositeGroupD3MultiLineGraph.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/monitoring/table/CompositeGroupD3MultiLineGraph.java
@@ -96,26 +96,25 @@ public class CompositeGroupD3MultiLineGraph extends CompositeGroupD3GraphListVie
yAxis,
timeScale,
xAxis,
+ colorScale = $wnd.d3.scale.category20(),
chart,
svg;
function determineScale() {
- var xTicks, xTickSubDivide;
+ var xTicks, xTickSubDivide, minY, maxY;
console.log("DetermineScale for # resources: "+ chartContext.data.length);
if (chartContext.data.length > 0) {
xTicks = 8;
xTickSubDivide = 5;
+ var myExtent = getExtentFromNestedValues(chartContext.data);
+ console.info("minY, maxY: "+myExtent[0] + ", "+myExtent[1] );
yScale = $wnd.d3.scale.linear()
.clamp(true)
.rangeRound([height, 0])
- .domain([$wnd.d3.min(chartContext.data[0], function (d) {
- return d.y;
- }), $wnd.d3.max(chartContext.data[0], function (d) {
- return d.y;
- })]);
+ .domain([myExtent[0],myExtent[1]]);
yAxis = $wnd.d3.svg.axis()
.scale(yScale)
@@ -124,10 +123,10 @@ public class CompositeGroupD3MultiLineGraph extends CompositeGroupD3GraphListVie
.tickSize(4, 4, 0)
.orient("left");
-
+ var firstDataset = chartContext.data[0].value;
timeScale = $wnd.d3.time.scale()
.range([0, width])
- .domain($wnd.d3.extent(chartContext.data[0], function (d) {
+ .domain($wnd.d3.extent(firstDataset, function(d){
return d.x;
}));
@@ -150,6 +149,24 @@ public class CompositeGroupD3MultiLineGraph extends CompositeGroupD3GraphListVie
}
+ function getExtentFromNestedValues(data){
+ var tempArray = [],
+ mergedArray = [],
+ resultArray = [],
+ max = 0,
+ min = 0;
+
+ for(var i=0; i< data.length;i++){
+ tempArray.push(data[i].value);
+ }
+ mergedArray = $wnd.d3.merge(tempArray, function(d){ return d.y;});
+ max = $wnd.d3.max(mergedArray, function(d){ return d.y});
+ min = $wnd.d3.min(mergedArray, function(d){ return d.y});
+ resultArray.push(min);
+ resultArray.push(max);
+ return resultArray;
+ }
+
function createYAxisGridLines() {
// create the y axis grid lines
svg.append("g").classed("grid y_grid", true)
@@ -164,7 +181,7 @@ public class CompositeGroupD3MultiLineGraph extends CompositeGroupD3GraphListVie
function createXandYAxes() {
- xAxis.tickFormat($wnd.rhqCommon.getD3CustomTimeFormat(chartContext.chartXaxisTimeFormatHours, chartContext.chartXaxisTimeFormatHoursMinutes));
+ //xAxis.tickFormat($wnd.rhqCommon.getD3CustomTimeFormat(chartContext.chartXaxisTimeFormatHours, chartContext.chartXaxisTimeFormatHoursMinutes));
// create x-axis
svg.append("g")
@@ -189,8 +206,6 @@ public class CompositeGroupD3MultiLineGraph extends CompositeGroupD3GraphListVie
}
-
-
function createHeader(titleName) {
var title = chart.append("g").append("rect")
.attr("class", "title")
@@ -224,14 +239,14 @@ public class CompositeGroupD3MultiLineGraph extends CompositeGroupD3GraphListVie
return yScale(d.y);
});
- chart.selectAll(".multiLine")
+ svg.selectAll(".multiLine")
.data(chartContext.data)
.enter()
.append('path')
.attr("class", "multiLine")
.attr("fill", "none")
- .attr("stroke", "#2e376a")
- .attr("stroke-width", "1.5")
+ .attr("stroke", function(d,i){ return colorScale(i);})
+ .attr("stroke-width", "2")
.attr("stroke-opacity", ".9")
.attr("d", function(d) { return graphLine(d.value);});
@@ -244,21 +259,20 @@ public class CompositeGroupD3MultiLineGraph extends CompositeGroupD3GraphListVie
"use strict";
// Guard condition that can occur when a portlet has not been configured yet
console.log("multi-resource chart handle:" + chartContext.chartHandle);
- //console.dir(chartContext.data);
if (chartContext.data.length > 0) {
console.log("Creating MultiLine Chart: " + chartContext.chartSelection + " --> " + chartContext.chartTitle);
determineScale();
createHeader(chartContext.chartTitle);
- console.log("created multi-header");
createYAxisGridLines();
createMultiLines(chartContext);
createXandYAxes();
+ console.log("finished drawing multi-line graph");
}
}
}; // end public closure
}();
- if (chartContext.data !== undefined && chartContext.data.length > 0) {
+ if (typeof chartContext.data !== 'undefined' && chartContext.data.length > 0) {
multiLineGraph.draw(chartContext);
}
10 years, 11 months
[rhq] Branch 'nightly/rhq.jon' - modules/enterprise
by Simeon Pinder
modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/cloud/StorageNodeManagerBeanTest.java | 55 +++++++---
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/StorageNodeManagerBean.java | 7 -
2 files changed, 46 insertions(+), 16 deletions(-)
New commits:
commit 5e6b4892e9306392505f61a8900319198da1bd70
Author: John Sanda <jsanda(a)redhat.com>
Date: Thu Jul 4 07:29:32 2013 -0400
fix failing test
Now that StorageNodeManagerBean creates the storage node resource group, the
group has to be deleted during test runs.
diff --git a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/cloud/StorageNodeManagerBeanTest.java b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/cloud/StorageNodeManagerBeanTest.java
index d45ae90..d44d637 100644
--- a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/cloud/StorageNodeManagerBeanTest.java
+++ b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/cloud/StorageNodeManagerBeanTest.java
@@ -25,6 +25,10 @@
package org.rhq.enterprise.server.cloud;
+import static org.rhq.enterprise.server.cloud.StorageNodeManagerBean.STORAGE_NODE_GROUP_NAME;
+import static org.rhq.enterprise.server.cloud.StorageNodeManagerBean.STORAGE_NODE_PLUGIN_NAME;
+import static org.rhq.enterprise.server.cloud.StorageNodeManagerBean.STORAGE_NODE_RESOURCE_TYPE_NAME;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
@@ -32,27 +36,30 @@ import java.util.List;
import java.util.Set;
import java.util.UUID;
+import javax.ejb.EJB;
import javax.persistence.Query;
import javax.transaction.Transaction;
import org.testng.Assert;
import org.testng.annotations.Test;
-import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.cloud.StorageNode;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple;
import org.rhq.core.domain.configuration.definition.PropertySimpleType;
+import org.rhq.core.domain.criteria.ResourceGroupCriteria;
import org.rhq.core.domain.criteria.StorageNodeCriteria;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceCategory;
import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.domain.resource.group.ResourceGroup;
import org.rhq.core.domain.util.PageList;
import org.rhq.core.domain.util.PageOrdering;
+import org.rhq.enterprise.server.auth.SubjectManagerLocal;
import org.rhq.enterprise.server.resource.ResourceTypeManagerLocal;
+import org.rhq.enterprise.server.resource.group.ResourceGroupManagerLocal;
import org.rhq.enterprise.server.test.AbstractEJB3Test;
import org.rhq.enterprise.server.test.TransactionCallback;
-import org.rhq.enterprise.server.util.LookupUtil;
/**
* @author Jirka Kremser
@@ -60,17 +67,19 @@ import org.rhq.enterprise.server.util.LookupUtil;
@Test
public class StorageNodeManagerBeanTest extends AbstractEJB3Test {
+ @EJB
private StorageNodeManagerLocal nodeManager;
+
+ @EJB
private ResourceTypeManagerLocal typeManager;
- private Subject overlord;
- private static final String TEST_PREFIX = "test-";
- @Override
- protected void beforeMethod() throws Exception {
- nodeManager = LookupUtil.getStorageNodeManager();
- typeManager = LookupUtil.getResourceTypeManager();
- overlord = LookupUtil.getSubjectManager().getOverlord();
- }
+ @EJB
+ private ResourceGroupManagerLocal resourceGroupManager;
+
+ @EJB
+ private SubjectManagerLocal subjectManager;
+
+ private static final String TEST_PREFIX = "test-";
@Test
public void testInit() throws Exception {
@@ -79,6 +88,7 @@ public class StorageNodeManagerBeanTest extends AbstractEJB3Test {
try {
prepareScheduler();
+ cleanDatabase();
executeInTransaction(new TransactionCallback() {
@Override
@@ -89,8 +99,6 @@ public class StorageNodeManagerBeanTest extends AbstractEJB3Test {
System.setProperty(cassandraSeedsProperty, addresses.get(0) + "|123|123," + addresses.get(1)
+ "|987|987," + addresses.get(2) + "|123|123");
- cleanDatabase();
-
// create the resource type if it doesn't exist
ResourceType testResourceType = typeManager.getResourceTypeByNameAndPlugin("RHQ Storage Node",
"RHQStorage");
@@ -175,7 +183,8 @@ public class StorageNodeManagerBeanTest extends AbstractEJB3Test {
criteria.addFilterAddress(prefix);
// use DESC just to make sure sorting on name is different than insert order
criteria.addSortAddress(PageOrdering.DESC);
- PageList<StorageNode> list = nodeManager.findStorageNodesByCriteria(overlord, criteria);
+ PageList<StorageNode> list = nodeManager.findStorageNodesByCriteria(subjectManager.getOverlord(),
+ criteria);
assertTrue("The number of found storage nodes should be " + storageNodeCount + ". Was: " + list.size(),
storageNodeCount == list.size());
@@ -205,6 +214,26 @@ public class StorageNodeManagerBeanTest extends AbstractEJB3Test {
// this method is still needed, because tests calls SLSB methods that are executed in their own transaction
// and the rollback performed once the TransactionCallback is finished just wont clean everything
+ // We can only filter on the group name because the resource type info might not exist in the test
+ // database.
+ ResourceGroupCriteria criteria = new ResourceGroupCriteria();
+ criteria.addFilterName(STORAGE_NODE_GROUP_NAME);
+
+ List<ResourceGroup> groups = resourceGroupManager.findResourceGroupsByCriteria(subjectManager.getOverlord(),
+ criteria);
+
+ if (!groups.isEmpty()) {
+ resourceGroupManager.deleteResourceGroup(subjectManager.getOverlord(), groups.get(0).getId());
+ }
+
+// for (ResourceGroup group : groups) {
+// if (group.getName().equals(STORAGE_NODE_GROUP_NAME)) {
+// resourceGroupManager.deleteResourceGroup(subjectManager.getOverlord(), group.getId());
+// break;
+// }
+// }
+
+
// pause the currently running TX
Transaction runningTransaction = getTransactionManager().suspend();
getTransactionManager().begin();
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/StorageNodeManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/StorageNodeManagerBean.java
index 90d9497..07640ab 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/StorageNodeManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/StorageNodeManagerBean.java
@@ -96,11 +96,12 @@ public class StorageNodeManagerBean implements StorageNodeManagerLocal, StorageN
private static final String SEEDS_PROP = "rhq.cassandra.seeds";
- private static final String STORAGE_NODE_GROUP_NAME = "RHQ Storage Nodes";
+ // The following have package visibility to make accessible to StorageNodeManagerBeanTest
+ static final String STORAGE_NODE_GROUP_NAME = "RHQ Storage Nodes";
- private static final String STORAGE_NODE_RESOURCE_TYPE_NAME = "RHQ Storage Node";
+ static final String STORAGE_NODE_RESOURCE_TYPE_NAME = "RHQ Storage Node";
- private static final String STORAGE_NODE_PLUGIN_NAME = "RHQStorage";
+ static final String STORAGE_NODE_PLUGIN_NAME = "RHQStorage";
@PersistenceContext(unitName = RHQConstants.PERSISTENCE_UNIT_NAME)
private EntityManager entityManager;
10 years, 11 months
[rhq] 2 commits - modules/common modules/enterprise modules/plugins
by John Sanda
modules/common/cassandra-schema/src/main/java/org/rhq/cassandra/schema/SchemaManager.java | 4
modules/enterprise/server/appserver/src/main/scripts/rhq-container.build.xml | 2
modules/enterprise/server/installer/src/main/java/org/rhq/enterprise/server/installer/InstallerServiceImpl.java | 3
modules/enterprise/server/installer/src/main/java/org/rhq/enterprise/server/installer/ServerInstallUtil.java | 85 ++++
modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/cloud/StorageNodeManagerBeanTest.java | 66 ---
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/StorageNodeManagerBean.java | 172 ----------
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/StorageNodeManagerLocal.java | 20 +
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/storage/StorageClientManagerBean.java | 8
modules/plugins/cassandra/src/main/java/org/rhq/plugins/cassandra/CassandraNodeComponent.java | 30 +
9 files changed, 145 insertions(+), 245 deletions(-)
New commits:
commit 686716224eeaeed7179e1edc9a4532702b7bd494
Author: John Sanda <jsanda(a)redhat.com>
Date: Mon Jul 8 09:52:51 2013 -0400
revert snashot call in avail check
also log the execution time for avail checks
diff --git a/modules/plugins/cassandra/src/main/java/org/rhq/plugins/cassandra/CassandraNodeComponent.java b/modules/plugins/cassandra/src/main/java/org/rhq/plugins/cassandra/CassandraNodeComponent.java
index 93d758c..5e7692b 100644
--- a/modules/plugins/cassandra/src/main/java/org/rhq/plugins/cassandra/CassandraNodeComponent.java
+++ b/modules/plugins/cassandra/src/main/java/org/rhq/plugins/cassandra/CassandraNodeComponent.java
@@ -128,18 +128,28 @@ public class CassandraNodeComponent extends JMXServerComponent<ResourceComponent
@Override
public AvailabilityType getAvailability() {
- ResourceContext<?> context = getResourceContext();
- ProcessInfo processInfo = context.getNativeProcess();
+ long start = System.currentTimeMillis();
+ try {
+ ResourceContext<?> context = getResourceContext();
+ ProcessInfo processInfo = context.getNativeProcess();
- if (processInfo == null) {
- return UNKNOWN;
- } else {
- // It is safe to read prior snapshot as getNativeProcess always return a fresh instance
- ProcessInfoSnapshot processInfoSnaphot = processInfo.freshSnapshot();
- if (processInfoSnaphot.isRunning()) {
- return UP;
+ if (processInfo == null) {
+ return UNKNOWN;
} else {
- return DOWN;
+ // It is safe to read prior snapshot as getNativeProcess always return a fresh instance
+ // ProcessInfoSnapshot processInfoSnaphot = processInfo.freshSnapshot();
+ if (processInfo.priorSnaphot().isRunning()) {
+ return UP;
+ } else {
+ return DOWN;
+ }
+ }
+ } finally {
+ long end = System.currentTimeMillis();
+ long totalTime = end - start;
+ log.debug("Finished availability check in " + totalTime + " ms");
+ if (totalTime > (1000 * 5)) {
+ log.warn("Availability check exceeded five seconds. Total time was " + totalTime + " ms");
}
}
}
commit 2d36e94937dd694ebfb6bab50e57db3717687363
Author: John Sanda <jsanda(a)redhat.com>
Date: Mon Jul 8 09:46:20 2013 -0400
Create storage nodes from rhq.cassandra.seeds prop during installation
Previously we were reading rhq.cassandra.seeds at server start up and had logic
in place to see if there were any changes in the property. If changes were
detected (i.e., new node added), cluster maintenance would be scheduled. We
really only want to create/persist seeds nodes at installation time though.
Once the server has been installed, rhqctl install should be used to install
new storage nodes. This simplifies server start up logic and also reduces the
chances for screwing up the deployment.
diff --git a/modules/common/cassandra-schema/src/main/java/org/rhq/cassandra/schema/SchemaManager.java b/modules/common/cassandra-schema/src/main/java/org/rhq/cassandra/schema/SchemaManager.java
index 8f67ab3..2836964 100644
--- a/modules/common/cassandra-schema/src/main/java/org/rhq/cassandra/schema/SchemaManager.java
+++ b/modules/common/cassandra-schema/src/main/java/org/rhq/cassandra/schema/SchemaManager.java
@@ -98,6 +98,10 @@ public class SchemaManager {
return topology.updateTopology(isNewSchema);
}
+ public List<StorageNode> getStorageNodes() {
+ return nodes;
+ }
+
private static List<StorageNode> parseNodeInformation(String... nodes) {
List<StorageNode> parsedNodes = new ArrayList<StorageNode>();
for (String node : nodes) {
diff --git a/modules/enterprise/server/appserver/src/main/scripts/rhq-container.build.xml b/modules/enterprise/server/appserver/src/main/scripts/rhq-container.build.xml
index 32824e2..cfe13be 100644
--- a/modules/enterprise/server/appserver/src/main/scripts/rhq-container.build.xml
+++ b/modules/enterprise/server/appserver/src/main/scripts/rhq-container.build.xml
@@ -675,6 +675,8 @@ rhq.cassandra.password=${rhq.cassandra.password}
#
# hostname|jmxPort|nativeTransportPort|
#
+# Note that this is actually an installer setting. Changing the value after
+# installation will have no effect.
rhq.cassandra.seeds=
# If enabled data sent to and from storage nodes will be compressed using
diff --git a/modules/enterprise/server/installer/src/main/java/org/rhq/enterprise/server/installer/InstallerServiceImpl.java b/modules/enterprise/server/installer/src/main/java/org/rhq/enterprise/server/installer/InstallerServiceImpl.java
index 4c87f70..284ddbd 100644
--- a/modules/enterprise/server/installer/src/main/java/org/rhq/enterprise/server/installer/InstallerServiceImpl.java
+++ b/modules/enterprise/server/installer/src/main/java/org/rhq/enterprise/server/installer/InstallerServiceImpl.java
@@ -499,6 +499,9 @@ public class InstallerServiceImpl implements InstallerService {
// ensure the server info is up to date and stored in the DB
ServerInstallUtil.storeServerDetails(serverProperties, clearTextDbPassword, serverDetails);
+
+ ServerInstallUtil.persistStorageNodesIfNecessary(serverProperties, clearTextDbPassword,
+ storageNodeSchemaManager.getStorageNodes());
}
@Override
diff --git a/modules/enterprise/server/installer/src/main/java/org/rhq/enterprise/server/installer/ServerInstallUtil.java b/modules/enterprise/server/installer/src/main/java/org/rhq/enterprise/server/installer/ServerInstallUtil.java
index 0318e0e..d0f6f3f 100644
--- a/modules/enterprise/server/installer/src/main/java/org/rhq/enterprise/server/installer/ServerInstallUtil.java
+++ b/modules/enterprise/server/installer/src/main/java/org/rhq/enterprise/server/installer/ServerInstallUtil.java
@@ -68,6 +68,7 @@ import org.rhq.core.db.DbUtil;
import org.rhq.core.db.OracleDatabaseType;
import org.rhq.core.db.PostgresqlDatabaseType;
import org.rhq.core.db.setup.DBSetup;
+import org.rhq.core.domain.cloud.StorageNode;
import org.rhq.core.util.PropertiesFileUpdate;
import org.rhq.core.util.exception.ThrowableUtil;
import org.rhq.core.util.file.FileUtil;
@@ -950,6 +951,89 @@ public class ServerInstallUtil {
}
/**
+ * Persists the storage nodes to the database only if no storage node entities already exist. This method is used
+ * to persist storage nodes created from the rhq.cassandra.seeds server configuration property. The only time those
+ * seed nodes should be created is during an initial server installation. After the initial installation storage
+ * nodes should be created using <code>rhqctl install</code>. This ensures that any necessary cluster maintenance
+ * tasks will be performed.
+ *
+ * @param serverProperties the server properties
+ * @param password clear text password to connect to the database
+ * @param storageNodes the {@link StorageNode storage nodes} to persist
+ * @throws Exception
+ */
+ public static void persistStorageNodesIfNecessary(HashMap<String, String> serverProperties, String password,
+ List<StorageNode> storageNodes) throws Exception {
+ DatabaseType db = null;
+ Connection connection = null;
+ Statement queryStatement = null;
+ ResultSet resultSet = null;
+ PreparedStatement insertStatement = null;
+
+ try {
+ String dbUrl = serverProperties.get(ServerProperties.PROP_DATABASE_CONNECTION_URL);
+ String userName = serverProperties.get(ServerProperties.PROP_DATABASE_USERNAME);
+ connection = getDatabaseConnection(dbUrl, userName, password);
+ db = DatabaseTypeFactory.getDatabaseType(connection);
+
+ if (!(db instanceof PostgresqlDatabaseType || db instanceof OracleDatabaseType)) {
+ throw new IllegalArgumentException("Unknown database type, can't continue: " + db);
+ }
+
+ connection = getDatabaseConnection(dbUrl, userName, password);
+ queryStatement = connection.createStatement();
+ resultSet = queryStatement.executeQuery("SELECT count(id) FROM rhq_storage_node");
+ resultSet.next();
+
+ if (resultSet.getInt(1) == 0) {
+ connection.setAutoCommit(false);
+
+ try {
+ LOG.info("Persisting to database new storage nodes for values specified in server configuration " +
+ "property [rhq.cassandra.seeds]");
+
+ insertStatement = connection.prepareStatement(
+ "INSERT INTO rhq_storage_node (id, address, jmx_port, cql_port, operation_mode, ctime, mtime) " +
+ "VALUES (?, ?, ?, ?, ?, ?, ?)"
+ );
+
+ int id = 1001;
+ for (StorageNode storageNode : storageNodes) {
+ insertStatement.setInt(1, id);
+ insertStatement.setString(2, storageNode.getAddress());
+ insertStatement.setInt(3, storageNode.getJmxPort());
+ insertStatement.setInt(4, storageNode.getCqlPort());
+ insertStatement.setString(5, StorageNode.OperationMode.INSTALLED.toString());
+ insertStatement.setLong(6, System.currentTimeMillis());
+ insertStatement.setLong(7, System.currentTimeMillis());
+
+ insertStatement.executeUpdate();
+ id += 1;
+ }
+
+ connection.commit();
+ } catch (SQLException e) {
+ LOG.error("Failed to persist to database the storage nodes specified by server configuration " +
+ "property [rhq.cassandra.seeds]. Transaction will be rolled back.", e);
+ connection.rollback();
+ throw e;
+ }
+ } else {
+ LOG.info("Storage nodes already exist in database. Server configuration property " +
+ "[rhq.cassandra.seeds] will be ignored.");
+ }
+
+ } finally {
+ if (db != null) {
+ db.closeResultSet(resultSet);
+ db.closeStatement(queryStatement);
+ db.closeStatement(insertStatement);
+ db.closeConnection(connection);
+ }
+ }
+ }
+
+ /**
* Stores the server details (such as the public endpoint) in the database. If the server definition already
* exists, it will be updated; otherwise, a new server will be added to the HA cloud.
*
@@ -982,6 +1066,7 @@ public class ServerInstallUtil {
}
}
+
private static void updateOrInsertServer(DatabaseType db, Connection conn, ServerDetails serverDetails) {
PreparedStatement stm = null;
ResultSet rs = null;
diff --git a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/cloud/StorageNodeManagerBeanTest.java b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/cloud/StorageNodeManagerBeanTest.java
index d44d637..4e04447 100644
--- a/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/cloud/StorageNodeManagerBeanTest.java
+++ b/modules/enterprise/server/itests-2/src/test/java/org/rhq/enterprise/server/cloud/StorageNodeManagerBeanTest.java
@@ -26,8 +26,6 @@
package org.rhq.enterprise.server.cloud;
import static org.rhq.enterprise.server.cloud.StorageNodeManagerBean.STORAGE_NODE_GROUP_NAME;
-import static org.rhq.enterprise.server.cloud.StorageNodeManagerBean.STORAGE_NODE_PLUGIN_NAME;
-import static org.rhq.enterprise.server.cloud.StorageNodeManagerBean.STORAGE_NODE_RESOURCE_TYPE_NAME;
import java.util.ArrayList;
import java.util.Arrays;
@@ -81,70 +79,6 @@ public class StorageNodeManagerBeanTest extends AbstractEJB3Test {
private static final String TEST_PREFIX = "test-";
- @Test
- public void testInit() throws Exception {
- final String cassandraSeedsProperty = "rhq.cassandra.seeds";
- final String originalSeedValue = System.getProperty(cassandraSeedsProperty);
-
- try {
- prepareScheduler();
- cleanDatabase();
- executeInTransaction(new TransactionCallback() {
-
- @Override
- public void execute() throws Exception {
- String testHostName = TEST_PREFIX + "hostname";
- List<String> addresses = Arrays.asList(testHostName, TEST_PREFIX + "hostWithNoFoundResource",
- TEST_PREFIX + "secondHostWithNoFoundResource");
- System.setProperty(cassandraSeedsProperty, addresses.get(0) + "|123|123," + addresses.get(1)
- + "|987|987," + addresses.get(2) + "|123|123");
-
- // create the resource type if it doesn't exist
- ResourceType testResourceType = typeManager.getResourceTypeByNameAndPlugin("RHQ Storage Node",
- "RHQStorage");
- if (testResourceType == null) {
- testResourceType = createResourceType();
- }
- Resource testResource = createResource(testResourceType, testHostName);
-
- // finds the storage nodes and pairs them w/ the associated resources
- nodeManager.scanForStorageNodes();
-
- // get the storage nodes and checks some properties on them
- List<StorageNode> storageNodes = nodeManager.getStorageNodes();
- Assert.assertNotNull(storageNodes, "The list of storage nodes shouldn't be null.");
- Assert.assertFalse(storageNodes.isEmpty(), "The list of storage nodes shouldn't be empty.");
- Assert.assertTrue(storageNodes.size() >= addresses.size(),
- "The size of the list of storage nodes should be at least " + addresses.size());
-
- List<String> obtainedAddresses = new ArrayList<String>(storageNodes.size());
- for (StorageNode storageNode : storageNodes) {
- Assert.assertNotNull(storageNode.getAddress(), "Address of storage node cannot be null.");
- obtainedAddresses.add(storageNode.getAddress());
- if (storageNode.getAddress().equals(testHostName)) {
- Assert.assertEquals(storageNode.getResource().getId(), testResource.getId());
- Assert.assertNotNull(storageNode.getResource(), "Associated resource cannot be null.");
- } else {
- Assert.assertNull(storageNode.getResource(),
- "The resource field should be null at this point.");
- }
- }
-
- Assert.assertTrue(obtainedAddresses.containsAll(addresses),
- "There are some storage nodes that should be created but were not discovered and returned."
- + " The storage nodes that should be returned: " + addresses
- + " The storage nodes that were returned: " + obtainedAddresses
- + " (the second should be a super-set (not necessarily strict) of the first.)");
-
- }
- });
- } finally {
- unprepareScheduler();
- cleanDatabase();
- System.setProperty(cassandraSeedsProperty, originalSeedValue);
- }
- }
-
@Test(groups = "integration.ejb3")
public void testStorageNodeCriteriaFinder() throws Exception {
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/StorageNodeManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/StorageNodeManagerBean.java
index b76d054..9d073ee 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/StorageNodeManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/StorageNodeManagerBean.java
@@ -53,16 +53,13 @@ import org.rhq.core.domain.common.JobTrigger;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.criteria.ResourceGroupCriteria;
import org.rhq.core.domain.criteria.StorageNodeCriteria;
-import org.rhq.core.domain.measurement.AvailabilityType;
import org.rhq.core.domain.measurement.MeasurementAggregate;
import org.rhq.core.domain.measurement.MeasurementUnits;
import org.rhq.core.domain.operation.bean.GroupOperationSchedule;
-import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.resource.group.ResourceGroup;
import org.rhq.core.domain.util.PageList;
-import org.rhq.core.util.StringUtil;
import org.rhq.enterprise.server.RHQConstants;
import org.rhq.enterprise.server.auth.SubjectManagerLocal;
import org.rhq.enterprise.server.authz.RequiredPermission;
@@ -88,22 +85,10 @@ public class StorageNodeManagerBean implements StorageNodeManagerLocal, StorageN
private final Log log = LogFactory.getLog(StorageNodeManagerBean.class);
- private static final String RHQ_STORAGE_RESOURCE_TYPE = "RHQ Storage Node";
- private static final String RHQ_STORAGE_PLUGIN = "RHQStorage";
-
private static final String RHQ_STORAGE_CQL_PORT_PROPERTY = "nativeTransportPort";
private static final String RHQ_STORAGE_JMX_PORT_PROPERTY = "jmxPort";
private static final String RHQ_STORAGE_ADDRESS_PROPERTY = "host";
- private static final String SEEDS_PROP = "rhq.cassandra.seeds";
-
- // The following have package visibility to make accessible to StorageNodeManagerBeanTest
- static final String STORAGE_NODE_GROUP_NAME = "RHQ Storage Nodes";
-
- static final String STORAGE_NODE_RESOURCE_TYPE_NAME = "RHQ Storage Node";
-
- static final String STORAGE_NODE_PLUGIN_NAME = "RHQStorage";
-
@PersistenceContext(unitName = RHQConstants.PERSISTENCE_UNIT_NAME)
private EntityManager entityManager;
@@ -126,89 +111,6 @@ public class StorageNodeManagerBean implements StorageNodeManagerLocal, StorageN
private OperationManagerLocal operationManager;
@Override
- public synchronized List<StorageNode> scanForStorageNodes() {
- List<StorageNode> existingStorageNodes = getStorageNodes();
- if (log.isDebugEnabled()) {
- log.debug("Found existing storage nodes [" + StringUtil.listToString(existingStorageNodes)
- + "] in the database");
- }
-
- String seeds = System.getProperty(SEEDS_PROP);
-
- if (StringUtil.isEmpty(seeds) && existingStorageNodes.isEmpty()) {
- // We need to find storage node connection info from one or the other but not
- // necessarily both. If this is a single server deployment where the storage
- // node(s) is running on a separate machine, then SEEDS_PROP will have to be set
- // manually. And in this scenario during the initial deployment, there will not
- // be any storage nodes in the db. In a HA deployment, where there are already
- // storage nodes in the db, an RHQ server does not have to have SEEDS_PROP set
- // since it can obtain connection info from the storage node table.
- throw new IllegalStateException("There are no existing storage nodes defined in the RHQ database and "
- + "the system property [" + SEEDS_PROP + "] is not set. The RHQ server will not be able to connect "
- + "to the RHQ storage node(s). The [" + SEEDS_PROP + "] property should be defined in "
- + "rhq-server.properties.");
- }
-
- List<StorageNode> seedNodes = parseSeedsProperty(seeds);
- boolean clusterMaintenanceNeeded = false;
- List<StorageNode> newNodes = null;
-
- if (existingStorageNodes.isEmpty()) {
- // This should only happen on the very first server start upon installation.
- if (log.isDebugEnabled()) {
- log.debug("No storage node entities exist in the database");
- log.debug("Persisting seed nodes [" + StringUtil.listToString(seedNodes) + "]");
- }
- createStorageNodeGroup();
- } else {
- // There are existing storage nodes but we need to check if the storage node
- // group exists. In the case of an upgrade, the group would not yet exist so it
- // has to be created now.
- if (!storageNodeGroupExists()) {
- createStorageNodeGroup();
- addExistingStorageNodesToGroup();
- }
-
- newNodes = findNewStorageNodes(existingStorageNodes, seedNodes);
- if (!newNodes.isEmpty()) {
- log.info("Detected topology change. New seed nodes will be persisted.");
- if (log.isDebugEnabled()) {
- log.debug("Persisting new seed nodes [" + StringUtil.listToString(newNodes));
- }
-
- clusterMaintenanceNeeded = true;
- }
- }
-
- Map<String, StorageNode> storageNodeMap = new HashMap<String, StorageNode>(existingStorageNodes.size()
- + seedNodes.size());
- for (StorageNode existingStorageNode : existingStorageNodes) {
- storageNodeMap.put(existingStorageNode.getAddress(), existingStorageNode);
- }
- // possibly overide the existing storage nodes with up to date data
- for (StorageNode seedNode : seedNodes) {
- StorageNode existing = storageNodeMap.get(seedNode.getAddress());
- if (existing != null) {
- if (existing.getJmxPort() != seedNode.getJmxPort() || existing.getCqlPort() != seedNode.getCqlPort()
- || existing.getResource() != seedNode.getResource()) {
- existing.setMtime(new Date().getTime());
- }
- seedNode.setResource(existing.getResource());
- }
- storageNodeMap.put(seedNode.getAddress(), seedNode);
- }
-
- this.discoverResourceInformation(storageNodeMap);
- this.updateStorageNodes(storageNodeMap);
-
- if (clusterMaintenanceNeeded) {
- this.scheduleQuartzJob(existingStorageNodes.size());
- }
-
- return new ArrayList<StorageNode>(storageNodeMap.values());
- }
-
- @Override
public void linkResource(Resource resource) {
List<StorageNode> storageNodes = this.getStorageNodes();
@@ -250,7 +152,8 @@ public class StorageNodeManagerBean implements StorageNodeManagerLocal, StorageN
}
}
- private void createStorageNodeGroup() {
+ @Override
+ public void createStorageNodeGroup() {
log.info("Creating resource group [" + STORAGE_NODE_GROUP_NAME + "]");
ResourceGroup group = new ResourceGroup(STORAGE_NODE_GROUP_NAME);
@@ -261,6 +164,8 @@ public class StorageNodeManagerBean implements StorageNodeManagerLocal, StorageN
group.setRecursive(false);
resourceGroupManager.createResourceGroup(subjectManager.getOverlord(), group);
+
+ addExistingStorageNodesToGroup();
}
private void addExistingStorageNodesToGroup() {
@@ -283,13 +188,8 @@ public class StorageNodeManagerBean implements StorageNodeManagerLocal, StorageN
new int[] {resource.getId()});
}
- /**
- * This method is very similar to {@link #getStorageNodeGroup()} but may be called
- * prior to the group being created.
- *
- * @return true if the storage node resource group exists, false otherwise.
- */
- private boolean storageNodeGroupExists() {
+ @Override
+ public boolean storageNodeGroupExists() {
Subject overlord = subjectManager.getOverlord();
ResourceGroupCriteria criteria = new ResourceGroupCriteria();
@@ -302,14 +202,7 @@ public class StorageNodeManagerBean implements StorageNodeManagerLocal, StorageN
return !groups.isEmpty();
}
- /**
- * Note that this method assumes the storage node resource group already exists; as
- * such, it should only be called from places in the code that are after the point(s)
- * where the group has been created.
- *
- * @return The storage node resource group.
- * @throws IllegalStateException if the group is not found or does not exist.
- */
+ @Override
public ResourceGroup getStorageNodeGroup() {
Subject overlord = subjectManager.getOverlord();
@@ -499,24 +392,6 @@ public class StorageNodeManagerBean implements StorageNodeManagerLocal, StorageN
return storageNodes;
}
- private List<StorageNode> findNewStorageNodes(List<StorageNode> nodes, List<StorageNode> seedNodes) {
- if (log.isDebugEnabled()) {
- log.debug("Checking system property [" + SEEDS_PROP + "] for any new nodes to be persisted");
- }
- List<StorageNode> newNodes = new ArrayList<StorageNode>();
- for (StorageNode seedNode : seedNodes) {
- // The contains call should be ok even though it is an O(N) operation because
- // the number of storage nodes will be small and this is only done at start up.
- if (!nodes.contains(seedNode)) {
- if (log.isDebugEnabled()) {
- log.debug("Detected new storage node [" + seedNode + "]");
- }
- newNodes.add(seedNode);
- }
- }
- return newNodes;
- }
-
private void scheduleQuartzJob(int clusterSize) {
String jobName = StorageNodeMaintenanceJob.class.getName();
String jobGroupName = StorageNodeMaintenanceJob.class.getName();
@@ -552,38 +427,7 @@ public class StorageNodeManagerBean implements StorageNodeManagerLocal, StorageN
}
entityManager.flush();
}
-
- private void discoverResourceInformation(Map<String, StorageNode> storageNodeMap) {
- TypedQuery<ResourceType> query = entityManager.<ResourceType>createNamedQuery(ResourceType.QUERY_FIND_BY_NAME_AND_PLUGIN, ResourceType.class)
- .setParameter("name", RHQ_STORAGE_RESOURCE_TYPE).setParameter("plugin", RHQ_STORAGE_PLUGIN);
- List<ResourceType> resourceTypes = query.getResultList();
-
- if (resourceTypes.isEmpty()) {
- return;
- }
-
- TypedQuery<Resource> resourceQuery = entityManager.<Resource>createNamedQuery(Resource.QUERY_FIND_BY_TYPE_ADMIN, Resource.class).setParameter("type",
- resourceTypes.get(0));
- List<Resource> cassandraResources = resourceQuery.getResultList();
-
- for (Resource resource : cassandraResources) {
- Configuration resourceConfiguration = resource.getPluginConfiguration();
- String host = resourceConfiguration.getSimpleValue(RHQ_STORAGE_ADDRESS_PROPERTY);
-
- if (host != null && storageNodeMap.containsKey(host)) {
- StorageNode storageNode = storageNodeMap.get(host);
-
- storageNode.setResource(resource);
- if (resource.getInventoryStatus() == InventoryStatus.NEW) {
- storageNode.setOperationMode(OperationMode.INSTALLED);
- } else if (resource.getInventoryStatus() == InventoryStatus.COMMITTED
- && resource.getCurrentAvailability().getAvailabilityType() == AvailabilityType.UP) {
- storageNode.setOperationMode(OperationMode.NORMAL);
- }
- }
- }
- }
-
+
private StorageNodeLoadComposite.MeasurementAggregateWithUnits getMeasurementAggregateWithUnits(Subject subject,
int schedId, MeasurementUnits units, long beginTime, long endTime) {
MeasurementAggregate measurementAggregate = measurementManager.getAggregate(subject, schedId, beginTime,
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/StorageNodeManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/StorageNodeManagerLocal.java
index 52e2424..5c3f092 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/StorageNodeManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/StorageNodeManagerLocal.java
@@ -33,7 +33,10 @@ import org.rhq.core.domain.util.PageList;
@Local
public interface StorageNodeManagerLocal {
- List<StorageNode> scanForStorageNodes();
+ // The following have package visibility to make accessible to StorageNodeManagerBeanTest
+ String STORAGE_NODE_GROUP_NAME = "RHQ Storage Nodes";
+ String STORAGE_NODE_RESOURCE_TYPE_NAME = "RHQ Storage Node";
+ String STORAGE_NODE_PLUGIN_NAME = "RHQStorage";
List<StorageNode> getStorageNodes();
@@ -88,6 +91,21 @@ public interface StorageNodeManagerLocal {
void runReadRepair();
/**
+ * Creates the storage node resource group which will be named {@link #STORAGE_NODE_GROUP_NAME}. This method should
+ * only be called at start up by {@link org.rhq.enterprise.server.storage.StorageClientManagerBean StorageClientManagerBean}.
+ * Storage node entities created during installation will be added to the group.
+ */
+ void createStorageNodeGroup();
+
+ /**
+ * Checks whether or not the storage node resource group exists. This method is very similar to
+ * {@link #getStorageNodeGroup()} but may be called prior to the group being created.
+ *
+ * @return true if the storage node resource group exists, false otherwise.
+ */
+ boolean storageNodeGroupExists();
+
+ /**
* This method assumes the storage node resource group already exists; as such, it should only be called from places
* in the code that are after the point(s) where the group has been created.
*
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/storage/StorageClientManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/storage/StorageClientManagerBean.java
index 0c76dee..2d48092 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/storage/StorageClientManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/storage/StorageClientManagerBean.java
@@ -86,10 +86,10 @@ public class StorageClientManagerBean {
log.info("Initializing storage client subsystem");
- //decide if there are no storage nodes persisted before doing anything
- boolean isNewServerInstall = storageNodeManager.getStorageNodes().isEmpty();
-
- storageNodeManager.scanForStorageNodes();
+ boolean isNewServerInstall = !storageNodeManager.storageNodeGroupExists();
+ if (isNewServerInstall) {
+ storageNodeManager.createStorageNodeGroup();
+ }
String username = getRequiredStorageProperty(USERNAME_PROP);
String password = getRequiredStorageProperty(PASSWORD_PROP);
10 years, 11 months
[rhq] Branch 'mtho11/d3-multiline-graph' - modules/enterprise
by mike thompson
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/graph/graphtype/AvailabilityLineGraphType.java | 3
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/graph/graphtype/AvailabilityOverUnderGraphType.java | 13
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/graph/graphtype/StackedBarMetricGraphImpl.java | 22
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/monitoring/table/CompositeGroupD3GraphListView.java | 8
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/monitoring/table/CompositeGroupD3MultiLineGraph.java | 37 -
modules/enterprise/gui/coregui/src/main/webapp/js/rhq.js | 234 +++++-----
6 files changed, 153 insertions(+), 164 deletions(-)
New commits:
commit 644b57605e5bcb79c2137ed8ad3902e600c9a9a0
Author: Mike Thompson <mithomps(a)redhat.com>
Date: Sun Jul 7 14:15:08 2013 -0700
Consolidate the d3 time format stuff into rhq.js so all graphs have access.
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/graph/graphtype/AvailabilityLineGraphType.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/graph/graphtype/AvailabilityLineGraphType.java
index 60b5e26..34ca60b 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/graph/graphtype/AvailabilityLineGraphType.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/graph/graphtype/AvailabilityLineGraphType.java
@@ -32,9 +32,12 @@ import org.rhq.enterprise.gui.coregui.client.util.Log;
import org.rhq.enterprise.gui.coregui.client.util.MeasurementConverterClient;
/**
+ * This is now old and for demonstration purposes only.
* Contains the javascript chart definition for an implementation of the d3 availability chart. This implementation is
* just a line that changes color based on availability type: up=green, down=red, orange=disabled, unknown=grey,
* empty=grey, warn=yellow. This version of the availability graph shows continuous intervals.
+ * @deprecated
+ * @see AvailabilityOverUnderGraphType
*
* @author Mike Thompson
*/
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/graph/graphtype/AvailabilityOverUnderGraphType.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/graph/graphtype/AvailabilityOverUnderGraphType.java
index 3822b59..7c5f80a 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/graph/graphtype/AvailabilityOverUnderGraphType.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/graph/graphtype/AvailabilityOverUnderGraphType.java
@@ -171,7 +171,6 @@ public class AvailabilityOverUnderGraphType implements AvailabilityGraphType {
.tickSize(13, 0, 0)
.orient("bottom"),
- customTimeFormat,
calcBarY = function (d) {
var ABOVE = -6,
@@ -253,17 +252,7 @@ public class AvailabilityOverUnderGraphType implements AvailabilityGraphType {
return calcBarFill(d);
});
- customTimeFormat = timeFormat([
- [$wnd.d3.time.format("%Y"), function() { return true; }],
- [$wnd.d3.time.format("%B"), function(d) { return d.getMonth(); }],
- [$wnd.d3.time.format("%b %d"), function(d) { return d.getDate() != 1; }],
- [$wnd.d3.time.format("%a %d"), function(d) { return d.getDay() && d.getDate() != 1; }],
- [$wnd.d3.time.format(availChartContext.chartXaxisTimeFormatHours), function(d) { return d.getHours(); }],
- [$wnd.d3.time.format(availChartContext.chartXaxisTimeFormatHoursMinutes), function(d) { return d.getMinutes(); }],
- [$wnd.d3.time.format(":%S"), function(d) { return d.getSeconds(); }],
- [$wnd.d3.time.format(".%L"), function(d) { return d.getMilliseconds(); }]
- ]);
- xAxis.tickFormat(customTimeFormat);
+ xAxis.tickFormat($wnd.rhqCommon.getD3CustomTimeFormat(availChartContext.chartXaxisTimeFormatHours, availChartContext.chartXaxisTimeFormatHoursMinutes));
// create x-axis
svg.append("g")
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/graph/graphtype/StackedBarMetricGraphImpl.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/graph/graphtype/StackedBarMetricGraphImpl.java
index 0178f93..b8c63f4 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/graph/graphtype/StackedBarMetricGraphImpl.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/common/graph/graphtype/StackedBarMetricGraphImpl.java
@@ -461,17 +461,8 @@ public class StackedBarMetricGraphImpl extends AbstractMetricGraph {
}
function createXandYAxes() {
- var customTimeFormat = timeFormat([
- [$wnd.d3.time.format("%Y"), function() { return true; }],
- [$wnd.d3.time.format("%B"), function(d) { return d.getMonth(); }],
- [$wnd.d3.time.format("%b %d"), function(d) { return d.getDate() != 1; }],
- [$wnd.d3.time.format("%a %d"), function(d) { return d.getDay() && d.getDate() != 1; }],
- [$wnd.d3.time.format(chartContext.chartXaxisTimeFormatHours), function(d) { return d.getHours(); }],
- [$wnd.d3.time.format(chartContext.chartXaxisTimeFormatHoursMinutes), function(d) { return d.getMinutes(); }],
- [$wnd.d3.time.format(":%S"), function(d) { return d.getSeconds(); }],
- [$wnd.d3.time.format(".%L"), function(d) { return d.getMilliseconds(); }]
- ]);
- xAxis.tickFormat(customTimeFormat);
+
+ xAxis.tickFormat($wnd.rhqCommon.getD3CustomTimeFormat(chartContext.chartXaxisTimeFormatHours, chartContext.chartXaxisTimeFormatHoursMinutes));
// create x-axis
svg.append("g")
@@ -495,15 +486,6 @@ public class StackedBarMetricGraphImpl extends AbstractMetricGraph {
}
- function timeFormat(formats) {
- return function(date) {
- var i = formats.length - 1, f = formats[i];
- while (!f[1](date)) f = formats[--i];
- return f[0](date);
- }
- }
-
-
function createAvgLines() {
var showBarAvgTrendline =
global.@org.rhq.enterprise.gui.coregui.client.inventory.common.graph.AbstractMetricGraph::showBarAvgTrendLine()(),
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/monitoring/table/CompositeGroupD3GraphListView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/monitoring/table/CompositeGroupD3GraphListView.java
index 7a4232a..7ade3f7 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/monitoring/table/CompositeGroupD3GraphListView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/monitoring/table/CompositeGroupD3GraphListView.java
@@ -73,7 +73,7 @@ public abstract class CompositeGroupD3GraphListView extends EnhancedVLayout impl
private final String chartHoverDateFormat = MSG.chart_hover_date_format();
private int groupId;
private int definitionId;
- private boolean isAutogroup;
+ private boolean isAutoGroup;
private MeasurementDefinition definition;
private MeasurementUserPreferences measurementUserPreferences;
private ButtonBarDateTimeRangeEditor buttonBarDateTimeRangeEditor;
@@ -86,10 +86,10 @@ public abstract class CompositeGroupD3GraphListView extends EnhancedVLayout impl
private String chartTitle;
private Integer chartHeight;
- public CompositeGroupD3GraphListView(int groupId, int defId, boolean isAutogroup) {
+ public CompositeGroupD3GraphListView(int groupId, int defId, boolean isAutoGroup) {
super();
this.groupId = groupId;
- this.isAutogroup = isAutogroup;
+ this.isAutoGroup = isAutoGroup;
setDefinitionId(defId);
measurementForEachResource = new ArrayList<MultiLineGraphData>();
measurementUserPreferences = new MeasurementUserPreferences(UserSessionManager.getUserPreferences());
@@ -105,7 +105,7 @@ public abstract class CompositeGroupD3GraphListView extends EnhancedVLayout impl
ResourceGroupCriteria criteria = new ResourceGroupCriteria();
criteria.addFilterId(groupId);
criteria.fetchResourceType(true);
- criteria.addFilterVisible(!isAutogroup);
+ criteria.addFilterVisible(!isAutoGroup);
criteria.fetchExplicitResources(true);
measurementForEachResource.clear();
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/monitoring/table/CompositeGroupD3MultiLineGraph.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/monitoring/table/CompositeGroupD3MultiLineGraph.java
index be6d110..42e5f0c 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/monitoring/table/CompositeGroupD3MultiLineGraph.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/monitoring/table/CompositeGroupD3MultiLineGraph.java
@@ -163,33 +163,8 @@ public class CompositeGroupD3MultiLineGraph extends CompositeGroupD3GraphListVie
}
function createXandYAxes() {
- var customTimeFormat = timeFormat([
- [$wnd.d3.time.format("%Y"), function () {
- return true;
- }],
- [$wnd.d3.time.format("%B"), function (d) {
- return d.getMonth();
- }],
- [$wnd.d3.time.format("%b %d"), function (d) {
- return d.getDate() != 1;
- }],
- [$wnd.d3.time.format("%a %d"), function (d) {
- return d.getDay() && d.getDate() != 1;
- }],
- [$wnd.d3.time.format(chartContext.chartXaxisTimeFormatHours), function (d) {
- return d.getHours();
- }],
- [$wnd.d3.time.format(chartContext.chartXaxisTimeFormatHoursMinutes), function (d) {
- return d.getMinutes();
- }],
- [$wnd.d3.time.format(":%S"), function (d) {
- return d.getSeconds();
- }],
- [$wnd.d3.time.format(".%L"), function (d) {
- return d.getMilliseconds();
- }]
- ]);
- xAxis.tickFormat(customTimeFormat);
+
+ xAxis.tickFormat($wnd.rhqCommon.getD3CustomTimeFormat(chartContext.chartXaxisTimeFormatHours, chartContext.chartXaxisTimeFormatHoursMinutes));
// create x-axis
svg.append("g")
@@ -213,13 +188,7 @@ public class CompositeGroupD3MultiLineGraph extends CompositeGroupD3GraphListVie
}
- function timeFormat(formats) {
- return function (date) {
- var i = formats.length - 1, f = formats[i];
- while (!f[1](date)) f = formats[--i];
- return f[0](date);
- }
- }
+
function createHeader(titleName) {
diff --git a/modules/enterprise/gui/coregui/src/main/webapp/js/rhq.js b/modules/enterprise/gui/coregui/src/main/webapp/js/rhq.js
index 435fd67..40c7ca8 100644
--- a/modules/enterprise/gui/coregui/src/main/webapp/js/rhq.js
+++ b/modules/enterprise/gui/coregui/src/main/webapp/js/rhq.js
@@ -4,7 +4,8 @@
// Handle browsers not supporting console object
if (!window.console) window.console = {};
-if (!window.console.log) window.console.log = function () { };
+if (!window.console.log) window.console.log = function () {
+};
/**
* ChartContext Constructor Object
@@ -39,101 +40,146 @@ if (!window.console.log) window.console.log = function () { };
* @param chartXaxisTimeFormatHoursMinutes
* @constructor
*/
-var ChartContext = function (chartId, chartHeight, metricsData, xAxisLabel, chartTitle, yAxisUnits, minChartTitle, avgChartTitle, peakChartTitle, dateLabel, timeLabel, downLabel, unknownLabel, noDataLabel, hoverStartLabel,hoverEndLabel, hoverPeriodLabel, hoverBarLabel, chartHoverTimeFormat, chartHoverDateFormat, isPortalGraph, portalId, buttonBarDateTimeFormat, singleValueLabel, chartXaxisTimeFormatHours, chartXaxisTimeFormatHoursMinutes )
-{
- "use strict";
- if(!(this instanceof ChartContext)){
- throw new Error("ChartContext function cannot be called as a function.")
- }
- this.chartId = chartId;
- this.chartHeight = chartHeight;
- this.data = jQuery.parseJSON(metricsData); // make into json
- this.xAxisLabel = xAxisLabel;
- this.chartTitle = chartTitle;
- this.yAxisUnits = yAxisUnits;
- this.minChartTitle = minChartTitle;
- this.avgChartTitle = avgChartTitle;
- this.peakChartTitle = peakChartTitle;
- this.dateLabel = dateLabel;
- this.timeLabel = timeLabel;
- this.downLabel = downLabel;
- this.unknownLabel = unknownLabel;
- this.singleValueLabel = singleValueLabel;
- this.noDataLabel = noDataLabel;
- this.hoverStartLabel = hoverStartLabel;
- this.hoverEndLabel = hoverEndLabel;
- this.hoverPeriodLabel = hoverPeriodLabel;
- this.hoverBarLabel = hoverBarLabel;
- this.chartHoverTimeFormat = chartHoverTimeFormat;
- this.chartHoverDateFormat = chartHoverDateFormat;
- this.isPortalGraph = isPortalGraph;
- this.portalId = portalId;
- if(isPortalGraph){
- this.chartHandle = "rChart-"+chartId+"-"+portalId;
- }else {
- this.chartHandle = "rChart-"+chartId;
- }
- this.chartSelection = this.chartHandle + " svg";
- this.buttonBarDateTimeFormat = buttonBarDateTimeFormat;
- this.chartXaxisTimeFormatHours = chartXaxisTimeFormatHours;
- this.chartXaxisTimeFormatHoursMinutes = chartXaxisTimeFormatHoursMinutes;
+var ChartContext = function (chartId, chartHeight, metricsData, xAxisLabel, chartTitle, yAxisUnits, minChartTitle, avgChartTitle, peakChartTitle, dateLabel, timeLabel, downLabel, unknownLabel, noDataLabel, hoverStartLabel, hoverEndLabel, hoverPeriodLabel, hoverBarLabel, chartHoverTimeFormat, chartHoverDateFormat, isPortalGraph, portalId, buttonBarDateTimeFormat, singleValueLabel, chartXaxisTimeFormatHours, chartXaxisTimeFormatHoursMinutes) {
+ "use strict";
+ if (!(this instanceof ChartContext)) {
+ throw new Error("ChartContext function cannot be called as a function.")
+ }
+ this.chartId = chartId;
+ this.chartHeight = chartHeight;
+ this.data = jQuery.parseJSON(metricsData); // make into json
+ this.xAxisLabel = xAxisLabel;
+ this.chartTitle = chartTitle;
+ this.yAxisUnits = yAxisUnits;
+ this.minChartTitle = minChartTitle;
+ this.avgChartTitle = avgChartTitle;
+ this.peakChartTitle = peakChartTitle;
+ this.dateLabel = dateLabel;
+ this.timeLabel = timeLabel;
+ this.downLabel = downLabel;
+ this.unknownLabel = unknownLabel;
+ this.singleValueLabel = singleValueLabel;
+ this.noDataLabel = noDataLabel;
+ this.hoverStartLabel = hoverStartLabel;
+ this.hoverEndLabel = hoverEndLabel;
+ this.hoverPeriodLabel = hoverPeriodLabel;
+ this.hoverBarLabel = hoverBarLabel;
+ this.chartHoverTimeFormat = chartHoverTimeFormat;
+ this.chartHoverDateFormat = chartHoverDateFormat;
+ this.isPortalGraph = isPortalGraph;
+ this.portalId = portalId;
+ if (isPortalGraph) {
+ this.chartHandle = "rChart-" + chartId + "-" + portalId;
+ }
+ else {
+ this.chartHandle = "rChart-" + chartId;
+ }
+ this.chartSelection = this.chartHandle + " svg";
+ this.buttonBarDateTimeFormat = buttonBarDateTimeFormat;
+ this.chartXaxisTimeFormatHours = chartXaxisTimeFormatHours;
+ this.chartXaxisTimeFormatHoursMinutes = chartXaxisTimeFormatHoursMinutes;
-},
-/**
- * Availability Context object constructor
- * @param chartId
- * @param availData
- * @param dateLabel
- * @param timeLabel
- * @param hoverStartLabel
- * @param hoverBarLabel
- * @param availabilityLabel
- * @param chartHoverTimeFormat
- * @param chartHoverDateFormat
- * @param chartTitle
- * @param chartUpLabel
- * @param chartDownLabel
- * @param chartXaxisTimeFormatHours
- * @param chartXaxisTimeFormatHoursMinutes
- * @constructor
- */
-AvailChartContext = function (chartId, availData, dateLabel, timeLabel, hoverStartLabel, hoverBarLabel, availabilityLabel, chartHoverTimeFormat, chartHoverDateFormat, chartTitle, chartUpLabel, chartDownLabel, chartXaxisTimeFormatHours, chartXaxisTimeFormatHoursMinutes) {
- "use strict";
- if (!(this instanceof AvailChartContext)) {
- throw new Error("AvailChartContext function cannot be called as a function.")
- }
- this.chartId = chartId;
- this.chartHandle = "#availChart-" + this.chartId;
- this.chartSelection = this.chartHandle + " svg";
- this.data = jQuery.parseJSON(availData); // make into json
- this.dateLabel = dateLabel;
- this.timeLabel = timeLabel;
- this.hoverStartLabel = hoverStartLabel;
- this.hoverBarLabel = hoverBarLabel;
- this.hoverBarAvailabilityLabel = availabilityLabel;
- this.chartHoverTimeFormat = chartHoverTimeFormat;
- this.chartHoverDateFormat = chartHoverDateFormat;
- this.chartTitle = chartTitle;
- this.chartDownLabel = chartDownLabel;
- this.chartUpLabel = chartUpLabel;
- this.chartXaxisTimeFormatHours = chartXaxisTimeFormatHours;
- this.chartXaxisTimeFormatHoursMinutes = chartXaxisTimeFormatHoursMinutes;
+ },
+ /**
+ * Availability Context object constructor
+ * @param chartId
+ * @param availData
+ * @param dateLabel
+ * @param timeLabel
+ * @param hoverStartLabel
+ * @param hoverBarLabel
+ * @param availabilityLabel
+ * @param chartHoverTimeFormat
+ * @param chartHoverDateFormat
+ * @param chartTitle
+ * @param chartUpLabel
+ * @param chartDownLabel
+ * @param chartXaxisTimeFormatHours
+ * @param chartXaxisTimeFormatHoursMinutes
+ * @constructor
+ */
+ AvailChartContext = function (chartId, availData, dateLabel, timeLabel, hoverStartLabel, hoverBarLabel, availabilityLabel, chartHoverTimeFormat, chartHoverDateFormat, chartTitle, chartUpLabel, chartDownLabel, chartXaxisTimeFormatHours, chartXaxisTimeFormatHoursMinutes) {
+ "use strict";
+ if (!(this instanceof AvailChartContext)) {
+ throw new Error("AvailChartContext function cannot be called as a function.")
+ }
+ this.chartId = chartId;
+ this.chartHandle = "#availChart-" + this.chartId;
+ this.chartSelection = this.chartHandle + " svg";
+ this.data = jQuery.parseJSON(availData); // make into json
+ this.dateLabel = dateLabel;
+ this.timeLabel = timeLabel;
+ this.hoverStartLabel = hoverStartLabel;
+ this.hoverBarLabel = hoverBarLabel;
+ this.hoverBarAvailabilityLabel = availabilityLabel;
+ this.chartHoverTimeFormat = chartHoverTimeFormat;
+ this.chartHoverDateFormat = chartHoverDateFormat;
+ this.chartTitle = chartTitle;
+ this.chartDownLabel = chartDownLabel;
+ this.chartUpLabel = chartUpLabel;
+ this.chartXaxisTimeFormatHours = chartXaxisTimeFormatHours;
+ this.chartXaxisTimeFormatHoursMinutes = chartXaxisTimeFormatHoursMinutes;
+
+ },
+
+ /**
+ * GraphDateContext object constructor.
+ * @param startDate moment object representing startDate range
+ * @param endDate moment object representing endDate range
+ * @constructor
+ */
+ GraphDateContext = function (startDate, endDate) {
+ "use strict";
+ if (!(this instanceof GraphDateContext)) {
+ throw new Error("GraphDateContext function cannot be called as a function.")
+ }
+ this.startDate = startDate;
+ this.endDate = endDate;
+ },
+ rhqCommon = (function () {
+
+
+ var timeFormat = function (formats) {
+ return function(date) {
+ var i = formats.length - 1, f = formats[i];
+ while (!f[1](date)) f = formats[--i];
+ return f[0](date);
+ }
+ };
+
+ return {
+ getD3CustomTimeFormat: function (xAxisTimeFormatHours, xAxisTimeFormatHoursMinutes) {
+ return timeFormat([
+ [d3.time.format("%Y"), function () {
+ return true;
+ }],
+ [d3.time.format("%B"), function (d) {
+ return d.getMonth();
+ }],
+ [d3.time.format("%b %d"), function (d) {
+ return d.getDate() != 1;
+ }],
+ [d3.time.format("%a %d"), function (d) {
+ return d.getDay() && d.getDate() != 1;
+ }],
+ [d3.time.format(xAxisTimeFormatHours), function (d) {
+ return d.getHours();
+ }],
+ [d3.time.format(xAxisTimeFormatHoursMinutes), function (d) {
+ return d.getMinutes();
+ }],
+ [d3.time.format(":%S"), function (d) {
+ return d.getSeconds();
+ }],
+ [d3.time.format(".%L"), function (d) {
+ return d.getMilliseconds();
+ }]
+ ]);
+ }
+
+ }
+ })();
-},
-/**
- * GraphDateContext object constructor.
- * @param startDate moment object representing startDate range
- * @param endDate moment object representing endDate range
- * @constructor
- */
-GraphDateContext = function (startDate, endDate){
- "use strict";
- if (!(this instanceof GraphDateContext)) {
- throw new Error("GraphDateContext function cannot be called as a function.")
- }
- this.startDate = startDate;
- this.endDate = endDate;
-};
10 years, 11 months
[rhq] modules/enterprise
by Thomas Segismont
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java | 9 -
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/inventory/ResourceGroupResourceSelector.java | 67 ++++++++--
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/selection/ResourceSelector.java | 8 -
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java | 19 ++
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java | 54 +++++++-
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java | 20 +-
6 files changed, 140 insertions(+), 37 deletions(-)
New commits:
commit d5b6714edf6eacbed95fbf2253de9f4ab5c1b08b
Author: Thomas Segismont <tsegismo(a)redhat.com>
Date: Fri Jul 5 15:09:44 2013 +0200
Bug 910646 - Unable to add more than 100 resources to a Compatible Group
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java
index bd6209a..3248186 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2010 Red Hat, Inc.
+ * Copyright (C) 2005-2013 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -13,8 +13,8 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * 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.enterprise.gui.coregui.client.gwt;
@@ -113,4 +113,7 @@ public interface ResourceGWTService extends RemoteService {
List<Integer> uninventoryResources(int[] resourceIds) throws RuntimeException;
+ PageList<Resource> findGroupMemberCandidateResources(ResourceCriteria criteria, int[] alreadySelectedResourceIds)
+ throws RuntimeException;
+
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/inventory/ResourceGroupResourceSelector.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/inventory/ResourceGroupResourceSelector.java
index 0882ce2..2bf0883 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/inventory/ResourceGroupResourceSelector.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/inventory/ResourceGroupResourceSelector.java
@@ -1,24 +1,20 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2010 Red Hat, Inc.
+ * Copyright (C) 2005-2013 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.
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2 of the License.
*
* 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.
+ * GNU 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.
+ * 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.enterprise.gui.coregui.client.inventory.groups.detail.inventory;
@@ -26,24 +22,33 @@ import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.smartgwt.client.data.DSRequest;
+import com.smartgwt.client.data.DSResponse;
import com.smartgwt.client.data.Record;
+import com.smartgwt.client.rpc.RPCResponse;
import com.smartgwt.client.types.Overflow;
import com.smartgwt.client.widgets.grid.ListGridRecord;
+import org.rhq.core.domain.criteria.ResourceCriteria;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.domain.util.PageList;
+import org.rhq.enterprise.gui.coregui.client.CoreGUI;
import org.rhq.enterprise.gui.coregui.client.inventory.resource.AncestryUtil;
import org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceDatasource;
import org.rhq.enterprise.gui.coregui.client.inventory.resource.selection.ResourceSelector;
import org.rhq.enterprise.gui.coregui.client.inventory.resource.type.ResourceTypeRepository;
import org.rhq.enterprise.gui.coregui.client.inventory.resource.type.ResourceTypeRepository.TypesLoadedCallback;
+import org.rhq.enterprise.gui.coregui.client.util.RPCDataSource;
/**
* @author Jay Shaughnessy
*/
public class ResourceGroupResourceSelector extends ResourceSelector {
+ private static final int MAX_AVAILABLE_RECORDS = 300;
- Collection<Resource> resources;
+ private Collection<Resource> resources;
public ResourceGroupResourceSelector(Collection<Resource> resources, ResourceType resourceTypeFilter,
boolean forceResourceTypeFilter) {
@@ -96,4 +101,44 @@ public class ResourceGroupResourceSelector extends ResourceSelector {
}
}
+ @Override
+ protected int getMaxAvailableRecords() {
+ return MAX_AVAILABLE_RECORDS;
+ }
+
+ @Override
+ protected RPCDataSource<Resource, ResourceCriteria> getDataSource() {
+ return new SelectedResourcesAwareDataSource();
+ }
+
+ private class SelectedResourcesAwareDataSource extends SelectedResourceDataSource {
+
+ @Override
+ public void executeFetch(final DSRequest request, final DSResponse response, final ResourceCriteria criteria) {
+ getResourceService().findGroupMemberCandidateResources(criteria, getSelectedResourceIds(),
+ new AsyncCallback<PageList<Resource>>() {
+ @Override
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError(MSG.view_inventory_resources_loadFailed(), caught);
+ response.setStatus(RPCResponse.STATUS_FAILURE);
+ processResponse(request.getRequestId(), response);
+ }
+
+ @Override
+ public void onSuccess(PageList<Resource> result) {
+ dataRetrieved(result, response, request);
+ }
+ });
+ }
+
+ private int[] getSelectedResourceIds() {
+ ListGridRecord[] assignedRecords = assignedGrid.getRecords();
+ int[] selectedResourceIds = new int[assignedRecords.length];
+ for (int i = 0; i < assignedRecords.length; i++) {
+ ListGridRecord assignedRecord = assignedRecords[i];
+ selectedResourceIds[i] = assignedRecord.getAttributeAsInt(getSelectorKey());
+ }
+ return selectedResourceIds;
+ }
+ }
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/selection/ResourceSelector.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/selection/ResourceSelector.java
index 90511d7..03b70b3 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/selection/ResourceSelector.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/selection/ResourceSelector.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2010 Red Hat, Inc.
+ * Copyright (C) 2005-2013 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -13,8 +13,8 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * 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.enterprise.gui.coregui.client.inventory.resource.selection;
@@ -185,7 +185,7 @@ public class ResourceSelector extends AbstractSelector<Resource, ResourceCriteri
return true;
}
- private class SelectedResourceDataSource extends ResourceDatasource {
+ protected class SelectedResourceDataSource extends ResourceDatasource {
@Override
protected ResourceCriteria getFetchCriteria(final DSRequest request) {
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java
index 456a69a..dfa1b9f 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2011 Red Hat, Inc.
+ * Copyright (C) 2005-2013 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -13,8 +13,8 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * 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.enterprise.gui.coregui.server.gwt;
@@ -463,4 +463,17 @@ public class ResourceGWTServiceImpl extends AbstractGWTServiceImpl implements Re
throw getExceptionToThrowToClient(t);
}
}
+
+ @Override
+ public PageList<Resource> findGroupMemberCandidateResources(ResourceCriteria criteria,
+ int[] alreadySelectedResourceIds) throws RuntimeException {
+ try {
+ PageList<Resource> result = resourceManager.findGroupMemberCandidateResources(getSessionSubject(),
+ criteria, alreadySelectedResourceIds);
+ ObjectFilter.filterFieldsInCollection(result, importantFieldsSet);
+ return SerialUtility.prepare(result, "ResourceService.findResourcesByCriteria");
+ } catch (Throwable t) {
+ throw getExceptionToThrowToClient(t);
+ }
+ }
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
index e3a89a4..0c8594d 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2010 Red Hat, Inc.
+ * Copyright (C) 2005-2013 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -13,11 +13,15 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * 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.enterprise.server.resource;
+import static org.rhq.core.domain.criteria.Criteria.Restriction.COLLECTION_ONLY;
+import static org.rhq.core.domain.criteria.Criteria.Restriction.COUNT_ONLY;
+import static org.rhq.enterprise.server.util.CriteriaQueryGenerator.getPageControl;
+
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -30,6 +34,7 @@ import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
+import java.util.Set;
import javax.ejb.EJB;
import javax.ejb.Stateless;
@@ -2921,4 +2926,47 @@ public class ResourceManagerBean implements ResourceManagerLocal, ResourceManage
return reports;
}
+ @Override
+ public PageList<Resource> findGroupMemberCandidateResources(Subject subject, ResourceCriteria criteria,
+ int[] alreadySelectedResourceIds) {
+
+ Set<Integer> alreadySelectedResourceIdSet = new HashSet<Integer>(
+ ArrayUtils.wrapInList(alreadySelectedResourceIds));
+
+ PageControl originalPageControl = getPageControl(criteria);
+ PageControl pageControl = (PageControl) originalPageControl.clone();
+ criteria.setPageControl(pageControl);
+
+ int requiredPageSize = pageControl.getPageSize();
+ criteria.setRestriction(COUNT_ONLY);
+ int totalSize = findResourcesByCriteria(subject, criteria).getTotalSize();
+ int totalPages = (totalSize / requiredPageSize) + (((totalSize % requiredPageSize) > 0) ? 1 : 0);
+
+ criteria.setRestriction(COLLECTION_ONLY);
+ List<Resource> candidates = new LinkedList<Resource>();
+ for (int pageNumber = 0; candidates.size() < requiredPageSize && pageNumber < totalPages; pageNumber++) {
+ pageControl.setPageNumber(pageNumber);
+ PageList<Resource> foundResources = findResourcesByCriteria(subject, criteria);
+ Collection<Resource> filteredResources = filterOutAlreadySelectedResources(foundResources,
+ alreadySelectedResourceIdSet);
+
+ candidates.addAll(filteredResources);
+ }
+ if (candidates.size() > requiredPageSize) {
+ candidates = candidates.subList(0, requiredPageSize);
+ }
+
+ return new PageList<Resource>(candidates, totalSize, originalPageControl);
+ }
+
+ private Collection<Resource> filterOutAlreadySelectedResources(Collection<Resource> foundResources,
+ Collection<Integer> alreadySelectedResourceIds) {
+ List<Resource> result = new LinkedList<Resource>();
+ for (Resource foundResource : foundResources) {
+ if (!alreadySelectedResourceIds.contains(foundResource.getId())) {
+ result.add(foundResource);
+ }
+ }
+ return result;
+ }
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java
index 0d4dd15..b6db0fd 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2010 Red Hat, Inc.
+ * Copyright (C) 2005-2013 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -13,8 +13,8 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * 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.enterprise.server.resource;
@@ -54,7 +54,6 @@ import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
import org.rhq.core.util.IntExtractor;
import org.rhq.enterprise.server.resource.disambiguation.DisambiguationUpdateStrategy;
-import org.rhq.enterprise.server.resource.disambiguation.Disambiguator;
import org.rhq.enterprise.server.resource.group.ResourceGroupNotFoundException;
/**
@@ -220,16 +219,9 @@ public interface ResourceManagerLocal {
PageList<Resource> findChildResourcesByCategoryAndInventoryStatus(Subject user, Resource parent,
ResourceCategory category, InventoryStatus status, PageControl pageControl);
- /**
- *
- * @see ResourceManagerRemote#findResourcesByCategory(Subject, ResourceCategory, InventoryStatus, PageControl)
- */
PageList<Resource> findResourcesByCategory(Subject user, ResourceCategory category,
InventoryStatus inventoryStatus, PageControl pageControl);
- /**
- * @see ResourceManagerRemote#findResourceComposites(Subject, ResourceCategory, String, int, String, PageControl)
- */
PageList<ResourceComposite> findResourceComposites(Subject user, ResourceCategory category, String typeName,
String pluginName, Resource parentResource, String searchString, boolean attachParentResource,
PageControl pageControl);
@@ -542,7 +534,6 @@ public interface ResourceManagerLocal {
Resource getParentResource(Subject subject, int resourceId);
/**
- * @see Disambiguator#disambiguate(List, boolean, IntExtractor, javax.persistence.EntityManager)
* @return the disambiguation result or null on error
*/
<T> List<DisambiguationReport<T>> disambiguate(List<T> results, IntExtractor<? super T> resourceIdExtractor,
@@ -557,4 +548,7 @@ public interface ResourceManagerLocal {
List<Integer> disableResources(Subject subject, int[] resourceIds);
List<Integer> enableResources(Subject subject, int[] resourceIds);
-}
\ No newline at end of file
+
+ PageList<Resource> findGroupMemberCandidateResources(Subject subject, ResourceCriteria criteria,
+ int[] alreadySelectedResourceIds);
+}
10 years, 11 months
[rhq] modules/core modules/enterprise modules/plugins
by snegrea
modules/core/domain/src/main/java/org/rhq/core/domain/cloud/StorageNodeLoadComposite.java | 56 ++---
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/storage/StorageNodeDatasource.java | 37 +--
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/StorageNodeManagerBean.java | 104 ++++++----
modules/enterprise/server/plugins/alertdef-rhq/src/main/java/org/rhq/enterprise/server/plugins/alertdef/AlertDefinitionServerPluginComponent.java | 66 ++++++
modules/plugins/cassandra/src/main/java/org/rhq/plugins/cassandra/StorageServiceComponent.java | 65 +++---
modules/plugins/cassandra/src/main/resources/META-INF/rhq-plugin.xml | 9
6 files changed, 232 insertions(+), 105 deletions(-)
New commits:
commit c19b6ea19c342474b0cc43733fc8eec5ae1c955f
Author: Stefan Negrea <snegrea(a)redhat.com>
Date: Thu Jul 4 02:47:49 2013 -0500
Update the way the percentage disk space use is calculated. It is now based on the aggregate usage of all the partitions that have data files. Also, this is based on the total disk use, not just Cassandra. Added an alert based on this metric.
Added a new metric to the storage node composite that aggregates all the metrics that refer to storage related to Cassandra: data files, commit logs, row cache, and key cache. This will be used for CLI an web only, it will not be a plugin metric.
Updated the plugin descriptor to collect metrics related to disk space usage.
Minor other code refactorings and updates.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/cloud/StorageNodeLoadComposite.java b/modules/core/domain/src/main/java/org/rhq/core/domain/cloud/StorageNodeLoadComposite.java
index 379eba6..0913f1d 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/cloud/StorageNodeLoadComposite.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/cloud/StorageNodeLoadComposite.java
@@ -36,19 +36,20 @@ public class StorageNodeLoadComposite implements Serializable {
private StorageNode storageNode;
private long beginTime;
private long endTime;
-
+
private MeasurementAggregateWithUnits heapCommitted;
private MeasurementAggregateWithUnits heapUsed;
private MeasurementAggregateWithUnits heapPercentageUsed;
private MeasurementAggregateWithUnits load;
- private MeasurementAggregateWithUnits diskSpacePercentageUsed;
- private MeasurementAggregate tokens;
+ private MeasurementAggregateWithUnits partitionDiskUsedPercentage;
+ private MeasurementAggregateWithUnits dataDiskUsed;
+ private MeasurementAggregate tokens;
private MeasurementAggregateWithUnits actuallyOwns;
public StorageNodeLoadComposite() {
// GWT needs this
}
-
+
public StorageNodeLoadComposite(StorageNode storageNode, long beginTime, long endTime) {
this.storageNode = storageNode;
this.beginTime = beginTime;
@@ -114,15 +115,26 @@ public class StorageNodeLoadComposite implements Serializable {
}
/**
- * @return A computed metric for the space used on disk by all SSTables of all column families expressed as a
- * percentage.
+ * @return A computed metric for the percentage of disk space used on the partition that contains the SSTables.
+ * If multiple data locations are configured then the partition with the highest utilization will be reported.
*/
- public MeasurementAggregateWithUnits getDiskSpacePercentageUsed() {
- return diskSpacePercentageUsed;
+ public MeasurementAggregateWithUnits getPartitionDiskUsedPercentage() {
+ return partitionDiskUsedPercentage;
}
- public void setDiskSpacePercentageUsed(MeasurementAggregateWithUnits diskSpacePercentageUsed) {
- this.diskSpacePercentageUsed = diskSpacePercentageUsed;
+ public void setPartitionDiskUsedPercentage(MeasurementAggregateWithUnits partitionDiskUsedPercentage) {
+ this.partitionDiskUsedPercentage = partitionDiskUsedPercentage;
+ }
+
+ /**
+ * @return A computed metric for the space used on disk by all data files, commit logs, and saved caches.
+ */
+ public MeasurementAggregateWithUnits getDataDiskUsed() {
+ return dataDiskUsed;
+ }
+
+ public void setDataDiskUsed(MeasurementAggregateWithUnits dataDiskUsed) {
+ this.dataDiskUsed = dataDiskUsed;
}
/**
@@ -161,38 +173,32 @@ public class StorageNodeLoadComposite implements Serializable {
this.actuallyOwns = actuallyOwns;
}
+ /* (non-Javadoc)
+ * @see java.lang.Object#toString()
+ */
public String toString() {
StringBuilder builder = new StringBuilder();
- // gwt doesn't support String.format
-// builder.append("average values for last ");
-// builder.append((endtime - begintime) / (1000 * 60 * 60));
-// builder.append(" hours");
-// builder.append("\naddress load tokens owns (effective)\n");
-// builder.append(string.format("%15s", storagenode.getaddress()));
-// builder.append(string.format("%11s", load.getaggregate().getavg())).append(" ").append(load.getunits().getname());
-// builder.append(string.format("%8s", tokens.getavg()));
-// builder.append(string.format("%16s", actuallyowns.getavg()));
-
builder.append("storageNode.addresss=").append(storageNode.getAddress()).append(", ");
builder.append("beginTime=").append(beginTime).append(", ");
builder.append("heapCommitted=").append(heapCommitted).append(", ");
builder.append("heapUsed=").append(heapUsed).append(", ");
builder.append("heapPercentageUsed=").append(heapPercentageUsed).append(", ");
builder.append("load=").append(load).append(", ");
- builder.append("diskSpacePercentageUsed=").append(diskSpacePercentageUsed).append(", ");
+ builder.append("partitionDiskUsedPercentage=").append(partitionDiskUsedPercentage).append(", ");
+ builder.append("dataDiskUsed=").append(dataDiskUsed).append(", ");
builder.append("tokens=").append(tokens).append(", ");
builder.append("actuallyOwns=").append(actuallyOwns);
return builder.toString();
}
-
+
public static class MeasurementAggregateWithUnits implements Serializable {
private static final long serialVersionUID = 1L;
-
+
private MeasurementAggregate aggregate;
private MeasurementUnits units;
private String formattedValue;
-
+
public MeasurementAggregateWithUnits() {
// GWT needs this
}
@@ -209,7 +215,7 @@ public class StorageNodeLoadComposite implements Serializable {
public MeasurementUnits getUnits() {
return units;
}
-
+
public void setFormattedValue(String formattedValue) {
this.formattedValue = formattedValue;
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/storage/StorageNodeDatasource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/storage/StorageNodeDatasource.java
index f267602..7d413fd 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/storage/StorageNodeDatasource.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/storage/StorageNodeDatasource.java
@@ -61,7 +61,7 @@ import org.rhq.enterprise.server.measurement.util.MeasurementUtils;
/**
* Datasource for @see StorageNode.
- *
+ *
* @author Jirka Kremser
*/
public class StorageNodeDatasource extends RPCDataSource<StorageNode, StorageNodeCriteria> {
@@ -104,7 +104,7 @@ public class StorageNodeDatasource extends RPCDataSource<StorageNode, StorageNod
ListGridField createdTimeField = FIELD_CTIME.getListGridField("120");
TimestampCellFormatter.prepareDateField(createdTimeField);
fields.add(createdTimeField);
-
+
ListGridField lastUpdateTimeField = FIELD_MTIME.getListGridField("120");
TimestampCellFormatter.prepareDateField(lastUpdateTimeField);
fields.add(lastUpdateTimeField);
@@ -142,7 +142,7 @@ public class StorageNodeDatasource extends RPCDataSource<StorageNode, StorageNod
*/
@Override
protected PageControl getPageControl(DSRequest request) {
- // Initialize paging.
+ // Initialize paging.
PageControl pageControl = new PageControl(0, getDataPageSize());
// Initialize sorting.
@@ -197,7 +197,7 @@ public class StorageNodeDatasource extends RPCDataSource<StorageNode, StorageNod
return criteria;
}
-
+
public static class StorageNodeLoadCompositeDatasource extends RPCDataSource<StorageNodeLoadComposite, StorageNodeCriteria> {
public static final String HEAP_PERCENTAGE_KEY = "heapPercentage";
public static final String DISK_SPACE_PERCENTAGE_KEY = "diskSpacePercentage";
@@ -205,12 +205,12 @@ public class StorageNodeDatasource extends RPCDataSource<StorageNode, StorageNod
public static StorageNodeLoadCompositeDatasource getInstance(int id) {
// if (instance == null) {
-// instance =
+ // instance =
return new StorageNodeLoadCompositeDatasource(id);
// }
// return instance;
}
-
+
public StorageNodeLoadCompositeDatasource(int id) {
super();
this.id = id;
@@ -235,7 +235,7 @@ public class StorageNodeDatasource extends RPCDataSource<StorageNode, StorageNod
fields.add(idField);
return fields;
}
-
+
public List<ListGridField> getListGridFields() {
List<ListGridField> fields = new ArrayList<ListGridField>();
ListGridField idField = FIELD_ID.getListGridField();
@@ -259,8 +259,7 @@ public class StorageNodeDatasource extends RPCDataSource<StorageNode, StorageNod
fields.add(hoverField);
return fields;
}
-
-
+
@Override
protected void executeFetch(final DSRequest request, final DSResponse response, StorageNodeCriteria criteria) {
// Integer id = getFilter(request, FIELD_ID.propertyName(), Integer.class);
@@ -286,7 +285,6 @@ public class StorageNodeDatasource extends RPCDataSource<StorageNode, StorageNod
private ListGridRecord[] makeListGridRecords(StorageNodeLoadComposite loadComposite) {
List<ListGridRecord> recordsList = new ArrayList<ListGridRecord>(6);
- @SuppressWarnings("unchecked")
List<List<Object>> loadFields = Arrays
.<List<Object>> asList(
Arrays.<Object> asList(loadComposite.getHeapCommitted(), "Heap Maximum",
@@ -298,10 +296,16 @@ public class StorageNodeDatasource extends RPCDataSource<StorageNode, StorageNod
"This value is calculated by dividing Heap Used by Heap Maximum.", HEAP_PERCENTAGE_KEY),
Arrays.<Object> asList(loadComposite.getLoad(), "Load", "Data stored on the node", "load"),
Arrays.<Object> asList(
- loadComposite.getDiskSpacePercentageUsed(),
+ loadComposite.getPartitionDiskUsedPercentage(),
"Disk Space Percent Used",
- "How much of diskspace is already used. This takes into account the installation path, where Cassandra was installed.",
- DISK_SPACE_PERCENTAGE_KEY), Arrays.<Object> asList(loadComposite.getActuallyOwns(),
+ "Percentage of total disk space used for the partition that contains the data files.If multiple data locations are specified then this will report the average utilization accross all the partitions.",
+ DISK_SPACE_PERCENTAGE_KEY),
+ Arrays.<Object> asList(
+ loadComposite.getDataDiskUsed(),
+ "Total Disk Space Used",
+ "Total space used on disk by all data files, commit logs, and saved caches.",
+ "totaldisk"),
+ Arrays.<Object> asList(loadComposite.getActuallyOwns(),
"Ownership", "Refers to the percentage of keys that a node owns.", "ownership"));
for (List<Object> aggregateWithUnitsList : loadFields) {
if (aggregateWithUnitsList.get(0) != null) {
@@ -346,14 +350,13 @@ public class StorageNodeDatasource extends RPCDataSource<StorageNode, StorageNod
record.setAttribute("hover", hover);
return record;
}
-
-
+
@Override
protected StorageNodeCriteria getFetchCriteria(DSRequest request) {
return new StorageNodeCriteria();
// throw new UnsupportedOperationException("StorageNodeDatasource.StorageNodeLoadCompositeDatasource.getFetchCriteria()");
}
-
+
@Override
public StorageNodeLoadComposite copyValues(Record from) {
throw new UnsupportedOperationException("StorageNodeDatasource.StorageNodeLoadCompositeDatasource.copyValues(Record from)");
@@ -363,6 +366,6 @@ public class StorageNodeDatasource extends RPCDataSource<StorageNode, StorageNod
public ListGridRecord copyValues(StorageNodeLoadComposite from) {
throw new UnsupportedOperationException("StorageNodeDatasource.StorageNodeLoadCompositeDatasource.copyValues(StorageNodeLoadComposite from)");
}
-
+
}
}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/StorageNodeManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/StorageNodeManagerBean.java
index b21946a..b76d054 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/StorageNodeManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/cloud/StorageNodeManagerBean.java
@@ -332,71 +332,96 @@ public class StorageNodeManagerBean implements StorageNodeManagerLocal, StorageN
@Override
@RequiredPermission(Permission.MANAGE_SETTINGS)
public StorageNodeLoadComposite getLoad(Subject subject, StorageNode node, long beginTime, long endTime) {
- StorageNodeLoadComposite result = new StorageNodeLoadComposite(node, beginTime, endTime);
- final String tokensMetric = "Tokens", ownershipMetric = "Ownership", loadMetric = "Load", diskUsedPercentageMetric = "Calculated.DiskSpaceUsedPercentage";
- final String heapCommittedMetric = "{HeapMemoryUsage.committed}", heapUsedMetric = "{HeapMemoryUsage.used}", heapUsedPercentageMetric = "Calculated.HeapUsagePercentage";
-
int resourceId = getResourceIdFromStorageNode(node);
+ Map<String, Integer> scheduleIdsMap = new HashMap<String, Integer>();
// get the schedule ids for Storage Service resource
+ final String tokensMetric = "Tokens", ownershipMetric = "Ownership", diskUsedPercentageMetric = "Calculated.PartitionDiskUsedPercentage";
+ final String loadMetric = "Load", keyCacheSize = "KeyCacheSize", rowCacheSize = "RowCacheSize", totalCommitLogSize = "TotalCommitlogSize";
TypedQuery<Object[]> query = entityManager.<Object[]> createNamedQuery(
StorageNode.QUERY_FIND_SCHEDULE_IDS_BY_PARENT_RESOURCE_ID_AND_MEASUREMENT_DEFINITION_NAMES, Object[].class);
query.setParameter("parrentId", resourceId).setParameter("metricNames",
- Arrays.asList(tokensMetric, ownershipMetric, loadMetric, diskUsedPercentageMetric));
- List<Object[]> scheduleIds = query.getResultList();
- Map<String, Integer> scheduleIdsMap = new HashMap<String, Integer>(4);
- for (Object[] pair : scheduleIds) {
+ Arrays.asList(tokensMetric, ownershipMetric, diskUsedPercentageMetric, loadMetric, keyCacheSize,
+ rowCacheSize, totalCommitLogSize));
+ for (Object[] pair : query.getResultList()) {
scheduleIdsMap.put((String) pair[0], (Integer) pair[1]);
}
// get the schedule ids for Memory Subsystem resource
+ final String heapCommittedMetric = "{HeapMemoryUsage.committed}", heapUsedMetric = "{HeapMemoryUsage.used}", heapUsedPercentageMetric = "Calculated.HeapUsagePercentage";
query = entityManager.<Object[]> createNamedQuery(
StorageNode.QUERY_FIND_SCHEDULE_IDS_BY_GRANDPARENT_RESOURCE_ID_AND_MEASUREMENT_DEFINITION_NAMES,
Object[].class);
query.setParameter("grandparrentId", resourceId).setParameter("metricNames",
Arrays.asList(heapCommittedMetric, heapUsedMetric, heapUsedPercentageMetric));
- scheduleIds = query.getResultList();
- for (Object[] pair : scheduleIds) {
+ for (Object[] pair : query.getResultList()) {
scheduleIdsMap.put((String) pair[0], (Integer) pair[1]);
}
+
+ StorageNodeLoadComposite result = new StorageNodeLoadComposite(node, beginTime, endTime);
+ MeasurementAggregate totalDiskUsedaggregate = new MeasurementAggregate(0d, 0d, 0d);
+ Integer scheduleId = null;
+
// find the aggregates and enrich the result instance
if (!scheduleIdsMap.isEmpty()) {
- if (scheduleIdsMap.get(tokensMetric) != null) {
- MeasurementAggregate tokensAggregate = measurementManager.getAggregate(subject,
- scheduleIdsMap.get(tokensMetric), beginTime, endTime);
+ if ((scheduleId = scheduleIdsMap.get(tokensMetric)) != null) {
+ MeasurementAggregate tokensAggregate = measurementManager.getAggregate(subject, scheduleId, beginTime,
+ endTime);
result.setTokens(tokensAggregate);
}
- if (scheduleIdsMap.get(ownershipMetric) != null) {
+ if ((scheduleId = scheduleIdsMap.get(ownershipMetric)) != null) {
StorageNodeLoadComposite.MeasurementAggregateWithUnits ownershipAggregateWithUnits = getMeasurementAggregateWithUnits(
- subject, scheduleIdsMap.get(ownershipMetric), MeasurementUnits.PERCENTAGE, beginTime, endTime);
+ subject, scheduleId, MeasurementUnits.PERCENTAGE, beginTime, endTime);
result.setActuallyOwns(ownershipAggregateWithUnits);
}
- if (scheduleIdsMap.get(loadMetric) != null) {
+ if ((scheduleId = scheduleIdsMap.get(diskUsedPercentageMetric)) != null) {
+ StorageNodeLoadComposite.MeasurementAggregateWithUnits diskUsedPercentageAggregateWithUnits = getMeasurementAggregateWithUnits(
+ subject, scheduleId, MeasurementUnits.PERCENTAGE, beginTime, endTime);
+ result.setPartitionDiskUsedPercentage(diskUsedPercentageAggregateWithUnits);
+ }
+
+ if ((scheduleId = scheduleIdsMap.get(loadMetric)) != null) {
StorageNodeLoadComposite.MeasurementAggregateWithUnits loadAggregateWithUnits = getMeasurementAggregateWithUnits(
- subject, scheduleIdsMap.get(loadMetric), MeasurementUnits.BYTES, beginTime, endTime);
+ subject, scheduleId, MeasurementUnits.BYTES, beginTime, endTime);
result.setLoad(loadAggregateWithUnits);
+
+ updateAggregateTotal(totalDiskUsedaggregate, loadAggregateWithUnits.getAggregate());
}
- if (scheduleIdsMap.get(diskUsedPercentageMetric) != null) {
- StorageNodeLoadComposite.MeasurementAggregateWithUnits diskUsedPercentageAggregateWithUnits = getMeasurementAggregateWithUnits(
- subject, scheduleIdsMap.get(diskUsedPercentageMetric), MeasurementUnits.PERCENTAGE, beginTime,
- endTime);
- result.setDiskSpacePercentageUsed(diskUsedPercentageAggregateWithUnits);
+ if ((scheduleId = scheduleIdsMap.get(keyCacheSize)) != null) {
+ updateAggregateTotal(totalDiskUsedaggregate,
+ measurementManager.getAggregate(subject, scheduleId, beginTime, endTime));
+ }
+ if ((scheduleId = scheduleIdsMap.get(rowCacheSize)) != null) {
+ updateAggregateTotal(totalDiskUsedaggregate,
+ measurementManager.getAggregate(subject, scheduleId, beginTime, endTime));
+ }
+ if ((scheduleId = scheduleIdsMap.get(totalCommitLogSize)) != null) {
+ updateAggregateTotal(totalDiskUsedaggregate,
+ measurementManager.getAggregate(subject, scheduleId, beginTime, endTime));
+ }
+
+ if (totalDiskUsedaggregate.getMax() > 0) {
+ StorageNodeLoadComposite.MeasurementAggregateWithUnits totalDiskUsedAggregateWithUnits = new StorageNodeLoadComposite.MeasurementAggregateWithUnits(
+ totalDiskUsedaggregate, MeasurementUnits.BYTES);
+ totalDiskUsedAggregateWithUnits.setFormattedValue(getSummaryString(totalDiskUsedaggregate,
+ MeasurementUnits.BYTES));
+ result.setDataDiskUsed(totalDiskUsedAggregateWithUnits);
}
- if (scheduleIdsMap.get(heapCommittedMetric) != null) {
+ if ((scheduleId = scheduleIdsMap.get(heapCommittedMetric)) != null) {
StorageNodeLoadComposite.MeasurementAggregateWithUnits heapCommittedAggregateWithUnits = getMeasurementAggregateWithUnits(
- subject, scheduleIdsMap.get(heapCommittedMetric), MeasurementUnits.BYTES, beginTime, endTime);
+ subject, scheduleId, MeasurementUnits.BYTES, beginTime, endTime);
result.setHeapCommitted(heapCommittedAggregateWithUnits);
}
- if (scheduleIdsMap.get(heapUsedMetric) != null) {
+ if ((scheduleId = scheduleIdsMap.get(heapUsedMetric)) != null) {
StorageNodeLoadComposite.MeasurementAggregateWithUnits heapUsedAggregateWithUnits = getMeasurementAggregateWithUnits(
- subject, scheduleIdsMap.get(heapUsedMetric), MeasurementUnits.BYTES, beginTime, endTime);
+ subject, scheduleId, MeasurementUnits.BYTES, beginTime, endTime);
result.setHeapUsed(heapUsedAggregateWithUnits);
}
- if (scheduleIdsMap.get(heapUsedPercentageMetric) != null) {
+ if ((scheduleId = scheduleIdsMap.get(heapUsedPercentageMetric)) != null) {
StorageNodeLoadComposite.MeasurementAggregateWithUnits heapUsedPercentageAggregateWithUnits = getMeasurementAggregateWithUnits(
- subject, scheduleIdsMap.get(heapUsedPercentageMetric), MeasurementUnits.PERCENTAGE, beginTime,
+ subject, scheduleId, MeasurementUnits.PERCENTAGE, beginTime,
endTime);
result.setHeapPercentageUsed(heapUsedPercentageAggregateWithUnits);
}
@@ -405,13 +430,28 @@ public class StorageNodeManagerBean implements StorageNodeManagerLocal, StorageN
return result;
}
+ /**
+ * @param accumulator
+ * @param input
+ */
+ private void updateAggregateTotal(MeasurementAggregate accumulator, MeasurementAggregate input) {
+ if (accumulator != null && input != null
+ && input.getMax() != null && !Double.isNaN(input.getMax())
+ && input.getMin() != null && !Double.isNaN(input.getMin())
+ && input.getAvg() != null && !Double.isNaN(input.getAvg())) {
+ accumulator.setAvg(accumulator.getAvg() + input.getAvg());
+ accumulator.setMax(accumulator.getMax() + input.getMax());
+ accumulator.setMin(accumulator.getMin() + input.getMin());
+ }
+ }
+
@Override
public List<StorageNode> getStorageNodes() {
TypedQuery<StorageNode> query = entityManager.<StorageNode> createNamedQuery(StorageNode.QUERY_FIND_ALL,
StorageNode.class);
return query.getResultList();
}
-
+
@Override
@RequiredPermission(Permission.MANAGE_SETTINGS)
public PageList<StorageNode> findStorageNodesByCriteria(Subject subject, StorageNodeCriteria criteria) {
@@ -432,7 +472,7 @@ public class StorageNodeManagerBean implements StorageNodeManagerLocal, StorageN
Server server = serverManager.getServer();
// setting the server mode to maintenance
topologyManager.updateServerMode(subject, new Integer[] { server.getId() }, Server.OperationMode.MAINTENANCE);
-
+
Configuration parameters = new Configuration();
parameters.setSimpleValue("snapshotName", String.valueOf(System.currentTimeMillis()));
// scheduling the operation
@@ -543,7 +583,7 @@ public class StorageNodeManagerBean implements StorageNodeManagerLocal, StorageN
}
}
}
-
+
private StorageNodeLoadComposite.MeasurementAggregateWithUnits getMeasurementAggregateWithUnits(Subject subject,
int schedId, MeasurementUnits units, long beginTime, long endTime) {
MeasurementAggregate measurementAggregate = measurementManager.getAggregate(subject, schedId, beginTime,
@@ -553,7 +593,7 @@ public class StorageNodeManagerBean implements StorageNodeManagerLocal, StorageN
measurementAggregateWithUnits.setFormattedValue(getSummaryString(measurementAggregate, units));
return measurementAggregateWithUnits;
}
-
+
private int getResourceIdFromStorageNode(StorageNode storageNode) {
int resourceId;
if (storageNode.getResource() == null) {
diff --git a/modules/enterprise/server/plugins/alertdef-rhq/src/main/java/org/rhq/enterprise/server/plugins/alertdef/AlertDefinitionServerPluginComponent.java b/modules/enterprise/server/plugins/alertdef-rhq/src/main/java/org/rhq/enterprise/server/plugins/alertdef/AlertDefinitionServerPluginComponent.java
index 566dfe2..1cff654 100644
--- a/modules/enterprise/server/plugins/alertdef-rhq/src/main/java/org/rhq/enterprise/server/plugins/alertdef/AlertDefinitionServerPluginComponent.java
+++ b/modules/enterprise/server/plugins/alertdef-rhq/src/main/java/org/rhq/enterprise/server/plugins/alertdef/AlertDefinitionServerPluginComponent.java
@@ -54,15 +54,19 @@ import org.rhq.enterprise.server.util.LookupUtil;
/**
* An alert definition server-side plugin component that the server uses to inject "factory-installed" alert definitions.
- *
+ *
* @author Jay Shaughnessy
*/
public class AlertDefinitionServerPluginComponent implements ServerPluginComponent, ControlFacet {
private final Log log = LogFactory.getLog(AlertDefinitionServerPluginComponent.class);
+ private static final String PARTITION_DISK_USED_PERCENTAGE_METRIC_NAME = "Calculated.PartitionDiskUsedPercentage";
+ private static final String DATA_FILE_LOCATIONS_NAME = "AllDataFileLocations";
+
static private final List<InjectedTemplate> injectedTemplates;
static private final InjectedTemplate storageNodeHighHeapTemplate;
+ static private final InjectedTemplate storageNodeHighDiskUsageTemplate;
static {
storageNodeHighHeapTemplate = new InjectedTemplate(
@@ -71,8 +75,15 @@ public class AlertDefinitionServerPluginComponent implements ServerPluginCompone
"StorageNodeHighHeapTemplate", //
"An alert template to notify users of excessive heap use by an RHQ Storage Node. When fired please see documentation for the proper corrective action.");
+ storageNodeHighDiskUsageTemplate = new InjectedTemplate(
+ "RHQStorage", //
+ "StorageService", //
+ "StorageNodeHighDiskUsageTemplate", //
+ "An alert template to notify users of excessive heap use by an RHQ Storage Node. When fired please see documentation for the proper corrective action.");
+
injectedTemplates = new ArrayList<InjectedTemplate>();
injectedTemplates.add(storageNodeHighHeapTemplate);
+ injectedTemplates.add(storageNodeHighDiskUsageTemplate);
}
private ServerPluginContext context;
@@ -213,6 +224,8 @@ public class AlertDefinitionServerPluginComponent implements ServerPluginCompone
if (storageNodeHighHeapTemplate.equals(injectedAlertDef)) {
newAlertDefId = injectStorageNodeHighHeapTemplate(resourceType);
+ } else if (storageNodeHighDiskUsageTemplate.equals(injectedAlertDef)) {
+ newAlertDefId = injectStorageNodeHighDiskUsageTemplate(resourceType);
}
adc.addFilterId(newAlertDefId);
@@ -273,6 +286,57 @@ public class AlertDefinitionServerPluginComponent implements ServerPluginCompone
return newTemplateId;
}
+ private int injectStorageNodeHighDiskUsageTemplate(ResourceType resourceType) {
+ AlertTemplateManagerLocal alertTemplateManager = LookupUtil.getAlertTemplateManager();
+ SubjectManagerLocal subjectManager = LookupUtil.getSubjectManager();
+
+ AlertDefinition newTemplate = new AlertDefinition();
+ newTemplate.setName(storageNodeHighDiskUsageTemplate.getName());
+ newTemplate.setResourceType(resourceType);
+ newTemplate.setPriority(AlertPriority.MEDIUM);
+ newTemplate.setConditionExpression(BooleanExpression.ANY);
+ newTemplate.setRecoveryId(0);
+ newTemplate.setEnabled(true);
+
+ AlertCondition ac = new AlertCondition();
+ ac.setCategory(AlertConditionCategory.THRESHOLD);
+ ac.setComparator(">");
+ ac.setThreshold(0.75D);
+
+ List<Integer> measurementDefinitionIds = new ArrayList<Integer>(1);
+ for (MeasurementDefinition d : resourceType.getMetricDefinitions()) {
+ if (PARTITION_DISK_USED_PERCENTAGE_METRIC_NAME.equals(d.getName())) {
+ measurementDefinitionIds.add(d.getId());
+ ac.setMeasurementDefinition(d);
+ ac.setName(d.getDisplayName());
+ } else if (DATA_FILE_LOCATIONS_NAME.equals(d.getName())) {
+ measurementDefinitionIds.add(d.getId());
+ }
+ }
+ assert null != ac.getMeasurementDefinition() : "Did not find expected measurement definition "
+ + PARTITION_DISK_USED_PERCENTAGE_METRIC_NAME + " for "
+ + resourceType;
+ newTemplate.addCondition(ac);
+
+ AlertDampening dampener = new AlertDampening(AlertDampening.Category.PARTIAL_COUNT);
+ dampener.setPeriod(15);
+ dampener.setPeriodUnits(TimeUnits.MINUTES);
+ dampener.setValue(10);
+ newTemplate.setAlertDampening(dampener);
+
+ int newTemplateId = alertTemplateManager.createAlertTemplate(subjectManager.getOverlord(), newTemplate,
+ resourceType.getId());
+
+ // additionally, we want to ensure that the metric is enabled and collecting at a more frequent interval than
+ // is set by default.
+ MeasurementScheduleManagerLocal measurementManager = LookupUtil.getMeasurementScheduleManager();
+ measurementManager.updateDefaultCollectionIntervalAndEnablementForMeasurementDefinitions(
+ subjectManager.getOverlord(), ArrayUtils.toPrimitive(measurementDefinitionIds.toArray(new Integer[2])),
+ 60000L, true, true);
+
+ return newTemplateId;
+ }
+
private static class InjectedTemplate {
static public final String FIELD_PLUGIN_NAME = "plugin";
static public final String FIELD_RESOURCE_TYPE_NAME = "type";
diff --git a/modules/plugins/cassandra/src/main/java/org/rhq/plugins/cassandra/StorageServiceComponent.java b/modules/plugins/cassandra/src/main/java/org/rhq/plugins/cassandra/StorageServiceComponent.java
index b2987be..7281f9b 100644
--- a/modules/plugins/cassandra/src/main/java/org/rhq/plugins/cassandra/StorageServiceComponent.java
+++ b/modules/plugins/cassandra/src/main/java/org/rhq/plugins/cassandra/StorageServiceComponent.java
@@ -29,9 +29,10 @@ import static org.rhq.core.domain.measurement.AvailabilityType.DOWN;
import static org.rhq.core.domain.measurement.AvailabilityType.UNKNOWN;
import static org.rhq.core.domain.measurement.AvailabilityType.UP;
-import java.io.File;
import java.net.InetAddress;
import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -48,19 +49,20 @@ import org.rhq.core.domain.measurement.MeasurementReport;
import org.rhq.core.domain.measurement.MeasurementScheduleRequest;
import org.rhq.core.pluginapi.inventory.ResourceContext;
import org.rhq.core.pluginapi.operation.OperationResult;
+import org.rhq.core.system.FileSystemInfo;
import org.rhq.plugins.jmx.JMXComponent;
/**
* @author John Sanda
*/
public class StorageServiceComponent extends ComplexConfigurationResourceComponent {
-
+
private static final String OWNERSHIP_METRIC_NAME = "Ownership";
- private static final String DISK_USED_METRIC_NAME = "Calculated.DiskSpaceUsedPercentage";
+ private static final String PARTITION_DISK_USED_PERCENTAGE_METRIC_NAME = "Calculated.PartitionDiskUsedPercentage";
private static final String DATA_FILE_LOCATIONS_NAME = "AllDataFileLocations";
private Log log = LogFactory.getLog(StorageServiceComponent.class);
private InetAddress host;
-
+
@Override
public void start(ResourceContext<JMXComponent<?>> context) {
super.start(context);
@@ -73,7 +75,7 @@ public class StorageServiceComponent extends ComplexConfigurationResourceCompone
e);
}
}
-
+
@Override
public AvailabilityType getAvailability() {
ResourceContext<?> context = getResourceContext();
@@ -148,7 +150,7 @@ public class StorageServiceComponent extends ComplexConfigurationResourceCompone
return new OperationResult();
}
-
+
@Override
protected void getValues(MeasurementReport report, Set<MeasurementScheduleRequest> requests, EmsBean bean) {
super.getValues(report, requests, bean);
@@ -175,32 +177,43 @@ public class StorageServiceComponent extends ComplexConfigurationResourceCompone
report.addData(new MeasurementDataNumeric(request, value.doubleValue()));
}
break;
- } else if (DISK_USED_METRIC_NAME.equals(request.getName())) {
+ } else if (PARTITION_DISK_USED_PERCENTAGE_METRIC_NAME.equals(request.getName())) {
EmsAttribute attribute = bean.getAttribute(DATA_FILE_LOCATIONS_NAME);
Object valueObject = attribute.refresh();
if (valueObject instanceof String[]) {
- String[] paths = (String[]) valueObject;
- double max = 0;
- for (String path : paths) {
- double taken = getUsage(path);
- if (taken > max) {
- max = taken;
- }
- }
- if (max > 0.0001d) {
- report.addData(new MeasurementDataNumeric(request, max));
- }
+ //Please visit for details: https://issues.apache.org/jira/browse/CASSANDRA-2749
+ //The average usage of all partitions with the data will be reported.
+ //Cassandra selects the partition with most free space for SStable flush and compaction.
+ report.addData(new MeasurementDataNumeric(request,
+ getPartitionDiskUsedPercentage((String[]) valueObject)));
}
}
}
}
-
- private double getUsage(String path) {
- File f = new File(path);
- return ((double)f.getTotalSpace() - f.getUsableSpace()) / f.getTotalSpace();
- }
-
- public static boolean kindOfIP(final String addr) {
- return addr.matches("^\\d{1,3}\\.\\d{1,3\\.\\d{1,3\\.\\d{1,3$"); // || addr.indexOf(":") >= 0) or IPv6
+
+ private double getPartitionDiskUsedPercentage(String[] paths) {
+ List<String> visitedMountPoints = new ArrayList<String>();
+ long totalDiskSpace = 0;
+ long totalUsedDiskSpace = 0;
+
+ for (String path : paths) {
+ try {
+ FileSystemInfo fileSystemInfo = this.getResourceContext().getSystemInformation().getFileSystem(path);
+ if (!visitedMountPoints.contains(fileSystemInfo.getMountPoint())) {
+ visitedMountPoints.add(fileSystemInfo.getMountPoint());
+ totalDiskSpace += fileSystemInfo.getFileSystemUsage().getTotal();
+ totalUsedDiskSpace += fileSystemInfo.getFileSystemUsage().getUsed();
+ }
+ } catch (Exception e) {
+ log.error("Unable to determine file system usage information for data file location " + path, e);
+ }
+ }
+
+ if (totalDiskSpace != 0) {
+ double rawPercentage = ((double) totalUsedDiskSpace) / ((double) totalDiskSpace);
+ return Math.round(rawPercentage * 100.0) / 100.0;
+ }
+
+ return 0;
}
}
diff --git a/modules/plugins/cassandra/src/main/resources/META-INF/rhq-plugin.xml b/modules/plugins/cassandra/src/main/resources/META-INF/rhq-plugin.xml
index ebaef94..cac0a8d 100644
--- a/modules/plugins/cassandra/src/main/resources/META-INF/rhq-plugin.xml
+++ b/modules/plugins/cassandra/src/main/resources/META-INF/rhq-plugin.xml
@@ -183,7 +183,8 @@
</operation>
<metric property="CurrentGenerationNumber" dataType="trait" displayType="summary" description="Current generation number"/>
- <metric property="Calculated.DiskSpaceUsedPercentage" dataType="measurement" units="percentage" displayType="summary" description="How much of diskspace is already used. This takes into account the installation path, where Cassandra was installed."/>
+ <metric property="Calculated.PartitionDiskUsedPercentage" dataType="measurement" units="percentage" displayType="summary" description="Percentage of total disk space used for the partition that contains the data files.
+ If multiple data locations are specified then this will report the average utilization accross all the partitions."/>
<metric property="ExceptionCount" measurementType="trendsup" dataType="measurement" displayType="summary" description="Exception Count"/>
<metric property="Initialized" dataType="trait" displayType="summary" description="Initialized"/>
<metric property="Joined" dataType="trait" displayType="summary" description="Joined"/>
@@ -272,7 +273,7 @@
<c:simple-property name="nameTemplate" readOnly="true" type="string" default="Commit Log" />
</plugin-configuration>
- <metric property="TotalCommitlogSize" measurementType="trendsup" dataType="measurement" displayType="summary" description="Size of all commit log segments"/>
+ <metric property="TotalCommitlogSize" measurementType="dynamic" displayType="summary" description="Size of all commit log segments"/>
<metric property="PendingTasks" measurementType="dynamic" displayType="summary" description="Number of tasks waiting to be executed"/>
<metric property="CompletedTasks" measurementType="trendsup" displayType="summary" description="Number of completed tasks"/>
</service>
@@ -393,8 +394,8 @@
<metric property="KeyCacheCapacityInBytes" measurementType="dynamic" displayType="summary" description="Key cache capacity in bytes"/>
<metric property="RowCacheCapacityInBytes" measurementType="dynamic" displayType="summary" description="Row cache capacity in bytes"/>
- <metric property="KeyCacheSize" measurementType="dynamic" displayType="detail" description="Key cache size"/>
- <metric property="RowCacheSize" measurementType="dynamic" displayType="detail" description="Row cache size"/>
+ <metric property="KeyCacheSize" measurementType="dynamic" displayType="summary" description="Key cache size"/>
+ <metric property="RowCacheSize" measurementType="dynamic" displayType="summary" description="Row cache size"/>
<resource-configuration>
<c:simple-property name="KeyCacheCapacityInMB" type="long" required="true" displayName="Key Cache Capacity In MB" description="Key cache capacity in MB"/>
10 years, 11 months