[rhq] modules/enterprise
by ips
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RoleEditView.java | 8 +++++---
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RolesView.java | 10 ++++++++--
2 files changed, 13 insertions(+), 5 deletions(-)
New commits:
commit 2ab62ba6ae4b0d533bc47e46155c80a4af34804d
Author: Ian Springer <ian.springer(a)redhat.com>
Date: Wed Mar 9 11:40:46 2011 -0500
fix so role details view can again be reached by selecting a role from the roles list view (https://bugzilla.redhat.com/show_bug.cgi?id=683429)
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 0264d3b..58cde04 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
@@ -291,7 +291,7 @@ public class RoleEditView extends AbstractRecordEditor<RolesDataSource> implemen
.view_adminConfig_systemSettings()));
label.setWidth100();
label.setHeight(20);
- label.setPadding(5);
+ label.setPadding(10);
updateTab(this.ldapGroupsTab, label);
}
}
@@ -303,10 +303,12 @@ public class RoleEditView extends AbstractRecordEditor<RolesDataSource> implemen
protected List<FormItem> createFormItems(EnhancedDynamicForm form) {
List<FormItem> items = new ArrayList<FormItem>();
- TextItem nameItem = new TextItem(RolesDataSource.Field.NAME, MSG.common_title_name());
+ TextItem nameItem = new TextItem(RolesDataSource.Field.NAME);
+ nameItem.setShowTitle(true);
items.add(nameItem);
- TextItem descriptionItem = new TextItem(RolesDataSource.Field.DESCRIPTION, MSG.common_title_description());
+ TextItem descriptionItem = new TextItem(RolesDataSource.Field.DESCRIPTION);
+ descriptionItem.setShowTitle(true);
descriptionItem.setColSpan(form.getNumCols());
items.add(descriptionItem);
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 7dac43e..46fa148 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
@@ -59,14 +59,17 @@ public class RolesView extends TableSection<RolesDataSource> implements Bookmark
public RolesView(String locatorId) {
super(locatorId, MSG.view_adminSecurity_roles());
- fetchManageSecurityPermissionAsync();
-
final RolesDataSource datasource = RolesDataSource.getInstance();
setDataSource(datasource);
setHeaderIcon(HEADER_ICON);
}
@Override
+ protected void onDraw() {
+ fetchManageSecurityPermissionAsync();
+ }
+
+ @Override
protected void configureTable() {
updateSelectionStyle();
getListGrid().addCellClickHandler(new CellClickHandler() {
@@ -159,6 +162,9 @@ public class RolesView extends TableSection<RolesDataSource> implements Bookmark
} else {
hasManageSecurity = false;
}
+ if (!initialized) {
+ RolesView.super.onDraw();
+ }
initialized = true;
}
});
13 years, 2 months
[rhq] modules/enterprise
by ips
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RolesDataSource.java | 2 +-
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/form/AbstractRecordEditor.java | 1 +
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/util/RPCDataSource.java | 5 ++++-
3 files changed, 6 insertions(+), 2 deletions(-)
New commits:
commit 78ccb4b157c81e7a6c60222affb70a95e5958c69
Author: Ian Springer <ian.springer(a)redhat.com>
Date: Wed Mar 9 11:03:19 2011 -0500
fix bug where clicking on Reset button on user or role edit view would result in an exception (https://bugzilla.redhat.com/show_bug.cgi?id=677421)
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 04330ae..9fefcb3 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
@@ -283,7 +283,7 @@ public class RolesDataSource extends RPCDataSource<Role> {
Integer id = getFilter(request, Field.ID, Integer.class);
criteria.addFilterId(id);
- Integer subjectId = request.getCriteria().getAttributeAsInt(CriteriaField.SUBJECT_ID);
+ Integer subjectId = getFilter(request, CriteriaField.SUBJECT_ID, Integer.class);
if (subjectId != null) {
criteria.addFilterSubjectId(subjectId);
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/form/AbstractRecordEditor.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/form/AbstractRecordEditor.java
index e4f061b..f9249f4 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/form/AbstractRecordEditor.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/form/AbstractRecordEditor.java
@@ -457,6 +457,7 @@ public abstract class AbstractRecordEditor<DS extends RPCDataSource> extends Loc
public void onClick(ClickEvent clickEvent) {
reset();
resetButton.disable();
+ saveButton.disable();
}
});
hLayout.addMember(resetButton);
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 07f766b..b87345e 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
@@ -21,7 +21,9 @@ package org.rhq.enterprise.gui.coregui.client.util;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
import java.util.Date;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
@@ -507,7 +509,8 @@ public abstract class RPCDataSource<T> extends DataSource {
@SuppressWarnings("unchecked")
public static <S> S getFilter(DSRequest request, String paramName, Class<S> type) {
Criteria criteria = request.getCriteria();
- Map<String, Object> criteriaMap = criteria.getValues();
+ Map<String, Object> criteriaMap = (criteria != null) ? criteria.getValues() :
+ Collections.<String, Object>emptyMap();
S result = null;
13 years, 2 months
[rhq] Branch 'release-3.0.0' - modules/enterprise
by lkrejci
modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/taglib/Authorization.java | 12 +++++-----
1 file changed, 6 insertions(+), 6 deletions(-)
New commits:
commit 091cf3cc56cde7ab585bb55a14ea1740263b88d7
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Fri Feb 18 12:27:17 2011 +0100
BZ 678349 - fixing the authz logic in the hq:authorization JSP tag.
diff --git a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/taglib/Authorization.java b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/taglib/Authorization.java
index ae3164d..a8e5d07 100644
--- a/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/taglib/Authorization.java
+++ b/modules/enterprise/gui/portal-war/src/main/java/org/rhq/enterprise/gui/legacy/taglib/Authorization.java
@@ -56,19 +56,19 @@ public class Authorization extends ConditionalTagSupport {
}
Context context = Context.Global;
- int objectId = getResourceId(request);
- if (objectId != 0) {
+ int resourceId = getResourceId(request);
+ if (resourceId != 0) {
context = Context.Resource;
}
- objectId = getResourceGroupId(request);
- if (objectId != 0) {
+ int groupId = getResourceGroupId(request);
+ if (groupId != 0) {
context = Context.Group;
}
if (context == Context.Resource) {
- return authorizationManager.hasResourcePermission(user, permission, objectId);
+ return authorizationManager.hasResourcePermission(user, permission, resourceId);
} else if (context == Context.Group) {
- return authorizationManager.hasGroupPermission(user, permission, objectId);
+ return authorizationManager.hasGroupPermission(user, permission, groupId);
} else if (context == Context.Global) {
return authorizationManager.hasGlobalPermission(user, permission);
} else {
13 years, 2 months
[rhq] modules/enterprise
by ips
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/roles/RolesView.java | 114 +++++++---
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/users/UsersView.java | 64 ++++-
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/table/TableSection.java | 36 +--
3 files changed, 154 insertions(+), 60 deletions(-)
New commits:
commit fbbf83cf2f614c671fd2f18c1a1a881391156e26
Author: Ian Springer <ian.springer(a)redhat.com>
Date: Tue Mar 8 18:18:24 2011 -0500
users without MANAGED_SECURITY can no longer create or delete roles (https://bugzilla.redhat.com/show_bug.cgi?id=682710)
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 bd6b812..7dac43e 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
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2010 Red Hat, Inc.
+ * Copyright (C) 2005-2011 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -18,12 +18,17 @@
*/
package org.rhq.enterprise.gui.coregui.client.admin.roles;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Set;
+import com.smartgwt.client.types.SelectionStyle;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.grid.ListGridField;
import com.smartgwt.client.widgets.grid.ListGridRecord;
+import com.smartgwt.client.widgets.grid.events.CellClickEvent;
+import com.smartgwt.client.widgets.grid.events.CellClickHandler;
import org.rhq.core.domain.authz.Permission;
import org.rhq.enterprise.gui.coregui.client.BookmarkableView;
import org.rhq.enterprise.gui.coregui.client.PermissionsLoadedListener;
@@ -49,10 +54,13 @@ public class RolesView extends TableSection<RolesDataSource> implements Bookmark
private static final String HEADER_ICON = "global/Role_24.png";
private boolean hasManageSecurity;
+ private boolean initialized;
public RolesView(String locatorId) {
super(locatorId, MSG.view_adminSecurity_roles());
+ fetchManageSecurityPermissionAsync();
+
final RolesDataSource datasource = RolesDataSource.getInstance();
setDataSource(datasource);
setHeaderIcon(HEADER_ICON);
@@ -60,36 +68,50 @@ public class RolesView extends TableSection<RolesDataSource> implements Bookmark
@Override
protected void configureTable() {
- ListGridField nameField = new ListGridField(RolesDataSource.Field.NAME, 150);
-
- ListGridField descriptionField = new ListGridField(RolesDataSource.Field.DESCRIPTION);
+ updateSelectionStyle();
+ getListGrid().addCellClickHandler(new CellClickHandler() {
+ public void onCellClick(CellClickEvent event) {
+ updateSelectionStyle();
+ }
+ });
- setListGridFields(nameField, descriptionField);
+ List<ListGridField> fields = createFields();
+ setListGridFields(fields.toArray(new ListGridField[fields.size()]));
+ addTableAction(extendLocatorId("New"), MSG.common_button_new(), createNewAction());
addTableAction(extendLocatorId("Delete"), MSG.common_button_delete(), getDeleteConfirmMessage(),
- new TableAction() {
- public boolean isEnabled(ListGridRecord[] selection) {
- int count = selection.length;
- if (count == 0) {
- return false;
- }
+ createDeleteAction());
- for (ListGridRecord record : selection) {
- int roleId = record.getAttributeAsInt(RolesDataSource.Field.ID);
- if (RolesDataSource.isSystemRoleId(roleId)) {
- // The superuser role cannot be deleted.
- return false;
- }
- }
- return true;
- }
+ super.configureTable();
+ }
- public void executeAction(ListGridRecord[] selection, Object actionValue) {
- deleteSelectedRecords();
- }
- });
+ @Override
+ public void refresh() {
+ super.refresh();
+
+ updateSelectionStyle();
+ }
+
+ @Override
+ protected boolean isDetailsEnabled() {
+ // Non-superusers cannot view or edit roles.
+ return this.hasManageSecurity;
+ }
+
+ private List<ListGridField> createFields() {
+ List<ListGridField> fields = new ArrayList<ListGridField>();
+
+ ListGridField nameField = new ListGridField(RolesDataSource.Field.NAME, 150);
+ fields.add(nameField);
- addTableAction(extendLocatorId("New"), MSG.common_button_new(), new TableAction() {
+ ListGridField descriptionField = new ListGridField(RolesDataSource.Field.DESCRIPTION);
+ fields.add(descriptionField);
+
+ return fields;
+ }
+
+ private TableAction createNewAction() {
+ return new TableAction() {
public boolean isEnabled(ListGridRecord[] selection) {
return hasManageSecurity;
}
@@ -97,16 +119,39 @@ public class RolesView extends TableSection<RolesDataSource> implements Bookmark
public void executeAction(ListGridRecord[] selection, Object actionValue) {
newDetails();
}
- });
+ };
+ }
- fetchManageSecurityPermissionAsync();
+ private TableAction createDeleteAction() {
+ return new TableAction() {
+ public boolean isEnabled(ListGridRecord[] selection) {
+ if (!hasManageSecurity) {
+ return false;
+ }
- super.configureTable();
+ int count = selection.length;
+ if (count == 0) {
+ return false;
+ }
+
+ for (ListGridRecord record : selection) {
+ int roleId = record.getAttributeAsInt(RolesDataSource.Field.ID);
+ if (RolesDataSource.isSystemRoleId(roleId)) {
+ // The superuser role cannot be deleted.
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public void executeAction(ListGridRecord[] selection, Object actionValue) {
+ deleteSelectedRecords();
+ }
+ };
}
private void fetchManageSecurityPermissionAsync() {
new PermissionsLoader().loadExplicitGlobalPermissions(new PermissionsLoadedListener() {
- @Override
public void onPermissionsLoaded(Set<Permission> permissions) {
if (permissions != null) {
hasManageSecurity = permissions.contains(Permission.MANAGE_SECURITY);
@@ -114,10 +159,21 @@ public class RolesView extends TableSection<RolesDataSource> implements Bookmark
} else {
hasManageSecurity = false;
}
+ initialized = true;
}
});
}
+ private void updateSelectionStyle() {
+ if (initialized) {
+ if (!hasManageSecurity) {
+ getListGrid().deselectAllRecords();
+ }
+ SelectionStyle selectionStyle = hasManageSecurity ? getDefaultSelectionStyle() : SelectionStyle.NONE;
+ getListGrid().setSelectionType(selectionStyle);
+ }
+ }
+
@Override
public Canvas getDetailsView(int roleId) {
return new RoleEditView(extendLocatorId("Detail"), roleId);
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 e57bafa..f124703 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
@@ -22,10 +22,13 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Set;
+import com.smartgwt.client.types.SelectionStyle;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.grid.ListGridField;
import com.smartgwt.client.widgets.grid.ListGridRecord;
+import com.smartgwt.client.widgets.grid.events.CellClickEvent;
+import com.smartgwt.client.widgets.grid.events.CellClickHandler;
import org.rhq.core.domain.authz.Permission;
import org.rhq.enterprise.gui.coregui.client.PermissionsLoadedListener;
import org.rhq.enterprise.gui.coregui.client.PermissionsLoader;
@@ -52,6 +55,7 @@ public class UsersView extends TableSection<UsersDataSource> {
private static final String HEADER_ICON = "global/User_24.png";
private boolean hasManageSecurity;
+ private boolean initialized;
public UsersView(String locatorId) {
super(locatorId, MSG.view_adminSecurity_users());
@@ -60,25 +64,38 @@ public class UsersView extends TableSection<UsersDataSource> {
setDataSource(dataSource);
setHeaderIcon(HEADER_ICON);
+
+ fetchManageSecurityPermissionAsync();
}
@Override
protected void configureTable() {
+ updateSelectionStyle();
+ getListGrid().addCellClickHandler(new CellClickHandler() {
+ public void onCellClick(CellClickEvent event) {
+ updateSelectionStyle();
+ }
+ });
+
List<ListGridField> fields = createFields();
setListGridFields(fields.toArray(new ListGridField[fields.size()]));
+ addTableAction(extendLocatorId("New"), MSG.common_button_new(), createNewAction());
addTableAction(extendLocatorId("Delete"), MSG.common_button_delete(), getDeleteConfirmMessage(),
createDeleteAction());
- addTableAction(extendLocatorId("New"), MSG.common_button_new(), createNewAction());
-
- fetchManageSecurityPermissionAsync();
super.configureTable();
}
+ @Override
+ public void refresh() {
+ super.refresh();
+
+ updateSelectionStyle();
+ }
+
private void fetchManageSecurityPermissionAsync() {
new PermissionsLoader().loadExplicitGlobalPermissions(new PermissionsLoadedListener() {
- @Override
public void onPermissionsLoaded(Set<Permission> permissions) {
if (permissions != null) {
hasManageSecurity = permissions.contains(Permission.MANAGE_SECURITY);
@@ -86,10 +103,21 @@ public class UsersView extends TableSection<UsersDataSource> {
} else {
hasManageSecurity = false;
}
+ initialized = true;
}
});
}
+ private void updateSelectionStyle() {
+ if (initialized) {
+ if (!hasManageSecurity) {
+ getListGrid().deselectAllRecords();
+ }
+ SelectionStyle selectionStyle = hasManageSecurity ? getDefaultSelectionStyle() : SelectionStyle.NONE;
+ getListGrid().setSelectionType(selectionStyle);
+ }
+ }
+
private List<ListGridField> createFields() {
List<ListGridField> fields = new ArrayList<ListGridField>();
@@ -138,9 +166,25 @@ public class UsersView extends TableSection<UsersDataSource> {
return fields;
}
+ private TableAction createNewAction() {
+ return new TableAction() {
+ public boolean isEnabled(ListGridRecord[] selection) {
+ return hasManageSecurity;
+ }
+
+ public void executeAction(ListGridRecord[] selection, Object actionValue) {
+ newDetails();
+ }
+ };
+ }
+
private TableAction createDeleteAction() {
return new TableAction() {
public boolean isEnabled(ListGridRecord[] selection) {
+ if (!hasManageSecurity) {
+ return false;
+ }
+
int count = selection.length;
if (count == 0) {
return false;
@@ -162,18 +206,6 @@ public class UsersView extends TableSection<UsersDataSource> {
};
}
- private TableAction createNewAction() {
- return new TableAction() {
- public boolean isEnabled(ListGridRecord[] selection) {
- return hasManageSecurity;
- }
-
- public void executeAction(ListGridRecord[] selection, Object actionValue) {
- newDetails();
- }
- };
- }
-
public Canvas getDetailsView(int subjectId) {
return new UserEditView(extendLocatorId("Detail"), subjectId);
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/table/TableSection.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/table/TableSection.java
index 57f3c6f..e551deb 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/table/TableSection.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/table/TableSection.java
@@ -120,24 +120,30 @@ public abstract class TableSection<DS extends RPCDataSource> extends Table<DS> i
*/
@Override
protected void configureTable() {
+ if (isDetailsEnabled()) {
+ ListGrid grid = getListGrid();
- // Make the value of some specific field a link to the details view for the corresponding record
- ListGrid grid = getListGrid();
- ListGridField field = (grid != null) ? grid.getField(getDetailsLinkColumnName()) : null;
- if (field != null) {
- field.setCellFormatter(getDetailsLinkColumnCellFormatter());
- }
+ // Make the value of some specific field a link to the details view for the corresponding record.
+ ListGridField field = (grid != null) ? grid.getField(getDetailsLinkColumnName()) : null;
+ if (field != null) {
+ field.setCellFormatter(getDetailsLinkColumnCellFormatter());
+ }
- setListGridDoubleClickHandler(new DoubleClickHandler() {
- @Override
- public void onDoubleClick(DoubleClickEvent event) {
- ListGrid listGrid = (ListGrid) event.getSource();
- ListGridRecord[] selectedRows = listGrid.getSelection();
- if (selectedRows != null && selectedRows.length == 1) {
- showDetails(selectedRows[0]);
+ setListGridDoubleClickHandler(new DoubleClickHandler() {
+ @Override
+ public void onDoubleClick(DoubleClickEvent event) {
+ ListGrid listGrid = (ListGrid) event.getSource();
+ ListGridRecord[] selectedRows = listGrid.getSelection();
+ if (selectedRows != null && selectedRows.length == 1) {
+ showDetails(selectedRows[0]);
+ }
}
- }
- });
+ });
+ }
+ }
+
+ protected boolean isDetailsEnabled() {
+ return true;
}
/**
13 years, 2 months
[rhq] modules/enterprise
by ips
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/templates/ResourceTypeTreeView.java | 130 ++++------
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/table/ResourceCategoryCellFormatter.java | 54 ++++
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceSearchView.java | 21 -
3 files changed, 115 insertions(+), 90 deletions(-)
New commits:
commit 3fce94f8bb41682b7f9920b7c60ea3a67bc6a13f
Author: Ian Springer <ian.springer(a)redhat.com>
Date: Tue Mar 8 17:13:15 2011 -0500
format resource category names correctly and extract the formatting logic to a new ResourceCategoryCellFormatter class (https://bugzilla.redhat.com/show_bug.cgi?id=673505)
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/templates/ResourceTypeTreeView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/templates/ResourceTypeTreeView.java
index ea355c4..3daa669 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/templates/ResourceTypeTreeView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/templates/ResourceTypeTreeView.java
@@ -1,6 +1,6 @@
/*
* RHQ Management Platform
- * Copyright (C) 2005-2010 Red Hat, Inc.
+ * Copyright (C) 2005-2011 Red Hat, Inc.
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -18,19 +18,16 @@
*/
package org.rhq.enterprise.gui.coregui.client.admin.templates;
-import java.util.HashMap;
import java.util.Map;
import com.smartgwt.client.data.Record;
import com.smartgwt.client.types.Alignment;
-import com.smartgwt.client.types.ListGridFieldType;
import com.smartgwt.client.types.SelectionStyle;
import com.smartgwt.client.types.VisibilityMode;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.ImgButton;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
-import com.smartgwt.client.widgets.grid.HoverCustomizer;
import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.grid.ListGridField;
import com.smartgwt.client.widgets.grid.ListGridRecord;
@@ -54,6 +51,7 @@ import org.rhq.enterprise.gui.coregui.client.admin.AdministrationView;
import org.rhq.enterprise.gui.coregui.client.alert.definitions.TemplateAlertDefinitionsView;
import org.rhq.enterprise.gui.coregui.client.components.TitleBar;
import org.rhq.enterprise.gui.coregui.client.components.buttons.BackButton;
+import org.rhq.enterprise.gui.coregui.client.components.table.ResourceCategoryCellFormatter;
import org.rhq.enterprise.gui.coregui.client.components.view.ViewName;
import org.rhq.enterprise.gui.coregui.client.inventory.resource.type.ResourceTypeRepository;
import org.rhq.enterprise.gui.coregui.client.inventory.resource.type.ResourceTypeRepository.TypesLoadedCallback;
@@ -251,43 +249,46 @@ public class ResourceTypeTreeView extends LocatableVLayout implements Bookmarkab
setEmptyMessage(MSG.common_msg_loading());
setSelectionType(SelectionStyle.NONE);
- final ListGridField name = new ListGridField(ResourceTypeTreeNodeBuilder.ATTRIB_NAME, MSG
+ final ListGridField nameField = new ListGridField(ResourceTypeTreeNodeBuilder.ATTRIB_NAME, MSG
.common_title_name());
- final ListGridField plugin = new ListGridField(ResourceTypeTreeNodeBuilder.ATTRIB_PLUGIN, MSG
+ nameField.setShowValueIconOnly(false);
+
+ final ListGridField pluginField = new ListGridField(ResourceTypeTreeNodeBuilder.ATTRIB_PLUGIN, MSG
.common_title_plugin());
- final ListGridField category = new ListGridField(ResourceTypeTreeNodeBuilder.ATTRIB_CATEGORY, MSG
+ final ListGridField categoryField = new ListGridField(ResourceTypeTreeNodeBuilder.ATTRIB_CATEGORY, MSG
.common_title_category());
- final ListGridField enabledAlertTemplates = new ListGridField(
+ categoryField.setCellFormatter(new ResourceCategoryCellFormatter());
+ final ListGridField enabledAlertTemplatesField = new ListGridField(
ResourceTypeTreeNodeBuilder.ATTRIB_ENABLED_ALERT_TEMPLATES, MSG
.view_adminTemplates_enabledAlertTemplates());
- final ListGridField disabledAlertTemplates = new ListGridField(
+ final ListGridField disabledAlertTemplatesField = new ListGridField(
ResourceTypeTreeNodeBuilder.ATTRIB_DISABLED_ALERT_TEMPLATES, MSG
.view_adminTemplates_disabledAlertTemplates());
- final ListGridField enabledMetricTemplates = new ListGridField(
+ final ListGridField enabledMetricTemplatesField = new ListGridField(
ResourceTypeTreeNodeBuilder.ATTRIB_ENABLED_METRIC_TEMPLATES, MSG
.view_adminTemplates_enabledMetricTemplates());
- final ListGridField disabledMetricTemplates = new ListGridField(
+ final ListGridField disabledMetricTemplatesField = new ListGridField(
ResourceTypeTreeNodeBuilder.ATTRIB_DISABLED_METRIC_TEMPLATES, MSG
.view_adminTemplates_disabledMetricTemplates());
- plugin.setHidden(true);
- category.setHidden(true);
+ pluginField.setHidden(true);
+ categoryField.setHidden(true);
- name.setWidth("*");
- plugin.setWidth("10%");
- category.setWidth("5%");
- enabledAlertTemplates.setWidth("10%");
- disabledAlertTemplates.setWidth("10%");
- enabledMetricTemplates.setWidth("10%");
- disabledMetricTemplates.setWidth("10%");
+ nameField.setWidth("*");
+ pluginField.setWidth("10%");
+ categoryField.setWidth("5%");
+ enabledAlertTemplatesField.setWidth("10%");
+ disabledAlertTemplatesField.setWidth("10%");
+ enabledMetricTemplatesField.setWidth("10%");
+ disabledMetricTemplatesField.setWidth("10%");
- enabledAlertTemplates.setPrompt(MSG.view_adminTemplates_prompt_enabledAlertTemplates());
- disabledAlertTemplates.setPrompt(MSG.view_adminTemplates_prompt_disabledAlertTemplates());
- enabledMetricTemplates.setPrompt(MSG.view_adminTemplates_prompt_enabledMetricTemplates());
- disabledMetricTemplates.setPrompt(MSG.view_adminTemplates_prompt_disabledMetricTemplates());
+ enabledAlertTemplatesField.setPrompt(MSG.view_adminTemplates_prompt_enabledAlertTemplates());
+ disabledAlertTemplatesField.setPrompt(MSG.view_adminTemplates_prompt_disabledAlertTemplates());
+ enabledMetricTemplatesField.setPrompt(MSG.view_adminTemplates_prompt_enabledMetricTemplates());
+ disabledMetricTemplatesField.setPrompt(MSG.view_adminTemplates_prompt_disabledMetricTemplates());
- setFields(name, plugin, category, enabledAlertTemplates, disabledAlertTemplates, enabledMetricTemplates,
- disabledMetricTemplates);
+ setFields(nameField, pluginField, categoryField, enabledAlertTemplatesField, disabledAlertTemplatesField, enabledMetricTemplatesField,
+ disabledMetricTemplatesField);
}
@Override
@@ -335,6 +336,16 @@ public class ResourceTypeTreeView extends LocatableVLayout implements Bookmarkab
return rollOverCanvas;
}
+ @Override
+ public String getValueIcon(ListGridField field, Object value, ListGridRecord record) {
+ if (field.getName().equals(ResourceTypeTreeNodeBuilder.ATTRIB_NAME)) {
+ String categoryName = record.getAttribute(ResourceTypeTreeNodeBuilder.ATTRIB_CATEGORY);
+ return ImageManager.getResourceIcon(ResourceCategory.valueOf(categoryName));
+ } else {
+ return super.getValueIcon(field, value, record);
+ }
+ }
+
private int getRollOverId() {
return Integer.parseInt(rollOverRecord.getAttribute(ResourceTypeTreeNodeBuilder.ATTRIB_ID));
}
@@ -354,66 +365,43 @@ public class ResourceTypeTreeView extends LocatableVLayout implements Bookmarkab
setSelectionType(SelectionStyle.NONE);
setAnimateFolders(false);
- final TreeGridField name = new TreeGridField(ResourceTypeTreeNodeBuilder.ATTRIB_NAME, MSG
+ final TreeGridField nameField = new TreeGridField(ResourceTypeTreeNodeBuilder.ATTRIB_NAME, MSG
.common_title_name());
- final TreeGridField plugin = new TreeGridField(ResourceTypeTreeNodeBuilder.ATTRIB_PLUGIN, MSG
+ final TreeGridField pluginField = new TreeGridField(ResourceTypeTreeNodeBuilder.ATTRIB_PLUGIN, MSG
.common_title_plugin());
- final TreeGridField category = new TreeGridField(ResourceTypeTreeNodeBuilder.ATTRIB_CATEGORY, MSG
+ final TreeGridField categoryField = new TreeGridField(ResourceTypeTreeNodeBuilder.ATTRIB_CATEGORY, MSG
.common_title_category());
- final TreeGridField enabledAlertTemplates = new TreeGridField(
+ categoryField.setCellFormatter(new ResourceCategoryCellFormatter());
+ final TreeGridField enabledAlertTemplatesField = new TreeGridField(
ResourceTypeTreeNodeBuilder.ATTRIB_ENABLED_ALERT_TEMPLATES, MSG
.view_adminTemplates_enabledAlertTemplates());
- final TreeGridField disabledAlertTemplates = new TreeGridField(
+ final TreeGridField disabledAlertTemplatesField = new TreeGridField(
ResourceTypeTreeNodeBuilder.ATTRIB_DISABLED_ALERT_TEMPLATES, MSG
.view_adminTemplates_disabledAlertTemplates());
- final TreeGridField enabledMetricTemplates = new TreeGridField(
+ final TreeGridField enabledMetricTemplatesField = new TreeGridField(
ResourceTypeTreeNodeBuilder.ATTRIB_ENABLED_METRIC_TEMPLATES, MSG
.view_adminTemplates_enabledMetricTemplates());
- final TreeGridField disabledMetricTemplates = new TreeGridField(
+ final TreeGridField disabledMetricTemplatesField = new TreeGridField(
ResourceTypeTreeNodeBuilder.ATTRIB_DISABLED_METRIC_TEMPLATES, MSG
.view_adminTemplates_disabledMetricTemplates());
- category.setType(ListGridFieldType.ICON);
- category.setShowValueIconOnly(true);
- HashMap<String, String> categoryIcons = new HashMap<String, String>(3);
- categoryIcons
- .put(ResourceCategory.PLATFORM.name(), ImageManager.getResourceIcon(ResourceCategory.PLATFORM));
- categoryIcons.put(ResourceCategory.SERVER.name(), ImageManager.getResourceIcon(ResourceCategory.SERVER));
- categoryIcons.put(ResourceCategory.SERVICE.name(), ImageManager.getResourceIcon(ResourceCategory.SERVICE));
- category.setValueIcons(categoryIcons);
- category.setShowHover(true);
- category.setHoverCustomizer(new HoverCustomizer() {
- @Override
- public String hoverHTML(Object value, ListGridRecord record, int rowNum, int colNum) {
- String cat = record.getAttribute(ResourceTypeTreeNodeBuilder.ATTRIB_CATEGORY);
- if (ResourceCategory.PLATFORM.name().equals(cat)) {
- return MSG.common_title_platform();
- } else if (ResourceCategory.SERVER.name().equals(cat)) {
- return MSG.common_title_server();
- } else if (ResourceCategory.SERVICE.name().equals(cat)) {
- return MSG.common_title_service();
- }
- return "";
- }
- });
-
- category.setHidden(true);
+ categoryField.setHidden(true);
- name.setWidth("*");
- plugin.setWidth("10%");
- category.setWidth("5%");
- enabledAlertTemplates.setWidth("10%");
- disabledAlertTemplates.setWidth("10%");
- enabledMetricTemplates.setWidth("10%");
- disabledMetricTemplates.setWidth("10%");
+ nameField.setWidth("*");
+ pluginField.setWidth("10%");
+ categoryField.setWidth("5%");
+ enabledAlertTemplatesField.setWidth("10%");
+ disabledAlertTemplatesField.setWidth("10%");
+ enabledMetricTemplatesField.setWidth("10%");
+ disabledMetricTemplatesField.setWidth("10%");
- enabledAlertTemplates.setPrompt(MSG.view_adminTemplates_prompt_enabledAlertTemplates());
- disabledAlertTemplates.setPrompt(MSG.view_adminTemplates_prompt_disabledAlertTemplates());
- enabledMetricTemplates.setPrompt(MSG.view_adminTemplates_prompt_enabledMetricTemplates());
- disabledMetricTemplates.setPrompt(MSG.view_adminTemplates_prompt_disabledMetricTemplates());
+ enabledAlertTemplatesField.setPrompt(MSG.view_adminTemplates_prompt_enabledAlertTemplates());
+ disabledAlertTemplatesField.setPrompt(MSG.view_adminTemplates_prompt_disabledAlertTemplates());
+ enabledMetricTemplatesField.setPrompt(MSG.view_adminTemplates_prompt_enabledMetricTemplates());
+ disabledMetricTemplatesField.setPrompt(MSG.view_adminTemplates_prompt_disabledMetricTemplates());
- setFields(name, plugin, category, enabledAlertTemplates, disabledAlertTemplates, enabledMetricTemplates,
- disabledMetricTemplates);
+ setFields(nameField, pluginField, categoryField, enabledAlertTemplatesField, disabledAlertTemplatesField,
+ enabledMetricTemplatesField, disabledMetricTemplatesField);
}
@Override
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/table/ResourceCategoryCellFormatter.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/table/ResourceCategoryCellFormatter.java
new file mode 100644
index 0000000..5a30742
--- /dev/null
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/table/ResourceCategoryCellFormatter.java
@@ -0,0 +1,54 @@
+package org.rhq.enterprise.gui.coregui.client.components.table;
+
+import com.smartgwt.client.widgets.grid.CellFormatter;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
+import org.rhq.core.domain.resource.ResourceCategory;
+import org.rhq.enterprise.gui.coregui.client.CoreGUI;
+import org.rhq.enterprise.gui.coregui.client.Messages;
+
+/**
+ * Formats a ResourceCategory value.
+ *
+ * @author Ian Springer
+ */
+public class ResourceCategoryCellFormatter implements CellFormatter {
+
+ private static final Messages MSG = CoreGUI.getMessages();
+
+ public String format(Object value, ListGridRecord record, int rowNum, int colNum) {
+ if (value == null) {
+ return "null";
+ }
+ ResourceCategory resourceCategory;
+ if (value instanceof ResourceCategory) {
+ resourceCategory = (ResourceCategory) value;
+ } else if (value instanceof String) {
+ String categoryName = (String) value;
+ resourceCategory = ResourceCategory.valueOf(categoryName);
+ } else {
+ throw new IllegalArgumentException("This cell formatter does not support values of type " +
+ value.getClass().getName());
+ }
+
+ return getDisplayName(resourceCategory);
+ }
+
+ private String getDisplayName(ResourceCategory resourceCategory) {
+ String displayName = "";
+
+ switch (resourceCategory) {
+ case PLATFORM:
+ displayName = MSG.common_title_platform();
+ break;
+ case SERVER:
+ displayName = MSG.common_title_server();
+ break;
+ case SERVICE:
+ displayName = MSG.common_title_service();
+ break;
+ }
+
+ return displayName;
+ }
+
+}
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 0a380d5..1977126 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
@@ -47,6 +47,7 @@ import org.rhq.core.domain.search.SearchSubsystem;
import org.rhq.enterprise.gui.coregui.client.CoreGUI;
import org.rhq.enterprise.gui.coregui.client.LinkManager;
import org.rhq.enterprise.gui.coregui.client.components.table.AbstractTableAction;
+import org.rhq.enterprise.gui.coregui.client.components.table.ResourceCategoryCellFormatter;
import org.rhq.enterprise.gui.coregui.client.components.table.Table;
import org.rhq.enterprise.gui.coregui.client.components.table.TableActionEnablement;
import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
@@ -174,25 +175,7 @@ public class ResourceSearchView extends Table {
ListGridField pluginNameField = new ListGridField(PLUGIN.propertyName(), PLUGIN.title(), 100);
ListGridField categoryField = new ListGridField(CATEGORY.propertyName(), CATEGORY.title(), 60);
- categoryField.setCellFormatter(new CellFormatter() {
- public String format(Object value, ListGridRecord record, int rowNum, int colNum) {
- String categoryName = (String) value;
- ResourceCategory category = ResourceCategory.valueOf(categoryName);
- String displayName = "";
- switch (category) {
- case PLATFORM:
- displayName = MSG.common_title_platform();
- break;
- case SERVER:
- displayName = MSG.common_title_server();
- break;
- case SERVICE:
- displayName = MSG.common_title_service();
- break;
- }
- return displayName;
- }
- });
+ categoryField.setCellFormatter(new ResourceCategoryCellFormatter());
categoryField.setHidden(true); // the icon field already shows us this, no need to show it in another column
ListGridField availabilityField = new ListGridField(AVAILABILITY.propertyName(), AVAILABILITY.title(), 70);
13 years, 2 months
[rhq] 5 commits - modules/core modules/enterprise
by Jay Shaughnessy
modules/core/dbutils/pom.xml | 2
modules/core/dbutils/src/main/java/org/rhq/core/db/upgrade/ResourceAncestryUpgradeTask.java | 95 ++++
modules/core/dbutils/src/main/scripts/dbsetup/inventory-schema.xml | 2
modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml | 7
modules/core/domain/src/main/java/org/rhq/core/domain/resource/Resource.java | 74 +++
modules/core/domain/src/main/java/org/rhq/core/domain/resource/composite/ProblemResourceComposite.java | 193 +++++-----
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/selector/AbstractSelector.java | 26 +
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/recent/problems/ProblemResourcesPortlet.java | 41 +-
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java | 4
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/inventory/MembersView.java | 21 -
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/inventory/ResourceGroupMembershipView.java | 31 +
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/AncestryUtil.java | 133 ++++++
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceCompositeDataSource.java | 100 +++--
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceDataSourceField.java | 4
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceDatasource.java | 37 +
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceSearchView.java | 20 -
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/selection/ResourceSelector.java | 28 +
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/resource/ProblemResourcesDataSource.java | 189 ++++++---
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/server/gwt/ResourceGWTServiceImpl.java | 50 +-
modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties | 3
modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_de.properties | 2
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java | 61 +--
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceFactoryManagerBean.java | 31 -
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceFactoryManagerLocal.java | 14
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java | 24 +
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerLocal.java | 15
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBean.java | 14
27 files changed, 874 insertions(+), 347 deletions(-)
New commits:
commit c54415b08a04677f06ecd9bcad77193a93f87081
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Tue Mar 8 14:22:40 2011 -0500
Disambiguation - More work on ProblemResourcesPortlet
- reverted using Resource entity in ProblemResourceComposite. As it turns out
it's about 19x more query processing time to construct resources than to pluck
add more individual fields to the composite. So, to actually improve
perf over the rhq3 D12N avoided using Resource entity.
- tweaked the resource filtering added recently to the
findResourceCompositesByCriteria service.
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/Resource.java b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/Resource.java
index 33e4b2f..7ce7a66 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/Resource.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/Resource.java
@@ -86,7 +86,7 @@ import org.rhq.core.domain.util.Summary;
@NamedQuery(name = Resource.QUERY_FIND_PROBLEM_RESOURCES_ALERT_ADMIN, query = "" //
+ " SELECT DISTINCT new org.rhq.core.domain.resource.composite.ProblemResourceComposite"
+ " ( "
- + " res, COUNT(DISTINCT alert.id), res.id, res.name, res.currentAvailability.availabilityType"
+ + " res.id, res.resourceType.id, res.name, res.ancestry, COUNT(DISTINCT alert.id), res.currentAvailability.availabilityType"
+ " ) "
+ " FROM Resource res "
+ " LEFT JOIN res.alertDefinitions alertDef "
@@ -94,11 +94,11 @@ import org.rhq.core.domain.util.Summary;
+ " WHERE res.inventoryStatus = 'COMMITTED' "
+ " AND (( res.currentAvailability.availabilityType = 0) " //
+ " OR (alert.ctime >= :oldest)) "
- + "GROUP BY res.id, res.name, res.currentAvailability.availabilityType "),
+ + "GROUP BY res.id, res.resourceType.id, res.name, res.ancestry, res.currentAvailability.availabilityType "),
@NamedQuery(name = Resource.QUERY_FIND_PROBLEM_RESOURCES_ALERT, query = "" //
+ " SELECT DISTINCT new org.rhq.core.domain.resource.composite.ProblemResourceComposite"
+ " ( "
- + " res, COUNT(DISTINCT alert.id), res.id, res.name, res.currentAvailability.availabilityType"
+ + " res.id, res.resourceType.id, res.name, res.ancestry, COUNT(DISTINCT alert.id), res.currentAvailability.availabilityType"
+ " ) "
+ " FROM Resource res "
+ " LEFT JOIN res.alertDefinitions alertDef "
@@ -107,7 +107,7 @@ import org.rhq.core.domain.util.Summary;
+ " AND res.inventoryStatus = 'COMMITTED' "
+ " AND (( res.currentAvailability.availabilityType = 0) " //
+ " OR (alert.ctime >= :oldest)) "
- + "GROUP BY res.id, res.name, res.currentAvailability.availabilityType "),
+ + "GROUP BY res.id, res.resourceType.id, res.name, res.ancestry, res.currentAvailability.availabilityType "),
@NamedQuery(name = Resource.QUERY_FIND_PROBLEM_RESOURCES_ALERT_COUNT_ADMIN, query = "" //
+ " SELECT COUNT( DISTINCT res.id ) "
+ " FROM Resource res "
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/composite/ProblemResourceComposite.java b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/composite/ProblemResourceComposite.java
index d9b34c5..6ce9895 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/composite/ProblemResourceComposite.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/composite/ProblemResourceComposite.java
@@ -25,7 +25,6 @@ package org.rhq.core.domain.resource.composite;
import java.io.Serializable;
import org.rhq.core.domain.measurement.AvailabilityType;
-import org.rhq.core.domain.resource.Resource;
/**
* Information on a resource that is considered having a "problem" - it is either {@link AvailabilityType#DOWN down},
@@ -37,46 +36,49 @@ public class ProblemResourceComposite implements Serializable {
private static final long serialVersionUID = 1L;
- private Resource resource;
- private long numAlerts;
- private AvailabilityType availabilityType;
-
- // TODO: The Resource entity has been added. Leaving these for backCompat in portal war. When portal war is
- // removed these fields should go. Note, keep availabilityType as it is not present by default in Resource.
+ //private Resource resource;
private int resourceId;
+ private int resourceTypeId;
private String resourceName;
+ private String ancestry;
+ private long numAlerts;
+ private AvailabilityType availabilityType;
/** Private no args contstructor for JAXB serialization. */
@SuppressWarnings("unused")
private ProblemResourceComposite() {
}
- public ProblemResourceComposite(Resource resource, long numAlerts, int resourceId, String resourceName,
- AvailabilityType availabilityType) {
- this.resource = resource;
- this.numAlerts = numAlerts;
- this.availabilityType = availabilityType; // pull explicitly because lazy-loaded by default
-
+ public ProblemResourceComposite(int resourceId, int resourceTypeId, String resourceName, String ancestry,
+ long numAlerts, AvailabilityType availabilityType) {
this.resourceId = resourceId;
+ this.resourceTypeId = resourceTypeId;
this.resourceName = resourceName;
+ this.ancestry = ancestry;
+ this.numAlerts = numAlerts;
+ this.availabilityType = availabilityType; // pull explicitly because lazy-loaded by default
}
public int getResourceId() {
return resourceId;
}
- public Resource getResource() {
- return resource;
- }
-
- public void setResource(Resource resource) {
- this.resource = resource;
+ public int getResourceTypeId() {
+ return resourceTypeId;
}
public String getResourceName() {
return resourceName;
}
+ public String getAncestry() {
+ return ancestry;
+ }
+
+ public long getNumAlerts() {
+ return numAlerts;
+ }
+
/**
* Indicates if the resource is down. If this returns <code>null</code>, the resource may be up or unknown. In any
* case, a <code>null</code> means the resource is not known to be down.
@@ -87,10 +89,6 @@ public class ProblemResourceComposite implements Serializable {
return availabilityType;
}
- public long getNumAlerts() {
- return numAlerts;
- }
-
@Override
public String toString() {
StringBuilder str = new StringBuilder("ProblemResource: ");
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/AncestryUtil.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/AncestryUtil.java
index cf6f1ef..6dd55ac 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/AncestryUtil.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/AncestryUtil.java
@@ -35,16 +35,15 @@ import org.rhq.enterprise.gui.coregui.client.util.selenium.SeleniumUtility;
public abstract class AncestryUtil {
/**
- * Get the complete set of resource types in the ancestry of the provided resources. This is useful for
+ * Get the complete set of resource types in the ancestries provided. This is useful for
* being able to load all the types in advance of generating decoded values.
*
* @return
*/
- public static HashSet<Integer> getResourceTypeIds(Collection<Resource> resources) {
+ public static HashSet<Integer> getAncestryTypeIds(Collection<String> ancestries) {
HashSet<Integer> result = new HashSet<Integer>();
- for (Resource resource : resources) {
- String ancestry = resource.getAncestry();
+ for (String ancestry : ancestries) {
if (null == ancestry) {
continue;
}
@@ -112,9 +111,8 @@ public abstract class AncestryUtil {
*
* @return the long name for the resource
*/
- public static String getResourceLongName(Resource resource) {
+ public static String getResourceLongName(int resourceId, String resourceName, ResourceType type) {
StringBuilder sb = new StringBuilder();
- ResourceType type = resource.getResourceType();
if (type != null) {
if (type.getPlugin() != null) {
sb.append(type.getPlugin());
@@ -125,9 +123,9 @@ public abstract class AncestryUtil {
sb.append(" ");
}
- String url = LinkManager.getResourceLink(resource.getId());
- String suffix = String.valueOf(resource.getId());
- sb.append(SeleniumUtility.getLocatableHref(url, resource.getName(), suffix));
+ String url = LinkManager.getResourceLink(resourceId);
+ String suffix = String.valueOf(resourceId);
+ sb.append(SeleniumUtility.getLocatableHref(url, resourceName, suffix));
return sb.toString();
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceCompositeDataSource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceCompositeDataSource.java
index 8a5e48a..8a7d883 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceCompositeDataSource.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceCompositeDataSource.java
@@ -89,6 +89,7 @@ public class ResourceCompositeDataSource extends RPCDataSource<ResourceComposite
protected void dataRetrieved(final PageList<ResourceComposite> result, final DSResponse response,
final DSRequest request) {
HashSet<Integer> typesSet = new HashSet<Integer>();
+ HashSet<String> ancestries = new HashSet<String>();
ArrayList<Resource> resources = new ArrayList<Resource>(result.size());
for (ResourceComposite resourceComposite : result) {
Resource resource = resourceComposite.getResource();
@@ -97,12 +98,13 @@ public class ResourceCompositeDataSource extends RPCDataSource<ResourceComposite
if (type != null) {
typesSet.add(type.getId());
}
+ ancestries.add(resource.getAncestry());
}
// In addition to the types of the result resources, get the types of their ancestry
- // NOTE: this may be too labor intensive in general, but since this is a singleton I coudln't
+ // NOTE: this may be too labor intensive in general, but since this is a singleton I couldn't
// make it easily optional.
- typesSet.addAll(AncestryUtil.getResourceTypeIds(resources));
+ typesSet.addAll(AncestryUtil.getAncestryTypeIds(ancestries));
ResourceTypeRepository typeRepo = ResourceTypeRepository.Cache.getInstance();
typeRepo.getResourceTypes(typesSet.toArray(new Integer[typesSet.size()]), new TypesLoadedCallback() {
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 a1d8505..7f7cb7e 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
@@ -149,17 +149,19 @@ public class ResourceDatasource extends RPCDataSource<Resource> {
protected void dataRetrieved(final PageList<Resource> result, final DSResponse response, final DSRequest request) {
HashSet<Integer> typesSet = new HashSet<Integer>();
+ HashSet<String> ancestries = new HashSet<String>();
for (Resource resource : result) {
ResourceType type = resource.getResourceType();
if (type != null) {
typesSet.add(type.getId());
}
+ ancestries.add(resource.getAncestry());
}
// In addition to the types of the result resources, get the types of their ancestry
- // NOTE: this may be too labor intensive in general, but since this is a singleton I coudln't
+ // NOTE: this may be too labor intensive in general, but since this is a singleton I couldn't
// make it easily optional.
- typesSet.addAll(AncestryUtil.getResourceTypeIds(result));
+ typesSet.addAll(AncestryUtil.getAncestryTypeIds(ancestries));
ResourceTypeRepository typeRepo = ResourceTypeRepository.Cache.getInstance();
typeRepo.getResourceTypes(typesSet.toArray(new Integer[typesSet.size()]), new TypesLoadedCallback() {
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/resource/ProblemResourcesDataSource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/resource/ProblemResourcesDataSource.java
index e299844..daa29e4 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/resource/ProblemResourcesDataSource.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/resource/ProblemResourcesDataSource.java
@@ -18,7 +18,6 @@ package org.rhq.enterprise.gui.coregui.client.resource;
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -34,7 +33,6 @@ import com.smartgwt.client.rpc.RPCResponse;
import com.smartgwt.client.widgets.grid.ListGridField;
import com.smartgwt.client.widgets.grid.ListGridRecord;
-import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.resource.composite.ProblemResourceComposite;
import org.rhq.core.domain.util.PageList;
@@ -66,7 +64,9 @@ public class ProblemResourcesDataSource extends RPCDataSource<ProblemResourceCom
AVAILABILITY("availabilityType", CoreGUI.getMessages().common_title_availability()),
- RESOURCE("resource", CoreGUI.getMessages().common_title_resource());
+ RESOURCE("resource", CoreGUI.getMessages().common_title_resource()),
+
+ TYPE("resourceType", CoreGUI.getMessages().common_title_type());
/**
* Corresponds to a property name of Resource (e.g. resourceType.name).
@@ -181,20 +181,16 @@ public class ProblemResourcesDataSource extends RPCDataSource<ProblemResourceCom
protected void dataRetrieved(final PageList<ProblemResourceComposite> result, final DSResponse response,
final DSRequest request) {
HashSet<Integer> typesSet = new HashSet<Integer>();
- ArrayList<Resource> resources = new ArrayList<Resource>(result.size());
+ HashSet<String> ancestries = new HashSet<String>();
for (ProblemResourceComposite resourceComposite : result) {
- Resource resource = resourceComposite.getResource();
- resources.add(resource);
- ResourceType type = resource.getResourceType();
- if (type != null) {
- typesSet.add(type.getId());
- }
+ typesSet.add(resourceComposite.getResourceTypeId());
+ ancestries.add(resourceComposite.getAncestry());
}
// In addition to the types of the result resources, get the types of their ancestry
- // NOTE: this may be too labor intensive in general, but since this is a singleton I coudln't
+ // NOTE: this may be too labor intensive in general, but since this datasource is a singleton I couldn't
// make it easily optional.
- typesSet.addAll(AncestryUtil.getResourceTypeIds(resources));
+ typesSet.addAll(AncestryUtil.getAncestryTypeIds(ancestries));
ResourceTypeRepository typeRepo = ResourceTypeRepository.Cache.getInstance();
typeRepo.getResourceTypes(typesSet.toArray(new Integer[typesSet.size()]), new TypesLoadedCallback() {
@@ -203,12 +199,19 @@ public class ProblemResourcesDataSource extends RPCDataSource<ProblemResourceCom
Record[] records = buildRecords(result);
for (Record record : records) {
+ // enhance resource name
+ int resourceId = record.getAttributeAsInt("id");
+ int resourceTypeId = record.getAttributeAsInt(Field.TYPE.propertyName);
+ String resourceName = record.getAttributeAsString(Field.RESOURCE.propertyName);
+ ResourceType type = types.get(resourceTypeId);
+ record.setAttribute(Field.RESOURCE.propertyName, AncestryUtil.getResourceLongName(resourceId,
+ resourceName, type));
+
// decode ancestry
String ancestry = record.getAttributeAsString(Field.ANCESTRY.propertyName());
if (null == ancestry) {
continue;
}
- int resourceId = record.getAttributeAsInt("id");
String[] decodedAncestry = AncestryUtil.decodeAncestry(resourceId, ancestry, types);
// Preserve the encoded ancestry for special-case formatting at higher levels. Set the
// decoded strings as different attributes.
@@ -225,13 +228,13 @@ public class ProblemResourcesDataSource extends RPCDataSource<ProblemResourceCom
@Override
public ListGridRecord copyValues(ProblemResourceComposite from) {
ListGridRecord record = new ListGridRecord();
- Resource resource = from.getResource();
- record.setAttribute("id", resource.getId());
- record.setAttribute(Field.RESOURCE.propertyName, AncestryUtil.getResourceLongName(resource));
- record.setAttribute(Field.ANCESTRY.propertyName, resource.getAncestry());
+ record.setAttribute("id", from.getResourceId());
+ record.setAttribute(Field.ANCESTRY.propertyName, from.getAncestry());
record.setAttribute(Field.ALERTS.propertyName, from.getNumAlerts());
record.setAttribute(Field.AVAILABILITY.propertyName, ImageManager.getAvailabilityIconFromAvailType(from
.getAvailabilityType()));
+ record.setAttribute(Field.RESOURCE.propertyName, from.getResourceName());
+ record.setAttribute(Field.TYPE.propertyName, from.getResourceTypeId());
record.setAttribute("entity", from);
return record;
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 b1ce435..2925d5e 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
@@ -142,11 +142,11 @@ public class ResourceGWTServiceImpl extends AbstractGWTServiceImpl implements Re
try {
PageList<ResourceComposite> result = resourceManager.findResourceCompositesByCriteria(getSessionSubject(),
criteria);
- List<Resource> resources = new ArrayList<Resource>(result.size());
- for (ResourceComposite composite : result) {
- resources.add(composite.getResource());
- }
- if (resources.size() > 1) {
+ if (result.size() > 1) {
+ List<Resource> resources = new ArrayList<Resource>(result.size());
+ for (ResourceComposite composite : result) {
+ resources.add(composite.getResource());
+ }
ObjectFilter.filterFieldsInCollection(resources, importantFieldsSet);
}
@@ -164,13 +164,6 @@ public class ResourceGWTServiceImpl extends AbstractGWTServiceImpl implements Re
MeasurementProblemManagerLocal problemManager = LookupUtil.getMeasurementProblemManager();
PageList<ProblemResourceComposite> result = problemManager.findProblemResources(getSessionSubject(), ctime,
new PageControl(0, maxItems));
- List<Resource> resources = new ArrayList<Resource>(result.size());
- for (ProblemResourceComposite composite : result) {
- resources.add(composite.getResource());
- }
- if (resources.size() > 1) {
- ObjectFilter.filterFieldsInCollection(resources, importantFieldsSet);
- }
return SerialUtility.prepare(result, "ResourceService.findProblemResources");
} catch (Throwable t) {
commit 83372fe2d44ba13d4c3690df433d1948106b44da
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Mon Mar 7 16:17:01 2011 -0500
Convert the Problem Resources portlet to use ancestry-based disambiguation.
- Change ProblemResourceComposite to contain a Resource entity as opposed to
individual fields. This provides ancestry and simplifies usage.
- removed a couple of obsolete I18N properties.
Also
- added missing Resource entity filtering in findResourceCompositesByCriteria
- protect against db storage of excessive ancestry string
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/Resource.java b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/Resource.java
index 9da2469..33e4b2f 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/Resource.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/Resource.java
@@ -86,7 +86,7 @@ import org.rhq.core.domain.util.Summary;
@NamedQuery(name = Resource.QUERY_FIND_PROBLEM_RESOURCES_ALERT_ADMIN, query = "" //
+ " SELECT DISTINCT new org.rhq.core.domain.resource.composite.ProblemResourceComposite"
+ " ( "
- + " res.id, res.name, res.currentAvailability.availabilityType, COUNT(DISTINCT alert.id)"
+ + " res, COUNT(DISTINCT alert.id), res.id, res.name, res.currentAvailability.availabilityType"
+ " ) "
+ " FROM Resource res "
+ " LEFT JOIN res.alertDefinitions alertDef "
@@ -98,7 +98,7 @@ import org.rhq.core.domain.util.Summary;
@NamedQuery(name = Resource.QUERY_FIND_PROBLEM_RESOURCES_ALERT, query = "" //
+ " SELECT DISTINCT new org.rhq.core.domain.resource.composite.ProblemResourceComposite"
+ " ( "
- + " res.id, res.name, res.currentAvailability.availabilityType, COUNT(DISTINCT alert.id)"
+ + " res, COUNT(DISTINCT alert.id), res.id, res.name, res.currentAvailability.availabilityType"
+ " ) "
+ " FROM Resource res "
+ " LEFT JOIN res.alertDefinitions alertDef "
@@ -1183,7 +1183,11 @@ public class Resource implements Comparable<Resource>, Serializable {
ancestry.append(parentAncestry);
}
- this.setAncestry(ancestry.toString());
+ // protect against the *very* unlikely case that this value is too big for the db
+ if (ancestry.length() < 4000) {
+ this.setAncestry(ancestry.toString());
+ }
+
return this.getAncestry();
}
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/composite/ProblemResourceComposite.java b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/composite/ProblemResourceComposite.java
index c099c90..d9b34c5 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/composite/ProblemResourceComposite.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/composite/ProblemResourceComposite.java
@@ -1,91 +1,106 @@
-/*
- * 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.resource.composite;
-
-import java.io.Serializable;
-
-import org.rhq.core.domain.measurement.AvailabilityType;
-
-/**
- * Information on a resource that is considered having a "problem" - it is either {@link AvailabilityType#DOWN down},
- * has one or more alerts, or a combination of those two conditions.
- *
- * @author John Mazzitelli
- */
-public class ProblemResourceComposite implements Serializable {
-
- private static final long serialVersionUID = 1L;
-
- private int resourceId;
- private String resourceName;
- private AvailabilityType availabilityType;
- private long numAlerts;
-
- /** Private no args contstructor for JAXB serialization. */
- @SuppressWarnings("unused")
- private ProblemResourceComposite() {
- }
-
- public ProblemResourceComposite(int resourceId, String resourceName, AvailabilityType availabilityType,
- long numAlerts) {
- this.resourceId = resourceId;
- this.resourceName = resourceName;
- this.availabilityType = availabilityType;
- this.numAlerts = numAlerts;
- }
-
- public int getResourceId() {
- return resourceId;
- }
-
- public String getResourceName() {
- return resourceName;
- }
-
- /**
- * Indicates if the resource is down. If this returns <code>null</code>, the resource may be up or unknown. In any
- * case, a <code>null</code> means the resource is not known to be down.
- *
- * @return up or down status of the resource
- */
- public AvailabilityType getAvailabilityType() {
- return availabilityType;
- }
-
- public long getNumAlerts() {
- return numAlerts;
- }
-
- @Override
- public String toString() {
- StringBuilder str = new StringBuilder("ProblemResource: ");
-
- str.append("resource-id=[" + this.resourceId);
- str.append("], resource-name=[" + this.resourceName);
- str.append("], availability-type=[" + this.availabilityType);
- str.append("], num-alerts=[" + this.numAlerts);
- str.append("]");
-
- return str.toString();
- }
+/*
+ * 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.resource.composite;
+
+import java.io.Serializable;
+
+import org.rhq.core.domain.measurement.AvailabilityType;
+import org.rhq.core.domain.resource.Resource;
+
+/**
+ * Information on a resource that is considered having a "problem" - it is either {@link AvailabilityType#DOWN down},
+ * has one or more alerts, or a combination of those two conditions.
+ *
+ * @author John Mazzitelli
+ */
+public class ProblemResourceComposite implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private Resource resource;
+ private long numAlerts;
+ private AvailabilityType availabilityType;
+
+ // TODO: The Resource entity has been added. Leaving these for backCompat in portal war. When portal war is
+ // removed these fields should go. Note, keep availabilityType as it is not present by default in Resource.
+ private int resourceId;
+ private String resourceName;
+
+ /** Private no args contstructor for JAXB serialization. */
+ @SuppressWarnings("unused")
+ private ProblemResourceComposite() {
+ }
+
+ public ProblemResourceComposite(Resource resource, long numAlerts, int resourceId, String resourceName,
+ AvailabilityType availabilityType) {
+ this.resource = resource;
+ this.numAlerts = numAlerts;
+ this.availabilityType = availabilityType; // pull explicitly because lazy-loaded by default
+
+ this.resourceId = resourceId;
+ this.resourceName = resourceName;
+ }
+
+ public int getResourceId() {
+ return resourceId;
+ }
+
+ public Resource getResource() {
+ return resource;
+ }
+
+ public void setResource(Resource resource) {
+ this.resource = resource;
+ }
+
+ public String getResourceName() {
+ return resourceName;
+ }
+
+ /**
+ * Indicates if the resource is down. If this returns <code>null</code>, the resource may be up or unknown. In any
+ * case, a <code>null</code> means the resource is not known to be down.
+ *
+ * @return up or down status of the resource
+ */
+ public AvailabilityType getAvailabilityType() {
+ return availabilityType;
+ }
+
+ public long getNumAlerts() {
+ return numAlerts;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder str = new StringBuilder("ProblemResource: ");
+
+ str.append("resource-id=[" + this.resourceId);
+ str.append("], resource-name=[" + this.resourceName);
+ str.append("], availability-type=[" + this.availabilityType);
+ str.append("], num-alerts=[" + this.numAlerts);
+ str.append("]");
+
+ return str.toString();
+ }
}
\ No newline at end of file
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/recent/problems/ProblemResourcesPortlet.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/recent/problems/ProblemResourcesPortlet.java
index 1eccd68..b21f9c4 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/recent/problems/ProblemResourcesPortlet.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/dashboard/portlets/recent/problems/ProblemResourcesPortlet.java
@@ -20,10 +20,17 @@ package org.rhq.enterprise.gui.coregui.client.dashboard.portlets.recent.problems
*/
//import java.text.SimpleDateFormat;
+import static org.rhq.enterprise.gui.coregui.client.resource.ProblemResourcesDataSource.Field.ALERTS;
+import static org.rhq.enterprise.gui.coregui.client.resource.ProblemResourcesDataSource.Field.ANCESTRY;
+import static org.rhq.enterprise.gui.coregui.client.resource.ProblemResourcesDataSource.Field.AVAILABILITY;
+import static org.rhq.enterprise.gui.coregui.client.resource.ProblemResourcesDataSource.Field.RESOURCE;
+
import java.util.Date;
import java.util.List;
import com.google.gwt.user.client.Timer;
+import com.smartgwt.client.types.Alignment;
+import com.smartgwt.client.types.ListGridFieldType;
import com.smartgwt.client.types.Overflow;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.HTMLFlow;
@@ -31,7 +38,11 @@ import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.events.SubmitValuesEvent;
import com.smartgwt.client.widgets.form.events.SubmitValuesHandler;
import com.smartgwt.client.widgets.form.fields.SelectItem;
+import com.smartgwt.client.widgets.grid.CellFormatter;
+import com.smartgwt.client.widgets.grid.HoverCustomizer;
import com.smartgwt.client.widgets.grid.ListGrid;
+import com.smartgwt.client.widgets.grid.ListGridField;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
import org.rhq.core.domain.configuration.PropertySimple;
import org.rhq.core.domain.configuration.definition.ConfigurationDefinition;
@@ -46,6 +57,7 @@ import org.rhq.enterprise.gui.coregui.client.dashboard.CustomSettingsPortlet;
import org.rhq.enterprise.gui.coregui.client.dashboard.Portlet;
import org.rhq.enterprise.gui.coregui.client.dashboard.PortletViewFactory;
import org.rhq.enterprise.gui.coregui.client.dashboard.PortletWindow;
+import org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceDatasource;
import org.rhq.enterprise.gui.coregui.client.resource.ProblemResourcesDataSource;
import org.rhq.enterprise.gui.coregui.client.util.MeasurementUtility;
import org.rhq.enterprise.gui.coregui.client.util.selenium.LocatableDynamicForm;
@@ -105,13 +117,34 @@ public class ProblemResourcesPortlet extends Table implements CustomSettingsPort
protected void configureTable() {
ListGrid listGrid = getListGrid();
if (listGrid != null) {
- //extend height for displaying disambiguated resources
- listGrid.setCellHeight(50);
- //wrap to display disambiguation
- listGrid.setWrapCells(true);
addExtraWidget(new TimeRange(extendLocatorId("TimeRange"), this), false);
}
+ ListGridField resourceField = new ListGridField(RESOURCE.propertyName(), RESOURCE.title());
+
+ ListGridField ancestryField = new ListGridField(ANCESTRY.propertyName(), ANCESTRY.title());
+ ancestryField.setCellFormatter(new CellFormatter() {
+ public String format(Object o, ListGridRecord listGridRecord, int rowNum, int colNum) {
+ return listGridRecord.getAttributeAsString(ResourceDatasource.ATTR_ANCESTRY_RESOURCES);
+ }
+ });
+ ancestryField.setShowHover(true);
+ ancestryField.setHoverCustomizer(new HoverCustomizer() {
+ public String hoverHTML(Object value, ListGridRecord listGridRecord, int rowNum, int colNum) {
+ return "<p style='width:400px'>"
+ + listGridRecord.getAttributeAsString(ResourceDatasource.ATTR_ANCESTRY_RESOURCES) + "</br>"
+ + listGridRecord.getAttributeAsString(ResourceDatasource.ATTR_ANCESTRY_TYPES) + "</p>";
+ }
+ });
+
+ ListGridField alertsField = new ListGridField(ALERTS.propertyName(), ALERTS.title(), 70);
+
+ ListGridField availabilityField = new ListGridField(AVAILABILITY.propertyName(), AVAILABILITY.title(), 70);
+ availabilityField.setType(ListGridFieldType.IMAGE);
+ availabilityField.setAlign(Alignment.CENTER);
+
+ setListGridFields(resourceField, ancestryField, alertsField, availabilityField);
+
}
@Override
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java
index ccf6a0b..72be13d 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/gwt/ResourceGWTService.java
@@ -30,7 +30,6 @@ import org.rhq.core.domain.resource.DeleteResourceHistory;
import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceError;
-import org.rhq.core.domain.resource.composite.DisambiguationReport;
import org.rhq.core.domain.resource.composite.ProblemResourceComposite;
import org.rhq.core.domain.resource.composite.RecentlyAddedResourceComposite;
import org.rhq.core.domain.resource.composite.ResourceComposite;
@@ -60,8 +59,7 @@ public interface ResourceGWTService extends RemoteService {
List<ResourceError> findResourceErrors(int resourceId) throws RuntimeException;
- List<DisambiguationReport<ProblemResourceComposite>> findProblemResources(long ctime, int maxItems)
- throws RuntimeException;
+ PageList<ProblemResourceComposite> findProblemResources(long ctime, int maxItems) throws RuntimeException;
Resource getPlatformForResource(int resourceId) throws RuntimeException;
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/AncestryUtil.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/AncestryUtil.java
index 71e1a79..cf6f1ef 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/AncestryUtil.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/AncestryUtil.java
@@ -45,6 +45,9 @@ public abstract class AncestryUtil {
for (Resource resource : resources) {
String ancestry = resource.getAncestry();
+ if (null == ancestry) {
+ continue;
+ }
String[] ancestryEntries = ancestry.split(Resource.ANCESTRY_DELIM);
for (int i = 0; i < ancestryEntries.length; ++i) {
String[] entryTokens = ancestryEntries[i].split(Resource.ANCESTRY_ENTRY_DELIM);
@@ -101,4 +104,32 @@ public abstract class AncestryUtil {
return result;
}
+ /**
+ * Get a resource name that combines type and resource information. This is useful for when we want to
+ * use a single column for dispay of the resource "name". The name is wrapped in a navigable link.
+ *
+ * @param resource The resource
+ *
+ * @return the long name for the resource
+ */
+ public static String getResourceLongName(Resource resource) {
+ StringBuilder sb = new StringBuilder();
+ ResourceType type = resource.getResourceType();
+ if (type != null) {
+ if (type.getPlugin() != null) {
+ sb.append(type.getPlugin());
+ sb.append(" ");
+ }
+
+ sb.append(type.getName());
+ sb.append(" ");
+ }
+
+ String url = LinkManager.getResourceLink(resource.getId());
+ String suffix = String.valueOf(resource.getId());
+ sb.append(SeleniumUtility.getLocatableHref(url, resource.getName(), suffix));
+
+ return sb.toString();
+ }
+
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/resource/ProblemResourcesDataSource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/resource/ProblemResourcesDataSource.java
index b21b0bf..e299844 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/resource/ProblemResourcesDataSource.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/resource/ProblemResourcesDataSource.java
@@ -18,7 +18,10 @@ package org.rhq.enterprise.gui.coregui.client.resource;
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.smartgwt.client.data.DSRequest;
@@ -27,16 +30,23 @@ import com.smartgwt.client.data.DataSourceField;
import com.smartgwt.client.data.Record;
import com.smartgwt.client.data.fields.DataSourceImageField;
import com.smartgwt.client.data.fields.DataSourceTextField;
+import com.smartgwt.client.rpc.RPCResponse;
+import com.smartgwt.client.widgets.grid.ListGridField;
import com.smartgwt.client.widgets.grid.ListGridRecord;
-import org.rhq.core.domain.resource.composite.DisambiguationReport;
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.resource.composite.ProblemResourceComposite;
+import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.gui.coregui.client.CoreGUI;
import org.rhq.enterprise.gui.coregui.client.ImageManager;
import org.rhq.enterprise.gui.coregui.client.dashboard.Portlet;
import org.rhq.enterprise.gui.coregui.client.dashboard.portlets.recent.problems.ProblemResourcesPortlet;
import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
-import org.rhq.enterprise.gui.coregui.client.resource.disambiguation.ReportDecorator;
+import org.rhq.enterprise.gui.coregui.client.inventory.resource.AncestryUtil;
+import org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceDatasource;
+import org.rhq.enterprise.gui.coregui.client.inventory.resource.type.ResourceTypeRepository;
+import org.rhq.enterprise.gui.coregui.client.inventory.resource.type.ResourceTypeRepository.TypesLoadedCallback;
import org.rhq.enterprise.gui.coregui.client.util.RPCDataSource;
/**
@@ -44,13 +54,52 @@ import org.rhq.enterprise.gui.coregui.client.util.RPCDataSource;
* translating the deserialized content into specific record entries for display
*
* @author Simeon Pinder
+ * @author Jay Shaughnessy
*/
-public class ProblemResourcesDataSource extends RPCDataSource<DisambiguationReport<ProblemResourceComposite>> {
+public class ProblemResourcesDataSource extends RPCDataSource<ProblemResourceComposite> {
- public static final String FIELD_RESOURCE = "resource";
- public static final String FIELD_LOCATION = "location";
- public static final String FIELD_ALERTS = "alerts";
- public static final String FIELD_AVAILABLE = "available";
+ public enum Field {
+
+ ALERTS("numAlerts", CoreGUI.getMessages().dataSource_problemResources_field_alerts()),
+
+ ANCESTRY("resource.ancestry", CoreGUI.getMessages().common_title_ancestry()),
+
+ AVAILABILITY("availabilityType", CoreGUI.getMessages().common_title_availability()),
+
+ RESOURCE("resource", CoreGUI.getMessages().common_title_resource());
+
+ /**
+ * Corresponds to a property name of Resource (e.g. resourceType.name).
+ */
+ private String propertyName;
+
+ /**
+ * The table header for the field or property (e.g. Type).
+ */
+ private String title;
+
+ private Field(String propertyName, String title) {
+ this.propertyName = propertyName;
+ this.title = title;
+ }
+
+ public String propertyName() {
+ return propertyName;
+ }
+
+ public String title() {
+ return title;
+ }
+
+ public ListGridField getListGridField() {
+ return new ListGridField(propertyName, title);
+ }
+
+ public ListGridField getListGridField(int width) {
+ return new ListGridField(propertyName, title, width);
+ }
+
+ }
private Portlet portlet = null;
private long oldestDate = -1;
@@ -73,21 +122,16 @@ public class ProblemResourcesDataSource extends RPCDataSource<DisambiguationRepo
protected List<DataSourceField> addDataSourceFields() {
List<DataSourceField> fields = super.addDataSourceFields();
- DataSourceTextField resourceField = new DataSourceTextField(FIELD_RESOURCE, MSG
- .dataSource_problemResources_field_resource());
- resourceField.setPrimaryKey(true);
- fields.add(resourceField);
+ DataSourceTextField ancestryField = new DataSourceTextField(Field.ANCESTRY.propertyName(), Field.ANCESTRY
+ .title());
+ fields.add(ancestryField);
- DataSourceTextField locationField = new DataSourceTextField(FIELD_LOCATION, MSG
- .dataSource_problemResources_field_location());
- fields.add(locationField);
-
- DataSourceTextField alertsField = new DataSourceTextField(FIELD_ALERTS, MSG
- .dataSource_problemResources_field_alerts());
+ DataSourceTextField alertsField = new DataSourceTextField(Field.ALERTS.propertyName, Field.ALERTS.title());
fields.add(alertsField);
- DataSourceImageField availabilityField = new DataSourceImageField(FIELD_AVAILABLE, MSG
- .dataSource_problemResources_field_available());
+ DataSourceImageField availabilityField = new DataSourceImageField(Field.AVAILABILITY.propertyName,
+ Field.AVAILABILITY.title(), 20);
+ availabilityField.setCanEdit(false);
fields.add(availabilityField);
return fields;
@@ -119,70 +163,74 @@ public class ProblemResourcesDataSource extends RPCDataSource<DisambiguationRepo
}
GWTServiceLookup.getResourceService().findProblemResources(ctime, maxItems,
- new AsyncCallback<List<DisambiguationReport<ProblemResourceComposite>>>() {
+ new AsyncCallback<PageList<ProblemResourceComposite>>() {
public void onFailure(Throwable throwable) {
CoreGUI.getErrorHandler().handleError(MSG.dataSource_problemResources_error_fetchFailure(),
throwable);
+ response.setStatus(RPCResponse.STATUS_FAILURE);
+ processResponse(request.getRequestId(), response);
}
- public void onSuccess(List<DisambiguationReport<ProblemResourceComposite>> problemResourcesList) {
-
- //translate DisambiguationReport into dataset entries
- response.setData(buildList(problemResourcesList));
- //entry count
- if (null != problemResourcesList) {
- response.setTotalRows(problemResourcesList.size());
- } else {
- response.setTotalRows(0);
- }
- //pass off for processing
- processResponse(request.getRequestId(), response);
+ public void onSuccess(PageList<ProblemResourceComposite> result) {
+ dataRetrieved(result, response, request);
}
});
}
- /** Translates the DisambiguationReport of ProblemResourceComposites into specific
- * and ordered record values.
- *
- * @param list DisambiguationReport of entries.
- * @return Record[] ordered record entries.
- */
- protected Record[] buildList(List<DisambiguationReport<ProblemResourceComposite>> list) {
-
- ListGridRecord[] dataValues = null;
- if (list != null) {
- dataValues = new ListGridRecord[list.size()];
- int indx = 0;
-
- for (DisambiguationReport<ProblemResourceComposite> report : list) {
- ListGridRecord record = new ListGridRecord();
- //disambiguated Resource name, decorated with html anchors to problem resources
- record.setAttribute(FIELD_RESOURCE, ReportDecorator.decorateResourceName(
- ReportDecorator.GWT_RESOURCE_URL, report.getResourceType(), report.getOriginal().getResourceName(),
- report.getOriginal().getResourceId(), true));
- //disambiguated resource lineage, decorated with html anchors
- record.setAttribute(FIELD_LOCATION, ReportDecorator.decorateResourceLineage(report.getParents(), true));
- //alert cnt.
- record.setAttribute(FIELD_ALERTS, report.getOriginal().getNumAlerts());
- //populate availability icon
- record.setAttribute(FIELD_AVAILABLE, ImageManager.getAvailabilityIconFromAvailType(report.getOriginal()
- .getAvailabilityType()));
-
- dataValues[indx++] = record;
+ protected void dataRetrieved(final PageList<ProblemResourceComposite> result, final DSResponse response,
+ final DSRequest request) {
+ HashSet<Integer> typesSet = new HashSet<Integer>();
+ ArrayList<Resource> resources = new ArrayList<Resource>(result.size());
+ for (ProblemResourceComposite resourceComposite : result) {
+ Resource resource = resourceComposite.getResource();
+ resources.add(resource);
+ ResourceType type = resource.getResourceType();
+ if (type != null) {
+ typesSet.add(type.getId());
}
}
- return dataValues;
+
+ // In addition to the types of the result resources, get the types of their ancestry
+ // NOTE: this may be too labor intensive in general, but since this is a singleton I coudln't
+ // make it easily optional.
+ typesSet.addAll(AncestryUtil.getResourceTypeIds(resources));
+
+ ResourceTypeRepository typeRepo = ResourceTypeRepository.Cache.getInstance();
+ typeRepo.getResourceTypes(typesSet.toArray(new Integer[typesSet.size()]), new TypesLoadedCallback() {
+ @Override
+ public void onTypesLoaded(Map<Integer, ResourceType> types) {
+
+ Record[] records = buildRecords(result);
+ for (Record record : records) {
+ // decode ancestry
+ String ancestry = record.getAttributeAsString(Field.ANCESTRY.propertyName());
+ if (null == ancestry) {
+ continue;
+ }
+ int resourceId = record.getAttributeAsInt("id");
+ String[] decodedAncestry = AncestryUtil.decodeAncestry(resourceId, ancestry, types);
+ // Preserve the encoded ancestry for special-case formatting at higher levels. Set the
+ // decoded strings as different attributes.
+ record.setAttribute(ResourceDatasource.ATTR_ANCESTRY_RESOURCES, decodedAncestry[0]);
+ record.setAttribute(ResourceDatasource.ATTR_ANCESTRY_TYPES, decodedAncestry[1]);
+ }
+ response.setData(records);
+ response.setTotalRows(result.getTotalSize()); // for paging to work we have to specify size of full result set
+ processResponse(request.getRequestId(), response);
+ }
+ });
}
@Override
- public ListGridRecord copyValues(DisambiguationReport<ProblemResourceComposite> from) {
+ public ListGridRecord copyValues(ProblemResourceComposite from) {
ListGridRecord record = new ListGridRecord();
- record.setAttribute(FIELD_RESOURCE, ReportDecorator.decorateResourceName(ReportDecorator.GWT_RESOURCE_URL, from
- .getResourceType(), from.getOriginal().getResourceName(), from.getOriginal().getResourceId(), true));
- record.setAttribute(FIELD_LOCATION, ReportDecorator.decorateResourceLineage(from.getParents(), true));
- record.setAttribute(FIELD_ALERTS, from.getOriginal().getNumAlerts());
- record.setAttribute(FIELD_AVAILABLE, ImageManager.getAvailabilityIconFromAvailType(from.getOriginal()
+ Resource resource = from.getResource();
+ record.setAttribute("id", resource.getId());
+ record.setAttribute(Field.RESOURCE.propertyName, AncestryUtil.getResourceLongName(resource));
+ record.setAttribute(Field.ANCESTRY.propertyName, resource.getAncestry());
+ record.setAttribute(Field.ALERTS.propertyName, from.getNumAlerts());
+ record.setAttribute(Field.AVAILABILITY.propertyName, ImageManager.getAvailabilityIconFromAvailType(from
.getAvailabilityType()));
record.setAttribute("entity", from);
@@ -190,7 +238,7 @@ public class ProblemResourcesDataSource extends RPCDataSource<DisambiguationRepo
}
@Override
- public DisambiguationReport<ProblemResourceComposite> copyValues(Record from) {
+ public ProblemResourceComposite copyValues(Record from) {
throw new UnsupportedOperationException("ProblemResource data is read only");
}
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 218765c..b1ce435 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
@@ -37,7 +37,6 @@ import org.rhq.core.domain.resource.DeleteResourceHistory;
import org.rhq.core.domain.resource.InventoryStatus;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceError;
-import org.rhq.core.domain.resource.composite.DisambiguationReport;
import org.rhq.core.domain.resource.composite.ProblemResourceComposite;
import org.rhq.core.domain.resource.composite.RecentlyAddedResourceComposite;
import org.rhq.core.domain.resource.composite.ResourceComposite;
@@ -53,7 +52,6 @@ import org.rhq.enterprise.server.discovery.DiscoveryBossLocal;
import org.rhq.enterprise.server.measurement.MeasurementProblemManagerLocal;
import org.rhq.enterprise.server.resource.ResourceFactoryManagerLocal;
import org.rhq.enterprise.server.resource.ResourceManagerLocal;
-import org.rhq.enterprise.server.resource.disambiguation.DefaultDisambiguationUpdateStrategies;
import org.rhq.enterprise.server.util.LookupUtil;
/**
@@ -145,7 +143,9 @@ public class ResourceGWTServiceImpl extends AbstractGWTServiceImpl implements Re
PageList<ResourceComposite> result = resourceManager.findResourceCompositesByCriteria(getSessionSubject(),
criteria);
List<Resource> resources = new ArrayList<Resource>(result.size());
-
+ for (ResourceComposite composite : result) {
+ resources.add(composite.getResource());
+ }
if (resources.size() > 1) {
ObjectFilter.filterFieldsInCollection(resources, importantFieldsSet);
}
@@ -159,20 +159,20 @@ public class ResourceGWTServiceImpl extends AbstractGWTServiceImpl implements Re
/** Locate ProblemResourcesComposites and generate the disambiguation reports for them.
* Criteria passed in not currently used.
*/
- public List<DisambiguationReport<ProblemResourceComposite>> findProblemResources(long ctime, int maxItems)
- throws RuntimeException {
+ public PageList<ProblemResourceComposite> findProblemResources(long ctime, int maxItems) throws RuntimeException {
try {
- List<ProblemResourceComposite> located = new ArrayList<ProblemResourceComposite>();
MeasurementProblemManagerLocal problemManager = LookupUtil.getMeasurementProblemManager();
- ResourceManagerLocal resourceManager = LookupUtil.getResourceManager();
-
- //retrieve list of discovered problem resources. Grab all, live scrolling data
- located = problemManager.findProblemResources(getSessionSubject(), ctime, new PageControl(0, maxItems));
+ PageList<ProblemResourceComposite> result = problemManager.findProblemResources(getSessionSubject(), ctime,
+ new PageControl(0, maxItems));
+ List<Resource> resources = new ArrayList<Resource>(result.size());
+ for (ProblemResourceComposite composite : result) {
+ resources.add(composite.getResource());
+ }
+ if (resources.size() > 1) {
+ ObjectFilter.filterFieldsInCollection(resources, importantFieldsSet);
+ }
- //translate the returned problem resources to disambiguated links
- List<DisambiguationReport<ProblemResourceComposite>> translated = resourceManager.disambiguate(located,
- RESOURCE_ID_EXTRACTOR, DefaultDisambiguationUpdateStrategies.getDefault());
- return translated;
+ return SerialUtility.prepare(result, "ResourceService.findProblemResources");
} catch (Throwable t) {
throw new RuntimeException(ThrowableUtil.getAllMessages(t));
}
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties
index f7bfa4a..d2ad756 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties
@@ -499,8 +499,6 @@ dataSource_resourceGroups_loadFailed = Failed to load Resource Groups
# Problem Resources
#------------------------------
-dataSource_problemResources_field_resource = Resource
-dataSource_problemResources_field_location = Location
dataSource_problemResources_field_alerts = Alerts
dataSource_problemResources_field_available = Current Availability
dataSource_problemResources_error_fetchFailure = Failed to load Resources with alerts/unavailability.
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_de.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_de.properties
index 22e239a..713ecee 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_de.properties
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages_de.properties
@@ -365,8 +365,6 @@ dataSource_schedules_updateSuccessful_full_group=A new collection interval of [{
# Problem Resources
#------------------------------
-dataSource_problemResources_field_resource = Ressource
-dataSource_problemResources_field_location = Ort
dataSource_problemResources_field_alerts = Alarme
dataSource_problemResources_field_available = Aktuelle Verfügbarkeit
dataSource_problemResources_error_fetchFailure = Konnte die Liste der Ressourcen mit Alarmen oder unverfügbarkeit nicht laden.
commit d75f7c430b5ea0f893aa27d79808b258ae2e15a9
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Fri Mar 4 17:13:02 2011 -0500
More Disambiguation (D12N) work
- Get ancestry asignment working for newly inventoried resources
- Get ancestry update working when an resource name changes
- Get hover tooltips to show some expanded info
- Add D12N (with hover) to resource selector
- Some side work for selector layout
-- use more avail real estate
-- add cancel button for members selection
-- move buttons to bottom for members selection
- Add D12N to resource children view
-- Also fixed an issue, type is now displayed as typeName, not typeId
- Added AncestryUtil as a place to share useful code for dealing with ancestry decoding
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/Resource.java b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/Resource.java
index a1c3785..9da2469 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/Resource.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/Resource.java
@@ -908,7 +908,7 @@ public class Resource implements Comparable<Resource>, Serializable {
@Summary(index = 1)
private String name;
- @Column(name = "ANCESTRY", nullable = false)
+ @Column(name = "ANCESTRY", nullable = true)
@Summary(index = 5)
private String ancestry;
@@ -1154,31 +1154,37 @@ public class Resource implements Comparable<Resource>, Serializable {
/**
* Using the current settings for resource field set the encoded ancestry string. This method
* is called automatically from {@link #setParentResource(Resource)} because the parent defines the ancestry.
- * If the parent is not an attached entity the update will be skipped, as a valid id and resource type are required.
- * It can also be called at any time the ancestry has changed, for example, if a resource name has been updated.
+ * The parent should be an attached entity to ensure access to all necessary information. If the parent is
+ * not a persisted entity, or if it lacks the required information, the update will be skipped.<br/><br.>
+ * It can also be called at any time the ancestry has changed, for example, if a resource name has
+ * been updated.
*
* @return the built ancestry string
*/
public String updateAncestryForResource() {
- if (this.parentResource == null || //
- this.parentResource.getId() <= 0 || //
- this.parentResource.getResourceType() == null) {
+ Resource parentResource = this.getParentResource();
+
+ if (parentResource == null || //
+ parentResource.getId() <= 0 || //
+ parentResource.getResourceType() == null) {
return null;
}
StringBuilder ancestry = new StringBuilder();
- ancestry.append(this.parentResource.resourceType.getId());
+ ancestry.append(parentResource.getResourceType().getId());
ancestry.append(ANCESTRY_ENTRY_DELIM);
- ancestry.append(this.parentResource.id);
+ ancestry.append(parentResource.getId());
ancestry.append(ANCESTRY_ENTRY_DELIM);
- ancestry.append(this.parentResource.name);
- if (Resource.ROOT != parentResource) {
+ ancestry.append(parentResource.getName());
+ String parentAncestry = parentResource.getAncestry();
+ if (null != parentAncestry) {
ancestry.append(ANCESTRY_DELIM);
- ancestry.append(parentResource.getAncestry());
+ ancestry.append(parentAncestry);
}
- return ancestry.toString();
+ this.setAncestry(ancestry.toString());
+ return this.getAncestry();
}
public String getResourceKey() {
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/selector/AbstractSelector.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/selector/AbstractSelector.java
index ba6dcf6..c3ae654 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/selector/AbstractSelector.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/components/selector/AbstractSelector.java
@@ -48,6 +48,7 @@ import com.smartgwt.client.widgets.events.KeyPressHandler;
import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.events.ItemChangedEvent;
import com.smartgwt.client.widgets.form.events.ItemChangedHandler;
+import com.smartgwt.client.widgets.grid.HoverCustomizer;
import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.grid.ListGridField;
import com.smartgwt.client.widgets.grid.ListGridRecord;
@@ -242,8 +243,8 @@ public abstract class AbstractSelector<T> extends LocatableVLayout {
private SectionStack buildAvailableItemsStack() {
SectionStack availableSectionStack = new LocatableSectionStack(extendLocatorId("Available"));
- availableSectionStack.setWidth(300);
- availableSectionStack.setHeight(250);
+ availableSectionStack.setWidth("*");
+ availableSectionStack.setHeight100();
SectionStackSection availableSection = new SectionStackSection(getAvailableItemsGridTitle());
availableSection.setCanCollapse(false);
@@ -272,6 +273,10 @@ public abstract class AbstractSelector<T> extends LocatableVLayout {
availableFields.add(iconField);
}
ListGridField nameField = new ListGridField(getNameField(), MSG.common_title_name());
+ if (supportsNameHoverCustomizer()) {
+ nameField.setShowHover(true);
+ nameField.setHoverCustomizer(getNameHoverCustomizer());
+ }
availableFields.add(nameField);
this.availableGrid.setFields(availableFields.toArray(new ListGridField[availableFields.size()]));
@@ -404,8 +409,8 @@ public abstract class AbstractSelector<T> extends LocatableVLayout {
private SectionStack buildAssignedItemsStack() {
SectionStack assignedSectionStack = new LocatableSectionStack(extendLocatorId("Assigned"));
- assignedSectionStack.setWidth(300);
- assignedSectionStack.setHeight(250);
+ assignedSectionStack.setWidth("*");
+ assignedSectionStack.setHeight100();
assignedSectionStack.setAlign(Alignment.LEFT);
SectionStackSection assignedSection = new SectionStackSection(getAssignedItemsGridTitle());
@@ -435,6 +440,11 @@ public abstract class AbstractSelector<T> extends LocatableVLayout {
assignedFields.add(iconField);
}
ListGridField nameField = new ListGridField(getNameField(), MSG.common_title_name());
+ if (supportsNameHoverCustomizer()) {
+ nameField.setShowHover(true);
+ nameField.setHoverCustomizer(getNameHoverCustomizer());
+ }
+
assignedFields.add(nameField);
this.assignedGrid.setFields(assignedFields.toArray(new ListGridField[assignedFields.size()]));
@@ -480,6 +490,14 @@ public abstract class AbstractSelector<T> extends LocatableVLayout {
return assignedSectionStack;
}
+ protected boolean supportsNameHoverCustomizer() {
+ return false;
+ }
+
+ protected HoverCustomizer getNameHoverCustomizer() {
+ return null;
+ }
+
private void notifyAssignedItemsChangedHandlers() {
for (AssignedItemsChangedHandler handler : this.assignedItemsChangedHandlers) {
handler.onSelectionChanged(new AssignedItemsChangedEvent(this.assignedGrid.getSelection()));
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/inventory/MembersView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/inventory/MembersView.java
index ed222b1..c483a25 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/inventory/MembersView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/inventory/MembersView.java
@@ -45,8 +45,8 @@ public class MembersView extends ResourceSearchView {
private boolean canModifyMembers;
public MembersView(String locatorId, int groupId, boolean canModifyMembers) {
- super(locatorId, new Criteria(ResourceDatasource.FILTER_GROUP_ID, String.valueOf(groupId)),
- MSG.view_inventory_resources_title_members());
+ super(locatorId, new Criteria(ResourceDatasource.FILTER_GROUP_ID, String.valueOf(groupId)), MSG
+ .view_inventory_resources_title_members());
this.canModifyMembers = canModifyMembers;
this.groupId = groupId;
}
@@ -56,8 +56,8 @@ public class MembersView extends ResourceSearchView {
super.configureTable();
addTableAction(extendLocatorId("Members"), MSG.view_groupInventoryMembers_button_updateMembership() + "...",
- new AbstractTableAction((this.canModifyMembers) ? TableActionEnablement.ALWAYS :
- TableActionEnablement.NEVER) {
+ new AbstractTableAction((this.canModifyMembers) ? TableActionEnablement.ALWAYS
+ : TableActionEnablement.NEVER) {
@Override
public void executeAction(ListGridRecord[] selection, Object actionValue) {
final LocatableWindow winModal = new LocatableWindow(extendLocatorId("MembersWindow"));
@@ -79,17 +79,24 @@ public class MembersView extends ResourceSearchView {
}
});
- ResourceGroupMembershipView membershipView = new ResourceGroupMembershipView(
- MembersView.this.extendLocatorId("View"), MembersView.this.groupId);
+ ResourceGroupMembershipView membershipView = new ResourceGroupMembershipView(MembersView.this
+ .extendLocatorId("View"), MembersView.this.groupId);
membershipView.setSaveButtonHandler(new ClickHandler() {
- @Override
+
public void onClick(ClickEvent event) {
winModal.markForDestroy();
CoreGUI.refresh();
}
});
+ membershipView.setCancelButtonHandler(new ClickHandler() {
+
+ public void onClick(ClickEvent event) {
+ winModal.destroy();
+ }
+ });
+
winModal.addItem(membershipView);
winModal.show();
}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/inventory/ResourceGroupMembershipView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/inventory/ResourceGroupMembershipView.java
index 55edef1..7017071 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/inventory/ResourceGroupMembershipView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/groups/detail/inventory/ResourceGroupMembershipView.java
@@ -45,6 +45,7 @@ public class ResourceGroupMembershipView extends LocatableVLayout {
private ResourceGroup resourceGroup;
private ResourceGroupResourceSelector selector;
private ClickHandler saveButtonHandler;
+ private ClickHandler cancelButtonHandler;
public ResourceGroupMembershipView(String locatorId, int resourceGroupId) {
super(locatorId);
@@ -63,6 +64,17 @@ public class ResourceGroupMembershipView extends LocatableVLayout {
this.saveButtonHandler = saveButtonHandler;
}
+ /**
+ * Allows an external component to hook into the cancel button. The given
+ * handler will be invoked when the cancel button is pressed. If <code>null</code>
+ * is given, then no external handler will be called.
+ *
+ * @param cancelButtonHandler
+ */
+ public void setCancelButtonHandler(ClickHandler cancelButtonHandler) {
+ this.cancelButtonHandler = cancelButtonHandler;
+ }
+
@Override
protected void onDraw() {
super.onDraw();
@@ -71,7 +83,8 @@ public class ResourceGroupMembershipView extends LocatableVLayout {
}
public void build() {
- ToolStrip toolStrip = new ToolStrip();
+
+ final ToolStrip toolStrip = new ToolStrip();
toolStrip.setWidth100();
toolStrip.setExtraSpace(10);
toolStrip.setMembersMargin(5);
@@ -86,9 +99,18 @@ public class ResourceGroupMembershipView extends LocatableVLayout {
}
}
});
-
toolStrip.addMember(saveButton);
- this.addMember(toolStrip);
+
+ IButton cancelButton = new LocatableIButton(this.extendLocatorId("Cancel"), MSG.common_button_cancel());
+ cancelButton.addClickHandler(new ClickHandler() {
+ public void onClick(ClickEvent clickEvent) {
+ if (ResourceGroupMembershipView.this.cancelButtonHandler != null) {
+ ResourceGroupMembershipView.this.cancelButtonHandler.onClick(clickEvent);
+ }
+ destroy();
+ }
+ });
+ toolStrip.addMember(cancelButton);
ResourceGroupCriteria c = new ResourceGroupCriteria();
c.addFilterId(this.resourceGroupId);
@@ -111,6 +133,9 @@ public class ResourceGroupMembershipView extends LocatableVLayout {
: null, false);
addMember(ResourceGroupMembershipView.this.selector);
+
+ addMember(toolStrip);
+
markForRedraw();
}
});
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/AncestryUtil.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/AncestryUtil.java
new file mode 100644
index 0000000..71e1a79
--- /dev/null
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/AncestryUtil.java
@@ -0,0 +1,104 @@
+/*
+ * RHQ Management Platform
+ * Copyright (C) 2005-2011 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.resource;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+
+import org.rhq.core.domain.resource.Resource;
+import org.rhq.core.domain.resource.ResourceType;
+import org.rhq.enterprise.gui.coregui.client.LinkManager;
+import org.rhq.enterprise.gui.coregui.client.util.selenium.SeleniumUtility;
+
+/**
+ * A utility class for working with Resource ancestry values.
+ *
+ * @author Jay Shaughnessy
+ */
+public abstract class AncestryUtil {
+
+ /**
+ * Get the complete set of resource types in the ancestry of the provided resources. This is useful for
+ * being able to load all the types in advance of generating decoded values.
+ *
+ * @return
+ */
+ public static HashSet<Integer> getResourceTypeIds(Collection<Resource> resources) {
+ HashSet<Integer> result = new HashSet<Integer>();
+
+ for (Resource resource : resources) {
+ String ancestry = resource.getAncestry();
+ String[] ancestryEntries = ancestry.split(Resource.ANCESTRY_DELIM);
+ for (int i = 0; i < ancestryEntries.length; ++i) {
+ String[] entryTokens = ancestryEntries[i].split(Resource.ANCESTRY_ENTRY_DELIM);
+ int rtId = Integer.valueOf(entryTokens[0]);
+ result.add(rtId);
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Decode the provided ancestry into display values.
+ *
+ * @param resourceId Used for unique locators in the LocatableHref links.
+ * @param ancestry The encoded ancestry for the resource
+ * @param types if provided, must contain all of the resource types found in the ancestry.
+ * @return Array of length 2. result[0] is the resource ancestry, complete with locatable Hrefs. result[1] is
+ * the type ancestry, or null if types were not provided.
+ */
+ public static String[] decodeAncestry(int resourceId, String ancestry, Map<Integer, ResourceType> types) {
+ String[] result = new String[2];
+
+ if (null == ancestry) {
+ return result;
+ }
+
+ StringBuilder sbResources = new StringBuilder();
+ StringBuilder sbTypes = (null != types) ? new StringBuilder() : null;
+ String[] ancestryEntries = ancestry.split(Resource.ANCESTRY_DELIM);
+ for (int i = 0; i < ancestryEntries.length; ++i) {
+ String[] entryTokens = ancestryEntries[i].split(Resource.ANCESTRY_ENTRY_DELIM);
+ int ancestorTypeId = Integer.valueOf(entryTokens[0]);
+ int ancestorResourceId = Integer.valueOf(entryTokens[1]);
+ String ancestorName = entryTokens[2];
+
+ sbResources.append((i > 0) ? " > " : "");
+ String url = LinkManager.getResourceLink(ancestorResourceId);
+ String suffix = resourceId + "_" + entryTokens[1];
+ sbResources.append(SeleniumUtility.getLocatableHref(url, ancestorName, suffix));
+
+ if (null != sbTypes) {
+ sbTypes.append((i > 0) ? " > " : "");
+ ResourceType rt = types.get(ancestorTypeId);
+ sbTypes.append(rt.getName() + "[" + rt.getPlugin() + "]");
+ }
+ }
+
+ result[0] = sbResources.toString();
+ if (null != sbTypes) {
+ result[1] = sbTypes.toString();
+ }
+
+ return result;
+ }
+
+}
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceCompositeDataSource.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceCompositeDataSource.java
index 6cb947d..8a5e48a 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceCompositeDataSource.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceCompositeDataSource.java
@@ -1,5 +1,6 @@
package org.rhq.enterprise.gui.coregui.client.inventory.resource;
+import static org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceDataSourceField.ANCESTRY;
import static org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceDataSourceField.AVAILABILITY;
import static org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceDataSourceField.CATEGORY;
import static org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceDataSourceField.DESCRIPTION;
@@ -7,16 +8,16 @@ import static org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceD
import static org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceDataSourceField.PLUGIN;
import static org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceDataSourceField.TYPE;
+import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
+import java.util.Map;
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.Record;
-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;
@@ -24,12 +25,15 @@ import org.rhq.core.domain.criteria.ResourceCriteria;
import org.rhq.core.domain.measurement.AvailabilityType;
import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceCategory;
+import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.resource.composite.ResourceComposite;
import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.gui.coregui.client.CoreGUI;
import org.rhq.enterprise.gui.coregui.client.ImageManager;
import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
import org.rhq.enterprise.gui.coregui.client.gwt.ResourceGWTServiceAsync;
+import org.rhq.enterprise.gui.coregui.client.inventory.resource.type.ResourceTypeRepository;
+import org.rhq.enterprise.gui.coregui.client.inventory.resource.type.ResourceTypeRepository.TypesLoadedCallback;
import org.rhq.enterprise.gui.coregui.client.util.RPCDataSource;
/**
@@ -62,38 +66,7 @@ public class ResourceCompositeDataSource extends RPCDataSource<ResourceComposite
protected List<DataSourceField> addDataSourceFields() {
List<DataSourceField> fields = super.addDataSourceFields();
- DataSourceField idDataField = new DataSourceIntegerField("id", MSG.common_title_id(), 50);
- idDataField.setPrimaryKey(true);
- idDataField.setCanEdit(false);
- fields.add(idDataField);
-
- DataSourceImageField iconField = new DataSourceImageField("icon", "");
- fields.add(iconField);
-
- DataSourceTextField nameDataField = new DataSourceTextField(NAME.propertyName(), NAME.title(), 200);
- nameDataField.setCanEdit(false);
- fields.add(nameDataField);
-
- DataSourceTextField descriptionDataField = new DataSourceTextField(DESCRIPTION.propertyName(), DESCRIPTION
- .title());
- descriptionDataField.setCanEdit(false);
- fields.add(descriptionDataField);
-
- DataSourceTextField typeNameDataField = new DataSourceTextField(TYPE.propertyName(), TYPE.title());
- fields.add(typeNameDataField);
-
- DataSourceTextField pluginNameDataField = new DataSourceTextField(PLUGIN.propertyName(), PLUGIN.title());
- fields.add(pluginNameDataField);
-
- DataSourceTextField categoryDataField = new DataSourceTextField(CATEGORY.propertyName(), CATEGORY.title());
- fields.add(categoryDataField);
-
- DataSourceImageField availabilityDataField = new DataSourceImageField(AVAILABILITY.propertyName(), AVAILABILITY
- .title(), 20);
- availabilityDataField.setCanEdit(false);
- fields.add(availabilityDataField);
-
- return fields;
+ return ResourceDatasource.addResourceDatasourceFields(fields);
}
public void executeFetch(final DSRequest request, final DSResponse response) {
@@ -113,11 +86,55 @@ public class ResourceCompositeDataSource extends RPCDataSource<ResourceComposite
});
}
- protected void dataRetrieved(PageList<ResourceComposite> result, DSResponse response, DSRequest request) {
- Record[] records = this.buildRecords(result);
- response.setData(records);
- response.setTotalRows(result.getTotalSize()); // for paging to work we have to specify size of full result set
- processResponse(request.getRequestId(), response);
+ protected void dataRetrieved(final PageList<ResourceComposite> result, final DSResponse response,
+ final DSRequest request) {
+ HashSet<Integer> typesSet = new HashSet<Integer>();
+ ArrayList<Resource> resources = new ArrayList<Resource>(result.size());
+ for (ResourceComposite resourceComposite : result) {
+ Resource resource = resourceComposite.getResource();
+ resources.add(resource);
+ ResourceType type = resource.getResourceType();
+ if (type != null) {
+ typesSet.add(type.getId());
+ }
+ }
+
+ // In addition to the types of the result resources, get the types of their ancestry
+ // NOTE: this may be too labor intensive in general, but since this is a singleton I coudln't
+ // make it easily optional.
+ typesSet.addAll(AncestryUtil.getResourceTypeIds(resources));
+
+ ResourceTypeRepository typeRepo = ResourceTypeRepository.Cache.getInstance();
+ typeRepo.getResourceTypes(typesSet.toArray(new Integer[typesSet.size()]), new TypesLoadedCallback() {
+ @Override
+ public void onTypesLoaded(Map<Integer, ResourceType> types) {
+
+ Record[] records = buildRecords(result);
+ for (Record record : records) {
+ // replace type id with type name
+ Integer typeId = record.getAttributeAsInt(TYPE.propertyName());
+ ResourceType type = types.get(typeId);
+ if (type != null) {
+ record.setAttribute(TYPE.propertyName(), type.getName());
+ }
+
+ // decode ancestry
+ String ancestry = record.getAttributeAsString(ANCESTRY.propertyName());
+ if (null == ancestry) {
+ continue;
+ }
+ int resourceId = record.getAttributeAsInt("id");
+ String[] decodedAncestry = AncestryUtil.decodeAncestry(resourceId, ancestry, types);
+ // Preserve the encoded ancestry for special-case formatting at higher levels. Set the
+ // decoded strings as different attributes.
+ record.setAttribute(ResourceDatasource.ATTR_ANCESTRY_RESOURCES, decodedAncestry[0]);
+ record.setAttribute(ResourceDatasource.ATTR_ANCESTRY_TYPES, decodedAncestry[1]);
+ }
+ response.setData(records);
+ response.setTotalRows(result.getTotalSize()); // for paging to work we have to specify size of full result set
+ processResponse(request.getRequestId(), response);
+ }
+ });
}
protected ResourceCriteria getFetchCriteria(final DSRequest request) {
@@ -154,6 +171,7 @@ public class ResourceCompositeDataSource extends RPCDataSource<ResourceComposite
record.setAttribute("resource", res);
record.setAttribute("id", res.getId());
record.setAttribute(NAME.propertyName(), res.getName());
+ record.setAttribute(ANCESTRY.propertyName(), res.getAncestry());
record.setAttribute(DESCRIPTION.propertyName(), res.getDescription());
record.setAttribute(TYPE.propertyName(), res.getResourceType().getId());
record.setAttribute(PLUGIN.propertyName(), res.getResourceType().getPlugin());
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 a1032fd..a1d8505 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
@@ -49,13 +49,11 @@ import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.gui.coregui.client.CoreGUI;
import org.rhq.enterprise.gui.coregui.client.ImageManager;
-import org.rhq.enterprise.gui.coregui.client.LinkManager;
import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
import org.rhq.enterprise.gui.coregui.client.gwt.ResourceGWTServiceAsync;
import org.rhq.enterprise.gui.coregui.client.inventory.resource.type.ResourceTypeRepository;
import org.rhq.enterprise.gui.coregui.client.inventory.resource.type.ResourceTypeRepository.TypesLoadedCallback;
import org.rhq.enterprise.gui.coregui.client.util.RPCDataSource;
-import org.rhq.enterprise.gui.coregui.client.util.selenium.SeleniumUtility;
/**
* @author Greg Hinkle
@@ -64,10 +62,14 @@ public class ResourceDatasource extends RPCDataSource<Resource> {
public static final String FILTER_GROUP_ID = "groupId";
- private ResourceGWTServiceAsync resourceService = GWTServiceLookup.getResourceService();
+ // a decoded resource ancestry for display, with
+ public static final String ATTR_ANCESTRY_RESOURCES = ANCESTRY.name() + "Resources";
+ public static final String ATTR_ANCESTRY_TYPES = ANCESTRY.name() + "Types";
private static ResourceDatasource INSTANCE;
+ private ResourceGWTServiceAsync resourceService = GWTServiceLookup.getResourceService();
+
public static ResourceDatasource getInstance() {
if (INSTANCE == null) {
INSTANCE = new ResourceDatasource();
@@ -85,6 +87,10 @@ public class ResourceDatasource extends RPCDataSource<Resource> {
protected List<DataSourceField> addDataSourceFields() {
List<DataSourceField> fields = super.addDataSourceFields();
+ return addResourceDatasourceFields(fields);
+ }
+
+ public static List<DataSourceField> addResourceDatasourceFields(List<DataSourceField> fields) {
DataSourceField idDataField = new DataSourceIntegerField("id", MSG.common_title_id(), 50);
idDataField.setPrimaryKey(true);
idDataField.setCanEdit(false);
@@ -98,9 +104,9 @@ public class ResourceDatasource extends RPCDataSource<Resource> {
nameDataField.setCanEdit(false);
fields.add(nameDataField);
- DataSourceTextField lineageDataField = new DataSourceTextField(ANCESTRY.propertyName(), ANCESTRY.title(), 200);
- lineageDataField.setCanEdit(false);
- fields.add(lineageDataField);
+ DataSourceTextField ancestryDataField = new DataSourceTextField(ANCESTRY.propertyName(), ANCESTRY.title(), 200);
+ ancestryDataField.setCanEdit(false);
+ fields.add(ancestryDataField);
DataSourceTextField descriptionDataField = new DataSourceTextField(DESCRIPTION.propertyName(), DESCRIPTION
.title());
@@ -150,38 +156,36 @@ public class ResourceDatasource extends RPCDataSource<Resource> {
}
}
+ // In addition to the types of the result resources, get the types of their ancestry
+ // NOTE: this may be too labor intensive in general, but since this is a singleton I coudln't
+ // make it easily optional.
+ typesSet.addAll(AncestryUtil.getResourceTypeIds(result));
+
ResourceTypeRepository typeRepo = ResourceTypeRepository.Cache.getInstance();
typeRepo.getResourceTypes(typesSet.toArray(new Integer[typesSet.size()]), new TypesLoadedCallback() {
@Override
public void onTypesLoaded(Map<Integer, ResourceType> types) {
- // now that we have the types, we can replace encoded lineage strings with display strings
- //processLineage(result, types);
Record[] records = buildRecords(result);
for (Record record : records) {
+ // replace type id with type name
Integer typeId = record.getAttributeAsInt(TYPE.propertyName());
ResourceType type = types.get(typeId);
if (type != null) {
record.setAttribute(TYPE.propertyName(), type.getName());
}
+ // decode ancestry
String ancestry = record.getAttributeAsString(ANCESTRY.propertyName());
if (null == ancestry) {
continue;
}
- StringBuilder sb = new StringBuilder();
- String[] ancestryEntries = ancestry.split(Resource.ANCESTRY_DELIM);
- for (int i = 0; i < ancestryEntries.length; ++i) {
- sb.append((i > 0) ? " > " : "");
- String[] entryTokens = ancestryEntries[i].split(Resource.ANCESTRY_ENTRY_DELIM);
- //int typeId = Integer.valueOf(resourceTokens[0]);
- int resourceId = Integer.valueOf(entryTokens[1]);
- String url = LinkManager.getResourceLink(resourceId);
- String suffix = record.getAttributeAsInt("id") + "_" + entryTokens[1];
- sb.append(SeleniumUtility.getLocatableHref(url, entryTokens[2], suffix));
- }
- record.setAttribute(ANCESTRY.propertyName(), sb.toString());
-
+ int resourceId = record.getAttributeAsInt("id");
+ String[] decodedAncestry = AncestryUtil.decodeAncestry(resourceId, ancestry, types);
+ // Preserve the encoded ancestry for special-case formatting at higher levels. Set the
+ // decoded strings as different attributes.
+ record.setAttribute(ATTR_ANCESTRY_RESOURCES, decodedAncestry[0]);
+ record.setAttribute(ATTR_ANCESTRY_TYPES, decodedAncestry[1]);
}
response.setData(records);
response.setTotalRows(result.getTotalSize()); // for paging to work we have to specify size of full result set
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 d8f3a85..0a380d5 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
@@ -18,10 +18,10 @@
*/
package org.rhq.enterprise.gui.coregui.client.inventory.resource;
+import static org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceDataSourceField.ANCESTRY;
import static org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceDataSourceField.AVAILABILITY;
import static org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceDataSourceField.CATEGORY;
import static org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceDataSourceField.DESCRIPTION;
-import static org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceDataSourceField.ANCESTRY;
import static org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceDataSourceField.NAME;
import static org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceDataSourceField.PLUGIN;
import static org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceDataSourceField.TYPE;
@@ -153,6 +153,19 @@ public class ResourceSearchView extends Table {
});
ListGridField ancestryField = new ListGridField(ANCESTRY.propertyName(), ANCESTRY.title());
+ ancestryField.setCellFormatter(new CellFormatter() {
+ public String format(Object o, ListGridRecord listGridRecord, int rowNum, int colNum) {
+ return listGridRecord.getAttributeAsString(ResourceDatasource.ATTR_ANCESTRY_RESOURCES);
+ }
+ });
+ ancestryField.setShowHover(true);
+ ancestryField.setHoverCustomizer(new HoverCustomizer() {
+ public String hoverHTML(Object value, ListGridRecord listGridRecord, int rowNum, int colNum) {
+ return "<p style='width:400px'>"
+ + listGridRecord.getAttributeAsString(ResourceDatasource.ATTR_ANCESTRY_RESOURCES) + "</br>"
+ + listGridRecord.getAttributeAsString(ResourceDatasource.ATTR_ANCESTRY_TYPES) + "</p>";
+ }
+ });
ListGridField descriptionField = new ListGridField(DESCRIPTION.propertyName(), DESCRIPTION.title());
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/selection/ResourceSelector.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/selection/ResourceSelector.java
index 1f2701b..94749e2 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/selection/ResourceSelector.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/selection/ResourceSelector.java
@@ -31,6 +31,8 @@ import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.fields.IPickTreeItem;
import com.smartgwt.client.widgets.form.fields.SelectItem;
import com.smartgwt.client.widgets.form.fields.TextItem;
+import com.smartgwt.client.widgets.grid.HoverCustomizer;
+import com.smartgwt.client.widgets.grid.ListGridRecord;
import org.rhq.core.domain.criteria.ResourceCriteria;
import org.rhq.core.domain.resource.Resource;
@@ -140,11 +142,6 @@ public class ResourceSelector extends AbstractSelector<Resource> {
return criteria;
}
- @Override
- protected String getItemTitle() {
- return "resource";
- }
-
// protected Criteria getLatestCriteria(DynamicForm availableFilterForm) {
// String search = (String) availableFilterForm.getValue("search");
// String type = availableFilterForm.getValueAsString("type");
@@ -171,6 +168,27 @@ public class ResourceSelector extends AbstractSelector<Resource> {
// return latestCriteria;
//}
+ @Override
+ protected String getItemTitle() {
+ return "resource";
+ }
+
+ @Override
+ protected HoverCustomizer getNameHoverCustomizer() {
+ return new HoverCustomizer() {
+ public String hoverHTML(Object value, ListGridRecord listGridRecord, int rowNum, int colNum) {
+ return "<p style='width:400px'>"
+ + listGridRecord.getAttributeAsString(ResourceDatasource.ATTR_ANCESTRY_RESOURCES) + "</br>"
+ + listGridRecord.getAttributeAsString(ResourceDatasource.ATTR_ANCESTRY_TYPES) + "</p>";
+ }
+ };
+ }
+
+ @Override
+ protected boolean supportsNameHoverCustomizer() {
+ return true;
+ }
+
private class SelectedResourceDataSource extends ResourceDatasource {
@Override
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 43a6d3f..8c0e7d6 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
@@ -228,7 +228,7 @@ public class ResourceManagerBean implements ResourceManagerLocal, ResourceManage
// On name change make sure we update the ancestry as the name is part of the ancestry string
if (!persistedResource.getName().equals(resource.getName())) {
persistedResource.setName(resource.getName());
- updateAncestry(persistedResource, persistedResource.getChildResources());
+ updateAncestry(persistedResource);
}
persistedResource.setLocation(resource.getLocation());
persistedResource.setDescription(resource.getDescription());
@@ -2368,22 +2368,21 @@ public class ResourceManagerBean implements ResourceManagerLocal, ResourceManage
.getDuplicateTypeNames());
}
- public void updateAncestry(Subject subject, int parentResourceId) {
- Resource parentResource = entityManager.find(Resource.class, parentResourceId);
- if (null == parentResource) {
- throw new ResourceNotFoundException(parentResourceId);
+ public void updateAncestry(Subject subject, int resourceId) {
+ Resource resource = entityManager.find(Resource.class, resourceId);
+ if (null == resource) {
+ throw new ResourceNotFoundException(resourceId);
}
- Set<Resource> children = parentResource.getChildResources();
-
- updateAncestry(parentResource, children);
+ updateAncestry(resource);
}
- private void updateAncestry(Resource parentResource, Set<Resource> children) {
- parentResource.updateAncestryForResource();
+ private void updateAncestry(Resource resource) {
+ resource.updateAncestryForResource();
- for (Resource child : children) {
- updateAncestry(child, child.getChildResources());
+ for (Resource child : resource.getChildResources()) {
+ child.setParentResource(resource);
+ updateAncestry(child);
}
}
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 a017a49..4eba088 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
@@ -425,7 +425,7 @@ public interface ResourceManagerLocal {
ResourceAvailabilitySummary getAvailabilitySummary(Subject user, int resourceId);
/**
- * Update the ancestry for the specified parent resource and its child lineage.
+ * Update the ancestry for the specified resource and its child lineage.
* <pre>
* The ancestry is recursively defined as:
*
@@ -437,7 +437,7 @@ public interface ResourceManagerLocal {
* @param subject
* @param resourceId
*/
- public void updateAncestry(Subject subject, int parentResourceId);
+ public void updateAncestry(Subject subject, int resourceId);
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//
commit 0384316935c70becb8cfbfe8d2dc8019c04a0137
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Thu Mar 3 17:54:13 2011 -0500
Remove obsolete method.
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceFactoryManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceFactoryManagerBean.java
index cad1e08..c7732da 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceFactoryManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceFactoryManagerBean.java
@@ -21,7 +21,6 @@ package org.rhq.enterprise.server.resource;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
-import java.util.Calendar;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -118,35 +117,6 @@ public class ResourceFactoryManagerBean implements ResourceFactoryManagerLocal,
// ResourceFactoryManagerLocal Implementation --------------------------------------------
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
- public Resource createInventoryResource(int parentResourceId, int resourceTypeId, String resourceName,
- String resourceKey) {
- // Load persisted entities
- Resource parentResource = entityManager.find(Resource.class, parentResourceId);
- ResourceType resourceType = entityManager.find(ResourceType.class, resourceTypeId);
-
- Subject overLord = subjectManager.getOverlord();
- // Check to see if the resource exists but marked as deleted
- Resource resource = resourceManager.getResourceByParentAndKey(overLord, parentResource, resourceKey,
- resourceType.getPlugin(), resourceType.getName());
-
- if (resource == null) {
- // Create the resource
- resource = new Resource(resourceKey, resourceName, resourceType);
- resource.setParentResource(parentResource);
- resource.setAgent(parentResource.getAgent());
- resource.setInventoryStatus(InventoryStatus.COMMITTED);
-
- // Persist the resource
- entityManager.persist(resource);
- } else {
- resource.setInventoryStatus(InventoryStatus.COMMITTED);
- resource.setItime(Calendar.getInstance().getTimeInMillis());
- }
-
- return resource;
- }
-
- @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void completeCreateResource(CreateResourceResponse response) {
log.debug("Received call to complete create resource: " + response);
@@ -230,6 +200,7 @@ public class ResourceFactoryManagerBean implements ResourceFactoryManagerLocal,
}
}
+ @SuppressWarnings("unchecked")
public void checkForTimedOutRequests() {
try {
Query query;
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceFactoryManagerLocal.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceFactoryManagerLocal.java
index 3f9a2c4..261aff5 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceFactoryManagerLocal.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceFactoryManagerLocal.java
@@ -32,7 +32,6 @@ import org.rhq.core.domain.content.PackageVersion;
import org.rhq.core.domain.resource.CreateDeletePolicy;
import org.rhq.core.domain.resource.CreateResourceHistory;
import org.rhq.core.domain.resource.DeleteResourceHistory;
-import org.rhq.core.domain.resource.Resource;
import org.rhq.core.domain.resource.ResourceCreationDataType;
import org.rhq.core.domain.util.PageControl;
import org.rhq.core.domain.util.PageList;
@@ -158,19 +157,6 @@ public interface ResourceFactoryManagerLocal {
PageControl pageControl);
/**
- * Creates a new resource in the inventory.
- * This should NOT be made accessible to remote clients, do not call this unless you know what you are doing
- *
- * @param parentResourceId parent of the new resource
- * @param resourceTypeId type of resource being created
- * @param resourceName name of the new resource
- * @param resourceKey resource key of the new resource
- *
- * @return resource object after it's been persisted
- */
- Resource createInventoryResource(int parentResourceId, int resourceTypeId, String resourceName, String resourceKey);
-
- /**
* Persists a record in the resource history to indicate a request has been made to create a configuration-backed
* resource.
*
commit 362fea200d557185f3ec609bb042286d69097353
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Thu Mar 3 17:53:54 2011 -0500
First pass at precomputed ancestry as opposed to on-demand disambiguation.
See http://www.rhq-project.org/display/RHQ/Disambiguation+API for more on
the design.
diff --git a/modules/core/dbutils/pom.xml b/modules/core/dbutils/pom.xml
index e2b59a9..270adec 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.105</db.schema.version>
+ <db.schema.version>2.106</db.schema.version>
</properties>
<dependencies>
diff --git a/modules/core/dbutils/src/main/java/org/rhq/core/db/upgrade/ResourceAncestryUpgradeTask.java b/modules/core/dbutils/src/main/java/org/rhq/core/db/upgrade/ResourceAncestryUpgradeTask.java
new file mode 100644
index 0000000..d07e09b
--- /dev/null
+++ b/modules/core/dbutils/src/main/java/org/rhq/core/db/upgrade/ResourceAncestryUpgradeTask.java
@@ -0,0 +1,95 @@
+/*
+ * 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.core.db.upgrade;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.List;
+
+import org.rhq.core.db.DatabaseType;
+
+/**
+ * The introduction of pre-computed disambiguated "ancestry" for Resources requires that existing
+ * inventory be updated with pre-computed values. Rhq_resource.ancestry must be set.
+ *
+ * This task queries for each platform, assigns its ancestry string, and then traverses the family tree assigning
+ * ancestry strings as it goes. InventoryStatus is not important as the resource hieracrhy is always well-formed.
+ *
+ * @author Jay Shaughnessy
+ */
+public class ResourceAncestryUpgradeTask implements DatabaseUpgradeTask {
+
+ public static final String ANCESTRY_ENTRY_DELIM = "_:_"; // delimiter separating entry fields
+ public static final String ANCESTRY_DELIM = "_::_"; // delimiter seperating ancestry entries
+
+ private DatabaseType databaseType;
+ private Connection connection;
+
+ public void execute(DatabaseType databaseType, Connection connection) throws SQLException {
+ this.databaseType = databaseType;
+ this.connection = connection;
+
+ String sql = "" //
+ + "select rt.ID, res.ID, res.NAME from RHQ_RESOURCE res, RHQ_RESOURCE_TYPE rt where " //
+ + " res.RESOURCE_TYPE_ID=rt.ID and rt.CATEGORY='PLATFORM'";
+ List<Object[]> rs = databaseType.executeSelectSql(connection, sql);
+ for (Object[] result : rs) {
+ int rtId = (Integer) result[0];
+ int resId = (Integer) result[1];
+ String resName = (String) result[2];
+
+ handleChildren(rtId, resId, resName, null);
+ }
+ }
+
+ private void handleChildren(int parentRtId, int parentResId, String parentResName, String parentAncestry)
+ throws SQLException {
+
+ String sql = "" //
+ + "select rt.ID, res.ID, res.NAME from RHQ_RESOURCE res, RHQ_RESOURCE_TYPE rt where " //
+ + " res.RESOURCE_TYPE_ID=rt.ID and res.PARENT_RESOURCE_ID=" + parentResId;
+ List<Object[]> rs = databaseType.executeSelectSql(connection, sql);
+ for (Object[] result : rs) {
+ int rtId = (Integer) result[0];
+ int resId = (Integer) result[1];
+ String resName = (String) result[2];
+ String ancestry = getAncestry(parentRtId, parentResId, parentResName, parentAncestry);
+ String updateSql = "update RHQ_RESOURCE set ANCESTRY='" + ancestry + "' where ID=" + resId;
+ databaseType.executeSql(connection, updateSql);
+
+ handleChildren(rtId, resId, resName, ancestry);
+ }
+ }
+
+ private String getAncestry(int rtId, int resId, String resName, String parentAncestry) {
+
+ StringBuilder ancestry = new StringBuilder();
+ ancestry.append(rtId);
+ ancestry.append(ANCESTRY_ENTRY_DELIM);
+ ancestry.append(resId);
+ ancestry.append(ANCESTRY_ENTRY_DELIM);
+ ancestry.append(resName);
+ if (null != parentAncestry) {
+ ancestry.append(ANCESTRY_DELIM);
+ ancestry.append(parentAncestry);
+ }
+ return ancestry.toString();
+ }
+
+}
diff --git a/modules/core/dbutils/src/main/scripts/dbsetup/inventory-schema.xml b/modules/core/dbutils/src/main/scripts/dbsetup/inventory-schema.xml
index a181d83..7b85143 100644
--- a/modules/core/dbutils/src/main/scripts/dbsetup/inventory-schema.xml
+++ b/modules/core/dbutils/src/main/scripts/dbsetup/inventory-schema.xml
@@ -85,6 +85,8 @@
<column name="RESOURCE_TYPE_ID" type="INTEGER" required="true" references="RHQ_RESOURCE_TYPE"/>
<column name="UUID" type="CHAR" size="36" required="true"/>
<column name="NAME" type="VARCHAR2" size="500"/>
+ <!-- ancestry holds the full parental ancestry, used for disambiguation -->
+ <column name="ANCESTRY" type="VARCHAR2" required="false" size="4000"/>
<column name="RESOURCE_KEY" type="VARCHAR2" required="true" size="500"/>
<column name="AGENT_ID" required="false" type="INTEGER" references="RHQ_AGENT(id)"/>
<column name="INVENTORY_STATUS" type="VARCHAR2" size="20"/>
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 f0d6cc5..57f82f0 100644
--- a/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
+++ b/modules/core/dbutils/src/main/scripts/dbupgrade/db-upgrade.xml
@@ -3377,6 +3377,13 @@
</statement>
</schema-directSQL>
</schemaSpec>
+
+ <schemaSpec version="2.106">
+ <!-- add pre-computed disambiguated name for Resource -->
+ <schema-addColumn table="RHQ_RESOURCE" column="ANCESTRY" columnType="VARCHAR2" precision="4000" />
+ <schema-javaTask className="ResourceAncestryUpgradeTask" />
+ </schemaSpec>
+
</dbupgrade>
</target>
</project>
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/Resource.java b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/Resource.java
index fff65b2..a1c3785 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/Resource.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/Resource.java
@@ -885,6 +885,9 @@ public class Resource implements Comparable<Resource>, Serializable {
private static final long serialVersionUID = 1L;
+ public static final String ANCESTRY_ENTRY_DELIM = "_:_"; // delimiter separating entry fields
+ public static final String ANCESTRY_DELIM = "_::_"; // delimiter seperating ancestry entries
+
public static final Resource ROOT = null;
public static final int ROOT_ID = -1;
@@ -905,6 +908,10 @@ public class Resource implements Comparable<Resource>, Serializable {
@Summary(index = 1)
private String name;
+ @Column(name = "ANCESTRY", nullable = false)
+ @Summary(index = 5)
+ private String ancestry;
+
@Column(name = "INVENTORY_STATUS")
@Enumerated(EnumType.STRING)
private InventoryStatus inventoryStatus = InventoryStatus.NEW;
@@ -1130,6 +1137,50 @@ public class Resource implements Comparable<Resource>, Serializable {
this.name = name;
}
+ public String getAncestry() {
+ return ancestry;
+ }
+
+ /**
+ * In general this method should not be called by application code. At least not for any Resource that will be
+ * persisted or merged. The ancestry string is maintained internally. {@link #updateAncestryForResource()}.
+ *
+ * @param ancestry
+ */
+ public void setAncestry(String ancestry) {
+ this.ancestry = ancestry;
+ }
+
+ /**
+ * Using the current settings for resource field set the encoded ancestry string. This method
+ * is called automatically from {@link #setParentResource(Resource)} because the parent defines the ancestry.
+ * If the parent is not an attached entity the update will be skipped, as a valid id and resource type are required.
+ * It can also be called at any time the ancestry has changed, for example, if a resource name has been updated.
+ *
+ * @return the built ancestry string
+ */
+ public String updateAncestryForResource() {
+
+ if (this.parentResource == null || //
+ this.parentResource.getId() <= 0 || //
+ this.parentResource.getResourceType() == null) {
+ return null;
+ }
+
+ StringBuilder ancestry = new StringBuilder();
+ ancestry.append(this.parentResource.resourceType.getId());
+ ancestry.append(ANCESTRY_ENTRY_DELIM);
+ ancestry.append(this.parentResource.id);
+ ancestry.append(ANCESTRY_ENTRY_DELIM);
+ ancestry.append(this.parentResource.name);
+ if (Resource.ROOT != parentResource) {
+ ancestry.append(ANCESTRY_DELIM);
+ ancestry.append(parentResource.getAncestry());
+ }
+
+ return ancestry.toString();
+ }
+
public String getResourceKey() {
return resourceKey;
}
@@ -1297,6 +1348,7 @@ public class Resource implements Comparable<Resource>, Serializable {
public void setParentResource(@Nullable Resource parentResource) {
this.parentResource = parentResource;
+ updateAncestryForResource();
}
public Configuration getResourceConfiguration() {
@@ -1733,10 +1785,6 @@ public class Resource implements Comparable<Resource>, Serializable {
return buffer.toString();
}
- public void afterUnmarshal(Object u, Object parent) {
- this.parentResource = (Resource) parent;
- }
-
// this should only ever be called once, during initial persistence
public void initCurrentAvailability() {
this.currentAvailability = new ResourceAvailability(this, null);
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceDataSourceField.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceDataSourceField.java
index b689133..cf11666 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceDataSourceField.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/inventory/resource/ResourceDataSourceField.java
@@ -39,7 +39,9 @@ public enum ResourceDataSourceField {
CATEGORY("resourceType.category", CoreGUI.getMessages().common_title_category()),
- AVAILABILITY("currentAvailability", CoreGUI.getMessages().common_title_availability());
+ AVAILABILITY("currentAvailability", CoreGUI.getMessages().common_title_availability()),
+
+ ANCESTRY("ancestry", CoreGUI.getMessages().common_title_ancestry());
/**
* Corresponds to a property name of Resource (e.g. resourceType.name).
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 bf3fdba..a1032fd 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
@@ -18,6 +18,7 @@
*/
package org.rhq.enterprise.gui.coregui.client.inventory.resource;
+import static org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceDataSourceField.ANCESTRY;
import static org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceDataSourceField.AVAILABILITY;
import static org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceDataSourceField.CATEGORY;
import static org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceDataSourceField.DESCRIPTION;
@@ -48,11 +49,13 @@ import org.rhq.core.domain.resource.ResourceType;
import org.rhq.core.domain.util.PageList;
import org.rhq.enterprise.gui.coregui.client.CoreGUI;
import org.rhq.enterprise.gui.coregui.client.ImageManager;
+import org.rhq.enterprise.gui.coregui.client.LinkManager;
import org.rhq.enterprise.gui.coregui.client.gwt.GWTServiceLookup;
import org.rhq.enterprise.gui.coregui.client.gwt.ResourceGWTServiceAsync;
import org.rhq.enterprise.gui.coregui.client.inventory.resource.type.ResourceTypeRepository;
import org.rhq.enterprise.gui.coregui.client.inventory.resource.type.ResourceTypeRepository.TypesLoadedCallback;
import org.rhq.enterprise.gui.coregui.client.util.RPCDataSource;
+import org.rhq.enterprise.gui.coregui.client.util.selenium.SeleniumUtility;
/**
* @author Greg Hinkle
@@ -95,6 +98,10 @@ public class ResourceDatasource extends RPCDataSource<Resource> {
nameDataField.setCanEdit(false);
fields.add(nameDataField);
+ DataSourceTextField lineageDataField = new DataSourceTextField(ANCESTRY.propertyName(), ANCESTRY.title(), 200);
+ lineageDataField.setCanEdit(false);
+ fields.add(lineageDataField);
+
DataSourceTextField descriptionDataField = new DataSourceTextField(DESCRIPTION.propertyName(), DESCRIPTION
.title());
descriptionDataField.setCanEdit(false);
@@ -147,6 +154,9 @@ public class ResourceDatasource extends RPCDataSource<Resource> {
typeRepo.getResourceTypes(typesSet.toArray(new Integer[typesSet.size()]), new TypesLoadedCallback() {
@Override
public void onTypesLoaded(Map<Integer, ResourceType> types) {
+ // now that we have the types, we can replace encoded lineage strings with display strings
+ //processLineage(result, types);
+
Record[] records = buildRecords(result);
for (Record record : records) {
Integer typeId = record.getAttributeAsInt(TYPE.propertyName());
@@ -154,6 +164,24 @@ public class ResourceDatasource extends RPCDataSource<Resource> {
if (type != null) {
record.setAttribute(TYPE.propertyName(), type.getName());
}
+
+ String ancestry = record.getAttributeAsString(ANCESTRY.propertyName());
+ if (null == ancestry) {
+ continue;
+ }
+ StringBuilder sb = new StringBuilder();
+ String[] ancestryEntries = ancestry.split(Resource.ANCESTRY_DELIM);
+ for (int i = 0; i < ancestryEntries.length; ++i) {
+ sb.append((i > 0) ? " > " : "");
+ String[] entryTokens = ancestryEntries[i].split(Resource.ANCESTRY_ENTRY_DELIM);
+ //int typeId = Integer.valueOf(resourceTokens[0]);
+ int resourceId = Integer.valueOf(entryTokens[1]);
+ String url = LinkManager.getResourceLink(resourceId);
+ String suffix = record.getAttributeAsInt("id") + "_" + entryTokens[1];
+ sb.append(SeleniumUtility.getLocatableHref(url, entryTokens[2], suffix));
+ }
+ record.setAttribute(ANCESTRY.propertyName(), sb.toString());
+
}
response.setData(records);
response.setTotalRows(result.getTotalSize()); // for paging to work we have to specify size of full result set
@@ -202,6 +230,7 @@ public class ResourceDatasource extends RPCDataSource<Resource> {
record.setAttribute("id", from.getId());
record.setAttribute("uuid", from.getUuid());
record.setAttribute(NAME.propertyName(), from.getName());
+ record.setAttribute(ANCESTRY.propertyName(), from.getAncestry());
record.setAttribute(DESCRIPTION.propertyName(), from.getDescription());
record.setAttribute(TYPE.propertyName(), from.getResourceType().getId());
record.setAttribute(PLUGIN.propertyName(), from.getResourceType().getPlugin());
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 93f02e1..d8f3a85 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
@@ -21,6 +21,7 @@ package org.rhq.enterprise.gui.coregui.client.inventory.resource;
import static org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceDataSourceField.AVAILABILITY;
import static org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceDataSourceField.CATEGORY;
import static org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceDataSourceField.DESCRIPTION;
+import static org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceDataSourceField.ANCESTRY;
import static org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceDataSourceField.NAME;
import static org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceDataSourceField.PLUGIN;
import static org.rhq.enterprise.gui.coregui.client.inventory.resource.ResourceDataSourceField.TYPE;
@@ -151,6 +152,8 @@ public class ResourceSearchView extends Table {
}
});
+ ListGridField ancestryField = new ListGridField(ANCESTRY.propertyName(), ANCESTRY.title());
+
ListGridField descriptionField = new ListGridField(DESCRIPTION.propertyName(), DESCRIPTION.title());
ListGridField typeNameField = new ListGridField(TYPE.propertyName(), TYPE.title(), 130);
@@ -183,8 +186,8 @@ public class ResourceSearchView extends Table {
availabilityField.setType(ListGridFieldType.IMAGE);
availabilityField.setAlign(Alignment.CENTER);
- setListGridFields(iconField, nameField, descriptionField, typeNameField, pluginNameField, categoryField,
- availabilityField);
+ setListGridFields(iconField, nameField, ancestryField, descriptionField, typeNameField, pluginNameField,
+ categoryField, availabilityField);
addTableAction(extendLocatorId("Uninventory"), MSG.common_button_uninventory(), MSG
.view_inventory_resources_uninventoryConfirm(), new AbstractTableAction(TableActionEnablement.ANY) {
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 bf501ec..218765c 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
@@ -67,25 +67,26 @@ public class ResourceGWTServiceImpl extends AbstractGWTServiceImpl implements Re
private ResourceFactoryManagerLocal resourceFactoryManager = LookupUtil.getResourceFactoryManager();
private DiscoveryBossLocal discoveryBoss = LookupUtil.getDiscoveryBoss();
- private static String[] importantFields = { "serialVersionUID",
- // "ROOT \n" +
+ private static String[] importantFields = { //
+ "serialVersionUID", //
+ // "ROOT \n" +
// "ROOT_ID \n" +
- "id",
-
+ "id", //
"uuid", // This is important, because it is what Resource's equals() and hashCode() impls use.
// "resourceKey \n" +
- "name",
-
+ "name", //
+ "ancestry", //
// "connected \n" +
// "version \n" +
- "description",
-
+ "description", //
// "ctime \n" +
// "mtime \n" +
// "itime \n" +
// "modifiedBy \n" +
// "location \n" +
- "resourceType", "childResources", "parentResource",
+ "resourceType", //
+ "childResources", //
+ "parentResource", //
// "resourceConfiguration \n" +
// "pluginConfiguration \n" +
// "agent \n" +
@@ -93,7 +94,7 @@ public class ResourceGWTServiceImpl extends AbstractGWTServiceImpl implements Re
// "resourceConfigurationUpdates \n" +
// "pluginConfigurationUpdates \n" +
// "implicitGroups \n" +
- "explicitGroups",
+ "explicitGroups", //
// "contentServiceRequests \n" +
// "createChildResourceRequests \n" +
// "deleteResourceRequests \n" +
@@ -101,9 +102,9 @@ public class ResourceGWTServiceImpl extends AbstractGWTServiceImpl implements Re
// "installedPackages \n" +
// "installedPackageHistory \n" +
// "resourceRepos \n" +
- "schedules",
+ "schedules", //
// "availability \n" +
- "currentAvailability",
+ "currentAvailability", //
// "resourceErrors \n" +
// "eventSources \n" +
// "productVersion "}
diff --git a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties
index 52bc84e..f7bfa4a 100644
--- a/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties
+++ b/modules/enterprise/gui/coregui/src/main/resources/org/rhq/enterprise/gui/coregui/client/Messages.properties
@@ -87,6 +87,7 @@ common_title_address = Address
common_title_add_column = Add Column
common_title_add_portlet = Add Portlet
common_title_alert_range = Alert Range
+common_title_ancestry = Ancestry
common_title_availability = Availability
common_title_average_metrics = Average Metrics per Minute
common_title_available_resources = Available Resources
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
index 3a39723..4eb3e9e 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
@@ -229,14 +229,13 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
long count = (Long) queryCount.getSingleResult();
List<Resource> results;
- if (count>0) {
+ if (count > 0) {
Query query = PersistenceUtility.createQueryWithOrderBy(entityManager,
Resource.QUERY_FIND_QUEUED_PLATFORMS_BY_INVENTORY_STATUS, pc);
query.setParameter("inventoryStatuses", statuses);
results = query.getResultList();
- }
- else
+ } else
results = Collections.emptyList();
return new PageList<Resource>(results, (int) count, pc);
@@ -610,7 +609,7 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
Resource existingResource = getExistingResource(resource);
if (existingResource != null) {
- updatePreviouslyInventoriedResource(resource, existingResource, parentResource);
+ updatePreviouslyInventoriedResource(resource, existingResource);
} else {
presetAgent(resource, agent);
addResourceToInventory(resource, parentResource);
@@ -720,8 +719,8 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
return existingResource;
}
- private void updatePreviouslyInventoriedResource(Resource resource, Resource existingResource,
- Resource parentResource) throws InvalidInventoryReportException {
+ private void updatePreviouslyInventoriedResource(Resource updatedResource, Resource existingResource)
+ throws InvalidInventoryReportException {
/*
* there exists a small window of time after the synchronous part of the uninventory and before the async
* quartz job comes along to perform the actual removal of the resource from the database, that an inventory
@@ -737,59 +736,67 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
return;
}
- assert (parentResource == null) || (parentResource.getId() != 0);
-
- ResourceType existingResourceParentType = (existingResource.getParentResource() != null) ? existingResource
- .getParentResource().getResourceType() : null;
- ResourceType resourceParentType = (resource.getParentResource() != null) ? resource.getParentResource()
+ Resource existingParent = existingResource.getParentResource();
+ Resource updatedParent = updatedResource.getParentResource();
+ ResourceType existingResourceParentType = (existingParent != null) ? existingResource.getParentResource()
+ .getResourceType() : null;
+ ResourceType updatedResourceParentType = (updatedParent != null) ? updatedResource.getParentResource()
.getResourceType() : null;
Set<ResourceType> validParentTypes = existingResource.getResourceType().getParentResourceTypes();
+
if (validParentTypes != null && !validParentTypes.isEmpty()
&& !validParentTypes.contains(existingResourceParentType)) {
+
// The existing Resource has an invalid parent ResourceType. This may be because its ResourceType was moved
// to a new parent ResourceType, but its new parent was not yet discovered at the time of the type move. See
// if the Resource reported by the Agent has a valid parent type, and, if so, update the existing Resource's
// parent to that type.
- if (validParentTypes.contains(resourceParentType)) {
+ if (validParentTypes.contains(updatedResourceParentType)) {
if (existingResource.getParentResource() != null) {
existingResource.getParentResource().removeChildResource(existingResource);
}
- if (resource.getParentResource() != null) {
- parentResource = getExistingResource(resource.getParentResource());
- parentResource.addChildResource(existingResource);
+ if (updatedParent != Resource.ROOT) {
+ updatedParent = getExistingResource(updatedParent);
+ updatedParent.addChildResource(existingResource);
+ } else {
+ existingResource.setParentResource(Resource.ROOT);
}
- existingResource.setParentResource(resource.getParentResource());
+ // now that the parent has been established, update the lineage. Note that this method will
+ // recurse on the children, so update only this resource and let the children be handled by
+ // the recursion.
+ // TODO: this can be removed, I think, as the ancestry should be handled under the covers.
+ //existingResource.setLineageForResource();
} else {
log.debug("Existing Resource " + existingResource + " has invalid parent type ("
- + existingResourceParentType + ") and so does plugin-reported Resource " + resource + " ("
- + resourceParentType + ") - valid parent types are [" + validParentTypes + "].");
+ + existingResourceParentType + ") and so does plugin-reported Resource " + updatedResource + " ("
+ + updatedResourceParentType + ") - valid parent types are [" + validParentTypes + "].");
}
}
// The below block is for Resources that were created via the RHQ GUI, whose descriptions will be null.
- if (existingResource.getDescription() == null && resource.getDescription() != null) {
+ if (existingResource.getDescription() == null && updatedResource.getDescription() != null) {
log.debug("Setting description of existing resource with id " + existingResource.getId() + " to '"
- + resource.getDescription() + "' (as reported by agent)...");
- existingResource.setDescription(resource.getDescription());
+ + updatedResource.getDescription() + "' (as reported by agent)...");
+ existingResource.setDescription(updatedResource.getDescription());
}
// Log a warning if the agent says the Resource key has changed (should rarely happen).
if ((existingResource.getResourceKey() != null)
- && !existingResource.getResourceKey().equals(resource.getResourceKey())) {
+ && !existingResource.getResourceKey().equals(updatedResource.getResourceKey())) {
log.warn("Agent reported that key for " + existingResource + " has changed from '"
- + existingResource.getResourceKey() + "' to '" + resource.getResourceKey() + "'.");
+ + existingResource.getResourceKey() + "' to '" + updatedResource.getResourceKey() + "'.");
}
- updateResourceVersion(existingResource, resource.getVersion());
+ updateResourceVersion(existingResource, updatedResource.getVersion());
// If the resource was marked as deleted, reactivate it again.
if (existingResource.getInventoryStatus() == InventoryStatus.DELETED) {
existingResource.setInventoryStatus(InventoryStatus.COMMITTED);
- existingResource.setPluginConfiguration(resource.getPluginConfiguration());
+ existingResource.setPluginConfiguration(updatedResource.getPluginConfiguration());
}
- for (Resource childResource : resource.getChildResources()) {
+ for (Resource childResource : updatedResource.getChildResources()) {
// It's important to specify the existing Resource, which is an attached entity bean, as the parent.
mergeResource(childResource, existingResource, existingResource.getAgent());
}
@@ -877,6 +884,8 @@ public class DiscoveryBossBean implements DiscoveryBossLocal, DiscoveryBossRemot
resource.setItime(System.currentTimeMillis());
resource.setModifiedBy(subjectManager.getOverlord().getName());
+ // This can be removed I think because the ancestry should be built under the covers
+ //resource.buildLineage();
for (Resource childResource : resource.getChildResources()) {
initAutoDiscoveredResource(childResource, 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 770a69c..43a6d3f 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
@@ -225,7 +225,11 @@ public class ResourceManagerBean implements ResourceManagerLocal, ResourceManage
* { throw new ResourceAlreadyExistsException("Resource with key '" + resource.getName() + "' already
* exists");}*/
- persistedResource.setName(resource.getName());
+ // On name change make sure we update the ancestry as the name is part of the ancestry string
+ if (!persistedResource.getName().equals(resource.getName())) {
+ persistedResource.setName(resource.getName());
+ updateAncestry(persistedResource, persistedResource.getChildResources());
+ }
persistedResource.setLocation(resource.getLocation());
persistedResource.setDescription(resource.getDescription());
@@ -2364,6 +2368,25 @@ public class ResourceManagerBean implements ResourceManagerLocal, ResourceManage
.getDuplicateTypeNames());
}
+ public void updateAncestry(Subject subject, int parentResourceId) {
+ Resource parentResource = entityManager.find(Resource.class, parentResourceId);
+ if (null == parentResource) {
+ throw new ResourceNotFoundException(parentResourceId);
+ }
+
+ Set<Resource> children = parentResource.getChildResources();
+
+ updateAncestry(parentResource, children);
+ }
+
+ private void updateAncestry(Resource parentResource, Set<Resource> children) {
+ parentResource.updateAncestryForResource();
+
+ for (Resource child : children) {
+ updateAncestry(child, child.getChildResources());
+ }
+ }
+
@SuppressWarnings("unchecked")
public List<Integer> findIdsByTypeIds(List<Integer> resourceTypeIds) {
return entityManager.createNamedQuery(Resource.QUERY_FIND_IDS_BY_TYPE_IDS).setParameter("resourceTypeIds",
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 88a82e0..a017a49 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
@@ -424,6 +424,21 @@ public interface ResourceManagerLocal {
ResourceAvailabilitySummary getAvailabilitySummary(Subject user, int resourceId);
+ /**
+ * Update the ancestry for the specified parent resource and its child lineage.
+ * <pre>
+ * The ancestry is recursively defined as:
+ *
+ * resourceAncestry=parentResourceResourceTypeId_:_parentResourceId_:_parentResourceName_::_parentResourceAncestry
+ *
+ * * note that platform resources have no parent and therefore have a null ancestry
+ *
+ * </pre>
+ * @param subject
+ * @param resourceId
+ */
+ public void updateAncestry(Subject subject, int parentResourceId);
+
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//
// The following are shared with the Remote Interface
diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBean.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBean.java
index 24467c1..14a5343 100644
--- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBean.java
+++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/metadata/ResourceMetadataManagerBean.java
@@ -138,8 +138,8 @@ public class ResourceMetadataManagerBean implements ResourceMetadataManagerLocal
long startTime = System.currentTimeMillis();
updateType(resourceType);
long endTime = System.currentTimeMillis();
- log.debug("Updated resource type [" + toConciseString(resourceType) + "] in " + (endTime - startTime) +
- " ms");
+ log.debug("Updated resource type [" + toConciseString(resourceType) + "] in " + (endTime - startTime)
+ + " ms");
legitimateChildren.addAll(resourceType.getChildResourceTypes());
}
@@ -294,7 +294,7 @@ public class ResourceMetadataManagerBean implements ResourceMetadataManagerLocal
}
entityManager.flush();
- existingType = entityManager.find(existingType.getClass(), existingType.getId());
+ existingType = entityManager.find(existingType.getClass(), existingType.getId());
// Remove all compatible groups that are of the type.
List<ResourceGroup> compatGroups = existingType.getResourceGroups();
@@ -391,8 +391,8 @@ public class ResourceMetadataManagerBean implements ResourceMetadataManagerLocal
long startTime = System.currentTimeMillis();
pluginConfigMetadataMgr.updatePluginConfigurationDefinition(existingType, resourceType);
long endTime = System.currentTimeMillis();
- log.debug("Updated plugin configuration definition for ResourceType[" + toConciseString(existingType) +
- "] in " + (endTime - startTime) + " ms");
+ log.debug("Updated plugin configuration definition for ResourceType[" + toConciseString(existingType) + "] in "
+ + (endTime - startTime) + " ms");
resourceConfigMetadataMgr.updateResourceConfigurationDefinition(existingType, resourceType);
@@ -564,6 +564,9 @@ public class ResourceMetadataManagerBean implements ResourceMetadataManagerLocal
resource.getParentResource().removeChildResource(resource);
}
newParent.addChildResource(resource);
+ // Assigning a new parent changes the ancestry for the resource and its children. Since the
+ // children are not handled in this method, update their ancestry now.
+ resourceManager.updateAncestry(subjectManager.getOverlord(), resource.getId());
} else {
log.debug("We were unable to move " + resource + " from invalid parent " + resource.getParentResource()
+ " to a new valid parent with one of the following types: " + newParentTypes);
@@ -598,7 +601,6 @@ public class ResourceMetadataManagerBean implements ResourceMetadataManagerLocal
return result;
}
-
/**
* Update the set of process scans for a given resource type
*
13 years, 2 months
[rhq] modules/core modules/enterprise
by lkrejci
modules/core/util/src/main/java/org/rhq/core/util/exception/ThrowableUtil.java | 93 +++++++++-
modules/core/util/src/test/java/org/rhq/core/util/exception/ThrowableUtilTest.java | 15 +
modules/enterprise/binding/src/main/java/org/rhq/bindings/SandboxedScriptEngine.java | 20 +-
modules/enterprise/binding/src/main/java/org/rhq/bindings/engine/JsEngineInitializer.java | 22 ++
modules/enterprise/binding/src/main/java/org/rhq/bindings/engine/ScriptEngineInitializer.java | 17 +
modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java | 49 ++++-
6 files changed, 198 insertions(+), 18 deletions(-)
New commits:
commit f55ddb760bb5877549fa0f61b0df9ca1fff3a1ae
Author: Lukas Krejci <lkrejci(a)redhat.com>
Date: Tue Mar 8 11:48:36 2011 +0100
Try hard to limit the size of SenderResult in the CLI alert notif to 4k. Improve the error messages captured from the script run.
diff --git a/modules/core/util/src/main/java/org/rhq/core/util/exception/ThrowableUtil.java b/modules/core/util/src/main/java/org/rhq/core/util/exception/ThrowableUtil.java
index c21e3c2..8eebde6 100644
--- a/modules/core/util/src/main/java/org/rhq/core/util/exception/ThrowableUtil.java
+++ b/modules/core/util/src/main/java/org/rhq/core/util/exception/ThrowableUtil.java
@@ -33,6 +33,11 @@ import java.util.ArrayList;
* @author John Mazzitelli
*/
public class ThrowableUtil {
+
+ private static final String EXCEPTION_WAS_NULL = ">> exception was null <<";
+ private static final String DOTS = " ... ";
+ private static final String ARROW = " -> ";
+
/**
* Prevent instantiation.
*/
@@ -58,17 +63,98 @@ public class ThrowableUtil {
ret_message.append(msgs[0]);
for (int i = 1; i < msgs.length; i++) {
- ret_message.append(" -> ");
+ ret_message.append(ARROW);
ret_message.append(msgs[i]);
}
} else {
- ret_message.append(">> exception was null <<");
+ ret_message.append(EXCEPTION_WAS_NULL);
}
return ret_message.toString();
}
/**
+ * Generates a string with all exception messages similarly to {@link #getAllMessages(Throwable, boolean)}
+ * but limits the length of the string to the provided limit.
+ * The messages are left out of the resulting string in the following manner:
+ * <ul>
+ * <li>The last message (i.e. the ultimate cause) is *always* in the output, regardless the maxSize
+ * <li>The first throwable is output, then the second, etc. up until the point where appending the
+ * next message *AND* the last message would make the output longer than maxSize.
+ * <li>An ellipsis is appended if the ultimate cause isn't the direct cause of the
+ * throwable which was last output according to the above algo.
+ * </ul>
+ * @param t
+ * @param includeExceptionNames
+ * @param maxSize the maximum size of the message. If < 0, the output is not limited.
+ * @return
+ */
+ public static final String getAllMessages(Throwable t, boolean includeExceptionNames, int maxSize) {
+ if (maxSize < 0) {
+ return getAllMessages(t, includeExceptionNames);
+ }
+
+ if (t == null) {
+ return EXCEPTION_WAS_NULL;
+ }
+
+ int arrowLength = ARROW.length();
+ int dotsLength = DOTS.length();
+
+ StringBuilder bld = new StringBuilder();
+
+ String[] msgs = getAllMessagesArray(t, includeExceptionNames);
+
+ //reduce the max size by the length of the last message
+ int maxDottedSize = maxSize - msgs[msgs.length - 1].length() - dotsLength;
+ // the dots and arrow have different lengths so we have to specialize for
+ //the case where the output actually fits in the maxSize
+ int maxFullSize = maxDottedSize + dotsLength - arrowLength;
+
+ if (msgs.length == 1 || maxDottedSize < 0) {
+ return msgs[msgs.length - 1];
+ }
+
+ int maxIdx = msgs.length - 1;
+ int lastIdx = maxIdx - 1;
+ int curLen = msgs[0].length();
+
+ if (curLen <= maxDottedSize) {
+ bld.append(msgs[0]);
+ }
+
+ int curIdx = 1;
+ for(; curIdx < maxIdx; ++curIdx) {
+ int lenIncr = arrowLength + msgs[curIdx].length();
+
+ if (curIdx == lastIdx) {
+ if (curLen + lenIncr > maxFullSize) {
+ break;
+ }
+ } else {
+ if (curLen + lenIncr > maxDottedSize) {
+ break;
+ }
+ }
+
+ bld.append(ARROW);
+ bld.append(msgs[curIdx]);
+
+ curLen += lenIncr;
+ }
+
+ if (curIdx < msgs.length - 1) {
+ bld.append(DOTS);
+ } else {
+ bld.append(ARROW);
+ }
+
+ bld.append(msgs[msgs.length - 1]);
+
+ return bld.toString();
+ }
+
+ /**
* Same as {@link #getAllMessages(Throwable, boolean)} with the "include exception name" parameter set to <code>
* true</code>.
*
@@ -94,6 +180,7 @@ public class ThrowableUtil {
ArrayList<String> list = new ArrayList<String>();
if (t != null) {
+
String msg;
if (includeExceptionName) {
@@ -157,7 +244,7 @@ public class ThrowableUtil {
ret_message.append(msgs[0]);
for (int i = 1; i < msgs.length; i++) {
- ret_message.append(" -> ");
+ ret_message.append(ARROW);
ret_message.append(msgs[i]);
}
} else {
diff --git a/modules/core/util/src/test/java/org/rhq/core/util/exception/ThrowableUtilTest.java b/modules/core/util/src/test/java/org/rhq/core/util/exception/ThrowableUtilTest.java
index d518c02..9d19293 100644
--- a/modules/core/util/src/test/java/org/rhq/core/util/exception/ThrowableUtilTest.java
+++ b/modules/core/util/src/test/java/org/rhq/core/util/exception/ThrowableUtilTest.java
@@ -81,4 +81,19 @@ public class ThrowableUtilTest {
.equals("java.lang.Throwable:sql exception wrapper -> java.sql.SQLException:one[SQLException=one -> two(error-code=0,sql-state=null) -> three(error-code=0,sql-state=null)]") : "Msg doesn't match: "
+ msg;
}
+
+ public void testMaxSize() {
+ String len10 = "1010101010";
+ String len20 = "20202020202020202020";
+ String len30 = "303030303030303030303030303030";
+
+ Exception e = new Exception(len10, new Exception(len20, new Exception(len30)));
+
+ assert ThrowableUtil.getAllMessages(e, false, 10).equals(len30);
+ assert ThrowableUtil.getAllMessages(e, false, 35).equals(" ... " + len30);
+ assert ThrowableUtil.getAllMessages(e, false, 45).equals(len10 + " ... " + len30);
+ assert ThrowableUtil.getAllMessages(e, false, 65).equals(len10 + " ... " + len30);
+ assert ThrowableUtil.getAllMessages(e, false, 67).equals(len10 + " ... " + len30);
+ assert ThrowableUtil.getAllMessages(e, false, 68).equals(len10 + " -> " + len20 + " -> "+ len30);
+ }
}
\ No newline at end of file
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/SandboxedScriptEngine.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/SandboxedScriptEngine.java
index ed3de18..7b34c6d 100644
--- a/modules/enterprise/binding/src/main/java/org/rhq/bindings/SandboxedScriptEngine.java
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/SandboxedScriptEngine.java
@@ -95,7 +95,7 @@ public class SandboxedScriptEngine implements ScriptEngine {
}
}, accessControlContext);
} catch (PrivilegedActionException e) {
- throw new ScriptException(e);
+ throw transfer(e);
}
}
@@ -107,7 +107,7 @@ public class SandboxedScriptEngine implements ScriptEngine {
}
}, accessControlContext);
} catch (PrivilegedActionException e) {
- throw new ScriptException(e);
+ throw transfer(e);
}
}
@@ -119,7 +119,7 @@ public class SandboxedScriptEngine implements ScriptEngine {
}
}, accessControlContext);
} catch (PrivilegedActionException e) {
- throw new ScriptException(e);
+ throw transfer(e);
}
}
@@ -131,7 +131,7 @@ public class SandboxedScriptEngine implements ScriptEngine {
}
}, accessControlContext);
} catch (PrivilegedActionException e) {
- throw new ScriptException(e);
+ throw transfer(e);
}
}
@@ -143,7 +143,7 @@ public class SandboxedScriptEngine implements ScriptEngine {
}
}, accessControlContext);
} catch (PrivilegedActionException e) {
- throw new ScriptException(e);
+ throw transfer(e);
}
}
@@ -155,7 +155,7 @@ public class SandboxedScriptEngine implements ScriptEngine {
}
}, accessControlContext);
} catch (PrivilegedActionException e) {
- throw new ScriptException(e);
+ throw transfer(e);
}
}
@@ -190,4 +190,12 @@ public class SandboxedScriptEngine implements ScriptEngine {
public ScriptEngineFactory getFactory() {
return engine.getFactory();
}
+
+ private static ScriptException transfer(PrivilegedActionException e) {
+ if (e.getCause() instanceof ScriptException) {
+ return (ScriptException) e.getCause();
+ } else {
+ return new ScriptException(e);
+ }
+ }
}
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/engine/JsEngineInitializer.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/engine/JsEngineInitializer.java
index 3aa4616..57545c4 100644
--- a/modules/enterprise/binding/src/main/java/org/rhq/bindings/engine/JsEngineInitializer.java
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/engine/JsEngineInitializer.java
@@ -33,6 +33,8 @@ import javax.script.ScriptException;
*/
public class JsEngineInitializer implements ScriptEngineInitializer {
+ private static final String WRAPPED_EXCEPTION_PREFIX = "Wrapped ";
+
private ScriptEngineManager engineManager = new ScriptEngineManager();
public boolean implementsLanguage(String language) {
@@ -70,4 +72,24 @@ public class JsEngineInitializer implements ScriptEngineInitializer {
return functionDefinition;
}
+
+ public String extractUserFriendlyErrorMessage(ScriptException e) {
+ String errorMessage = e.getMessage();
+
+ int wrappedIdx = errorMessage.lastIndexOf(WRAPPED_EXCEPTION_PREFIX);
+
+ if (wrappedIdx < 0) {
+ return errorMessage;
+ }
+
+ errorMessage = errorMessage.substring(wrappedIdx + WRAPPED_EXCEPTION_PREFIX.length());
+
+ int sourceInfoStartIdx = errorMessage.indexOf(" (<Unknown source>#");
+
+ if (sourceInfoStartIdx >= 0) {
+ errorMessage = errorMessage.substring(0, sourceInfoStartIdx);
+ }
+
+ return errorMessage;
+ }
}
diff --git a/modules/enterprise/binding/src/main/java/org/rhq/bindings/engine/ScriptEngineInitializer.java b/modules/enterprise/binding/src/main/java/org/rhq/bindings/engine/ScriptEngineInitializer.java
index fe99bf5..0f2f075 100644
--- a/modules/enterprise/binding/src/main/java/org/rhq/bindings/engine/ScriptEngineInitializer.java
+++ b/modules/enterprise/binding/src/main/java/org/rhq/bindings/engine/ScriptEngineInitializer.java
@@ -20,7 +20,6 @@
package org.rhq.bindings.engine;
import java.lang.reflect.Method;
-import java.util.List;
import java.util.Set;
import javax.script.ScriptEngine;
@@ -57,4 +56,20 @@ public interface ScriptEngineInitializer {
* @return a string with method definition in the scripting language
*/
String generateIndirectionMethod(String boundObjectName, Method method);
+
+ /**
+ * At least the Rhino script engine for java script generates exceptions
+ * whose error messages contain just "too much" information to be easily
+ * decipherable by the end users.
+ * <p>
+ * This method extracts messages from the exception such that they are
+ * presentable to the end user.
+ * <p>
+ * The returned string should only contain the error message. The filename, line
+ * and column information should be stripped from it if at all possible.
+ *
+ * @param e
+ * @return
+ */
+ String extractUserFriendlyErrorMessage(ScriptException e);
}
diff --git a/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java b/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java
index 61d5a3b..26c9cdf 100644
--- a/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java
+++ b/modules/enterprise/server/plugins/alert-cli/src/main/java/org/rhq/enterprise/server/plugins/alertCli/CliSender.java
@@ -44,6 +44,7 @@ import org.rhq.bindings.SandboxedScriptEngine;
import org.rhq.bindings.ScriptEngineFactory;
import org.rhq.bindings.StandardBindings;
import org.rhq.bindings.StandardScriptPermissions;
+import org.rhq.bindings.engine.ScriptEngineInitializer;
import org.rhq.bindings.util.PackageFinder;
import org.rhq.core.domain.alert.Alert;
import org.rhq.core.domain.alert.notification.SenderResult;
@@ -69,6 +70,10 @@ import org.rhq.enterprise.server.util.LookupUtil;
*/
public class CliSender extends AlertSender<CliComponent> {
+ private static final String ENGINE_NAME = "JavaScript";
+
+ private static final int MAX_RESULT_SIZE = 4000;
+
public static final String PROP_PACKAGE_ID = "packageId";
public static final String PROP_REPO_ID = "repoId";
public static final String PROP_USER_ID = "userId";
@@ -92,13 +97,13 @@ public class CliSender extends AlertSender<CliComponent> {
* Simple strongly typed representation of the alert configuration
*/
private static class Config {
- Subject subject;
+ Subject subject;
int packageId;
int repoId;
}
private static class ExceptionHolder {
- public Throwable throwable;
+ public ScriptException scriptException;
}
public SenderResult send(Alert alert) {
@@ -133,7 +138,7 @@ public class CliSender extends AlertSender<CliComponent> {
sandbox.eval(rdr);
SessionManager.getInstance().invalidate(config.subject.getSessionId());
} catch (ScriptException e) {
- exceptionHolder.throwable = e;
+ exceptionHolder.scriptException = e;
}
}
}, "Script Runner for alert " + alert);
@@ -148,8 +153,16 @@ public class CliSender extends AlertSender<CliComponent> {
scriptRunner.interrupt();
- if (exceptionHolder.throwable != null) {
- throw new Exception("Script failed with an exception.", exceptionHolder.throwable);
+ if (exceptionHolder.scriptException != null) {
+ LOG.info("The script execution for CLI notification of alert [" + alert + "] failed.", exceptionHolder.scriptException);
+
+ //make things pretty for the UI
+ ScriptEngineInitializer initializer = ScriptEngineFactory.getInitializer(ENGINE_NAME);
+ String message = initializer.extractUserFriendlyErrorMessage(exceptionHolder.scriptException);
+ int col = exceptionHolder.scriptException.getColumnNumber();
+ int line = exceptionHolder.scriptException.getLineNumber();
+ String scriptName = createSummary(config, "script $packageName ($packageVersion) in repo $repoName");
+ throw new ScriptException(message, scriptName, line, col);
}
scriptOut.flush();
@@ -159,13 +172,17 @@ public class CliSender extends AlertSender<CliComponent> {
scriptOutput = "Script generated no output.";
}
+ if (scriptOutput.length() > remainingResultSize(result)) {
+ scriptOutput = scriptOutput.substring(0, remainingResultSize(result));
+ }
+
result.addSuccessMessage(scriptOutput);
return result;
} catch (IllegalArgumentException e) {
- return SenderResult.getSimpleFailure(e.getMessage());
+ return SenderResult.getSimpleFailure(e.getMessage()); //well, let's just hope the message doesn't exceed 4k.
} catch (Exception e) {
- result.addFailureMessage(ThrowableUtil.getAllMessages(e));
+ result.addFailureMessage(ThrowableUtil.getAllMessages(e, true, remainingResultSize(result)));
return result;
} finally {
if (engine != null) {
@@ -381,7 +398,7 @@ public class CliSender extends AlertSender<CliComponent> {
ScriptEngine engine = SCRIPT_ENGINES.poll();
if (engine == null) {
- engine = ScriptEngineFactory.getScriptEngine("JavaScript",
+ engine = ScriptEngineFactory.getScriptEngine(ENGINE_NAME,
new PackageFinder(Collections.<File> emptyList()), bindings);
} else {
ScriptEngineFactory.injectStandardBindings(engine, bindings, true);
@@ -400,4 +417,20 @@ public class CliSender extends AlertSender<CliComponent> {
SCRIPT_ENGINES.notify();
}
}
+
+ private static int remainingResultSize(SenderResult r) {
+ //the "10" is a ballpark to allow for some formatting
+ //done by the receivers of the SenderResult.
+ int ret = MAX_RESULT_SIZE - r.getSummary().length() - 10;
+
+ for(String m : r.getSuccessMessages()) {
+ ret -= m.length() + 10;
+ }
+
+ for(String m : r.getFailureMessages()) {
+ ret -= m.length() + 10;
+ }
+
+ return ret;
+ }
}
13 years, 2 months
[rhq] modules/enterprise
by mazz
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/SystemSettingsView.java | 19 +++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
New commits:
commit 424ea1880f8897351d70f6f138c27a4b89b89513
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Tue Mar 8 11:04:55 2011 -0500
bz 683108 - make sys config view more tolerant of configs not set but where we have defaults
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/SystemSettingsView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/SystemSettingsView.java
index 6d8aaa2..15ca21f 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/SystemSettingsView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/admin/SystemSettingsView.java
@@ -38,6 +38,7 @@ import org.rhq.core.domain.common.ServerDetails.Detail;
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.configuration.definition.PropertyDefinition;
import org.rhq.core.domain.configuration.definition.PropertyDefinitionSimple;
import org.rhq.core.domain.configuration.definition.PropertyGroupDefinition;
import org.rhq.core.domain.configuration.definition.PropertySimpleType;
@@ -172,6 +173,7 @@ public class SystemSettingsView extends LocatableVLayout implements PropertyValu
config.put(prop);
}
+ // build our config definition and populate our config editor
editor = new ConfigurationEditor(extendLocatorId("configEditor"), getSystemSettingsDefinition(config),
config);
editor.addPropertyValueChangeListener(SystemSettingsView.this);
@@ -518,8 +520,23 @@ public class SystemSettingsView extends LocatableVLayout implements PropertyValu
ldapBindPW.setDefaultValue("");
def.put(ldapBindPW);
- return def;
+ //
+ // if the config is missing any properties for which we have defaults, set them to their defaults
+ //
+ Map<String, PropertyDefinition> allDefinitions = def.getPropertyDefinitions();
+ for (Map.Entry<String, PropertyDefinition> defEntry : allDefinitions.entrySet()) {
+ String propertyName = defEntry.getKey();
+ PropertyDefinition propertyDef = defEntry.getValue();
+ if (config.get(propertyName) == null) {
+ if (propertyDef instanceof PropertyDefinitionSimple
+ && ((PropertyDefinitionSimple) propertyDef).getDefaultValue() != null) {
+ config.put(new PropertySimple(propertyName, ((PropertyDefinitionSimple) propertyDef)
+ .getDefaultValue()));
+ }
+ }
+ }
+ return def;
}
private DynamicForm getServerDetails() {
13 years, 2 months
[rhq] modules/enterprise
by mazz
modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/test/i18n/TestRemoteServiceStatisticsView.java | 70 +++++-----
1 file changed, 35 insertions(+), 35 deletions(-)
New commits:
commit 52c8302d3ba0568bf6ea4ba3726857f645efc309
Author: John Mazzitelli <mazz(a)redhat.com>
Date: Tue Mar 8 10:10:03 2011 -0500
add a "refresh" button on the standalone window so its easier to quickly get the new data
diff --git a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/test/i18n/TestRemoteServiceStatisticsView.java b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/test/i18n/TestRemoteServiceStatisticsView.java
index 5024c59..7a36f1d 100644
--- a/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/test/i18n/TestRemoteServiceStatisticsView.java
+++ b/modules/enterprise/gui/coregui/src/main/java/org/rhq/enterprise/gui/coregui/client/test/i18n/TestRemoteServiceStatisticsView.java
@@ -153,6 +153,14 @@ public class TestRemoteServiceStatisticsView extends Table {
}
});
+ addTableAction(extendLocatorId("refresh"), MSG.common_button_refresh(), new AbstractTableAction(
+ TableActionEnablement.ALWAYS) {
+ @Override
+ public void executeAction(ListGridRecord[] selection, Object actionValue) {
+ refresh();
+ }
+ });
+
if (window != null) {
LinkedHashMap<String, Integer> timerValues = new LinkedHashMap<String, Integer>();
timerValues.put("Now", Integer.valueOf("-2"));
@@ -172,43 +180,35 @@ public class TestRemoteServiceStatisticsView extends Table {
}
});
- addTableAction(extendLocatorId("refreshTimer"), "Refresh", null, timerValues, new AbstractTableAction(
- TableActionEnablement.ALWAYS) {
- @Override
- public void executeAction(ListGridRecord[] selection, Object actionValue) {
-
- Integer timeout = (Integer) actionValue;
-
- // if being asked to refresh now, just refresh but don't touch our schedules
- if (timeout == null || timeout.intValue() == -2) {
- refresh();
- return;
+ addTableAction(extendLocatorId("refreshTimer"), "Refresh Timer", null, timerValues,
+ new AbstractTableAction(TableActionEnablement.ALWAYS) {
+ @Override
+ public void executeAction(ListGridRecord[] selection, Object actionValue) {
+
+ Integer timeout = (Integer) actionValue;
+
+ // if being asked to refresh now, just refresh but don't touch our schedules
+ if (timeout == null || timeout.intValue() == -2) {
+ refresh();
+ return;
+ }
+
+ // cancel everything - will reinstate if user elected to do one of these
+ refreshTimer.cancel();
+ refreshOnPageChange = false;
+
+ if (timeout.intValue() == -1) {
+ setTableTitle(TABLE_TITLE);
+ } else if (timeout.intValue() == 0) {
+ refreshOnPageChange = true;
+ setTableTitle(TABLE_TITLE + " (refresh on page change)");
+ } else {
+ refreshTimer.scheduleRepeating(timeout.intValue() * 1000);
+ setTableTitle(TABLE_TITLE + " (refresh every " + timeout + "s)");
+ }
}
-
- // cancel everything - will reinstate if user elected to do one of these
- refreshTimer.cancel();
- refreshOnPageChange = false;
-
- if (timeout.intValue() == -1) {
- setTableTitle(TABLE_TITLE);
- } else if (timeout.intValue() == 0) {
- refreshOnPageChange = true;
- setTableTitle(TABLE_TITLE + " (refresh on page change)");
- } else {
- refreshTimer.scheduleRepeating(timeout.intValue() * 1000);
- setTableTitle(TABLE_TITLE + " (refresh every " + timeout + "s)");
- }
- }
- });
+ });
} else { // not in the standalone window
- addTableAction(extendLocatorId("refresh"), MSG.common_button_refresh(), new AbstractTableAction(
- TableActionEnablement.ALWAYS) {
- @Override
- public void executeAction(ListGridRecord[] selection, Object actionValue) {
- refresh();
- }
- });
-
addTableAction(extendLocatorId("showInWin"), "Show In Window", new AbstractTableAction(
TableActionEnablement.ALWAYS) {
@Override
13 years, 2 months
[rhq] modules/enterprise
by Jay Shaughnessy
modules/enterprise/server/plugins/alert-cli/pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
New commits:
commit e1c1468c1749848bed2fadabc185f39fa49ce286
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Tue Mar 8 09:25:35 2011 -0500
Fix dep version problem presumably left from a release build.
diff --git a/modules/enterprise/server/plugins/alert-cli/pom.xml b/modules/enterprise/server/plugins/alert-cli/pom.xml
index dadc2e4..96b129a 100644
--- a/modules/enterprise/server/plugins/alert-cli/pom.xml
+++ b/modules/enterprise/server/plugins/alert-cli/pom.xml
@@ -24,7 +24,7 @@
<dependency>
<groupId>org.rhq</groupId>
<artifactId>rhq-server-client-api</artifactId>
- <version>4.0.0.Beta1</version>
+ <version>${project.version}</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
13 years, 2 months