/* * RHQ Management Platform * Copyright (C) 2005-2014 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 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 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ package org.rhq.enterprise.server.alert.test; import static java.util.concurrent.TimeUnit.MINUTES; import static java.util.concurrent.TimeUnit.SECONDS; import static org.rhq.test.AssertUtils.timedAssertion; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import org.testng.Assert; import org.testng.annotations.Test; 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.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.MeasurementDataTrait; import org.rhq.core.domain.measurement.MeasurementDefinition; import org.rhq.core.domain.measurement.MeasurementReport; import org.rhq.core.domain.measurement.MeasurementSchedule; import org.rhq.core.domain.measurement.MeasurementScheduleRequest; import org.rhq.core.domain.resource.Resource; import org.rhq.core.domain.resource.ResourceType; 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.test.TransactionCallback; import org.rhq.enterprise.server.test.TransactionCallbackReturnable; import org.rhq.enterprise.server.util.LookupUtil; import org.rhq.test.AssertUtils; @Test public class AlertConditionTest extends UpdatePluginMetadataTestBase { private static final boolean ENABLED = true; private Resource resource; @Override protected String getSubsystemDirectory() { return "alerts"; } @Override protected void afterMethod() throws Exception { if (resource != null) { deleteNewResource(resource); resource = null; } super.afterMethod(); } @Test(enabled = ENABLED) public void testBZ735262_InsideRangeCondition() throws Exception { // create our resource with alert definition MeasurementDefinition metricDef = createResourceWithMetricSchedule(); createAlertDefinitionWithOneInsideRangeCondition(metricDef, resource.getId()); // this test would fail if we used createAlertDefinitionWithTwoConditionsALL // re-load the resource so we get the measurement schedule Resource resourceWithSchedules = loadResourceWithSchedules(resource.getId()); MeasurementSchedule schedule = resourceWithSchedules.getSchedules().iterator().next(); // simulate a measurement report coming from the agent - two values, but neither fit in our range, so no alerts are fired MeasurementScheduleRequest request = new MeasurementScheduleRequest(schedule); MeasurementReport report = new MeasurementReport(); report.addData(new MeasurementDataNumeric(getTimestamp(60), request, 20.0)); // 20 < 60 but !(20 > 40) report.addData(new MeasurementDataNumeric(getTimestamp(30), request, 70.0)); // !(70 < 60) but 70 > 40 MeasurementDataManagerLocal dataManager = LookupUtil.getMeasurementDataManager(); dataManager.mergeMeasurementReport(report); // wait for our JMS messages to process and see if we get any alerts Thread.sleep(5000); // make sure no alert was triggered PageList<Alert> alerts = getAlerts(resourceWithSchedules.getId()); assert alerts.size() == 0 : "no alerts should have fired: " + alerts; // simulate another measurement report coming from the agent - one values that fits in our range, so 1 alert is fired request = new MeasurementScheduleRequest(schedule); report = new MeasurementReport(); report.addData(new MeasurementDataNumeric(getTimestamp(15), request, 50.0)); // 50 < 60 AND 50 > 40 dataManager.mergeMeasurementReport(report); // wait for our JMS messages to process and see if we get any alerts Thread.sleep(5000); // make sure one alert was triggered alerts = getAlerts(resourceWithSchedules.getId()); assert alerts.size() == 1 : "1 alert should have fired: " + alerts; } @Test(enabled = ENABLED) public void testBZ735262_OutsideRangeCondition() throws Exception { // create our resource with alert definition MeasurementDefinition metricDef = createResourceWithMetricSchedule(); createAlertDefinitionWithOneOutsideRangeCondition(metricDef, resource.getId()); // this test would fail if we used createAlertDefinitionWithTwoConditionsALL // re-load the resource so we get the measurement schedule Resource resourceWithSchedules = loadResourceWithSchedules(resource.getId()); MeasurementSchedule schedule = resourceWithSchedules.getSchedules().iterator().next(); // simulate a measurement report coming from the agent - one value that is inside our range, so no alerts are fired MeasurementScheduleRequest request = new MeasurementScheduleRequest(schedule); MeasurementReport report = new MeasurementReport(); report.addData(new MeasurementDataNumeric(getTimestamp(60), request, 50.0)); // 50 is inside the range 40...60 MeasurementDataManagerLocal dataManager = LookupUtil.getMeasurementDataManager(); dataManager.mergeMeasurementReport(report); // wait for our JMS messages to process and see if we get any alerts Thread.sleep(5000); // make sure no alert was triggered PageList<Alert> alerts = getAlerts(resourceWithSchedules.getId()); assert alerts.size() == 0 : "no alerts should have fired: " + alerts; // simulate another measurement report coming from the agent - one value that is outside the range, so 1 alert is fired request = new MeasurementScheduleRequest(schedule); report = new MeasurementReport(); report.addData(new MeasurementDataNumeric(getTimestamp(15), request, 20.0)); // 20 is outside 40...60 dataManager.mergeMeasurementReport(report); // wait for our JMS messages to process and see if we get any alerts Thread.sleep(5000); // make sure one alert was triggered alerts = getAlerts(resourceWithSchedules.getId()); assert alerts.size() == 1 : "1 alert should have fired: " + alerts; } @Test(enabled = ENABLED) public void testBZ736685_DeleteConditionLogButNoAlert() throws Exception { // create our resource with alert definition MeasurementDefinition metricDef = createResourceWithMetricSchedule(); AlertDefinition alertDef = createAlertDefinitionWithTwoConditionsALL(metricDef, resource.getId()); // re-load the resource so we get the measurement schedule Resource resourceWithSchedules = loadResourceWithSchedules(resource.getId()); MeasurementSchedule schedule = resourceWithSchedules.getSchedules().iterator().next(); // simulate a measurement report coming from the agent // with a single metric that makes a condition trigger but does not fire an alert MeasurementScheduleRequest request = new MeasurementScheduleRequest(schedule); MeasurementReport report = new MeasurementReport(); report.addData(new MeasurementDataNumeric(getTimestamp(60), request, 20.0)); // 20 < 60 but !(20 > 40) MeasurementDataManagerLocal dataManager = LookupUtil.getMeasurementDataManager(); dataManager.mergeMeasurementReport(report); // wait for our JMS messages to process and see if we get any alerts Thread.sleep(5000); PageList<Alert> alerts = getAlerts(resourceWithSchedules.getId()); assert alerts.size() == 0 : "no alerts should have fired: " + alerts; // ...but make sure a condition was true (the condition we know is true is "< 60") int condId = 0; for (AlertCondition cond : alertDef.getConditions()) { if (cond.getComparator().equals("<")) { condId = cond.getId(); break; } } assert condId > 0 : "failed to get the condition ID - something is wrong with test setup"; AlertCondition conditionWithLogs = getAlertConditionWithLogs(condId); // should eagerly load logs Set<AlertConditionLog> logs = conditionWithLogs.getConditionLogs(); assert logs != null && logs.size() > 0 : "missing condition log - we should have one that was generated"; AlertConditionLog log = logs.iterator().next(); assert log.getAlert() == null : "condition should not have fired an alert: " + logs; // 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?"; } @Test(enabled = ENABLED) public void testAvailChangeAlert() throws Exception { // create our resource with alert definition @SuppressWarnings("unused") 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 final PageList<Alert> finalAlerts = alerts; timedAssertion(new AssertUtils.BooleanCondition() { @Override public boolean eval() { PageList<Alert> pageList = getAlerts(resource.getId()); if (pageList.size() == 2) { finalAlerts.addAll(pageList); return true; } return false; } }, "Two alerts should have fired on the avail change", 1, MINUTES, 1, SECONDS); 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?"; } @Test(enabled = ENABLED) public void testAvailDurationAlert() throws Exception { // create our resource with two alert definitions (we use 2 to test BZ888927) @SuppressWarnings("unused") MeasurementDefinition metricDef = createResourceWithMetricSchedule(); // use a 10s duration, this is not allowed in general, the gui forces 1 minute minimum createAlertDefinitionWithAvailDurationCondition(resource.getId(), "testAvailDurationAlertDef_1", AlertConditionOperator.AVAIL_DURATION_DOWN, 10); createAlertDefinitionWithAvailDurationCondition(resource.getId(), "testAvailDurationAlertDef_2", 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(4000); 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(4000); alerts = getAlerts(resource.getId()); assert alerts.size() == 0 : "No alert should have fired after 4s, will take at least 10s: " + alerts; // wait for our alert condition duration to pass and see if we get any alerts timedAssertion(new AssertUtils.BooleanCondition() { @Override public boolean eval() { return getAlerts(resource.getId()).size() == 2; } }, "Two alerts should have fired on the avail duration", 1, MINUTES, 1, SECONDS); Thread.sleep(10000); // 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?"; } @Test(enabled = ENABLED) public void testBZ830463_updateDef() throws Exception { // create our resource with alert definition MeasurementDefinition metricDef = createResourceWithMetricSchedule(); AlertDefinition alertDef = createAlertDefinitionWithOneInsideRangeCondition(metricDef, resource.getId()); assert alertDef.getConditions().size() == 1 : "1 alertDef condition should exist"; AlertCondition condition = alertDef.getConditions().iterator().next(); int conditionId = condition.getId(); // re-load the resource so we get the measurement schedule Resource resourceWithSchedules = loadResourceWithSchedules(resource.getId()); MeasurementSchedule schedule = resourceWithSchedules.getSchedules().iterator().next(); // simulate a measurement report coming from the agent - one values that fits in our range, so 1 alert is fired MeasurementScheduleRequest request = new MeasurementScheduleRequest(schedule); MeasurementReport report = new MeasurementReport(); report.addData(new MeasurementDataNumeric(getTimestamp(15), request, 50.0)); // 50 < 60 AND 50 > 40 MeasurementDataManagerLocal dataManager = LookupUtil.getMeasurementDataManager(); dataManager.mergeMeasurementReport(report); // wait for our JMS messages to process and see if we get any alerts Thread.sleep(5000); // make sure one alert was triggered List<Alert> alerts = getAlerts(resourceWithSchedules.getId()); assert alerts.size() == 1 : "1 alert should have fired: " + alerts; Alert alert = alerts.get(0); assert alert.getConditionLogs().size() == 1 : "1 condition log should exist"; AlertConditionLog conditionLog = alert.getConditionLogs().iterator().next(); Assert.assertEquals(conditionLog.getCondition().getId(), conditionId, "original condition should have been associated with the alert"); // update a non-condition aspect of the def and then update the def String updatedDesc = "Updated Description"; alertDef.setDescription(updatedDesc); AlertDefinition updatedAlertDef = LookupUtil.getAlertDefinitionManager().updateAlertDefinition(getOverlord(), alertDef.getId(), alertDef, false); // note that resetMatching is false assert updatedDesc.equals(updatedAlertDef.getDescription()) : "Description should be updated"; assert updatedAlertDef.getConditions().size() == 1 : "1 alertDef condition should exist after the update"; assert updatedAlertDef.getConditions().iterator().next().getId() == condition.getId() : "condition should not be updated"; // get the alert again, and make sure it still has a log with the same condition alerts = getAlerts(resourceWithSchedules.getId()); assert alerts.size() == 1 : "1 alert should have fired: " + alerts; alert = alerts.get(0); assert alert.getConditionLogs().size() == 1 : "1 condition log should exist after the update"; conditionLog = alert.getConditionLogs().iterator().next(); Assert.assertEquals(conditionLog.getCondition().getId(), conditionId, "original condition should still have been associated with the alert"); // update the condition on the def and then update the def condition.setThreshold(41.0); updatedAlertDef = LookupUtil.getAlertDefinitionManager().updateAlertDefinition(getOverlord(), alertDef.getId(), alertDef, true); // note that resetMatching is true assert updatedAlertDef.getConditions().size() == 1 : "1 alertDef condition should exist after the update"; assert updatedAlertDef.getConditions().iterator().next().getId() != condition.getId() : "condition should be updated"; // get the alert again, and make sure it still has a log with the same condition alerts = getAlerts(resourceWithSchedules.getId()); assert alerts.size() == 1 : "1 alert should have fired: " + alerts; alert = alerts.get(0); assert alert.getConditionLogs().size() == 1 : "1 condition log should exist after the update"; conditionLog = alert.getConditionLogs().iterator().next(); Assert.assertEquals(conditionLog.getCondition().getId(), conditionId, "original condition should still have been associated with the alert"); } @Test(enabled = ENABLED) public void testBZ1058534_changeCondition() throws Exception { // create our resource with alert definition MeasurementDefinition metricDef = createResourceWithMetricSchedule("type-with-trait.xml", "TypeWithTrait"); AlertDefinition alertDef = createAlertDefinitionWithChangeFromNull(metricDef, resource.getId()); assert alertDef.getConditions().size() == 1 : "1 alertDef condition should exist"; AlertCondition condition = alertDef.getConditions().iterator().next(); int conditionId = condition.getId(); // re-load the resource so we get the measurement schedule final Resource resourceWithSchedules = loadResourceWithSchedules(resource.getId()); MeasurementSchedule schedule = resourceWithSchedules.getSchedules().iterator().next(); // simulate a measurement report coming from the agent - one values that changes value, so 1 alert is fired MeasurementScheduleRequest request = new MeasurementScheduleRequest(schedule); MeasurementReport report = new MeasurementReport(); report.addData(new MeasurementDataTrait(getTimestamp(15), request, "Foo")); MeasurementDataManagerLocal dataManager = LookupUtil.getMeasurementDataManager(); dataManager.mergeMeasurementReport(report); final Alert[] alertHolder = new Alert[1]; // wait for our JMS messages to process and see if we get any alerts timedAssertion(new AssertUtils.BooleanCondition() { @Override public boolean eval() { List<Alert> alerts = getAlerts(resourceWithSchedules.getId()); if (alerts.size() == 1) { alertHolder[0] = alerts.iterator().next(); return true; } return false; } }, "1 alert should have fired", 10, SECONDS, 1, SECONDS); Alert alert = alertHolder[0]; assert alert.getConditionLogs().size() == 1 : "1 condition log should exist"; AlertConditionLog conditionLog = alert.getConditionLogs().iterator().next(); Assert.assertEquals(conditionLog.getCondition().getId(), conditionId, "original condition should have been associated with the alert"); } public void testDampeningWorksAcrossConditionCacheReloads() throws Exception { MeasurementDefinition measDef = createResourceWithMetricSchedule(); createAlertDefinitionWithDampening(measDef, resource.getId()); Resource resourceWithSchedules = loadResourceWithSchedules(resource.getId()); MeasurementSchedule schedule = resourceWithSchedules.getSchedules().iterator().next(); //the dampening is set for 3 consecutive matches. //we want to test that the agent cache reload doesn't confuse the counting //first, send 2 matches MeasurementDataManagerLocal measurementDataManager = LookupUtil.getMeasurementDataManager(); MeasurementScheduleRequest request = new MeasurementScheduleRequest(schedule); MeasurementReport report = new MeasurementReport(); report.addData(new MeasurementDataNumeric(getTimestamp(25), request, 0d)); measurementDataManager.mergeMeasurementReport(report); Thread.sleep(3000); request = new MeasurementScheduleRequest(schedule); report = new MeasurementReport(); report.addData(new MeasurementDataNumeric(getTimestamp(20), request, 0d)); measurementDataManager.mergeMeasurementReport(report); Thread.sleep(3000); //now reload the caches reloadAllAlertConditionCaches(); //ok, so before BZ 1025491, after the cache reload, a non-match wouldn't cancel the counting. //so we need to test that if we send a non-match followed by a match we DON'T get an alert. //send a non-match, followed by a match request = new MeasurementScheduleRequest(schedule); report = new MeasurementReport(); report.addData(new MeasurementDataNumeric(getTimestamp(15), request, 1d)); measurementDataManager.mergeMeasurementReport(report); Thread.sleep(3000); request = new MeasurementScheduleRequest(schedule); report = new MeasurementReport(); report.addData(new MeasurementDataNumeric(getTimestamp(10), request, 0d)); measurementDataManager.mergeMeasurementReport(report); Thread.sleep(3000); //now, we should get NO alert List<Alert> alerts = getAlerts(resourceWithSchedules.getId()); assert alerts.size() == 0 : "No alert should have fired: " + alerts; //let's send in 2 more matches - we should be getting an alert request = new MeasurementScheduleRequest(schedule); report = new MeasurementReport(); report.addData(new MeasurementDataNumeric(getTimestamp(5), request, 0d)); measurementDataManager.mergeMeasurementReport(report); Thread.sleep(3000); //throw in a cache reload to check that it doesn't mess up the counting of the positives in sequence reloadAllAlertConditionCaches(); request = new MeasurementScheduleRequest(schedule); report = new MeasurementReport(); report.addData(new MeasurementDataNumeric(getTimestamp(0), request, 0d)); measurementDataManager.mergeMeasurementReport(report); //wait Thread.sleep(5000); //and check that this time, we GOT an alert alerts = getAlerts(resourceWithSchedules.getId()); assert alerts.size() == 1 : "1 alert should have fired: " + alerts; } private PageList<Alert> getAlerts(int resourceId) { AlertManagerLocal alertManager = LookupUtil.getAlertManager(); AlertCriteria alertCriteria = new AlertCriteria(); alertCriteria.addFilterResourceIds(resourceId); alertCriteria.fetchConditionLogs(true); return alertManager.findAlertsByCriteria(getOverlord(), alertCriteria); } private AlertCondition getAlertConditionWithLogs(final int conditionId) { return executeInTransaction(false, new TransactionCallbackReturnable<AlertCondition>() { @Override public AlertCondition execute() throws Exception { AlertCondition cond = em.find(AlertCondition.class, conditionId); cond.getConditionLogs().size(); // force the load return cond; } }); } private Resource loadResourceWithSchedules(int resourceId) { ResourceCriteria resourceCriteria = new ResourceCriteria(); resourceCriteria.addFilterId(resourceId); resourceCriteria.fetchSchedules(true); Resource resourceWithSchedules = getResource(resourceCriteria); assert resourceWithSchedules != null : "could not obtain resource from DB"; assert resourceWithSchedules.getSchedules() != null && resourceWithSchedules.getSchedules().size() == 1 : "missing schedule"; return resourceWithSchedules; } private AlertDefinition createAlertDefinitionWithTwoConditionsALL(MeasurementDefinition metricDef, int resourceId) { // create alert definition with the conditions "metric value > 40 AND metric value < 60" HashSet<AlertCondition> conditions = new HashSet<AlertCondition>(2); AlertCondition cond1 = new AlertCondition(); cond1.setCategory(AlertConditionCategory.THRESHOLD); cond1.setName(metricDef.getDisplayName()); cond1.setComparator(">"); cond1.setThreshold(40.0); // value > 40 threshold cond1.setOption(null); cond1.setMeasurementDefinition(metricDef); conditions.add(cond1); AlertCondition cond2 = new AlertCondition(); cond2.setCategory(AlertConditionCategory.THRESHOLD); cond2.setName(metricDef.getDisplayName()); cond2.setComparator("<"); cond2.setThreshold(60.0); // value < 60 threshold cond2.setOption(null); cond2.setMeasurementDefinition(metricDef); conditions.add(cond2); AlertDefinition alertDefinition = new AlertDefinition(); alertDefinition.setName("two condition ALL alert"); alertDefinition.setEnabled(true); alertDefinition.setPriority(AlertPriority.HIGH); alertDefinition.setAlertDampening(new AlertDampening(Category.NONE)); alertDefinition.setRecoveryId(0); alertDefinition.setConditionExpression(BooleanExpression.ALL); alertDefinition.setConditions(conditions); AlertDefinitionManagerLocal alertDefManager = LookupUtil.getAlertDefinitionManager(); alertDefinition = alertDefManager.createAlertDefinitionInNewTransaction(getOverlord(), alertDefinition, resourceId, true); 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 createAlertDefinitionWithDampening(MeasurementDefinition metricDef, int resourceId) { AlertCondition cond = new AlertCondition(); cond.setCategory(AlertConditionCategory.THRESHOLD); cond.setName(metricDef.getDisplayName()); cond.setComparator("="); cond.setThreshold(0d); // value = 0 threshold cond.setOption(null); cond.setMeasurementDefinition(metricDef); AlertDampening dampening = new AlertDampening(Category.CONSECUTIVE_COUNT); dampening.setValue(3); AlertDefinition alertDefinition = new AlertDefinition(); alertDefinition.setName("alert with consecutive count = 3 dampening"); alertDefinition.setEnabled(true); alertDefinition.setPriority(AlertPriority.HIGH); alertDefinition.setAlertDampening(dampening); alertDefinition.setRecoveryId(0); alertDefinition.setConditionExpression(BooleanExpression.ALL); alertDefinition.setConditions(Collections.singleton(cond)); AlertDefinitionManagerLocal alertDefManager = LookupUtil.getAlertDefinitionManager(); alertDefinition = alertDefManager.createAlertDefinitionInNewTransaction(getOverlord(), alertDefinition, resourceId, true); 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 createAlertDefinitionWithOneInsideRangeCondition(MeasurementDefinition metricDef, int resourceId) { // create alert definition with the range condition "metric value between 40...60" HashSet<AlertCondition> conditions = new HashSet<AlertCondition>(1); AlertCondition cond1 = new AlertCondition(); cond1.setCategory(AlertConditionCategory.RANGE); cond1.setName(metricDef.getDisplayName()); cond1.setThreshold(40.0); // threshold is always the low value of the range cond1.setOption(Double.valueOf(60.0).toString()); // option is a stringified double that is always the high value of the range cond1.setComparator("<"); // the value must be inside the range cond1.setMeasurementDefinition(metricDef); conditions.add(cond1); AlertDefinition alertDefinition = new AlertDefinition(); alertDefinition.setName("one inside-range condition alert"); alertDefinition.setEnabled(true); alertDefinition.setPriority(AlertPriority.HIGH); alertDefinition.setAlertDampening(new AlertDampening(Category.NONE)); alertDefinition.setRecoveryId(0); alertDefinition.setConditionExpression(BooleanExpression.ALL); alertDefinition.setConditions(conditions); AlertDefinitionManagerLocal alertDefManager = LookupUtil.getAlertDefinitionManager(); alertDefinition = alertDefManager.createAlertDefinitionInNewTransaction(getOverlord(), alertDefinition, resourceId, true); 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 createAlertDefinitionWithChangeFromNull(MeasurementDefinition metricDef, int resourceId) { HashSet<AlertCondition> conditions = new HashSet<AlertCondition>(1); AlertCondition cond1 = new AlertCondition(); cond1.setCategory(AlertConditionCategory.TRAIT); cond1.setName(metricDef.getDisplayName()); cond1.setMeasurementDefinition(metricDef); conditions.add(cond1); AlertDefinition alertDefinition = new AlertDefinition(); alertDefinition.setName("one trait change from null alert"); alertDefinition.setEnabled(true); alertDefinition.setPriority(AlertPriority.HIGH); alertDefinition.setAlertDampening(new AlertDampening(Category.NONE)); alertDefinition.setRecoveryId(0); alertDefinition.setConditionExpression(BooleanExpression.ALL); alertDefinition.setConditions(conditions); AlertDefinitionManagerLocal alertDefManager = LookupUtil.getAlertDefinitionManager(); alertDefinition = alertDefManager.createAlertDefinitionInNewTransaction(getOverlord(), alertDefinition, resourceId, true); 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 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(0); alertDefinition.setConditionExpression(BooleanExpression.ALL); alertDefinition.setConditions(conditions); AlertDefinitionManagerLocal alertDefManager = LookupUtil.getAlertDefinitionManager(); alertDefinition = alertDefManager.createAlertDefinitionInNewTransaction(getOverlord(), alertDefinition, resourceId, true); 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, String alertDefName, 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(alertDefName); alertDefinition.setEnabled(true); alertDefinition.setPriority(AlertPriority.HIGH); alertDefinition.setAlertDampening(new AlertDampening(Category.NONE)); alertDefinition.setRecoveryId(0); alertDefinition.setConditionExpression(BooleanExpression.ALL); alertDefinition.setConditions(conditions); AlertDefinitionManagerLocal alertDefManager = LookupUtil.getAlertDefinitionManager(); alertDefinition = alertDefManager.createAlertDefinitionInNewTransaction(getOverlord(), alertDefinition, resourceId, true); 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" HashSet<AlertCondition> conditions = new HashSet<AlertCondition>(1); AlertCondition cond1 = new AlertCondition(); cond1.setCategory(AlertConditionCategory.RANGE); cond1.setName(metricDef.getDisplayName()); cond1.setThreshold(40.0); // threshold is always the low value of the range cond1.setOption(Double.valueOf(60.0).toString()); // option is a stringified double that is always the high value of the range cond1.setComparator(">"); // the value must be outside the range cond1.setMeasurementDefinition(metricDef); conditions.add(cond1); AlertDefinition alertDefinition = new AlertDefinition(); alertDefinition.setName("one outside-range condition alert"); alertDefinition.setEnabled(true); alertDefinition.setPriority(AlertPriority.HIGH); alertDefinition.setAlertDampening(new AlertDampening(Category.NONE)); alertDefinition.setRecoveryId(0); alertDefinition.setConditionExpression(BooleanExpression.ALL); alertDefinition.setConditions(conditions); AlertDefinitionManagerLocal alertDefManager = LookupUtil.getAlertDefinitionManager(); alertDefinition = alertDefManager.createAlertDefinitionInNewTransaction(getOverlord(), alertDefinition, resourceId, true); 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; } /** * Creates a resource, stores it in the "resource" data field and returns the measurement definition * that the schedule is for. * * @return measurement definition that was used to create the schedule for the new resource * @throws Exception */ private MeasurementDefinition createResourceWithMetricSchedule() throws Exception { return createResourceWithMetricSchedule("type-with-metric.xml", "TypeWithMetrics"); } /** * Creates a resource, stores it in the "resource" data field and returns the measurement definition * that the schedule is for. * * @return measurement definition that was used to create the schedule for the new resource * @throws Exception */ private MeasurementDefinition createResourceWithMetricSchedule(String plugin, String typeName) throws Exception { registerPlugin(plugin); ResourceType resourceType = getResourceType(typeName); assert resourceType != null : "failed to deploy resource type"; assert resourceType.getMetricDefinitions() != null : "failed to create metric defs"; assert resourceType.getMetricDefinitions().size() == 1 : "do not have the expected number of metric defs"; final MeasurementDefinition metricDef = resourceType.getMetricDefinitions().iterator().next(); resource = persistNewResource(resourceType.getName()); // will have UNKNOWN avail assert resource != null && resource.getId() > 0 : "failed to create test resource"; executeInTransaction(false, new TransactionCallback() { @Override public void execute() throws Exception { MeasurementSchedule schedule = new MeasurementSchedule(metricDef, resource); em.persist(schedule); } }); // create a server which attaches our agent to it - we need this for the alert subsystem to do its thing createServerIdentity(); return metricDef; } /** * Returns a epoch millis timestamp that is the current time minus the given number of seconds. * In other words, this returns a time in the past - how far in the past is determined by the * number of seconds parameter. */ private long getTimestamp(long secondsAgo) { return System.currentTimeMillis() - (secondsAgo * 1000); } private void reloadAllAlertConditionCaches() { LookupUtil.getAlertConditionCacheManager().reloadAllCaches(); } }