modules/core/domain/src/main/java/org/rhq/core/domain/alert/composite/AlertConditionAvailabilityCategoryComposite.java
| 4
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertFormatUtility.java
| 3
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/NewConditionEditor.java
| 4
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java
| 3
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/model/AvailabilityDurationCacheElement.java
| 5
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/alert/test/AlertConditionTest.java
| 192 +++++++++-
6 files changed, 201 insertions(+), 10 deletions(-)
New commits:
commit cc0002a38492c653e8943a592a58943ce1500080
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Wed Feb 29 16:42:44 2012 -0500
Add tests for Avail Change and Avail Duration conditions. To support
faster tests change storage of durations from minutes to seconds. Note that
the gui will still treat user input in minutes, making the minimum
non-test duration 1 minute.
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertFormatUtility.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertFormatUtility.java
index 80d52d2..abcde0b 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertFormatUtility.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertFormatUtility.java
@@ -93,7 +93,8 @@ public class AlertFormatUtility {
}
str.append(" For ");
- String value = condition.getOption();
+ // value is stored in seconds but should be presented in minutes
+ String value = String.valueOf(Integer.valueOf(condition.getOption()) * 60);
String formatted = MeasurementConverterClient.format(value,
MeasurementUnits.MINUTES);
str.append(formatted);
str.append("]");
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/NewConditionEditor.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/NewConditionEditor.java
index 5f29d29..0e4b8c5 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/NewConditionEditor.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/NewConditionEditor.java
@@ -346,7 +346,9 @@ public class NewConditionEditor extends LocatableDynamicForm {
newCondition.setName(getValueAsString(AVAILABILITY_DURATION_ITEMNAME));
newCondition.setComparator(null);
newCondition.setThreshold(null);
-
newCondition.setOption(getValueAsString(AVAILABILITY_DURATION_VAL_ITEMNAME));
+ // user enters value in minutes but the value is stored in seconds
+ int duration = 60 *
Integer.valueOf(getValueAsString(AVAILABILITY_DURATION_VAL_ITEMNAME));
+ newCondition.setOption(String.valueOf(duration));
newCondition.setMeasurementDefinition(null);
break;
}
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java
index 3717ee5..d50c736 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java
@@ -871,7 +871,8 @@ public class AlertManagerBean implements AlertManagerLocal,
AlertManagerRemote {
str.append(AlertI18NFactory.getMessage(msg));
str.append(" [");
- String value = condition.getOption();
+ // stored in seconds but present in minutes
+ String value = String.valueOf(Integer.valueOf(condition.getOption()) * 60);
String formatted = MeasurementConverter.format(value,
MeasurementUnits.MINUTES);
str.append(formatted);
str.append("]");
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/model/AvailabilityDurationCacheElement.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/model/AvailabilityDurationCacheElement.java
index beeafbd..ea608f5 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/model/AvailabilityDurationCacheElement.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/engine/model/AvailabilityDurationCacheElement.java
@@ -43,7 +43,7 @@ public final class AvailabilityDurationCacheElement extends
AbstractEnumCacheEle
/**
* @param operator
- * @param operatorOption the duration, in minutes (as String)
+ * @param operatorOption the duration, in seconds (as String)
* @param value
* @param conditionTriggerId this is actually the alertConditionId, renamed here.
*/
@@ -106,7 +106,8 @@ public final class AvailabilityDurationCacheElement extends
AbstractEnumCacheEle
String operator = cacheElement.getAlertConditionOperator().name();
String triggerName = operator + "-" + resource.getId();
String duration = (String) cacheElement.getAlertConditionOperatorOption();
- Date jobTime = new Date(System.currentTimeMillis() +
(Long.valueOf(duration).longValue() * 60 * 1000));
+ // convert from seconds to milliseconds
+ Date jobTime = new Date(System.currentTimeMillis() +
(Long.valueOf(duration).longValue() * 1000));
if (log.isDebugEnabled()) {
log.debug("Scheduling availability duration job for [" +
DateFormat.getDateTimeInstance().format(jobTime)
diff --git
a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/alert/test/AlertConditionTest.java
b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/alert/test/AlertConditionTest.java
index b6c7206..645d049 100644
---
a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/alert/test/AlertConditionTest.java
+++
b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/alert/test/AlertConditionTest.java
@@ -35,14 +35,18 @@ import org.rhq.core.domain.alert.Alert;
import org.rhq.core.domain.alert.AlertCondition;
import org.rhq.core.domain.alert.AlertConditionCategory;
import org.rhq.core.domain.alert.AlertConditionLog;
+import org.rhq.core.domain.alert.AlertConditionOperator;
import org.rhq.core.domain.alert.AlertDampening;
+import org.rhq.core.domain.alert.AlertDampening.Category;
import org.rhq.core.domain.alert.AlertDefinition;
import org.rhq.core.domain.alert.AlertPriority;
import org.rhq.core.domain.alert.BooleanExpression;
-import org.rhq.core.domain.alert.AlertDampening.Category;
import org.rhq.core.domain.cloud.Server;
import org.rhq.core.domain.criteria.AlertCriteria;
import org.rhq.core.domain.criteria.ResourceCriteria;
+import org.rhq.core.domain.discovery.AvailabilityReport;
+import org.rhq.core.domain.discovery.AvailabilityReport.Datum;
+import org.rhq.core.domain.measurement.AvailabilityType;
import org.rhq.core.domain.measurement.MeasurementDataNumeric;
import org.rhq.core.domain.measurement.MeasurementDefinition;
import org.rhq.core.domain.measurement.MeasurementReport;
@@ -55,14 +59,19 @@ import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.server.alert.AlertDefinitionManagerLocal;
import org.rhq.enterprise.server.alert.AlertManagerLocal;
+import org.rhq.enterprise.server.measurement.AvailabilityManagerLocal;
import org.rhq.enterprise.server.measurement.MeasurementDataManagerLocal;
import org.rhq.enterprise.server.resource.metadata.test.UpdatePluginMetadataTestBase;
+import org.rhq.enterprise.server.scheduler.SchedulerLocal;
+import org.rhq.enterprise.server.scheduler.jobs.AlertAvailabilityDurationJob;
import org.rhq.enterprise.server.util.LookupUtil;
import org.rhq.test.JPAUtils;
import org.rhq.test.TransactionCallbackWithContext;
@Test
public class AlertConditionTest extends UpdatePluginMetadataTestBase {
+ private static final boolean ENABLED = false;
+
// this must match the constant found in ServerManagerBean
private static final String RHQ_SERVER_NAME_PROPERTY =
"rhq.server.high-availability.name";
private static final String RHQ_SERVER_NAME_PROPERTY_VALUE =
"AlertConditionTestServer";
@@ -97,6 +106,7 @@ public class AlertConditionTest extends UpdatePluginMetadataTestBase {
System.setProperty(RHQ_SERVER_NAME_PROPERTY, "");
}
+ @Test(enabled = ENABLED)
public void testBZ735262_InsideRangeCondition() throws Exception {
// create our resource with alert definition
MeasurementDefinition metricDef = createResourceWithMetricSchedule();
@@ -136,6 +146,7 @@ public class AlertConditionTest extends UpdatePluginMetadataTestBase
{
return;
}
+ @Test(enabled = ENABLED)
public void testBZ735262_OutsideRangeCondition() throws Exception {
// create our resource with alert definition
MeasurementDefinition metricDef = createResourceWithMetricSchedule();
@@ -174,6 +185,7 @@ public class AlertConditionTest extends UpdatePluginMetadataTestBase
{
return;
}
+ @Test(enabled = ENABLED)
public void testBZ736685_DeleteConditionLogButNoAlert() throws Exception {
// create our resource with alert definition
MeasurementDefinition metricDef = createResourceWithMetricSchedule();
@@ -218,13 +230,119 @@ public class AlertConditionTest extends
UpdatePluginMetadataTestBase {
resource = null;
AlertDefinitionManagerLocal alertDefManager =
LookupUtil.getAlertDefinitionManager();
- PageList<AlertDefinition> defs =
alertDefManager.findAlertDefinitions(getOverlord(), resourceId, PageControl
- .getUnlimitedInstance());
+ PageList<AlertDefinition> defs =
alertDefManager.findAlertDefinitions(getOverlord(), resourceId,
+ PageControl.getUnlimitedInstance());
assert defs.isEmpty() : "failed to delete the alert definition - are
condition logs still around?";
return;
}
+ @Test(enabled = ENABLED)
+ public void testAvailChangeAlert() throws Exception {
+ // create our resource with alert definition
+ MeasurementDefinition metricDef = createResourceWithMetricSchedule();
+ createAlertDefinitionWithAvailChangeCondition(resource.getId(),
AlertConditionOperator.AVAIL_GOES_DOWN);
+ createAlertDefinitionWithAvailChangeCondition(resource.getId(),
AlertConditionOperator.AVAIL_GOES_NOT_UP);
+
+ // resource has initial UNKNOWN ResourceAvailability and no Availability records.
simulate an avail report
+ // coming from the agent and setting the initial avail to UP.
+ AvailabilityReport availReport = new AvailabilityReport(AGENT_NAME);
+ availReport.addAvailability(new Datum(resource.getId(), AvailabilityType.UP,
System.currentTimeMillis()));
+ AvailabilityManagerLocal availManager = LookupUtil.getAvailabilityManager();
+ availManager.mergeAvailabilityReport(availReport);
+
+ // wait for our JMS messages to process and see if we get any alerts
+ Thread.sleep(3000);
+
+ PageList<Alert> alerts = getAlerts(resource.getId());
+ assert alerts.size() == 0 : "No alert should have fired on the initial avail
reporting: " + alerts;
+
+ // Now simulate the down avail
+ availReport = new AvailabilityReport(AGENT_NAME);
+ availReport
+ .addAvailability(new Datum(resource.getId(), AvailabilityType.DOWN,
System.currentTimeMillis() + 10));
+ availManager.mergeAvailabilityReport(availReport);
+
+ // wait for our JMS messages to process and see if we get any alerts
+ Thread.sleep(3000);
+
+ alerts = getAlerts(resource.getId());
+ assert alerts.size() == 2 : "Two alerts should have fired on the avail
change: " + alerts;
+
+ assert
!alerts.get(0).getAlertDefinition().getName().equals(alerts.get(1).getAlertDefinition().getName())
: "Alerts should have been from different definitions";
+
+ // purge the resource fully, which should remove all alert defs and alert
conditions and condition logs
+ int resourceId = resource.getId();
+ deleteNewResource(resource);
+ resource = null;
+
+ AlertDefinitionManagerLocal alertDefManager =
LookupUtil.getAlertDefinitionManager();
+ PageList<AlertDefinition> defs =
alertDefManager.findAlertDefinitions(getOverlord(), resourceId,
+ PageControl.getUnlimitedInstance());
+ assert defs.isEmpty() : "failed to delete the alert definition - are
condition logs still around?";
+
+ return;
+ }
+
+ @Test(enabled = ENABLED)
+ public void testAvailDurationAlert() throws Exception {
+ try {
+ prepareScheduler();
+ SchedulerLocal scheduler = LookupUtil.getSchedulerBean();
+ scheduler.scheduleTriggeredJob(AlertAvailabilityDurationJob.class, false,
null);
+
+ // create our resource with alert definition
+ MeasurementDefinition metricDef = createResourceWithMetricSchedule();
+ // use a 10s duration, this is not allowed in general, the gui forces 1
minute minimum
+ createAlertDefinitionWithAvailDurationCondition(resource.getId(),
+ AlertConditionOperator.AVAIL_DURATION_DOWN, 10);
+
+ // resource has initial UNKNOWN ResourceAvailability and no Availability
records. simulate an avail report
+ // coming from the agent and setting the initial avail to UP.
+ AvailabilityReport availReport = new AvailabilityReport(AGENT_NAME);
+ availReport.addAvailability(new Datum(resource.getId(), AvailabilityType.UP,
System.currentTimeMillis()));
+ AvailabilityManagerLocal availManager = LookupUtil.getAvailabilityManager();
+ availManager.mergeAvailabilityReport(availReport);
+
+ // wait for our JMS messages to process and see if we get any alerts
+ Thread.sleep(3000);
+
+ PageList<Alert> alerts = getAlerts(resource.getId());
+ assert alerts.size() == 0 : "No alert should have fired on the initial
avail reporting: " + alerts;
+
+ // Now simulate the down avail
+ availReport = new AvailabilityReport(AGENT_NAME);
+ availReport.addAvailability(new Datum(resource.getId(),
AvailabilityType.DOWN,
+ System.currentTimeMillis() + 10));
+ availManager.mergeAvailabilityReport(availReport);
+
+ // wait for our JMS messages to process and see if we get any alerts
+ Thread.sleep(5000);
+
+ alerts = getAlerts(resource.getId());
+ assert alerts.size() == 0 : "No alert should have fired after 30s, will
take at least a minute: " + alerts;
+
+ // wait for our JMS messages to process and see if we get any alerts
+ Thread.sleep(6000);
+
+ alerts = getAlerts(resource.getId());
+ assert alerts.size() == 1 : "One alert should have fired on the avail
duration: " + alerts;
+
+ // purge the resource fully, which should remove all alert defs and alert
conditions and condition logs
+ int resourceId = resource.getId();
+ deleteNewResource(resource);
+ resource = null;
+
+ AlertDefinitionManagerLocal alertDefManager =
LookupUtil.getAlertDefinitionManager();
+ PageList<AlertDefinition> defs =
alertDefManager.findAlertDefinitions(getOverlord(), resourceId,
+ PageControl.getUnlimitedInstance());
+ assert defs.isEmpty() : "failed to delete the alert definition - are
condition logs still around?";
+
+ } finally {
+ unprepareScheduler();
+ }
+ }
+
private PageList<Alert> getAlerts(int resourceId) {
AlertManagerLocal alertManager = LookupUtil.getAlertManager();
AlertCriteria alertCriteria = new AlertCriteria();
@@ -330,6 +448,72 @@ public class AlertConditionTest extends UpdatePluginMetadataTestBase
{
return alertDefinition;
}
+ private AlertDefinition createAlertDefinitionWithAvailChangeCondition(int
resourceId,
+ AlertConditionOperator condition) {
+ HashSet<AlertCondition> conditions = new HashSet<AlertCondition>(1);
+ AlertCondition cond1 = new AlertCondition();
+ cond1.setCategory(AlertConditionCategory.AVAILABILITY);
+ cond1.setName(condition.name());
+ cond1.setThreshold(null);
+ cond1.setOption(null);
+ cond1.setComparator(null);
+ cond1.setMeasurementDefinition(null);
+ conditions.add(cond1);
+
+ AlertDefinition alertDefinition = new AlertDefinition();
+ alertDefinition.setName("avail change: " + condition.name());
+ alertDefinition.setEnabled(true);
+ alertDefinition.setPriority(AlertPriority.HIGH);
+ alertDefinition.setAlertDampening(new AlertDampening(Category.NONE));
+ alertDefinition.setRecoveryId(Integer.valueOf(0));
+ alertDefinition.setConditionExpression(BooleanExpression.ALL);
+ alertDefinition.setConditions(conditions);
+
+ AlertDefinitionManagerLocal alertDefManager =
LookupUtil.getAlertDefinitionManager();
+ int defId = alertDefManager.createAlertDefinition(getOverlord(), alertDefinition,
resourceId);
+ alertDefinition = alertDefManager.getAlertDefinition(getOverlord(), defId); //
load it back so we get its ID and all condition IDs
+ assert alertDefinition != null && alertDefinition.getId() > 0 :
"did not persist alert def properly: "
+ + alertDefinition;
+
+ // now that we created an alert def, we have to reload the alert condition cache
+ reloadAllAlertConditionCaches();
+
+ return alertDefinition;
+ }
+
+ private AlertDefinition createAlertDefinitionWithAvailDurationCondition(int
resourceId,
+ AlertConditionOperator condition, int duration) {
+ HashSet<AlertCondition> conditions = new HashSet<AlertCondition>(1);
+ AlertCondition cond1 = new AlertCondition();
+ cond1.setCategory(AlertConditionCategory.AVAIL_DURATION);
+ cond1.setName(condition.name());
+ cond1.setThreshold(null);
+ cond1.setOption(String.valueOf(duration));
+ cond1.setComparator(null);
+ cond1.setMeasurementDefinition(null);
+ conditions.add(cond1);
+
+ AlertDefinition alertDefinition = new AlertDefinition();
+ alertDefinition.setName("avail duration: " + condition.name());
+ alertDefinition.setEnabled(true);
+ alertDefinition.setPriority(AlertPriority.HIGH);
+ alertDefinition.setAlertDampening(new AlertDampening(Category.NONE));
+ alertDefinition.setRecoveryId(Integer.valueOf(0));
+ alertDefinition.setConditionExpression(BooleanExpression.ALL);
+ alertDefinition.setConditions(conditions);
+
+ AlertDefinitionManagerLocal alertDefManager =
LookupUtil.getAlertDefinitionManager();
+ int defId = alertDefManager.createAlertDefinition(getOverlord(), alertDefinition,
resourceId);
+ alertDefinition = alertDefManager.getAlertDefinition(getOverlord(), defId); //
load it back so we get its ID and all condition IDs
+ assert alertDefinition != null && alertDefinition.getId() > 0 :
"did not persist alert def properly: "
+ + alertDefinition;
+
+ // now that we created an alert def, we have to reload the alert condition cache
+ reloadAllAlertConditionCaches();
+
+ return alertDefinition;
+ }
+
private AlertDefinition
createAlertDefinitionWithOneOutsideRangeCondition(MeasurementDefinition metricDef,
int resourceId) {
// create alert definition with the range condition "metric value outside
40...60"
@@ -380,7 +564,7 @@ public class AlertConditionTest extends UpdatePluginMetadataTestBase
{
final MeasurementDefinition metricDef =
resourceType.getMetricDefinitions().iterator().next();
- resource = persistNewResource(resourceType.getName());
+ resource = persistNewResource(resourceType.getName()); // will have UNKNOWN
avail
assert resource != null && resource.getId() > 0 : "failed to
create test resource";
JPAUtils.executeInTransaction(new TransactionCallbackWithContext<Object>()
{
commit 7c3bf70d0cb8f82fd296e2b5ec7cad8e8bc70d22
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Wed Feb 29 16:38:57 2012 -0500
Fix a bug for alerting against new resources, that do not yet have
any Availability records.
diff --git
a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/composite/AlertConditionAvailabilityCategoryComposite.java
b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/composite/AlertConditionAvailabilityCategoryComposite.java
index fd4ccb4..22ab463 100644
---
a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/composite/AlertConditionAvailabilityCategoryComposite.java
+++
b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/composite/AlertConditionAvailabilityCategoryComposite.java
@@ -40,8 +40,10 @@ public class AlertConditionAvailabilityCategoryComposite extends
AbstractAlertCo
AvailabilityType availabilityType) {
super(condition);
+
this.resourceId = resourceId;
- this.availabilityType = availabilityType;
+ // For a resource with no Availability records, ensure we initialize to UNKNOWN
as opposed to null
+ this.availabilityType = (null != availabilityType) ? availabilityType :
AvailabilityType.UNKNOWN;
}
public Integer getResourceId() {