[rhq] Branch 'gwt' - modules/core modules/enterprise
by ips
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(a)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);
13 years, 9 months
[rhq] Branch 'gwt' - 3 commits - modules/core modules/enterprise
by Greg Hinkle
dev/null |binary
modules/core/domain/pom.xml | 34 -
modules/core/domain/src/main/java/org/rhq/core/RHQDomain.gwt.xml | 5
modules/core/domain/src/main/java/org/rhq/core/domain/criteria/AlertCriteria.java | 1
modules/core/domain/src/main/java/org/rhq/core/domain/criteria/Criteria.java | 47 -
modules/core/domain/war/org.rhq.core.RHQDomain/RHQDomain.css | 7
modules/core/domain/war/org.rhq.core.RHQDomain/RHQDomain.html | 10
modules/core/domain/war/org.rhq.core.RHQDomain/hosted.html | 333 ----------
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/CoreGUI.java | 13
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/PermissionEditorView.java | 99 ++
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RoleEditView.java | 90 ++
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RoleGroupsEditorItem.java | 100 +++
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RolesDataSource.java | 24
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RolesView.java | 68 +-
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/UsersDataSource.java | 9
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/UsersView.java | 20
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/alert/AlertDataSource.java | 18
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/HeaderLabel.java | 35 +
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/SimpleCollapsiblePanel.java | 1
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/Portlet.java | 3
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGroupGWTService.java | 5
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/ResourceGroupsDataSource.java | 122 +++
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceDatasource.java | 18
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceSearchView.java | 29
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceDetailView.java | 12
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceSummaryView.java | 16
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/GraphListView.java | 9
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/SmallGraphView.java | 27
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/menu/MenuBarView.java | 1
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/ErrorHandler.java | 44 +
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java | 71 +-
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java | 10
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGroupGWTServiceImpl.java | 16
modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.css | 58 +
modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.html | 4
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java | 17
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerBean.java | 10
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryGenerator.java | 61 +
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryRunner.java | 2
39 files changed, 859 insertions(+), 590 deletions(-)
New commits:
commit 39130db6bbeed3e7108ac483443a0d09d6de0c27
Author: Greg Hinkle <ghinkle(a)redhat.com>
Date: Fri Feb 26 16:57:27 2010 -0500
Start to Role permission and group assignment editing
RPCDatasource adjusted to expect column names that match the sortOverrides from their respective criteria objects
Adjustments on list-detail model based on UXD feedback
Errorhandling infrastructure
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/CoreGUI.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/CoreGUI.java
index 27cbebd..9b081c0 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/CoreGUI.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/CoreGUI.java
@@ -9,6 +9,7 @@ import org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourcesView;
import org.rhq.enterprise.gui.coregui.client.inventory.resource.detail.ResourceView;
import org.rhq.enterprise.gui.coregui.client.menu.MenuBarView;
import org.rhq.enterprise.gui.coregui.client.places.Place;
+import org.rhq.enterprise.gui.coregui.client.util.ErrorHandler;
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
@@ -44,6 +45,8 @@ public class CoreGUI implements EntryPoint {
private static Subject sessionSubject;
private static Subject fullSubject;
+ private static ErrorHandler errorHandler = new ErrorHandler();
+
private static BreadCrumb breadCrumb;
private static Canvas content;
@@ -61,6 +64,13 @@ public class CoreGUI implements EntryPoint {
});
}
+ GWT.setUncaughtExceptionHandler(new GWT.UncaughtExceptionHandler() {
+ public void onUncaughtException(Throwable e) {
+ SC.say("Globally uncaught exception... " + e.getMessage());
+ e.printStackTrace();
+ }
+ });
+
RequestBuilder b = new RequestBuilder(RequestBuilder.GET, "/j_security_check.do?j_username=rhqadmin&j_password=rhqadmin");
try {
b.setCallback(new RequestCallback() {
@@ -210,6 +220,9 @@ public class CoreGUI implements EntryPoint {
// -------------------- Static application utilities ----------------------
+ public static ErrorHandler getErrorHandler() {
+ return errorHandler;
+ }
public static Subject getSessionSubject() {
return sessionSubject;
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/PermissionEditorView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/PermissionEditorView.java
new file mode 100644
index 0000000..c788499
--- /dev/null
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/PermissionEditorView.java
@@ -0,0 +1,99 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-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 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.coregui.client.admin.roles;
+
+import org.rhq.core.domain.authz.Permission;
+import org.rhq.enterprise.gui.coregui.client.components.SimpleCollapsiblePanel;
+
+import com.smartgwt.client.widgets.Canvas;
+import com.smartgwt.client.widgets.form.DynamicForm;
+import com.smartgwt.client.widgets.form.fields.CanvasItem;
+import com.smartgwt.client.widgets.form.fields.CheckboxItem;
+import com.smartgwt.client.widgets.form.fields.FormItem;
+import com.smartgwt.client.widgets.form.fields.HeaderItem;
+
+import java.util.ArrayList;
+import java.util.EnumSet;
+import java.util.Set;
+
+/**
+ * @author Greg Hinkle
+ */
+public class PermissionEditorView extends CanvasItem {
+
+
+ private Set<Permission> permissions = EnumSet.noneOf(Permission.class);
+
+ private DynamicForm form;
+
+ public PermissionEditorView(String name, String title) {
+ super(name, title);
+
+
+ setCanvas(new SimpleCollapsiblePanel("Permissions", buildForm()));
+ }
+
+ @Override
+ public Canvas getCanvas() {
+ System.out.println("ANythinglksjgalksdjfalskdjfalkdjflaksjdfl?");
+ return super.getCanvas(); // TODO: Implement this method.
+ }
+
+ public Canvas buildForm() {
+ System.out.println("Building permissions canvas");
+
+// Object o = getAttributeAsObject(getFieldName());
+
+ this.form = new DynamicForm();
+ ArrayList<FormItem> items = new ArrayList<FormItem>();
+
+
+ HeaderItem h1 = new HeaderItem("globalPermissions","Global Permissions");
+ h1.setValue("Global Permissions");
+ items.add(h1);
+ for (Permission p : Permission.values()) {
+ if (p.getTarget() == Permission.Target.GLOBAL) {
+ items.add(new CheckboxItem(p.name(),p.name()));
+ }
+ }
+
+ HeaderItem h2 = new HeaderItem("resourcePermissions","Resource Permissions");
+ h2.setValue("Resource Permissions");
+ items.add(h2);
+ for (Permission p : Permission.values()) {
+ if (p.getTarget() == Permission.Target.RESOURCE) {
+ items.add(new CheckboxItem(p.name(),p.name()));
+ }
+ }
+
+ form.setItems(items.toArray(new FormItem[items.size()]));
+
+
+ return form;
+ }
+
+
+ public void setPermissions(Set<Permission> permissions) {
+ this.permissions = permissions;
+ for (Permission p : Permission.values()) {
+ form.setValue(p.name(), permissions.contains(p));
+ }
+ form.markForRedraw();
+ }
+}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RoleEditView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RoleEditView.java
index 01e3843..56b913e 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RoleEditView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RoleEditView.java
@@ -18,56 +18,116 @@
*/
package org.rhq.enterprise.gui.coregui.client.admin.roles;
+import org.rhq.core.domain.authz.Permission;
+import org.rhq.core.domain.resource.group.ResourceGroup;
+import org.rhq.core.domain.util.PageList;
+import org.rhq.enterprise.gui.coregui.client.components.HeaderLabel;
+
import com.smartgwt.client.data.DataSource;
import com.smartgwt.client.data.Record;
+import com.smartgwt.client.types.Overflow;
+import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.Label;
import com.smartgwt.client.widgets.form.DynamicForm;
+import com.smartgwt.client.widgets.form.fields.CanvasItem;
+import com.smartgwt.client.widgets.form.fields.FormItem;
+import com.smartgwt.client.widgets.form.fields.ResetItem;
+import com.smartgwt.client.widgets.form.fields.SectionItem;
import com.smartgwt.client.widgets.form.fields.SubmitItem;
+import com.smartgwt.client.widgets.form.fields.TextItem;
import com.smartgwt.client.widgets.layout.VLayout;
+import java.util.Set;
+
/**
* @author Greg Hinkle
*/
public class RoleEditView extends VLayout {
private Label message = new Label("Select a role to edit...");
+
+
+ private VLayout editCanvas;
+ private HeaderLabel editLabel;
private DynamicForm form;
+ private PermissionEditorView permissionEditorItem;
+ private RoleGroupsEditorItem assignedGroupEditorItem;
+
+ public RoleEditView() {
+ super();
+ setPadding(10);
+ setOverflow(Overflow.AUTO);
+ }
+
@Override
protected void onInit() {
super.onInit();
-// addMember(message);
+
+ addMember(message);
addMember(buildRoleForm());
-
+
+ editCanvas.hide();
}
- DynamicForm buildRoleForm() {
+ private Canvas buildRoleForm() {
+
+ this.editCanvas = new VLayout();
+
+ editLabel = new HeaderLabel("Create User");
+ // TODO create header css style and set
+
+ editCanvas.addMember(editLabel);
form = new DynamicForm();
form.setAutoFetchData(true);
form.setDataSource(RolesDataSource.getInstance());
- form.setUseAllDataSourceFields(true);
+ TextItem idItem = new TextItem("id","Id");
+
+ TextItem nameItem = new TextItem("name","Name");
+
+ permissionEditorItem = new PermissionEditorView("permissionEditor", "Permissions");
+ permissionEditorItem.setShowTitle(false);
+ permissionEditorItem.setColSpan(2);
+
- form.setItems(new SubmitItem("save","Save"));
- form.setItems(new SubmitItem("cancel","Cancel"));
-// form.hide();
+ assignedGroupEditorItem = new RoleGroupsEditorItem("assignedGroups","Assigned Groups");
+ assignedGroupEditorItem.setShowTitle(false);
+ assignedGroupEditorItem.setColSpan(2);
- return form;
+ form.setItems(
+ idItem,
+ nameItem,
+ permissionEditorItem,
+ assignedGroupEditorItem,
+ new SubmitItem("save", "Save"), new ResetItem("reset", "Reset"));
+
+
+ editCanvas.addMember(form);
+
+ return editCanvas;
}
public void editRecord(Record record) {
-
- form.editRecord(record);
-// message.hide();
- form.show();
- form.redraw();
+ message.hide();
+ editCanvas.show();
+ try {
+ editLabel.setContents("Editing user " + record.getAttribute("name"));
+ form.editRecord(record);
+ permissionEditorItem.setPermissions((Set<Permission>) record.getAttributeAsObject("permissions"));
+ assignedGroupEditorItem.setGroups((PageList<ResourceGroup>) record.getAttributeAsObject("assignedGroups"));
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+ markForRedraw();
}
public void editNone() {
-// form.hide();
-// message.show();
+ message.show();
+ editCanvas.hide();
+ markForRedraw();
}
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RoleGroupsEditorItem.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RoleGroupsEditorItem.java
new file mode 100644
index 0000000..1a2da36
--- /dev/null
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RoleGroupsEditorItem.java
@@ -0,0 +1,100 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-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 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.coregui.client.admin.roles;
+
+import org.rhq.core.domain.resource.group.ResourceGroup;
+import org.rhq.core.domain.util.PageList;
+import org.rhq.enterprise.gui.coregui.client.components.SimpleCollapsiblePanel;
+import org.rhq.enterprise.gui.coregui.client.inventory.groups.ResourceGroupsDataSource;
+
+import com.smartgwt.client.types.DragDataAction;
+import com.smartgwt.client.types.DragTrackerMode;
+import com.smartgwt.client.widgets.Canvas;
+import com.smartgwt.client.widgets.TransferImgButton;
+import com.smartgwt.client.widgets.form.fields.CanvasItem;
+import com.smartgwt.client.widgets.grid.ListGrid;
+import com.smartgwt.client.widgets.grid.ListGridField;
+import com.smartgwt.client.widgets.layout.HLayout;
+import com.smartgwt.client.widgets.layout.VStack;
+
+/**
+ * @author Greg Hinkle
+ */
+public class RoleGroupsEditorItem extends CanvasItem {
+
+ private PageList<ResourceGroup> assignedGroups;
+
+ private ListGrid assignedGroupGrid;
+ private ListGrid availableGroupGrid;
+
+ public RoleGroupsEditorItem(String name, String title) {
+ super(name, title);
+ setCanvas(new SimpleCollapsiblePanel("Assigned Groups", buildForm()));
+ }
+
+ private Canvas buildForm() {
+
+ HLayout layout = new HLayout(10);
+
+ availableGroupGrid = new ListGrid();
+ availableGroupGrid.setMinHeight(350);
+ availableGroupGrid.setCanDragRecordsOut(true);
+ availableGroupGrid.setDragTrackerMode(DragTrackerMode.RECORD);
+ availableGroupGrid.setDragDataAction(DragDataAction.MOVE);
+ availableGroupGrid.setDataSource(new ResourceGroupsDataSource());
+ availableGroupGrid.setAutoFetchData(true);
+ availableGroupGrid.setFields(new ListGridField("id",50), new ListGridField("name"));
+
+ layout.addMember(availableGroupGrid);
+
+ VStack moveButtonStack = new VStack(10);
+ moveButtonStack.setWidth(50);
+
+ TransferImgButton addButton = new TransferImgButton(TransferImgButton.RIGHT);
+ TransferImgButton removeButton = new TransferImgButton(TransferImgButton.LEFT);
+ TransferImgButton addAllButton = new TransferImgButton(TransferImgButton.RIGHT_ALL);
+ TransferImgButton removeAllButton = new TransferImgButton(TransferImgButton.LEFT_ALL);
+
+ moveButtonStack.addMember(addButton);
+ moveButtonStack.addMember(removeButton);
+ moveButtonStack.addMember(addAllButton);
+ moveButtonStack.addMember(removeAllButton);
+
+ layout.addMember(moveButtonStack);
+
+ assignedGroupGrid = new ListGrid();
+ assignedGroupGrid.setMinHeight(350);
+ assignedGroupGrid.setCanDragRecordsOut(true);
+ assignedGroupGrid.setCanAcceptDroppedRecords(true);
+ assignedGroupGrid.setDataSource(new ResourceGroupsDataSource());
+ assignedGroupGrid.setFields(new ListGridField("id", 50), new ListGridField("name"));
+
+ layout.addMember(assignedGroupGrid);
+
+
+ return layout;
+ }
+
+ public void setGroups(PageList<ResourceGroup> assignedGroups) {
+ this.assignedGroups = assignedGroups;
+
+ assignedGroupGrid.setData(ResourceGroupsDataSource.buildRecords(assignedGroups));
+ }
+
+}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RolesDataSource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RolesDataSource.java
index bf97cca..bf100c0 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RolesDataSource.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RolesDataSource.java
@@ -40,12 +40,10 @@ import com.smartgwt.client.widgets.grid.ListGridRecord;
*/
public class RolesDataSource extends RPCDataSource {
- private RoleGWTServiceAsync roleService = GWTServiceLookup.getRoleService();
-
- private boolean initialized = false;
-
private static RolesDataSource INSTANCE;
+ private RoleGWTServiceAsync roleService = GWTServiceLookup.getRoleService();
+
public static RolesDataSource getInstance() {
if (INSTANCE == null) {
INSTANCE = new RolesDataSource();
@@ -53,15 +51,12 @@ public class RolesDataSource extends RPCDataSource {
return INSTANCE;
}
-
- private String query;
-
protected RolesDataSource() {
super("Roles");
-
DataSourceField idDataField = new DataSourceIntegerField("id", "ID");
idDataField.setPrimaryKey(true);
+ idDataField.setCanEdit(false);
DataSourceTextField nameField = new DataSourceTextField("name", "Name");
@@ -74,8 +69,13 @@ public class RolesDataSource extends RPCDataSource {
final long start = System.currentTimeMillis();
RoleCriteria criteria = new RoleCriteria();
- criteria.setPageControl(getPageControl(request, criteria.getAlias()));
-
+ criteria.setPageControl(getPageControl(request));
+
+
+ criteria.setFetchResourceGroups(true);
+ criteria.setFetchPermissions(true);
+ criteria.setFetchSubjects(true);
+
roleService.findRolesByCriteria(criteria, new AsyncCallback<PageList<Role>>() {
public void onFailure(Throwable caught) {
Window.alert("Failed to load " + caught.getMessage());
@@ -94,7 +94,10 @@ public class RolesDataSource extends RPCDataSource {
ListGridRecord record = new ListGridRecord();
record.setAttribute("id", role.getId());
record.setAttribute("name", role.getName());
+
+ record.setAttribute("resourceGroups", role.getResourceGroups());
record.setAttribute("permissions", role.getPermissions());
+ record.setAttribute("subjects", role.getSubjects());
records[x] = record;
}
@@ -102,7 +105,6 @@ public class RolesDataSource extends RPCDataSource {
response.setData(records);
response.setTotalRows(result.getTotalSize()); // for paging to work we have to specify size of full result set
processResponse(request.getRequestId(), response);
-
}
});
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RolesView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RolesView.java
index 7356424..ab78f58 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RolesView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RolesView.java
@@ -18,10 +18,14 @@
*/
package org.rhq.enterprise.gui.coregui.client.admin.roles;
+import org.rhq.enterprise.gui.coregui.client.Presenter;
import org.rhq.enterprise.gui.coregui.client.admin.users.UsersDataSource;
+import org.rhq.enterprise.gui.coregui.client.places.Place;
+import com.smartgwt.client.docs.CheckboxField;
import com.smartgwt.client.types.Autofit;
import com.smartgwt.client.types.ListGridFieldType;
+import com.smartgwt.client.types.Overflow;
import com.smartgwt.client.types.SelectionAppearance;
import com.smartgwt.client.types.SelectionStyle;
import com.smartgwt.client.types.VisibilityMode;
@@ -31,6 +35,7 @@ import com.smartgwt.client.widgets.IButton;
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.form.fields.CheckboxItem;
import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.grid.ListGridField;
import com.smartgwt.client.widgets.grid.events.SelectionChangedHandler;
@@ -41,17 +46,18 @@ import com.smartgwt.client.widgets.layout.SectionStackSection;
import com.smartgwt.client.widgets.layout.VLayout;
import com.smartgwt.client.widgets.toolbar.ToolStrip;
+import java.util.List;
+
/**
* @author Greg Hinkle
*/
-public class RolesView extends SectionStack {
+public class RolesView extends VLayout implements Presenter {
@Override
protected void onInit() {
super.onInit();
- setVisibilityMode(VisibilityMode.MULTIPLE);
setWidth100();
setHeight100();
@@ -59,7 +65,10 @@ public class RolesView extends SectionStack {
VLayout gridHolder = new VLayout();
gridHolder.setWidth100();
- gridHolder.setHeight100();
+ gridHolder.setHeight("50%");
+ gridHolder.setShowResizeBar(true);
+ gridHolder.setResizeBarTarget("next");
+
final ListGrid listGrid = new ListGrid();
listGrid.setWidth100();
@@ -68,24 +77,20 @@ public class RolesView extends SectionStack {
listGrid.setAutoFetchData(true);
listGrid.setAutoFitData(Autofit.HORIZONTAL);
listGrid.setAlternateRecordStyles(true);
- listGrid.setSelectionType(SelectionStyle.SIMPLE);
- listGrid.setSelectionAppearance(SelectionAppearance.CHECKBOX);
+// listGrid.setSelectionType(SelectionStyle.SIMPLE);
+// listGrid.setSelectionAppearance(SelectionAppearance.CHECKBOX);
listGrid.setShowFilterEditor(true);
+// listGrid.setUseAllDataSourceFields(true);
+
+
+ ListGridField idField = new ListGridField("id", "Id", 55);
+ idField.setType(ListGridFieldType.INTEGER);
- listGrid.setUseAllDataSourceFields(true);
+ ListGridField nameField = new ListGridField("username", "Name");
-// ListGridField idField = new ListGridField("id", "Id", 55);
-// idField.setType(ListGridFieldType.INTEGER);
-//
-// ListGridField nameField = new ListGridField("username", "Name", 100);
-//
-//
-// ListGridField descriptionField = new ListGridField("name", "Name", 150);
-// ListGridField emailField = new ListGridField("email", "Email Address", 100);
-//
-// listGrid.setFields(idField, nameField, descriptionField, emailField);
+ listGrid.setFields(idField, nameField);
gridHolder.addMember(listGrid);
@@ -127,31 +132,36 @@ public class RolesView extends SectionStack {
});
- SectionStackSection topSection = new SectionStackSection("Roles");
- topSection.setExpanded(true);
- topSection.setItems(gridHolder);
-
- addSection(topSection);
-
+ addMember(gridHolder);
final RoleEditView roleEditor = new RoleEditView();
-
- final SectionStackSection detailSection = new SectionStackSection("Edit Role");
- detailSection.setItems(roleEditor);
- addSection(detailSection);
+ roleEditor.setOverflow(Overflow.AUTO);
+ addMember(roleEditor);
listGrid.addSelectionChangedHandler(new SelectionChangedHandler() {
public void onSelectionChanged(SelectionEvent selectionEvent) {
if (selectionEvent.getState()) {
- expandSection(1);
roleEditor.editRecord(selectionEvent.getRecord());
- } else
- collapseSection(1);
+ } else {
roleEditor.editNone();
+ }
}
});
}
+
+ public boolean fireDisplay(Place place, List<Place> children) {
+ if (!getPlace().equals(place)) {
+ return false;
+ }
+
+
+ return true;
+ }
+
+ public Place getPlace() {
+ return new Place("Roles", "Manage Roles");
+ }
}
\ No newline at end of file
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/UsersDataSource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/UsersDataSource.java
index 6bfc7a6..dcf7199 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/UsersDataSource.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/UsersDataSource.java
@@ -25,6 +25,7 @@ import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
import org.rhq.enterprise.gui.coregui.client.gwt.SubjectGWTServiceAsync;
import org.rhq.enterprise.gui.coregui.client.util.RPCDataSource;
+import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.smartgwt.client.data.DSRequest;
@@ -62,16 +63,12 @@ public class UsersDataSource extends RPCDataSource {
DataSourceTextField usernameField = new DataSourceTextField("username", "User Name");
usernameField.setCanEdit(false);
- //DataSourceTextField name = new DataSourceTextField("name", "Name");
-
DataSourceTextField firstName = new DataSourceTextField("firstName", "First Name");
DataSourceTextField lastName = new DataSourceTextField("lastName", "Last Name");
-
DataSourceTextField email = new DataSourceTextField("email", "Email Address");
-
DataSourceTextField phone = new DataSourceTextField("phoneNumber", "Phone");
DataSourceTextField department = new DataSourceTextField("department", "Department");
@@ -90,7 +87,7 @@ public class UsersDataSource extends RPCDataSource {
final long start = System.currentTimeMillis();
SubjectCriteria criteria = new SubjectCriteria();
- criteria.setPageControl(getPageControl(request, criteria.getAlias()));
+ criteria.setPageControl(getPageControl(request));
subjectService.findSubjectsByCriteria(criteria, new AsyncCallback<PageList<Subject>>() {
public void onFailure(Throwable caught) {
@@ -109,7 +106,7 @@ public class UsersDataSource extends RPCDataSource {
ListGridRecord record = new ListGridRecord();
record.setAttribute("id",res.getId());
record.setAttribute("username",res.getName());
- record.setAttribute("name",res.getFirstName() + " " + res.getLastName());
+// record.setAttribute("name",res.getFirstName() + " " + res.getLastName());
record.setAttribute("firstName", res.getFirstName());
record.setAttribute("lastName", res.getLastName());
record.setAttribute("factive", res.getFactive());
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/UsersView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/UsersView.java
index ba3bab3..1c2b183 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/UsersView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/UsersView.java
@@ -18,7 +18,9 @@
*/
package org.rhq.enterprise.gui.coregui.client.admin.users;
+import org.rhq.enterprise.gui.coregui.client.Presenter;
import org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceDatasource;
+import org.rhq.enterprise.gui.coregui.client.places.Place;
import com.smartgwt.client.data.Criteria;
import com.smartgwt.client.types.Alignment;
@@ -44,10 +46,12 @@ import com.smartgwt.client.widgets.layout.SectionStackSection;
import com.smartgwt.client.widgets.layout.VLayout;
import com.smartgwt.client.widgets.toolbar.ToolStrip;
+import java.util.List;
+
/**
* @author Greg Hinkle
*/
-public class UsersView extends SectionStack {
+public class UsersView extends SectionStack implements Presenter {
@@ -154,4 +158,18 @@ public class UsersView extends SectionStack {
addSection(detailsSection);
}
+
+ public boolean fireDisplay(Place place, List<Place> children) {
+ if (!place.equals(getPlace())) {
+ return false;
+ }
+ if (children.size() > 0) {
+ int userId = Integer.parseInt(children.get(0).getId());
+ }
+ return true;
+ }
+
+ public Place getPlace() {
+ return new Place("users", "Users");
+ }
}
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 9e73bbb..58c96e3 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
@@ -77,10 +77,10 @@ public class AlertDataSource extends RPCDataSource {
idDataField.setPrimaryKey(true);
idDataField.setHidden(true);
- DataSourceField resourceIdDataField = new DataSourceIntegerField("alertDefinition.resource.Id", "Resource Id");
+ DataSourceField resourceIdDataField = new DataSourceIntegerField("resourceId", "Resource Id");
idDataField.setHidden(true);
- DataSourceTextField nameField = new DataSourceTextField("alertDefinition.name", "Name", 100);
+ DataSourceTextField nameField = new DataSourceTextField("name", "Name", 100);
DataSourceTextField conditionTextField = new DataSourceTextField("conditionText", "Condition Text");
conditionTextField.setCanSortClientOnly(true);
@@ -92,7 +92,7 @@ public class AlertDataSource extends RPCDataSource {
recoveryInfoField.setCanSortClientOnly(true);
// TODO: Use DataSourceEnumField here?
- DataSourceTextField priorityField = new DataSourceTextField("alertDefinition.priority", "Priority", 15);
+ DataSourceTextField priorityField = new DataSourceTextField("priority", "Priority", 15);
DataSourceTextField ctimeField = new DataSourceTextField("ctime", "Creation Time");
@@ -159,7 +159,7 @@ public class AlertDataSource extends RPCDataSource {
criteria.fetchConditionLogs(true);
criteria.fetchRecoveryAlertDefinition(true);
- criteria.setPageControl(getPageControl(request, criteria.getAlias()));
+ criteria.setPageControl(getPageControl(request));
this.alertService.findAlertsByCriteria(criteria, new AsyncCallback<PageList<Alert>>() {
public void onFailure(Throwable caught) {
@@ -197,9 +197,9 @@ public class AlertDataSource extends RPCDataSource {
private ListGridRecord createRecord(Alert alert) {
ListGridRecord record = new ListGridRecord();
record.setAttribute("id", alert.getId());
- record.setAttribute("alertDefinition.resource.id", alert.getAlertDefinition().getResource().getId());
- record.setAttribute("alertDefinition.name", alert.getAlertDefinition().getName());
- record.setAttribute("alertDefinition.priority", alert.getAlertDefinition().getPriority().name());
+ record.setAttribute("resourceId", alert.getAlertDefinition().getResource().getId());
+ record.setAttribute("name", alert.getAlertDefinition().getName());
+ record.setAttribute("priority", alert.getAlertDefinition().getPriority().name());
record.setAttribute("ctime", DATE_TIME_FORMAT.format(new Date(alert.getCtime())));
Set<AlertConditionLog> conditionLogs = alert.getConditionLogs();
@@ -229,11 +229,11 @@ public class AlertDataSource extends RPCDataSource {
return record;
}
- @Override
+ /*@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/components/HeaderLabel.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/HeaderLabel.java
new file mode 100644
index 0000000..f4ddfc3
--- /dev/null
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/HeaderLabel.java
@@ -0,0 +1,35 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-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 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.coregui.client.components;
+
+import com.smartgwt.client.widgets.HTMLFlow;
+import com.smartgwt.client.widgets.Label;
+
+/**
+ * @author Greg Hinkle
+ */
+public class HeaderLabel extends HTMLFlow {
+
+ public HeaderLabel(String contents) {
+ super(contents);
+ setHeight(60);
+ setStylePrimaryName("HeaderLabel");
+ setStyleName("HeaderLabel");
+ }
+}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/SimpleCollapsiblePanel.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/SimpleCollapsiblePanel.java
index 84d7c8c..e516d00 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/SimpleCollapsiblePanel.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/SimpleCollapsiblePanel.java
@@ -67,6 +67,7 @@ public class SimpleCollapsiblePanel extends VLayout {
button.setIcon("[skin]/images/SectionHeader/opener_closed.png");
content.hide();
}
+ getParentElement().markForRedraw();
markForRedraw();
}
});
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/Portlet.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/Portlet.java
index 7c2c825..71e97c4 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/Portlet.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/Portlet.java
@@ -54,5 +54,8 @@ public class Portlet extends Window {
// (since width is determined from the containing layout, not the portlet contents)
// setVPolicy(LayoutPolicy.NONE);
setOverflow(Overflow.VISIBLE);
+
+ setCanDragResize(true);
+ setResizeFrom("B");
}
}
\ No newline at end of file
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGroupGWTService.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGroupGWTService.java
index dbacd16..d1fc4a3 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGroupGWTService.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGroupGWTService.java
@@ -19,6 +19,10 @@
package org.rhq.enterprise.gui.coregui.client.gwt;
+import org.rhq.core.domain.criteria.ResourceGroupCriteria;
+import org.rhq.core.domain.resource.group.ResourceGroup;
+import org.rhq.core.domain.util.PageList;
+
import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
@@ -30,5 +34,6 @@ import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
@RemoteServiceRelativePath("ResourceGroupGWTService")
public interface ResourceGroupGWTService extends RemoteService {
+ PageList<ResourceGroup> findResourceGroupsByCriteria(ResourceGroupCriteria criteria);
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/ResourceGroupsDataSource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/ResourceGroupsDataSource.java
new file mode 100644
index 0000000..69a8968
--- /dev/null
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/ResourceGroupsDataSource.java
@@ -0,0 +1,122 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-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 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.coregui.client.inventory.groups;
+
+import org.rhq.core.domain.criteria.ResourceGroupCriteria;
+import org.rhq.core.domain.measurement.AvailabilityType;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.group.ResourceGroup;
+import org.rhq.core.domain.util.PageList;
+import org.rhq.enterprise.gui.coregui.client.CoreGUI;
+import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
+import org.rhq.enterprise.gui.coregui.client.gwt.ResourceGroupGWTServiceAsync;
+import org.rhq.enterprise.gui.coregui.client.util.RPCDataSource;
+
+import com.google.gwt.user.client.Window;
+import com.google.gwt.user.client.rpc.AsyncCallback;
+import com.smartgwt.client.data.DSRequest;
+import com.smartgwt.client.data.DSResponse;
+import com.smartgwt.client.data.DataSourceField;
+import com.smartgwt.client.data.fields.DataSourceImageField;
+import com.smartgwt.client.data.fields.DataSourceIntegerField;
+import com.smartgwt.client.data.fields.DataSourceTextField;
+import com.smartgwt.client.rpc.RPCResponse;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+
+/**
+ * @author Greg Hinkle
+ */
+public class ResourceGroupsDataSource extends RPCDataSource {
+
+ private String query;
+
+ private ResourceGroupGWTServiceAsync groupService = GWTServiceLookup.getResourceGroupService();
+
+
+ public ResourceGroupsDataSource() {
+
+ DataSourceField idDataField = new DataSourceIntegerField("id", "ID", 20);
+ idDataField.setPrimaryKey(true);
+
+ DataSourceTextField nameDataField = new DataSourceTextField("name", "Name", 200);
+ nameDataField.setCanEdit(false);
+
+ DataSourceTextField descriptionDataField = new DataSourceTextField("description", "Description");
+ descriptionDataField.setCanEdit(false);
+
+ DataSourceTextField typeNameDataField = new DataSourceTextField("typeName", "Type");
+ DataSourceTextField pluginNameDataField = new DataSourceTextField("pluginName", "Plugin");
+ DataSourceTextField categoryDataField = new DataSourceTextField("category", "Category");
+
+
+ setFields(idDataField, nameDataField, descriptionDataField, typeNameDataField, pluginNameDataField, categoryDataField);
+ }
+
+ public void executeFetch(final DSRequest request, final DSResponse response) {
+ final long start = System.currentTimeMillis();
+
+ ResourceGroupCriteria criteria = new ResourceGroupCriteria();
+ criteria.setPageControl(getPageControl(request));
+ criteria.addFilterName(query);
+
+
+ groupService.findResourceGroupsByCriteria(criteria, new AsyncCallback<PageList<ResourceGroup>>() {
+ public void onFailure(Throwable caught) {
+ CoreGUI.getErrorHandler().handleError("Failed to load groups", caught);
+ response.setStatus(RPCResponse.STATUS_FAILURE);
+ processResponse(request.getRequestId(), response);
+ }
+
+ public void onSuccess(PageList<ResourceGroup> result) {
+ System.out.println("Data retrieved in: " + (System.currentTimeMillis() - start));
+
+ response.setData(buildRecords(result));
+ response.setTotalRows(result.getTotalSize()); // for paging to work we have to specify size of full result set
+ processResponse(request.getRequestId(), response);
+ }
+ });
+ }
+
+
+ public static ListGridRecord[] buildRecords(PageList<ResourceGroup> groupList) {
+
+ ListGridRecord[] records = null;
+ if (groupList != null) {
+ records = new ListGridRecord[groupList.size()];
+
+ for (int x = 0; x < groupList.size(); x++) {
+ ResourceGroup group = groupList.get(x);
+ ListGridRecord record = new ListGridRecord();
+ record.setAttribute("group", group);
+ record.setAttribute("id", group.getId());
+ record.setAttribute("name", group.getName());
+ record.setAttribute("description", group.getDescription());
+ record.setAttribute("groupCategory", group.getGroupCategory());
+
+ record.setAttribute("resourceType", group.getResourceType());
+ record.setAttribute("typeName", group.getResourceType().getName());
+ record.setAttribute("pluginName", group.getResourceType().getPlugin());
+
+ records[x] = record;
+ }
+ }
+ return records;
+ }
+
+}
\ No newline at end of file
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceDatasource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceDatasource.java
index 618fefe..647b072 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceDatasource.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceDatasource.java
@@ -58,11 +58,15 @@ public class ResourceDatasource extends RPCDataSource {
DataSourceTextField descriptionDataField = new DataSourceTextField("description", "Description");
descriptionDataField.setCanEdit(false);
- DataSourceImageField availabilityDataField = new DataSourceImageField("currentAvailability.availabilityType",
- "Availability", 20);
+ DataSourceTextField typeNameDataField = new DataSourceTextField("typeName", "Type");
+ DataSourceTextField pluginNameDataField = new DataSourceTextField("pluginName", "Plugin");
+ DataSourceTextField categoryDataField = new DataSourceTextField("category", "Category");
+
+ DataSourceImageField availabilityDataField = new DataSourceImageField("currentAvailability", "Availability", 20);
+
availabilityDataField.setCanEdit(false);
- setFields(idDataField, nameDataField, descriptionDataField, availabilityDataField);
+ setFields(idDataField, nameDataField, descriptionDataField, typeNameDataField, pluginNameDataField, categoryDataField, availabilityDataField);
}
public String getQuery() {
@@ -78,7 +82,7 @@ public class ResourceDatasource extends RPCDataSource {
final long start = System.currentTimeMillis();
ResourceCriteria criteria = new ResourceCriteria();
- criteria.setPageControl(getPageControl(request, criteria.getAlias()));
+ criteria.setPageControl(getPageControl(request));
criteria.addFilterName(this.query);
resourceService.findResourcesByCriteria(criteria, new AsyncCallback<PageList<Resource>>() {
@@ -101,7 +105,11 @@ public class ResourceDatasource extends RPCDataSource {
record.setAttribute("id",res.getId());
record.setAttribute("name",res.getName());
record.setAttribute("description",res.getDescription());
- record.setAttribute("currentAvailability.availabilityType",
+ record.setAttribute("typeName",res.getResourceType().getName());
+ record.setAttribute("pluginName",res.getResourceType().getPlugin());
+ record.setAttribute("category",res.getResourceType().getCategory().getDisplayName());
+
+ record.setAttribute("currentAvailability",
res.getCurrentAvailability().getAvailabilityType() == AvailabilityType.UP
? "/images/icons/availability_green_16.png"
: "/images/icons/availability_red_16.png");
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceSearchView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceSearchView.java
index 333a877..8a6b60f 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceSearchView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceSearchView.java
@@ -27,6 +27,7 @@ import org.rhq.enterprise.gui.coregui.client.gwt.ResourceGWTServiceAsync;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.smartgwt.client.data.Criteria;
+import com.smartgwt.client.data.fields.DataSourceTextField;
import com.smartgwt.client.types.Alignment;
import com.smartgwt.client.types.ListGridFieldType;
import com.smartgwt.client.types.SelectionAppearance;
@@ -108,34 +109,17 @@ public class ResourceSearchView extends VLayout {
}
});
- /* TODO: Safe to remove this, we're now using links in the records
- nameField.addRecordClickHandler(new RecordClickHandler() {
- public void onRecordClick(final RecordClickEvent recordClickEvent) {
- for (final ResourceSelectListener l : selectListeners) {
- // TODO GH: This doesn't work
- final int resourceId = recordClickEvent.getRecord().getAttributeAsInt("id");
- ResourceCriteria c = new ResourceCriteria();
- c.addFilterId(resourceId);
- ResourceGWTServiceAsync.Util.getInstance().findResourcesByCriteria(CoreGUI.getSessionSubject(), c, new AsyncCallback<PageList<Resource>>() {
- public void onFailure(Throwable caught) {
- System.out.println("Failed ehre");
- }
- public void onSuccess(PageList<Resource> result) {
+ ListGridField descriptionField = new ListGridField("description", "Description");
+ ListGridField typeNameField = new ListGridField("typeName", "Type", 130);
+ ListGridField pluginNameField = new ListGridField("pluginName", "Plugin", 100);
+ ListGridField categoryField = new ListGridField("category", "Category", 60);
- l.onResourceSelected(result.get(0));
- }
- });
- }
- }
- });
- */
- ListGridField descriptionField = new ListGridField("description", "Description");
ListGridField availabilityField = new ListGridField("currentAvailability", "Availability", 55);
availabilityField.setAlign(Alignment.CENTER);
- listGrid.setFields(idField, nameField, descriptionField, availabilityField);
+ listGrid.setFields(idField, nameField, descriptionField, typeNameField, pluginNameField, categoryField, availabilityField);
gridHolder.addMember(listGrid);
@@ -159,6 +143,7 @@ public class ResourceSearchView extends VLayout {
+
final Label tableInfo = new Label("Total: " + listGrid.getTotalRows());
tableInfo.setWrap(false);
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceDetailView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceDetailView.java
index dede07c..0e2a101 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceDetailView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceDetailView.java
@@ -22,6 +22,7 @@ import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.enterprise.gui.coregui.client.Presenter;
import org.rhq.enterprise.gui.coregui.client.components.FullHTMLPane;
+import org.rhq.enterprise.gui.coregui.client.components.SimpleCollapsiblePanel;
import org.rhq.enterprise.gui.coregui.client.components.SubTabLayout;
import org.rhq.enterprise.gui.coregui.client.components.configuration.ConfigurationEditor;
import org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceSelectListener;
@@ -50,6 +51,7 @@ public class ResourceDetailView extends VLayout implements Presenter, ResourceSe
private Resource resource;
+ private SimpleCollapsiblePanel summaryPanel;
private ResourceSummaryView summaryView;
private Tab summaryTab;
@@ -76,8 +78,14 @@ public class ResourceDetailView extends VLayout implements Presenter, ResourceSe
setWidth100();
setHeight100();
- // addMember(new ResourceSummaryView());
+
+
+ // The header section
summaryView = new ResourceSummaryView();
+ summaryPanel = new SimpleCollapsiblePanel("Summary", summaryView);
+
+
+ // The Tabs section
topTabSet = new TabSet();
topTabSet.setTabBarPosition(Side.TOP);
@@ -102,7 +110,7 @@ public class ResourceDetailView extends VLayout implements Presenter, ResourceSe
title.setContents("Loading...");
addMember(title);
- addMember(summaryView);
+ addMember(summaryPanel);
addMember(topTabSet);
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceSummaryView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceSummaryView.java
index f16b04e..0cd388a 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceSummaryView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/ResourceSummaryView.java
@@ -161,14 +161,14 @@ public class ResourceSummaryView extends DynamicForm implements ResourceSelectLi
// item.setValue("?");
}
- SectionItem section = new SectionItem("Summary", "Summary");
- section.setTitle("Summary");
- section.setDefaultValue("Summary");
- section.setCanCollapse(true);
- section.setCellStyle("HidablePlainSectionHeader");
- section.setItemIds(itemIds.toArray(new String[itemIds.size()]));
-
- formItems.add(0, section);
+// SectionItem section = new SectionItem("Summary", "Summary");
+// section.setTitle("Summary");
+// section.setDefaultValue("Summary");
+// section.setCanCollapse(true);
+// section.setCellStyle("HidablePlainSectionHeader");
+// section.setItemIds(itemIds.toArray(new String[itemIds.size()]));
+// formItems.add(0, section);
+
formItems.add(new SpacerItem());
setItems(formItems.toArray(new FormItem[formItems.size()]));
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/GraphListView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/GraphListView.java
index 1ff9332..df284fa 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/GraphListView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/GraphListView.java
@@ -62,7 +62,9 @@ public class GraphListView extends VLayout implements ResourceSelectListener {
for (Canvas c : getMembers()) {
c.destroy();
}
- buildGraphs();
+ if (resource != null) {
+ buildGraphs();
+ }
}
@@ -113,8 +115,11 @@ public class GraphListView extends VLayout implements ResourceSelectListener {
}
private void buildGraph(MeasurementDefinition def, List<MeasurementDataNumericHighLowComposite> data) {
+ SmallGraphView graph = new SmallGraphView(def, data);
+ graph.setWidth("80%");
+ graph.setHeight(250);
- addMember(new SmallGraphView(def, data));
+ addMember(graph);
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/SmallGraphView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/SmallGraphView.java
index b053c71..525c8b7 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/SmallGraphView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/detail/monitoring/SmallGraphView.java
@@ -36,6 +36,7 @@ import ca.nanometrics.gflot.client.options.TickFormatter;
import org.rhq.core.domain.measurement.MeasurementConverterClient;
import org.rhq.core.domain.measurement.MeasurementDefinition;
+import org.rhq.core.domain.measurement.MeasurementUnits;
import org.rhq.core.domain.measurement.composite.MeasurementDataNumericHighLowComposite;
import com.google.gwt.i18n.client.DateTimeFormat;
@@ -43,6 +44,7 @@ import com.smartgwt.client.types.AnimationEffect;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.HTMLFlow;
import com.smartgwt.client.widgets.Label;
+import com.smartgwt.client.widgets.WidgetCanvas;
import com.smartgwt.client.widgets.layout.VLayout;
import java.util.Date;
@@ -74,9 +76,12 @@ public class SmallGraphView extends VLayout {
super();
this.definition = def;
this.data = data;
- setHeight(250);
+// setHeight(250);
+ setHeight100();
setWidth100();
- setPadding(10);
+// setPadding(10);
+
+
}
public String getName() {
@@ -94,6 +99,13 @@ public class SmallGraphView extends VLayout {
drawGraph();
}
+
+ @Override
+ public void parentResized() {
+ super.parentResized();
+ onDraw();
+ }
+
private void drawGraph() {
PlotModel model = new PlotModel();
@@ -117,7 +129,9 @@ public class SmallGraphView extends VLayout {
// create the plot
SimplePlot plot = new SimplePlot(model, plotOptions);
- plot.setSize("100%","70%");
+ plot.setSize(String.valueOf(getInnerContentWidth()), String.valueOf(getInnerContentHeight() - 20));
+// "80%","80%");
+
// add hover listener
@@ -159,7 +173,8 @@ public class SmallGraphView extends VLayout {
if (definition != null) {
addMember(new HTMLFlow("<b>" + definition.getDisplayName() + "</b> " + definition.getDescription()));
}
- addMember(plot);
+
+ addMember(new WidgetCanvas(plot));
}
private String getHover(PlotItem item) {
@@ -190,7 +205,9 @@ public class SmallGraphView extends VLayout {
plotOptions.setXAxisOptions(new AxisOptions().setTicks(8). setMinimum(min).setMaximum(max).setTickFormatter(new TickFormatter() {
public String formatTickValue(double tickValue, Axis axis) {
- return String.valueOf(new Date((long) tickValue));
+ com.google.gwt.i18n.client.DateTimeFormat dateFormat = DateTimeFormat.getShortDateTimeFormat();
+ return dateFormat.format(new Date((long)tickValue));
+// return String.valueOf(new Date((long) tickValue));
// return MONTH_NAMES[(int) (tickValue - 1)];
}
}));
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/menu/MenuBarView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/menu/MenuBarView.java
index a45cfa4..90dcac4 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/menu/MenuBarView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/menu/MenuBarView.java
@@ -106,6 +106,7 @@ public class MenuBarView extends HLayout {
Hyperlink dashboardLink = new Hyperlink("Dashboard", "Dashboard");
dashboardLink.setStylePrimaryName("TopSectionLink");
+ dashboardLink.setStyleName("TopSectionLink");
addMember(dashboardLink);
Hyperlink demoLink = new Hyperlink("Demo", "Demo");
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/ErrorHandler.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/ErrorHandler.java
new file mode 100644
index 0000000..766f6a5
--- /dev/null
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/ErrorHandler.java
@@ -0,0 +1,44 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-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 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.coregui.client.util;
+
+import com.smartgwt.client.util.SC;
+
+import java.util.List;
+
+/**
+ * @author Greg Hinkle
+ */
+public class ErrorHandler {
+
+
+ private List<String> errors;
+
+
+ public void handleError(String message, Throwable t) {
+
+ // TODO: This is just a placeholder implementation
+ SC.say(message);
+
+ t.printStackTrace();
+ errors.add(message);
+
+ }
+
+}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java
index ef00853..c979e3f 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java
@@ -18,9 +18,11 @@
*/
package org.rhq.enterprise.gui.coregui.client.util;
+import org.rhq.core.domain.criteria.ResourceCriteria;
import org.rhq.core.domain.util.OrderingField;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageOrdering;
+import org.rhq.enterprise.gui.coregui.client.CoreGUI;
import com.smartgwt.client.data.DSRequest;
import com.smartgwt.client.data.DSResponse;
@@ -51,60 +53,59 @@ public abstract class RPCDataSource extends DataSource {
@Override
protected Object transformRequest(DSRequest request) {
- switch (request.getOperationType()) {
- case FETCH:
- DSResponse response = createResponse(request);
- executeFetch(request, response);
- break;
- case ADD:
- case UPDATE:
- case REMOVE:
- super.transformRequest(request);
- break;
- default:
- super.transformRequest(request);
- break;
+ try {
+ switch (request.getOperationType()) {
+ case FETCH:
+ DSResponse response = createResponse(request);
+ executeFetch(request, response);
+ break;
+ case ADD:
+ case UPDATE:
+ case REMOVE:
+ super.transformRequest(request);
+ break;
+ default:
+ super.transformRequest(request);
+ break;
+ }
+ } catch (Throwable t) {
+ CoreGUI.getErrorHandler().handleError("Failure in datasource [" + request.getOperationType() + "]", t);
+ return null;
}
-
return request.getData();
}
/**
* Returns a prepopulated PageControl based on the provided DSRequest. This will set sort fields,
* pagination, but *not* filter fields.
- *
+ *
* @param request the request to turn into a page control
* @return the page control for passing to criteria and other queries
*/
- protected PageControl getPageControl(DSRequest request, String alias) {
+ protected PageControl getPageControl(DSRequest request) {
// Initialize paging.
- PageControl pageControl = PageControl.getExplicitPageControl(request.getStartRow(), request.getEndRow() - request.getStartRow());
+ PageControl pageControl;
+ if (request.getStartRow() == null || request.getEndRow() == null) {
+ pageControl = new PageControl();
+ } else {
+ pageControl = PageControl.getExplicitPageControl(request.getStartRow(), request.getEndRow() - request.getStartRow());
+ }
// Initialize sorting.
String sortBy = request.getAttribute("sortBy");
- if (sortBy == null) {
- List<OrderingField> orderingFields = getDefaultOrderingFields(alias);
- if (orderingFields != null) {
- for (OrderingField orderingField : orderingFields) {
- pageControl.addDefaultOrderingField(orderingField.getField(), orderingField.getOrdering());
- }
- }
- } else {
+ if (sortBy != null) {
String[] sorts = sortBy.split(",");
for (String sort : sorts) {
PageOrdering ordering = (sort.startsWith("-")) ? PageOrdering.DESC : PageOrdering.ASC;
String columnName = (ordering == PageOrdering.DESC) ? sort.substring(1) : sort;
- String fieldName = alias + "." + columnName;
- pageControl.addDefaultOrderingField(fieldName, ordering);
+ ResourceCriteria c;
+ pageControl.addDefaultOrderingField(columnName, ordering);
}
}
return pageControl;
}
- protected List<OrderingField> getDefaultOrderingFields(String alias) {
- return null;
- }
protected abstract void executeFetch(final DSRequest request, final DSResponse response);
@@ -112,13 +113,13 @@ public abstract class RPCDataSource extends DataSource {
* Executed on <code>REMOVE</code> operation. <code>processResponse (requestId, response)</code>
* should be called when operation completes (either successful or failure).
*
- * @param request <code>DSRequest</code> being processed. <code>request.getData ()</code>
- * contains record should be removed.
+ * @param request <code>DSRequest</code> being processed. <code>request.getData ()</code>
+ * contains record should be removed.
* @param response <code>DSResponse</code>. <code>setData (list)</code> should be called on
- * successful execution of this method. Array should contain single element representing
- * removed row. <code>setStatus (<0)</code> should be called on failure.
+ * successful execution of this method. Array should contain single element representing
+ * removed row. <code>setStatus (<0)</code> should be called on failure.
*/
- protected void executeRemove (final DSRequest request, final DSResponse response) {
+ protected void executeRemove(final DSRequest request, final DSResponse response) {
throw new UnsupportedOperationException("This dataSource does not support removal.");
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java
index 4198923..6230e90 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java
@@ -120,17 +120,9 @@ public class ResourceGWTServiceImpl extends AbstractGWTServiceImpl implements Re
resource.setAgent(null);
}
-
- HibernateDetachUtility.nullOutUninitializedFields(result,
- HibernateDetachUtility.SerializationType.SERIALIZATION);
-
- long start = System.currentTimeMillis();
-
ObjectFilter.filterFields(result, importantFieldsSet);
- System.out.println("Took: " + (System.currentTimeMillis() - start) + "ms");
-
- return result;
+ return SerialUtility.prepare(result, "ResourceService.findResourceByCriteria");
} catch (Exception e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
throw new RuntimeException(e);
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGroupGWTServiceImpl.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGroupGWTServiceImpl.java
index 3516ecc..a4ae911 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGroupGWTServiceImpl.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGroupGWTServiceImpl.java
@@ -20,12 +20,26 @@ package org.rhq.enterprise.gui.coregui.server.gwt;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
+import org.rhq.core.domain.criteria.ResourceGroupCriteria;
+import org.rhq.core.domain.resource.group.ResourceGroup;
+import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.gui.coregui.client.gwt.ResourceGroupGWTService;
-
+import org.rhq.enterprise.gui.coregui.server.util.SerialUtility;
+import org.rhq.enterprise.server.resource.group.ResourceGroupManagerBean;
+import org.rhq.enterprise.server.resource.group.ResourceGroupManagerLocal;
+import org.rhq.enterprise.server.util.LookupUtil;
/**
* @author Greg Hinkle
*/
public class ResourceGroupGWTServiceImpl extends AbstractGWTServiceImpl implements ResourceGroupGWTService {
+
+ private ResourceGroupManagerLocal groupManager = LookupUtil.getResourceGroupManager();
+
+ public PageList<ResourceGroup> findResourceGroupsByCriteria(ResourceGroupCriteria criteria) {
+ return SerialUtility.prepare(groupManager.findResourceGroupsByCriteria(getSessionSubject(), criteria),
+ "ResourceGroupService.findResourceGroupsByCriteria");
+ }
+
}
\ No newline at end of file
diff --git a/modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.css b/modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.css
index 76cd9c5..7211bc6 100644
--- a/modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.css
+++ b/modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.css
@@ -1,11 +1,57 @@
-body {
+/*body {
background-color: white;
color: black;
font-family: Arial, sans-serif;
font-size: small;
margin: 8px;
+}*/
+
+body, p, td, th, option, input, textarea, select {
+ color: #000000;
+ font-family: tahoma, verdana, sans-serif;
+ font-size: 11px;
+}
+
+img {
+ border-style: none;
+}
+
+hr {
+ background-color: #AAAAAA;
+ border: 0 none;
+ color: #AAAAAA;
+ height: 1px;
+ margin-left: 0;
+ margin-right: 0;
+ text-align: center;
+ width: 100%;
}
+a:link {
+ color: #003399;
+ font-weight: bold;
+ text-decoration: none;
+}
+
+a:visited {
+ color: #003399;
+ font-weight: bold;
+ text-decoration: none;
+}
+
+a:hover {
+ color: #003399;
+ font-weight: bold;
+ text-decoration: underline;
+}
+
+.HeaderLabel {
+ font-size: 14pt;
+ font-weight: bold;
+ color: #444444;
+}
+
+
.OddRow {
background-color: white;
border-bottom-color: rgb(230, 234, 239);
@@ -57,7 +103,6 @@ body {
color: black;
}
-z
.BreadCrumb {
font-size: 12pt;
@@ -80,6 +125,15 @@ z
}
+
+.GraphTooltip {
+ background-color:#B5D5FF;
+ font-weight:bold;
+ padding:5px;
+}
+
+
+
.SubTabButton,
.SubTabButtonOver,
.SubTabButtonFocused,
diff --git a/modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.html b/modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.html
index f7b8df4..5b78843 100644
--- a/modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.html
+++ b/modules/enterprise/gui/coregui/src/main/webapp/CoreGUI.html
@@ -2,9 +2,13 @@
<head>
<title>RHQ Core Application</title>
<link rel="stylesheet" href="CoreGUI.css">
+ <link rel="icon" type="image/png" href="/images/favicon.png" />
+ <link rel="apple-touch-icon" href="/images/favicon.png" />
<script type="text/javascript">var isomorphicDir = "org.rhq.enterprise.gui.coregui.CoreGUI/sc/";
</script>
+
+
</head>
<body>
<script type="text/javascript" language="javascript"
commit b9c3f28dc306938414c71f70776f8b126fed1679
Author: Greg Hinkle <ghinkle(a)redhat.com>
Date: Fri Feb 26 16:55:07 2010 -0500
Reworked the sort loading from page control to be gwt compatible
Fixed some criteria query using APIs that were not using CriteriaQueryRunner
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 25aa0d8..057ebdf 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
@@ -86,6 +86,7 @@ public class AlertCriteria extends Criteria {
filterOverrides.put("groupAlertDefinitionIds", "alertDefinition.groupAlertDefinition.id IN ( ? )");
sortOverrides.put("name", "alertDefinition.name");
+ sortOverrides.put("resourceId", "alertDefinition.resource.id");
sortOverrides.put("priority", "alertDefinition.priority");
}
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/Criteria.java b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/Criteria.java
index 214be85..75c32dc 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/Criteria.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/Criteria.java
@@ -41,6 +41,7 @@ import java.util.Map;
*/
@XmlAccessorType(XmlAccessType.FIELD)
public abstract class Criteria implements Serializable {
+
public enum Type {
FILTER, FETCH, SORT;
}
@@ -82,6 +83,17 @@ public abstract class Criteria implements Serializable {
public abstract Class getPersistentClass();
+ public Integer getPageNumber() {
+ return pageNumber;
+ }
+
+ public Integer getPageSize() {
+ return pageSize;
+ }
+
+ public List<String> getOrderingFieldNames() {
+ return orderingFieldNames;
+ }
public String getJPQLFilterOverride(String fieldName) {
return filterOverrides.get(fieldName);
@@ -183,39 +195,8 @@ public abstract class Criteria implements Serializable {
this.requiredPermissions = Arrays.asList(requiredPermissions);
}
- public PageControl getPageControl() {
- PageControl pc = null;
-
- if (pageControlOverrides != null) {
- pc = pageControlOverrides;
- } else {
- if (pageNumber == null || pageSize == null) {
- pc = PageControl.getUnlimitedInstance();
- } else {
- pc = new PageControl(pageNumber, pageSize);
- }
- for (String fieldName : orderingFieldNames) {
- /* TODO: GWT
- for (Field sortField : getFields(Type.SORT)) {
- if (sortField.getName().equals(fieldName) == false) {
- continue;
- }
- Object sortFieldValue = null;
- try {
- sortFieldValue = sortField.get(this);
- } catch (IllegalAccessException iae) {
- throw new RuntimeException(iae);
- }
- if (sortFieldValue != null) {
- PageOrdering pageOrdering = (PageOrdering) sortFieldValue;
- pc.addDefaultOrderingField(getCleansedFieldName(sortField, 4), pageOrdering);
- }
- }
- */
- }
- }
- return pc;
- }
+
+
public String getAlias() {
if (this.alias == null) {
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
index 472dbb0..b84dea8 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/ContentManagerBean.java
@@ -95,6 +95,7 @@ import org.rhq.enterprise.server.core.AgentManagerLocal;
import org.rhq.enterprise.server.resource.ResourceTypeManagerLocal;
import org.rhq.enterprise.server.resource.ResourceTypeNotFoundException;
import org.rhq.enterprise.server.util.CriteriaQueryGenerator;
+import org.rhq.enterprise.server.util.CriteriaQueryRunner;
/**
* EJB that handles content subsystem interaction with resources, including content discovery reports and create/delete
@@ -1435,13 +1436,9 @@ public class ContentManagerBean implements ContentManagerLocal, ContentManagerRe
"resource", subject.getId());
}
- Query query = generator.getQuery(entityManager);
- Query countQuery = generator.getCountQuery(entityManager);
+ CriteriaQueryRunner<InstalledPackage> queryRunner = new CriteriaQueryRunner(criteria, generator, entityManager);
- long count = (Long) countQuery.getSingleResult();
- List<InstalledPackage> results = query.getResultList();
-
- return new PageList<InstalledPackage>(results, (int) count, criteria.getPageControl());
+ return queryRunner.execute();
}
@SuppressWarnings("unchecked")
@@ -1461,13 +1458,9 @@ public class ContentManagerBean implements ContentManagerLocal, ContentManagerRe
CriteriaQueryGenerator generator = new CriteriaQueryGenerator(criteria);
- Query query = generator.getQuery(entityManager);
- Query countQuery = generator.getCountQuery(entityManager);
-
- long count = (Long) countQuery.getSingleResult();
- List<PackageVersion> results = query.getResultList();
+ CriteriaQueryRunner<PackageVersion> queryRunner = new CriteriaQueryRunner(criteria, generator, entityManager);
- return new PageList<PackageVersion>(results, (int) count, criteria.getPageControl());
+ return queryRunner.execute();
}
public InstalledPackage getBackingPackageForResource(Subject subject, int resourceId) {
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerBean.java
index dca0b68..e16edc4 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/content/RepoManagerBean.java
@@ -773,13 +773,9 @@ public class RepoManagerBean implements RepoManagerLocal, RepoManagerRemote {
CriteriaQueryGenerator generator = new CriteriaQueryGenerator(criteria);
- Query query = generator.getQuery(entityManager);
- Query countQuery = generator.getCountQuery(entityManager);
-
- long count = (Long) countQuery.getSingleResult();
- List<PackageVersion> packageVersions = query.getResultList();
-
- return new PageList<PackageVersion>(packageVersions, (int) count, criteria.getPageControl());
+ CriteriaQueryRunner<PackageVersion> queryRunner = new CriteriaQueryRunner(criteria, generator, entityManager);
+
+ return queryRunner.execute();
}
@RequiredPermission(Permission.MANAGE_INVENTORY)
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryGenerator.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryGenerator.java
index 7d88f60..033417f 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryGenerator.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryGenerator.java
@@ -252,7 +252,7 @@ public final class CriteriaQueryGenerator {
PageControl pc = criteria.getPageControlOverrides();
if (pc == null) {
overridden = false;
- pc = criteria.getPageControl();
+ pc = getPageControl(criteria);
}
boolean first = true;
@@ -264,19 +264,17 @@ public final class CriteriaQueryGenerator {
results.append(", ");
}
- if (overridden) {
- String fieldName = orderingField.getField();
- PageOrdering ordering = orderingField.getOrdering();
-
- results.append(fieldName).append(' ').append(ordering);
+ String fieldName = orderingField.getField();
+ String override = criteria.getJPQLSortOverride(fieldName);
+ if (override == null) {
+ override = alias + "." + fieldName;
} else {
- String fieldName = orderingField.getField();
- String override = criteria.getJPQLSortOverride(fieldName);
- String fragment = override != null ? override : fieldName;
-
- results.append(alias).append('.').append(fragment);
- results.append(' ').append(orderingField.getOrdering());
+ override = alias + "." + override;
}
+
+ PageOrdering ordering = orderingField.getOrdering();
+
+ results.append(override).append(' ').append(ordering);
}
}
results.append(NL);
@@ -309,7 +307,7 @@ public final class CriteriaQueryGenerator {
}
- private List<Field> getFields(Criteria criteria, Criteria.Type fieldType) {
+ private static List<Field> getFields(Criteria criteria, Criteria.Type fieldType) {
String prefix = fieldType.name().toLowerCase();
List<Field> results = new ArrayList<Field>();
@@ -327,7 +325,7 @@ public final class CriteriaQueryGenerator {
return results;
}
- public String getCleansedFieldName(Field field, int leadingCharsToStrip) {
+ public static String getCleansedFieldName(Field field, int leadingCharsToStrip) {
String fieldNameFragment = field.getName().substring(leadingCharsToStrip);
String fieldName = Character.toLowerCase(fieldNameFragment.charAt(0)) + fieldNameFragment.substring(1);
return fieldName;
@@ -402,7 +400,7 @@ public final class CriteriaQueryGenerator {
String queryString = getQueryString(false);
Query query = em.createQuery(queryString);
setBindValues(query, false);
- PersistenceUtility.setDataPage(query, criteria.getPageControl());
+ PersistenceUtility.setDataPage(query, getPageControl(criteria));
return query;
}
@@ -514,4 +512,37 @@ public final class CriteriaQueryGenerator {
generator.getQueryString(false);
generator.getQueryString(true);
}
+
+
+ public static PageControl getPageControl(Criteria criteria) {
+ PageControl pc = null;
+
+ if (criteria.getPageControlOverrides() != null) {
+ pc = criteria.getPageControlOverrides();
+ } else {
+ if (criteria.getPageNumber() == null || criteria.getPageSize() == null) {
+ pc = PageControl.getUnlimitedInstance();
+ } else {
+ pc = new PageControl(criteria.getPageNumber(), criteria.getPageSize());
+ }
+ for (String fieldName : criteria.getOrderingFieldNames()) {
+ for (Field sortField : getFields(criteria, Criteria.Type.SORT)) {
+ if (sortField.getName().equals(fieldName) == false) {
+ continue;
+ }
+ Object sortFieldValue = null;
+ try {
+ sortFieldValue = sortField.get(criteria);
+ } catch (IllegalAccessException iae) {
+ throw new RuntimeException(iae);
+ }
+ if (sortFieldValue != null) {
+ PageOrdering pageOrdering = (PageOrdering) sortFieldValue;
+ pc.addDefaultOrderingField(getCleansedFieldName(sortField, 4), pageOrdering);
+ }
+ }
+ }
+ }
+ return pc;
+ }
}
\ No newline at end of file
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryRunner.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryRunner.java
index 12099c8..dad2707 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryRunner.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryRunner.java
@@ -57,7 +57,7 @@ public class CriteriaQueryRunner<T> {
initAllPersistentBags(results);
}
- return new PageList<T>(results, (int) count, criteria.getPageControl());
+ return new PageList<T>(results, (int) count, CriteriaQueryGenerator.getPageControl(criteria));
}
private void initAllPersistentBags(List<T> entities) {
commit ca17f94f2925b49a50a48d8112be8eab8407b43d
Author: Greg Hinkle <ghinkle(a)redhat.com>
Date: Fri Feb 26 16:52:53 2010 -0500
Moved the generated files out so they don't intefere with scm
Got rid of the unneeded smartgwt deps
removed extraneous gwt files
diff --git a/modules/core/domain/pom.xml b/modules/core/domain/pom.xml
index 0564164..b47cad8 100644
--- a/modules/core/domain/pom.xml
+++ b/modules/core/domain/pom.xml
@@ -215,11 +215,11 @@
<scope>provided</scope>
</dependency>
- <dependency>
+ <!--<dependency>
<groupId>com.smartgwt</groupId>
<artifactId>smartgwt</artifactId>
<version>2.0</version>
- </dependency>
+ </dependency>-->
</dependencies>
@@ -251,14 +251,20 @@
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>gwt-maven-plugin</artifactId>
- <version>1.2.0-11137</version>
+ <version>1.2</version>
+
<configuration>
- <inplace>true</inplace>
- <logLevel>DEBUG</logLevel>
- <runTarget>RHQDomain.html</runTarget>
- <warSourceDirectory>war</warSourceDirectory>
+ <noServer>true</noServer>
+ <inplace>false</inplace>
+ <logLevel>INFO</logLevel>
<extraJvmArgs>-Xmx512m</extraJvmArgs>
+ <localWorkers>2</localWorkers>
+ <draftCompile>true</draftCompile>
+ <buildOutputDirectory>target/gwtclasses</buildOutputDirectory>
+ <hostedWebapp>target/hostedwar</hostedWebapp>
+ <debugSuspend>false</debugSuspend>
</configuration>
+
<executions>
<execution>
<goals>
@@ -414,4 +420,18 @@
</profiles>
+
+ <repositories>
+ <repository>
+ <id>codehaus</id>
+ <name>codehaus</name>
+ <url>http://repository.codehaus.org/</url>
+ <snapshots>
+ <enabled>false</enabled>
+ </snapshots>
+ </repository>
+ </repositories>
+
+
+
</project>
diff --git a/modules/core/domain/src/main/java/org/rhq/core/RHQDomain.gwt.xml b/modules/core/domain/src/main/java/org/rhq/core/RHQDomain.gwt.xml
index 634ac86..a9a94a9 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/RHQDomain.gwt.xml
+++ b/modules/core/domain/src/main/java/org/rhq/core/RHQDomain.gwt.xml
@@ -3,7 +3,6 @@
<module>
<inherits name='com.google.gwt.user.User'/>
- <inherits name='com.smartgwt.SmartGwt' />
<entry-point class='org.rhq.core.client.RHQDomain'/>
@@ -11,9 +10,9 @@
<source path="domain"/>
- <generate-with class="org.rhq.core.rebind.RecordBuilderGenerator">
+ <!--<generate-with class="org.rhq.core.rebind.RecordBuilderGenerator">
<when-type-assignable class="org.rhq.core.domain.util.Recordizable"/>
- </generate-with>
+ </generate-with>-->
</module>
\ No newline at end of file
diff --git a/modules/core/domain/war/org.rhq.core.RHQDomain/RHQDomain.css b/modules/core/domain/war/org.rhq.core.RHQDomain/RHQDomain.css
deleted file mode 100644
index a111f82..0000000
--- a/modules/core/domain/war/org.rhq.core.RHQDomain/RHQDomain.css
+++ /dev/null
@@ -1,7 +0,0 @@
-body {
- background-color: white;
- color: black;
- font-family: Arial, sans-serif;
- font-size: small;
- margin: 8px;
-}
diff --git a/modules/core/domain/war/org.rhq.core.RHQDomain/RHQDomain.html b/modules/core/domain/war/org.rhq.core.RHQDomain/RHQDomain.html
deleted file mode 100644
index 3878eb5..0000000
--- a/modules/core/domain/war/org.rhq.core.RHQDomain/RHQDomain.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<html>
-<head>
- <title>RHQDomain Application</title>
- <link rel="stylesheet" href="RHQDomain.css">
-</head>
-<body>
-<script type="text/javascript" language="javascript" src="org.rhq.core.RHQDomain.nocache.js"></script>
-<h1>RHQDomain Application</h1>
-</body>
-</html>
diff --git a/modules/core/domain/war/org.rhq.core.RHQDomain/clear.cache.gif b/modules/core/domain/war/org.rhq.core.RHQDomain/clear.cache.gif
deleted file mode 100644
index e565824..0000000
Binary files a/modules/core/domain/war/org.rhq.core.RHQDomain/clear.cache.gif and /dev/null differ
diff --git a/modules/core/domain/war/org.rhq.core.RHQDomain/hosted.html b/modules/core/domain/war/org.rhq.core.RHQDomain/hosted.html
deleted file mode 100644
index e8983af..0000000
--- a/modules/core/domain/war/org.rhq.core.RHQDomain/hosted.html
+++ /dev/null
@@ -1,333 +0,0 @@
-<html>
-<head><script>
-var $wnd = parent;
-var $doc = $wnd.document;
-var $moduleName, $moduleBase, $entry
-,$stats = $wnd.__gwtStatsEvent ? function(a) {return $wnd.__gwtStatsEvent(a);} : null
-,$sessionId = $wnd.__gwtStatsSessionId ? $wnd.__gwtStatsSessionId : null;
-// Lightweight metrics
-if ($stats) {
- var moduleFuncName = location.search.substr(1);
- var moduleFunc = $wnd[moduleFuncName];
- var moduleName = moduleFunc ? moduleFunc.moduleName : "unknown";
- $stats({moduleName:moduleName,sessionId:$sessionId,subSystem:'startup',evtGroup:'moduleStartup',millis:(new Date()).getTime(),type:'moduleEvalStart'});
-}
-var $hostedHtmlVersion="2.0";
-
-var gwtOnLoad;
-var $hosted = "localhost:9997";
-
-function loadIframe(url) {
- var topDoc = window.top.document;
-
- // create an iframe
- var iframeDiv = topDoc.createElement("div");
- iframeDiv.innerHTML = "<iframe scrolling=no frameborder=0 src='" + url + "'>";
- var iframe = iframeDiv.firstChild;
-
- // mess with the iframe style a little
- var iframeStyle = iframe.style;
- iframeStyle.position = "absolute";
- iframeStyle.borderWidth = "0";
- iframeStyle.left = "0";
- iframeStyle.top = "0";
- iframeStyle.width = "100%";
- iframeStyle.backgroundColor = "#ffffff";
- iframeStyle.zIndex = "1";
- iframeStyle.height = "100%";
-
- // update the top window's document's body's style
- var hostBodyStyle = window.top.document.body.style;
- hostBodyStyle.margin = "0";
- hostBodyStyle.height = iframeStyle.height;
- hostBodyStyle.overflow = "hidden";
-
- // insert the iframe
- topDoc.body.insertBefore(iframe, topDoc.body.firstChild);
-}
-
-var ua = navigator.userAgent.toLowerCase();
-if (ua.indexOf("gecko") != -1) {
- // install eval wrapper on FF to avoid EvalError problem
- var __eval = window.eval;
- window.eval = function(s) {
- return __eval(s);
- }
-}
-if (ua.indexOf("chrome") != -1) {
- // work around __gwt_ObjectId appearing in JS objects
- var hop = Object.prototype.hasOwnProperty;
- Object.prototype.hasOwnProperty = function(prop) {
- return prop != "__gwt_ObjectId" && hop.call(this, prop);
- };
-}
-
-// wrapper to call JS methods, which we need both to be able to supply a
-// different this for method lookup and to get the exception back
-function __gwt_jsInvoke(thisObj, methodName) {
- try {
- var args = Array.prototype.slice.call(arguments, 2);
- return [0, window[methodName].apply(thisObj, args)];
- } catch (e) {
- return [1, e];
- }
-}
-
-var __gwt_javaInvokes = [];
-function __gwt_makeJavaInvoke(argCount) {
- return __gwt_javaInvokes[argCount] || __gwt_doMakeJavaInvoke(argCount);
-}
-
-function __gwt_doMakeJavaInvoke(argCount) {
- // IE6 won't eval() anonymous functions except as r-values
- var argList = "";
- for (var i = 0; i < argCount; i++) {
- argList += ",p" + i;
- }
- var argListNoComma = argList.substring(1);
-
- return eval(
- "__gwt_javaInvokes[" + argCount + "] =\n" +
- " function(thisObj, dispId" + argList + ") {\n" +
- " var result = __static(dispId, thisObj" + argList + ");\n" +
- " if (result[0]) {\n" +
- " throw result[1];\n" +
- " } else {\n" +
- " return result[1];\n" +
- " }\n" +
- " }\n"
- );
-}
-
-/*
- * This is used to create tear-offs of Java methods. Each function corresponds
- * to exactly one dispId, and also embeds the argument count. We get the "this"
- * value from the context in which the function is being executed.
- * Function-object identity is preserved by caching in a sparse array.
- */
-var __gwt_tearOffs = [];
-var __gwt_tearOffGenerators = [];
-function __gwt_makeTearOff(proxy, dispId, argCount) {
- return __gwt_tearOffs[dispId] || __gwt_doMakeTearOff(dispId, argCount);
-}
-
-function __gwt_doMakeTearOff(dispId, argCount) {
- return __gwt_tearOffs[dispId] =
- (__gwt_tearOffGenerators[argCount] || __gwt_doMakeTearOffGenerator(argCount))(dispId);
-}
-
-function __gwt_doMakeTearOffGenerator(argCount) {
- // IE6 won't eval() anonymous functions except as r-values
- var argList = "";
- for (var i = 0; i < argCount; i++) {
- argList += ",p" + i;
- }
- var argListNoComma = argList.substring(1);
-
- return eval(
- "__gwt_tearOffGenerators[" + argCount + "] =\n" +
- " function(dispId) {\n" +
- " return function(" + argListNoComma + ") {\n" +
- " var result = __static(dispId, this" + argList + ");\n" +
- " if (result[0]) {\n" +
- " throw result[1];\n" +
- " } else {\n" +
- " return result[1];\n" +
- " }\n" +
- " }\n" +
- " }\n"
- );
-}
-
-function __gwt_makeResult(isException, result) {
- return [isException, result];
-}
-
-function __gwt_disconnected() {
- // Prevent double-invocation.
- window.__gwt_disconnected = new Function();
- // Do it in a timeout so we can be sure we have a clean stack.
- window.setTimeout(__gwt_disconnected_impl, 1);
-}
-
-function __gwt_disconnected_impl() {
- var topWin = window.top;
- var topDoc = topWin.document;
- var outer = topDoc.createElement("div");
- // Do not insert whitespace or outer.firstChild will get a text node.
- outer.innerHTML =
- '<div style="position:absolute;z-index:2147483646;left:0px;top:0px;right:0px;bottom:0px;filter:alpha(opacity=75);opacity:0.75;background-color:#000000;"></div>' +
- '<div style="position:absolute;z-index:2147483647;left:50px;top:50px;width:600px;color:#FFFFFF;font-family:verdana;">' +
- '<div style="font-size:30px;font-weight:bold;">GWT Code Server Disconnected</div>' +
- '<p style="font-size:15px;"> Most likely, you closed GWT development mode. Or you might have lost network connectivity. To fix this, try restarting GWT Development Mode and <a style="color: #FFFFFF; font-weight: bold;" href="javascript:location.reload()">REFRESH</a> this page.</p>' +
- '</div>'
- ;
- topDoc.body.appendChild(outer);
- var glass = outer.firstChild;
- var glassStyle = glass.style;
-
- // Scroll to the top and remove scrollbars.
- topWin.scrollTo(0, 0);
- if (topDoc.compatMode == "BackCompat") {
- topDoc.body.style["overflow"] = "hidden";
- } else {
- topDoc.documentElement.style["overflow"] = "hidden";
- }
-
- // Steal focus.
- glass.focus();
-
- if ((navigator.userAgent.indexOf("MSIE") >= 0) && (topDoc.compatMode == "BackCompat")) {
- // IE quirks mode doesn't support right/bottom, but does support this.
- glassStyle.width = "125%";
- glassStyle.height = "100%";
- } else if (navigator.userAgent.indexOf("MSIE 6") >= 0) {
- // IE6 doesn't have a real standards mode, so we have to use hacks.
- glassStyle.width = "125%"; // Get past scroll bar area.
- // Nasty CSS; onresize would be better but the outer window won't let us add a listener IE.
- glassStyle.setExpression("height", "document.documentElement.clientHeight");
- }
-}
-
-function findPluginObject() {
- try {
- return document.getElementById('pluginObject');
- } catch (e) {
- return null;
- }
-}
-
-function findPluginEmbed() {
- try {
- return document.getElementById('pluginEmbed')
- } catch (e) {
- return null;
- }
-}
-
-function findPluginXPCOM() {
- try {
- return __gwt_HostedModePlugin;
- } catch (e) {
- return null;
- }
-}
-
-gwtOnLoad = function(errFn, modName, modBase){
- $moduleName = modName;
- $moduleBase = modBase;
-
- // Note that the order is important
- var pluginFinders = [
- findPluginXPCOM,
- findPluginObject,
- findPluginEmbed,
- ];
- var topWin = window.top;
- var url = topWin.location.href;
- if (!topWin.__gwt_SessionID) {
- var ASCII_EXCLAMATION = 33;
- var ASCII_TILDE = 126;
- var chars = [];
- for (var i = 0; i < 16; ++i) {
- chars.push(Math.floor(ASCII_EXCLAMATION
- + Math.random() * (ASCII_TILDE - ASCII_EXCLAMATION + 1)));
- }
- topWin.__gwt_SessionID = String.fromCharCode.apply(null, chars);
- }
- var plugin = null;
- for (var i = 0; i < pluginFinders.length; ++i) {
- try {
- var maybePlugin = pluginFinders[i]();
- if (maybePlugin != null && maybePlugin.init(window)) {
- plugin = maybePlugin;
- break;
- }
- } catch (e) {
- }
- }
- if (!plugin) {
- // try searching for a v1 plugin for backwards compatibility
- var found = false;
- for (var i = 0; i < pluginFinders.length; ++i) {
- try {
- plugin = pluginFinders[i]();
- if (plugin != null && plugin.connect($hosted, $moduleName, window)) {
- return;
- }
- } catch (e) {
- }
- }
- loadIframe("http://gwt.google.com/missing-plugin");
- } else {
- if (plugin.connect(url, topWin.__gwt_SessionID, $hosted, $moduleName,
- $hostedHtmlVersion)) {
- window.onUnload = function() {
- try {
- // wrap in try/catch since plugins are not required to supply this
- plugin.disconnect();
- } catch (e) {
- }
- };
- } else {
- if (errFn) {
- errFn(modName);
- } else {
- alert("Plugin failed to connect to hosted mode server at " + $hosted);
- loadIframe("http://code.google.com/p/google-web-toolkit/wiki/TroubleshootingOOPHM");
- }
- }
- }
-}
-
-window.onunload = function() {
-};
-
-// Lightweight metrics
-window.fireOnModuleLoadStart = function(className) {
- $stats && $stats({moduleName:$moduleName, sessionId:$sessionId, subSystem:'startup', evtGroup:'moduleStartup', millis:(new Date()).getTime(), type:'onModuleLoadStart', className:className});
-};
-
-window.__gwt_module_id = 0;
-</script></head>
-<body>
-<font face='arial' size='-1'>This html file is for hosted mode support.</font>
-<script><!--
-// Lightweight metrics
-$stats && $stats({moduleName:$moduleName, sessionId:$sessionId, subSystem:'startup', evtGroup:'moduleStartup', millis:(new Date()).getTime(), type:'moduleEvalEnd'});
-
-// OOPHM currently only supports IFrameLinker
-var query = parent.location.search;
-if (!findPluginXPCOM()) {
- document.write('<embed id="pluginEmbed" type="application/x-gwt-hosted-mode" width="10" height="10">');
- document.write('</embed>');
- document.write('<object id="pluginObject" CLASSID="CLSID:1D6156B6-002B-49E7-B5CA-C138FB843B4E">');
- document.write('</object>');
-}
-
-// look for the old query parameter if we don't find the new one
-var idx = query.indexOf("gwt.codesvr=");
-if (idx >= 0) {
- idx += 12; // "gwt.codesvr=".length() == 12
-} else {
- idx = query.indexOf("gwt.hosted=");
- if (idx >= 0) {
- idx += 11; // "gwt.hosted=".length() == 11
- }
-}
-if (idx >= 0) {
- var amp = query.indexOf("&", idx);
- if (amp >= 0) {
- $hosted = query.substring(idx, amp);
- } else {
- $hosted = query.substring(idx);
- }
-
- // According to RFC 3986, some of this component's characters (e.g., ':')
- // are reserved and *may* be escaped.
- $hosted = decodeURIComponent($hosted);
-}
-
-query = window.location.search.substring(1);
-if (query && $wnd[query]) setTimeout($wnd[query].onScriptLoad, 1);
---></script></body></html>
13 years, 9 months
[rhq] 2 commits - modules/core
by Joseph Marques
modules/core/dbutils/src/main/scripts/dbsetup/search-data.xml | 4 ++--
modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml | 4 +---
2 files changed, 3 insertions(+), 5 deletions(-)
New commits:
commit 6278e7056403b2dcd0ffde84a7109e60790022eb
Author: Joseph Marques <joseph(a)redhat.com>
Date: Fri Feb 26 16:55:32 2010 -0500
simplify dbupgrade by merge saved search-related entries into a single schemaSpec
diff --git a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
index 6fe555e..b2b3b11 100644
--- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
+++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
@@ -3231,9 +3231,7 @@
<schema-alterColumn table="RHQ_SAVED_SEARCH" column="SUBJECT_ID" nullable="FALSE" />
<schema-addColumn table="RHQ_SAVED_SEARCH" column="GLOBAL" columnType="BOOLEAN" />
<schema-alterColumn table="RHQ_SAVED_SEARCH" column="GLOBAL" nullable="FALSE" />
- </schemaSpec>
-
- <schemaSpec version="2.82.1">
+
<schema-directSQL>
<statement targetDBVendor="postgresql" desc="Inserting global default saved search 'Downed Platforms'">
INSERT INTO rhq_saved_search (id, context, name, description, pattern, last_compute_time, subject_id, global)
commit a6efa283222790b6e22f82861b1c145e34af9391
Author: Joseph Marques <joseph(a)redhat.com>
Date: Fri Feb 26 16:54:58 2010 -0500
insert some default global searches into the system during dbsetup
diff --git a/modules/core/dbutils/src/main/scripts/dbsetup/search-data.xml b/modules/core/dbutils/src/main/scripts/dbsetup/search-data.xml
index 1a11114..da98622 100644
--- a/modules/core/dbutils/src/main/scripts/dbsetup/search-data.xml
+++ b/modules/core/dbutils/src/main/scripts/dbsetup/search-data.xml
@@ -10,7 +10,7 @@
DESCRIPTION="All downed machines across the entire enterprise"
PATTERN="down platform"
LAST_COMPUTE_TIME="0"
- SUBJECT="1"
+ SUBJECT_ID="1"
GLOBAL="TRUE" />
<data ID="2"
CONTEXT="Resource"
@@ -18,7 +18,7 @@
DESCRIPTION="All downed servers across the entire enterprise"
PATTERN="down server"
LAST_COMPUTE_TIME="0"
- SUBJECT="1"
+ SUBJECT_ID="1"
GLOBAL="TRUE" />
</table>
13 years, 9 months
[rhq] Branch 'search' - 2 commits - modules/core
by Joseph Marques
modules/core/dbutils/src/main/scripts/dbsetup/search-data.xml | 4 ++--
modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml | 4 +---
2 files changed, 3 insertions(+), 5 deletions(-)
New commits:
commit 6278e7056403b2dcd0ffde84a7109e60790022eb
Author: Joseph Marques <joseph(a)redhat.com>
Date: Fri Feb 26 16:55:32 2010 -0500
simplify dbupgrade by merge saved search-related entries into a single schemaSpec
diff --git a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
index 6fe555e..b2b3b11 100644
--- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
+++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
@@ -3231,9 +3231,7 @@
<schema-alterColumn table="RHQ_SAVED_SEARCH" column="SUBJECT_ID" nullable="FALSE" />
<schema-addColumn table="RHQ_SAVED_SEARCH" column="GLOBAL" columnType="BOOLEAN" />
<schema-alterColumn table="RHQ_SAVED_SEARCH" column="GLOBAL" nullable="FALSE" />
- </schemaSpec>
-
- <schemaSpec version="2.82.1">
+
<schema-directSQL>
<statement targetDBVendor="postgresql" desc="Inserting global default saved search 'Downed Platforms'">
INSERT INTO rhq_saved_search (id, context, name, description, pattern, last_compute_time, subject_id, global)
commit a6efa283222790b6e22f82861b1c145e34af9391
Author: Joseph Marques <joseph(a)redhat.com>
Date: Fri Feb 26 16:54:58 2010 -0500
insert some default global searches into the system during dbsetup
diff --git a/modules/core/dbutils/src/main/scripts/dbsetup/search-data.xml b/modules/core/dbutils/src/main/scripts/dbsetup/search-data.xml
index 1a11114..da98622 100644
--- a/modules/core/dbutils/src/main/scripts/dbsetup/search-data.xml
+++ b/modules/core/dbutils/src/main/scripts/dbsetup/search-data.xml
@@ -10,7 +10,7 @@
DESCRIPTION="All downed machines across the entire enterprise"
PATTERN="down platform"
LAST_COMPUTE_TIME="0"
- SUBJECT="1"
+ SUBJECT_ID="1"
GLOBAL="TRUE" />
<data ID="2"
CONTEXT="Resource"
@@ -18,7 +18,7 @@
DESCRIPTION="All downed servers across the entire enterprise"
PATTERN="down server"
LAST_COMPUTE_TIME="0"
- SUBJECT="1"
+ SUBJECT_ID="1"
GLOBAL="TRUE" />
</table>
13 years, 9 months
[rhq] modules/core
by Joseph Marques
modules/core/dbutils/src/main/scripts/dbsetup/search-schema.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
New commits:
commit 1d02547312924f4904730bb0aebe7d0d8d9b70d2
Author: Joseph Marques <joseph(a)redhat.com>
Date: Fri Feb 26 16:21:37 2010 -0500
fix typo for column name in saved search table
diff --git a/modules/core/dbutils/src/main/scripts/dbsetup/search-schema.xml b/modules/core/dbutils/src/main/scripts/dbsetup/search-schema.xml
index 7c0de23..14634b6 100644
--- a/modules/core/dbutils/src/main/scripts/dbsetup/search-schema.xml
+++ b/modules/core/dbutils/src/main/scripts/dbsetup/search-schema.xml
@@ -17,7 +17,7 @@
<column name="RESULT_COUNT" type="LONG" required="false"/>
<column name="SUBJECT_ID" type="INTEGER" references="RHQ_SUBJECT" required="true"/>
- <column name="ENABLED" type="BOOLEAN" required="true"/>
+ <column name="GLOBAL" type="BOOLEAN" required="true"/>
</table>
</dbsetup>
\ No newline at end of file
13 years, 9 months
[rhq] Branch 'search' - modules/core
by Joseph Marques
modules/core/dbutils/src/main/scripts/dbsetup/search-schema.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
New commits:
commit 1d02547312924f4904730bb0aebe7d0d8d9b70d2
Author: Joseph Marques <joseph(a)redhat.com>
Date: Fri Feb 26 16:21:37 2010 -0500
fix typo for column name in saved search table
diff --git a/modules/core/dbutils/src/main/scripts/dbsetup/search-schema.xml b/modules/core/dbutils/src/main/scripts/dbsetup/search-schema.xml
index 7c0de23..14634b6 100644
--- a/modules/core/dbutils/src/main/scripts/dbsetup/search-schema.xml
+++ b/modules/core/dbutils/src/main/scripts/dbsetup/search-schema.xml
@@ -17,7 +17,7 @@
<column name="RESULT_COUNT" type="LONG" required="false"/>
<column name="SUBJECT_ID" type="INTEGER" references="RHQ_SUBJECT" required="true"/>
- <column name="ENABLED" type="BOOLEAN" required="true"/>
+ <column name="GLOBAL" type="BOOLEAN" required="true"/>
</table>
</dbsetup>
\ No newline at end of file
13 years, 9 months
[rhq] modules/core
by Joseph Marques
modules/core/dbutils/src/main/scripts/dbsetup-build.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
New commits:
commit 92adfd37e105c60efc0f1981d7fc2258ee423ad5
Author: Joseph Marques <joseph(a)redhat.com>
Date: Fri Feb 26 16:05:08 2010 -0500
change order of dbsetup so that saved search table gets created after the rhq_subject table
diff --git a/modules/core/dbutils/src/main/scripts/dbsetup-build.xml b/modules/core/dbutils/src/main/scripts/dbsetup-build.xml
index f5e4eae..d5be746 100644
--- a/modules/core/dbutils/src/main/scripts/dbsetup-build.xml
+++ b/modules/core/dbutils/src/main/scripts/dbsetup-build.xml
@@ -39,7 +39,7 @@ To run the default target, you must set one of the following properties to true:
<property name="dbsetup.scripts.dir" value="${basedir}/src/main/scripts/dbsetup" />
<property name="dbsetup.output.dir" value="${basedir}/target/dbsetup" /> <!-- away from classes so it doesn't go into the jar -->
<!-- define the setup creation processing order. note, removals are done in the reverse order -->
- <property name="dbsetup.subsystems" value="search,config,cluster,inventory,auth,authz,operation,event,alert,sysconfig,scheduler,amps,measurement,content,resource-request,jms,obsolete"/>
+ <property name="dbsetup.subsystems" value="config,cluster,inventory,auth,authz,search,operation,event,alert,sysconfig,scheduler,amps,measurement,content,resource-request,jms,obsolete"/>
<property name="dbsetup.combined.schema" value="${dbsetup.output.dir}/all-schema.xml" />
<property name="dbsetup.combined.data" value="${dbsetup.output.dir}/all-data.xml" />
<property name="dbsetup.tstamp.file" value="${dbsetup.output.dir}/dbsetup-combine.tstamp" />
13 years, 9 months
[rhq] Branch 'search' - modules/core
by Joseph Marques
modules/core/dbutils/src/main/scripts/dbsetup-build.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
New commits:
commit 92adfd37e105c60efc0f1981d7fc2258ee423ad5
Author: Joseph Marques <joseph(a)redhat.com>
Date: Fri Feb 26 16:05:08 2010 -0500
change order of dbsetup so that saved search table gets created after the rhq_subject table
diff --git a/modules/core/dbutils/src/main/scripts/dbsetup-build.xml b/modules/core/dbutils/src/main/scripts/dbsetup-build.xml
index f5e4eae..d5be746 100644
--- a/modules/core/dbutils/src/main/scripts/dbsetup-build.xml
+++ b/modules/core/dbutils/src/main/scripts/dbsetup-build.xml
@@ -39,7 +39,7 @@ To run the default target, you must set one of the following properties to true:
<property name="dbsetup.scripts.dir" value="${basedir}/src/main/scripts/dbsetup" />
<property name="dbsetup.output.dir" value="${basedir}/target/dbsetup" /> <!-- away from classes so it doesn't go into the jar -->
<!-- define the setup creation processing order. note, removals are done in the reverse order -->
- <property name="dbsetup.subsystems" value="search,config,cluster,inventory,auth,authz,operation,event,alert,sysconfig,scheduler,amps,measurement,content,resource-request,jms,obsolete"/>
+ <property name="dbsetup.subsystems" value="config,cluster,inventory,auth,authz,search,operation,event,alert,sysconfig,scheduler,amps,measurement,content,resource-request,jms,obsolete"/>
<property name="dbsetup.combined.schema" value="${dbsetup.output.dir}/all-schema.xml" />
<property name="dbsetup.combined.data" value="${dbsetup.output.dir}/all-data.xml" />
<property name="dbsetup.tstamp.file" value="${dbsetup.output.dir}/dbsetup-combine.tstamp" />
13 years, 9 months
[rhq] 25 commits - .classpath modules/core modules/enterprise
by Joseph Marques
.classpath | 1
modules/core/dbutils/pom.xml | 2
modules/core/dbutils/src/main/scripts/dbsetup-build.xml | 2
modules/core/dbutils/src/main/scripts/dbsetup/search-data.xml | 25
modules/core/dbutils/src/main/scripts/dbsetup/search-schema.xml | 23
modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml | 53 ++
modules/core/domain/src/main/java/org/rhq/core/domain/criteria/SavedSearchCriteria.java | 142 +++++
modules/core/domain/src/main/java/org/rhq/core/domain/search/SavedSearch.java | 253 ++++++++++
modules/core/domain/src/main/java/org/rhq/core/domain/search/SearchContext.java | 38 +
modules/enterprise/remoting/client-api/src/main/java/org/rhq/enterprise/client/RemoteClient.java | 2
modules/enterprise/server/jar/pom.xml | 47 +
modules/enterprise/server/jar/src/main/antlr3/org/rhq/enterprise/server/search/RHQL.g | 181 +++++++
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerBean.java | 120 ++++
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerLocal.java | 31 +
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerRemote.java | 119 ++++
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryGenerator.java | 17
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/LookupUtil.java | 6
modules/enterprise/server/jar/src/main/resources/single-line-rhql.txt | 126 ++++
modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/search/RHQLTest.java | 171 ++++++
19 files changed, 1353 insertions(+), 6 deletions(-)
New commits:
commit d0ef49e101ef7887e834b0a9021c0c0654a7f5d5
Merge: 613b993... 8a0951a...
Author: Joseph Marques <joseph(a)redhat.com>
Date: Fri Feb 26 15:34:50 2010 -0500
Merge branch 'master' into search
commit 613b993b85ac47117fda5d7f7810318e891cdf0e
Author: Joseph Marques <joseph(a)redhat.com>
Date: Fri Feb 26 15:32:41 2010 -0500
construct AST from parse tree for RHQL grammar
diff --git a/modules/enterprise/server/jar/src/main/antlr3/org/rhq/enterprise/server/search/RHQL.g b/modules/enterprise/server/jar/src/main/antlr3/org/rhq/enterprise/server/search/RHQL.g
index 00a0dab..ded91a1 100644
--- a/modules/enterprise/server/jar/src/main/antlr3/org/rhq/enterprise/server/search/RHQL.g
+++ b/modules/enterprise/server/jar/src/main/antlr3/org/rhq/enterprise/server/search/RHQL.g
@@ -27,11 +27,43 @@
* @author Joseph Marques
*/
grammar RHQL;
-
options {
language=Java;
backtrack=true;
memoize=true;
+ output=AST;
+ ASTLabelType=CommonTree;
+}
+
+/*
+ * Imaginary nodes serve to fully abstract the parse tree from the AST. This
+ * allows us, for example, to support the conjunctive ('and') operator between
+ * conditional expressions, but gives us the flexibility to modify the lexical
+ * element that represents that operation. In the future, we might want to
+ * support '&&' instead of 'and', or even support them both. The inclusion of
+ * imaginary tokens creates a more stable AST that downstream grammars can use
+ * without fear that every change to the syntax will break their tree parser.
+ */
+tokens {
+ OR;
+ AND;
+
+ CONTEXT;
+ LINEAGE;
+ PATH;
+ PARAM;
+ IDENT;
+ VALUE;
+
+ OP_EQUALS;
+ OP_EQUALS_STRICT;
+ OP_NULL;
+ OP_IN;
+
+ OP_NOT_EQUALS;
+ OP_NOT_EQUALS_STRICT;
+ OP_NOT_NULL;
+ OP_NOT_IN;
}
@header {
@@ -41,26 +73,29 @@ options {
package org.rhq.enterprise.server.search;
}
+
/*
* parser rules
*/
searchExpression
- : conditionalExpression
+ : conditionalExpression { System.out.println($conditionalExpression.tree.toStringTree()); }
;
conditionalExpression
- : conditionalFactor ( 'or' conditionalFactor )*
- ;
+ : conds+=conditionalFactor ( WS* ( 'or' ) WS* conds+=conditionalFactor )* -> { $conds.size() == 1 }? ^($conds)
+ -> ^(OR conditionalFactor+)
+ ; // use rewrite predicates to eliminate superfluous 'or' node if only one child
conditionalFactor
- : conditionalPrimary ( ( 'and' )? conditionalPrimary )*
- ;
+ : conds+=conditionalPrimary ( WS* ( 'and' WS* )? conds+=conditionalPrimary )* -> { $conds.size() == 1 }? ^($conds)
+ -> ^(AND conditionalPrimary+)
+ ; // use rewrite predicates to eliminate superfluous 'and' node if only one child
conditionalPrimary
- : simpleConditionalExpression
- | '(' conditionalExpression ')'
- ;
+ : WS* simpleConditionalExpression WS* -> simpleConditionalExpression
+ | '(' WS* conditionalExpression WS* ')' -> conditionalExpression
+ ; // avoid building nodes for parens, tree structure implies existence appropriately -- ignore captured WS
simpleConditionalExpression
: comparisonConditionalExpression
@@ -69,69 +104,78 @@ simpleConditionalExpression
;
comparisonConditionalExpression
- : context comparisonOperator identifier
- ;
+ : c=context WS* op=comparisonOperator WS* ident=identifier -> ^($op $c ^(VALUE $ident))
+ ; // rewrite tree output so operator is always the root -- ignore captured WS
nullComparisonConditionalExpression
- : context nullOperator
- ;
+ : c=context WS* op=nullOperator -> ^($op $c)
+ ; // rewrite tree output so operator is always the root -- ignore captured WS
inExpression
- : context inOperator '[' '='? identifier ( ',' '='? identifier )* ']'
- ;
+ : c=context WS* op=inOperator WS* '[' WS* ids+=identifier WS* ( ',' WS* ids+=identifier WS* )* ']'
+ -> ^($op $c ^(VALUE $ids+))
+ ; // rewrite tree output so operator is always the root -- ignore captured WS
context
- : ( lineage '.' )? path ( '[' identifier ']' )?
+ : ( l=lineage '.' )? p=path ( '[' ident=identifier ']' )? -> ^(CONTEXT ^(LINEAGE $l)? ^(PATH $p) ^(PARAM $ident)?)
;
lineage
- : path ( '(' INT ')' )?
- ;
+ : path ( '('! LEVEL ')'! )?
+ ; // avoid building nodes for brackets, tree structure implies existence appropriately
path
: ID+
;
identifier
- : quotedValue
- | value
+ : doubleQuotedValue -> ^(IDENT doubleQuotedValue)
+ | quotedValue -> ^(IDENT quotedValue)
+ | openEndedvalue -> ^(IDENT openEndedvalue)
;
+doubleQuotedValue
+ : '"'! ~('"')* '"'!
+ ; // avoid building nodes for the double-quote characters
+
+
quotedValue
- : '\'' ~('\'')* '\''
- ;
+ : '\''! ~('\'')* '\''!
+ ; // avoid building nodes for the sinngle-quote characters
-value
- : ~('\'') ~(']'|','|')')*
- ;
+openEndedvalue
+ : ~(']' | ',' | ')' | '(' | 'or' | 'and' | WS )*
+ ; // consume until we find a char to terminate the current phrase ']' ',' ')' or begin the next '(' 'or' 'and'
comparisonOperator
- : '='
- | '=='
- | '!='
- | '!=='
- ;
+ : '=' -> ^(OP_EQUALS)
+ | '==' -> ^(OP_EQUALS_STRICT)
+ | '!=' -> ^(OP_NOT_EQUALS)
+ | '!==' -> ^(OP_NOT_EQUALS_STRICT)
+ ; // use imaginary nodes for all operators, which further removes the AST from the real lexical elements
nullOperator
- : 'is' 'not'? 'null'
- ;
+ : 'is' WS+ (negation='not' WS+)? 'null' -> { $negation == null }? ^(OP_NULL)
+ -> ^(OP_NOT_NULL)
+ ; // use imaginary nodes for all operators, which further removes the AST from the real lexical elements
inOperator
- : 'not'? 'in'
- ;
+ : (negation+='not' WS+)? 'in' -> { $negation == null }? ^(OP_IN)
+ -> ^(OP_NOT_IN)
+ ; // use imaginary nodes for all operators, which further removes the AST from the real lexical elements
/*
* lexical elements
- */
+ */
ID
: 'a'..'z'
;
-INT
- : '0'..'9'
+LEVEL
+ : '0'..'5'
;
WS
- : ( ' ' | '\n' | '\r' )+ { $channel = HIDDEN; }
+ : ( ' ' | '\n' | '\r' )+
;
\ No newline at end of file
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/search/RHQLTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/search/RHQLTest.java
index 637e339..ceab3e3 100644
--- a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/search/RHQLTest.java
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/search/RHQLTest.java
@@ -62,6 +62,7 @@ public class RHQLTest extends AssertJUnit {
@Override
public TestResult call() throws Exception {
try {
+ System.out.println(line);
ANTLRStringStream input = new ANTLRStringStream(line); // Create an input character stream from standard in
RHQLLexer lexer = new RHQLLexer(input); // Create an echoLexer that feeds from that stream
CommonTokenStream tokens = new CommonTokenStream(lexer); // Create a stream of tokens fed by the lexer
commit eac78662084095c22fb80326643fbf59f0e1a863
Author: Joseph Marques <joseph(a)redhat.com>
Date: Fri Feb 26 15:31:54 2010 -0500
modify RHQL test case file to adhere to simpler syntax for IN-clause:
* remove multi-word non-quoted identifers for the IN-clause
* remove ability to change case-sensitivity comparison for IN-clause
diff --git a/modules/enterprise/server/jar/src/main/resources/single-line-rhql.txt b/modules/enterprise/server/jar/src/main/resources/single-line-rhql.txt
index 2a5a195..f8c241a 100644
--- a/modules/enterprise/server/jar/src/main/resources/single-line-rhql.txt
+++ b/modules/enterprise/server/jar/src/main/resources/single-line-rhql.txt
@@ -7,11 +7,11 @@ context !== value
context is null
context is not null
context in [value]
-context in [value1, =value2]
-context in [=value1, value2, value3]
+context in [value1, value2]
+context in [value1, value2, value3]
context not in [value]
-context not in [value1, =value2]
-context not in [=value1, value2, value3]
+context not in [value1, value2]
+context not in [value1, value2, value3]
# simple term, all operators, quoted value
context = 'quoted value'
@@ -21,19 +21,11 @@ context !== 'quoted value'
context is null
context is not null
context in ['quoted value1']
-context in ['quoted value1', ='quoted value2']
-context in [='quoted value1', 'quoted value2', 'quoted value3']
+context in ['quoted value1', 'quoted value2']
+context in ['quoted value1', 'quoted value2', 'quoted value3']
context not in ['quoted value1']
-context not in ['quoted value1', ='quoted value2']
-context not in [='quoted value1', 'quoted value2', 'quoted value3']
-
-# simple term, 'in' operator, non-quoted but multi-word values
-context in [quoted value1]
-context in [quoted value1, =quoted value2]
-context in [=quoted value1, quoted value2, quoted value3]
-context not in [quoted value1]
-context not in [quoted value1, =quoted value2]
-context not in [=quoted value1, quoted value2, quoted value3]
+context not in ['quoted value1', 'quoted value2']
+context not in ['quoted value1', 'quoted value2', 'quoted value3']
# parameterized term, all operators
context[param] = value
@@ -43,11 +35,11 @@ context[param] !== value
context[param] is null
context[param] is not null
context[param] in [value]
-context[param] in [value1, =value2]
-context[param] in [=value1, value2, value3]
+context[param] in [value1, value2]
+context[param] in [value1, value2, value3]
context[param] not in [value]
-context[param] not in [value1, =value2]
-context[param] not in [=value1, value2, value3]
+context[param] not in [value1, value2]
+context[param] not in [value1, value2, value3]
# deeply nested parenthetical simple terms
((context = value))
@@ -63,11 +55,11 @@ context[param] not in [=value1, value2, value3]
(context is null)
(context is not null)
(context in [value])
-(context in [value1, =value2])
-(context in [=value1, value2, value3])
+(context in [value1, value2])
+(context in [value1, value2, value3])
(context not in [value])
-(context not in [value1, =value2])
-(context not in [=value1, value2, value3])
+(context not in [value1, value2])
+(context not in [value1, value2, value3])
# parameterized parenthetical term, all operators
(context[param] = value)
@@ -77,11 +69,11 @@ context[param] not in [=value1, value2, value3]
(context[param] is null)
(context[param] is not null)
(context[param] in [value])
-(context[param] in [value1, =value2])
-(context[param] in [=value1, value2, value3])
+(context[param] in [value1, value2])
+(context[param] in [value1, value2, value3])
(context[param] not in [value])
-(context[param] not in [value1, =value2])
-(context[param] not in [=value1, value2, value3])
+(context[param] not in [value1, value2])
+(context[param] not in [value1, value2, value3])
# single-pair parenthetical combinations
@@ -131,4 +123,4 @@ context = value1 and ((context = value2))
((context = value1)) context = value2
(context = value1) (context = value2)
(context = value1 (context = value2))
-context = value1 ((context1 = value2))
\ No newline at end of file
+context = value1 ((context = value2))
\ No newline at end of file
commit 602b8780654df9298dc36f6e8523e2ebb3e0c906
Author: Joseph Marques <joseph(a)redhat.com>
Date: Thu Feb 25 12:34:39 2010 -0500
add missing @WebMethod annotation to saved search manager remote interface
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerRemote.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerRemote.java
index ffd4255..231167e 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerRemote.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerRemote.java
@@ -112,6 +112,7 @@ public interface SavedSearchManagerRemote {
* @return the {@link PageList} of {@link SavedSearch} entities that match the criteria filters, an empty list
* will be returned if no results were found or none matches the given filters
*/
+ @WebMethod
public PageList<SavedSearch> findSavedSearchesByCriteria( //
@WebParam(name = "subject") Subject subject, //
@WebParam(name = "criteria") SavedSearchCriteria criteria);
commit 07a482e999b87952b9cdbd2573fe6b04c4b8ff8e
Author: Joseph Marques <joseph(a)redhat.com>
Date: Wed Feb 24 22:04:30 2010 -0500
abstract RHQL grammar support:
* initial combined lexer/parser grammar file
* test harness to verify grammar correctness
* 100 acceptance test cases exercising all major parts of generic syntax
diff --git a/modules/enterprise/server/jar/src/main/antlr3/org/rhq/enterprise/server/search/RHQL.g b/modules/enterprise/server/jar/src/main/antlr3/org/rhq/enterprise/server/search/RHQL.g
new file mode 100644
index 0000000..00a0dab
--- /dev/null
+++ b/modules/enterprise/server/jar/src/main/antlr3/org/rhq/enterprise/server/search/RHQL.g
@@ -0,0 +1,137 @@
+/*
+ * 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, 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.
+ */
+
+/*
+ * Antlr v3 grammar file to parse RHQL search expressions.
+ *
+ * @author Joseph Marques
+ */
+grammar RHQL;
+
+options {
+ language=Java;
+ backtrack=true;
+ memoize=true;
+}
+
+@header {
+ package org.rhq.enterprise.server.search;
+}
+@lexer::header {
+ package org.rhq.enterprise.server.search;
+}
+
+/*
+ * parser rules
+ */
+
+searchExpression
+ : conditionalExpression
+ ;
+
+conditionalExpression
+ : conditionalFactor ( 'or' conditionalFactor )*
+ ;
+
+conditionalFactor
+ : conditionalPrimary ( ( 'and' )? conditionalPrimary )*
+ ;
+
+conditionalPrimary
+ : simpleConditionalExpression
+ | '(' conditionalExpression ')'
+ ;
+
+simpleConditionalExpression
+ : comparisonConditionalExpression
+ | nullComparisonConditionalExpression
+ | inExpression
+ ;
+
+comparisonConditionalExpression
+ : context comparisonOperator identifier
+ ;
+
+nullComparisonConditionalExpression
+ : context nullOperator
+ ;
+
+inExpression
+ : context inOperator '[' '='? identifier ( ',' '='? identifier )* ']'
+ ;
+
+context
+ : ( lineage '.' )? path ( '[' identifier ']' )?
+ ;
+
+lineage
+ : path ( '(' INT ')' )?
+ ;
+
+path
+ : ID+
+ ;
+
+identifier
+ : quotedValue
+ | value
+ ;
+
+quotedValue
+ : '\'' ~('\'')* '\''
+ ;
+
+value
+ : ~('\'') ~(']'|','|')')*
+ ;
+
+comparisonOperator
+ : '='
+ | '=='
+ | '!='
+ | '!=='
+ ;
+
+nullOperator
+ : 'is' 'not'? 'null'
+ ;
+
+inOperator
+ : 'not'? 'in'
+ ;
+
+/*
+ * lexical elements
+ */
+
+ID
+ : 'a'..'z'
+ ;
+
+INT
+ : '0'..'9'
+ ;
+
+WS
+ : ( ' ' | '\n' | '\r' )+ { $channel = HIDDEN; }
+ ;
\ No newline at end of file
diff --git a/modules/enterprise/server/jar/src/main/resources/single-line-rhql.txt b/modules/enterprise/server/jar/src/main/resources/single-line-rhql.txt
new file mode 100644
index 0000000..2a5a195
--- /dev/null
+++ b/modules/enterprise/server/jar/src/main/resources/single-line-rhql.txt
@@ -0,0 +1,134 @@
+
+# simple term, all operators
+context = value
+context == value
+context != value
+context !== value
+context is null
+context is not null
+context in [value]
+context in [value1, =value2]
+context in [=value1, value2, value3]
+context not in [value]
+context not in [value1, =value2]
+context not in [=value1, value2, value3]
+
+# simple term, all operators, quoted value
+context = 'quoted value'
+context == 'quoted value'
+context != 'quoted value'
+context !== 'quoted value'
+context is null
+context is not null
+context in ['quoted value1']
+context in ['quoted value1', ='quoted value2']
+context in [='quoted value1', 'quoted value2', 'quoted value3']
+context not in ['quoted value1']
+context not in ['quoted value1', ='quoted value2']
+context not in [='quoted value1', 'quoted value2', 'quoted value3']
+
+# simple term, 'in' operator, non-quoted but multi-word values
+context in [quoted value1]
+context in [quoted value1, =quoted value2]
+context in [=quoted value1, quoted value2, quoted value3]
+context not in [quoted value1]
+context not in [quoted value1, =quoted value2]
+context not in [=quoted value1, quoted value2, quoted value3]
+
+# parameterized term, all operators
+context[param] = value
+context[param] == value
+context[param] != value
+context[param] !== value
+context[param] is null
+context[param] is not null
+context[param] in [value]
+context[param] in [value1, =value2]
+context[param] in [=value1, value2, value3]
+context[param] not in [value]
+context[param] not in [value1, =value2]
+context[param] not in [=value1, value2, value3]
+
+# deeply nested parenthetical simple terms
+((context = value))
+(((context = value)))
+((((context = value))))
+(((((context = value)))))
+
+# simple parenthetical term, all operators
+(context = value)
+(context == value)
+(context != value)
+(context !== value)
+(context is null)
+(context is not null)
+(context in [value])
+(context in [value1, =value2])
+(context in [=value1, value2, value3])
+(context not in [value])
+(context not in [value1, =value2])
+(context not in [=value1, value2, value3])
+
+# parameterized parenthetical term, all operators
+(context[param] = value)
+(context[param] == value)
+(context[param] != value)
+(context[param] !== value)
+(context[param] is null)
+(context[param] is not null)
+(context[param] in [value])
+(context[param] in [value1, =value2])
+(context[param] in [=value1, value2, value3])
+(context[param] not in [value])
+(context[param] not in [value1, =value2])
+(context[param] not in [=value1, value2, value3])
+
+
+# single-pair parenthetical combinations
+# simple expression, 'or' boolean operator
+context = value1 or context = value2
+(context = value1) or context = value2
+context = value1 or (context = value2)
+(context = value1) or (context = value2)
+
+# single-pair parenthetical combinations
+# simple expression, 'and' boolean operator
+context = value and context = value
+(context = value) and context = value
+context = value and (context = value)
+(context = value) and (context = value)
+
+# single-pair parenthetical combinations
+# simple expression, no boolean operator (implies 'and' semantics)
+context = value context = value
+(context = value) context = value
+context = value (context = value)
+(context = value) (context = value)
+
+
+# double-pair parenthetical combinations
+# simple expression, 'or' boolean operator
+((context = value1 or context = value2))
+((context = value1) or context = value2)
+((context = value1)) or context = value2
+(context = value1) or (context = value2)
+(context = value1 or (context = value2))
+context = value1 or ((context = value2))
+
+# double-pair parenthetical combinations
+# simple expression, 'and' boolean operator
+((context = value1 and context = value2))
+((context = value1) and context = value2)
+((context = value1)) and context = value2
+(context = value1) and (context = value2)
+(context = value1 and (context = value2))
+context = value1 and ((context = value2))
+
+# double-pair parenthetical combinations
+# simple expression, no boolean operator (implies 'and' semantics)
+((context = value1 context = value2))
+((context = value1) context = value2)
+((context = value1)) context = value2
+(context = value1) (context = value2)
+(context = value1 (context = value2))
+context = value1 ((context1 = value2))
\ No newline at end of file
diff --git a/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/search/RHQLTest.java b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/search/RHQLTest.java
new file mode 100644
index 0000000..637e339
--- /dev/null
+++ b/modules/enterprise/server/jar/src/test/java/org/rhq/enterprise/server/search/RHQLTest.java
@@ -0,0 +1,170 @@
+/*
+ * 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, 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.server.search;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import org.antlr.runtime.ANTLRStringStream;
+import org.antlr.runtime.CommonTokenStream;
+import org.testng.AssertJUnit;
+import org.testng.annotations.AfterSuite;
+import org.testng.annotations.BeforeSuite;
+import org.testng.annotations.Test;
+
+/**
+ * Test harness to verify correctness of RHQL grammar
+ *
+ * @author Joseph Marques
+ */
+public class RHQLTest extends AssertJUnit {
+
+ private enum TestResult {
+ SUCCESS, FAILURE, TIMEOUT, SKIPPED;
+ }
+
+ private class AntlrTask implements Callable<TestResult> {
+ private String line;
+
+ public AntlrTask(String line) {
+ this.line = line;
+ }
+
+ @Override
+ public TestResult call() throws Exception {
+ try {
+ ANTLRStringStream input = new ANTLRStringStream(line); // Create an input character stream from standard in
+ RHQLLexer lexer = new RHQLLexer(input); // Create an echoLexer that feeds from that stream
+ CommonTokenStream tokens = new CommonTokenStream(lexer); // Create a stream of tokens fed by the lexer
+ RHQLParser parser = new RHQLParser(tokens); // Create a parser that feeds off the token stream
+ parser.searchExpression(); // Begin parsing at 'searchExpression' rule
+ return TestResult.SUCCESS;
+ } catch (Throwable t) {
+ return TestResult.FAILURE;
+ }
+ }
+ };
+
+ private ExecutorService executor;
+
+ @BeforeSuite
+ public void init() {
+ executor = Executors.newSingleThreadExecutor();
+ }
+
+ @AfterSuite
+ public void teardown() {
+ executor.shutdownNow();
+ }
+
+ @Test
+ public void testSingleLineRHQL() throws Exception {
+ BufferedReader reader = null;
+ List<String> successes = new java.util.ArrayList<String>();
+ List<String> failures = new java.util.ArrayList<String>();
+ int count = 0;
+ try {
+ InputStream stream = getClass().getClassLoader().getResourceAsStream("single-line-rhql.txt");
+ reader = new BufferedReader(new InputStreamReader(stream));
+ String line = null;
+ long timeout = 2000;
+ while ((line = reader.readLine()) != null) {
+ TestResult result = testSuccess(line, timeout);
+ if (result == TestResult.SKIPPED) {
+ continue;
+ }
+ count++;
+ if (result == TestResult.SUCCESS) {
+ successes.add(line);
+ } else if (result == TestResult.FAILURE) {
+ failures.add(line);
+ } else if (result == TestResult.TIMEOUT) {
+ System.out.println("Parsing took more than " + timeout
+ + "ms, does your grammar have an infinite loop?");
+ }
+ }
+ } catch (Exception e) {
+ System.out.println("Error testing single line RHQL: " + e);
+ throw e;
+ } finally {
+ if (reader != null) {
+ reader.close();
+ }
+ }
+
+ System.out.println();
+ for (String success : successes) {
+ System.out.println("Parse success: " + success);
+ }
+ for (String failure : failures) {
+ System.out.println("Parse failure: " + failure);
+ }
+
+ System.out.println();
+ System.out.printf("RHQL expressions parsed: %1$s, Failures: %2$s", count, failures.size());
+ System.out.println();
+
+ assert failures.size() == 0;
+ }
+
+ private TestResult testSuccess(final String line, long timeout) {
+ if (shouldSkip(line)) {
+ return TestResult.SKIPPED; // skip empty lines used for visual separation in test file
+ }
+
+ AntlrTask task = new AntlrTask(line);
+ Future<TestResult> futureTask = executor.submit(task);
+ TestResult result = null;
+ try {
+ result = futureTask.get(timeout, TimeUnit.MILLISECONDS);
+ } catch (ExecutionException ee) {
+ } catch (TimeoutException te) {
+ futureTask.cancel(true);
+ result = TestResult.TIMEOUT;
+ } catch (InterruptedException ie) {
+ futureTask.cancel(true);
+ }
+
+ return result;
+ }
+
+ private boolean shouldSkip(String line) {
+ line = line.trim();
+ if (line.equals("")) {
+ return true; // ignore empty lines
+ }
+ if (line.startsWith("#")) {
+ return true; // ignore comments
+ }
+ return false;
+ }
+}
commit 7369db803076bc12f02bcc6131b9fe1e5303ae47
Author: Joseph Marques <joseph(a)redhat.com>
Date: Wed Feb 24 01:57:08 2010 -0500
antlr should compile the grammar files before the standard maven compile phase
diff --git a/modules/enterprise/server/jar/pom.xml b/modules/enterprise/server/jar/pom.xml
index b322503..533c0e9 100644
--- a/modules/enterprise/server/jar/pom.xml
+++ b/modules/enterprise/server/jar/pom.xml
@@ -467,10 +467,10 @@
<version>3.2</version>
<executions>
<execution>
- <phase>compile</phase>
- <goals>
- <goal>antlr</goal>
- </goals>
+ <phase>generate-sources</phase>
+ <goals>
+ <goal>antlr</goal>
+ </goals>
<configuration>
<conversionTimeout>30000</conversionTimeout>
<debug>false</debug>
commit d17f4616c524e65decd6af3db65df8a83d18c12e
Author: Joseph Marques <joseph(a)redhat.com>
Date: Tue Feb 23 16:54:20 2010 -0500
add anltr support to server/jar maven module, update eclipse classpath accordingly;
diff --git a/.classpath b/.classpath
index 660d74d..1a35400 100644
--- a/.classpath
+++ b/.classpath
@@ -19,6 +19,7 @@
<classpathentry kind="src" path="modules/plugins/jboss-cache/src/main/java"/>
<classpathentry kind="src" path="modules/plugins/jboss-cache-v3/src/main/java"/>
<classpathentry kind="src" path="etc/samples/perspectives/sample-perspective/app/src/main/java"/>
+ <classpathentry kind="src" path="modules/enterprise/server/jar/target/generated-sources/antlr3"/>
<classpathentry kind="var" path="M2_REPO/org/jboss/integration/jboss-profileservice-spi/5.1.0.SP1/jboss-profileservice-spi-5.1.0.SP1.jar"/>
<classpathentry kind="var" path="M2_REPO/org/jboss/man/jboss-managed/2.1.1.GA/jboss-managed-2.1.1.GA.jar"/>
<classpathentry kind="var" path="M2_REPO/org/jboss/man/jboss-metatype/2.1.1.GA/jboss-metatype-2.1.1.GA.jar"/>
diff --git a/modules/enterprise/server/jar/pom.xml b/modules/enterprise/server/jar/pom.xml
index e109c41..b322503 100644
--- a/modules/enterprise/server/jar/pom.xml
+++ b/modules/enterprise/server/jar/pom.xml
@@ -366,6 +366,13 @@
<artifactId>test-utils</artifactId>
<version>${version}</version>
</dependency>
+
+ <dependency>
+ <groupId>org.antlr</groupId>
+ <artifactId>antlr</artifactId>
+ <version>3.2</version>
+ <scope>compile</scope>
+ </dependency>
</dependencies>
<build>
@@ -454,6 +461,41 @@
</configuration>
</plugin>
+ <plugin>
+ <groupId>org.antlr</groupId>
+ <artifactId>antlr3-maven-plugin</artifactId>
+ <version>3.2</version>
+ <executions>
+ <execution>
+ <phase>compile</phase>
+ <goals>
+ <goal>antlr</goal>
+ </goals>
+ <configuration>
+ <conversionTimeout>30000</conversionTimeout>
+ <debug>false</debug>
+ <dfa>false</dfa>
+ <nfa>false</nfa>
+ <excludes>
+
+ </excludes>
+ <includes>
+
+ </includes>
+ <libDirectory>src/main/antlr3/imports</libDirectory>
+ <messageFormat>antlr</messageFormat>
+ <outputDirectory>target/generated-sources/antlr3</outputDirectory>
+ <printGrammar>false</printGrammar>
+ <profile>false</profile>
+ <report>false</report>
+ <sourceDirectory>src/main/antlr3</sourceDirectory>
+ <trace>false</trace>
+ <verbose>true</verbose>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+
</plugins>
</build>
commit fc1118af81ff953f2c05fb696629d799169b22f1
Author: Joseph Marques <joseph(a)redhat.com>
Date: Tue Feb 23 13:21:29 2010 -0500
fix some whitespace issues
diff --git a/modules/enterprise/server/jar/pom.xml b/modules/enterprise/server/jar/pom.xml
index f14e145..e109c41 100644
--- a/modules/enterprise/server/jar/pom.xml
+++ b/modules/enterprise/server/jar/pom.xml
@@ -414,7 +414,7 @@
Build-Jdk=${java.version}
Build-OS-Name=${os.name}
Build-OS-Version=${os.version}
-</echo>
+ </echo>
</tasks>
</configuration>
<goals>
@@ -593,8 +593,7 @@
<link href="../domain" />
<link href="../plugin-api" />
<link href="http://java.sun.com/j2se/1.5.0/docs/api/" />
- <bottom><![CDATA[Copyright © 2008-2009 <a href="http://rhq-project.org/">Red Hat, Inc.</a>. All Rights Reserved.
-]]></bottom>
+ <bottom><![CDATA[Copyright © 2008-2009 <a href="http://rhq-project.org/">Red Hat, Inc.</a>. All Rights Reserved.]]></bottom>
</javadoc>
</tasks>
</configuration>
commit 1c79730a4d3ce260e2f3d6ce9b8e971da158e1d7
Author: Joseph Marques <joseph(a)redhat.com>
Date: Tue Feb 23 13:10:18 2010 -0500
add some default, global saved searches for the resource context
diff --git a/modules/core/dbutils/src/main/scripts/dbsetup/search-data.xml b/modules/core/dbutils/src/main/scripts/dbsetup/search-data.xml
new file mode 100644
index 0000000..1a11114
--- /dev/null
+++ b/modules/core/dbutils/src/main/scripts/dbsetup/search-data.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<dbsetup name="search-data.xml">
+
+ <!-- overlord-created, global, default saved searches -->
+ <table name="RHQ_SAVED_SEARCH">
+ <data ID="1"
+ CONTEXT="Resource"
+ NAME="Downed Platforms"
+ DESCRIPTION="All downed machines across the entire enterprise"
+ PATTERN="down platform"
+ LAST_COMPUTE_TIME="0"
+ SUBJECT="1"
+ GLOBAL="TRUE" />
+ <data ID="2"
+ CONTEXT="Resource"
+ NAME="Downed Servers"
+ DESCRIPTION="All downed servers across the entire enterprise"
+ PATTERN="down server"
+ LAST_COMPUTE_TIME="0"
+ SUBJECT="1"
+ GLOBAL="TRUE" />
+ </table>
+
+</dbsetup>
diff --git a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
index 834e9ce..6fe555e 100644
--- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
+++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
@@ -3202,13 +3202,18 @@
</statement>
</schema-directSQL>
</schemaSpec>
-
+
<schemaSpec version="2.82">
<schema-directSQL>
<statement desc="Creating table RHQ_SAVED_SEARCH">
CREATE TABLE RHQ_SAVED_SEARCH ( ID INTEGER )
</statement>
</schema-directSQL>
+ <schema-directSQL>
+ <statement desc="Creating primary key for RHQ_AFFINITY_GROUP">
+ ALTER TABLE RHQ_SAVED_SEARCH ADD PRIMARY KEY ( ID )
+ </statement>
+ </schema-directSQL>
<schema-addColumn table="RHQ_SAVED_SEARCH" column="CONTEXT" columnType="VARCHAR2" precision="25" />
<schema-alterColumn table="RHQ_SAVED_SEARCH" column="CONTEXT" nullable="FALSE" />
@@ -3227,6 +3232,29 @@
<schema-addColumn table="RHQ_SAVED_SEARCH" column="GLOBAL" columnType="BOOLEAN" />
<schema-alterColumn table="RHQ_SAVED_SEARCH" column="GLOBAL" nullable="FALSE" />
</schemaSpec>
+
+ <schemaSpec version="2.82.1">
+ <schema-directSQL>
+ <statement targetDBVendor="postgresql" desc="Inserting global default saved search 'Downed Platforms'">
+ INSERT INTO rhq_saved_search (id, context, name, description, pattern, last_compute_time, subject_id, global)
+ VALUES (1, 'Resource', 'Downed Platforms', 'All downed machines across the entire enterprise', 'down platform', 0, 1, true)
+ </statement>
+ <statement targetDBVendor="oracle" desc="Inserting global default saved search 'Downed Platforms'">
+ INSERT INTO rhq_saved_search (id, context, name, description, pattern, last_compute_time, subject_id, global)
+ VALUES (1, 'Resource', 'Downed Platforms', 'All downed machines across the entire enterprise', 'down platform', 0, 1, 1)
+ </statement>
+ </schema-directSQL>
+ <schema-directSQL>
+ <statement targetDBVendor="postgresql" desc="Inserting global default saved search 'Downed Servers'">
+ INSERT INTO rhq_saved_search (id, context, name, description, pattern, last_compute_time, subject_id, global)
+ VALUES (2, 'Resource', 'Downed Servers', 'All downed servers across the entire enterprise', 'down server', 0, 1, true)
+ </statement>
+ <statement targetDBVendor="oracle" desc="Inserting global default saved search 'Downed Servers'">
+ INSERT INTO rhq_saved_search (id, context, name, description, pattern, last_compute_time, subject_id, global)
+ VALUES (2, 'Resource', 'Downed Servers', 'All downed servers across the entire enterprise', 'down server', 0, 1, 1)
+ </statement>
+ </schema-directSQL>
+ </schemaSpec>
</dbupgrade>
</target>
</project>
commit 68f3634b787768dd5ee138a04a5398fdd4cb6404
Author: Joseph Marques <joseph(a)redhat.com>
Date: Tue Feb 23 12:07:56 2010 -0500
fix copy/paste error for saved search entity annotation
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/search/SavedSearch.java b/modules/core/domain/src/main/java/org/rhq/core/domain/search/SavedSearch.java
index 9142772..d6b50e7 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/search/SavedSearch.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/search/SavedSearch.java
@@ -87,7 +87,7 @@ public class SavedSearch {
@Column(name = "SUBJECT_ID", nullable = false)
private Subject subject;
- @Column(name = "RESOURCE_ID", insertable = false, updatable = false)
+ @Column(name = "SUBJECT_ID", insertable = false, updatable = false)
private int subjectId;
@Column(name = "GLOBAL", nullable = false)
commit 2325fa6314a7ebcbf1d932fb42e9f9559e1d079b
Author: Joseph Marques <joseph(a)redhat.com>
Date: Tue Feb 23 03:02:28 2010 -0500
add auto-completion capability for saved search manager to the CLI
diff --git a/modules/enterprise/remoting/client-api/src/main/java/org/rhq/enterprise/client/RemoteClient.java b/modules/enterprise/remoting/client-api/src/main/java/org/rhq/enterprise/client/RemoteClient.java
index acafe6f..a1a5b38 100644
--- a/modules/enterprise/remoting/client-api/src/main/java/org/rhq/enterprise/client/RemoteClient.java
+++ b/modules/enterprise/remoting/client-api/src/main/java/org/rhq/enterprise/client/RemoteClient.java
@@ -54,6 +54,7 @@ import org.rhq.enterprise.server.resource.ResourceFactoryManagerRemote;
import org.rhq.enterprise.server.resource.ResourceManagerRemote;
import org.rhq.enterprise.server.resource.ResourceTypeManagerRemote;
import org.rhq.enterprise.server.resource.group.ResourceGroupManagerRemote;
+import org.rhq.enterprise.server.search.SavedSearchManagerRemote;
import org.rhq.enterprise.server.support.SupportManagerRemote;
import org.rhq.enterprise.server.system.ServerVersion;
import org.rhq.enterprise.server.system.SystemManagerRemote;
@@ -94,6 +95,7 @@ public class RemoteClient {
ResourceGroupManager(ResourceGroupManagerRemote.class), //
ResourceTypeManager(ResourceTypeManagerRemote.class), //
RoleManager(RoleManagerRemote.class), //
+ SavedSearchManager(SavedSearchManagerRemote.class), //
SubjectManager(SubjectManagerRemote.class), //
SupportManager(SupportManagerRemote.class), //
SystemManager(SystemManagerRemote.class) //
commit 9bfad0211e66635e09d02d8959a81db33f6175b7
Author: Joseph Marques <joseph(a)redhat.com>
Date: Tue Feb 23 02:51:14 2010 -0500
add LookupUtil method to retrieve the saved search manager from the UI layer
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/LookupUtil.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/LookupUtil.java
index dc9ae11..c21526a 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/LookupUtil.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/LookupUtil.java
@@ -165,6 +165,8 @@ import org.rhq.enterprise.server.resource.metadata.ResourceMetadataManagerBean;
import org.rhq.enterprise.server.resource.metadata.ResourceMetadataManagerLocal;
import org.rhq.enterprise.server.scheduler.SchedulerBean;
import org.rhq.enterprise.server.scheduler.SchedulerLocal;
+import org.rhq.enterprise.server.search.SavedSearchManagerBean;
+import org.rhq.enterprise.server.search.SavedSearchManagerLocal;
import org.rhq.enterprise.server.subsystem.AlertSubsystemManagerBean;
import org.rhq.enterprise.server.subsystem.AlertSubsystemManagerLocal;
import org.rhq.enterprise.server.subsystem.ConfigurationSubsystemManagerBean;
@@ -516,6 +518,10 @@ public final class LookupUtil {
return lookupLocal(SchedulerBean.class);
}
+ public static SavedSearchManagerLocal getSavedSearchManager() {
+ return lookupLocal(SavedSearchManagerBean.class);
+ }
+
public static SubjectManagerLocal getSubjectManager() {
return lookupLocal(SubjectManagerBean.class);
}
commit 7b68ec1372bd5af42793b5d15020e7b2f66bb931
Author: Joseph Marques <joseph(a)redhat.com>
Date: Tue Feb 23 02:49:08 2010 -0500
add criteria-based retrieval for the saved search manager
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/SavedSearchCriteria.java b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/SavedSearchCriteria.java
new file mode 100644
index 0000000..bd70b6f
--- /dev/null
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/SavedSearchCriteria.java
@@ -0,0 +1,142 @@
+/*
+ * 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, 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.core.domain.criteria;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+
+import org.rhq.core.domain.search.SavedSearch;
+import org.rhq.core.domain.search.SearchContext;
+import org.rhq.core.domain.util.PageOrdering;
+
+/**
+ * @author Joseph Marques
+ */
+(a)XmlAccessorType(XmlAccessType.FIELD)
+@SuppressWarnings("unused")
+public class SavedSearchCriteria extends Criteria {
+ public static final long serialVersionUID = 1L;
+
+ private Integer filterId;
+ private SearchContext filterContext;
+ private String filterName;
+ private String filterDescription;
+ private String filterPattern;
+ private Long filterLastComputeTimeMin;
+ private Long filterLastComputeTimeMax;
+ private Long filterResultCountMin;
+ private Long filterResultCountMax;
+ private Integer filterSubjectId;
+ private Boolean filterGlobal;
+
+ private boolean fetchSubject;
+
+ private PageOrdering sortContext;
+ private PageOrdering sortName;
+ private PageOrdering sortLastComputeTime;
+ private PageOrdering sortResultCount;
+ private PageOrdering sortGlobal;
+
+ public SavedSearchCriteria() {
+ super(SavedSearch.class);
+
+ filterOverrides.put("lastComputeTimeMin", "lastComputeTime >= ?");
+ filterOverrides.put("lastComputeTimeMax", "lastComputeTime <= ?");
+ filterOverrides.put("resultCountMin", "resultCount >= ?");
+ filterOverrides.put("resultCountMax", "resultCount <= ?");
+ }
+
+ public void addFilterId(Integer filterId) {
+ this.filterId = filterId;
+ }
+
+ public void addFilterSearchContext(SearchContext filterContext) {
+ this.filterContext = filterContext;
+ }
+
+ public void addFilterName(String filterName) {
+ this.filterName = filterName;
+ }
+
+ public void addFilterDescription(String filterDescription) {
+ this.filterDescription = filterDescription;
+ }
+
+ public void addFilterPattern(String filterPattern) {
+ this.filterPattern = filterPattern;
+ }
+
+ public void addFilterResultCountMin(Long filterResultCountMin) {
+ this.filterResultCountMin = filterResultCountMin;
+ }
+
+ public void addFilterResultCountMax(Long filterResultCountMax) {
+ this.filterResultCountMax = filterResultCountMax;
+ }
+
+ public void addFilterLastComputeTimeMin(Long filterLastComputeTimeMin) {
+ this.filterLastComputeTimeMin = filterLastComputeTimeMin;
+ }
+
+ public void addFilterLastComputeTimeMax(Long filterLastComputeTimeMax) {
+ this.filterLastComputeTimeMax = filterLastComputeTimeMax;
+ }
+
+ public void addFilterSubjectId(Integer filterSubjectId) {
+ this.filterSubjectId = filterSubjectId;
+ }
+
+ public void addFilterGlobal(Boolean filterGlobal) {
+ this.filterGlobal = filterGlobal;
+ }
+
+ public void setFetchSubject(boolean fetchSubject) {
+ this.fetchSubject = fetchSubject;
+ }
+
+ public void addSortContext(PageOrdering sortContext) {
+ addSortField("context");
+ this.sortContext = sortContext;
+ }
+
+ public void addSortName(PageOrdering sortName) {
+ addSortField("name");
+ this.sortName = sortName;
+ }
+
+ public void addSortLastComputeTime(PageOrdering sortLastComputeTime) {
+ addSortField("lastComputeTime");
+ this.sortLastComputeTime = sortLastComputeTime;
+ }
+
+ public void addSortResultCount(PageOrdering sortResultCount) {
+ addSortField("resultCount");
+ this.sortResultCount = sortResultCount;
+ }
+
+ public void addSortGlobal(PageOrdering sortGlobal) {
+ addSortField("global");
+ this.sortGlobal = sortGlobal;
+ }
+
+}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerBean.java
index f672ac7..1485197 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerBean.java
@@ -24,10 +24,14 @@ import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.criteria.SavedSearchCriteria;
import org.rhq.core.domain.search.SavedSearch;
+import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.server.RHQConstants;
import org.rhq.enterprise.server.authz.AuthorizationManagerLocal;
import org.rhq.enterprise.server.authz.PermissionException;
+import org.rhq.enterprise.server.util.CriteriaQueryGenerator;
+import org.rhq.enterprise.server.util.CriteriaQueryRunner;
/**
* This bean provides functionality to CRUD saved search patterns.
@@ -79,6 +83,18 @@ public class SavedSearchManagerBean implements SavedSearchManagerLocal /* local
return savedSearch;
}
+ public PageList<SavedSearch> findSavedSearchesByCriteria(Subject subject, SavedSearchCriteria criteria) {
+ CriteriaQueryGenerator generator = new CriteriaQueryGenerator(criteria);
+
+ if (!authorizationManager.isInventoryManager(subject)) {
+ generator.setAuthorizationCustomConditionFragment("(subject.id=" + subject.getId() + " OR global=true)");
+ }
+
+ CriteriaQueryRunner<SavedSearch> queryRunner = new CriteriaQueryRunner<SavedSearch>(criteria, generator,
+ entityManager);
+ return queryRunner.execute();
+ }
+
private void validateManipulatePermission(Subject subject, SavedSearch savedSearch) {
if (savedSearch.isGlobal()) {
if (!authorizationManager.isInventoryManager(subject)) {
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerRemote.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerRemote.java
index a1615ec..ffd4255 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerRemote.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerRemote.java
@@ -25,7 +25,9 @@ import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.criteria.SavedSearchCriteria;
import org.rhq.core.domain.search.SavedSearch;
+import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.server.authz.PermissionException;
import org.rhq.enterprise.server.system.ServerVersion;
@@ -99,4 +101,18 @@ public interface SavedSearchManagerRemote {
public SavedSearch getSavedSearchById( //
@WebParam(name = "subject") Subject subject, //
@WebParam(name = "savedSearchId") int savedSearchId);
+
+ /**
+ * Returns the {@link PageList} of {@link SavedSearch} entities that match the criteria filters that are visible
+ * to the user
+ *
+ * @param subject the logged in user requesting the {@link PageList} of {@link SavedSearch} to be returned
+ * @param criteria the {@link SavedSearchCriteria} object that will filter the returned results
+ *
+ * @return the {@link PageList} of {@link SavedSearch} entities that match the criteria filters, an empty list
+ * will be returned if no results were found or none matches the given filters
+ */
+ public PageList<SavedSearch> findSavedSearchesByCriteria( //
+ @WebParam(name = "subject") Subject subject, //
+ @WebParam(name = "criteria") SavedSearchCriteria criteria);
}
commit 8bee964f9c9fb494fc08a3baaa307361d826b445
Author: Joseph Marques <joseph(a)redhat.com>
Date: Tue Feb 23 02:48:32 2010 -0500
enhance the CriteriaQueryGenerator to allow more flexible authorization:
support users to set a completely arbitrary authorization fragment, which
will be inserted into the list of conditions for the generated query
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryGenerator.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryGenerator.java
index 9c62eed..bb0c072 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryGenerator.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryGenerator.java
@@ -58,13 +58,14 @@ public final class CriteriaQueryGenerator {
public enum AuthorizationTokenType {
RESOURCE, // specifies the resource alias to join on for standard res-group-role-subject authorization checking
- GROUP; // specifies the group alias to join on for standard group-role-subject authorization checking
+ GROUP; // specifies the group alias to join on for standard group-role-subject authorization checking
}
private Criteria criteria;
private String authorizationJoinFragment;
private String authorizationPermsFragment;
+ private String authorizationCustomConditionFragment;
private int authorizationSubjectId;
private String alias;
@@ -89,6 +90,10 @@ public final class CriteriaQueryGenerator {
this.alias = aliasBuilder.toString();
}
+ public void setAuthorizationCustomConditionFragment(String fragment) {
+ this.authorizationCustomConditionFragment = fragment;
+ }
+
public void setAuthorizationResourceFragment(AuthorizationTokenType type, int subjectId) {
String defaultFragment = null;
if (type == AuthorizationTokenType.RESOURCE) {
@@ -260,6 +265,16 @@ public final class CriteriaQueryGenerator {
}
}
+ if (authorizationCustomConditionFragment != null) {
+ if (firstCrit) {
+ firstCrit = false;
+ } else {
+ // always want AND for security, regardless of conjunctiveFragment
+ results.append(NL).append(" AND ");
+ }
+ results.append(this.authorizationCustomConditionFragment);
+ }
+
if (countQuery == false) {
boolean overridden = true;
PageControl pc = criteria.getPageControlOverrides();
commit d065f478b829887eda067308a10f98edef113b66
Author: Joseph Marques <joseph(a)redhat.com>
Date: Tue Feb 23 00:50:35 2010 -0500
initial SLSB support basic CRUD, with security restrictions, for saved search patterns
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerBean.java
new file mode 100644
index 0000000..f672ac7
--- /dev/null
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerBean.java
@@ -0,0 +1,104 @@
+/*
+ * 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.server.search;
+
+import javax.ejb.EJB;
+import javax.ejb.Stateless;
+import javax.persistence.EntityManager;
+import javax.persistence.PersistenceContext;
+
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.search.SavedSearch;
+import org.rhq.enterprise.server.RHQConstants;
+import org.rhq.enterprise.server.authz.AuthorizationManagerLocal;
+import org.rhq.enterprise.server.authz.PermissionException;
+
+/**
+ * This bean provides functionality to CRUD saved search patterns.
+ *
+ * @author Joseoh Marques
+ */
+@Stateless
+public class SavedSearchManagerBean implements SavedSearchManagerLocal /* local already implements remote interface */{
+
+ @PersistenceContext(unitName = RHQConstants.PERSISTENCE_UNIT_NAME)
+ private EntityManager entityManager;
+
+ @EJB
+ private AuthorizationManagerLocal authorizationManager;
+
+ /**
+ * @see SavedSearchManagerRemote#createSavedSearch(Subject, SavedSearch)
+ */
+ public void createSavedSearch(Subject subject, SavedSearch savedSearch) {
+ validateManipulatePermission(subject, savedSearch);
+ entityManager.persist(savedSearch);
+ return;
+ }
+
+ /**
+ * @see SavedSearchManagerRemote#updateSavedSearch(Subject, SavedSearch)
+ */
+ public void updateSavedSearch(Subject subject, SavedSearch savedSearch) {
+ validateManipulatePermission(subject, savedSearch);
+ entityManager.merge(savedSearch);
+ return;
+ }
+
+ /**
+ * @see SavedSearchManagerRemote#deleteSavedSearch(Subject, int)
+ */
+ public void deleteSavedSearch(Subject subject, int savedSearchId) {
+ SavedSearch savedSearch = entityManager.find(SavedSearch.class, savedSearchId);
+ validateManipulatePermission(subject, savedSearch);
+ entityManager.remove(savedSearch);
+ }
+
+ /**
+ * @see SavedSearchManagerRemote#getSavedSearchById(Subject, int)
+ */
+ public SavedSearch getSavedSearchById(Subject subject, int savedSearchId) {
+ SavedSearch savedSearch = entityManager.find(SavedSearch.class, savedSearchId);
+ validateReadPermission(subject, savedSearch);
+ return savedSearch;
+ }
+
+ private void validateManipulatePermission(Subject subject, SavedSearch savedSearch) {
+ if (savedSearch.isGlobal()) {
+ if (!authorizationManager.isInventoryManager(subject)) {
+ throw new PermissionException("Only inventory managers can manipulate global saved searches");
+ }
+ // note: inventory managers can modify any saved search pattern, not just their own
+ } else {
+ if (subject.equals(savedSearch.getSubject())) {
+ throw new PermissionException("Users without inventory manager permission "
+ + "can only manipulate their own saved searches");
+ }
+ }
+ }
+
+ private void validateReadPermission(Subject subject, SavedSearch savedSearch) {
+ if (!savedSearch.isGlobal()) {
+ if (subject.equals(savedSearch.getSubject())) {
+ throw new PermissionException("Users without inventory manager permission "
+ + "can only view their own or global saved saved searches");
+ }
+ }
+ }
+}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerLocal.java
new file mode 100644
index 0000000..7ced552
--- /dev/null
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerLocal.java
@@ -0,0 +1,31 @@
+/*
+ * 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.server.search;
+
+import javax.ejb.Local;
+
+/**
+ * The local interface to the SavedSearchManager.
+ *
+ * @author Joseph Marques
+ */
+@Local
+public interface SavedSearchManagerLocal extends SavedSearchManagerRemote {
+ // there are currently no methods in the local interface that do not exist in the remote interface
+}
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerRemote.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerRemote.java
new file mode 100644
index 0000000..a1615ec
--- /dev/null
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/search/SavedSearchManagerRemote.java
@@ -0,0 +1,102 @@
+/*
+ * 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.server.search;
+
+import javax.ejb.Remote;
+import javax.jws.WebMethod;
+import javax.jws.WebParam;
+import javax.jws.WebService;
+import javax.jws.soap.SOAPBinding;
+
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.search.SavedSearch;
+import org.rhq.enterprise.server.authz.PermissionException;
+import org.rhq.enterprise.server.system.ServerVersion;
+
+/**
+ * The remote interface to the SavedSearchManager.
+ *
+ * @author Joseph Marques
+ */
+@SOAPBinding(style = SOAPBinding.Style.DOCUMENT)
+@WebService(targetNamespace = ServerVersion.namespace)
+@Remote
+public interface SavedSearchManagerRemote {
+
+ /**
+ * Persisted a new {@link SavedSearch} with the given primary key
+ *
+ * @param subject the logged in user requesting the {@link SavedSearch} deletion
+ * @param savedSearchId the primary key of the {@link SavedSearch} to be deleted
+ *
+ * @throws PermissionException if the user is not authorized to create the {@link SavedSearch}. Only inventory
+ * managers can create global saved searches. Regular users can only create {@link SavedSearch}es against
+ * their own accounts.
+ */
+ @WebMethod
+ public void createSavedSearch( //
+ @WebParam(name = "subject") Subject subject, //
+ @WebParam(name = "savedSearch") SavedSearch savedSearch);
+
+ /**
+ * Saves all changes to the passed {@link SavedSearch} database, correlating it to the record already
+ * persisted with the same primary key
+ *
+ * @param subject the logged in user requesting the {@link SavedSearch} persisted modification
+ * @param savedSearchId the {@link SavedSearch} which will have its modifications persisted
+ *.
+ * @throws PermissionException if the user is not authorized to modify the {@link SavedSearch}. Only inventory
+ * managers can update global saved searches. Regular users can only update {@link SavedSearch}es from
+ * their own accounts.
+ */
+ @WebMethod
+ public void updateSavedSearch( //
+ @WebParam(name = "subject") Subject subject, //
+ @WebParam(name = "savedSearch") SavedSearch savedSearch);
+
+ /**
+ * Deletes the {@link SavedSearch} with the given primary key
+ *
+ * @param subject the logged in user requesting the {@link SavedSearch} deletion
+ * @param savedSearchId the primary key of the {@link SavedSearch} to be deleted
+ *
+ * @throws PermissionException if the user is not authorized to delete the {@link SavedSearch}. Only inventory
+ * managers can delete global saved searches. Regular users can only delete {@link SavedSearch}es from
+ * their own accounts.
+ */
+ @WebMethod
+ public void deleteSavedSearch( //
+ @WebParam(name = "subject") Subject subject, //
+ @WebParam(name = "savedSearchId") int savedSearchId);
+
+ /**
+ * Returns the {@link SavedSearch} with the given primary key
+ *
+ * @param subject the logged in user requesting the {@link SavedSearch} to be loaded
+ * @param savedSearchId the primary key of the {@link SavedSearch} to be loaded
+ *
+ * @return the {@link SavedSearch} or <code>null</code> if it wasn't found
+ * @throws PermissionException if the user is not authorized to view the {@link SavedSearch}. Regular users can
+ * only view {@link SavedSearch}es from their own accounts.
+ */
+ @WebMethod
+ public SavedSearch getSavedSearchById( //
+ @WebParam(name = "subject") Subject subject, //
+ @WebParam(name = "savedSearchId") int savedSearchId);
+}
commit c95388946134a47b002f5821c3a168db6f549355
Author: Joseph Marques <joseph(a)redhat.com>
Date: Mon Feb 22 21:06:31 2010 -0500
saved search hibernate entities
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/search/SavedSearch.java b/modules/core/domain/src/main/java/org/rhq/core/domain/search/SavedSearch.java
new file mode 100644
index 0000000..9142772
--- /dev/null
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/search/SavedSearch.java
@@ -0,0 +1,253 @@
+/*
+ * 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, 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.core.domain.search;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+
+import org.rhq.core.domain.auth.Subject;
+
+/**
+ * The data model for saved searches. Each users has his or her own set of
+ * saved searches, but inventory managers are allowed to "promote" their
+ * saved searches to GLOBAL status, which makes them available to all users
+ * under that installation of RHQ.
+ *
+ * There are two levels of pre-computed data within this structured. After
+ * the {@link SavedSearch} is created, the pattern will be translated into its
+ * JPQL equivalent and stored. If the {@link SavedSearch} is ever modified
+ * and saved, the JPQL will be re-computed.
+ *
+ * Periodically, the count-query version of the {@link SavedSearch} will be
+ * executed (using the stored JPQL), and the number of matching records will
+ * be stored. If this {@link SavedSearch} ever needs to be displayed on the
+ * user interface, it will by default retrieve this cached result count.
+ *
+ * @author Joseph Marques
+ */
+@Entity
+@SequenceGenerator(name = "id", sequenceName = "RHQ_SAVED_SEARCH_ID_SEQ")
+@Table(name = "RHQ_SAVED_SEARCH")
+public class SavedSearch {
+
+ @Id
+ @Column(name = "ID", nullable = false)
+ @GeneratedValue(strategy = GenerationType.AUTO, generator = "id")
+ private Integer id;
+
+ @Column(name = "CONTEXT", nullable = false)
+ @Enumerated(EnumType.STRING)
+ private SearchContext context;
+
+ @Column(name = "NAME")
+ private String name;
+
+ @Column(name = "DESCRIPTION")
+ private String description;
+
+ @Column(name = "PATTERN", nullable = false)
+ private String pattern;
+
+ @Column(name = "JPQL_TRANSLATION")
+ private String jpqlTranslation;
+
+ @Column(name = "LAST_COMPUTE_TIME", nullable = false)
+ private long lastComputeTime;
+
+ @Column(name = "RESULT_COUNT")
+ private Long resultCount;
+
+ @Column(name = "SUBJECT_ID", nullable = false)
+ private Subject subject;
+
+ @Column(name = "RESOURCE_ID", insertable = false, updatable = false)
+ private int subjectId;
+
+ @Column(name = "GLOBAL", nullable = false)
+ private boolean global;
+
+ protected SavedSearch() {
+ // no-arg ctor for Hibernate
+ }
+
+ public SavedSearch(SearchContext context, String name, String pattern, Subject subject) {
+ // call setters to go through parameter validation
+ setContext(context);
+ setPattern(pattern);
+ setSubject(subject);
+ setName(name); // name can be null, to allow for saving searches quickly
+
+ this.description = null;
+ this.jpqlTranslation = null; // null value for pre-computed JPQL implies computation is needed
+ this.lastComputeTime = 0; // further imply that computation needs to occur
+ this.resultCount = null; // NULL resultCount implies either computation failed or hasn't begun yet
+ this.global = false; // user must promote saved search to be a global after creation
+ }
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(Integer id) {
+ this.id = id;
+ }
+
+ public SearchContext getContext() {
+ return context;
+ }
+
+ private void setContext(SearchContext context) {
+ if (context == null) {
+ throw new IllegalArgumentException("All saved searches must be bound to a SearchContext");
+ }
+ this.context = context;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ private void setName(String name) {
+ this.name = name;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getPattern() {
+ return pattern;
+ }
+
+ public void setPattern(String pattern) {
+ if (pattern == null || pattern.trim().equals("")) {
+ throw new IllegalArgumentException("All saved searches must have a non-empty pattern");
+ }
+ this.pattern = pattern;
+ }
+
+ public String getJpqlTranslation() {
+ return jpqlTranslation;
+ }
+
+ public void setJpqlTransation(String jpqlTranslation) {
+ this.jpqlTranslation = jpqlTranslation;
+ }
+
+ public long getLastComputeTime() {
+ return lastComputeTime;
+ }
+
+ public void setLastComputeTime(long lastComputeTime) {
+ this.lastComputeTime = lastComputeTime;
+ }
+
+ public Long getResultCount() {
+ return resultCount;
+ }
+
+ public void setResultCount(Long resultCount) {
+ this.resultCount = resultCount;
+ }
+
+ public Subject getSubject() {
+ return subject;
+ }
+
+ private void setSubject(Subject subject) {
+ if (subject == null) {
+ throw new IllegalArgumentException("All saved searches must be owned by a specific user");
+ }
+ this.subject = subject;
+ this.subjectId = subject.getId();
+ }
+
+ public int getSubjectId() {
+ return subjectId;
+ }
+
+ public boolean isGlobal() {
+ return global;
+ }
+
+ public void setGlobal(boolean global) {
+ this.global = global;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = (prime * result) + subjectId;
+ result = (prime * result) + context.hashCode();
+ result = (prime * result) + ((name == null) ? 0 : name.hashCode());
+ result = (prime * result) + pattern.hashCode();
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+
+ if ((obj == null) || (!(obj instanceof SavedSearch))) {
+ return false;
+ }
+
+ final SavedSearch other = (SavedSearch) obj;
+
+ if (subjectId != other.subjectId) {
+ return false;
+ }
+
+ if (context != other.context) {
+ return false;
+ }
+
+ if (name == null) {
+ if (other.name != null) {
+ return false;
+ }
+ } else if (!name.equals(other.name)) {
+ return false;
+ }
+
+ if (!pattern.equals(other.pattern)) {
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/search/SearchContext.java b/modules/core/domain/src/main/java/org/rhq/core/domain/search/SearchContext.java
new file mode 100644
index 0000000..bb045d5
--- /dev/null
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/search/SearchContext.java
@@ -0,0 +1,38 @@
+/*
+ * 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, 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.core.domain.search;
+
+/**
+ * The search mechanism is generic and, thus, suited to finding data in any
+ * RHQ subsystem, including its own. Each individual page in the UI can have
+ * different advanced syntax. This enum will serve as a unique identifier
+ * for which context is currently active. You can think of it as a piece of
+ * meta-data that annotates each saved search, representing which context it
+ * belongs to. This will also affect which grammar is used to auto-complete
+ * search expressions.
+ *
+ * @author Joseph Marques
+ */
+public enum SearchContext {
+ Resource, Group;
+}
commit c9d080cc510d6e4bf5c26c34f7b9050544736da3
Author: Joseph Marques <joseph(a)redhat.com>
Date: Mon Feb 22 21:06:19 2010 -0500
saved search dbupgrade scripts
diff --git a/modules/core/dbutils/pom.xml b/modules/core/dbutils/pom.xml
index 1d4d3dd..2fb6a90 100644
--- a/modules/core/dbutils/pom.xml
+++ b/modules/core/dbutils/pom.xml
@@ -22,7 +22,7 @@
<properties>
<scm.module.path>modules/core/dbutils/</scm.module.path>
- <db.schema.version>2.79</db.schema.version>
+ <db.schema.version>2.82</db.schema.version>
</properties>
<dependencies>
diff --git a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
index 9af6aa5..834e9ce 100644
--- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
+++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
@@ -3202,6 +3202,31 @@
</statement>
</schema-directSQL>
</schemaSpec>
+
+ <schemaSpec version="2.82">
+ <schema-directSQL>
+ <statement desc="Creating table RHQ_SAVED_SEARCH">
+ CREATE TABLE RHQ_SAVED_SEARCH ( ID INTEGER )
+ </statement>
+ </schema-directSQL>
+ <schema-addColumn table="RHQ_SAVED_SEARCH" column="CONTEXT" columnType="VARCHAR2" precision="25" />
+ <schema-alterColumn table="RHQ_SAVED_SEARCH" column="CONTEXT" nullable="FALSE" />
+
+ <schema-addColumn table="RHQ_SAVED_SEARCH" column="NAME" columnType="VARCHAR2" precision="200" />
+ <schema-addColumn table="RHQ_SAVED_SEARCH" column="DESCRIPTION" columnType="VARCHAR2" precision="500" />
+ <schema-addColumn table="RHQ_SAVED_SEARCH" column="PATTERN" columnType="VARCHAR2" precision="1000" />
+ <schema-alterColumn table="RHQ_SAVED_SEARCH" column="PATTERN" nullable="FALSE" />
+
+ <schema-addColumn table="RHQ_SAVED_SEARCH" column="JPQL_TRANSLATION" columnType="VARCHAR2" precision="4000" />
+ <schema-addColumn table="RHQ_SAVED_SEARCH" column="LAST_COMPUTE_TIME" columnType="LONG" />
+ <schema-alterColumn table="RHQ_SAVED_SEARCH" column="LAST_COMPUTE_TIME" nullable="FALSE" />
+ <schema-addColumn table="RHQ_SAVED_SEARCH" column="RESULT_COUNT" columnType="LONG" />
+
+ <schema-addColumn table="RHQ_SAVED_SEARCH" column="SUBJECT_ID" columnType="INTEGER" />
+ <schema-alterColumn table="RHQ_SAVED_SEARCH" column="SUBJECT_ID" nullable="FALSE" />
+ <schema-addColumn table="RHQ_SAVED_SEARCH" column="GLOBAL" columnType="BOOLEAN" />
+ <schema-alterColumn table="RHQ_SAVED_SEARCH" column="GLOBAL" nullable="FALSE" />
+ </schemaSpec>
</dbupgrade>
</target>
</project>
commit afc78a9b2bfcb14b5b079ffb29aa82c4e6b0e81f
Author: Joseph Marques <joseph(a)redhat.com>
Date: Mon Feb 22 21:06:07 2010 -0500
saved searches dbsetup scripts
diff --git a/modules/core/dbutils/src/main/scripts/dbsetup-build.xml b/modules/core/dbutils/src/main/scripts/dbsetup-build.xml
index 047d615..f5e4eae 100644
--- a/modules/core/dbutils/src/main/scripts/dbsetup-build.xml
+++ b/modules/core/dbutils/src/main/scripts/dbsetup-build.xml
@@ -39,7 +39,7 @@ To run the default target, you must set one of the following properties to true:
<property name="dbsetup.scripts.dir" value="${basedir}/src/main/scripts/dbsetup" />
<property name="dbsetup.output.dir" value="${basedir}/target/dbsetup" /> <!-- away from classes so it doesn't go into the jar -->
<!-- define the setup creation processing order. note, removals are done in the reverse order -->
- <property name="dbsetup.subsystems" value="config,cluster,inventory,auth,authz,operation,event,alert,sysconfig,scheduler,amps,measurement,content,resource-request,jms,obsolete"/>
+ <property name="dbsetup.subsystems" value="search,config,cluster,inventory,auth,authz,operation,event,alert,sysconfig,scheduler,amps,measurement,content,resource-request,jms,obsolete"/>
<property name="dbsetup.combined.schema" value="${dbsetup.output.dir}/all-schema.xml" />
<property name="dbsetup.combined.data" value="${dbsetup.output.dir}/all-data.xml" />
<property name="dbsetup.tstamp.file" value="${dbsetup.output.dir}/dbsetup-combine.tstamp" />
diff --git a/modules/core/dbutils/src/main/scripts/dbsetup/search-schema.xml b/modules/core/dbutils/src/main/scripts/dbsetup/search-schema.xml
new file mode 100644
index 0000000..7c0de23
--- /dev/null
+++ b/modules/core/dbutils/src/main/scripts/dbsetup/search-schema.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<dbsetup name="amps-schema.xml"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="urn:xmlns:rhq-dbsetup-schema">
+
+ <table name="RHQ_SAVED_SEARCH">
+ <column name="ID" default="sequence-only" initial="10001" primarykey="true" required="true" type="INTEGER"/>
+ <column name="CONTEXT" type="VARCHAR2" size="25" required="true"/>
+
+ <column name="NAME" type="VARCHAR2" size="200" required="true"/>
+ <column name="DESCRIPTION" type="VARCHAR2" size="500" required="false"/>
+ <column name="PATTERN" type="VARCHAR2" size="1000" required="true"/>
+
+ <column name="JPQL_TRANSLATION" type="VARCHAR2" size="4000" required="false"/>
+ <column name="LAST_COMPUTE_TIME" type="LONG" required="true"/>
+ <column name="RESULT_COUNT" type="LONG" required="false"/>
+
+ <column name="SUBJECT_ID" type="INTEGER" references="RHQ_SUBJECT" required="true"/>
+ <column name="ENABLED" type="BOOLEAN" required="true"/>
+ </table>
+
+</dbsetup>
\ No newline at end of file
commit 6d87241b69c095bd2928f4e3b03bc9dcfbeeefd1
Author: Heiko W. Rupp <pilhuhn(a)fedorapeople.org>
Date: Sat Feb 20 10:49:01 2010 +0100
Fix potential NPE
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/AlertNotificationLog.java b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/AlertNotificationLog.java
index 5ed6d4f..b90def3 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/AlertNotificationLog.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/AlertNotificationLog.java
@@ -113,8 +113,8 @@ public class AlertNotificationLog implements Serializable {
@PrePersist
@PreUpdate
public void trimMessage() {
- if (message.length()>255)
- message = message.substring(0,254);
+ if (message!=null && message.length()>255)
+ message = message.substring(0,255);
}
protected AlertNotificationLog() {
commit 2d38d85bb4500c1a873aba7b193fb9984d00539d
Author: Heiko W. Rupp <pilhuhn(a)fedorapeople.org>
Date: Sat Feb 20 09:47:10 2010 +0100
Truncate the message at 140 chars, as identi.ca bails out on longer messages; seems to improve stability with Twitter too.
Introduce abbreviated versions of the messages as space on Microblog etc is scarce. BZ 555091
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/AlertNotificationLog.java b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/AlertNotificationLog.java
index ba75940..5ed6d4f 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/AlertNotificationLog.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/AlertNotificationLog.java
@@ -38,6 +38,8 @@ import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
+import javax.persistence.PrePersist;
+import javax.persistence.PreUpdate;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Transient;
@@ -108,6 +110,13 @@ public class AlertNotificationLog implements Serializable {
@Transient
transient List<String> transientEmails = new ArrayList<String>();
+ @PrePersist
+ @PreUpdate
+ public void trimMessage() {
+ if (message.length()>255)
+ message = message.substring(0,254);
+ }
+
protected AlertNotificationLog() {
} // JPA
@@ -130,7 +139,6 @@ public class AlertNotificationLog implements Serializable {
public AlertNotificationLog(Alert alert, String senderName, ResultState state, String message) {
this.alert = alert;
- this.sender = sender;
this.resultState = state;
this.message = message;
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 454b9a9..ff4025f 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
@@ -780,7 +780,7 @@ public class AlertManagerBean implements AlertManagerLocal, AlertManagerRemote {
Map<String, String> alertMessage = emailManager.getAlertEmailMessage(
prettyPrintResourceHierarchy(alertDefinition.getResource()), alertDefinition.getResource().getName(),
alertDefinition.getName(), alertDefinition.getPriority().toString(), new Date(alert.getCtime()).toString(),
- prettyPrintAlertConditions(alert.getConditionLogs()), prettyPrintAlertURL(alert));
+ prettyPrintAlertConditions(alert.getConditionLogs(), false), prettyPrintAlertURL(alert));
String messageSubject = alertMessage.keySet().iterator().next();
String messageBody = alertMessage.values().iterator().next();
@@ -834,13 +834,14 @@ public class AlertManagerBean implements AlertManagerLocal, AlertManagerRemote {
/**
* Create a human readable description of the conditions that led to this alert.
* @param alert Alert to create human readable condition description
+ * @param shortVersion if true the messages printed are abbreviated to save space
* @return human readable condition log
*/
- public String prettyPrintAlertConditions(Alert alert) {
- return prettyPrintAlertConditions(alert.getConditionLogs());
+ public String prettyPrintAlertConditions(Alert alert, boolean shortVersion) {
+ return prettyPrintAlertConditions(alert.getConditionLogs(), shortVersion);
}
- private String prettyPrintAlertConditions(Set<AlertConditionLog> conditionLogs) {
+ private String prettyPrintAlertConditions(Set<AlertConditionLog> conditionLogs, boolean shortVersion) {
StringBuilder builder = new StringBuilder();
int conditionCounter = 1;
@@ -858,16 +859,27 @@ public class AlertManagerBean implements AlertManagerLocal, AlertManagerRemote {
builder.append(NEW_LINE);
- builder.append(AlertI18NFactory.getMessage(AlertI18NResourceKeys.ALERT_EMAIL_CONDITION_LOG_FORMAT,
- conditionCounter, prettyPrintAlertCondition(aLog.getCondition()), new SimpleDateFormat(
- "yyyy/MM/dd HH:mm:ss z").format(new Date(aLog.getCtime())), formattedValue));
+ String format;
+ if (shortVersion)
+ format = AlertI18NResourceKeys.ALERT_EMAIL_CONDITION_LOG_FORMAT_SHORT;
+ else
+ format = AlertI18NResourceKeys.ALERT_EMAIL_CONDITION_LOG_FORMAT;
+ SimpleDateFormat dateFormat;
+ if (shortVersion)
+ dateFormat= new SimpleDateFormat(
+ "yy/MM/dd HH:mm:ss z");
+ else
+ dateFormat= new SimpleDateFormat(
+ "yyyy/MM/dd HH:mm:ss z");
+ builder.append(AlertI18NFactory.getMessage(format,
+ conditionCounter, prettyPrintAlertCondition(aLog.getCondition(), shortVersion), dateFormat.format(new Date(aLog.getCtime())), formattedValue));
conditionCounter++;
}
return builder.toString();
}
- private String prettyPrintAlertCondition(AlertCondition condition) {
+ private String prettyPrintAlertCondition(AlertCondition condition, boolean shortVersion) {
StringBuilder builder = new StringBuilder();
AlertConditionCategory category = condition.getCategory();
@@ -915,19 +927,38 @@ public class AlertManagerBean implements AlertManagerLocal, AlertManagerRemote {
}
} else if ((category == AlertConditionCategory.RESOURCE_CONFIG) || (category == AlertConditionCategory.CHANGE)
|| (category == AlertConditionCategory.TRAIT)) {
- builder.append(AlertI18NFactory.getMessage(AlertI18NResourceKeys.ALERT_CURRENT_LIST_VALUE_CHANGED));
+
+ if (shortVersion)
+ builder.append(AlertI18NFactory.getMessage(AlertI18NResourceKeys.ALERT_CURRENT_LIST_VALUE_CHANGED_SHORT));
+ else
+ builder.append(AlertI18NFactory.getMessage(AlertI18NResourceKeys.ALERT_CURRENT_LIST_VALUE_CHANGED));
+
} else if (category == AlertConditionCategory.EVENT) {
if ((condition.getOption() != null) && (condition.getOption().length() > 0)) {
+ String propsCbEventSeverityRegexMatch;
+ if (shortVersion)
+ propsCbEventSeverityRegexMatch = AlertI18NResourceKeys.ALERT_CONFIG_PROPS_CB_EVENT_SEVERITY_REGEX_MATCH_SHORT;
+ else
+ propsCbEventSeverityRegexMatch = AlertI18NResourceKeys.ALERT_CONFIG_PROPS_CB_EVENT_SEVERITY_REGEX_MATCH;
+
builder.append(AlertI18NFactory.getMessage(
- AlertI18NResourceKeys.ALERT_CONFIG_PROPS_CB_EVENT_SEVERITY_REGEX_MATCH, condition.getName(),
+ propsCbEventSeverityRegexMatch, condition.getName(),
condition.getOption()));
} else {
- builder.append(AlertI18NFactory.getMessage(AlertI18NResourceKeys.ALERT_CONFIG_PROPS_CB_EVENT_SEVERITY,
- condition.getName()));
+ if (shortVersion)
+ builder.append(AlertI18NFactory.getMessage(AlertI18NResourceKeys.ALERT_CONFIG_PROPS_CB_EVENT_SEVERITY_SHORT,
+ condition.getName()));
+ else
+ builder.append(AlertI18NFactory.getMessage(AlertI18NResourceKeys.ALERT_CONFIG_PROPS_CB_EVENT_SEVERITY,
+ condition.getName()));
}
} else if (category == AlertConditionCategory.AVAILABILITY) {
- builder.append(AlertI18NFactory.getMessage(AlertI18NResourceKeys.ALERT_CONFIG_PROPS_CB_AVAILABILITY,
- condition.getOption()));
+ if (shortVersion)
+ builder.append(AlertI18NFactory.getMessage(AlertI18NResourceKeys.ALERT_CONFIG_PROPS_CB_AVAILABILITY_SHORT,
+ condition.getOption()));
+ else
+ builder.append(AlertI18NFactory.getMessage(AlertI18NResourceKeys.ALERT_CONFIG_PROPS_CB_AVAILABILITY,
+ condition.getOption()));
} else {
// do nothing
}
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 996f245..e482ffa 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
@@ -96,9 +96,10 @@ public interface AlertManagerLocal {
/**
* Create a human readable description of the conditions that led to this alert.
* @param alert Alert to create human readable condition description
+ * @param shortVersion if true the messages printed are abbreviated to save space
* @return human readable condition log
*/
- String prettyPrintAlertConditions(Alert alert);
+ String prettyPrintAlertConditions(Alert alert, boolean shortVersion);
/**
* Tells us if the definition of the passed alert will be disabled after this alert was fired
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/i18n/AlertI18NResourceKeys.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/i18n/AlertI18NResourceKeys.java
index 8734771..1de3d85 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/i18n/AlertI18NResourceKeys.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/i18n/AlertI18NResourceKeys.java
@@ -32,20 +32,41 @@ public interface AlertI18NResourceKeys {
@I18NMessage(locale = "de", value = "Verfgbarkeit wird {0}") })
String ALERT_CONFIG_PROPS_CB_AVAILABILITY = "alert.config.props.CB.Availability";
+ @I18NMessages( { @I18NMessage("Avail goes {0}"),
+ @I18NMessage(locale = "de", value = "Verf. wird {0}") })
+ String ALERT_CONFIG_PROPS_CB_AVAILABILITY_SHORT = "alert.config.props.CB.Availability.short";
+
@I18NMessages( { @I18NMessage("Event Severity: {0}"),
@I18NMessage(locale = "de", value = "Schwere des Ereignesses: {0}") })
String ALERT_CONFIG_PROPS_CB_EVENT_SEVERITY = "alert.config.props.CB.EventSeverity";
+ @I18NMessages( { @I18NMessage("Sev: {0}"),
+ @I18NMessage(locale = "de", value = "Schwere: {0}") })
+ String ALERT_CONFIG_PROPS_CB_EVENT_SEVERITY_SHORT = "alert.config.props.CB.EventSeverity.short";
+
@I18NMessages( { @I18NMessage("Event Severity: {0} and matching expression \"{1}\""),
@I18NMessage(locale = "de", value = "Schwere des Ereignesses: {0} und zugehriger Ausdruck \"{1}\"") })
String ALERT_CONFIG_PROPS_CB_EVENT_SEVERITY_REGEX_MATCH = "alert.config.props.CB.EventSeverity.RegexMatch";
+ @I18NMessages( { @I18NMessage("Sev: {0} & exp \"{1}\""),
+ @I18NMessage(locale = "de", value = "Schwere: {0} & Ausdruck \"{1}\"") })
+ String ALERT_CONFIG_PROPS_CB_EVENT_SEVERITY_REGEX_MATCH_SHORT = "alert.config.props.CB.EventSeverity.RegexMatch.short";
+
@I18NMessages( { @I18NMessage("value changed"), @I18NMessage(locale = "de", value = "Der Wert hat sich gendert") })
String ALERT_CURRENT_LIST_VALUE_CHANGED = "alert.current.list.ValueChanged";
+ @I18NMessages( { @I18NMessage("val chg"), @I18NMessage(locale = "de", value = "Wertnd.") })
+ String ALERT_CURRENT_LIST_VALUE_CHANGED_SHORT = "alert.current.list.ValueChanged.short";
+
@I18NMessages( {
@I18NMessage("\\ - Condition {0}: {1}\\n\\\n" + "\\ - Date/Time: {2}\\n\\\n" + "\\ - Details: {3}\\n\\\n"),
@I18NMessage(locale = "de", value = " - Bedingung {0}: {1}\\n\\\n - Datum/Uhrzeit: {2}\\n\\\n"
+ "\\ - Details: {3}\\n\\\n") })
String ALERT_EMAIL_CONDITION_LOG_FORMAT = "alert.email.condition.log.format";
+
+ @I18NMessages( {
+ @I18NMessage("\\ - Cond {0}: {1}\\n\\\n" + "\\ - Time: {2}\\n\\\n" + "\\ - Det: {3}\\n\\\n"),
+ @I18NMessage(locale = "de", value = " - Bed {0}: {1}\\n\\\n - Zeit: {2}\\n\\\n"
+ + "\\ - Det: {3}\\n\\\n") })
+ String ALERT_EMAIL_CONDITION_LOG_FORMAT_SHORT = "alert.email.condition.log.format.short";
}
\ No newline at end of file
diff --git a/modules/enterprise/server/plugins/alert-irc/src/main/java/org/rhq/enterprise/server/plugins/alertIrc/IrcSender.java b/modules/enterprise/server/plugins/alert-irc/src/main/java/org/rhq/enterprise/server/plugins/alertIrc/IrcSender.java
index 93eecc6..95abdb9 100644
--- a/modules/enterprise/server/plugins/alert-irc/src/main/java/org/rhq/enterprise/server/plugins/alertIrc/IrcSender.java
+++ b/modules/enterprise/server/plugins/alert-irc/src/main/java/org/rhq/enterprise/server/plugins/alertIrc/IrcSender.java
@@ -65,7 +65,7 @@ public class IrcSender extends AlertSender<IrcAlertComponent> {
b.append("): ");
b.append(alertManager.prettyPrintAlertURL(alert));
b.append("\n");
- b.append(alertManager.prettyPrintAlertConditions(alert));
+ b.append(alertManager.prettyPrintAlertConditions(alert, false));
return b.toString();
}
diff --git a/modules/enterprise/server/plugins/alert-microblog/src/main/java/org/rhq/enterprise/server/plugins/alertMicroblog/MicroblogSender.java b/modules/enterprise/server/plugins/alert-microblog/src/main/java/org/rhq/enterprise/server/plugins/alertMicroblog/MicroblogSender.java
index 257b315..b13763e 100644
--- a/modules/enterprise/server/plugins/alert-microblog/src/main/java/org/rhq/enterprise/server/plugins/alertMicroblog/MicroblogSender.java
+++ b/modules/enterprise/server/plugins/alert-microblog/src/main/java/org/rhq/enterprise/server/plugins/alertMicroblog/MicroblogSender.java
@@ -57,14 +57,19 @@ public class MicroblogSender extends AlertSender {
b.append("' (");
b.append(alert.getAlertDefinition().getResource().getId());
b.append("): ");
- b.append(alertManager.prettyPrintAlertConditions(alert));
+ b.append(alertManager.prettyPrintAlertConditions(alert, true));
b.append("-by @JBossJopr"); // TODO not for production :-)
// TODO use some alert url shortening service
SenderResult result ;
String txt = "user@baseUrl [" + user + "@" + baseUrl + "]:";
try {
- Status status = twitter.updateStatus(b.toString());
+ String msg = b.toString();
+ if (msg.length()>140)
+ msg = msg.substring(0,140);
+
+ Status status = twitter.updateStatus(msg);
+
result = new SenderResult(ResultState.SUCCESS,"Send notification to " + txt + ", msg-id: " + status.getId());
} catch (TwitterException e) {
diff --git a/modules/enterprise/server/plugins/alert-mobicents/src/main/java/org/rhq/enterprise/server/plugins/alertMobicents/MobicentsSender.java b/modules/enterprise/server/plugins/alert-mobicents/src/main/java/org/rhq/enterprise/server/plugins/alertMobicents/MobicentsSender.java
index 649d6ed..b14c85d 100644
--- a/modules/enterprise/server/plugins/alert-mobicents/src/main/java/org/rhq/enterprise/server/plugins/alertMobicents/MobicentsSender.java
+++ b/modules/enterprise/server/plugins/alert-mobicents/src/main/java/org/rhq/enterprise/server/plugins/alertMobicents/MobicentsSender.java
@@ -74,7 +74,7 @@ public class MobicentsSender extends AlertSender {
// Switch locale to english, as the voice synthesizer expects this for now
Locale currentLocale = Locale.getDefault();
Locale.setDefault(Locale.ENGLISH);
- b.append(alertManager.prettyPrintAlertConditions(alert));
+ b.append(alertManager.prettyPrintAlertConditions(alert, false));
Locale.setDefault(currentLocale);
boolean willBeDisabled = alertManager.willDefinitionBeDisabled(alert);
diff --git a/modules/enterprise/server/plugins/alert-scriptlang/src/main/java/org.rhq.enterprise.server.plugins.alertScriptlang/ScriptLangSender.java b/modules/enterprise/server/plugins/alert-scriptlang/src/main/java/org.rhq.enterprise.server.plugins.alertScriptlang/ScriptLangSender.java
index 985d890..bac51fb 100644
--- a/modules/enterprise/server/plugins/alert-scriptlang/src/main/java/org.rhq.enterprise.server.plugins.alertScriptlang/ScriptLangSender.java
+++ b/modules/enterprise/server/plugins/alert-scriptlang/src/main/java/org.rhq.enterprise.server.plugins.alertScriptlang/ScriptLangSender.java
@@ -93,7 +93,7 @@ public class ScriptLangSender extends AlertSender<ScriptLangComponent> {
Object[] args = new Object[3];
args[0] = alert;
args[1] = alertManager.prettyPrintAlertURL(alert);
- args[2] = alertManager.prettyPrintAlertConditions(alert);
+ args[2] = alertManager.prettyPrintAlertConditions(alert, false);
result = ((Invocable) engine).invokeFunction("sendAlert", args);
if (result == null) {
diff --git a/modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpSender.java b/modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpSender.java
index 3fd5d79..045c3bb 100644
--- a/modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpSender.java
+++ b/modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpSender.java
@@ -68,7 +68,7 @@ public class SnmpSender extends AlertSender {
String result;
List<Resource> lineage = resourceManager.getResourceLineage(alert.getAlertDefinition().getResource().getId());
String platformName = lineage.get(0).getName();
- String conditions = alertManager.prettyPrintAlertConditions(alert);
+ String conditions = alertManager.prettyPrintAlertConditions(alert, false);
String alertUrl = alertManager.prettyPrintAlertURL(alert);
SenderResult res ;
commit 798ac30ead634c43a72beed52446a38d9bfc1f09
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Fri Feb 19 17:51:53 2010 -0500
i think this should report an error always on lock acq failure. we'll leave the flag alone - don't set it to true - let the next call take care of whether or not the init callback should be invoked or not
diff --git a/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java b/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
index 8c37b50..cd3b479 100644
--- a/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
+++ b/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
@@ -588,11 +588,9 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
writeLock.unlock();
}
} else {
- if (m_needToCallInitializeCallback) {
- Throwable t = new Throwable("Initialize callback lock could not be acquired");
- LOG.error(CommI18NResourceKeys.INITIALIZE_CALLBACK_FAILED, t.getMessage());
- return new GenericCommandResponse(command, false, null, t);
- }
+ Throwable t = new Throwable("Initialize callback lock could not be acquired");
+ LOG.error(CommI18NResourceKeys.INITIALIZE_CALLBACK_FAILED, t.getMessage());
+ return new GenericCommandResponse(command, false, null, t);
}
}
return null;
commit 9746ea32492b638eacb741d608d9ce17349c925d
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Fri Feb 19 17:44:11 2010 -0500
should not worry about the lock failure if the init callback doesn't need to be invoked anyway
diff --git a/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java b/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
index 762b9b4..8c37b50 100644
--- a/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
+++ b/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
@@ -588,10 +588,11 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
writeLock.unlock();
}
} else {
- m_needToCallInitializeCallback = true; // can't invoke callback, we'll want to still call it later
- Throwable t = new Throwable("Initialize callback lock could not be acquired");
- LOG.error(CommI18NResourceKeys.INITIALIZE_CALLBACK_FAILED, t.getMessage());
- return new GenericCommandResponse(command, false, null, t);
+ if (m_needToCallInitializeCallback) {
+ Throwable t = new Throwable("Initialize callback lock could not be acquired");
+ LOG.error(CommI18NResourceKeys.INITIALIZE_CALLBACK_FAILED, t.getMessage());
+ return new GenericCommandResponse(command, false, null, t);
+ }
}
}
return null;
commit c2cca917c88986ca48c84bbbdaf3408753299bf1
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Fri Feb 19 17:38:16 2010 -0500
BZ 537396 - to not block indefinitely if a lock cannot be acquired before attempting to invoke the initialize callback
diff --git a/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java b/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
index 3775212..762b9b4 100644
--- a/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
+++ b/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
@@ -21,6 +21,9 @@ package org.rhq.enterprise.communications.command.client;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
import mazz.i18n.Logger;
@@ -95,10 +98,22 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
private InitializeCallback m_initializeCallback;
/**
- * When the first element is <code>true</code>, the initialize callback will need to be called prior
- * to sending any commands. This is an array because the array itself is used for its lock.
+ * When <code>true</code>, the initialize callback will need to be called prior
+ * to sending any commands. Used in conjunection with its associated RW lock.
*/
- private final boolean[] m_needToCallInitializeCallback;
+ private boolean m_needToCallInitializeCallback;
+
+ /**
+ * RW lock when needing to access its associated atomic boolean flag.
+ */
+ private final ReentrantReadWriteLock m_needToCallInitializeCallbackLock;
+
+ /**
+ * Number of minutes to wait while attempting to aquire a lock before attempting
+ * to invoke the initialize callback. If this amount of minutes expires before the lock
+ * is acquired, an error will occur and the initialize callback will have to be attempted later.
+ */
+ private final long m_initializeCallbackLockAcquisitionTimeoutMins;
/**
* Constructor for {@link JBossRemotingRemoteCommunicator} that initializes the client with no invoker locator
@@ -200,7 +215,17 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
m_clientConfiguration.putAll(client_config);
}
- m_needToCallInitializeCallback = new boolean[] { false };
+ m_needToCallInitializeCallback = false;
+ m_needToCallInitializeCallbackLock = new ReentrantReadWriteLock();
+
+ long mins;
+ try {
+ String minsStr = System.getProperty("rhq.communications.initial-callback-lock-wait-mins", "60");
+ mins = Long.parseLong(minsStr);
+ } catch (Throwable t) {
+ mins = 60L;
+ }
+ m_initializeCallbackLockAcquisitionTimeoutMins = mins;
return;
}
@@ -319,7 +344,7 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
if (m_remotingClient != null) {
m_remotingClient.disconnect();
m_remotingClient = null;
- m_needToCallInitializeCallback[0] = (getInitializeCallback() != null); // specifically do not synchronize, just set it
+ m_needToCallInitializeCallback = (getInitializeCallback() != null); // specifically do not synchrononize by using lock, just set it
}
LOG.info(CommI18NResourceKeys.COMMUNICATOR_CHANGING_ENDPOINT, m_invokerLocator, locator);
@@ -377,7 +402,7 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
public void setInitializeCallback(InitializeCallback callback) {
m_initializeCallback = callback;
- m_needToCallInitializeCallback[0] = (callback != null); // specifically do not synchronize, just set it
+ m_needToCallInitializeCallback = (callback != null); // specifically do not synchrononize by using lock, just set it
}
public String getRemoteEndpoint() {
@@ -403,7 +428,7 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
public void connect() throws Exception {
if ((m_remotingClient != null) && !m_remotingClient.isConnected()) {
m_remotingClient.connect();
- m_needToCallInitializeCallback[0] = (getInitializeCallback() != null); // specifically do not synchronize, just set it
+ m_needToCallInitializeCallback = (getInitializeCallback() != null); // specifically do not synchrononize by using lock, just set it
}
return;
@@ -412,7 +437,7 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
public void disconnect() {
if (m_remotingClient != null) {
m_remotingClient.disconnect();
- m_needToCallInitializeCallback[0] = (getInitializeCallback() != null); // specifically do not synchronize, just set it
+ m_needToCallInitializeCallback = (getInitializeCallback() != null); // specifically do not synchrononize by using lock, just set it
}
return;
@@ -535,18 +560,38 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
private CommandResponse invokeInitializeCallbackIfNeeded(Command command) {
InitializeCallback callback = getInitializeCallback();
if (callback != null) {
- // block here - in effect, this will stop all commands from going out until the callback is done
- synchronized (m_needToCallInitializeCallback) {
- if (m_needToCallInitializeCallback[0]) {
- try {
- m_needToCallInitializeCallback[0] = !callback.sendingInitialCommand(this, command);
- LOG.debug(CommI18NResourceKeys.INITIALIZE_CALLBACK_DONE, m_needToCallInitializeCallback[0]);
- } catch (Throwable t) {
- m_needToCallInitializeCallback[0] = true; // callback failed, we'll want to call it again
- LOG.error(t, CommI18NResourceKeys.INITIALIZE_CALLBACK_FAILED, ThrowableUtil.getAllMessages(t));
- return new GenericCommandResponse(command, false, null, t);
+ // block here - in effect, this will stop all commands from going out until the callback is done
+ // to avoid infinite blocking, we'll only wait for a set time (though long).
+
+ WriteLock writeLock = m_needToCallInitializeCallbackLock.writeLock();
+ boolean locked;
+ try {
+ locked = writeLock.tryLock(m_initializeCallbackLockAcquisitionTimeoutMins, TimeUnit.MINUTES);
+ } catch (InterruptedException ie) {
+ locked = false;
+ }
+
+ if (locked) {
+ try {
+ if (m_needToCallInitializeCallback) {
+ try {
+ m_needToCallInitializeCallback = (!callback.sendingInitialCommand(this, command));
+ LOG.debug(CommI18NResourceKeys.INITIALIZE_CALLBACK_DONE, m_needToCallInitializeCallback);
+ } catch (Throwable t) {
+ m_needToCallInitializeCallback = true; // callback failed, we'll want to call it again
+ LOG.error(t, CommI18NResourceKeys.INITIALIZE_CALLBACK_FAILED, ThrowableUtil
+ .getAllMessages(t));
+ return new GenericCommandResponse(command, false, null, t);
+ }
}
+ } finally {
+ writeLock.unlock();
}
+ } else {
+ m_needToCallInitializeCallback = true; // can't invoke callback, we'll want to still call it later
+ Throwable t = new Throwable("Initialize callback lock could not be acquired");
+ LOG.error(CommI18NResourceKeys.INITIALIZE_CALLBACK_FAILED, t.getMessage());
+ return new GenericCommandResponse(command, false, null, t);
}
}
return null;
commit 55ba6f8778820bdd417e99909220136a2e1e091f
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Fri Feb 19 11:10:53 2010 -0500
BZ 566724 - if classloader fails to be created, master PC will skip the plugin
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java
index f46eaf5..bd4feac 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java
@@ -136,16 +136,23 @@ public class MasterServerPluginContainer {
String pluginName = descriptor.getName();
ServerPluginType pluginType = new ServerPluginType(descriptor);
PluginKey pluginKey = PluginKey.createServerPluginKey(pluginType.stringify(), pluginName);
- ClassLoader classLoader = this.classLoaderManager.obtainServerPluginClassLoader(pluginKey);
- log.debug("Pre-loading server plugin [" + pluginKey + "] from [" + pluginUrl
- + "] into its plugin container");
try {
- ServerPluginEnvironment env = new ServerPluginEnvironment(pluginUrl, classLoader, descriptor);
- boolean enabled = !allDisabledPlugins.contains(pluginKey);
- pc.loadPlugin(env, enabled);
- log.info("Preloaded server plugin [" + pluginKey.getPluginName() + "]");
+ ClassLoader classLoader = this.classLoaderManager.obtainServerPluginClassLoader(pluginKey);
+ log.debug("Pre-loading server plugin [" + pluginKey + "] from [" + pluginUrl
+ + "] into its plugin container");
+ try {
+ ServerPluginEnvironment env = new ServerPluginEnvironment(pluginUrl, classLoader,
+ descriptor);
+ boolean enabled = !allDisabledPlugins.contains(pluginKey);
+ pc.loadPlugin(env, enabled);
+ log.info("Preloaded server plugin [" + pluginName + "]");
+ } catch (Exception e) {
+ log.warn("Failed to preload server plugin [" + pluginName + "] from URL [" + pluginUrl
+ + "]", e);
+ }
} catch (Exception e) {
- log.warn("Failed to preload server plugin [" + pluginUrl + "]", e);
+ log.warn("Failed to preload server plugin [" + pluginName
+ + "]; cannot get its classloader from URL [ " + pluginUrl + "]", e);
}
} else {
log.warn("There is no server plugin container to support plugin: " + pluginUrl);
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginClassLoader.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginClassLoader.java
index 9f27ce9..fa26970 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginClassLoader.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginClassLoader.java
@@ -64,7 +64,7 @@ public class ServerPluginClassLoader extends URLClassLoader {
try {
unpackedDirectory = unpackEmbeddedJars(pluginJarName, pluginUrl, classpathUrlList, tmpDirectory);
} catch (Exception e) {
- throw new Exception("Failed to unpack embedded JARs within: " + pluginUrl);
+ throw new Exception("Failed to unpack embedded JARs within: " + pluginUrl, e);
}
}
}
commit 2ffc564d7ff69a427755fa374419bc5980e47f94
Author: Heiko W. Rupp <pilhuhn(a)fedorapeople.org>
Date: Fri Feb 19 13:37:36 2010 +0100
Fix link to definitions BZ 566004
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/listAlertHistory.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/listAlertHistory.xhtml
index b6e386c..fd09f82 100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/listAlertHistory.xhtml
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/listAlertHistory.xhtml
@@ -148,8 +148,7 @@
</onc:sortableColumnHeader>
</f:facet>
- <h:outputLink value="/alerts/Config.do">
- <f:param name="mode" value="viewRoles"/>
+ <h:outputLink value="/rhq/resource/alert/viewAlert.xhtml">
<f:param name="id" value="#{Resource.id}"/>
<f:param name="ad" value="#{item.alert.alertDefinition.id}"/>
<h:outputText value="#{item.alert.alertDefinition.name}" />
13 years, 9 months
[rhq] Branch 'search' - 40 commits - modules/core modules/enterprise modules/plugins
by Joseph Marques
modules/core/domain/src/main/java/org/rhq/core/domain/alert/AlertConditionCategory.java | 4
modules/core/domain/src/main/java/org/rhq/core/domain/criteria/Criteria.java | 17
modules/core/domain/src/main/java/org/rhq/core/domain/operation/OperationRequestStatus.java | 4
modules/core/domain/src/main/java/org/rhq/core/domain/resource/composite/DisambiguationReport.java | 2
modules/core/domain/src/main/java/org/rhq/core/domain/resource/group/composite/ResourceGroupComposite.java | 2
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/AlertConditionUIBean.java | 3
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/AlertConditionsUIBean.java | 71 +++
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/AlertMessages.java | 70 +++
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/CustomContentUIBean.java | 9
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/converter/MetricPercentConverter.java | 9
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/description/ControlDescriber.java | 7
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/validator/AlertValidatorUtil.java | 45 ++
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/validator/EventRegexValidator.java | 48 ++
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/AckAlertAction.java | 78 ++++
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/ReenableAlertDefinitionAction.java | 80 ++++
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/group/inventory/AddGroupResourcesFormPrepareAction.java | 5
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/subsystem/SubsystemAlertDefinitionUIBean.java | 4
modules/enterprise/gui/portal-war/src/main/webapp-filtered/WEB-INF/classes/ApplicationResources.properties | 4
modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/struts-config.xml | 14
modules/enterprise/gui/portal-war/src/main/webapp/common/RSSFormat.jsp | 7
modules/enterprise/gui/portal-war/src/main/webapp/resource/common/monitor/alerts/ViewAlertProperties.jsp | 49 +-
modules/enterprise/gui/portal-war/src/main/webapp/resource/common/monitor/alerts/config/AlertDefinitionActive.jsp | 10
modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/listAlertTemplates.xhtml | 31 -
modules/enterprise/gui/portal-war/src/main/webapp/rhq/group/alert/listGroupAlertDefinitions.xhtml | 25 -
modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/alertDefinitionProperties.xhtml | 10
modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/listAlertDefinitions.xhtml | 32 -
modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/listConditions.xhtml | 174 +++++++--
modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/viewAlert.xhtml | 77 +++-
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertManagerBean.java | 13
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java | 13
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/CustomAlertSenderBackingBean.java | 30 +
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java | 173 +++++----
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java | 8
modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsBackingBean.java | 168 ++++++++-
modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsSender.java | 81 ++++
modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/Token.java | 72 ++++
modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/TokenClass.java | 59 +++
modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/TokenReplacer.java | 178 ++++++++++
modules/enterprise/server/plugins/alert-operations/src/main/resources/operations.xhtml | 47 +-
modules/enterprise/server/plugins/alert-operations/src/test/java/org/rhq/enterprise/server/plugins/alertOperations/TokenReplacementTest.java | 135 +++++++
modules/plugins/netservices/pom.xml | 18 -
41 files changed, 1600 insertions(+), 286 deletions(-)
New commits:
commit d0ef49e101ef7887e834b0a9021c0c0654a7f5d5
Merge: 613b993... 8a0951a...
Author: Joseph Marques <joseph(a)redhat.com>
Date: Fri Feb 26 15:34:50 2010 -0500
Merge branch 'master' into search
commit 8a0951a835997a2cdc75d2cf9840a7a7fdf59c15
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Feb 26 17:57:56 2010 +0100
BZ 568544 - disambiguation doesn't get confused if more than one item in the provided results corresponds to a signle resource.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/composite/DisambiguationReport.java b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/composite/DisambiguationReport.java
index 67f3276..dd359da 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/composite/DisambiguationReport.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/composite/DisambiguationReport.java
@@ -64,6 +64,6 @@ public class DisambiguationReport<T> implements Serializable {
}
public String toString() {
- return "DisambiguationReport(type=" + resourceTypeName + ", plugin=" + resourceTypePluginName + ", parents=" + parents + ")";
+ return "DisambiguationReport(type=" + resourceTypeName + ", plugin=" + resourceTypePluginName + ", parents=" + parents + ", original=" + original + ")";
}
}
\ No newline at end of file
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
index 3af7a35..e5684d2 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
@@ -31,6 +31,7 @@ import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
+import java.util.Set;
import javax.ejb.EJB;
import javax.ejb.Stateless;
@@ -2170,34 +2171,36 @@ public class ResourceManagerBean implements ResourceManagerLocal, ResourceManage
false);
}
- //this will contain the disambiguated results
- List<DisambiguationReport<T>> resolution = new ArrayList<DisambiguationReport<T>>(results.size());
boolean typeResolutionNeeded = false;
boolean pluginResolutionNeeded = false;
boolean parentResolutionNeeded = false;
//we can't assume the ordering of the provided results and the disambiguation query results
- //will be the same, hence this map.
- Map<Integer, MutableDisambiguationReport<T>> reportByResourceId = new HashMap<Integer, MutableDisambiguationReport<T>>();
+ //will be the same.
+
+ //this list contains the resulting reports in the same order as the original results
+ List<MutableDisambiguationReport<T>> reports = new ArrayList<MutableDisambiguationReport<T>>(results.size());
+
+ //this maps the reports to resourceIds. More than one report can correspond to a single
+ //resource id. The reports in this map are the same instances as in the reports list.
+ Map<Integer, List<MutableDisambiguationReport<T>>> reportsByResourceId = new HashMap<Integer, List<MutableDisambiguationReport<T>>>();
for (T r : results) {
MutableDisambiguationReport<T> value = new MutableDisambiguationReport<T>();
value.original = r;
int resourceId = extractor.extract(r);
if (resourceId > 0) {
- reportByResourceId.put(resourceId, value);
+ List<MutableDisambiguationReport<T>> correspondingResults = reportsByResourceId.get(resourceId);
+ if (correspondingResults == null) {
+ correspondingResults = new ArrayList<MutableDisambiguationReport<T>>();
+ reportsByResourceId.put(resourceId, correspondingResults);
+ }
+ correspondingResults.add(value);
}
+ reports.add(value);
}
//check that we still have something to disambiguate
- if (reportByResourceId.isEmpty()) {
- //no, we don't. construct the resolution only using the results.
-
- for (T result : results) {
- DisambiguationReport<T> report = new DisambiguationReport<T>(result, Collections
- .<ResourceParentFlyweight> emptyList(), null, null);
- resolution.add(report);
- }
- } else {
+ if (reportsByResourceId.size() > 0) {
//first find out how many ancestors we are going to require to disambiguate the resuls
String query = Resource.NATIVE_QUERY_FIND_DISAMBIGUATION_LEVEL;
@@ -2247,7 +2250,7 @@ public class ResourceManagerBean implements ResourceManagerLocal, ResourceManage
Query parentsQuery = entityManager.createQuery(selectBuilder.append(" ").append(fromBuilder).toString());
- parentsQuery.setParameter("resourceIds", reportByResourceId.keySet());
+ parentsQuery.setParameter("resourceIds", reportsByResourceId.keySet());
@SuppressWarnings("unchecked")
List<Object[]> parentsResults = (List<Object[]>) parentsQuery.getResultList();
@@ -2264,28 +2267,22 @@ public class ResourceManagerBean implements ResourceManagerLocal, ResourceManage
String parentName = (String) parentsResult[2 * i + 2];
parents.add(new ResourceParentFlyweight(parentId, parentName));
}
- MutableDisambiguationReport<T> report = reportByResourceId.get(resourceId);
- report.typeName = typeName;
- report.pluginName = pluginName;
- report.parents = parents;
- }
-
- //now we have all the information to create the result.
- for (T result : results) {
- int resourceId = extractor.extract(result);
- if (resourceId > 0) {
- //this results was disambiguated by the query above...
- MutableDisambiguationReport<T> report = reportByResourceId.get(resourceId);
- resolution.add(report.getReport());
- } else {
- //this result doesn't correspond to any resource, need to handle it specially
- DisambiguationReport<T> report = new DisambiguationReport<T>(result, Collections
- .<ResourceParentFlyweight> emptyList(), null, null);
- resolution.add(report);
+
+ //update all the reports that correspond to this resourceId
+ for(MutableDisambiguationReport<T> report : reportsByResourceId.get(resourceId)) {
+ report.typeName = typeName;
+ report.pluginName = pluginName;
+ report.parents = parents;
}
}
}
+ List<DisambiguationReport<T>> resolution = new ArrayList<DisambiguationReport<T>>(results.size());
+
+ for (MutableDisambiguationReport<T> report : reports) {
+ resolution.add(report.getReport());
+ }
+
return new ResourceNamesDisambiguationResult<T>(resolution, typeResolutionNeeded, parentResolutionNeeded,
pluginResolutionNeeded);
}
@@ -2297,7 +2294,8 @@ public class ResourceManagerBean implements ResourceManagerLocal, ResourceManage
public List<ResourceParentFlyweight> parents;
public DisambiguationReport<T> getReport() {
- return new DisambiguationReport<T>(original, parents, typeName, pluginName);
+ return new DisambiguationReport<T>(original, parents == null ? Collections
+ .<ResourceParentFlyweight> emptyList() : parents, typeName, pluginName);
}
}
}
commit b2f7c0e76fc8bd366bb58bda3250b75cf6f7ecca
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Feb 26 12:51:53 2010 +0100
BZ 565626 - fixing the URL query string for groups used in menu search.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/group/composite/ResourceGroupComposite.java b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/group/composite/ResourceGroupComposite.java
index a5bd861..6a837c9 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/group/composite/ResourceGroupComposite.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/group/composite/ResourceGroupComposite.java
@@ -164,7 +164,7 @@ public class ResourceGroupComposite implements Serializable {
* @return query string snippet that can appear after the "?" in group URLs.
*/
public String getGroupQueryString() {
- return "category=" + getCategory().getName() + "&groupId=" + getResourceGroup().getId();
+ return "groupId=" + getResourceGroup().getId();
}
private String getAlignedAvailabilityResults(long up, long down) {
commit f3d2b483a01c8771e106c407f4af8473bb1e61fb
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Thu Feb 25 17:11:43 2010 +0100
BZ 535432 suppress 'null' is the condition has no name, which is the case for availability.
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 c21bf21..0f48f9e 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
@@ -907,7 +907,8 @@ public class AlertManagerBean implements AlertManagerLocal, AlertManagerRemote {
builder.append(condition.getName()).append(' ');
}
} else {
- builder.append(condition.getName()).append(' ');
+ if (category.getName()!=null) // this is null for e.g. availability
+ builder.append(condition.getName()).append(' ');
}
// next format the RHS
commit 95ab39239a9d3d2f4081a49c8edcdc51acdacbfc
Merge: c8338b8... 3705350...
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Thu Feb 25 14:31:21 2010 +0100
Merge branch 'master' into alertPlugin
commit 37053500c05ec42b23740e4612899f2c56a21864
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Thu Feb 25 11:27:51 2010 +0100
BZ 568275 - add commons-codec which is needed with commons-httpclient 3
diff --git a/modules/plugins/netservices/pom.xml b/modules/plugins/netservices/pom.xml
index 58087fa..06ae2ae 100644
--- a/modules/plugins/netservices/pom.xml
+++ b/modules/plugins/netservices/pom.xml
@@ -33,6 +33,11 @@
<artifactId>commons-httpclient</artifactId>
<version>3.0.1</version>
</dependency>
+ <dependency>
+ <groupId>commons-codec</groupId>
+ <artifactId>commons-codec</artifactId>
+ <version>1.2</version>
+ </dependency>
</dependencies>
@@ -58,6 +63,11 @@
<artifactId>commons-httpclient</artifactId>
<version>3.0.1</version>
</artifactItem>
+ <artifactItem>
+ <groupId>commons-codec</groupId>
+ <artifactId>commons-codec</artifactId>
+ <version>1.2</version>
+ </artifactItem>
</artifactItems>
<outputDirectory>${project.build.outputDirectory}/lib</outputDirectory>
</configuration>
@@ -202,13 +212,13 @@
<id>deploy-jar-meta-inf</id>
<phase>package</phase>
<configuration>
- <tasks>
- <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" />
+ <tasks>
+ <property name="deployment.file" location="${rhq.deploymentDir}/${project.build.finalName}.jar" />
<echo>*** Updating META-INF dir in ${deployment.file}...</echo>
<unjar src="${project.build.directory}/${project.build.finalName}.jar" dest="${project.build.outputDirectory}">
<patternset><include name="META-INF/**" /></patternset>
</unjar>
- <jar destfile="${deployment.file}" manifest="${project.build.outputDirectory}/META-INF/MANIFEST.MF" update="true">
+ <jar destfile="${deployment.file}" manifest="${project.build.outputDirectory}/META-INF/MANIFEST.MF" update="true">
</jar>
</tasks>
</configuration>
@@ -216,7 +226,7 @@
<goal>run</goal>
</goals>
</execution>
-
+
<execution>
<id>undeploy</id>
<phase>clean</phase>
commit b32fab5ccf90e3f6bc5c9c16e78daeb069f62675
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Thu Feb 25 10:59:56 2010 +0100
Persisting a new resource is no error ...
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
index 6755733..3af7a35 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
@@ -188,7 +188,7 @@ public class ResourceManagerBean implements ResourceManagerLocal, ResourceManage
}
entityManager.persist(resource);
- log.error("********* resource persisted ************");
+ log.debug("********* resource persisted ************");
// Execute sub-methods as overlord to bypass additional security checks.
Subject overlord = this.subjectManager.getOverlord();
updateImplicitMembership(overlord, resource);
@@ -366,7 +366,7 @@ public class ResourceManagerBean implements ResourceManagerLocal, ResourceManage
PluginConfigurationUpdate.QUERY_DELETE_BY_RESOURCES_0,
PluginConfigurationUpdate.QUERY_DELETE_BY_RESOURCES_1, // first delete the config objects
PluginConfigurationUpdate.QUERY_DELETE_BY_RESOURCES_2, // then the history objects wrapping those configs
- AlertConditionLog.QUERY_DELETE_BY_RESOURCES, // Don't
+ AlertConditionLog.QUERY_DELETE_BY_RESOURCES, // Don't
AlertNotificationLog.QUERY_DELETE_BY_RESOURCES, // alter
Alert.QUERY_DELETE_BY_RESOURCES, // order
AlertCondition.QUERY_DELETE_BY_RESOURCES, // of
@@ -2134,7 +2134,7 @@ public class ResourceManagerBean implements ResourceManagerLocal, ResourceManage
parent = null;
break;
}
-
+
} while (parent != null);
if (resource != null) {
if (!authorizationManager.canViewResource(subject, resource.getId())) {
@@ -2164,7 +2164,7 @@ public class ResourceManagerBean implements ResourceManagerLocal, ResourceManage
public <T> ResourceNamesDisambiguationResult<T> disambiguate(List<T> results, boolean alwaysIncludeParent,
IntExtractor<? super T> extractor) {
-
+
if (results.isEmpty()) {
return new ResourceNamesDisambiguationResult<T>(new ArrayList<DisambiguationReport<T>>(), false, false,
false);
commit c8338b898b50fbfe86e07d4c25cba30deb9c3139
Merge: a99099e... 4714eb8...
Author: Justin Harris <jharris(a)redhat.com>
Date: Wed Feb 24 12:24:53 2010 -0500
Merge remote branch 'origin/alertPlugin' into bugz
commit 810993311fa5e22495be1eb9cfebb154a0e3a3ef
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Wed Feb 24 12:21:24 2010 -0500
don't bother looping/logging if debug not enabled.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/Criteria.java b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/Criteria.java
index ef27906..dd943e0 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/Criteria.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/criteria/Criteria.java
@@ -125,8 +125,11 @@ public abstract class Criteria implements Serializable {
results.put(getCleansedFieldName(filterField, 6), filterFieldValue);
}
}
- for (Map.Entry<String, Object> entries : results.entrySet()) {
- LOG.debug("Filter: (" + entries.getKey() + ", " + entries.getValue() + ")");
+
+ if (LOG.isDebugEnabled()) {
+ for (Map.Entry<String, Object> entries : results.entrySet()) {
+ LOG.debug("Filter: (" + entries.getKey() + ", " + entries.getValue() + ")");
+ }
}
return results;
}
@@ -160,8 +163,10 @@ public abstract class Criteria implements Serializable {
}
}
}
- for (String entry : results) {
- LOG.debug("Fetch: (" + entry + ")");
+ if (LOG.isDebugEnabled()) {
+ for (String entry : results) {
+ LOG.debug("Fetch: (" + entry + ")");
+ }
}
return results;
}
@@ -283,7 +288,9 @@ public abstract class Criteria implements Serializable {
}
}
}
- LOG.debug("Page Control: " + pc);
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Page Control: " + pc);
+ }
return pc;
}
commit a99099ea48d165b4a272949d2fce9e2815a3b061
Author: Justin Harris <jharris(a)redhat.com>
Date: Wed Feb 24 12:21:04 2010 -0500
Fix for BZ 561900
Adding in length and null value validation for alert definition names.
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/AlertConditionMessages.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/AlertConditionMessages.java
deleted file mode 100644
index 62a6fc0..0000000
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/AlertConditionMessages.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * RHQ Management Platform
- * Copyright (C) 2005-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 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.MessageFormat;
-import java.util.Map;
-import org.jboss.seam.ScopeType;
-import org.jboss.seam.annotations.In;
-import org.jboss.seam.annotations.Name;
-import org.jboss.seam.annotations.Scope;
-
-(a)Scope(ScopeType.APPLICATION)
-@Name("alertConditionMessages")
-public class AlertConditionMessages {
-
- @In
- private Map<String, String> messages;
-
- public String getThreshold() {
- return translate("errors.double", "Threshold");
- }
-
- public String getPercentRange() {
- return translate("errors.range", "Threshold", "0%", "1000%");
- }
-
- public String getDampeningCount() {
- return translate("errors.integer", "Dampening Count");
- }
-
- public String getDampeningEvaluation() {
- return translate("errors.integer", "Dampening Evaluations");
- }
-
- public String getTimePeriod() {
- return translate("errors.integer", "Time Period");
- }
-
- private String translate(String key, Object... params) {
- String message = messages.get(key);
-
- return MessageFormat.format(message, params);
- }
-}
\ No newline at end of file
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/AlertMessages.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/AlertMessages.java
new file mode 100644
index 0000000..79062ef
--- /dev/null
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/AlertMessages.java
@@ -0,0 +1,70 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-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 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.MessageFormat;
+import java.util.Map;
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.In;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+
+(a)Scope(ScopeType.APPLICATION)
+@Name("alertMessages")
+public class AlertMessages {
+
+ @In
+ private Map<String, String> messages;
+
+ public String getNameRequired() {
+ String name = translate("alerts.config.DefinitionList.ListHeader.AlertName");
+ return translate("errors.required", name);
+ }
+
+ public String getNameLength() {
+ String name = translate("alerts.config.DefinitionList.ListHeader.AlertName");
+ return translate("errors.maxlength", name);
+ }
+
+ public String getThreshold() {
+ return translate("errors.double", "Threshold");
+ }
+
+ public String getPercentRange() {
+ return translate("errors.range", "Threshold", "0%", "1000%");
+ }
+
+ public String getDampeningCount() {
+ return translate("errors.integer", "Dampening Count");
+ }
+
+ public String getDampeningEvaluation() {
+ return translate("errors.integer", "Dampening Evaluations");
+ }
+
+ public String getTimePeriod() {
+ return translate("errors.integer", "Time Period");
+ }
+
+ private String translate(String key, Object... params) {
+ String message = messages.get(key);
+
+ return MessageFormat.format(message, params);
+ }
+}
\ No newline at end of file
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/alertDefinitionProperties.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/alertDefinitionProperties.xhtml
index 9439c5f..fd8e260 100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/alertDefinitionProperties.xhtml
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/alertDefinitionProperties.xhtml
@@ -17,7 +17,15 @@
<h:panelGrid columns="2" border="1" cellpadding="5" style="margin: 15px;">
<h:outputLabel for="alertNameInput" value="Name: " />
- <h:inputText id="alertNameInput" value="#{alertDefinition.name}" style="width: 300px;" />
+ <h:inputText id="alertNameInput"
+ value="#{alertDefinition.name}"
+ style="width: 300px;"
+ maxlength="100"
+ required="true"
+ requiredMessage="#{alertMessages.nameRequired}"
+ validatorMessage="#{alertMessages.nameLength}">
+ <f:validateLength maximum="100" />
+ </h:inputText>
<h:outputLabel for="alertDescriptionInput" value="Description: " />
<h:inputTextarea id="alertDescriptionInput" value="#{alertDefinition.description}" style="width: 300px;" />
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/listConditions.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/listConditions.xhtml
index a5500e4..2000efd 100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/listConditions.xhtml
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/listConditions.xhtml
@@ -170,9 +170,9 @@
value="#{alertDefinition.alertDampening.value}"
size="4"
required="true"
- requiredMessage="#{alertConditionMessages.dampeningCount}"
- validatorMessage="#{alertConditionMessages.dampeningCount}"
- converterMessage="#{alertConditionMessages.dampeningCount}">
+ requiredMessage="#{alertMessages.dampeningCount}"
+ validatorMessage="#{alertMessages.dampeningCount}"
+ converterMessage="#{alertMessages.dampeningCount}">
<f:validateDoubleRange minimum="0" />
</h:inputText>
<h:outputText value=" #{messages['alert.config.props.CB.Content.DampenConsecutiveCount.2']}" />
@@ -184,9 +184,9 @@
value="#{alertDefinition.alertDampening.value}"
size="4"
required="true"
- requiredMessage="#{alertConditionMessages.dampeningCount}"
- validatorMessage="#{alertConditionMessages.dampeningCount}"
- converterMessage="#{alertConditionMessages.dampeningCount}">
+ requiredMessage="#{alertMessages.dampeningCount}"
+ validatorMessage="#{alertMessages.dampeningCount}"
+ converterMessage="#{alertMessages.dampeningCount}">
<f:validateLongRange minimum="0" />
</h:inputText>
<h:outputText value=" #{messages['alert.config.props.CB.Content.DampenPartialCount.2']} " />
@@ -194,9 +194,9 @@
value="#{alertDefinition.alertDampening.period}"
size="4"
required="true"
- requiredMessage="#{alertConditionMessages.dampeningEvaluation}"
- validatorMessage="#{alertConditionMessages.dampeningEvaluation}"
- converterMessage="#{alertConditionMessages.dampeningEvaluation}">
+ requiredMessage="#{alertMessages.dampeningEvaluation}"
+ validatorMessage="#{alertMessages.dampeningEvaluation}"
+ converterMessage="#{alertMessages.dampeningEvaluation}">
<f:validateLongRange minimum="0" />
</h:inputText>
<h:outputText value=" #{messages['alert.config.props.CB.Content.DampenPartialCount.3']}" />
@@ -208,9 +208,9 @@
value="#{alertDefinition.alertDampening.value}"
size="4"
required="true"
- requiredMessage="#{alertConditionMessages.dampeningCount}"
- validatorMessage="#{alertConditionMessages.dampeningCount}"
- converterMessage="#{alertConditionMessages.dampeningCount}">
+ requiredMessage="#{alertMessages.dampeningCount}"
+ validatorMessage="#{alertMessages.dampeningCount}"
+ converterMessage="#{alertMessages.dampeningCount}">
<f:validateLongRange minimum="0" />
</h:inputText>
<h:outputText value=" #{messages['alert.config.props.CB.Content.DampenDurationCount.2']} " />
@@ -218,9 +218,9 @@
value="#{alertDefinition.alertDampening.period}"
size="4"
required="true"
- requiredMessage="#{alertConditionMessages.timePeriod}"
- validatorMessage="#{alertConditionMessages.timePeriod}"
- converterMessage="#{alertConditionMessages.timePeriod}">
+ requiredMessage="#{alertMessages.timePeriod}"
+ validatorMessage="#{alertMessages.timePeriod}"
+ converterMessage="#{alertMessages.timePeriod}">
<f:validateLongRange minimum="0" />
</h:inputText>
<h:selectOneMenu value="#{alertDefinition.alertDampening.periodUnits}">
@@ -341,8 +341,8 @@
<h:inputText id="metricThresholdAbsolute"
value="#{alertConditionsUIBean.threshold}"
required="true"
- requiredMessage="#{alertConditionMessages.threshold}"
- validatorMessage="#{alertConditionMessages.threshold}">
+ requiredMessage="#{alertMessages.threshold}"
+ validatorMessage="#{alertMessages.threshold}">
<f:validateDoubleRange minimum="0.0" />
</h:inputText>
<h:outputLabel for="metricThresholdAbsolute" value="#{messages['alert.config.props.CB.Content.AbsoluteValue']}" />
@@ -371,8 +371,8 @@
value="#{alertConditionsUIBean.currentCondition.threshold}"
converter="#{metricPercentConverter}"
required="true"
- requiredMessage="#{alertConditionMessages.percentRange}"
- validatorMessage="#{alertConditionMessages.percentRange}">
+ requiredMessage="#{alertMessages.percentRange}"
+ validatorMessage="#{alertMessages.percentRange}">
<f:validateDoubleRange minimum="0.0" maximum="1000.0" />
</h:inputText>
<h:outputLabel for="metricBaselinePercent" value=" #{messages['alert.config.props.CB.Content.Percent']} " />
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/viewAlert.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/viewAlert.xhtml
index a987e65..dd349a1 100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/viewAlert.xhtml
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/viewAlert.xhtml
@@ -77,8 +77,7 @@
</ui:define>
<ui:define name="body">
- <h:messages showDetail="true"
- globalOnly="true"
+ <h:messages showSummary="true"
infoClass="InfoBlock"
warnClass="WarnBlock"
errorClass="ErrorBlock"
commit 4714eb87aeeb6dce6a6ebcb7573bc80dafa3928d
Merge: e25997a... 7f4d769...
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Wed Feb 24 18:19:46 2010 +0100
Merge branch 'master' into alertPlugin
commit 7f4d76951a1e2686aa4d104477765d9b4d350dad
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Feb 24 18:13:05 2010 +0100
BZ 566749 - fixing the NPE when adding platforms (that don't have a parent) to a resource group.
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/group/inventory/AddGroupResourcesFormPrepareAction.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/group/inventory/AddGroupResourcesFormPrepareAction.java
index 698cb5a..808f331 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/group/inventory/AddGroupResourcesFormPrepareAction.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/group/inventory/AddGroupResourcesFormPrepareAction.java
@@ -201,7 +201,10 @@ public class AddGroupResourcesFormPrepareAction extends Action {
Resource resource = dr.getOriginal();
Resource parent = resource.getParentResource();
- parent.setName(buildLineage(dr.getParents()));
+ //platforms don't have parents, need to check for null here
+ if (parent != null) {
+ parent.setName(buildLineage(dr.getParents()));
+ }
convertedResults.add(resource);
}
commit 38fb361e5cdb167bb5a947596586194d941e4221
Author: Justin Harris <jharris(a)redhat.com>
Date: Wed Feb 24 10:55:35 2010 -0500
Fix for BZ 567375
Changed method of resource id lookup in control describer.
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/description/ControlDescriber.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/description/ControlDescriber.java
index bcf5d25..ab1bd8a 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/description/ControlDescriber.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/description/ControlDescriber.java
@@ -18,9 +18,11 @@
*/
package org.rhq.enterprise.gui.alert.description;
+import org.jboss.seam.Component;
import org.rhq.core.domain.alert.AlertCondition;
import org.rhq.core.domain.alert.AlertConditionCategory;
import org.rhq.core.domain.operation.OperationDefinition;
+import org.rhq.core.domain.resource.ResourceType;
import org.rhq.enterprise.server.operation.OperationManagerLocal;
import org.rhq.enterprise.server.util.LookupUtil;
@@ -53,12 +55,13 @@ public class ControlDescriber extends AlertConditionDescriber {
private OperationDefinition getDefinition(AlertCondition condition) {
OperationManagerLocal operationManager = LookupUtil.getOperationManager();
- Integer resourceTypeId = condition.getAlertDefinition().getResource().getResourceType().getId();
+ // this is not a seam component, so look it up in the component contexts
+ ResourceType resourceType = (ResourceType)Component.getInstance("resourceType");
String operationName = condition.getName();
try {
return operationManager.getOperationDefinitionByResourceTypeAndName(
- resourceTypeId, operationName, false);
+ resourceType.getId(), operationName, false);
} catch (Exception e) {
return null;
}
commit e25997a61a0e49e38768d20461afffb9d19a554e
Merge: 33e3625... 1e8ab54...
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Wed Feb 24 16:53:45 2010 +0100
Merge branch 'master' into alertPlugin
commit 33e3625f6e4383d2bf44e832452347fc08241b97
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Wed Feb 24 16:33:43 2010 +0100
Linking fixes for BZ 566896
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/group/alert/listGroupAlertDefinitions.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/group/alert/listGroupAlertDefinitions.xhtml
index 2e5a565..5768c23 100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/group/alert/listGroupAlertDefinitions.xhtml
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/group/alert/listGroupAlertDefinitions.xhtml
@@ -18,10 +18,10 @@
<ui:param name="pageTitle" value="List Alert Definitions for Group '#{ResourceGroupUIBean.name}'"/>
<ui:param name="selectedTabName" value="Alert.Definitions"/>
<ui:define name="content">
-
+
<h:form id="alertDefinitionsListForm">
<input type="hidden" name="groupId" value="${param.groupId}"/>
-
+
<rich:panel styleClass="BlockContent">
<f:facet name="header">
<h:outputText value="Alert Definitions"/>
@@ -48,12 +48,12 @@
<f:facet name="PageControlView">
<onc:paginationControl id="GroupAlertDefinitionsList" />
</f:facet>
-
+
<rich:column>
<f:facet name="header">
<onc:allSelect target="selectedAlertDefinitions" />
</f:facet>
-
+
<onc:select name="selectedAlertDefinitions" value="#{item.id}" />
</rich:column>
@@ -63,25 +63,24 @@
<h:outputText styleClass="headerText" value="Name" />
</onc:sortableColumnHeader>
</f:facet>
-
- <h:outputLink value="/alerts/Config.do">
- <f:param name="mode" value="viewRoles"/>
+
+ <h:outputLink value="/rhq/resource/alert/viewAlert.xhtml">
<f:param name="groupId" value="#{param.groupId}"/>
<f:param name="ad" value="#{item.id}"/>
<h:outputText value="#{item.name}" />
</h:outputLink>
</rich:column>
-
+
<rich:column>
<f:facet name="header">
<onc:sortableColumnHeader sort="a.description">
<h:outputText styleClass="headerText" value="Description" />
</onc:sortableColumnHeader>
</f:facet>
-
+
<h:outputText value="#{item.description}"/>
</rich:column>
-
+
<rich:column>
<f:facet name="header">
<onc:sortableColumnHeader sort="a.ctime">
@@ -93,14 +92,14 @@
<f:converter converterId="UserDateTimeConverter" />
</h:outputText>
</rich:column>
-
+
<rich:column>
<f:facet name="header">
<onc:sortableColumnHeader sort="a.enabled">
<h:outputText styleClass="headerText" value="Active" />
</onc:sortableColumnHeader>
</f:facet>
-
+
<h:outputText value="#{item.enabled}"/>
</rich:column>
@@ -134,7 +133,7 @@
</rich:dataTable>
</h:panelGrid>
-
+
</rich:panel>
</h:form>
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/listAlertDefinitions.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/listAlertDefinitions.xhtml
index 708f559..ef13121 100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/listAlertDefinitions.xhtml
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/listAlertDefinitions.xhtml
@@ -18,10 +18,10 @@
<ui:param name="pageTitle" value="List Alert Definitions for Resource '#{ResourceUIBean.name}'"/>
<ui:param name="selectedTabName" value="Alert.Definitions"/>
<ui:define name="content">
-
+
<h:form id="alertDefinitionsListForm">
<input type="hidden" name="id" value="${param.id}"/>
-
+
<rich:panel styleClass="BlockContent">
<f:facet name="header">
<h:outputText value="Alert Definitions"/>
@@ -48,12 +48,12 @@
<f:facet name="PageControlView">
<onc:paginationControl id="AlertDefinitionsList" />
</f:facet>
-
+
<rich:column>
<f:facet name="header">
<onc:allSelect target="selectedAlertDefinitions" />
</f:facet>
-
+
<onc:select name="selectedAlertDefinitions" value="#{item.id}" />
</rich:column>
@@ -63,24 +63,24 @@
<h:outputText styleClass="headerText" value="Name" />
</onc:sortableColumnHeader>
</f:facet>
-
+
<h:outputLink value="/rhq/resource/alert/viewAlert.xhtml">
<f:param name="id" value="#{Resource.id}"/>
<f:param name="ad" value="#{item.id}"/>
<h:outputText value="#{item.name}" />
</h:outputLink>
</rich:column>
-
+
<rich:column>
<f:facet name="header">
<onc:sortableColumnHeader sort="a.description">
<h:outputText styleClass="headerText" value="Description" />
</onc:sortableColumnHeader>
</f:facet>
-
+
<h:outputText value="#{item.description}"/>
</rich:column>
-
+
<rich:column>
<f:facet name="header">
<onc:sortableColumnHeader sort="a.ctime">
@@ -92,14 +92,14 @@
<f:converter converterId="UserDateTimeConverter" />
</h:outputText>
</rich:column>
-
+
<rich:column>
<f:facet name="header">
<onc:sortableColumnHeader sort="a.enabled">
<h:outputText styleClass="headerText" value="Active" />
</onc:sortableColumnHeader>
</f:facet>
-
+
<h:outputText value="#{item.enabled}"/>
</rich:column>
@@ -107,15 +107,13 @@
<f:facet name="header">
<h:outputText styleClass="headerText" value="Parent" />
</f:facet>
-
- <h:outputLink value="/alerts/Config.do" rendered="#{item.parentId ne 0}">
- <f:param name="mode" value="viewRoles"/>
+
+ <h:outputLink value="http://localhost:7080/rhq/resource/alert/viewAlert.xhtml" rendered="#{item.parentId ne 0}">
<f:param name="type" value="#{item.resource.resourceType.id}"/>
- <f:param name="from" value="#{item.id}"/>
<f:param name="ad" value="#{item.parentId}"/>
<h:outputText value="View Template" />
</h:outputLink>
-
+
<h:outputLink value="/alerts/Config.do" rendered="#{not empty item.groupAlertDefinition}">
<f:param name="mode" value="viewRoles"/>
<f:param name="groupId" value="#{item.groupAlertDefinition.resourceGroup.id}"/>
@@ -129,7 +127,7 @@
<f:facet name="header">
<h:outputText styleClass="headerText" value="Read Only" />
</f:facet>
-
+
<h:outputText value="N/A" rendered="#{item.parentId eq 0 and empty item.groupAlertDefinition}"/>
<h:outputText value="#{item.readOnly}" rendered="#{item.parentId ne 0 or not empty item.groupAlertDefinition}"/>
</rich:column>
@@ -167,7 +165,7 @@
</rich:dataTable>
</h:panelGrid>
-
+
</rich:panel>
</h:form>
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/viewAlert.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/viewAlert.xhtml
index a987e65..75a1d50 100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/viewAlert.xhtml
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/viewAlert.xhtml
@@ -19,6 +19,9 @@
<c:when test="#{not empty param.type}">
<c:set var="title" value="Definition for '#{alertDefinition.name}' on resource type '#{ResourceTypeUIBean.name}'"/>
</c:when>
+ <c:when test="#{not empty param.groupId}">
+ <c:set var="title" value="Definition for '#{alertDefinition.name}' on group '#{ResourceGroupUIBean.name}'"/>
+ </c:when>
<c:otherwise>
<c:set var="title" value="Definition for '#{alertDefinition.name}' on resource '#{alertDefinition.resource.name}'"/>
</c:otherwise>
@@ -55,18 +58,25 @@
<h:outputText>Alert Definitions</h:outputText>
</h:outputLink>
<h:outputText> > </h:outputText>
- <h:outputLink value="viewAlert.xhtml">
- <f:param name="ad" value="#{alertDefinition.id}" />
- <h:outputText value=" Definition for '#{alertDefinition.name}' "/>
- </h:outputLink>
<c:choose>
<c:when test="#{not empty param.type}">
- <h:outputText> on resource type </h:outputText>
+ <h:outputText value=" Definition for alert template '#{alertDefinition.name}' "/>
+ <h:outputText> on Resource Type </h:outputText>
<h:outputLink value="/rhq/admin/listAlertTemplates.xhtml?type=${param.type}">
<h:outputText value=" #{ResourceTypeUIBean.name}"/>
</h:outputLink>
</c:when>
+ <c:when test="#{not empty param.groupId}">
+ <h:outputText> on resource group </h:outputText>
+ <h:outputLink value="/rhq/group/alert/listGroupAlertDefinitions.xhtml?groupId=${param.groupId}">
+ <h:outputText value=" #{ResourceGroupUIBean.name}"/>
+ </h:outputLink>
+ </c:when>
<c:otherwise>
+ <h:outputLink value="viewAlert.xhtml">
+ <f:param name="ad" value="#{alertDefinition.id}" />
+ <h:outputText value=" Definition for '#{alertDefinition.name}' "/>
+ </h:outputLink>
<h:outputText> on resource </h:outputText>
<h:outputLink value="/rhq/resource/summary/overview.xhtml">
<f:param name="id" value="#{alertDefinition.resource.id}" />
@@ -196,6 +206,11 @@
<h:outputText value="Back to Alert Definitions for Resource Type '#{ResourceTypeUIBean.name}'"/>
</h:outputLink>
</c:when>
+ <c:when test="#{not empty param.groupId}">
+ <h:outputLink value="/rhq/group/alert/listGroupAlertDefinitions.xhtml?groupId=${param.groupId}">
+ <h:outputText value="Back to Alert Definitions for Resource Group '#{ResourceGroupUIBean.name}'"/>
+ </h:outputLink>
+ </c:when>
<c:otherwise>
<h:outputLink value="/rhq/resource/alert/listAlertDefinitions.xhtml">
<f:param name="id" value="#{alertDefinition.resource.id}"/>
commit 1e8ab544201de380a8911b2fa88701c4b9b1a206
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Feb 24 15:33:18 2010 +0100
BZ 567925 - Restructured the ResourceManagerBean.disambiguate() method to handle (hopefully) all the corner cases resulting from the fact that not all of the provided results have to be mappable to a resource.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
index b0db81c..6755733 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
@@ -2162,45 +2162,23 @@ public class ResourceManagerBean implements ResourceManagerLocal, ResourceManage
return (findChildResources(subject, parentResource, pageControl));
}
- public <T> ResourceNamesDisambiguationResult<T> disambiguate(List<T> results, boolean alwaysIncludeParent, IntExtractor<? super T> extractor) {
- if (results.isEmpty()) {
- return new ResourceNamesDisambiguationResult<T>(new ArrayList<DisambiguationReport<T>>(), false, false, false);
- }
+ public <T> ResourceNamesDisambiguationResult<T> disambiguate(List<T> results, boolean alwaysIncludeParent,
+ IntExtractor<? super T> extractor) {
- String query = Resource.NATIVE_QUERY_FIND_DISAMBIGUATION_LEVEL;
-
- query = JDBCUtil.transformQueryForMultipleInParameters(query, "@@RESOURCE_IDS@@", results.size());
- Query disambiguateQuery = entityManager.createNativeQuery(query);
- int i = 1;
- for (T r : results) {
- disambiguateQuery.setParameter(i++, extractor.extract(r));
- }
-
- Object[] rs = (Object[]) disambiguateQuery.getSingleResult();
-
- int disambiguationLevel = Resource.MAX_SUPPORTED_RESOURCE_HIERARCHY_DEPTH; //the max we support
-
- int targetCnt = ((BigInteger) rs[0]).intValue();
- int typeCnt = ((BigInteger) rs[1]).intValue();
- int typeAndPluginCnt = ((BigInteger) rs[2]).intValue();
- for (i = 1; i <= Resource.MAX_SUPPORTED_RESOURCE_HIERARCHY_DEPTH; ++i) {
- int levelCnt = ((BigInteger) rs[2 + i]).intValue();
- if (levelCnt == targetCnt) {
- disambiguationLevel = i - 1;
- break;
- }
- }
-
- if (alwaysIncludeParent && disambiguationLevel == 0) {
- disambiguationLevel = 1;
+ if (results.isEmpty()) {
+ return new ResourceNamesDisambiguationResult<T>(new ArrayList<DisambiguationReport<T>>(), false, false,
+ false);
}
- boolean typeResolutionNeeded = typeAndPluginCnt > 1;
- boolean pluginResolutionNeeded = typeAndPluginCnt > typeCnt;
- boolean parentResolutionNeeded = disambiguationLevel > 0;
+ //this will contain the disambiguated results
+ List<DisambiguationReport<T>> resolution = new ArrayList<DisambiguationReport<T>>(results.size());
+ boolean typeResolutionNeeded = false;
+ boolean pluginResolutionNeeded = false;
+ boolean parentResolutionNeeded = false;
- //we can't assume any ordering in the results, hence this map
- Map<Integer, MutableDisambiguationReport<T>> reportByResourceId = new LinkedHashMap<Integer, MutableDisambiguationReport<T>>();
+ //we can't assume the ordering of the provided results and the disambiguation query results
+ //will be the same, hence this map.
+ Map<Integer, MutableDisambiguationReport<T>> reportByResourceId = new HashMap<Integer, MutableDisambiguationReport<T>>();
for (T r : results) {
MutableDisambiguationReport<T> value = new MutableDisambiguationReport<T>();
value.original = r;
@@ -2210,57 +2188,101 @@ public class ResourceManagerBean implements ResourceManagerLocal, ResourceManage
}
}
- //k, now let's construct the JPQL query to get the parents and type infos...
- StringBuilder selectBuilder = new StringBuilder("SELECT r0.id, r0.resourceType.name, r0.resourceType.plugin");
- StringBuilder fromBuilder = new StringBuilder("FROM Resource r0");
+ //check that we still have something to disambiguate
+ if (reportByResourceId.isEmpty()) {
+ //no, we don't. construct the resolution only using the results.
- for (i = 1; i <= disambiguationLevel; ++i) {
- int pi = i - 1;
- selectBuilder.append(", r").append(i).append(".id");
- selectBuilder.append(", r").append(i).append(".name");
- fromBuilder.append(" left join r").append(pi).append(".parentResource r").append(i);
- }
+ for (T result : results) {
+ DisambiguationReport<T> report = new DisambiguationReport<T>(result, Collections
+ .<ResourceParentFlyweight> emptyList(), null, null);
+ resolution.add(report);
+ }
+ } else {
+ //first find out how many ancestors we are going to require to disambiguate the resuls
+ String query = Resource.NATIVE_QUERY_FIND_DISAMBIGUATION_LEVEL;
+
+ query = JDBCUtil.transformQueryForMultipleInParameters(query, "@@RESOURCE_IDS@@", results.size());
+ Query disambiguateQuery = entityManager.createNativeQuery(query);
+ int i = 1;
+ for (T r : results) {
+ disambiguateQuery.setParameter(i++, extractor.extract(r));
+ }
- fromBuilder.append(" WHERE r0.id IN (:resourceIds)");
+ Object[] rs = (Object[]) disambiguateQuery.getSingleResult();
- Query parentsQuery = entityManager.createQuery(selectBuilder.append(" ").append(fromBuilder).toString());
+ int disambiguationLevel = Resource.MAX_SUPPORTED_RESOURCE_HIERARCHY_DEPTH; //the max we support
- parentsQuery.setParameter("resourceIds", reportByResourceId.keySet());
+ int targetCnt = ((BigInteger) rs[0]).intValue();
+ int typeCnt = ((BigInteger) rs[1]).intValue();
+ int typeAndPluginCnt = ((BigInteger) rs[2]).intValue();
+ for (i = 1; i <= Resource.MAX_SUPPORTED_RESOURCE_HIERARCHY_DEPTH; ++i) {
+ int levelCnt = ((BigInteger) rs[2 + i]).intValue();
+ if (levelCnt == targetCnt) {
+ disambiguationLevel = i - 1;
+ break;
+ }
+ }
+
+ if (alwaysIncludeParent && disambiguationLevel == 0) {
+ disambiguationLevel = 1;
+ }
- @SuppressWarnings("unchecked")
- List<Object[]> parentsResults = (List<Object[]>) parentsQuery.getResultList();
- for (Object[] parentsResult : parentsResults) {
- List<ResourceParentFlyweight> parents = new ArrayList<ResourceParentFlyweight>(disambiguationLevel);
- Integer resourceId = (Integer) parentsResult[0];
- String typeName = (String) parentsResult[1];
- String pluginName = (String) parentsResult[2];
+ typeResolutionNeeded = typeAndPluginCnt > 1;
+ pluginResolutionNeeded = typeAndPluginCnt > typeCnt;
+ parentResolutionNeeded = disambiguationLevel > 0;
+
+ //k, now let's construct the JPQL query to get the parents and type infos...
+ StringBuilder selectBuilder = new StringBuilder(
+ "SELECT r0.id, r0.resourceType.name, r0.resourceType.plugin");
+ StringBuilder fromBuilder = new StringBuilder("FROM Resource r0");
for (i = 1; i <= disambiguationLevel; ++i) {
- Integer parentId = (Integer) parentsResult[2 * i + 1];
- if (parentId == null)
- break;
- String parentName = (String) parentsResult[2 * i + 2];
- parents.add(new ResourceParentFlyweight(parentId, parentName));
+ int pi = i - 1;
+ selectBuilder.append(", r").append(i).append(".id");
+ selectBuilder.append(", r").append(i).append(".name");
+ fromBuilder.append(" left join r").append(pi).append(".parentResource r").append(i);
}
- MutableDisambiguationReport<T> report = reportByResourceId.get(resourceId);
- report.typeName = typeName;
- report.pluginName = pluginName;
- report.parents = parents;
- }
- //now we have all the information to create the result.
- //first create the immutable reports.
- List<DisambiguationReport<T>> resolution = new ArrayList<DisambiguationReport<T>>(results.size());
+ fromBuilder.append(" WHERE r0.id IN (:resourceIds)");
- for(T result : results) {
- int resourceId = extractor.extract(result);
- if (resourceId > 0) {
+ Query parentsQuery = entityManager.createQuery(selectBuilder.append(" ").append(fromBuilder).toString());
+
+ parentsQuery.setParameter("resourceIds", reportByResourceId.keySet());
+
+ @SuppressWarnings("unchecked")
+ List<Object[]> parentsResults = (List<Object[]>) parentsQuery.getResultList();
+ for (Object[] parentsResult : parentsResults) {
+ List<ResourceParentFlyweight> parents = new ArrayList<ResourceParentFlyweight>(disambiguationLevel);
+ Integer resourceId = (Integer) parentsResult[0];
+ String typeName = (String) parentsResult[1];
+ String pluginName = (String) parentsResult[2];
+
+ for (i = 1; i <= disambiguationLevel; ++i) {
+ Integer parentId = (Integer) parentsResult[2 * i + 1];
+ if (parentId == null)
+ break;
+ String parentName = (String) parentsResult[2 * i + 2];
+ parents.add(new ResourceParentFlyweight(parentId, parentName));
+ }
MutableDisambiguationReport<T> report = reportByResourceId.get(resourceId);
- resolution.add(report.getReport());
- } else {
- //this result doesn't correspond to any resource, need to handle it specially
- DisambiguationReport<T> report = new DisambiguationReport<T>(result, Collections.<ResourceParentFlyweight>emptyList(), null, null);
- resolution.add(report);
+ report.typeName = typeName;
+ report.pluginName = pluginName;
+ report.parents = parents;
+ }
+
+ //now we have all the information to create the result.
+ for (T result : results) {
+ int resourceId = extractor.extract(result);
+ if (resourceId > 0) {
+ //this results was disambiguated by the query above...
+ MutableDisambiguationReport<T> report = reportByResourceId.get(resourceId);
+ resolution.add(report.getReport());
+ } else {
+ //this result doesn't correspond to any resource, need to handle it specially
+ DisambiguationReport<T> report = new DisambiguationReport<T>(result, Collections
+ .<ResourceParentFlyweight> emptyList(), null, null);
+ resolution.add(report);
+ }
}
}
commit 2b28eb953aad5656ce7c7ecf6eaf029e767b27a9
Merge: 40bfa51... 7b5ccc1...
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Wed Feb 24 13:48:36 2010 +0100
Merge branch 'master' into alertPlugin
commit 40bfa515fa1c5dcc785e80597505f43866dd399c
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Wed Feb 24 13:46:00 2010 +0100
Provide an internal cleanup method that is called when the notification is deleted. This way, the backing bean can do some housekeeping if needed.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java
index dfa59f3..0896c6e 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/AlertNotificationManagerBean.java
@@ -41,7 +41,6 @@ import org.rhq.core.domain.alert.notification.AlertNotification;
import org.rhq.core.domain.alert.notification.NotificationTemplate;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.authz.Permission;
-import org.rhq.core.domain.authz.Role;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
import org.rhq.core.domain.plugin.PluginKey;
@@ -154,6 +153,18 @@ public class AlertNotificationManagerBean implements AlertNotificationManagerLoc
}
}
+ // Before we delete the notification, check if has a custom backing bean
+ // and give it the possibility to clean up
+ for (AlertNotification notification : toBeRemoved) {
+ CustomAlertSenderBackingBean bb = getBackingBeanForSender(notification.getSenderName(),notification.getId());
+ try {
+ bb.internalCleanup();
+ }
+ catch (Throwable t ) {
+ LOG.error("removeNotifications, calling backingBean.internalCleanup() resulted in " + t.getMessage());
+ }
+ }
+
alertDefinition.getAlertNotifications().removeAll(toBeRemoved);
postProcessAlertDefinition(alertDefinition);
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/CustomAlertSenderBackingBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/CustomAlertSenderBackingBean.java
index 5b39eae..e4b2d20 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/CustomAlertSenderBackingBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/CustomAlertSenderBackingBean.java
@@ -44,7 +44,7 @@ public class CustomAlertSenderBackingBean {
* This method is called when the alert notification that uses this backing bean
* is removed, so that the backing bean can do some cleanup work
*/
- protected void cleanup() {}
+ public void internalCleanup() {}
/**
* Persist the passed configuration object. This can be a new object or one
diff --git a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsBackingBean.java b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsBackingBean.java
index 2a3b635..98fa0e9 100644
--- a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsBackingBean.java
+++ b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsBackingBean.java
@@ -18,6 +18,7 @@
*/
package org.rhq.enterprise.server.plugins.alertOperations;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -71,6 +72,17 @@ public class OperationsBackingBean extends CustomAlertSenderBackingBean {
log.info("init");
}
+ @Override
+ public void internalCleanup() {
+ PropertySimple parameterConfigProp = alertParameters.getSimple(OperationsSender.PARAMETERS_CONFIG);
+ if (parameterConfigProp!=null) {
+ Integer paramId = parameterConfigProp.getIntegerValue();
+ if (paramId!=null) {
+ ConfigurationManagerLocal cmgr = LookupUtil.getConfigurationManager();
+ cmgr.deleteConfigurations(Arrays.asList(paramId));
+ }
+ }
+ }
public String selectResource() {
commit 780776f1eaf8067d86fa2ca45354fc5686f9d9c5
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Wed Feb 24 13:33:37 2010 +0100
Add a link to re-enable the definition on the detail page. Alternate solution to BZ 535889
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/ReenableAlertDefinitionAction.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/ReenableAlertDefinitionAction.java
new file mode 100644
index 0000000..265db09
--- /dev/null
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/ReenableAlertDefinitionAction.java
@@ -0,0 +1,80 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-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 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.legacy.action.resource.common.monitor.alerts;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.struts.action.ActionForm;
+import org.apache.struts.action.ActionForward;
+import org.apache.struts.action.ActionMapping;
+
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.enterprise.gui.legacy.action.BaseAction;
+import org.rhq.enterprise.gui.legacy.util.RequestUtils;
+import org.rhq.enterprise.server.alert.AlertDefinitionManagerLocal;
+import org.rhq.enterprise.server.alert.AlertManagerLocal;
+import org.rhq.enterprise.server.util.LookupUtil;
+
+/**
+ * Struts action to re-enable an alert definition from the
+ * AlertdefinitionActive.jsp tile, that gets included from
+ * ViewAlertProperties.jsp
+ * @author Heiko W. Rupp
+ */
+public class ReenableAlertDefinitionAction extends BaseAction {
+
+ private final Log log = LogFactory.getLog(ReenableAlertDefinitionAction.class);
+
+ public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request,
+ HttpServletResponse response) throws Exception {
+
+ Subject subject = RequestUtils.getSubject(request);
+ AlertDefinitionManagerLocal alertDefinitionManager = LookupUtil.getAlertDefinitionManager();
+
+ Map<String,Object> params = new HashMap<String,Object>(4);
+ // pass-through the alertId and resource id
+ Integer alertId = new Integer(request.getParameter("a"));
+ request.setAttribute("a", alertId);
+ params.put("a",alertId);
+
+ Integer alertDefId = new Integer(request.getParameter("ad"));
+ request.setAttribute("ad", alertDefId);
+ params.put("ad",alertDefId);
+
+ Integer resourceId = new Integer(request.getParameter("id"));
+ request.setAttribute("id",resourceId);
+ params.put("id",resourceId);
+
+ String mode = request.getParameter("mode");
+ request.setAttribute("mode",mode);
+ params.put("mode",mode);
+
+ alertDefinitionManager.enableAlertDefinitions(subject, new Integer[]{alertDefId});
+
+ log.debug("Reenabled Alert definition with id " + alertId + " and user " + subject.getName());
+
+ return returnSuccess(request,mapping,params);
+ }
+}
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/struts-config.xml b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/struts-config.xml
index a4c1b31..76321ce 100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/struts-config.xml
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/struts-config.xml
@@ -2563,9 +2563,13 @@
scope="request"
type="org.rhq.enterprise.gui.legacy.action.resource.common.monitor.alerts.AckAlertAction">
<set-property property="title" value="View+Alert"/>
- <exception key="exception.AlertNotFoundException"
- type="org.rhq.enterprise.server.legacy.events.AlertNotFoundException"
- path="/common/GenericError.jsp"/>
+ <forward name="success" path="/alerts/Alerts.do" redirect="true" />
+ </action>
+
+ <action path="/alerts/RenableAlertDefinition"
+ scope="request"
+ type="org.rhq.enterprise.gui.legacy.action.resource.common.monitor.alerts.ReenableAlertDefinitionAction">
+ <set-property property="title" value="View+Alert"/>
<forward name="success" path="/alerts/Alerts.do" redirect="true" />
</action>
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/resource/common/monitor/alerts/config/AlertDefinitionActive.jsp b/modules/enterprise/gui/portal-war/src/main/webapp/resource/common/monitor/alerts/config/AlertDefinitionActive.jsp
index 6affcc2..ed6b4fa 100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp/resource/common/monitor/alerts/config/AlertDefinitionActive.jsp
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/resource/common/monitor/alerts/config/AlertDefinitionActive.jsp
@@ -14,10 +14,14 @@
<fmt:message key="alert.config.props.PB.ActiveYes"/>
</td>
</c:when>
- <c:otherwise>
+ <c:otherwise>
<td width="30%" class="BlockContent">
- <html:img page="/images/icon_available_red.gif" width="12" height="12" border="0"/>
- <fmt:message key="alert.config.props.PB.ActiveNo"/>
+ <html:img page="/images/icon_available_red.gif" width="12" height="12" border="0"/>
+ <fmt:message key="alert.config.props.PB.ActiveNo"/>
+
+ <c:if test="${not alertDef.deleted}">
+ <a href="/alerts/RenableAlertDefinition.do?id=${Resource.id}&a=${alert.id}&mode=${param.mode}&ad=${alertDef.id}">click to re-enable</a>
+ </c:if>
</td>
</c:otherwise>
</c:choose>
commit 7b5ccc130607114a539bae8a97e7b097e7edc1ba
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Feb 24 13:27:56 2010 +0100
BZ 567925 - a follow up to my previous commit should finally fix the issue.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
index 54cebf6..b0db81c 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
@@ -2204,7 +2204,10 @@ public class ResourceManagerBean implements ResourceManagerLocal, ResourceManage
for (T r : results) {
MutableDisambiguationReport<T> value = new MutableDisambiguationReport<T>();
value.original = r;
- reportByResourceId.put(extractor.extract(r), value);
+ int resourceId = extractor.extract(r);
+ if (resourceId > 0) {
+ reportByResourceId.put(resourceId, value);
+ }
}
//k, now let's construct the JPQL query to get the parents and type infos...
@@ -2247,10 +2250,18 @@ public class ResourceManagerBean implements ResourceManagerLocal, ResourceManage
//now we have all the information to create the result.
//first create the immutable reports.
- List<DisambiguationReport<T>> resolution = new ArrayList<DisambiguationReport<T>>(reportByResourceId.size());
+ List<DisambiguationReport<T>> resolution = new ArrayList<DisambiguationReport<T>>(results.size());
- for (Map.Entry<Integer, MutableDisambiguationReport<T>> entry : reportByResourceId.entrySet()) {
- resolution.add(entry.getValue().getReport());
+ for(T result : results) {
+ int resourceId = extractor.extract(result);
+ if (resourceId > 0) {
+ MutableDisambiguationReport<T> report = reportByResourceId.get(resourceId);
+ resolution.add(report.getReport());
+ } else {
+ //this result doesn't correspond to any resource, need to handle it specially
+ DisambiguationReport<T> report = new DisambiguationReport<T>(result, Collections.<ResourceParentFlyweight>emptyList(), null, null);
+ resolution.add(report);
+ }
}
return new ResourceNamesDisambiguationResult<T>(resolution, typeResolutionNeeded, parentResolutionNeeded,
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java
index 2c99c9d..6db6155 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java
@@ -36,6 +36,7 @@ import org.rhq.core.domain.resource.ResourceCategory;
import org.rhq.core.domain.resource.ResourceError;
import org.rhq.core.domain.resource.ResourceErrorType;
import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.core.domain.resource.composite.DisambiguationReport;
import org.rhq.core.domain.resource.composite.RecentlyAddedResourceComposite;
import org.rhq.core.domain.resource.composite.ResourceAvailabilitySummary;
import org.rhq.core.domain.resource.composite.ResourceComposite;
@@ -449,7 +450,12 @@ public interface ResourceManagerLocal {
* The disambiguation result contains information on what types of information are needed to make the resources
* in the original result unambiguous and contains the decorated original data in the same order as the
* supplied result list.
- *
+ * <p>
+ * The objects in results do not necessarily need to correspond to a resource. In case of such objects,
+ * the resourceIdExtractor should return 0. In the resulting report such objects will still be wrapped
+ * in a {@link DisambiguationReport} but the parent list will be empty and resource type and plugin name will
+ * be null.
+ *
* @see ResourceNamesDisambiguationResult
*
* @param <T> the type of the result elements
commit ee6254859736c4b3447259517988e6ffe57e4cc8
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Wed Feb 24 12:33:52 2010 +0100
Fixing an NPE on alert definitions subsystem page caused by alert defs without an attached resource.
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/subsystem/SubsystemAlertDefinitionUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/subsystem/SubsystemAlertDefinitionUIBean.java
index 4d656b5..5831f3e 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/subsystem/SubsystemAlertDefinitionUIBean.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/subsystem/SubsystemAlertDefinitionUIBean.java
@@ -34,6 +34,7 @@ import org.rhq.core.domain.alert.AlertCondition;
import org.rhq.core.domain.alert.AlertConditionCategory;
import org.rhq.core.domain.alert.composite.AlertDefinitionComposite;
import org.rhq.core.domain.auth.Subject;
+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;
@@ -74,7 +75,8 @@ public class SubsystemAlertDefinitionUIBean extends SubsystemView {
private IntExtractor<AlertDefinitionComposite> RESOURCE_ID_EXTRACTOR = new IntExtractor<AlertDefinitionComposite>() {
public int extract(AlertDefinitionComposite object) {
- return object.getAlertDefinition().getResource().getId();
+ Resource resource = object.getAlertDefinition().getResource();
+ return resource == null ? 0 : resource.getId();
}
};
commit dbbfa75ddfa4ce4443f2f72df49b483970ea4e8c
Author: Justin Harris <jharris(a)redhat.com>
Date: Tue Feb 23 16:54:51 2010 -0500
Adding in validation rules and messaging for the alert conditions page.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/AlertConditionCategory.java b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/AlertConditionCategory.java
index b304f29..531857b 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/AlertConditionCategory.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/AlertConditionCategory.java
@@ -60,6 +60,10 @@ public enum AlertConditionCategory {
return name();
}
+ public String getDisplayName() {
+ return displayName;
+ }
+
@Override
public String toString() {
return this.displayName;
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/operation/OperationRequestStatus.java b/modules/core/domain/src/main/java/org/rhq/core/domain/operation/OperationRequestStatus.java
index cd0dcdb..bf816e8 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/operation/OperationRequestStatus.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/operation/OperationRequestStatus.java
@@ -38,6 +38,10 @@ public enum OperationRequestStatus {
this.displayName = displayName;
}
+ public String getDisplayName() {
+ return displayName;
+ }
+
public String toString() {
return displayName;
}
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/AlertConditionMessages.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/AlertConditionMessages.java
new file mode 100644
index 0000000..62a6fc0
--- /dev/null
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/AlertConditionMessages.java
@@ -0,0 +1,60 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-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 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.MessageFormat;
+import java.util.Map;
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.In;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+
+(a)Scope(ScopeType.APPLICATION)
+@Name("alertConditionMessages")
+public class AlertConditionMessages {
+
+ @In
+ private Map<String, String> messages;
+
+ public String getThreshold() {
+ return translate("errors.double", "Threshold");
+ }
+
+ public String getPercentRange() {
+ return translate("errors.range", "Threshold", "0%", "1000%");
+ }
+
+ public String getDampeningCount() {
+ return translate("errors.integer", "Dampening Count");
+ }
+
+ public String getDampeningEvaluation() {
+ return translate("errors.integer", "Dampening Evaluations");
+ }
+
+ public String getTimePeriod() {
+ return translate("errors.integer", "Time Period");
+ }
+
+ private String translate(String key, Object... params) {
+ String message = messages.get(key);
+
+ return MessageFormat.format(message, params);
+ }
+}
\ No newline at end of file
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/AlertConditionUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/AlertConditionUIBean.java
index 1d5fe02..f15e5de 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/AlertConditionUIBean.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/AlertConditionUIBean.java
@@ -18,6 +18,7 @@
*/
package org.rhq.enterprise.gui.alert;
+import java.util.Arrays;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
@@ -74,9 +75,9 @@ public class AlertConditionUIBean {
private Map<String, String> conditionExpressions;
private Map<String, String> availabilities;
private Map<String, String> severities;
- private Map<String, String> operationStatuses;
private Map<String, String> comparators;
private Map<String, String> baselines;
+ private Map<String, String> operationStatuses;
private Map<String, Integer> measurements;
private Map<String, Integer> traits;
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/AlertConditionsUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/AlertConditionsUIBean.java
index f3365f0..c32965d 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/AlertConditionsUIBean.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/AlertConditionsUIBean.java
@@ -19,6 +19,7 @@
package org.rhq.enterprise.gui.alert;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
@@ -36,6 +37,7 @@ import org.jboss.seam.international.StatusMessage.Severity;
import org.jboss.seam.log.Log;
import org.rhq.core.domain.alert.AlertCondition;
import org.rhq.core.domain.alert.AlertConditionCategory;
+import org.rhq.core.domain.alert.AlertDampening;
import org.rhq.core.domain.alert.AlertDefinition;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.measurement.MeasurementDefinition;
@@ -70,7 +72,7 @@ public class AlertConditionsUIBean {
@In
private AlertDescriber alertDescriber;
private MetricAbsoluteConverter metricAbsoluteConverter = new MetricAbsoluteConverter();
- private Map<AlertConditionCategory, String> categories;
+ private Map<String, String> categories;
private List<ConditionDescription> conditionDescriptions;
private AlertCondition currentCondition;
@@ -86,11 +88,19 @@ public class AlertConditionsUIBean {
}
public String getMeasurementDefinitionId() {
- return measurementDefinitionId.toString();
+ if (this.measurementDefinitionId != null) {
+ return measurementDefinitionId.toString();
+ }
+
+ return null;
}
public void setMeasurementDefinitionId(String measurementDefinitionId) {
- this.measurementDefinitionId = Integer.parseInt(measurementDefinitionId);
+ try {
+ this.measurementDefinitionId = Integer.parseInt(measurementDefinitionId);
+ } catch (NumberFormatException e) {
+ this.measurementDefinitionId = null;
+ }
}
public String getThreshold() {
@@ -109,7 +119,7 @@ public class AlertConditionsUIBean {
return conditionDescriptions;
}
- public Map<AlertConditionCategory, String> getCategories() {
+ public Map<String, String> getCategories() {
return categories;
}
@@ -136,7 +146,10 @@ public class AlertConditionsUIBean {
@Create
public void init() {
this.conditionDescriptions = createDescriptions();
- this.categories = createCategoryMap();
+ this.categories = createCategories();
+
+ // start out with an empty condition
+ createCondition();
}
private List<ConditionDescription> createDescriptions() {
@@ -183,6 +196,10 @@ public class AlertConditionsUIBean {
}
public String saveAlertDefinition() {
+ if (!validateDefinition()) {
+ return null;
+ }
+
alertDefinition.setConditions(findConditions());
try {
@@ -198,12 +215,16 @@ public class AlertConditionsUIBean {
}
public String newAlertDefinition() {
+ if (!validateDefinition()) {
+ return null;
+ }
+
alertDefinition.setConditions(findConditions());
try {
alertDefinitionManager.createAlertDefinition(subject, alertDefinition, resourceId);
} catch(Exception e) {
- this.facesMessages.add(Severity.ERROR, "There was an error creating the alert definitino.");
+ this.facesMessages.add(Severity.ERROR, "There was an error creating the alert definition.");
this.log.error("Error persisting AlertDefinition: " + alertDefinition.getName(), e);
return null;
@@ -212,6 +233,28 @@ public class AlertConditionsUIBean {
return SUCCESS_OUTCOME;
}
+ private boolean validateDefinition() {
+ Set<AlertCondition> conditions = findConditions();
+
+ if (conditions.isEmpty()) {
+ this.facesMessages.add(Severity.ERROR, "Please add at least one condition.");
+
+ return false;
+ }
+
+ AlertDampening dampening = alertDefinition.getAlertDampening();
+
+ if (dampening.getCategory() == AlertDampening.Category.PARTIAL_COUNT) {
+ if (dampening.getValue() > dampening.getPeriod()) {
+ this.facesMessages.addFromResourceBundle(Severity.ERROR, "alert.config.error.PartialCountRangeTooSmall");
+
+ return false;
+ }
+ }
+
+ return true;
+ }
+
private boolean shouldSetMeasurementDefinition() {
if (currentCondition != null) {
AlertConditionCategory category = currentCondition.getCategory();
@@ -245,17 +288,17 @@ public class AlertConditionsUIBean {
return conditionSet;
}
- private Map<AlertConditionCategory, String> createCategoryMap() {
- Map<AlertConditionCategory, String> categoryMap = new HashMap<AlertConditionCategory, String>();
+ private Map<String, String> createCategories() {
+ Map<String, String> categoryMap = new HashMap<String, String>();
+ List<AlertConditionCategory> categoryList = new ArrayList(Arrays.asList(AlertConditionCategory.values()));
+ categoryList.remove(AlertConditionCategory.ALERT);
- for (AlertConditionCategory category : AlertConditionCategory.values()) {
- categoryMap.put(category, category.getName());
+ if (configurationManager.getResourceConfigurationDefinitionForResourceType(subject, resourceType.getId()) == null) {
+ categoryList.remove(AlertConditionCategory.RESOURCE_CONFIG);
}
- categoryMap.remove(AlertConditionCategory.ALERT);
-
- if (configurationManager.getResourceConfigurationDefinitionForResourceType(subject, resourceType.getId()) == null) {
- categoryMap.remove(AlertConditionCategory.RESOURCE_CONFIG);
+ for (AlertConditionCategory category : categoryList) {
+ categoryMap.put(category.toString(), category.getName());
}
return categoryMap;
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/converter/MetricPercentConverter.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/converter/MetricPercentConverter.java
index eec5333..19dae93 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/converter/MetricPercentConverter.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/converter/MetricPercentConverter.java
@@ -30,6 +30,7 @@ import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.faces.Converter;
import org.rhq.core.domain.measurement.MeasurementUnits;
import org.rhq.core.domain.measurement.composite.MeasurementNumericValueAndUnits;
+import org.rhq.core.domain.measurement.util.MeasurementConversionException;
import org.rhq.core.domain.measurement.util.MeasurementConverter;
@Converter
@@ -38,9 +39,13 @@ import org.rhq.core.domain.measurement.util.MeasurementConverter;
public class MetricPercentConverter implements javax.faces.convert.Converter {
public Object getAsObject(FacesContext context, UIComponent component, String value) {
- MeasurementNumericValueAndUnits percentage = MeasurementConverter.parse(value, MeasurementUnits.PERCENTAGE);
+ try {
+ MeasurementNumericValueAndUnits percentage = MeasurementConverter.parse(value, MeasurementUnits.PERCENTAGE);
- return percentage.getValue();
+ return percentage.getValue();
+ } catch (MeasurementConversionException e) {
+ return null;
+ }
}
public String getAsString(FacesContext context, UIComponent component, Object value) {
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/validator/AlertValidatorUtil.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/validator/AlertValidatorUtil.java
new file mode 100644
index 0000000..d8f142c
--- /dev/null
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/validator/AlertValidatorUtil.java
@@ -0,0 +1,45 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-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 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.validator;
+
+import javax.faces.application.FacesMessage;
+import javax.faces.validator.ValidatorException;
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.AutoCreate;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.faces.FacesMessages;
+
+@AutoCreate
+(a)Scope(ScopeType.APPLICATION)
+@Name("validatorUtil")
+public class AlertValidatorUtil {
+
+ public void error(String message) throws ValidatorException {
+ FacesMessage facesMessage = FacesMessages.createFacesMessage(FacesMessage.SEVERITY_ERROR , message);
+
+ throw new ValidatorException(facesMessage);
+ }
+
+ public void templateError(String key, Object... params) throws ValidatorException {
+ FacesMessage facesMessage = FacesMessages.createFacesMessage(FacesMessage.SEVERITY_ERROR , key, key, params);
+
+ throw new ValidatorException(facesMessage);
+ }
+}
\ No newline at end of file
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/validator/EventRegexValidator.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/validator/EventRegexValidator.java
new file mode 100644
index 0000000..e4831d4
--- /dev/null
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/validator/EventRegexValidator.java
@@ -0,0 +1,48 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-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 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.validator;
+
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.validator.ValidatorException;
+import org.jboss.seam.annotations.In;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.faces.Validator;
+
+@Name("eventRegexValidator")
+@Validator
+public class EventRegexValidator implements javax.faces.validator.Validator {
+
+ @In
+ private AlertValidatorUtil validatorUtil;
+
+ public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException {
+ String stringValue = (String)value;
+
+ if (stringValue != null && stringValue.length() > 0) {
+ try {
+ Pattern.compile(stringValue);
+ } catch (PatternSyntaxException e) {
+ validatorUtil.templateError("alert.config.error.InvalidEventDetails");
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/listConditions.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/listConditions.xhtml
index 24a0bdf..a5500e4 100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/listConditions.xhtml
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/listConditions.xhtml
@@ -35,7 +35,16 @@
</ui:define>
<ui:define name="body">
- <a4j:form id="alertConditionsForm">
+
+ <rich:messages showSummary="true"
+ infoClass="InfoBlock"
+ warnClass="WarnBlock"
+ errorClass="ErrorBlock"
+ fatalClass="FatalBlock"
+ layout="table"
+ width="100%" />
+
+ <h:form id="alertConditionsForm">
<ui:insert name="formTop" />
<rich:panel id="conditionsPanel">
@@ -44,11 +53,11 @@
</f:facet>
<rich:panel id="conditionExpression">
- <h:outputText value="#{messages['alert.config.props.CB.ExpressionDetails.1']} " />
- <h:selectOneMenu value="#{alertDefinition.conditionExpression}">
- <f:selectItems value="#{alertConditionUIBean.conditionExpressions}" />
- </h:selectOneMenu>
- <h:outputText value=" #{messages['alert.config.props.CB.ExpressionDetails.2']}" />
+ <h:outputText value="#{messages['alert.config.props.CB.ExpressionDetails.1']} " />
+ <h:selectOneMenu value="#{alertDefinition.conditionExpression}">
+ <f:selectItems value="#{alertConditionUIBean.conditionExpressions}" />
+ </h:selectOneMenu>
+ <h:outputText value=" #{messages['alert.config.props.CB.ExpressionDetails.2']}" />
</rich:panel>
<rich:panel id="conditionSet">
@@ -56,8 +65,6 @@
<h:outputText value="Condition Set"/>
</f:facet>
- <h:messages />
-
<rich:dataTable id="categoryTable" value="#{alertConditionsUIBean.conditionDescriptions}" var="conditionDescription">
<rich:column>
<h:outputText value="#{conditionDescription.description}" />
@@ -71,6 +78,7 @@
<f:setPropertyActionListener value="#{conditionDescription.condition}" target="#{alertConditionsUIBean.currentCondition}" />
<rich:componentControl for="categoryModalPanel" attachTo="editButton" operation="show" event="onclick" />
+ <a4j:support event="onclick" reRender="categoryOptionOkButton" />
</a4j:commandButton>
</rich:column>
@@ -93,7 +101,7 @@
action="#{alertConditionsUIBean.createCondition}"
styleClass="buttonmed">
<rich:componentControl for="categoryModalPanel" attachTo="addConditionButton" operation="show" event="onclick" />
- <a4j:support event="onclick" reRender="categoryOptionsPanel" />
+ <a4j:support event="onclick" reRender="categoryOptionsPanel,categoryOptionOkButton" />
</a4j:commandButton>
</rich:panel>
@@ -107,13 +115,20 @@
<h:outputText value="#{messages['alert.config.props.CB.Recovery']} " />
<h:outputText value="#{messages['alert.config.props.CB.RecoveryFor']}" />
- <h:selectOneMenu value="#{alertDefinition.recoveryId}">
+ <h:selectOneMenu id="recoveryForAlertSelectBox"
+ value="#{alertDefinition.recoveryId}"
+ disabled="#{alertDefinition.willRecover}">
<f:selectItem itemLabel="#{messages['alert.dropdown.SelectOption']}" itemValue="0" />
<f:selectItems value="#{alertConditionUIBean.existingAlerts}" />
+ <a4j:support event="onchange" reRender="willRecoverCheckbox" />
</h:selectOneMenu>
<br />
- <h:selectBooleanCheckbox id="willRecoverCheckbox" value="#{alertDefinition.willRecover}" />
+ <h:selectBooleanCheckbox id="willRecoverCheckbox"
+ value="#{alertDefinition.willRecover}"
+ disabled="#{alertDefinition.recoveryId != 0}">
+ <a4j:support event="onchange" reRender="recoveryForAlertSelectBox" />
+ </h:selectBooleanCheckbox>
<h:outputLabel for="willRecoverCheckbox" value="#{messages['alert.config.props.CB.Content.UntilRecovered']}" />
<br />
@@ -151,28 +166,63 @@
<ui:fragment rendered="#{alertDefinition.alertDampening.category == 'CONSECUTIVE_COUNT'}">
<h:outputText value="#{messages['alert.config.props.CB.Content.DampenConsecutiveCount.1']} " />
- <h:inputText value="#{alertDefinition.alertDampening.value}"
- required="true"
- maxlength="5"/>
+ <h:inputText id="consecutiveCount"
+ value="#{alertDefinition.alertDampening.value}"
+ size="4"
+ required="true"
+ requiredMessage="#{alertConditionMessages.dampeningCount}"
+ validatorMessage="#{alertConditionMessages.dampeningCount}"
+ converterMessage="#{alertConditionMessages.dampeningCount}">
+ <f:validateDoubleRange minimum="0" />
+ </h:inputText>
<h:outputText value=" #{messages['alert.config.props.CB.Content.DampenConsecutiveCount.2']}" />
</ui:fragment>
<ui:fragment rendered="#{alertDefinition.alertDampening.category == 'PARTIAL_COUNT'}">
<h:outputText value="#{messages['alert.config.props.CB.Content.DampenPartialCount.1']} " />
- <h:inputText value="#{alertDefinition.alertDampening.value}"
- required="true"
- maxlength="5"/>
+ <h:inputText id="partialCount"
+ value="#{alertDefinition.alertDampening.value}"
+ size="4"
+ required="true"
+ requiredMessage="#{alertConditionMessages.dampeningCount}"
+ validatorMessage="#{alertConditionMessages.dampeningCount}"
+ converterMessage="#{alertConditionMessages.dampeningCount}">
+ <f:validateLongRange minimum="0" />
+ </h:inputText>
<h:outputText value=" #{messages['alert.config.props.CB.Content.DampenPartialCount.2']} " />
- <h:inputText value="#{alertDefinition.alertDampening.period}" />
+ <h:inputText id="partialCountPeriod"
+ value="#{alertDefinition.alertDampening.period}"
+ size="4"
+ required="true"
+ requiredMessage="#{alertConditionMessages.dampeningEvaluation}"
+ validatorMessage="#{alertConditionMessages.dampeningEvaluation}"
+ converterMessage="#{alertConditionMessages.dampeningEvaluation}">
+ <f:validateLongRange minimum="0" />
+ </h:inputText>
<h:outputText value=" #{messages['alert.config.props.CB.Content.DampenPartialCount.3']}" />
</ui:fragment>
<ui:fragment rendered="#{alertDefinition.alertDampening.category == 'DURATION_COUNT'}">
<h:outputText value="#{messages['alert.config.props.CB.Content.DampenDurationCount.1']} " />
- <h:inputText value="#{alertDefinition.alertDampening.value}" />
+ <h:inputText id="durationCount"
+ value="#{alertDefinition.alertDampening.value}"
+ size="4"
+ required="true"
+ requiredMessage="#{alertConditionMessages.dampeningCount}"
+ validatorMessage="#{alertConditionMessages.dampeningCount}"
+ converterMessage="#{alertConditionMessages.dampeningCount}">
+ <f:validateLongRange minimum="0" />
+ </h:inputText>
<h:outputText value=" #{messages['alert.config.props.CB.Content.DampenDurationCount.2']} " />
- <h:inputText value="#{alertDefinition.alertDampening.period}" />
-
+ <h:inputText id="durationCountPeriod"
+ value="#{alertDefinition.alertDampening.period}"
+ size="4"
+ required="true"
+ requiredMessage="#{alertConditionMessages.timePeriod}"
+ validatorMessage="#{alertConditionMessages.timePeriod}"
+ converterMessage="#{alertConditionMessages.timePeriod}">
+ <f:validateLongRange minimum="0" />
+ </h:inputText>
<h:selectOneMenu value="#{alertDefinition.alertDampening.periodUnits}">
<f:selectItems value="#{alertConditionUIBean.timeUnits}" />
</h:selectOneMenu>
@@ -190,7 +240,7 @@
styleClass="buttonmed"
style="margin: 10px;" />
</ui:insert>
- </a4j:form>
+ </h:form>
<rich:modalPanel id="categoryModalPanel" moveable="false" autosized="true" width="400">
@@ -199,8 +249,8 @@
<h:form id="categoryForm">
<h:selectOneMenu value="#{alertConditionsUIBean.currentCondition.category}">
<f:selectItem itemLabel="#{messages['alert.dropdown.SelectOption']}" />
- <s:selectItems value="#{alertConditionsUIBean.categories}" />
- <a4j:support event="onchange" reRender="categoryOptions" status="categoryLoadStatus" />
+ <f:selectItems value="#{alertConditionsUIBean.categories}" />
+ <a4j:support event="onchange" reRender="EditConditionForm" status="categoryLoadStatus" />
</h:selectOneMenu>
</h:form>
@@ -221,14 +271,20 @@
<ui:fragment rendered="#{alertConditionsUIBean.currentCondition.category == 'CONTROL'}">
<h:outputLabel for="operationSelection" value="#{messages['alert.config.props.CB.Content.ControlAction']} " />
- <h:selectOneMenu id="operationSelection" value="#{alertConditionsUIBean.currentCondition.name}">
+ <h:selectOneMenu id="operationSelection"
+ value="#{alertConditionsUIBean.currentCondition.name}"
+ required="true"
+ requiredMessage="#{messages['alert.config.error.NoControlActionSelected']}">
<f:selectItem itemLabel="#{messages['alert.dropdown.SelectOption']}" />
<f:selectItems value="#{alertConditionUIBean.operations}" />
</h:selectOneMenu>
<h:outputText value=" #{messages['alert.config.props.CB.Content.Comparator.=']} " />
- <h:selectOneMenu id="operationStatusSelection" value="#{alertConditionsUIBean.currentCondition.option}">
+ <h:selectOneMenu id="operationStatusSelection"
+ value="#{alertConditionsUIBean.currentCondition.option}"
+ required="true"
+ requiredMessage="#{messages['alert.config.error.NoControlActionStatusSelected']}">
<f:selectItem itemLabel="#{messages['alert.dropdown.SelectOption']}" />
<f:selectItems value="#{alertConditionUIBean.operationStatuses}" />
</h:selectOneMenu>
@@ -238,7 +294,10 @@
<ui:fragment rendered="#{alertConditionsUIBean.currentCondition.category == 'AVAILABILITY'}">
<h:outputLabel for="availabilitySelection" value="#{messages['alert.config.props.CB.Content.Availability']} " />
- <h:selectOneMenu id="availabilitySelection" value="#{alertConditionsUIBean.currentCondition.option}">
+ <h:selectOneMenu id="availabilitySelection"
+ value="#{alertConditionsUIBean.currentCondition.option}"
+ required="true"
+ requiredMessage="#{messages['alert.config.error.NoAvailabilityStatusSelected']}">
<f:selectItem itemLabel="#{messages['alert.dropdown.SelectOption']}" />
<f:selectItems value="#{alertConditionUIBean.availabilities}" />
</h:selectOneMenu>
@@ -248,7 +307,10 @@
<ui:fragment rendered="#{alertConditionsUIBean.currentCondition.category == 'CHANGE'}">
<h:outputLabel for="metricChangeSelection" value="#{messages['alert.config.props.CB.Content.Metric']} " />
- <h:selectOneMenu id="metricChangeSelection" value="#{alertConditionsUIBean.measurementDefinitionId}">
+ <h:selectOneMenu id="metricChangeSelection"
+ value="#{alertConditionsUIBean.measurementDefinitionId}"
+ required="true"
+ requiredMessage="#{messages['alert.config.error.NoMetricSelected']}">
<f:selectItem itemLabel="#{messages['alert.dropdown.SelectOption']}" />
<f:selectItems value="#{alertConditionUIBean.measurements}" />
</h:selectOneMenu>
@@ -260,7 +322,10 @@
<ui:fragment rendered="#{alertConditionsUIBean.currentCondition.category == 'THRESHOLD'}">
<h:outputLabel for="metricThresholdSelection" value="#{messages['alert.config.props.CB.Content.Metric']}" />
- <h:selectOneMenu id="metricThresholdSelection" value="#{alertConditionsUIBean.measurementDefinitionId}">
+ <h:selectOneMenu id="metricThresholdSelection"
+ value="#{alertConditionsUIBean.measurementDefinitionId}"
+ required="true"
+ requiredMessage="#{messages['alert.config.error.NoMetricSelected']}">
<f:selectItem itemLabel="#{messages['alert.dropdown.SelectOption']}" />
<f:selectItems value="#{alertConditionUIBean.measurements}" />
</h:selectOneMenu>
@@ -273,14 +338,23 @@
<br />
<br />
- <h:inputText id="metricThresholdAbsolute" value="#{alertConditionsUIBean.threshold}" />
+ <h:inputText id="metricThresholdAbsolute"
+ value="#{alertConditionsUIBean.threshold}"
+ required="true"
+ requiredMessage="#{alertConditionMessages.threshold}"
+ validatorMessage="#{alertConditionMessages.threshold}">
+ <f:validateDoubleRange minimum="0.0" />
+ </h:inputText>
<h:outputLabel for="metricThresholdAbsolute" value="#{messages['alert.config.props.CB.Content.AbsoluteValue']}" />
</ui:fragment>
<ui:fragment rendered="#{alertConditionsUIBean.currentCondition.category == 'BASELINE'}">
<h:outputLabel for="metricBaselineSelection" value="#{messages['alert.config.props.CB.Content.Metric']} " />
- <h:selectOneMenu id="metricBaselineSelection" value="#{alertConditionsUIBean.measurementDefinitionId}">
+ <h:selectOneMenu id="metricBaselineSelection"
+ value="#{alertConditionsUIBean.measurementDefinitionId}"
+ required="true"
+ requiredMessage="#{messages['alert.config.error.NoMetricSelected']}">
<f:selectItem itemLabel="#{messages['alert.dropdown.SelectOption']}" />
<f:selectItems value="#{alertConditionUIBean.measurements}" />
</h:selectOneMenu>
@@ -293,10 +367,20 @@
<br />
<br />
- <h:inputText id="metricBaselinePercent" value="#{alertConditionsUIBean.currentCondition.threshold}" converter="#{metricPercentConverter}" />
+ <h:inputText id="metricBaselinePercent"
+ value="#{alertConditionsUIBean.currentCondition.threshold}"
+ converter="#{metricPercentConverter}"
+ required="true"
+ requiredMessage="#{alertConditionMessages.percentRange}"
+ validatorMessage="#{alertConditionMessages.percentRange}">
+ <f:validateDoubleRange minimum="0.0" maximum="1000.0" />
+ </h:inputText>
<h:outputLabel for="metricBaselinePercent" value=" #{messages['alert.config.props.CB.Content.Percent']} " />
- <h:selectOneMenu id="metricBaselineBaselineSelection" value="#{alertConditionsUIBean.currentCondition.option}">
+ <h:selectOneMenu id="metricBaselineBaselineSelection"
+ value="#{alertConditionsUIBean.currentCondition.option}"
+ required="true"
+ requiredMessage="#{messages['alert.config.error.NoBaselineOptionSelected']}">
<f:selectItems value="#{alertConditionUIBean.baselines}" />
</h:selectOneMenu>
</ui:fragment>
@@ -305,20 +389,29 @@
<ui:fragment rendered="#{alertConditionsUIBean.currentCondition.category == 'EVENT'}">
<h:outputLabel for="eventSelection" value="#{messages['alert.config.props.CB.Content.EventSeverity']} " />
- <h:selectOneMenu id="eventSelection" value="#{alertConditionsUIBean.currentCondition.name}">
+ <h:selectOneMenu id="eventSelection"
+ value="#{alertConditionsUIBean.currentCondition.name}"
+ required="true"
+ requiredMessage="#{messages['alert.config.error.NoEventSeveritySelected']}">
<f:selectItem itemLabel="#{messages['alert.dropdown.SelectOption']}" />
<f:selectItems value="#{alertConditionUIBean.severities}" />
</h:selectOneMenu>
<h:outputText value=" #{messages['alert.config.props.CB.Content.Match']}" />
- <h:inputText id="eventExpression" value="#{alertConditionsUIBean.currentCondition.option}" />
+ <h:inputText id="eventExpression"
+ value="#{alertConditionsUIBean.currentCondition.option}">
+ <f:validator validatorId="eventRegexValidator" />
+ </h:inputText>
</ui:fragment>
<ui:fragment rendered="#{alertConditionsUIBean.currentCondition.category == 'TRAIT'}">
<h:outputLabel for="traitSelection" value="#{messages['alert.config.props.CB.Content.Trait']} " />
- <h:selectOneMenu id="traitSelection" value="#{alertConditionsUIBean.measurementDefinitionId}">
+ <h:selectOneMenu id="traitSelection"
+ value="#{alertConditionsUIBean.measurementDefinitionId}"
+ required="true"
+ requiredMessage="#{messages['alert.config.error.NoTraitSelected']}">
<f:selectItem itemLabel="#{messages['alert.dropdown.SelectOption']}" />
<f:selectItems value="#{alertConditionUIBean.traits}" />
</h:selectOneMenu>
@@ -335,10 +428,11 @@
</rich:panel>
<h:commandButton id="categoryOptionOkButton"
- value="OK"
- action="#{alertConditionsUIBean.updateCondition}"
- styleClass="buttonmed"
- style="margin: 5px;">
+ value="OK"
+ rendered="#{not empty alertConditionsUIBean.currentCondition.category}"
+ action="#{alertConditionsUIBean.updateCondition}"
+ styleClass="buttonmed"
+ style="margin: 5px;">
<rich:componentControl for="categoryModalPanel" attachTo="categoryOptionOkButton" operation="hide" event="onclick" />
<a4j:support event="onclick" reRender="categoryTable" />
</h:commandButton>
commit e956b6f8b2608bc9d2941daba6e732caf4ad5715
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Tue Feb 23 22:25:45 2010 +0100
Introduce the possibility to ack an alert on the detail page.
BZ 567383
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/AckAlertAction.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/AckAlertAction.java
new file mode 100644
index 0000000..6043d19
--- /dev/null
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/action/resource/common/monitor/alerts/AckAlertAction.java
@@ -0,0 +1,78 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-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 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.legacy.action.resource.common.monitor.alerts;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.struts.action.ActionForm;
+import org.apache.struts.action.ActionForward;
+import org.apache.struts.action.ActionMapping;
+import org.apache.struts.tiles.ComponentContext;
+import org.apache.struts.tiles.actions.TilesAction;
+
+import org.rhq.core.domain.alert.Alert;
+import org.rhq.core.domain.auth.Subject;
+import org.rhq.enterprise.gui.legacy.action.BaseAction;
+import org.rhq.enterprise.gui.legacy.util.RequestUtils;
+import org.rhq.enterprise.server.alert.AlertManagerLocal;
+import org.rhq.enterprise.server.util.LookupUtil;
+
+/**
+ * Struts action to acknowledge one single alert from the
+ * ViewAlertProperties.jsp page
+ * @author Heiko W. Rupp
+ */
+public class AckAlertAction extends BaseAction {
+
+ Log log = LogFactory.getLog(AckAlertAction.class);
+
+ public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request,
+ HttpServletResponse response) throws Exception {
+
+ Subject subject = RequestUtils.getSubject(request);
+ AlertManagerLocal alertManager = LookupUtil.getAlertManager();
+
+ Map params = new HashMap(3);
+ // pass-through the alertId and resource id
+ Integer alertId = new Integer(request.getParameter("a"));
+ request.setAttribute("a", alertId);
+ params.put("a",alertId);
+
+ Integer resourceId = new Integer(request.getParameter("id"));
+ request.setAttribute("id",resourceId);
+ params.put("id",resourceId);
+
+ String mode = request.getParameter("mode");
+ request.setAttribute("mode",mode);
+ params.put("mode",mode);
+
+ alertManager.acknowledgeAlert(alertId,subject);
+
+ log.debug("Acknowledged Alert with id " + alertId + " and user " + subject.getName());
+
+ return returnSuccess(request,mapping,params);
+ }
+
+}
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/struts-config.xml b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/struts-config.xml
index 41da1ee..a4c1b31 100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/struts-config.xml
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/WEB-INF/struts-config.xml
@@ -2559,6 +2559,16 @@
path="/common/GenericError.jsp"/>
</action>
+ <action path="/alerts/AckAlert"
+ scope="request"
+ type="org.rhq.enterprise.gui.legacy.action.resource.common.monitor.alerts.AckAlertAction">
+ <set-property property="title" value="View+Alert"/>
+ <exception key="exception.AlertNotFoundException"
+ type="org.rhq.enterprise.server.legacy.events.AlertNotFoundException"
+ path="/common/GenericError.jsp"/>
+ <forward name="success" path="/alerts/Alerts.do" redirect="true" />
+ </action>
+
<action path="/alerts/ViewDefinition"
scope="request"
type="org.rhq.enterprise.gui.legacy.action.resource.common.monitor.alerts.config.ViewDefinitionAction">
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/resource/common/monitor/alerts/ViewAlertProperties.jsp b/modules/enterprise/gui/portal-war/src/main/webapp/resource/common/monitor/alerts/ViewAlertProperties.jsp
index 1b1c04b..0b49ecb 100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp/resource/common/monitor/alerts/ViewAlertProperties.jsp
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/resource/common/monitor/alerts/ViewAlertProperties.jsp
@@ -39,26 +39,37 @@
<td class="BlockLabel"><fmt:message key="alert.current.detail.props.AlertDate"/></td>
<td class="BlockContent" colspan="2"><hq:dateFormatter time="false" value="${alert.ctime}"/></td>
</tr>
- <tr valign="top">
- <td class="BlockLabel">Acknowledged by:</td>
- <td class="BlockContent">
- <c:if test="${not empty alert.ackBy}">
- <c:out value="${alert.ackBy.firstName}"/>
- <c:out value=" "/>
- <c:out value="${alert.ackBy.lastName}"/>
- <c:out value=" ("/>
- <c:out value="${alert.ackBy.name}"/>
- <c:out value=")"/>
- </c:if>
- </td>
- <td class="BlockLabel">Acknowledged at:</td>
- <td class="BlockContent">
- <c:if test="${alert.ackTime > 0}">
- <hq:dateFormatter time="false" value="${alert.ackTime}"/>
- </c:if>
+ <c:choose>
+ <c:when test="${not empty alert.ackBy}">
+ <tr valign="top">
+ <td class="BlockLabel">Acknowledged by:</td>
+ <td class="BlockContent">
+ <c:out value="${alert.ackBy.firstName}"/>
+ <c:out value=" "/>
+ <c:out value="${alert.ackBy.lastName}"/>
+ <c:out value=" ("/>
+ <c:out value="${alert.ackBy.name}"/>
+ <c:out value=")"/>
+ </td>
+ <td class="BlockLabel">Acknowledged at:</td>
+ <td class="BlockContent">
+ <hq:dateFormatter time="false" value="${alert.ackTime}"/>
+ </td>
+ </tr>
+ </c:when>
+ <c:otherwise>
+ <tr valign="top">
+ <td class="BlockLabel">Acknowledge Alert</td>
+ <td class="BlockContent">
+ <a href="/alerts/AckAlert.do?id=${Resource.id}&a=${alert.id}&mode=${param.mode}">click here</a>
+ </td>
+ <td class="BlockContent"> </td>
+ <td class="BlockContent"> </td>
+ </tr>
- </td>
- </tr>
+ </c:otherwise>
+
+ </c:choose>
<tr>
<td colspan="5" class="BlockContent"><html:img page="/images/spacer.gif" width="1" height="1" border="0"/></td>
</tr>
commit b22dc41c2c2251ee2c29387eabbdfbf9a616a41d
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Tue Feb 23 16:20:56 2010 +0100
Add a new cleanup() method and some JavaDoc
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/CustomAlertSenderBackingBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/CustomAlertSenderBackingBean.java
index 72f6ec8..5b39eae 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/CustomAlertSenderBackingBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/alert/CustomAlertSenderBackingBean.java
@@ -40,9 +40,24 @@ public class CustomAlertSenderBackingBean {
public void setAlertParameters(Configuration alertParameters) {
this.alertParameters = alertParameters;
}
+ /**
+ * This method is called when the alert notification that uses this backing bean
+ * is removed, so that the backing bean can do some cleanup work
+ */
+ protected void cleanup() {}
+ /**
+ * Persist the passed configuration object. This can be a new object or one
+ * that already exists in the database. If the input is null, not persistence
+ * happens and null is returned.
+ * @param config configuration to persist or update
+ * @return a merged copy of the configuration or null
+ */
protected Configuration persistConfiguration(Configuration config) {
+ if (config==null)
+ return null;
+
ConfigurationManagerLocal mgr = LookupUtil.getConfigurationManager();
config = mgr.mergeConfiguration(config);
@@ -50,6 +65,14 @@ public class CustomAlertSenderBackingBean {
}
+ /**
+ * Persist a single property of a given configuration. If the property does not yet exist,
+ * it is created otherwise overwritten with the new value.
+ * @param config configuration the property is on
+ * @param propertyName name of the property to persist
+ * @param value (new) value of the property to persist
+ * @return the updated configuration
+ */
protected Configuration persistProperty(Configuration config, String propertyName, Object value) {
PropertySimple prop = config.getSimple(propertyName);
@@ -65,6 +88,12 @@ public class CustomAlertSenderBackingBean {
return ret;
}
+ /**
+ * Remove one property from the passed configuration. Returns the updated configuration
+ * @param config configuration the property is on
+ * @param propertyName name of the property to remove
+ * @return the updated configuration
+ */
protected Configuration cleanProperty(Configuration config, String propertyName) {
Configuration ret = config;
@@ -76,4 +105,5 @@ public class CustomAlertSenderBackingBean {
return ret;
}
+
}
commit 6c0f0ebe7f448eb3aec0acdf04f581146938f45a
Merge: 354dd60... 59776e2...
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Tue Feb 23 15:29:43 2010 +0100
Merge branch 'master' into alertPlugin
commit 354dd6076c8e6c700086c6472963924f35b8deb1
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Tue Feb 23 15:28:34 2010 +0100
Cleanup of variable names and obtain the right operation name.
diff --git a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsBackingBean.java b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsBackingBean.java
index deabeae..2a3b635 100644
--- a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsBackingBean.java
+++ b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsBackingBean.java
@@ -28,7 +28,6 @@ import org.apache.commons.logging.LogFactory;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Create;
import org.jboss.seam.annotations.Scope;
-import org.jboss.seam.annotations.web.RequestParameter;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.configuration.Configuration;
@@ -54,8 +53,8 @@ public class OperationsBackingBean extends CustomAlertSenderBackingBean {
private String resMode;
private String tokenMode;
Integer resId;
- private Integer operationName;
- private Map<String, Integer> operationNames = new HashMap<String, Integer>();
+ private Integer operationId;
+ private Map<String, Integer> operationIds = new HashMap<String, Integer>();
private String resourceName;
@@ -79,12 +78,12 @@ public class OperationsBackingBean extends CustomAlertSenderBackingBean {
if (resId != null) {
persistProperty(alertParameters, OperationsSender.RESOURCE_ID,resId);
- cleanProperty(alertParameters,OperationsSender.OPERATION_NAME);
+ cleanProperty(alertParameters,OperationsSender.OPERATION_ID);
cleanProperty(alertParameters,OperationsSender.USABLE);
}
- obtainOperationNames();
+ obtainOperationIds();
return ALERT_NOTIFICATIONS;
}
@@ -92,10 +91,10 @@ public class OperationsBackingBean extends CustomAlertSenderBackingBean {
public String selectOperation() {
- log.info("In selectOperation, resId is " + resId + " opName is " + operationName);
+ log.info("In selectOperation, resId is " + resId + " opName is " + operationId);
- if (operationName != null ) {
- persistProperty(alertParameters, OperationsSender.OPERATION_NAME,operationName);
+ if (operationId != null ) {
+ persistProperty(alertParameters, OperationsSender.OPERATION_ID, operationId);
lookupConfiguration();
}
@@ -112,10 +111,10 @@ public class OperationsBackingBean extends CustomAlertSenderBackingBean {
// int operationId = Integer.valueOf(FacesContextUtility.getRequiredRequestParameter("opId"));
OperationManagerLocal opMan = LookupUtil.getOperationManager();
- obtainOperationNames();
+ obtainOperationIds();
- OperationDefinition operationDefinition = opMan.getOperationDefinition(subject, operationName);
+ OperationDefinition operationDefinition = opMan.getOperationDefinition(subject, operationId);
configurationDefinition = operationDefinition.getParametersConfigurationDefinition();
@@ -140,7 +139,7 @@ log.info("gConfig: " + configuration + ", " + configuration.hashCode() + ", " +
return ALERT_NOTIFICATIONS;
}
- private void obtainOperationNames() {
+ private void obtainOperationIds() {
PropertySimple prop = alertParameters.getSimple(OperationsSender.RESOURCE_ID);
if (prop!=null)
@@ -152,7 +151,7 @@ log.info("gConfig: " + configuration + ", " + configuration.hashCode() + ", " +
Subject subject = LookupUtil.getSubjectManager().getOverlord(); // TODO replace with real subject
List<OperationDefinition> opDefs = opMan.findSupportedResourceOperations(subject, resId, false);
for (OperationDefinition def : opDefs) {
- operationNames.put(def.getDisplayName(),def.getId()); // TODO add more distinctive stuff in display
+ operationIds.put(def.getDisplayName(),def.getId()); // TODO add more distinctive stuff in display
}
}
}
@@ -205,30 +204,30 @@ log.info("gConfig: " + configuration + ", " + configuration.hashCode() + ", " +
this.resourceName = resourceName;
}
- public Integer getOperationName() {
+ public Integer getOperationId() {
- if (operationName==null) {
- PropertySimple prop = alertParameters.getSimple(OperationsSender.OPERATION_NAME);
+ if (operationId ==null) {
+ PropertySimple prop = alertParameters.getSimple(OperationsSender.OPERATION_ID);
if (prop!=null)
- operationName = prop.getIntegerValue();
+ operationId = prop.getIntegerValue();
}
- return operationName;
+ return operationId;
}
- public void setOperationName(Integer operationName) {
- this.operationName = operationName;
+ public void setOperationId(Integer operationId) {
+ this.operationId = operationId;
}
- public Map<String, Integer> getOperationNames() {
+ public Map<String, Integer> getOperationIds() {
- obtainOperationNames();
+ obtainOperationIds();
- return operationNames;
+ return operationIds;
}
- public void setOperationNames(Map<String, Integer> operationNames) {
- this.operationNames = operationNames;
+ public void setOperationIds(Map<String, Integer> operationIds) {
+ this.operationIds = operationIds;
}
public ConfigurationDefinition getConfigurationDefinition() {
@@ -239,15 +238,11 @@ log.info("gConfig: " + configuration + ", " + configuration.hashCode() + ", " +
}
public void setConfigurationDefinition(ConfigurationDefinition configurationDefinition) {
- log.info("set CD: " + configurationDefinition);
this.configurationDefinition = configurationDefinition;
}
public Configuration getConfiguration() {
-
return configuration;
-
-
}
public void setConfiguration(Configuration configuration) {
@@ -255,7 +250,7 @@ log.info("gConfig: " + configuration + ", " + configuration.hashCode() + ", " +
log.info("setC: " + configuration);
}
- public String getNullConfigurationDefinitionMessage() {
+ public String getNullConfigurationDefinitionMessage() {
return "This operation does not take any parameters.";
}
@@ -280,5 +275,4 @@ log.info("gConfig: " + configuration + ", " + configuration.hashCode() + ", " +
persistProperty(alertParameters, OperationsSender.TOKEN_MODE,tokenMode);
}
-
}
diff --git a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsSender.java b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsSender.java
index 4359ad4..4f6c88e 100644
--- a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsSender.java
+++ b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsSender.java
@@ -18,9 +18,8 @@
*/
package org.rhq.enterprise.server.plugins.alertOperations;
+import java.util.List;
import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -34,7 +33,7 @@ import org.rhq.core.domain.alert.notification.SenderResult;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.PropertySimple;
-import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.operation.OperationDefinition;
import org.rhq.enterprise.server.configuration.ConfigurationManagerLocal;
import org.rhq.enterprise.server.exception.ScheduleException;
import org.rhq.enterprise.server.operation.OperationManagerLocal;
@@ -51,7 +50,7 @@ public class OperationsSender extends AlertSender {
private final Log log = LogFactory.getLog(OperationsSender.class);
static final String RESOURCE_ID = "resourceId";
- static final String OPERATION_NAME = "operationName";
+ static final String OPERATION_ID = "operationName";
static final String USABLE = "usable";
protected static final String TOKEN_MODE = "tokenMode";
private static final String LITERAL = "literal";
@@ -62,8 +61,8 @@ public class OperationsSender extends AlertSender {
public SenderResult send(Alert alert) {
PropertySimple resProp = alertParameters.getSimple(RESOURCE_ID);
- PropertySimple opNameProp = alertParameters.getSimple(OPERATION_NAME);
- if (resProp==null || resProp.getIntegerValue() == null || opNameProp == null || opNameProp.getStringValue() == null)
+ PropertySimple opIdProp = alertParameters.getSimple(OPERATION_ID);
+ if (resProp==null || resProp.getIntegerValue() == null || opIdProp == null || opIdProp.getStringValue() == null)
return new SenderResult(ResultState.FAILURE, "Not enough parameters given");
PropertySimple usableProp = alertParameters.getSimple(USABLE);
@@ -71,11 +70,26 @@ public class OperationsSender extends AlertSender {
return new SenderResult(ResultState.FAILURE,"Not yet configured");
Integer resourceId = resProp.getIntegerValue();
- String opName = opNameProp.getStringValue();
+ Integer opId = opIdProp.getIntegerValue();
+
+ String opName = null;
OperationManagerLocal opMgr = LookupUtil.getOperationManager();
Subject subject = LookupUtil.getSubjectManager().getOverlord(); // TODO get real subject
+ List<OperationDefinition> opdefs = opMgr.findSupportedResourceOperations(subject,resourceId,false);
+ for (OperationDefinition opdef : opdefs ) {
+ if (opdef.getId() == opId) {
+ opName = opdef.getName();
+ break;
+ }
+ }
+
+ if (opName==null) {
+ return new SenderResult(ResultState.FAILURE, "No operation found ");
+ }
+
+
PropertySimple parameterConfigProp = alertParameters.getSimple(PARAMETERS_CONFIG);
Configuration parameters = null ;
if (parameterConfigProp!=null) {
diff --git a/modules/enterprise/server/plugins/alert-operations/src/main/resources/operations.xhtml b/modules/enterprise/server/plugins/alert-operations/src/main/resources/operations.xhtml
index 4a6c0e6..98dcada 100644
--- a/modules/enterprise/server/plugins/alert-operations/src/main/resources/operations.xhtml
+++ b/modules/enterprise/server/plugins/alert-operations/src/main/resources/operations.xhtml
@@ -36,13 +36,13 @@
</h:panelGroup>
<h:panelGroup style="width:60%; vertical-align:top;" >
- <rich:panel rendered="#{not empty operationsBean.operationNames}">
+ <rich:panel rendered="#{not empty operationsBean.operationIds}">
Operations for: <h:outputText value=" #{operationsBean.resourceName}"/>
<br/>
- <h:selectOneMenu id="selectOperationMenu" value="#{operationsBean.operationName}">
- <f:selectItems value="#{operationsBean.operationNames}"/>
+ <h:selectOneMenu id="selectOperationMenu" value="#{operationsBean.operationId}">
+ <f:selectItems value="#{operationsBean.operationIds}"/>
</h:selectOneMenu>
<p/>
<h:commandButton id="opNameSubmit"
@@ -57,9 +57,9 @@
<p/>
<h:panelGroup style="width:100%">
<h:messages />
- <rich:panel rendered="#{not empty operationsBean.operationName}">
+ <rich:panel rendered="#{not empty operationsBean.operationId}">
<br/>
- Parameters for <h:outputText value=" #{operationsBean.operationName}"/>
+ Parameters for <h:outputText value=" #{operationsBean.operationId}"/>
<p/>
<h:selectOneMenu id="tokenModeMenu" value="#{operationsBean.tokenMode}">
<f:selectItem itemValue="literal" itemLabel="Literal"/>
commit 59776e2009c2e2b17ca45d5c88e6373def9da879
Author: Ian P. Springer <ips(a)jetengine.(none)>
Date: Tue Feb 23 09:23:23 2010 -0500
fix a couple invalid docs URLs
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp-filtered/WEB-INF/classes/ApplicationResources.properties b/modules/enterprise/gui/portal-war/src/main/webapp-filtered/WEB-INF/classes/ApplicationResources.properties
index 571cf22..8132311 100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp-filtered/WEB-INF/classes/ApplicationResources.properties
+++ b/modules/enterprise/gui/portal-war/src/main/webapp-filtered/WEB-INF/classes/ApplicationResources.properties
@@ -88,7 +88,7 @@ common.field.value=Value
common.marketing.FeatureDisabled=This feature is unavailable, please contact sales to upgrade
-common.url.help=https://network.jboss.com/confluence/display/DOC/Users+Guide
+common.url.help=http://www.rhq-project.org/display/JOPR2
common.error.invalid.oid=OID specified is invalid, please enter OID in form of 1.2.3.4
@@ -2916,7 +2916,7 @@ software.common.InstallPreview.PatchTitle=Title
software.common.InstallPreview.StepDescription=Step Description
software.common.InstallPreview.ShortDescription=Short Description
software.common.InstallPreview.LongDescription=Detailed Description
-software.common.InstallPreview.TopMessage=Clicking the [Install] button will begin the execution of the steps listed below. Review each step carefully before proceeding with the update installation.<br/><ul><li>Prior to installing this update, if you have applied any one-off fixes to this instance, please check the update description to see that they are included in the fixes that make up this update. If they are not included then this update may overwrite the one-off fix and leave your instance in an unstable state.</li><li>When updating a JBoss instance that shares a common server configuration, follow the instructions documented in the wiki\: <a href\="https\://network.jboss.com/confluence/display/DOC/Installing+a+Patch" target\="_new">Installing a Patch</a>. Please contact support for more information.</li></ul>
+software.common.InstallPreview.TopMessage=Clicking the [Install] button will begin the execution of the steps listed below. Review each step carefully before proceeding with the update installation.<br/><ul><li>Prior to installing this update, if you have applied any one-off fixes to this instance, please check the update description to see that they are included in the fixes that make up this update. If they are not included then this update may overwrite the one-off fix and leave your instance in an unstable state.</li><li>When updating a JBoss instance that shares a common server configuration, follow the instructions documented in the wiki\: <a href\="http://www.rhq-project.org/display/JOPR2/Demos#Demos-ContentSubsystem" target\="_new">Installing a Patch</a>. Please contact support for more information.</li></ul>
software.common.InstallPreview.NotAllowedToInstall=This user doesn't have the appropriate rights to install an update. Only users that can control a resource may install an update.
software.common.ManualUninstall.TableTitle=Manual Update Uninstallation
commit b3c691dfd0f407658ba9004bbcbdda0c235404ef
Author: Ian P. Springer <ips(a)jetengine.(none)>
Date: Tue Feb 23 09:22:03 2010 -0500
fix regression in RSS feed template (https://bugzilla.redhat.com/show_bug.cgi?id=567636)
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/common/RSSFormat.jsp b/modules/enterprise/gui/portal-war/src/main/webapp/common/RSSFormat.jsp
index 59bb5d1..3831ebb 100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp/common/RSSFormat.jsp
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/common/RSSFormat.jsp
@@ -1,10 +1,10 @@
-<?xml version="1.0" encoding="utf-8" ?>
+<?xml version="1.0" encoding="UTF-8"?>
<%@ page language="java" contentType="text/xml" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<%@ taglib uri="http://jakarta.apache.org/struts/tags-html-el" prefix="html" %>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
- <repo>
+ <channel>
<title><c:out value="${rssFeed.title}"/></title>
<link><c:out value="${rssFeed.baseUrl}"/></link>
<description><fmt:message key="dashboard.template.title"/> <c:out value="${rssFeed.title}"/></description>
@@ -25,5 +25,6 @@
<guid><![CDATA[<c:out value="${item.guid}"/>]]></guid>
</item>
</c:forEach>
- </repo>
+ </channel>
</rss>
+
commit 7bdec1c039fbda0b202c078fe0c7be1507d95612
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Tue Feb 23 10:57:34 2010 +0100
Display, persist and use operation parameters.
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/CustomContentUIBean.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/CustomContentUIBean.java
index 8b7c8d8..683057b 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/CustomContentUIBean.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/alert/CustomContentUIBean.java
@@ -73,7 +73,12 @@ public class CustomContentUIBean {
* name of bean, but this class is not an "official" seam component.
*/
private void outjectBean(String name, CustomAlertSenderBackingBean bean) {
- Context pageContext = Contexts.getPageContext();
- pageContext.set(name, bean);
+
+ Context context = Contexts.getSessionContext();
+
+ CustomAlertSenderBackingBean csb = (CustomAlertSenderBackingBean) context.get(name);
+ if (csb ==null)
+ context.set(name,bean);
+
}
}
diff --git a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsBackingBean.java b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsBackingBean.java
index 32e9f16..deabeae 100644
--- a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsBackingBean.java
+++ b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsBackingBean.java
@@ -25,38 +25,64 @@ import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.Create;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.web.RequestParameter;
+
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
import org.rhq.core.domain.operation.OperationDefinition;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.enterprise.server.configuration.ConfigurationManagerLocal;
import org.rhq.enterprise.server.operation.OperationManagerLocal;
import org.rhq.enterprise.server.plugin.pc.alert.CustomAlertSenderBackingBean;
+import org.rhq.enterprise.server.resource.ResourceManagerLocal;
import org.rhq.enterprise.server.util.LookupUtil;
/**
* Backing bean for the operations alert sender
* @author Heiko W. Rupp
*/
-
+(a)Scope(ScopeType.PAGE)
public class OperationsBackingBean extends CustomAlertSenderBackingBean {
private final Log log = LogFactory.getLog(OperationsBackingBean.class);
private String resMode;
+ private String tokenMode;
Integer resId;
- private String operationName;
- private Map<String,String> operationNames = new HashMap<String,String>();
+ private Integer operationName;
+ private Map<String, Integer> operationNames = new HashMap<String, Integer>();
+ private String resourceName;
+
+
private ConfigurationDefinition configurationDefinition;
private Configuration configuration;
private static final String ALERT_NOTIFICATIONS = "ALERT_NOTIFICATIONS";
+ public OperationsBackingBean() {
+ log.info("new " + hashCode());
+ }
+
+ @Create
+ public void init() {
+ log.info("init");
+ }
+
+
public String selectResource() {
log.info("In select Resource, resId is " + resId + " resMode is " + resMode);
- if (resId != null)
+ if (resId != null) {
persistProperty(alertParameters, OperationsSender.RESOURCE_ID,resId);
+ cleanProperty(alertParameters,OperationsSender.OPERATION_NAME);
+ cleanProperty(alertParameters,OperationsSender.USABLE);
+
+ }
obtainOperationNames();
@@ -68,15 +94,47 @@ public class OperationsBackingBean extends CustomAlertSenderBackingBean {
public String selectOperation() {
log.info("In selectOperation, resId is " + resId + " opName is " + operationName);
- if (operationName != null )
+ if (operationName != null ) {
persistProperty(alertParameters, OperationsSender.OPERATION_NAME,operationName);
+ lookupConfiguration();
+ }
return ALERT_NOTIFICATIONS;
}
+ private void lookupConfiguration() {
+
+
+// log.info("getCD: " + configurationDefinition);
+ try {
+// Subject subject = EnterpriseFacesContextUtility.getSubject();
+ Subject subject = LookupUtil.getSubjectManager().getOverlord(); // TODO replace with real subject
+
+// int operationId = Integer.valueOf(FacesContextUtility.getRequiredRequestParameter("opId"));
+ OperationManagerLocal opMan = LookupUtil.getOperationManager();
+ obtainOperationNames();
+
+
+ OperationDefinition operationDefinition = opMan.getOperationDefinition(subject, operationName);
+ configurationDefinition = operationDefinition.getParametersConfigurationDefinition();
+
+
+ // call a SLSB method to get around lazy initialization of configDefs and configTemplates
+ ConfigurationManagerLocal configurationManager = LookupUtil.getConfigurationManager();
+ configuration = configurationManager.getConfigurationFromDefaultTemplate(configurationDefinition);
+// Configuration newConfiguration = configuration.deepCopy(false);
+log.info("gConfig: " + configuration + ", " + configuration.hashCode() + ", " + configuration.getSimpleValue("detailedDiscovery","-unset-"));
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
public String useConfiguration() {
- log.info("In useConfiguration");
+ log.info("In useConfiguration, Configuration is " + configuration );
+ // COnfiguration should be valid here ...
+ super.persistConfiguration(configuration);
+ persistProperty(alertParameters,OperationsSender.PARAMETERS_CONFIG,configuration.getId());
persistProperty(alertParameters, OperationsSender.USABLE,true);
return ALERT_NOTIFICATIONS;
@@ -94,7 +152,7 @@ public class OperationsBackingBean extends CustomAlertSenderBackingBean {
Subject subject = LookupUtil.getSubjectManager().getOverlord(); // TODO replace with real subject
List<OperationDefinition> opDefs = opMan.findSupportedResourceOperations(subject, resId, false);
for (OperationDefinition def : opDefs) {
- operationNames.put(def.getDisplayName(),def.getName()); // TODO add more distinctive stuff in display
+ operationNames.put(def.getDisplayName(),def.getId()); // TODO add more distinctive stuff in display
}
}
}
@@ -107,6 +165,7 @@ public class OperationsBackingBean extends CustomAlertSenderBackingBean {
public void setResMode(String resMode) {
this.resMode = resMode;
+ log.info("setResMode: " + resMode);
}
public Integer getResId() {
@@ -122,47 +181,104 @@ public class OperationsBackingBean extends CustomAlertSenderBackingBean {
public void setResId(Integer resId) {
this.resId = resId;
+ log.info("Set resid " + resId);
+ if (resId!=null) {
+ persistProperty(alertParameters,OperationsSender.RESOURCE_ID,resId);
+ }
}
- public String getOperationName() {
+ public String getResourceName() {
+ if (resId==null)
+ getResId();
+
+ if (resId!=null) {
+ ResourceManagerLocal resMgr = LookupUtil.getResourceManager();
+ Subject subject = LookupUtil.getSubjectManager().getOverlord(); // TODO replace with real subject
+ Resource res = resMgr.getResource(subject,resId);
+
+ resourceName = res.getName() + " (" + res.getResourceType().getName() + ")";
+ }
+ return resourceName;
+ }
+
+ public void setResourceName(String resourceName) {
+ this.resourceName = resourceName;
+ }
+
+ public Integer getOperationName() {
if (operationName==null) {
PropertySimple prop = alertParameters.getSimple(OperationsSender.OPERATION_NAME);
if (prop!=null)
- operationName = prop.getStringValue();
+ operationName = prop.getIntegerValue();
}
return operationName;
}
- public void setOperationName(String operationName) {
+ public void setOperationName(Integer operationName) {
this.operationName = operationName;
}
- public Map<String,String> getOperationNames() {
+ public Map<String, Integer> getOperationNames() {
obtainOperationNames();
return operationNames;
}
- public void setOperationNames(Map<String,String> operationNames) {
+ public void setOperationNames(Map<String, Integer> operationNames) {
this.operationNames = operationNames;
}
public ConfigurationDefinition getConfigurationDefinition() {
return configurationDefinition;
+
+
+
}
public void setConfigurationDefinition(ConfigurationDefinition configurationDefinition) {
+ log.info("set CD: " + configurationDefinition);
this.configurationDefinition = configurationDefinition;
}
public Configuration getConfiguration() {
+
return configuration;
+
+
}
public void setConfiguration(Configuration configuration) {
this.configuration = configuration;
+ log.info("setC: " + configuration);
}
+
+ public String getNullConfigurationDefinitionMessage() {
+ return "This operation does not take any parameters.";
+ }
+
+ public String getNullConfigurationMessage() {
+ return "This operation parameters definition has not been initialized.";
+ }
+
+ public String getTokenMode() {
+ if (tokenMode==null) {
+ PropertySimple prop = alertParameters.getSimple(OperationsSender.TOKEN_MODE);
+ if (prop!=null)
+ tokenMode = prop.getStringValue();
+ }
+
+ return tokenMode;
+ }
+
+ public void setTokenMode(String tokenMode) {
+ this.tokenMode = tokenMode;
+ log.info("token mode" + tokenMode);
+
+ persistProperty(alertParameters, OperationsSender.TOKEN_MODE,tokenMode);
+ }
+
+
}
diff --git a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsSender.java b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsSender.java
index 4fa9bba..4359ad4 100644
--- a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsSender.java
+++ b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/OperationsSender.java
@@ -18,14 +18,24 @@
*/
package org.rhq.enterprise.server.plugins.alertOperations;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.jboss.seam.ScopeType;
+import org.jboss.seam.annotations.Scope;
+
import org.rhq.core.domain.alert.Alert;
import org.rhq.core.domain.alert.notification.ResultState;
import org.rhq.core.domain.alert.notification.SenderResult;
import org.rhq.core.domain.auth.Subject;
+import org.rhq.core.domain.configuration.Configuration;
import org.rhq.core.domain.configuration.PropertySimple;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.enterprise.server.configuration.ConfigurationManagerLocal;
import org.rhq.enterprise.server.exception.ScheduleException;
import org.rhq.enterprise.server.operation.OperationManagerLocal;
import org.rhq.enterprise.server.operation.ResourceOperationSchedule;
@@ -36,12 +46,17 @@ import org.rhq.enterprise.server.util.LookupUtil;
* Alert sender that triggers an operation on the resource
* @author Heiko W. Rupp
*/
+@Scope(value = ScopeType.PAGE)
public class OperationsSender extends AlertSender {
private final Log log = LogFactory.getLog(OperationsSender.class);
static final String RESOURCE_ID = "resourceId";
static final String OPERATION_NAME = "operationName";
static final String USABLE = "usable";
+ protected static final String TOKEN_MODE = "tokenMode";
+ private static final String LITERAL = "literal";
+ private static final String INTERPRETED = "interpreted";
+ public static final String PARAMETERS_CONFIG = "parametersConfig";
@Override
public SenderResult send(Alert alert) {
@@ -52,7 +67,7 @@ public class OperationsSender extends AlertSender {
return new SenderResult(ResultState.FAILURE, "Not enough parameters given");
PropertySimple usableProp = alertParameters.getSimple(USABLE);
- if (usableProp==null || usableProp.getBooleanValue()== null || usableProp.getBooleanValue() == false)
+ if (usableProp==null || usableProp.getBooleanValue()== null || !usableProp.getBooleanValue())
return new SenderResult(ResultState.FAILURE,"Not yet configured");
Integer resourceId = resProp.getIntegerValue();
@@ -61,17 +76,53 @@ public class OperationsSender extends AlertSender {
OperationManagerLocal opMgr = LookupUtil.getOperationManager();
Subject subject = LookupUtil.getSubjectManager().getOverlord(); // TODO get real subject
+ PropertySimple parameterConfigProp = alertParameters.getSimple(PARAMETERS_CONFIG);
+ Configuration parameters = null ;
+ if (parameterConfigProp!=null) {
+ Integer paramId = parameterConfigProp.getIntegerValue();
+ if (paramId!=null) {
+ ConfigurationManagerLocal cmgr = LookupUtil.getConfigurationManager();
+ parameters = cmgr.getConfiguration(subject,paramId);
+ }
+ }
+
+
+ String tokenMode = alertParameters.getSimpleValue(TOKEN_MODE, LITERAL);
+
+ /*
+ * If we have parameters and the user wants tokens to be interpreted, then loop
+ * over the parameters and do token replacement.
+ */
+ if (parameters!=null && tokenMode.equals(INTERPRETED)) {
+ Map<String,PropertySimple> propsMap = parameters.getSimpleProperties();
+ if (!propsMap.isEmpty()) {
+ TokenReplacer tr = new TokenReplacer(alert);
+ for (PropertySimple prop : propsMap.values()) {
+ String tmp = prop.getStringValue();
+ tmp = tr.replaceTokens(tmp);
+ prop.setStringValue(tmp);
+ }
+ }
+ }
+
+
+
+ /*
+ * Now fire off the operation with no delay and no repetition.
+ */
ResourceOperationSchedule sched;
try {
- sched = opMgr.scheduleResourceOperation(subject, resourceId, opName, 0, 0, 0, 0, null,
+ sched = opMgr.scheduleResourceOperation(subject, resourceId, opName, 0, 0, 0, 0, parameters,
"Alert operation for " + alert.getAlertDefinition().getName());
} catch (ScheduleException e) {
return new SenderResult(ResultState.FAILURE, "Scheduling of operation " + opName + " on resource " + resourceId + " failed: " + e.getMessage());
}
- // TODO evaluate retuen of schedule() call and defer, so we can leter check
- // If op sending was successfull
+ // If op sending was successful
return new SenderResult(ResultState.SUCCESS, "Scheduled operation " + opName + " on resource " + resourceId + " with jobId " + sched.getJobId() );
}
+
+
+
}
diff --git a/modules/enterprise/server/plugins/alert-operations/src/main/resources/operations.xhtml b/modules/enterprise/server/plugins/alert-operations/src/main/resources/operations.xhtml
index 1fd74ad..4a6c0e6 100644
--- a/modules/enterprise/server/plugins/alert-operations/src/main/resources/operations.xhtml
+++ b/modules/enterprise/server/plugins/alert-operations/src/main/resources/operations.xhtml
@@ -29,12 +29,18 @@
<h:commandButton id="resourceIdSubmit"
value="Select"
type="submit"
- action="#{operationsBean.selectResource}" />
+ action="#{operationsBean.selectResource}"
+ styleClass="buttonmed"
+ />
</rich:panel>
</h:panelGroup>
- <h:panelGroup style="width:60%">
+ <h:panelGroup style="width:60%; vertical-align:top;" >
<rich:panel rendered="#{not empty operationsBean.operationNames}">
+
+ Operations for: <h:outputText value=" #{operationsBean.resourceName}"/>
+ <br/>
+
<h:selectOneMenu id="selectOperationMenu" value="#{operationsBean.operationName}">
<f:selectItems value="#{operationsBean.operationNames}"/>
</h:selectOneMenu>
@@ -42,31 +48,40 @@
<h:commandButton id="opNameSubmit"
value="Select"
type="submit"
- action="#{operationsBean.selectOperation}" />
+ action="#{operationsBean.selectOperation}"
+ styleClass="buttonmed"
+ />
</rich:panel>
</h:panelGroup>
</h:panelGrid>
<p/>
<h:panelGroup style="width:100%">
- <h:outputText value="3rd panel : "/>
- <h:outputText value="#{operationsBean.operationName}"/>
- <br/>
+ <h:messages />
<rich:panel rendered="#{not empty operationsBean.operationName}">
+ <br/>
+ Parameters for <h:outputText value=" #{operationsBean.operationName}"/>
+ <p/>
+ <h:selectOneMenu id="tokenModeMenu" value="#{operationsBean.tokenMode}">
+ <f:selectItem itemValue="literal" itemLabel="Literal"/>
+ <f:selectItem itemValue="interpreted" itemLabel="Interpreted"/>
+ </h:selectOneMenu>
+ <p/>
<onc:config configurationDefinition="#{operationsBean.configurationDefinition}"
configuration="#{operationsBean.configuration}"
- nullConfigurationDefinitionMessage="NUll configuration definition"
- nullConfigurationMessage="null configuration"
+ nullConfigurationDefinitionMessage="#{operationsBean.nullConfigurationDefinitionMessage}"
+ nullConfigurationMessage="#{nullConfigurationMessage}"
nullConfigurationStyle="InfoBlock"
-
- id="opParamConfiguration"
+ readOnly="false"
/>
<p/>
<h:commandButton id="opParamSubmit"
value="Set"
type="submit"
- action="#{operationsBean.useConfiguration}" />
+ action="#{operationsBean.useConfiguration}"
+ styleClass="buttonmed"
+ />
</rich:panel>
</h:panelGroup>
</body>
-</html>
\ No newline at end of file
+</html>
commit b196e883688008615778ad6eb73fb94caff12015
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Tue Feb 23 10:56:59 2010 +0100
Implement code for token replacement
diff --git a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/Token.java b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/Token.java
new file mode 100644
index 0000000..bcd7570
--- /dev/null
+++ b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/Token.java
@@ -0,0 +1,72 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-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 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.server.plugins.alertOperations;
+
+import java.util.EnumSet;
+
+/**
+ * Tokens that can be replaced in
+ * @author Heiko W. Rupp
+ */
+public enum Token {
+
+ // Alert related tokens
+ ALERT_ID(TokenClass.ALERT, "id"),
+ ALERT_URL(TokenClass.ALERT, "url"),
+
+ // resource that triggered the alert related tokens
+ RESOURCE_ID(TokenClass.RESOURCE, "id"),
+ RESOURCE_NAME(TokenClass.RESOURCE, "name"),
+
+
+ // resource the operation is run on related tokens
+ TRESOURCE_ID(TokenClass.TARGET_RESOURCE, "id"),
+ TRESOURCE_NAME(TokenClass.TARGET_RESOURCE, "name"),
+
+
+ // only for testing
+ TEST_ECHO(TokenClass.TEST,"echo"),
+ TEST_FIX(TokenClass.TEST,"fix")
+
+ ;
+
+
+ private String text;
+
+ private Token(TokenClass tc, String text) {
+
+ this.text = tc.getText() + "." + text;
+ }
+
+ /**
+ * Return the token that matches the input text or null if not found.
+ * The token delimiters need to be already stripped from the input
+ * @param input a token text like <i>alert.id</i>, which would return the
+ * <i>ALERT_ID</i> token.
+ * @return The matching token or null if not found
+ */
+ public static Token getByText(String input) {
+ EnumSet<Token> es = EnumSet.allOf(Token.class);
+ for (Token t : es) {
+ if (t.text.equals(input))
+ return t;
+ }
+ return null;
+ }
+}
diff --git a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/TokenClass.java b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/TokenClass.java
new file mode 100644
index 0000000..5125a72
--- /dev/null
+++ b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/TokenClass.java
@@ -0,0 +1,59 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-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 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.server.plugins.alertOperations;
+
+import java.util.EnumSet;
+
+/**
+ * Class a @See{Token} can be in.
+ * @author Heiko W. Rupp
+ */
+public enum TokenClass {
+
+ ALERT("alert"),
+ RESOURCE("resource"),
+ TARGET_RESOURCE("targetResource"),
+ TEST("test");
+
+ private String text;
+
+ private TokenClass(String text) {
+ this.text = text;
+ }
+
+ public String getText() {
+ return text;
+ }
+
+ /**
+ * Return the tokenclass that matches the input text or null if not found.
+ * The token delimiters need to be already stripped from the input
+ * @param input a token text like <i>alert</i>, which would return the
+ * <i>ALERT</i> token class.
+ * @return The matching token class or null if not found
+ */
+ public static TokenClass getByText(String input) {
+ EnumSet<TokenClass> es = EnumSet.allOf(TokenClass.class);
+ for (TokenClass t : es) {
+ if (t.text.equals(input))
+ return t;
+ }
+ return null;
+ }
+}
diff --git a/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/TokenReplacer.java b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/TokenReplacer.java
new file mode 100644
index 0000000..0b230b4
--- /dev/null
+++ b/modules/enterprise/server/plugins/alert-operations/src/main/java/org/rhq/enterprise/server/plugins/alertOperations/TokenReplacer.java
@@ -0,0 +1,178 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-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 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.server.plugins.alertOperations;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.rhq.core.domain.alert.Alert;
+import org.rhq.core.domain.resource.Resource;
+
+/**
+ * Helper to replace tokens by their values
+ * @author Heiko W. Rupp
+ */
+public class TokenReplacer {
+
+ private final Log log = LogFactory.getLog(TokenReplacer.class);
+ private static final String NOT_YET_IMPLEMENTED = " - not yet implemented -";
+ protected static final String THE_QUICK_BROWN_FOX_JUMPS_OVER_THE_LAZY_DOG = "TheQuickBrownFoxJumpsOverTheLazyDOg";
+ private Alert alert;
+ private Pattern pattern;
+
+ public TokenReplacer(Alert alert) {
+ this.alert = alert;
+ pattern = Pattern.compile("<%\\s*([a-z]+\\.[a-z0-9]+)\\s*%>");
+ }
+
+ /**
+ * Replace all tokens on the input line. If no tokens are found the input is returned.
+ * Tokens have the form '<i><% class.sub %></i>'
+ * @param input a line of text
+ * @return input with tokens replaced.
+ * @see org.rhq.enterprise.server.plugins.alertOperations.Token
+ * @see org.rhq.enterprise.server.plugins.alertOperations.TokenClass
+ */
+ public String replaceTokens(String input) {
+
+ String work = input;
+ Matcher matcher = pattern.matcher(work);
+ if (!matcher.find()) {
+ log.warn("No tokens found in " + input);
+ return input;
+ }
+ matcher.reset();
+
+ do {
+// System.out.println(input);
+ matcher = pattern.matcher(work);
+ if (!matcher.find()) {
+ break;
+ }
+// System.out.println(matcher.regionStart() + ":" + matcher.regionEnd() + input.substring(matcher.regionStart(),matcher.regionEnd()));
+// System.out.println(matcher.group(1));
+ String replacement = replaceToken(matcher.group(1) );
+ String s = matcher.replaceFirst(replacement);
+// System.out.println(s);
+ work = s;
+
+// System.out.println("----");
+ } while (true);
+
+ return work;
+ }
+
+
+
+ /**
+ * Replace the token string passed (without the token delimiters ) with the actual value
+ * @param tokenString Input like alert.id
+ * @return replacement string or the input if the token was not valid.
+ */
+ public String replaceToken(String tokenString) {
+
+ // Ok, we have at least one token. Now split the tokenString and loop over the tokens
+
+ if (!tokenString.contains("."))
+ return tokenString;
+
+ String tmp = tokenString.substring(0, tokenString.indexOf("."));
+ TokenClass tc = TokenClass.getByText(tmp);
+ if (tc==null) {
+ log.warn("Unknown token class in [" + tokenString + "], not replacing tokens");
+ return tokenString;
+ }
+
+ Token token = Token.getByText(tokenString);
+ if (token == null) {
+ log.warn("No known token found in [" + tokenString + "], not replacing token");
+ return tokenString;
+ }
+ String ret = null;
+ switch (tc) {
+ case ALERT:
+ ret = replaceAlertToken(token,alert);
+ break;
+ case RESOURCE:
+ ret = replaceResourceToken(token,alert.getAlertDefinition().getResource());
+ break;
+ case TARGET_RESOURCE:
+ Resource resource = null; // TODO
+ ret = replaceTargetResourceToken(token, resource);
+ break;
+ case TEST:
+ switch (token) {
+ case TEST_ECHO:
+ ret = tokenString;
+ break;
+ case TEST_FIX:
+ ret = THE_QUICK_BROWN_FOX_JUMPS_OVER_THE_LAZY_DOG;
+ break;
+ default:
+ ret = NOT_YET_IMPLEMENTED;
+ }
+ break;
+ }
+ return ret;
+ }
+
+ private String replaceAlertToken(Token token, Alert alert) {
+
+ switch (token) {
+ case ALERT_ID:
+ return String.valueOf(alert.getId());
+ case ALERT_URL:
+ return NOT_YET_IMPLEMENTED;
+
+ default:
+ return NOT_YET_IMPLEMENTED;
+ }
+
+ }
+
+ private String replaceResourceToken(Token token, Resource resource) {
+
+ switch (token) {
+ case RESOURCE_ID:
+ return String.valueOf(resource.getId());
+ case RESOURCE_NAME:
+ return resource.getName();
+
+ default:
+ return NOT_YET_IMPLEMENTED;
+ }
+ }
+
+ private String replaceTargetResourceToken(Token token, Resource resource) {
+
+ switch (token) {
+ case TRESOURCE_ID:
+ return String.valueOf(resource.getId());
+ case TRESOURCE_NAME:
+ return resource.getName();
+
+ default:
+ return NOT_YET_IMPLEMENTED;
+ }
+ }
+
+}
diff --git a/modules/enterprise/server/plugins/alert-operations/src/test/java/org/rhq/enterprise/server/plugins/alertOperations/TokenReplacementTest.java b/modules/enterprise/server/plugins/alert-operations/src/test/java/org/rhq/enterprise/server/plugins/alertOperations/TokenReplacementTest.java
new file mode 100644
index 0000000..f41fc85
--- /dev/null
+++ b/modules/enterprise/server/plugins/alert-operations/src/test/java/org/rhq/enterprise/server/plugins/alertOperations/TokenReplacementTest.java
@@ -0,0 +1,135 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-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 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.server.plugins.alertOperations;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.testng.annotations.Test;
+
+import org.rhq.core.domain.alert.Alert;
+import org.rhq.core.domain.alert.AlertDefinition;
+import org.rhq.core.domain.resource.Resource;
+
+/**
+ * // TODO: Document this
+ * @author Heiko W. Rupp
+ */
+@Test
+public class TokenReplacementTest {
+
+ private final Log log = LogFactory.getLog(TokenReplacementTest.class);
+ private static final String TEST_ECHO = "test.echo";
+ private static final String FOO_BAR = "fooBar";
+ private static final String FOO_DOT_BAR = "foo.bar";
+ private static final String ALERT_BAR = "alert.bar";
+
+ public void testSimpleReplacement() throws Exception {
+
+ Alert al = new Alert();
+ TokenReplacer tr = new TokenReplacer(al);
+
+
+ String res = tr.replaceToken("test.fix");
+ assert res != null;
+ assert res.equals(TokenReplacer.THE_QUICK_BROWN_FOX_JUMPS_OVER_THE_LAZY_DOG);
+
+ res = tr.replaceToken(TEST_ECHO);
+ assert res != null;
+ assert res.equals(TEST_ECHO);
+
+ res = tr.replaceToken("alert.id");
+ assert res != null;
+ assert res.equals("0");
+
+ Resource r = new Resource(1234);
+ r.setName("A resource");
+ AlertDefinition def = new AlertDefinition();
+ def.setResource(r);
+ al = new Alert(def, System.currentTimeMillis());
+ tr = new TokenReplacer(al);
+
+ res = tr.replaceToken("resource.id");
+ assert "1234".equals(res);
+ res = tr.replaceToken("resource.name");
+ assert "A resource".equals(res);
+ }
+
+ public void testInvalidTokenString() {
+
+ Alert al = new Alert();
+ TokenReplacer tr = new TokenReplacer(al);
+
+
+ String res = tr.replaceToken(FOO_BAR);
+ assert res != null;
+ assert res.equals(FOO_BAR);
+
+ res = tr.replaceToken(FOO_DOT_BAR);
+ assert res != null;
+ assert res.equals(FOO_DOT_BAR);
+
+ res = tr.replaceToken(ALERT_BAR);
+ assert res != null;
+ assert res.equals(ALERT_BAR);
+
+ }
+
+ public void testFullTokenSimple() {
+
+ Alert al = new Alert();
+ TokenReplacer tr = new TokenReplacer(al);
+
+
+ String res = tr.replaceTokens("<%test.fix%>");
+ assert res != null;
+ assert !res.equals("<%test.fix%>") : "Res was " + res;
+ assert res.equals(TokenReplacer.THE_QUICK_BROWN_FOX_JUMPS_OVER_THE_LAZY_DOG);
+
+ String TF2 = "<% test.fix %>";
+ res = tr.replaceTokens(TF2);
+ assert res != null;
+ assert !res.equals(TF2) : "Res was " + res;
+
+ String TF3 = "<% test.fix %>";
+ res = tr.replaceTokens(TF3);
+ assert res != null;
+ assert !res.equals(TF3) : "Res was " + res;
+
+ String TF4 = "<% test.fix%> xXx <% test.echo%>";
+ res = tr.replaceTokens(TF4);
+ assert res != null;
+ assert !res.equals(TF4) : "Res was " + res;
+
+ res = tr.replaceTokens(FOO_BAR);
+ assert res != null;
+ assert res.equals(FOO_BAR) : "Res was " + res;
+
+ Resource r = new Resource(1234);
+ r.setName("A resource");
+ AlertDefinition def = new AlertDefinition();
+ def.setResource(r);
+ al = new Alert(def, System.currentTimeMillis());
+
+ tr = new TokenReplacer(al);
+ res = tr.replaceTokens("<% test.fix%><%resource.id%>");
+ assert res!=null;
+ assert res.equals(TokenReplacer.THE_QUICK_BROWN_FOX_JUMPS_OVER_THE_LAZY_DOG+"1234");
+ }
+
+}
commit e60d5bc39ad9c103e072eaa1e8fca7a0aedb9191
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Mon Feb 22 21:35:49 2010 +0100
If no emails failed, we can set the state to success
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 ff4025f..c21bf21 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
@@ -739,6 +739,16 @@ public class AlertManagerBean implements AlertManagerLocal, AlertManagerRemote {
}
if (anl.getResultState()==ResultState.FAILED_EMAIL)
anl.setBadEmails(StringUtils.getListAsString(badList,","));
+ if (anl.getResultState()==ResultState.DEFERRED_EMAIL && badList.isEmpty())
+ anl.setResultState(ResultState.SUCCESS);
+ }
+ }
+ else { // No bad addresses
+ // Only set the result state to success for email sending notifications
+ // We must not set them if the notification failed.
+ for (AlertNotificationLog anl : alert.getAlertNotificationLogs()) {
+ if (anl.getResultState()==ResultState.DEFERRED_EMAIL)
+ anl.setResultState(ResultState.SUCCESS);
}
}
commit a57abc5879531e4f58cc16f6fcd6655fdb035b77
Author: Heiko W. Rupp <hwr(a)redhat.com>
Date: Mon Feb 22 12:14:53 2010 +0100
Fix link from alert templates list to the view alert page. BZ 566896
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/listAlertTemplates.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/listAlertTemplates.xhtml
index b7131e8..2f30a9c 100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/listAlertTemplates.xhtml
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/admin/listAlertTemplates.xhtml
@@ -28,7 +28,7 @@
</ui:define>
<ui:define name="body">
-
+
<br/>
<h:messages showSummary="true"
showDetail="true"
@@ -39,10 +39,10 @@
globalOnly="true"
layout="table"
width="100%"/>
-
+
<h:form id="alertTemplatesListForm">
<input type="hidden" name="type" value="${param.type}"/>
-
+
<rich:panel>
<f:facet name="header">
<h:outputText value="#{ResourceTypeUIBean.name} Alert Templates"/>
@@ -66,50 +66,49 @@
<f:facet name="PageControlView">
<onc:paginationControl id="AlertTemplatesList" />
</f:facet>
-
+
<rich:column>
<f:facet name="header">
<onc:allSelect target="selectedAlertTemplates" />
</f:facet>
-
+
<onc:select name="selectedAlertTemplates" value="#{item.id}" />
</rich:column>
-
+
<rich:column rendered="#{param.debug}">
<f:facet name="header">
<onc:sortableColumnHeader sort="a.id">
<h:outputText styleClass="headerText" value="ID" />
</onc:sortableColumnHeader>
</f:facet>
-
+
<h:outputText value="#{item.id}"/>
</rich:column>
-
+
<rich:column>
<f:facet name="header">
<onc:sortableColumnHeader sort="a.name">
<h:outputText styleClass="headerText" value="Name" />
</onc:sortableColumnHeader>
</f:facet>
-
- <h:outputLink value="/alerts/Config.do">
- <f:param name="mode" value="viewRoles"/>
+
+ <h:outputLink value="/rhq/resource/alert/viewAlert.xhtml">
<f:param name="type" value="#{param.type}"/>
<f:param name="ad" value="#{item.id}"/>
<h:outputText value="#{item.name}" />
</h:outputLink>
</rich:column>
-
+
<rich:column>
<f:facet name="header">
<onc:sortableColumnHeader sort="a.description">
<h:outputText styleClass="headerText" value="Description" />
</onc:sortableColumnHeader>
</f:facet>
-
+
<h:outputText value="#{item.description}"/>
</rich:column>
-
+
<rich:column>
<f:facet name="header">
<onc:sortableColumnHeader sort="a.ctime">
@@ -121,14 +120,14 @@
<f:converter converterId="UserDateTimeConverter" />
</h:outputText>
</rich:column>
-
+
<rich:column>
<f:facet name="header">
<onc:sortableColumnHeader sort="a.enabled">
<h:outputText styleClass="headerText" value="Active" />
</onc:sortableColumnHeader>
</f:facet>
-
+
<h:outputText value="#{item.enabled}"/>
</rich:column>
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/viewAlert.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/viewAlert.xhtml
index dcfff68..a987e65 100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/viewAlert.xhtml
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/viewAlert.xhtml
@@ -15,8 +15,18 @@
xmlns:a4j="https://ajax4jsf.dev.java.net/ajax"
xmlns:rich="http://richfaces.ajax4jsf.org/rich">
+ <c:choose>
+ <c:when test="#{not empty param.type}">
+ <c:set var="title" value="Definition for '#{alertDefinition.name}' on resource type '#{ResourceTypeUIBean.name}'"/>
+ </c:when>
+ <c:otherwise>
+ <c:set var="title" value="Definition for '#{alertDefinition.name}' on resource '#{alertDefinition.resource.name}'"/>
+ </c:otherwise>
+ </c:choose>
+
<ui:composition template="/rhq/layout/main.xhtml">
- <ui:param name="pageTitle" value="Definition for '#{alertDefinition.name}' on resource '#{alertDefinition.resource.name}'"/>
+ <ui:param name="pageTitle" value="#{title}"/>
+
<ui:define name="metaHeaders">
<style>
@@ -49,11 +59,21 @@
<f:param name="ad" value="#{alertDefinition.id}" />
<h:outputText value=" Definition for '#{alertDefinition.name}' "/>
</h:outputLink>
- <h:outputText> on resource </h:outputText>
- <h:outputLink value="/rhq/resource/summary/overview.xhtml">
- <f:param name="id" value="#{alertDefinition.resource.id}" />
- <h:outputText value=" '#{alertDefinition.resource.name}'" />
- </h:outputLink>
+ <c:choose>
+ <c:when test="#{not empty param.type}">
+ <h:outputText> on resource type </h:outputText>
+ <h:outputLink value="/rhq/admin/listAlertTemplates.xhtml?type=${param.type}">
+ <h:outputText value=" #{ResourceTypeUIBean.name}"/>
+ </h:outputLink>
+ </c:when>
+ <c:otherwise>
+ <h:outputText> on resource </h:outputText>
+ <h:outputLink value="/rhq/resource/summary/overview.xhtml">
+ <f:param name="id" value="#{alertDefinition.resource.id}" />
+ <h:outputText value=" '#{alertDefinition.resource.name}'" />
+ </h:outputLink>
+ </c:otherwise>
+ </c:choose>
</ui:define>
<ui:define name="body">
@@ -170,10 +190,19 @@
<br />
<br />
- <h:outputLink value="/rhq/resource/alert/listAlertDefinitions.xhtml">
- <f:param name="id" value="#{alertDefinition.resource.id}"/>
- <h:outputText value="Back to Alert Definitions for Resource '#{alertDefinition.resource.name}'"/>
- </h:outputLink>
+ <c:choose>
+ <c:when test="#{not empty param.type}">
+ <h:outputLink value="/rhq/admin/listAlertTemplates.xhtml?type=${param.type}">
+ <h:outputText value="Back to Alert Definitions for Resource Type '#{ResourceTypeUIBean.name}'"/>
+ </h:outputLink>
+ </c:when>
+ <c:otherwise>
+ <h:outputLink value="/rhq/resource/alert/listAlertDefinitions.xhtml">
+ <f:param name="id" value="#{alertDefinition.resource.id}"/>
+ <h:outputText value="Back to Alert Definitions for Resource '#{alertDefinition.resource.name}'"/>
+ </h:outputLink>
+ </c:otherwise>
+ </c:choose>
<rich:modalPanel id="addAlertFromTemplatePanel" moveable="false" autosized="true">
<f:facet name="header">
@@ -230,4 +259,4 @@
</ui:define>
</ui:composition>
-</html>
\ No newline at end of file
+</html>
commit 3602414a6baff7fb52d637d2006574610212b46f
Author: Heiko W. Rupp <pilhuhn(a)fedorapeople.org>
Date: Sat Feb 20 10:49:01 2010 +0100
Fix potential NPE
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/AlertNotificationLog.java b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/AlertNotificationLog.java
index 5ed6d4f..b90def3 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/AlertNotificationLog.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/AlertNotificationLog.java
@@ -113,8 +113,8 @@ public class AlertNotificationLog implements Serializable {
@PrePersist
@PreUpdate
public void trimMessage() {
- if (message.length()>255)
- message = message.substring(0,254);
+ if (message!=null && message.length()>255)
+ message = message.substring(0,255);
}
protected AlertNotificationLog() {
commit 1c26e0f7c827ae7a250b4de583d6ce623ca3ff50
Merge: 32b3daf... e1c7603...
Author: Heiko W. Rupp <pilhuhn(a)fedorapeople.org>
Date: Sat Feb 20 09:52:53 2010 +0100
Merge branch 'master' into alertPlugin
commit 32b3daf0e818830cabf9797197666b8059472ba5
Author: Heiko W. Rupp <pilhuhn(a)fedorapeople.org>
Date: Sat Feb 20 09:47:10 2010 +0100
Truncate the message at 140 chars, as identi.ca bails out on longer messages; seems to improve stability with Twitter too.
Introduce abbreviated versions of the messages as space on Microblog etc is scarce. BZ 555091
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/AlertNotificationLog.java b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/AlertNotificationLog.java
index ba75940..5ed6d4f 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/AlertNotificationLog.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/alert/notification/AlertNotificationLog.java
@@ -38,6 +38,8 @@ import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
+import javax.persistence.PrePersist;
+import javax.persistence.PreUpdate;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Transient;
@@ -108,6 +110,13 @@ public class AlertNotificationLog implements Serializable {
@Transient
transient List<String> transientEmails = new ArrayList<String>();
+ @PrePersist
+ @PreUpdate
+ public void trimMessage() {
+ if (message.length()>255)
+ message = message.substring(0,254);
+ }
+
protected AlertNotificationLog() {
} // JPA
@@ -130,7 +139,6 @@ public class AlertNotificationLog implements Serializable {
public AlertNotificationLog(Alert alert, String senderName, ResultState state, String message) {
this.alert = alert;
- this.sender = sender;
this.resultState = state;
this.message = message;
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 454b9a9..ff4025f 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
@@ -780,7 +780,7 @@ public class AlertManagerBean implements AlertManagerLocal, AlertManagerRemote {
Map<String, String> alertMessage = emailManager.getAlertEmailMessage(
prettyPrintResourceHierarchy(alertDefinition.getResource()), alertDefinition.getResource().getName(),
alertDefinition.getName(), alertDefinition.getPriority().toString(), new Date(alert.getCtime()).toString(),
- prettyPrintAlertConditions(alert.getConditionLogs()), prettyPrintAlertURL(alert));
+ prettyPrintAlertConditions(alert.getConditionLogs(), false), prettyPrintAlertURL(alert));
String messageSubject = alertMessage.keySet().iterator().next();
String messageBody = alertMessage.values().iterator().next();
@@ -834,13 +834,14 @@ public class AlertManagerBean implements AlertManagerLocal, AlertManagerRemote {
/**
* Create a human readable description of the conditions that led to this alert.
* @param alert Alert to create human readable condition description
+ * @param shortVersion if true the messages printed are abbreviated to save space
* @return human readable condition log
*/
- public String prettyPrintAlertConditions(Alert alert) {
- return prettyPrintAlertConditions(alert.getConditionLogs());
+ public String prettyPrintAlertConditions(Alert alert, boolean shortVersion) {
+ return prettyPrintAlertConditions(alert.getConditionLogs(), shortVersion);
}
- private String prettyPrintAlertConditions(Set<AlertConditionLog> conditionLogs) {
+ private String prettyPrintAlertConditions(Set<AlertConditionLog> conditionLogs, boolean shortVersion) {
StringBuilder builder = new StringBuilder();
int conditionCounter = 1;
@@ -858,16 +859,27 @@ public class AlertManagerBean implements AlertManagerLocal, AlertManagerRemote {
builder.append(NEW_LINE);
- builder.append(AlertI18NFactory.getMessage(AlertI18NResourceKeys.ALERT_EMAIL_CONDITION_LOG_FORMAT,
- conditionCounter, prettyPrintAlertCondition(aLog.getCondition()), new SimpleDateFormat(
- "yyyy/MM/dd HH:mm:ss z").format(new Date(aLog.getCtime())), formattedValue));
+ String format;
+ if (shortVersion)
+ format = AlertI18NResourceKeys.ALERT_EMAIL_CONDITION_LOG_FORMAT_SHORT;
+ else
+ format = AlertI18NResourceKeys.ALERT_EMAIL_CONDITION_LOG_FORMAT;
+ SimpleDateFormat dateFormat;
+ if (shortVersion)
+ dateFormat= new SimpleDateFormat(
+ "yy/MM/dd HH:mm:ss z");
+ else
+ dateFormat= new SimpleDateFormat(
+ "yyyy/MM/dd HH:mm:ss z");
+ builder.append(AlertI18NFactory.getMessage(format,
+ conditionCounter, prettyPrintAlertCondition(aLog.getCondition(), shortVersion), dateFormat.format(new Date(aLog.getCtime())), formattedValue));
conditionCounter++;
}
return builder.toString();
}
- private String prettyPrintAlertCondition(AlertCondition condition) {
+ private String prettyPrintAlertCondition(AlertCondition condition, boolean shortVersion) {
StringBuilder builder = new StringBuilder();
AlertConditionCategory category = condition.getCategory();
@@ -915,19 +927,38 @@ public class AlertManagerBean implements AlertManagerLocal, AlertManagerRemote {
}
} else if ((category == AlertConditionCategory.RESOURCE_CONFIG) || (category == AlertConditionCategory.CHANGE)
|| (category == AlertConditionCategory.TRAIT)) {
- builder.append(AlertI18NFactory.getMessage(AlertI18NResourceKeys.ALERT_CURRENT_LIST_VALUE_CHANGED));
+
+ if (shortVersion)
+ builder.append(AlertI18NFactory.getMessage(AlertI18NResourceKeys.ALERT_CURRENT_LIST_VALUE_CHANGED_SHORT));
+ else
+ builder.append(AlertI18NFactory.getMessage(AlertI18NResourceKeys.ALERT_CURRENT_LIST_VALUE_CHANGED));
+
} else if (category == AlertConditionCategory.EVENT) {
if ((condition.getOption() != null) && (condition.getOption().length() > 0)) {
+ String propsCbEventSeverityRegexMatch;
+ if (shortVersion)
+ propsCbEventSeverityRegexMatch = AlertI18NResourceKeys.ALERT_CONFIG_PROPS_CB_EVENT_SEVERITY_REGEX_MATCH_SHORT;
+ else
+ propsCbEventSeverityRegexMatch = AlertI18NResourceKeys.ALERT_CONFIG_PROPS_CB_EVENT_SEVERITY_REGEX_MATCH;
+
builder.append(AlertI18NFactory.getMessage(
- AlertI18NResourceKeys.ALERT_CONFIG_PROPS_CB_EVENT_SEVERITY_REGEX_MATCH, condition.getName(),
+ propsCbEventSeverityRegexMatch, condition.getName(),
condition.getOption()));
} else {
- builder.append(AlertI18NFactory.getMessage(AlertI18NResourceKeys.ALERT_CONFIG_PROPS_CB_EVENT_SEVERITY,
- condition.getName()));
+ if (shortVersion)
+ builder.append(AlertI18NFactory.getMessage(AlertI18NResourceKeys.ALERT_CONFIG_PROPS_CB_EVENT_SEVERITY_SHORT,
+ condition.getName()));
+ else
+ builder.append(AlertI18NFactory.getMessage(AlertI18NResourceKeys.ALERT_CONFIG_PROPS_CB_EVENT_SEVERITY,
+ condition.getName()));
}
} else if (category == AlertConditionCategory.AVAILABILITY) {
- builder.append(AlertI18NFactory.getMessage(AlertI18NResourceKeys.ALERT_CONFIG_PROPS_CB_AVAILABILITY,
- condition.getOption()));
+ if (shortVersion)
+ builder.append(AlertI18NFactory.getMessage(AlertI18NResourceKeys.ALERT_CONFIG_PROPS_CB_AVAILABILITY_SHORT,
+ condition.getOption()));
+ else
+ builder.append(AlertI18NFactory.getMessage(AlertI18NResourceKeys.ALERT_CONFIG_PROPS_CB_AVAILABILITY,
+ condition.getOption()));
} else {
// do nothing
}
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 996f245..e482ffa 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
@@ -96,9 +96,10 @@ public interface AlertManagerLocal {
/**
* Create a human readable description of the conditions that led to this alert.
* @param alert Alert to create human readable condition description
+ * @param shortVersion if true the messages printed are abbreviated to save space
* @return human readable condition log
*/
- String prettyPrintAlertConditions(Alert alert);
+ String prettyPrintAlertConditions(Alert alert, boolean shortVersion);
/**
* Tells us if the definition of the passed alert will be disabled after this alert was fired
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/i18n/AlertI18NResourceKeys.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/i18n/AlertI18NResourceKeys.java
index 8734771..1de3d85 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/i18n/AlertI18NResourceKeys.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/alert/i18n/AlertI18NResourceKeys.java
@@ -32,20 +32,41 @@ public interface AlertI18NResourceKeys {
@I18NMessage(locale = "de", value = "Verfgbarkeit wird {0}") })
String ALERT_CONFIG_PROPS_CB_AVAILABILITY = "alert.config.props.CB.Availability";
+ @I18NMessages( { @I18NMessage("Avail goes {0}"),
+ @I18NMessage(locale = "de", value = "Verf. wird {0}") })
+ String ALERT_CONFIG_PROPS_CB_AVAILABILITY_SHORT = "alert.config.props.CB.Availability.short";
+
@I18NMessages( { @I18NMessage("Event Severity: {0}"),
@I18NMessage(locale = "de", value = "Schwere des Ereignesses: {0}") })
String ALERT_CONFIG_PROPS_CB_EVENT_SEVERITY = "alert.config.props.CB.EventSeverity";
+ @I18NMessages( { @I18NMessage("Sev: {0}"),
+ @I18NMessage(locale = "de", value = "Schwere: {0}") })
+ String ALERT_CONFIG_PROPS_CB_EVENT_SEVERITY_SHORT = "alert.config.props.CB.EventSeverity.short";
+
@I18NMessages( { @I18NMessage("Event Severity: {0} and matching expression \"{1}\""),
@I18NMessage(locale = "de", value = "Schwere des Ereignesses: {0} und zugehriger Ausdruck \"{1}\"") })
String ALERT_CONFIG_PROPS_CB_EVENT_SEVERITY_REGEX_MATCH = "alert.config.props.CB.EventSeverity.RegexMatch";
+ @I18NMessages( { @I18NMessage("Sev: {0} & exp \"{1}\""),
+ @I18NMessage(locale = "de", value = "Schwere: {0} & Ausdruck \"{1}\"") })
+ String ALERT_CONFIG_PROPS_CB_EVENT_SEVERITY_REGEX_MATCH_SHORT = "alert.config.props.CB.EventSeverity.RegexMatch.short";
+
@I18NMessages( { @I18NMessage("value changed"), @I18NMessage(locale = "de", value = "Der Wert hat sich gendert") })
String ALERT_CURRENT_LIST_VALUE_CHANGED = "alert.current.list.ValueChanged";
+ @I18NMessages( { @I18NMessage("val chg"), @I18NMessage(locale = "de", value = "Wertnd.") })
+ String ALERT_CURRENT_LIST_VALUE_CHANGED_SHORT = "alert.current.list.ValueChanged.short";
+
@I18NMessages( {
@I18NMessage("\\ - Condition {0}: {1}\\n\\\n" + "\\ - Date/Time: {2}\\n\\\n" + "\\ - Details: {3}\\n\\\n"),
@I18NMessage(locale = "de", value = " - Bedingung {0}: {1}\\n\\\n - Datum/Uhrzeit: {2}\\n\\\n"
+ "\\ - Details: {3}\\n\\\n") })
String ALERT_EMAIL_CONDITION_LOG_FORMAT = "alert.email.condition.log.format";
+
+ @I18NMessages( {
+ @I18NMessage("\\ - Cond {0}: {1}\\n\\\n" + "\\ - Time: {2}\\n\\\n" + "\\ - Det: {3}\\n\\\n"),
+ @I18NMessage(locale = "de", value = " - Bed {0}: {1}\\n\\\n - Zeit: {2}\\n\\\n"
+ + "\\ - Det: {3}\\n\\\n") })
+ String ALERT_EMAIL_CONDITION_LOG_FORMAT_SHORT = "alert.email.condition.log.format.short";
}
\ No newline at end of file
diff --git a/modules/enterprise/server/plugins/alert-irc/src/main/java/org/rhq/enterprise/server/plugins/alertIrc/IrcSender.java b/modules/enterprise/server/plugins/alert-irc/src/main/java/org/rhq/enterprise/server/plugins/alertIrc/IrcSender.java
index 93eecc6..95abdb9 100644
--- a/modules/enterprise/server/plugins/alert-irc/src/main/java/org/rhq/enterprise/server/plugins/alertIrc/IrcSender.java
+++ b/modules/enterprise/server/plugins/alert-irc/src/main/java/org/rhq/enterprise/server/plugins/alertIrc/IrcSender.java
@@ -65,7 +65,7 @@ public class IrcSender extends AlertSender<IrcAlertComponent> {
b.append("): ");
b.append(alertManager.prettyPrintAlertURL(alert));
b.append("\n");
- b.append(alertManager.prettyPrintAlertConditions(alert));
+ b.append(alertManager.prettyPrintAlertConditions(alert, false));
return b.toString();
}
diff --git a/modules/enterprise/server/plugins/alert-microblog/src/main/java/org/rhq/enterprise/server/plugins/alertMicroblog/MicroblogSender.java b/modules/enterprise/server/plugins/alert-microblog/src/main/java/org/rhq/enterprise/server/plugins/alertMicroblog/MicroblogSender.java
index 257b315..b13763e 100644
--- a/modules/enterprise/server/plugins/alert-microblog/src/main/java/org/rhq/enterprise/server/plugins/alertMicroblog/MicroblogSender.java
+++ b/modules/enterprise/server/plugins/alert-microblog/src/main/java/org/rhq/enterprise/server/plugins/alertMicroblog/MicroblogSender.java
@@ -57,14 +57,19 @@ public class MicroblogSender extends AlertSender {
b.append("' (");
b.append(alert.getAlertDefinition().getResource().getId());
b.append("): ");
- b.append(alertManager.prettyPrintAlertConditions(alert));
+ b.append(alertManager.prettyPrintAlertConditions(alert, true));
b.append("-by @JBossJopr"); // TODO not for production :-)
// TODO use some alert url shortening service
SenderResult result ;
String txt = "user@baseUrl [" + user + "@" + baseUrl + "]:";
try {
- Status status = twitter.updateStatus(b.toString());
+ String msg = b.toString();
+ if (msg.length()>140)
+ msg = msg.substring(0,140);
+
+ Status status = twitter.updateStatus(msg);
+
result = new SenderResult(ResultState.SUCCESS,"Send notification to " + txt + ", msg-id: " + status.getId());
} catch (TwitterException e) {
diff --git a/modules/enterprise/server/plugins/alert-mobicents/src/main/java/org/rhq/enterprise/server/plugins/alertMobicents/MobicentsSender.java b/modules/enterprise/server/plugins/alert-mobicents/src/main/java/org/rhq/enterprise/server/plugins/alertMobicents/MobicentsSender.java
index 649d6ed..b14c85d 100644
--- a/modules/enterprise/server/plugins/alert-mobicents/src/main/java/org/rhq/enterprise/server/plugins/alertMobicents/MobicentsSender.java
+++ b/modules/enterprise/server/plugins/alert-mobicents/src/main/java/org/rhq/enterprise/server/plugins/alertMobicents/MobicentsSender.java
@@ -74,7 +74,7 @@ public class MobicentsSender extends AlertSender {
// Switch locale to english, as the voice synthesizer expects this for now
Locale currentLocale = Locale.getDefault();
Locale.setDefault(Locale.ENGLISH);
- b.append(alertManager.prettyPrintAlertConditions(alert));
+ b.append(alertManager.prettyPrintAlertConditions(alert, false));
Locale.setDefault(currentLocale);
boolean willBeDisabled = alertManager.willDefinitionBeDisabled(alert);
diff --git a/modules/enterprise/server/plugins/alert-scriptlang/src/main/java/org.rhq.enterprise.server.plugins.alertScriptlang/ScriptLangSender.java b/modules/enterprise/server/plugins/alert-scriptlang/src/main/java/org.rhq.enterprise.server.plugins.alertScriptlang/ScriptLangSender.java
index 985d890..bac51fb 100644
--- a/modules/enterprise/server/plugins/alert-scriptlang/src/main/java/org.rhq.enterprise.server.plugins.alertScriptlang/ScriptLangSender.java
+++ b/modules/enterprise/server/plugins/alert-scriptlang/src/main/java/org.rhq.enterprise.server.plugins.alertScriptlang/ScriptLangSender.java
@@ -93,7 +93,7 @@ public class ScriptLangSender extends AlertSender<ScriptLangComponent> {
Object[] args = new Object[3];
args[0] = alert;
args[1] = alertManager.prettyPrintAlertURL(alert);
- args[2] = alertManager.prettyPrintAlertConditions(alert);
+ args[2] = alertManager.prettyPrintAlertConditions(alert, false);
result = ((Invocable) engine).invokeFunction("sendAlert", args);
if (result == null) {
diff --git a/modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpSender.java b/modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpSender.java
index 3fd5d79..045c3bb 100644
--- a/modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpSender.java
+++ b/modules/enterprise/server/plugins/alert-snmp/src/main/java/org/rhq/enterprise/server/plugins/alertSnmp/SnmpSender.java
@@ -68,7 +68,7 @@ public class SnmpSender extends AlertSender {
String result;
List<Resource> lineage = resourceManager.getResourceLineage(alert.getAlertDefinition().getResource().getId());
String platformName = lineage.get(0).getName();
- String conditions = alertManager.prettyPrintAlertConditions(alert);
+ String conditions = alertManager.prettyPrintAlertConditions(alert, false);
String alertUrl = alertManager.prettyPrintAlertURL(alert);
SenderResult res ;
commit e1c760378fe3f3fdcbee42beef05f9930eb3fd65
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Fri Feb 19 17:51:53 2010 -0500
i think this should report an error always on lock acq failure. we'll leave the flag alone - don't set it to true - let the next call take care of whether or not the init callback should be invoked or not
diff --git a/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java b/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
index 8c37b50..cd3b479 100644
--- a/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
+++ b/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
@@ -588,11 +588,9 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
writeLock.unlock();
}
} else {
- if (m_needToCallInitializeCallback) {
- Throwable t = new Throwable("Initialize callback lock could not be acquired");
- LOG.error(CommI18NResourceKeys.INITIALIZE_CALLBACK_FAILED, t.getMessage());
- return new GenericCommandResponse(command, false, null, t);
- }
+ Throwable t = new Throwable("Initialize callback lock could not be acquired");
+ LOG.error(CommI18NResourceKeys.INITIALIZE_CALLBACK_FAILED, t.getMessage());
+ return new GenericCommandResponse(command, false, null, t);
}
}
return null;
commit 1740b73d4ec9dddf1222fcf99b69a8164c090bbb
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Fri Feb 19 17:44:11 2010 -0500
should not worry about the lock failure if the init callback doesn't need to be invoked anyway
diff --git a/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java b/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
index 762b9b4..8c37b50 100644
--- a/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
+++ b/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
@@ -588,10 +588,11 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
writeLock.unlock();
}
} else {
- m_needToCallInitializeCallback = true; // can't invoke callback, we'll want to still call it later
- Throwable t = new Throwable("Initialize callback lock could not be acquired");
- LOG.error(CommI18NResourceKeys.INITIALIZE_CALLBACK_FAILED, t.getMessage());
- return new GenericCommandResponse(command, false, null, t);
+ if (m_needToCallInitializeCallback) {
+ Throwable t = new Throwable("Initialize callback lock could not be acquired");
+ LOG.error(CommI18NResourceKeys.INITIALIZE_CALLBACK_FAILED, t.getMessage());
+ return new GenericCommandResponse(command, false, null, t);
+ }
}
}
return null;
commit 60fa4314138911d607d6e95110987feb5a7b8fb7
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Fri Feb 19 17:38:16 2010 -0500
BZ 537396 - to not block indefinitely if a lock cannot be acquired before attempting to invoke the initialize callback
diff --git a/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java b/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
index 3775212..762b9b4 100644
--- a/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
+++ b/modules/enterprise/comm/src/main/java/org/rhq/enterprise/communications/command/client/JBossRemotingRemoteCommunicator.java
@@ -21,6 +21,9 @@ package org.rhq.enterprise.communications.command.client;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
import mazz.i18n.Logger;
@@ -95,10 +98,22 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
private InitializeCallback m_initializeCallback;
/**
- * When the first element is <code>true</code>, the initialize callback will need to be called prior
- * to sending any commands. This is an array because the array itself is used for its lock.
+ * When <code>true</code>, the initialize callback will need to be called prior
+ * to sending any commands. Used in conjunection with its associated RW lock.
*/
- private final boolean[] m_needToCallInitializeCallback;
+ private boolean m_needToCallInitializeCallback;
+
+ /**
+ * RW lock when needing to access its associated atomic boolean flag.
+ */
+ private final ReentrantReadWriteLock m_needToCallInitializeCallbackLock;
+
+ /**
+ * Number of minutes to wait while attempting to aquire a lock before attempting
+ * to invoke the initialize callback. If this amount of minutes expires before the lock
+ * is acquired, an error will occur and the initialize callback will have to be attempted later.
+ */
+ private final long m_initializeCallbackLockAcquisitionTimeoutMins;
/**
* Constructor for {@link JBossRemotingRemoteCommunicator} that initializes the client with no invoker locator
@@ -200,7 +215,17 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
m_clientConfiguration.putAll(client_config);
}
- m_needToCallInitializeCallback = new boolean[] { false };
+ m_needToCallInitializeCallback = false;
+ m_needToCallInitializeCallbackLock = new ReentrantReadWriteLock();
+
+ long mins;
+ try {
+ String minsStr = System.getProperty("rhq.communications.initial-callback-lock-wait-mins", "60");
+ mins = Long.parseLong(minsStr);
+ } catch (Throwable t) {
+ mins = 60L;
+ }
+ m_initializeCallbackLockAcquisitionTimeoutMins = mins;
return;
}
@@ -319,7 +344,7 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
if (m_remotingClient != null) {
m_remotingClient.disconnect();
m_remotingClient = null;
- m_needToCallInitializeCallback[0] = (getInitializeCallback() != null); // specifically do not synchronize, just set it
+ m_needToCallInitializeCallback = (getInitializeCallback() != null); // specifically do not synchrononize by using lock, just set it
}
LOG.info(CommI18NResourceKeys.COMMUNICATOR_CHANGING_ENDPOINT, m_invokerLocator, locator);
@@ -377,7 +402,7 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
public void setInitializeCallback(InitializeCallback callback) {
m_initializeCallback = callback;
- m_needToCallInitializeCallback[0] = (callback != null); // specifically do not synchronize, just set it
+ m_needToCallInitializeCallback = (callback != null); // specifically do not synchrononize by using lock, just set it
}
public String getRemoteEndpoint() {
@@ -403,7 +428,7 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
public void connect() throws Exception {
if ((m_remotingClient != null) && !m_remotingClient.isConnected()) {
m_remotingClient.connect();
- m_needToCallInitializeCallback[0] = (getInitializeCallback() != null); // specifically do not synchronize, just set it
+ m_needToCallInitializeCallback = (getInitializeCallback() != null); // specifically do not synchrononize by using lock, just set it
}
return;
@@ -412,7 +437,7 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
public void disconnect() {
if (m_remotingClient != null) {
m_remotingClient.disconnect();
- m_needToCallInitializeCallback[0] = (getInitializeCallback() != null); // specifically do not synchronize, just set it
+ m_needToCallInitializeCallback = (getInitializeCallback() != null); // specifically do not synchrononize by using lock, just set it
}
return;
@@ -535,18 +560,38 @@ public class JBossRemotingRemoteCommunicator implements RemoteCommunicator {
private CommandResponse invokeInitializeCallbackIfNeeded(Command command) {
InitializeCallback callback = getInitializeCallback();
if (callback != null) {
- // block here - in effect, this will stop all commands from going out until the callback is done
- synchronized (m_needToCallInitializeCallback) {
- if (m_needToCallInitializeCallback[0]) {
- try {
- m_needToCallInitializeCallback[0] = !callback.sendingInitialCommand(this, command);
- LOG.debug(CommI18NResourceKeys.INITIALIZE_CALLBACK_DONE, m_needToCallInitializeCallback[0]);
- } catch (Throwable t) {
- m_needToCallInitializeCallback[0] = true; // callback failed, we'll want to call it again
- LOG.error(t, CommI18NResourceKeys.INITIALIZE_CALLBACK_FAILED, ThrowableUtil.getAllMessages(t));
- return new GenericCommandResponse(command, false, null, t);
+ // block here - in effect, this will stop all commands from going out until the callback is done
+ // to avoid infinite blocking, we'll only wait for a set time (though long).
+
+ WriteLock writeLock = m_needToCallInitializeCallbackLock.writeLock();
+ boolean locked;
+ try {
+ locked = writeLock.tryLock(m_initializeCallbackLockAcquisitionTimeoutMins, TimeUnit.MINUTES);
+ } catch (InterruptedException ie) {
+ locked = false;
+ }
+
+ if (locked) {
+ try {
+ if (m_needToCallInitializeCallback) {
+ try {
+ m_needToCallInitializeCallback = (!callback.sendingInitialCommand(this, command));
+ LOG.debug(CommI18NResourceKeys.INITIALIZE_CALLBACK_DONE, m_needToCallInitializeCallback);
+ } catch (Throwable t) {
+ m_needToCallInitializeCallback = true; // callback failed, we'll want to call it again
+ LOG.error(t, CommI18NResourceKeys.INITIALIZE_CALLBACK_FAILED, ThrowableUtil
+ .getAllMessages(t));
+ return new GenericCommandResponse(command, false, null, t);
+ }
}
+ } finally {
+ writeLock.unlock();
}
+ } else {
+ m_needToCallInitializeCallback = true; // can't invoke callback, we'll want to still call it later
+ Throwable t = new Throwable("Initialize callback lock could not be acquired");
+ LOG.error(CommI18NResourceKeys.INITIALIZE_CALLBACK_FAILED, t.getMessage());
+ return new GenericCommandResponse(command, false, null, t);
}
}
return null;
commit 474b186034125b179eb03e1ff069036a3299f730
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Fri Feb 19 11:10:53 2010 -0500
BZ 566724 - if classloader fails to be created, master PC will skip the plugin
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java
index f46eaf5..bd4feac 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/MasterServerPluginContainer.java
@@ -136,16 +136,23 @@ public class MasterServerPluginContainer {
String pluginName = descriptor.getName();
ServerPluginType pluginType = new ServerPluginType(descriptor);
PluginKey pluginKey = PluginKey.createServerPluginKey(pluginType.stringify(), pluginName);
- ClassLoader classLoader = this.classLoaderManager.obtainServerPluginClassLoader(pluginKey);
- log.debug("Pre-loading server plugin [" + pluginKey + "] from [" + pluginUrl
- + "] into its plugin container");
try {
- ServerPluginEnvironment env = new ServerPluginEnvironment(pluginUrl, classLoader, descriptor);
- boolean enabled = !allDisabledPlugins.contains(pluginKey);
- pc.loadPlugin(env, enabled);
- log.info("Preloaded server plugin [" + pluginKey.getPluginName() + "]");
+ ClassLoader classLoader = this.classLoaderManager.obtainServerPluginClassLoader(pluginKey);
+ log.debug("Pre-loading server plugin [" + pluginKey + "] from [" + pluginUrl
+ + "] into its plugin container");
+ try {
+ ServerPluginEnvironment env = new ServerPluginEnvironment(pluginUrl, classLoader,
+ descriptor);
+ boolean enabled = !allDisabledPlugins.contains(pluginKey);
+ pc.loadPlugin(env, enabled);
+ log.info("Preloaded server plugin [" + pluginName + "]");
+ } catch (Exception e) {
+ log.warn("Failed to preload server plugin [" + pluginName + "] from URL [" + pluginUrl
+ + "]", e);
+ }
} catch (Exception e) {
- log.warn("Failed to preload server plugin [" + pluginUrl + "]", e);
+ log.warn("Failed to preload server plugin [" + pluginName
+ + "]; cannot get its classloader from URL [ " + pluginUrl + "]", e);
}
} else {
log.warn("There is no server plugin container to support plugin: " + pluginUrl);
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginClassLoader.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginClassLoader.java
index 9f27ce9..fa26970 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginClassLoader.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/plugin/pc/ServerPluginClassLoader.java
@@ -64,7 +64,7 @@ public class ServerPluginClassLoader extends URLClassLoader {
try {
unpackedDirectory = unpackEmbeddedJars(pluginJarName, pluginUrl, classpathUrlList, tmpDirectory);
} catch (Exception e) {
- throw new Exception("Failed to unpack embedded JARs within: " + pluginUrl);
+ throw new Exception("Failed to unpack embedded JARs within: " + pluginUrl, e);
}
}
}
commit b5e46e4c6e802cdf883307c46e5a275a94514457
Author: Heiko W. Rupp <pilhuhn(a)fedorapeople.org>
Date: Fri Feb 19 13:37:36 2010 +0100
Fix link to definitions BZ 566004
diff --git a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/listAlertHistory.xhtml b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/listAlertHistory.xhtml
index b6e386c..fd09f82 100644
--- a/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/listAlertHistory.xhtml
+++ b/modules/enterprise/gui/portal-war/src/main/webapp/rhq/resource/alert/listAlertHistory.xhtml
@@ -148,8 +148,7 @@
</onc:sortableColumnHeader>
</f:facet>
- <h:outputLink value="/alerts/Config.do">
- <f:param name="mode" value="viewRoles"/>
+ <h:outputLink value="/rhq/resource/alert/viewAlert.xhtml">
<f:param name="id" value="#{Resource.id}"/>
<f:param name="ad" value="#{item.alert.alertDefinition.id}"/>
<h:outputText value="#{item.alert.alertDefinition.name}" />
13 years, 9 months