modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertFormatUtility.java | 90 +++ modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/definitions/NewConditionEditor.java | 227 +++++++++- 2 files changed, 287 insertions(+), 30 deletions(-)
New commits: commit 665349f2a221a7aed276f67197ca9289fba322b2 Author: John Mazzitelli mazz@redhat.com Date: Mon Sep 20 13:05:03 2010 -0400
bz 535756 add the ability to create calltime conditions to an alert definition
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 098e92a..14cb2c2 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 @@ -54,17 +54,40 @@ public class AlertFormatUtility { break; } case THRESHOLD: { - str.append("Metric Value Exceeds Threshold"); - str.append(" ["); - str.append(condition.getName()); - str.append(" "); - str.append(condition.getComparator()); - str.append(" "); double value = condition.getThreshold(); MeasurementUnits units = condition.getMeasurementDefinition().getUnits(); String formatted = MeasurementConverterClient.format(value, units, true); - str.append(formatted); - str.append("]"); + + if (condition.getOption() == null) { + str.append("Metric Value Exceeds Threshold"); + str.append(" ["); + str.append(condition.getName()); + str.append(" "); + str.append(condition.getComparator()); + str.append(" "); + str.append(formatted); + str.append("]"); + } else { + // this is a calltime threshold condition + // the name of the metric is only obtainable by querying for the name from the meas def ID + // but since most times (all the time?) there is only one calltime metric per resource, + // not showing the metric name probably isn't detrimental + str.append("Calltime Value Exceeds Threshold"); + str.append(" ["); + str.append(condition.getOption()); // MIN, MAX, AVG (never null) + str.append(" "); + str.append(condition.getComparator()); // <, >, = + str.append(" "); + str.append(condition.getThreshold()); + str.append("]"); + if (condition.getName() != null && condition.getName().length() > 0) { + str.append(" "); + str.append("with call destination matching"); + str.append(" '"); + str.append(condition.getName()); + str.append("'"); + } + } break; } case BASELINE: { @@ -86,10 +109,39 @@ public class AlertFormatUtility { break; } case CHANGE: { - str.append("Metric Value Change"); - str.append(" ["); - str.append(condition.getName()); - str.append("]"); + if (condition.getOption() == null) { + str.append("Metric Value Change"); + str.append(" ["); + str.append(condition.getName()); + str.append("]"); + } else { + // this is a calltime change condition + // the name of the metric is only obtainable by querying for the name from the meas def ID + // but since most times (all the time?) there is only one calltime metric per resource, + // not showing the metric name probably isn't detrimental + str.append("Calltime Value Changes"); + str.append(" ["); + str.append(condition.getOption()); // MIN, MAX, AVG (never null) + str.append(" "); + str.append(getCalltimeChangeComparator(condition.getComparator())); // LO, HI, CH + str.append(" "); + str.append("by at least"); + str.append(" "); + + double value = condition.getThreshold(); + MeasurementUnits units = MeasurementUnits.PERCENTAGE; + String formatted = MeasurementConverterClient.format(value, units, true); + str.append(formatted); + + str.append("]"); + if (condition.getName() != null && condition.getName().length() > 0) { + str.append(" "); + str.append("with call destination matching"); + str.append(" '"); + str.append(condition.getName()); + str.append("'"); + } + } break; } case TRAIT: { @@ -122,9 +174,9 @@ public class AlertFormatUtility { if (condition.getOption() != null && condition.getOption().length() > 0) { str.append(" "); str.append("matching"); - str.append(" ["); + str.append(" '"); str.append(condition.getOption()); - str.append("]"); + str.append("'"); } break; } @@ -136,6 +188,16 @@ public class AlertFormatUtility { return str.toString(); }
+ private static String getCalltimeChangeComparator(String comparator) { + if ("HI".equals(comparator)) { + return "Grows"; + } else if ("LO".equals(comparator)) { + return "Shrinks"; + } else { // CH + return "Changes"; + } + } + public static String getAlertRecoveryInfo(Alert alert) { String recoveryInfo; AlertDefinition recoveryAlertDefinition = alert.getRecoveryAlertDefinition(); 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 7e81a0e..3fcc64e 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 @@ -58,6 +58,11 @@ import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableDynamicForm; */ public class NewConditionEditor extends LocatableDynamicForm {
+ // these aren't "real" calltime condition categories (not real AlertConditionCategory enums) + // but we need these values for the drop down menu selections + private static final String ALERT_CONDITION_CATEGORY_CALLTIME_CHANGE = "calltime-change"; + private static final String ALERT_CONDITION_CATEGORY_CALLTIME_THRESHOLD = "calltime-threshold"; + private static final String AVAILABILITY_ITEMNAME = "availability"; private static final String THRESHOLD_METRIC_ITEMNAME = "thresholdMetric"; private static final String THRESHOLD_COMPARATOR_ITEMNAME = "thresholdComparator"; @@ -67,6 +72,16 @@ public class NewConditionEditor extends LocatableDynamicForm { private static final String BASELINE_PERCENTAGE_ITEMNAME = "baselinePercentage"; private static final String BASELINE_SELECTION_ITEMNAME = "baselineSelection"; private static final String CHANGE_METRIC_ITEMNAME = "changeMetric"; + private static final String CALLTIME_THRESHOLD_METRIC_ITEMNAME = "calltimeThresholdMetric"; + private static final String CALLTIME_THRESHOLD_MINMAXAVG_ITEMNAME = "calltimeThresholdMinMaxAvgSelection"; + private static final String CALLTIME_THRESHOLD_COMPARATOR_ITEMNAME = "calltimeThresholdComparator"; + private static final String CALLTIME_THRESHOLD_ABSVALUE_ITEMNAME = "calltimeThresholdAbsoluteValue"; + private static final String CALLTIME_THRESHOLD_REGEX_ITEMNAME = "calltimeThresholdRegex"; + private static final String CALLTIME_CHANGE_METRIC_ITEMNAME = "calltimeChangeMetric"; + private static final String CALLTIME_CHANGE_MINMAXAVG_ITEMNAME = "calltimeChangeMinMaxAvgSelection"; + private static final String CALLTIME_CHANGE_COMPARATOR_ITEMNAME = "calltimeChangeComparator"; + private static final String CALLTIME_CHANGE_PERCENTAGE_ITEMNAME = "calltimeChangePercentageValue"; + private static final String CALLTIME_CHANGE_REGEX_ITEMNAME = "calltimeChangeRegex"; private static final String TRAIT_METRIC_ITEMNAME = "trait"; private static final String OPERATION_NAME_ITEMNAME = "operation"; private static final String OPERATION_RESULTS_ITEMNAME = "operationResults"; @@ -76,6 +91,7 @@ public class NewConditionEditor extends LocatableDynamicForm { private SelectItem conditionTypeSelectItem; private HashSet<AlertCondition> conditions; // the new condition we create goes into this set private boolean supportsMetrics = false; + private boolean supportsCalltimeMetrics = false; private boolean supportsTraits = false; private boolean supportsOperations = false; private boolean supportsEvents = false; @@ -101,6 +117,10 @@ public class NewConditionEditor extends LocatableDynamicForm { this.supportsMetrics = true; break; } + case CALLTIME: { + this.supportsCalltimeMetrics = true; + break; + } case TRAIT: { this.supportsTraits = true; break; @@ -132,6 +152,10 @@ public class NewConditionEditor extends LocatableDynamicForm { condTypes.put(AlertConditionCategory.BASELINE.name(), "Measurement Baseline Threshold"); condTypes.put(AlertConditionCategory.CHANGE.name(), "Measurement Value Change"); } + if (supportsCalltimeMetrics) { + condTypes.put(ALERT_CONDITION_CATEGORY_CALLTIME_THRESHOLD, "Calltime Value Threshold"); + condTypes.put(ALERT_CONDITION_CATEGORY_CALLTIME_CHANGE, "Calltime Value Change"); + } if (supportsTraits) { condTypes.put(AlertConditionCategory.TRAIT.name(), "Trait Value Change"); } @@ -176,6 +200,10 @@ public class NewConditionEditor extends LocatableDynamicForm { formItems.addAll(buildMetricBaselineFormItems()); formItems.addAll(buildMetricChangeFormItems()); } + if (supportsCalltimeMetrics) { + formItems.addAll(buildCalltimeThresholdFormItems()); + formItems.addAll(buildCalltimeChangeFormItems()); + } if (supportsTraits) { formItems.addAll(buildTraitChangeFormItems()); } @@ -194,8 +222,20 @@ public class NewConditionEditor extends LocatableDynamicForm { };
private void saveNewCondition() { - AlertConditionCategory category; - category = AlertConditionCategory.valueOf(conditionTypeSelectItem.getValue().toString()); + final boolean calltimeCategory; + final AlertConditionCategory category; + + String selectedCategory = conditionTypeSelectItem.getValue().toString(); + if (selectedCategory.equals(ALERT_CONDITION_CATEGORY_CALLTIME_THRESHOLD)) { + calltimeCategory = true; + category = AlertConditionCategory.THRESHOLD; + } else if (selectedCategory.equals(ALERT_CONDITION_CATEGORY_CALLTIME_CHANGE)) { + calltimeCategory = true; + category = AlertConditionCategory.CHANGE; + } else { + calltimeCategory = false; + category = AlertConditionCategory.valueOf(selectedCategory); + }
AlertCondition newCondition = new AlertCondition(); newCondition.setCategory(category); @@ -211,12 +251,21 @@ public class NewConditionEditor extends LocatableDynamicForm { }
case THRESHOLD: { - MeasurementDefinition measDef = getMeasurementDefinition(getValueAsString(THRESHOLD_METRIC_ITEMNAME)); - newCondition.setName(measDef.getDisplayName()); // TODO should not use display name - newCondition.setThreshold(Double.valueOf(getValueAsString(THRESHOLD_ABSVALUE_ITEMNAME))); - newCondition.setComparator(getValueAsString(THRESHOLD_COMPARATOR_ITEMNAME)); - newCondition.setOption(null); - newCondition.setMeasurementDefinition(measDef); + if (!calltimeCategory) { + MeasurementDefinition measDef = getMeasurementDefinition(getValueAsString(THRESHOLD_METRIC_ITEMNAME)); + newCondition.setName(measDef.getDisplayName()); // TODO should not use display name + newCondition.setThreshold(Double.valueOf(getValueAsString(THRESHOLD_ABSVALUE_ITEMNAME))); + newCondition.setComparator(getValueAsString(THRESHOLD_COMPARATOR_ITEMNAME)); + newCondition.setOption(null); + newCondition.setMeasurementDefinition(measDef); + } else { + MeasurementDefinition measDef = getMeasurementDefinition(getValueAsString(CALLTIME_THRESHOLD_METRIC_ITEMNAME)); + newCondition.setName(getValueAsString(CALLTIME_THRESHOLD_REGEX_ITEMNAME)); + newCondition.setThreshold(Double.valueOf(getValueAsString(CALLTIME_THRESHOLD_ABSVALUE_ITEMNAME))); + newCondition.setComparator(getValueAsString(CALLTIME_THRESHOLD_COMPARATOR_ITEMNAME)); + newCondition.setOption(getValueAsString(CALLTIME_THRESHOLD_MINMAXAVG_ITEMNAME)); + newCondition.setMeasurementDefinition(measDef); + } break; }
@@ -231,12 +280,22 @@ public class NewConditionEditor extends LocatableDynamicForm { }
case CHANGE: { - MeasurementDefinition measDef = getMeasurementDefinition(getValueAsString(CHANGE_METRIC_ITEMNAME)); - newCondition.setName(measDef.getDisplayName()); // TODO should not use display name - newCondition.setComparator(null); - newCondition.setThreshold(null); - newCondition.setOption(null); - newCondition.setMeasurementDefinition(measDef); + if (!calltimeCategory) { + MeasurementDefinition measDef = getMeasurementDefinition(getValueAsString(CHANGE_METRIC_ITEMNAME)); + newCondition.setName(measDef.getDisplayName()); // TODO should not use display name + newCondition.setComparator(null); + newCondition.setThreshold(null); + newCondition.setOption(null); + newCondition.setMeasurementDefinition(measDef); + } else { + MeasurementDefinition measDef = getMeasurementDefinition(getValueAsString(CALLTIME_CHANGE_METRIC_ITEMNAME)); + newCondition.setName(getValueAsString(CALLTIME_CHANGE_REGEX_ITEMNAME)); + newCondition + .setThreshold(Double.valueOf(getValueAsString(CALLTIME_CHANGE_PERCENTAGE_ITEMNAME)) / 100.0); + newCondition.setComparator(getValueAsString(CALLTIME_CHANGE_COMPARATOR_ITEMNAME)); + newCondition.setOption(getValueAsString(CALLTIME_CHANGE_MINMAXAVG_ITEMNAME)); + newCondition.setMeasurementDefinition(measDef); + } break; }
@@ -360,6 +419,97 @@ public class NewConditionEditor extends LocatableDynamicForm { return formItems; }
+ private ArrayList<FormItem> buildCalltimeThresholdFormItems() { + ArrayList<FormItem> formItems = new ArrayList<FormItem>(); + + ShowIfCategoryFunction ifFunc = new ShowIfCategoryFunction(ALERT_CONDITION_CATEGORY_CALLTIME_THRESHOLD); + + String helpStr = "Specify the calltime threshold value that, when violated, triggers the condition. The value you specify is an absolute value with an optional units specifier. You also must specify which calltime limit to compare the value with (minimum, maximum or average calltime value)."; + StaticTextItem helpItem = buildHelpTextItem("calltimeThresholdHelp", helpStr, ifFunc); + formItems.add(helpItem); + + formItems.add(buildCalltimeMetricDropDownMenu(CALLTIME_THRESHOLD_METRIC_ITEMNAME, ifFunc)); + + SelectItem minMaxAvgSelection = new SelectItem(CALLTIME_THRESHOLD_MINMAXAVG_ITEMNAME, "Calltime Limit"); + LinkedHashMap<String, String> limits = new LinkedHashMap<String, String>(3); + limits.put("MIN", "Minimum"); + limits.put("AVG", "Average"); + limits.put("MAX", "Maximum"); + minMaxAvgSelection.setTooltip("The calltime limit value that is to be compared with the given value"); + minMaxAvgSelection.setValueMap(limits); + minMaxAvgSelection.setDefaultValue("AVG"); + minMaxAvgSelection.setWrapTitle(false); + minMaxAvgSelection.setWidth("*"); + minMaxAvgSelection.setRedrawOnChange(true); + minMaxAvgSelection.setShowIfCondition(ifFunc); + formItems.add(minMaxAvgSelection); + + formItems.add(buildComparatorDropDownMenu(CALLTIME_THRESHOLD_COMPARATOR_ITEMNAME, ifFunc)); + TextItem absoluteValue = new TextItem(CALLTIME_THRESHOLD_ABSVALUE_ITEMNAME, "Calltime Value"); + absoluteValue.setWrapTitle(false); + absoluteValue.setRequired(true); + absoluteValue + .setTooltip("The threshold value of the metric that will trigger the condition when compared using the selected comparator."); + absoluteValue.setShowIfCondition(ifFunc); + formItems.add(absoluteValue); + + TextItem regex = new TextItem(CALLTIME_THRESHOLD_REGEX_ITEMNAME, "Regular Expression"); + regex.setRequired(false); + regex + .setTooltip("If specified, this is a regular expression that must match a call destination in order to trigger the condition."); + regex.setWrapTitle(false); + regex.setShowIfCondition(ifFunc); + formItems.add(regex); + + return formItems; + } + + private ArrayList<FormItem> buildCalltimeChangeFormItems() { + ArrayList<FormItem> formItems = new ArrayList<FormItem>(); + + ShowIfCategoryFunction ifFunc = new ShowIfCategoryFunction(ALERT_CONDITION_CATEGORY_CALLTIME_CHANGE); + + String helpStr = "Specify the calltime value that, when changed at least a specified amount, triggers the condition. You must specify which calltime limit to check (minimum, maximum or average calltime value) and the percentage of change that must occur."; + StaticTextItem helpItem = buildHelpTextItem("calltimeChangeHelp", helpStr, ifFunc); + formItems.add(helpItem); + + formItems.add(buildCalltimeMetricDropDownMenu(CALLTIME_CHANGE_METRIC_ITEMNAME, ifFunc)); + + SelectItem minMaxAvgSelection = new SelectItem(CALLTIME_CHANGE_MINMAXAVG_ITEMNAME, "Calltime Limit"); + LinkedHashMap<String, String> limits = new LinkedHashMap<String, String>(3); + limits.put("MIN", "Minimum"); + limits.put("AVG", "Average"); + limits.put("MAX", "Maximum"); + minMaxAvgSelection.setTooltip("The calltime limit value that is to be checked for change"); + minMaxAvgSelection.setValueMap(limits); + minMaxAvgSelection.setDefaultValue("AVG"); + minMaxAvgSelection.setWrapTitle(false); + minMaxAvgSelection.setWidth("*"); + minMaxAvgSelection.setRedrawOnChange(true); + minMaxAvgSelection.setShowIfCondition(ifFunc); + formItems.add(minMaxAvgSelection); + + formItems.add(buildCalltimeComparatorDropDownMenu(CALLTIME_CHANGE_COMPARATOR_ITEMNAME, ifFunc)); + + TextItem percentage = new TextItem(CALLTIME_CHANGE_PERCENTAGE_ITEMNAME, "Percentage Change"); + percentage.setWrapTitle(false); + percentage.setRequired(true); + percentage + .setTooltip("A collected calltime value will trigger this condition when it differs by at least this percentage of the selected calltime limit value"); + percentage.setShowIfCondition(ifFunc); + formItems.add(percentage); + + TextItem regex = new TextItem(CALLTIME_CHANGE_REGEX_ITEMNAME, "Regular Expression"); + regex.setRequired(false); + regex + .setTooltip("If specified, this is a regular expression that must match a call destination in order to trigger the condition."); + regex.setWrapTitle(false); + regex.setShowIfCondition(ifFunc); + formItems.add(regex); + + return formItems; + } + private ArrayList<FormItem> buildTraitChangeFormItems() { ArrayList<FormItem> formItems = new ArrayList<FormItem>();
@@ -510,9 +660,27 @@ public class NewConditionEditor extends LocatableDynamicForm { return metricSelection; }
+ private SelectItem buildCalltimeMetricDropDownMenu(String itemName, FormItemIfFunction ifFunc) { + + LinkedHashMap<String, String> metricsMap = new LinkedHashMap<String, String>(); + for (MeasurementDefinition def : this.resourceType.getMetricDefinitions()) { + if (def.getDataType() == DataType.CALLTIME) { + metricsMap.put(def.getName(), def.getDisplayName()); + } + } + + SelectItem metricSelection = new SelectItem(itemName, "Metric"); + metricSelection.setValueMap(metricsMap); + metricSelection.setDefaultValue(metricsMap.keySet().iterator().next()); // just use the first one + metricSelection.setWidth("*"); + metricSelection.setRedrawOnChange(true); + metricSelection.setShowIfCondition(ifFunc); + return metricSelection; + } + private SelectItem buildComparatorDropDownMenu(String itemName, FormItemIfFunction ifFunc) {
- LinkedHashMap<String, String> comparators = new LinkedHashMap<String, String>(); + LinkedHashMap<String, String> comparators = new LinkedHashMap<String, String>(3); comparators.put("<", "< (Less than)"); comparators.put("=", "= (Equal to)"); comparators.put(">", "> (Greater than)"); @@ -525,6 +693,21 @@ public class NewConditionEditor extends LocatableDynamicForm { return comparatorSelection; }
+ private SelectItem buildCalltimeComparatorDropDownMenu(String itemName, FormItemIfFunction ifFunc) { + + LinkedHashMap<String, String> comparators = new LinkedHashMap<String, String>(3); + comparators.put("LO", "Shrinks"); + comparators.put("CH", "Changes"); + comparators.put("HI", "Grows"); + + SelectItem comparatorSelection = new SelectItem(itemName, "Comparator"); + comparatorSelection.setValueMap(comparators); + comparatorSelection.setDefaultValue("CH"); + comparatorSelection.setTooltip("How a collected calltime value should be compared to the given calltime limit"); + comparatorSelection.setShowIfCondition(ifFunc); + return comparatorSelection; + } + private StaticTextItem buildHelpTextItem(String itemName, String helpText, FormItemIfFunction ifFunc) { StaticTextItem help = new StaticTextItem(itemName); help.setShowTitle(false); @@ -548,13 +731,25 @@ public class NewConditionEditor extends LocatableDynamicForm {
private class ShowIfCategoryFunction implements FormItemIfFunction { private final AlertConditionCategory category; + private final String calltimeCategory;
public ShowIfCategoryFunction(AlertConditionCategory category) { this.category = category; + this.calltimeCategory = null; + } + + public ShowIfCategoryFunction(String calltimeCategory) { + this.category = null; + this.calltimeCategory = calltimeCategory; }
public boolean execute(FormItem item, Object value, DynamicForm form) { - return category.name().equals(form.getValue("conditionType").toString()); + String conditionTypeString = form.getValue("conditionType").toString(); + if (category != null) { + return category.name().equals(conditionTypeString); + } else { + return calltimeCategory.equals(conditionTypeString); + } } } }
rhq-commits@lists.fedorahosted.org