modules/core/domain/src/main/java/org/rhq/core/domain/alert/Alert.java | 5 modules/core/domain/src/main/java/org/rhq/core/domain/alert/AlertConditionLog.java | 3 modules/core/domain/src/main/java/org/rhq/core/domain/criteria/AlertCriteria.java | 41 +- modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertDataSource.java | 107 +---- modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertDefinitionUtility.java | 186 ---------- modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertFormatUtility.java | 186 ++++++++++ modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertsView.java | 104 +++-- modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/AlertGWTService.java | 10 modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/AlertGWTServiceImpl.java | 4 modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java | 20 + modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerLocal.java | 11 11 files changed, 355 insertions(+), 322 deletions(-)
New commits: commit 186bdead774360a9c0eabe487f85b04317374cb0 Author: Ian P. Springer <ips@jetengine.(none)> Date: Fri Feb 26 23:25:57 2010 -0500
finish up v1 of Alert History page
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/Alert.java b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/Alert.java index 796ae01..0eb5fc3 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/Alert.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/Alert.java @@ -126,6 +126,8 @@ import org.rhq.core.domain.auth.Subject; + " AND (a.ctime > :startDate OR :startDate IS NULL) " + " AND (a.ctime < :endDate OR :endDate IS NULL) "), @NamedQuery(name = Alert.QUERY_FIND_ALL, query = "SELECT a FROM Alert AS a"), + @NamedQuery(name = Alert.QUERY_FIND_RESOURCES, query = "SELECT res FROM Alert AS a JOIN a.alertDefinition aDef " + + " JOIN aDef.resource res WHERE a.id in (:alertIds) AND res.id IS NOT NULL"), @NamedQuery(name = Alert.QUERY_DELETE_BY_CTIME, query = "" // + "DELETE FROM Alert AS a " // + " WHERE a.ctime BETWEEN :begin AND :end"),// @@ -204,7 +206,8 @@ public class Alert implements Serializable { public static final String QUERY_FIND_BY_MEAS_DEF_ID_AND_RESOURCEGROUP = "Alert.findByMeasDefIdAndResourceGroup"; public static final String QUERY_FIND_BY_MEAS_DEF_ID_AND_AUTOGROUP = "Alert.findByMeasDefIdAndAutoGroup"; public static final String QUERY_FIND_BY_MEAS_DEF_ID_AND_RESOURCE = "Alert.findByMeasDefIdAndResource"; - public static final String QUERY_GET_ALERT_COUNT_FOR_SCHEDULES = "Alert.QUERY_GET_ALERT_COUNT_FOR_SCHEDULES"; + public static final String QUERY_GET_ALERT_COUNT_FOR_SCHEDULES = "Alert.QUERY_GET_ALERT_COUNT_FOR_SCHEDULES"; + public static final String QUERY_FIND_RESOURCES = "Alert.findResources";
public static final String QUERY_NATIVE_TRUNCATE_SQL = "TRUNCATE TABLE RHQ_ALERT";
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/AlertConditionLog.java b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/AlertConditionLog.java index 2cfc4f0..ddcf92e 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/AlertConditionLog.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/AlertConditionLog.java @@ -61,7 +61,8 @@ import javax.persistence.Table; + " WHERE acl.id IN ( SELECT iacl.id " // + " FROM AlertConditionLog iacl" // + " WHERE iacl.condition.alertDefinition.id = :alertDefinitionId )" // - + " AND acl.alert IS NULL") }) + + " AND acl.alert IS NULL") +}) @SequenceGenerator(name = "RHQ_ALERT_CONDITION_LOG_ID_SEQ", sequenceName = "RHQ_ALERT_CONDITION_LOG_ID_SEQ") @Table(name = "RHQ_ALERT_CONDITION_LOG") public class AlertConditionLog implements Serializable { diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/AlertCriteria.java b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/AlertCriteria.java index 057ebdf..e1b4b2c 100644 --- a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/AlertCriteria.java +++ b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/AlertCriteria.java @@ -42,6 +42,14 @@ import org.rhq.core.domain.util.PageOrdering; public class AlertCriteria extends Criteria { private static final long serialVersionUID = 1L;
+ // sort fields from the Alert itself + public static final String SORT_FIELD_CTIME = "ctime"; + + // sort fields from the Alert's AlertDefinition + public static final String SORT_FIELD_NAME = "name"; + public static final String SORT_FIELD_PRIORITY = "priority"; + public static final String SORT_FIELD_RESOURCE_ID = "resourceId"; + private Integer filterId; private String filterTriggeredOperationName; // requires overrides private Long filterStartTime; // requires overrides @@ -61,9 +69,11 @@ public class AlertCriteria extends Criteria { private boolean fetchNotificationLogs; private boolean fetchRecoveryAlertDefinition;
- private PageOrdering sortName; // requires overrides private PageOrdering sortCtime; - private PageOrdering sortPriority; // requires overrides + + private PageOrdering sortName; // requires sort override + private PageOrdering sortPriority; // requires sort override + private PageOrdering sortResourceId; // requires sort override
public AlertCriteria() { super(Alert.class); @@ -85,9 +95,9 @@ public class AlertCriteria extends Criteria { filterOverrides.put("alertDefinitionIds", "alertDefinition.id IN ( ? )"); filterOverrides.put("groupAlertDefinitionIds", "alertDefinition.groupAlertDefinition.id IN ( ? )");
- sortOverrides.put("name", "alertDefinition.name"); - sortOverrides.put("resourceId", "alertDefinition.resource.id"); - sortOverrides.put("priority", "alertDefinition.priority"); + sortOverrides.put(SORT_FIELD_NAME, "alertDefinition.name"); + sortOverrides.put(SORT_FIELD_PRIORITY, "alertDefinition.priority"); + sortOverrides.put(SORT_FIELD_RESOURCE_ID, "alertDefinition.resource.id"); }
@Override @@ -163,18 +173,23 @@ public class AlertCriteria extends Criteria { this.fetchRecoveryAlertDefinition = fetchRecoveryAlertDefinition; }
- public void addSortName(PageOrdering sortName) { - addSortField("name"); - this.sortName = sortName; - } - public void addSortCtime(PageOrdering sortCtime) { - addSortField("ctime"); + addSortField(SORT_FIELD_CTIME); this.sortCtime = sortCtime; }
+ public void addSortName(PageOrdering sortName) { + addSortField(SORT_FIELD_NAME); + this.sortName = sortName; + } + public void addSortPriority(PageOrdering sortPriority) { - addSortField("priority"); + addSortField(SORT_FIELD_PRIORITY); this.sortPriority = sortPriority; - } + } + + public void addSortResourceId(PageOrdering sortResourceId) { + addSortField(SORT_FIELD_RESOURCE_ID); + this.sortResourceId = sortResourceId; + } } diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertDataSource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertDataSource.java index 58c96e3..c21d00a 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertDataSource.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertDataSource.java @@ -35,22 +35,18 @@ import org.rhq.core.domain.alert.AlertCondition; import org.rhq.core.domain.alert.AlertConditionLog; import org.rhq.core.domain.criteria.AlertCriteria; import org.rhq.core.domain.measurement.MeasurementConverterClient; -import org.rhq.core.domain.util.OrderingField; import org.rhq.core.domain.util.PageList; -import org.rhq.core.domain.util.PageOrdering; import org.rhq.enterprise.gui.coregui.client.gwt.AlertGWTServiceAsync; import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup; import org.rhq.enterprise.gui.coregui.client.util.RPCDataSource;
-import java.util.ArrayList; +import java.util.Arrays; import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; import java.util.Set;
/** + * A server-side SmartGWT DataSource for CRUD of {@link Alert}s. + * * @author Ian Springer */ public class AlertDataSource extends RPCDataSource { @@ -73,14 +69,14 @@ public class AlertDataSource extends RPCDataSource {
setCanMultiSort(true);
- DataSourceField idDataField = new DataSourceIntegerField("id", "Id"); - idDataField.setPrimaryKey(true); - idDataField.setHidden(true); + DataSourceField idField = new DataSourceIntegerField("id", "Id"); + idField.setPrimaryKey(true); + idField.setHidden(true);
- DataSourceField resourceIdDataField = new DataSourceIntegerField("resourceId", "Resource Id"); - idDataField.setHidden(true); + // TODO: Replace 'Resource Id' column with 'Resource Name' and 'Resource Lineage' columns. + DataSourceField resourceIdField = new DataSourceIntegerField(AlertCriteria.SORT_FIELD_RESOURCE_ID, "Resource Id");
- DataSourceTextField nameField = new DataSourceTextField("name", "Name", 100); + DataSourceTextField nameField = new DataSourceTextField(AlertCriteria.SORT_FIELD_NAME, "Name", 100);
DataSourceTextField conditionTextField = new DataSourceTextField("conditionText", "Condition Text"); conditionTextField.setCanSortClientOnly(true); @@ -91,64 +87,40 @@ public class AlertDataSource extends RPCDataSource { DataSourceTextField recoveryInfoField = new DataSourceTextField("recoveryInfo", "Recovery Info"); recoveryInfoField.setCanSortClientOnly(true);
- // TODO: Use DataSourceEnumField here? - DataSourceTextField priorityField = new DataSourceTextField("priority", "Priority", 15); + // TODO: Will using DataSourceEnumField here allow us to do + // record.setAttribute("priority", alert.getAlertDefinition().getPriority()), rather than + // record.setAttribute("priority", alert.getAlertDefinition().getPriority().name()) in + // createRecord() below? + DataSourceTextField priorityField = new DataSourceTextField(AlertCriteria.SORT_FIELD_PRIORITY, "Priority", 15);
- DataSourceTextField ctimeField = new DataSourceTextField("ctime", "Creation Time"); + DataSourceTextField ctimeField = new DataSourceTextField(AlertCriteria.SORT_FIELD_CTIME, "Creation Time");
- setFields(idDataField, nameField, conditionTextField, conditionValueField, recoveryInfoField, priorityField, - ctimeField); + setFields(idField, resourceIdField, nameField, conditionTextField, conditionValueField, recoveryInfoField, + priorityField, ctimeField); }
- void deleteAlerts(final ListGrid listGrid, final AlertsView alertsView) { + void deleteAlerts(final AlertsView alertsView) { + ListGrid listGrid = alertsView.getListGrid(); ListGridRecord[] records = listGrid.getSelection(); - final Map<Integer, List<ListGridRecord>> alertIdMap = new HashMap<Integer, List<ListGridRecord>>(); + + final Integer[] alertIds = new Integer[records.length]; for (int i = 0, selectionLength = records.length; i < selectionLength; i++) { ListGridRecord record = records[i]; - Integer resourceId = record.getAttributeAsInt("alertDefinition.resource.id"); - List<ListGridRecord> recordsForResource; - if (alertIdMap.containsKey(resourceId)) { - recordsForResource = alertIdMap.get(resourceId); - } else { - recordsForResource = new ArrayList<ListGridRecord>(); - alertIdMap.put(resourceId, recordsForResource); - } - recordsForResource.add(record); + Integer alertId = record.getAttributeAsInt("id"); + alertIds[i] = alertId; }
- AlertGWTServiceAsync alertService = GWTServiceLookup.getAlertService(); - final Set<Integer> successfulResourceIds = new HashSet<Integer>(); - final Set<Integer> failedResourceIds = new HashSet<Integer>(); - for (final Integer resourceId : alertIdMap.keySet()) { - final List<ListGridRecord> recordsForResource = alertIdMap.get(resourceId); - Integer[] alertIds = new Integer[recordsForResource.size()]; - for (int i = 0; i < recordsForResource.size(); i++) { - ListGridRecord listGridRecord = recordsForResource.get(i); - Integer alertId = listGridRecord.getAttributeAsInt("id"); - alertIds[i] = alertId; + this.alertService.deleteResourceAlerts(alertIds, new AsyncCallback<Void>() { + public void onSuccess(Void blah) { + System.out.println("Deleted Alerts with id's: " + Arrays.toString(alertIds) + "."); + alertsView.reloadData(); }
- alertService.deleteAlerts(resourceId, alertIds, new AsyncCallback<Void>() { - public void onSuccess(Void blah) { - /*for (ListGridRecord record : recordsForResource) { - removeData(record); - }*/ - successfulResourceIds.add(resourceId); - if (successfulResourceIds.size() + failedResourceIds.size() == alertIdMap.size()) { - alertsView.reportSelectedAlertsDeleted(listGrid); - } - } - - public void onFailure(Throwable caught) { - Window.alert("Failed to delete Alerts for Resource with id " + resourceId + " - cause: " + caught); - System.err.println("Failed to delete Alerts for Resource with id " + resourceId + " - cause: " + caught); - failedResourceIds.add(resourceId); - if (successfulResourceIds.size() + failedResourceIds.size() == alertIdMap.size()) { - // TODO: Report failure. - } - } - }); - } + public void onFailure(Throwable caught) { + Window.alert("Failed to delete Alerts with id's: " + Arrays.toString(alertIds) + " - cause: " + caught); + System.err.println("Failed to delete Alerts with id's " + Arrays.toString(alertIds) + " - cause: " + caught); + } + }); }
protected void executeFetch(final DSRequest request, final DSResponse response) { @@ -156,8 +128,9 @@ public class AlertDataSource extends RPCDataSource {
AlertCriteria criteria = new AlertCriteria(); criteria.fetchAlertDefinition(true); - criteria.fetchConditionLogs(true); criteria.fetchRecoveryAlertDefinition(true); + // TODO: Uncomment the below once the bad performance of it has been fixed. + //criteria.fetchConditionLogs(true);
criteria.setPageControl(getPageControl(request));
@@ -211,7 +184,7 @@ public class AlertDataSource extends RPCDataSource { } else if (conditionLogs.size() == 1) { AlertConditionLog conditionLog = conditionLogs.iterator().next(); AlertCondition condition = conditionLog.getCondition(); - conditionText = AlertDefinitionUtility.formatAlertConditionForDisplay(condition); + conditionText = AlertFormatUtility.formatAlertConditionForDisplay(condition); conditionValue = conditionLog.getValue(); if (condition.getMeasurementDefinition() != null) { conditionValue = MeasurementConverterClient.format(Double.valueOf(conditionLog.getValue()), condition @@ -224,16 +197,8 @@ public class AlertDataSource extends RPCDataSource { record.setAttribute("conditionText", conditionText); record.setAttribute("conditionValue", conditionValue);
- String recoveryInfo = AlertDefinitionUtility.getAlertRecoveryInfo(alert); + String recoveryInfo = AlertFormatUtility.getAlertRecoveryInfo(alert); record.setAttribute("recoveryInfo", recoveryInfo); return record; } - - /*@Override - protected List<OrderingField> getDefaultOrderingFields(String alias) { - List<OrderingField> orderingFields = new ArrayList<OrderingField>(2); - orderingFields.add(new OrderingField(alias + ".alertDefinition.name", PageOrdering.ASC)); - orderingFields.add(new OrderingField(alias + ".ctime", PageOrdering.DESC)); - return orderingFields; - }*/ } \ No newline at end of file diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertDefinitionUtility.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertDefinitionUtility.java deleted file mode 100644 index dcccee7..0000000 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertDefinitionUtility.java +++ /dev/null @@ -1,186 +0,0 @@ -/* - * RHQ Management Platform - * Copyright (C) 2010 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.enterprise.gui.coregui.client.alert; - -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.AlertDefinition; -import org.rhq.core.domain.measurement.MeasurementBaseline; -import org.rhq.core.domain.measurement.MeasurementConverterClient; -import org.rhq.core.domain.measurement.MeasurementSchedule; -import org.rhq.core.domain.measurement.MeasurementUnits; -import org.rhq.core.domain.measurement.util.MeasurementConversionException; - -import java.util.ArrayList; -import java.util.List; - -/** - * The methods in this class are ported from AlertDefUtil from portal-war and MeasurementFormatter from - * server-jar. - * - * @author Ian Springer - */ -public class AlertDefinitionUtility { - private static final String BASELINE_OPT_MEAN = "mean"; - private static final String BASELINE_OPT_MIN = "min"; - private static final String BASELINE_OPT_MAX = "max"; - - private static final String MEASUREMENT_BASELINE_MIN_TEXT = "Min Value"; - private static final String MEASUREMENT_BASELINE_MEAN_TEXT = "Baseline Value"; - private static final String MEASUREMENT_BASELINE_MAX_TEXT = "Max Value"; - - @SuppressWarnings("deprecation") - public static String formatAlertConditionForDisplay(AlertCondition condition) { - AlertConditionCategory category = condition.getCategory(); - - StringBuilder textValue = new StringBuilder(); - - // first format the LHS of the operator - if (category == AlertConditionCategory.CONTROL) { - try { - String operationName = condition.getName(); - /*Integer resourceTypeId = condition.getAlertDefinition().getResource().getResourceType().getId(); - OperationManagerLocal operationManager = LookupUtil.getOperationManager(); - OperationDefinition definition = operationManager.getOperationDefinitionByResourceTypeAndName( - resourceTypeId, operationName, false); - String operationDisplayName = definition.getDisplayName();*/ - textValue.append(operationName).append(' '); - } catch (Exception e) { - textValue.append(condition.getName()).append(' '); - } - } else if (category == AlertConditionCategory.RESOURCE_CONFIG) { - textValue.append("Resource Configuration").append(' '); - } else { - textValue.append(condition.getName()).append(' '); - } - - // next format the RHS - if (category == AlertConditionCategory.CONTROL) { - textValue.append(condition.getOption()); - } else if ((category == AlertConditionCategory.THRESHOLD) || (category == AlertConditionCategory.BASELINE)) { - textValue.append(condition.getComparator()); - textValue.append(' '); - - MeasurementSchedule schedule = null; - - MeasurementUnits units; - double value = condition.getThreshold(); - if (category == AlertConditionCategory.THRESHOLD) { - units = condition.getMeasurementDefinition().getUnits(); - } else // ( category == AlertConditionCategory.BASELINE ) - { - units = MeasurementUnits.PERCENTAGE; - } - - String formatted = MeasurementConverterClient.format(value, units, true); - textValue.append(formatted); - - if (category == AlertConditionCategory.BASELINE) { - textValue.append(" of "); - textValue.append(getBaselineText(condition.getOption(), schedule)); - } - } else if (category == AlertConditionCategory.RESOURCE_CONFIG || category == AlertConditionCategory.CHANGE - || category == AlertConditionCategory.TRAIT) { - textValue.append("Value Changed"); - } else if (category == AlertConditionCategory.EVENT) { - String msgKey = "alert.config.props.CB.EventSeverity"; - List<String> args = new ArrayList<String>(2); - - args.add(condition.getName()); - if ((condition.getOption() != null) && (condition.getOption().length() > 0)) { - msgKey += ".RegexMatch"; - args.add(condition.getOption()); - } - // TODO - textValue.append("TODO ").append(args); - } else if (category == AlertConditionCategory.AVAILABILITY) { - // TODO - textValue.append("Availability ").append(condition.getOption()); - } else { - // do nothing - } - - return textValue.toString(); - } - - public static String getAlertRecoveryInfo(Alert alert) { - String recoveryInfo; - AlertDefinition recoveryAlertDefinition = alert.getRecoveryAlertDefinition(); - if (recoveryAlertDefinition != null && recoveryAlertDefinition.getId() != 0) { - int resourceId = alert.getAlertDefinition().getResource().getId(); - recoveryInfo = "Triggered '<a href="/alerts/Config.do?mode=viewRoles&id=" + resourceId + "&ad=" + recoveryAlertDefinition.getId() - + "">" + recoveryAlertDefinition.getName() + "</a>' to be re-enabled."; - } else if (alert.getWillRecover()) { - recoveryInfo = "This alert caused its alert definition to be disabled."; - } else { - recoveryInfo = "N/A"; - } - return recoveryInfo; - } - - private static String getBaselineText(String baselineOption, MeasurementSchedule schedule) { - if ((null != schedule) && (null != schedule.getBaseline())) { - MeasurementBaseline baseline = schedule.getBaseline(); - - String lookupText = null; - Double value = null; - - if (baselineOption.equals(BASELINE_OPT_MIN)) { - lookupText = MEASUREMENT_BASELINE_MIN_TEXT; - value = baseline.getMin(); - } else if (baselineOption.equals(BASELINE_OPT_MEAN)) { - lookupText = MEASUREMENT_BASELINE_MEAN_TEXT; - value = baseline.getMean(); - } else if (baselineOption.equals(BASELINE_OPT_MAX)) { - lookupText = MEASUREMENT_BASELINE_MAX_TEXT; - value = baseline.getMax(); - } - - if (value != null) { - try { - String formatted = MeasurementConverterClient.scaleAndFormat(value, schedule, true); - return formatted + " (" + lookupText + ")"; - } catch (MeasurementConversionException mce) { - return lookupText; - } - } - /* - * will need a fall-through here because the value was null; this can happen when the user requests to view - * the formatted baseline before the first time it has been calculated - */ - } - - // here is the fall-through - if (BASELINE_OPT_MIN.equals(baselineOption)) { - return MEASUREMENT_BASELINE_MIN_TEXT; - } else if (BASELINE_OPT_MAX.equals(baselineOption)) { - return MEASUREMENT_BASELINE_MAX_TEXT; - } else { - return MEASUREMENT_BASELINE_MEAN_TEXT; - } - } - - private AlertDefinitionUtility() { - } -} 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 new file mode 100644 index 0000000..2554746 --- /dev/null +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertFormatUtility.java @@ -0,0 +1,186 @@ +/* + * RHQ Management Platform + * Copyright (C) 2010 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.enterprise.gui.coregui.client.alert; + +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.AlertDefinition; +import org.rhq.core.domain.measurement.MeasurementBaseline; +import org.rhq.core.domain.measurement.MeasurementConverterClient; +import org.rhq.core.domain.measurement.MeasurementSchedule; +import org.rhq.core.domain.measurement.MeasurementUnits; +import org.rhq.core.domain.measurement.util.MeasurementConversionException; + +import java.util.ArrayList; +import java.util.List; + +/** + * The methods in this class are ported from AlertDefUtil from portal-war and MeasurementFormatter from + * server-jar. + * + * @author Ian Springer + */ +public class AlertFormatUtility { + private static final String BASELINE_OPT_MEAN = "mean"; + private static final String BASELINE_OPT_MIN = "min"; + private static final String BASELINE_OPT_MAX = "max"; + + private static final String MEASUREMENT_BASELINE_MIN_TEXT = "Min Value"; + private static final String MEASUREMENT_BASELINE_MEAN_TEXT = "Baseline Value"; + private static final String MEASUREMENT_BASELINE_MAX_TEXT = "Max Value"; + + @SuppressWarnings("deprecation") + public static String formatAlertConditionForDisplay(AlertCondition condition) { + AlertConditionCategory category = condition.getCategory(); + + StringBuilder textValue = new StringBuilder(); + + // first format the LHS of the operator + if (category == AlertConditionCategory.CONTROL) { + try { + String operationName = condition.getName(); + /*Integer resourceTypeId = condition.getAlertDefinition().getResource().getResourceType().getId(); + OperationManagerLocal operationManager = LookupUtil.getOperationManager(); + OperationDefinition definition = operationManager.getOperationDefinitionByResourceTypeAndName( + resourceTypeId, operationName, false); + String operationDisplayName = definition.getDisplayName();*/ + textValue.append(operationName).append(' '); + } catch (Exception e) { + textValue.append(condition.getName()).append(' '); + } + } else if (category == AlertConditionCategory.RESOURCE_CONFIG) { + textValue.append("Resource Configuration").append(' '); + } else { + textValue.append(condition.getName()).append(' '); + } + + // next format the RHS + if (category == AlertConditionCategory.CONTROL) { + textValue.append(condition.getOption()); + } else if ((category == AlertConditionCategory.THRESHOLD) || (category == AlertConditionCategory.BASELINE)) { + textValue.append(condition.getComparator()); + textValue.append(' '); + + MeasurementSchedule schedule = null; + + MeasurementUnits units; + double value = condition.getThreshold(); + if (category == AlertConditionCategory.THRESHOLD) { + units = condition.getMeasurementDefinition().getUnits(); + } else // ( category == AlertConditionCategory.BASELINE ) + { + units = MeasurementUnits.PERCENTAGE; + } + + String formatted = MeasurementConverterClient.format(value, units, true); + textValue.append(formatted); + + if (category == AlertConditionCategory.BASELINE) { + textValue.append(" of "); + textValue.append(getBaselineText(condition.getOption(), schedule)); + } + } else if (category == AlertConditionCategory.RESOURCE_CONFIG || category == AlertConditionCategory.CHANGE + || category == AlertConditionCategory.TRAIT) { + textValue.append("Value Changed"); + } else if (category == AlertConditionCategory.EVENT) { + String msgKey = "alert.config.props.CB.EventSeverity"; + List<String> args = new ArrayList<String>(2); + + args.add(condition.getName()); + if ((condition.getOption() != null) && (condition.getOption().length() > 0)) { + msgKey += ".RegexMatch"; + args.add(condition.getOption()); + } + // TODO + textValue.append("TODO ").append(args); + } else if (category == AlertConditionCategory.AVAILABILITY) { + // TODO + textValue.append("Availability ").append(condition.getOption()); + } else { + // do nothing + } + + return textValue.toString(); + } + + public static String getAlertRecoveryInfo(Alert alert) { + String recoveryInfo; + AlertDefinition recoveryAlertDefinition = alert.getRecoveryAlertDefinition(); + if (recoveryAlertDefinition != null && recoveryAlertDefinition.getId() != 0) { + int resourceId = alert.getAlertDefinition().getResource().getId(); + recoveryInfo = "Triggered '<a href="/alerts/Config.do?mode=viewRoles&id=" + resourceId + "&ad=" + recoveryAlertDefinition.getId() + + "">" + recoveryAlertDefinition.getName() + "</a>' to be re-enabled."; + } else if (alert.getWillRecover()) { + recoveryInfo = "This alert caused its alert definition to be disabled."; + } else { + recoveryInfo = "N/A"; + } + return recoveryInfo; + } + + private static String getBaselineText(String baselineOption, MeasurementSchedule schedule) { + if ((null != schedule) && (null != schedule.getBaseline())) { + MeasurementBaseline baseline = schedule.getBaseline(); + + String lookupText = null; + Double value = null; + + if (baselineOption.equals(BASELINE_OPT_MIN)) { + lookupText = MEASUREMENT_BASELINE_MIN_TEXT; + value = baseline.getMin(); + } else if (baselineOption.equals(BASELINE_OPT_MEAN)) { + lookupText = MEASUREMENT_BASELINE_MEAN_TEXT; + value = baseline.getMean(); + } else if (baselineOption.equals(BASELINE_OPT_MAX)) { + lookupText = MEASUREMENT_BASELINE_MAX_TEXT; + value = baseline.getMax(); + } + + if (value != null) { + try { + String formatted = MeasurementConverterClient.scaleAndFormat(value, schedule, true); + return formatted + " (" + lookupText + ")"; + } catch (MeasurementConversionException mce) { + return lookupText; + } + } + /* + * will need a fall-through here because the value was null; this can happen when the user requests to view + * the formatted baseline before the first time it has been calculated + */ + } + + // here is the fall-through + if (BASELINE_OPT_MIN.equals(baselineOption)) { + return MEASUREMENT_BASELINE_MIN_TEXT; + } else if (BASELINE_OPT_MAX.equals(baselineOption)) { + return MEASUREMENT_BASELINE_MAX_TEXT; + } else { + return MEASUREMENT_BASELINE_MEAN_TEXT; + } + } + + private AlertFormatUtility() { + } +} diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertsView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertsView.java index 190b789..ce36802 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertsView.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertsView.java @@ -29,6 +29,8 @@ import com.smartgwt.client.widgets.Label; import com.smartgwt.client.widgets.events.ClickEvent; import com.smartgwt.client.widgets.events.ClickHandler; import com.smartgwt.client.widgets.grid.ListGrid; +import com.smartgwt.client.widgets.grid.events.DataArrivedEvent; +import com.smartgwt.client.widgets.grid.events.DataArrivedHandler; import com.smartgwt.client.widgets.grid.events.SelectionChangedHandler; import com.smartgwt.client.widgets.grid.events.SelectionEvent; import com.smartgwt.client.widgets.layout.LayoutSpacer; @@ -36,16 +38,20 @@ import com.smartgwt.client.widgets.layout.SectionStack; import com.smartgwt.client.widgets.layout.SectionStackSection; import com.smartgwt.client.widgets.layout.VLayout; import com.smartgwt.client.widgets.toolbar.ToolStrip; +import org.rhq.core.domain.criteria.AlertCriteria; import org.rhq.enterprise.gui.coregui.client.admin.roles.RoleEditView;
/** * A view that displays a paginated table of fired {@link org.rhq.core.domain.alert.Alert alert}s, along with the - * ability to filter or sort those alerts, click on an alert to view details about that alert, or delete selected - * alerts. + * ability to filter or sort those alerts, click on an alert to view details about that alert's definition, or delete + * selected alerts. * * @author Ian Springer */ public class AlertsView extends SectionStack { + private ListGrid listGrid; + private IButton removeButton; + private Label tableInfo;
@Override protected void onInit() { @@ -61,57 +67,62 @@ public class AlertsView extends SectionStack { gridHolder.setWidth100(); gridHolder.setHeight100();
- final ListGrid listGrid = new ListGrid(); - listGrid.setWidth100(); - listGrid.setHeight100(); - listGrid.setDataSource(dataSource); - listGrid.setAutoFetchData(true); - listGrid.setAutoFitData(Autofit.HORIZONTAL); - listGrid.setAlternateRecordStyles(true); - listGrid.setSelectionType(SelectionStyle.SIMPLE); - listGrid.setSelectionAppearance(SelectionAppearance.CHECKBOX); + this.listGrid = new ListGrid(); + this.listGrid.setWidth100(); + this.listGrid.setHeight100(); + this.listGrid.setDataSource(dataSource); + this.listGrid.setAutoFetchData(true); + this.listGrid.setAutoFitData(Autofit.HORIZONTAL); + this.listGrid.setAlternateRecordStyles(true); + this.listGrid.setSelectionType(SelectionStyle.SIMPLE); + this.listGrid.setSelectionAppearance(SelectionAppearance.CHECKBOX);
- listGrid.setShowFilterEditor(true); + this.listGrid.setShowFilterEditor(true);
- listGrid.setUseAllDataSourceFields(true); + this.listGrid.setUseAllDataSourceFields(true); + this.listGrid.setSortField(AlertCriteria.SORT_FIELD_NAME);
- gridHolder.addMember(listGrid); + gridHolder.addMember(this.listGrid);
ToolStrip toolStrip = new ToolStrip(); toolStrip.setMembersMargin(15);
- final IButton removeButton = new IButton("Delete"); - removeButton.setDisabled(true); - removeButton.addClickHandler(new ClickHandler() { + this.removeButton = new IButton("Delete"); + this.removeButton.setDisabled(true); + this.removeButton.addClickHandler(new ClickHandler() { public void onClick(ClickEvent clickEvent) { - SC.confirm("Are you sure you want to delete " + listGrid.getSelection().length + " alerts?", + SC.confirm("Are you sure you want to delete the " + AlertsView.this.listGrid.getSelection().length + + " selected alerts?", new BooleanCallback() { public void execute(Boolean confirmed) { if (confirmed) { - deleteSelectedAlerts(dataSource, listGrid); + //listGrid.removeSelectedData(); + dataSource.deleteAlerts(AlertsView.this); } } } ); } }); - - final Label tableInfo = new Label("Total: " + listGrid.getTotalRows()); - tableInfo.setWrap(false); - - toolStrip.addMember(removeButton); + toolStrip.addMember(this.removeButton); toolStrip.addMember(new LayoutSpacer()); - toolStrip.addMember(tableInfo); + + this.tableInfo = new Label(); + this.tableInfo.setWrap(false); + toolStrip.addMember(this.tableInfo);
gridHolder.addMember(toolStrip);
- listGrid.addSelectionChangedHandler(new SelectionChangedHandler() { - public void onSelectionChanged(SelectionEvent selectionEvent) { - int selectedCount = ((ListGrid) selectionEvent.getSource()).getSelection().length; - tableInfo.setContents("Total: " + listGrid.getTotalRows() + " (" + selectedCount + " selected)"); - removeButton.setDisabled(selectedCount == 0); + this.listGrid.addDataArrivedHandler(new DataArrivedHandler() { + public void onDataArrived(DataArrivedEvent event) { + updateFooter(); } }); + this.listGrid.addSelectionChangedHandler(new SelectionChangedHandler() { + public void onSelectionChanged(SelectionEvent event) { + updateFooter(); + } + });
SectionStackSection topSection = new SectionStackSection("Alerts"); topSection.setExpanded(true); @@ -121,11 +132,11 @@ public class AlertsView extends SectionStack {
final RoleEditView roleEditor = new RoleEditView();
- final SectionStackSection detailSection = new SectionStackSection("Selected Role"); + final SectionStackSection detailSection = new SectionStackSection("Selected Alert"); detailSection.setItems(roleEditor); addSection(detailSection);
- listGrid.addSelectionChangedHandler(new SelectionChangedHandler() { + this.listGrid.addSelectionChangedHandler(new SelectionChangedHandler() { public void onSelectionChanged(SelectionEvent selectionEvent) { if (selectionEvent.getState()) { expandSection(1); @@ -135,25 +146,24 @@ public class AlertsView extends SectionStack { roleEditor.editNone(); } }); - - }
- private void deleteSelectedAlerts(AlertDataSource dataSource, ListGrid listGrid) { - //listGrid.removeSelectedData(); - - /*DSRequest request = new DSRequest(); - request.setAttribute("data", listGrid.getSelection()); - DSResponse response = new DSResponse(); - dataSource.executeRemove(request, response);*/ + ListGrid getListGrid() { + return this.listGrid; + }
- dataSource.deleteAlerts(listGrid, this); - markForRedraw(); + void reloadData() { + this.tableInfo.setContents(""); + this.listGrid.invalidateCache(); + //this.listGrid.markForRedraw(); }
- void reportSelectedAlertsDeleted(ListGrid listGrid) { - listGrid.removeSelectedData(); - System.out.println("Alerts deleted successfully."); - listGrid.markForRedraw(); + private void updateFooter() { + String label = "Total: " + this.listGrid.getTotalRows(); + if (this.listGrid.anySelected()) { + label += " (" + this.listGrid.getSelection().length + " selected)"; + } + this.tableInfo.setContents(label); + this.removeButton.setDisabled(!listGrid.anySelected()); } } \ No newline at end of file diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/AlertGWTService.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/AlertGWTService.java index cf19e2d..be970b9 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/AlertGWTService.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/AlertGWTService.java @@ -38,5 +38,13 @@ public interface AlertGWTService extends RemoteService { */ PageList<Alert> findAlertsByCriteria(AlertCriteria criteria);
- void deleteAlerts(int resourceId, Integer[] alertIds); + /** + * Delete the Resource alerts with the specified id's if the current user has permission to do so (i.e. either + * the MANAGE_INVENTORY global permission, or the MANAGE_ALERTS Resource permission for all associated Resources). + * If the user does not have permission for all of the specified alerts, then none of the alerts will be deleted + * and a PermissionException will be thrown. + * + * @param alertIds the id's of the Resource alerts to be deleted + */ + void deleteResourceAlerts(Integer[] alertIds); } \ No newline at end of file diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/AlertGWTServiceImpl.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/AlertGWTServiceImpl.java index b88385e..685543e 100644 --- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/AlertGWTServiceImpl.java +++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/AlertGWTServiceImpl.java @@ -37,7 +37,7 @@ public class AlertGWTServiceImpl extends AbstractGWTServiceImpl implements Alert "AlertService.findAlertsByCriteria"); }
- public void deleteAlerts(int resourceId, Integer[] alertIds) { - this.alertManager.deleteAlerts(getSessionSubject(), resourceId, alertIds); + public void deleteResourceAlerts(Integer[] alertIds) { + this.alertManager.deleteResourceAlerts(getSessionSubject(), alertIds); } } \ No newline at end of file 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 057ce4d..8183853 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 @@ -85,6 +85,7 @@ import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.text.SimpleDateFormat; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Date; @@ -159,6 +160,25 @@ public class AlertManagerBean implements AlertManagerLocal, AlertManagerRemote { } }
+ public void deleteResourceAlerts(Subject user, Integer[] alertIds) { + Query q = entityManager.createNamedQuery(Alert.QUERY_FIND_RESOURCES); + q.setParameter("alertIds", Arrays.asList(alertIds)); + List<Resource> resources = q.getResultList(); + + List<Resource> forbiddenResources = new ArrayList<Resource>(); + for (Resource resource : resources) { + if (!authorizationManager.hasResourcePermission(user, Permission.MANAGE_ALERTS, resource.getId())) { + forbiddenResources.add(resource); + } + } + if (!forbiddenResources.isEmpty()) { + throw new PermissionException("User [" + user.getName() + "] does not have permissions to delete alerts " + + "for the following Resource(s): " + forbiddenResources); + } + + deleteAlerts(alertIds); + } + public void deleteAlerts(Subject user, int resourceId, Integer[] ids) { if (!authorizationManager.hasResourcePermission(user, Permission.MANAGE_ALERTS, resourceId)) { throw new PermissionException("User [" + user.getName() + "] does not have permissions to delete alerts " diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerLocal.java index efdf723..e953b2c 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerLocal.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerLocal.java @@ -41,6 +41,17 @@ public interface AlertManagerLocal {
Alert updateAlert(Alert alert);
+ /** + * Delete the Resource alerts with the specified id's if the specified user has permission to do so (i.e. either + * the MANAGE_INVENTORY global permission, or the MANAGE_ALERTS Resource permission for all associated Resources). + * If the user does not have permission for all of the specified alerts, then none of the alerts will be deleted + * and a PermissionException will be thrown. + * + * @param user the user requesting the deletion + * @param alertIds the id's of the Resource alerts to be deleted + */ + void deleteResourceAlerts(Subject user, Integer[] alertIds); + void deleteAlerts(Subject user, int resourceId, Integer[] ids);
void deleteAlertsForResourceGroup(Subject user, int resourceGroupId, Integer[] ids);