/*
* RHQ Management Platform
* Copyright (C) 2005-2008 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
package org.rhq.enterprise.gui.alert;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.faces.application.FacesMessage;
import javax.faces.model.DataModel;
import javax.faces.model.SelectItem;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.rhq.core.domain.alert.Alert;
import org.rhq.core.domain.alert.AlertCondition;
import org.rhq.core.domain.alert.AlertConditionLog;
import org.rhq.core.domain.alert.AlertPriority;
import org.rhq.core.domain.alert.composite.AlertWithLatestConditionLog;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.common.EntityContext;
import org.rhq.core.domain.common.composite.IntegerOptionItem;
import org.rhq.core.domain.criteria.AlertCriteria;
import org.rhq.core.domain.measurement.DataType;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
import org.rhq.core.gui.util.FacesContextUtility;
import org.rhq.core.gui.util.StringUtility;
import org.rhq.core.server.MeasurementConverter;
import org.rhq.enterprise.gui.common.converter.SelectItemUtils;
import org.rhq.enterprise.gui.common.framework.PagedDataTableUIBean;
import org.rhq.enterprise.gui.common.paging.PageControlView;
import org.rhq.enterprise.gui.common.paging.PagedListDataModel;
import org.rhq.enterprise.gui.legacy.action.resource.common.monitor.alerts.AlertDefUtil;
import org.rhq.enterprise.gui.util.EnterpriseFacesContextUtility;
import org.rhq.enterprise.server.alert.AlertDefinitionManagerLocal;
import org.rhq.enterprise.server.alert.AlertManagerLocal;
import org.rhq.enterprise.server.util.LookupUtil;
/**
* @author Greg Hinkle
* @author Joseph Marques
*/
public class ListAlertHistoryUIBean extends PagedDataTableUIBean {
private static final Log log = LogFactory.getLog(ListAlertHistoryUIBean.class);
public static final String MANAGED_BEAN_NAME = "ListAlertHistoryUIBean";
// filter stuff
private String dateFilter;
private String dateErrors;
private String alertDefinitionFilter;
private String alertPriorityFilter;
private SelectItem[] alertDefinitionSelectItems;
private SelectItem[] alertPrioritySelectItems;
private AlertManagerLocal alertManager = LookupUtil.getAlertManager();
private AlertDefinitionManagerLocal alertDefinitionManager = LookupUtil.getAlertDefinitionManager();
public ListAlertHistoryUIBean() {
}
public String getDateFilter() {
if (dateFilter == null) {
dateFilter = FacesContextUtility.getOptionalRequestParameter("alertHistoryForm:dateFilter");
}
return this.dateFilter;
}
public void setDateFilter(String dateFilter) {
this.dateFilter = dateFilter;
}
public String getDateErrors() {
return this.dateErrors;
}
public void setDateErrors(String dateErrors) {
this.dateErrors = dateErrors;
}
/*
* definition filter stuff
*/
public String getAlertDefinitionFilter() {
if (alertDefinitionFilter == null) {
alertDefinitionFilter = SelectItemUtils.getSelectItemFilter("alertHistoryForm:alertDefinitionFilter");
}
return SelectItemUtils.cleanse(alertDefinitionFilter);
}
public void setAlertDefinitionFilter(String alertDefinitionFilter) {
this.alertDefinitionFilter = alertDefinitionFilter;
}
public SelectItem[] getAlertDefinitionSelectItems() {
if (alertDefinitionSelectItems == null) {
List<IntegerOptionItem> optionItems = alertDefinitionManager.findAlertDefinitionOptionItemsForResource(
getSubject(), getResource().getId());
alertDefinitionSelectItems = SelectItemUtils.convertFromListOptionItem(optionItems, true);
}
return alertDefinitionSelectItems;
}
public void setAlertDefinitionSelectItems(SelectItem[] alertDefinitionSelectItems) {
this.alertDefinitionSelectItems = alertDefinitionSelectItems;
}
/*
* priority filter stuff
*/
public String getAlertPriorityFilter() {
if (alertPriorityFilter == null) {
alertPriorityFilter = SelectItemUtils.getSelectItemFilter("alertHistoryForm:alertPriorityFilter");
}
return SelectItemUtils.cleanse(alertPriorityFilter);
}
public void setAlertPriorityFilter(String alertPriorityFilter) {
this.alertPriorityFilter = alertPriorityFilter;
}
public SelectItem[] getAlertPrioritySelectItems() {
if (alertPrioritySelectItems == null) {
alertPrioritySelectItems = SelectItemUtils.convertFromEnum(AlertPriority.class, true);
}
return alertPrioritySelectItems;
}
public void setAlertPrioritySelectItems(SelectItem[] alertPrioritySelectItems) {
this.alertPrioritySelectItems = alertPrioritySelectItems;
}
public String deleteSelectedAlerts() {
Subject subject = EnterpriseFacesContextUtility.getSubject();
String[] selectedAlerts = getSelectedAlerts();
int[] alertDefinitionIds = StringUtility.getIntArray(selectedAlerts);
try {
alertManager.deleteAlerts(subject, alertDefinitionIds);
FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, "Deleted " + alertDefinitionIds.length
+ " alerts.");
} catch (Exception e) {
FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, "Failed to delete selected alerts.", e);
}
return "success";
}
public String acknowledgeSelectedAlerts() {
Subject subject = EnterpriseFacesContextUtility.getSubject();
String[] selectedAlerts = getSelectedAlerts();
int[] alertIds = StringUtility.getIntArray(selectedAlerts);
try {
int num = alertManager.acknowledgeAlerts(subject, alertIds);
if (num == -1)
FacesContextUtility.addMessage(FacesMessage.SEVERITY_WARN, "No Alerts passed to ack");
else
FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, "Acknowledged " + num + " alerts");
} catch (Exception e) {
FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, "Failed to acknowledge selected alerts.", e);
}
return "success";
}
public String purgeAllAlerts() {
Subject subject = EnterpriseFacesContextUtility.getSubject();
Resource resource = EnterpriseFacesContextUtility.getResource();
try {
int numDeleted = alertManager.deleteAlertsByContext(subject, EntityContext.forResource(resource.getId()));
FacesContextUtility.addMessage(FacesMessage.SEVERITY_INFO, "Deleted " + numDeleted
+ " alerts on this resource");
} catch (Exception e) {
FacesContextUtility.addMessage(FacesMessage.SEVERITY_ERROR, "Failed to delete alerts for resource[ "
+ resource.getId() + " ]", e);
log.error("failed to delete alerts for resource[ " + resource.getId() + " ]", e);
}
return "success";
}
@Override
public DataModel getDataModel() {
if (dataModel == null) {
dataModel = new ListAlertDefinitionsDataModel(PageControlView.AlertHistoryList, MANAGED_BEAN_NAME);
}
return dataModel;
}
private class ListAlertDefinitionsDataModel extends PagedListDataModel<AlertWithLatestConditionLog> {
public ListAlertDefinitionsDataModel(PageControlView view, String beanName) {
super(view, beanName);
}
@Override
public PageList<AlertWithLatestConditionLog> fetchPage(PageControl pc) {
String dateStr = getDateFilter(); // get the outer class's JSF-managed property
Date date = null;
ListAlertHistoryUIBean.this.setDateErrors(null);
if ((dateStr != null) && !dateStr.equals("")) {
try {
DateFormat df = new SimpleDateFormat("MM/dd/yy");
date = df.parse(dateStr);
} catch (ParseException pe) {
ListAlertHistoryUIBean.this.setDateErrors("Error: Invalid date filter, format is MM/dd/yy");
// do nothing else, things will pass through will a null date and function properly
}
}
Integer alertDefinitionId = getAlertDefinitionId();
AlertPriority alertPriority = getAlertPriority();
long MILLIS_IN_DAY = 24 * 60 * 60 * 1000;
Long beginTime = null;
Long endTime = null;
if (date != null) {
beginTime = date.getTime();
endTime = new Date(beginTime + MILLIS_IN_DAY).getTime();
}
Resource resource = getResource();
AlertCriteria criteria = new AlertCriteria();
criteria.addFilterResourceIds(resource.getId());
criteria.addFilterAlertDefinitionIds(alertDefinitionId);
criteria.addFilterPriorities(alertPriority);
criteria.addFilterStartTime(beginTime);
criteria.addFilterEndTime(endTime);
criteria.setPageControl(pc);
PageList<Alert> alerts = alertManager.findAlertsByCriteria(getSubject(), criteria);
List<AlertWithLatestConditionLog> results = new ArrayList<AlertWithLatestConditionLog>(alerts.size());
HttpServletRequest request = FacesContextUtility.getRequest();
for (Alert alert : alerts) {
String recoveryInfo = AlertDefUtil.getAlertRecoveryInfo(alert, resource.getId());
if (alert.getConditionLogs().size() > 1) {
results.add(new AlertWithLatestConditionLog(alert, "Multiple Conditions", "--", recoveryInfo));
} else if (alert.getConditionLogs().size() == 1) {
AlertConditionLog log = alert.getConditionLogs().iterator().next();
AlertCondition condition = log.getCondition();
String displayText = AlertDefUtil.formatAlertConditionForDisplay(condition, request);
String firedValue = log.getValue();
if (isPureNumeric(condition)) {
firedValue = MeasurementConverter.format(Double.valueOf(log.getValue()), condition
.getMeasurementDefinition().getUnits(), true);
}
results.add(new AlertWithLatestConditionLog(alert, displayText, firedValue, recoveryInfo));
} else {
results.add(new AlertWithLatestConditionLog(alert, "No Conditions", "--", recoveryInfo));
}
}
return new PageList<AlertWithLatestConditionLog>(results, alerts.getTotalSize(), pc);
}
}
private boolean isPureNumeric(AlertCondition condition) {
return condition.getMeasurementDefinition() != null
&& condition.getMeasurementDefinition().getDataType() != DataType.CALLTIME;
}
private Integer getAlertDefinitionId() {
String alertDefinitionString = getAlertDefinitionFilter();
if (alertDefinitionString != null) {
return Integer.parseInt(alertDefinitionString);
}
return null;
}
private AlertPriority getAlertPriority() {
String alertPriorityName = getAlertPriorityFilter();
if (alertPriorityName != null) {
return Enum.valueOf(AlertPriority.class, alertPriorityName);
}
return null;
}
private String[] getSelectedAlerts() {
return FacesContextUtility.getRequest().getParameterValues("selectedAlerts");
}
}