/* * 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.coregui.client.inventory.resource.discovery; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Set; 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.DataSource; import com.smartgwt.client.data.fields.DataSourceTextField; import com.smartgwt.client.types.DSDataFormat; import com.smartgwt.client.types.DSProtocol; import com.smartgwt.client.widgets.tree.TreeGrid; import com.smartgwt.client.widgets.tree.TreeNode; import org.rhq.core.domain.authz.Permission; import org.rhq.core.domain.criteria.ResourceCriteria; import org.rhq.core.domain.resource.InventoryStatus; 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.util.PageControl; import org.rhq.core.domain.util.PageList; import org.rhq.core.domain.util.PageOrdering; import org.rhq.core.domain.util.ResourceTypeUtility; import org.rhq.coregui.client.CoreGUI; import org.rhq.coregui.client.Messages; import org.rhq.coregui.client.PermissionsLoadedListener; import org.rhq.coregui.client.PermissionsLoader; import org.rhq.coregui.client.gwt.GWTServiceLookup; import org.rhq.coregui.client.gwt.ResourceGWTServiceAsync; import org.rhq.coregui.client.util.Log; /** * @author Greg Hinkle */ public class AutodiscoveryQueueDataSource extends DataSource { private static Messages MSG = CoreGUI.getMessages(); public static final String NEW = MSG.common_button_new(); public static final String IGNORED = MSG.view_autoDiscoveryQ_ignored(); public static final String NEW_AND_IGNORED = MSG.view_autoDiscoveryQ_newAndIgnored(); private static final String NO_MANAGE_INVENTORY_PERMS_EMPTY_MESSAGE = MSG.view_autoDiscoveryQ_noperm(); private static final String EMPTY_MESSAGE = MSG.common_msg_noItemsToShow(); private static final Permission MANAGE_INVENTORY = Permission.MANAGE_INVENTORY; private int unlimited = -1; private int maximumPlatformsToDisplay = -1; // Specify 60s timeout to compensate for slow loading of this view due to lack of paging of results. // TODO (ips, 08/31/11): Remove this once paging has been implemented. private ResourceGWTServiceAsync resourceService = GWTServiceLookup.getResourceService(60 * 1000); private PermissionsLoader permissionsLoader = new PermissionsLoader(); private TreeGrid dataContainerReference = null; private List<AsyncCallback> failedFetchListeners = new ArrayList<AsyncCallback>(); public AutodiscoveryQueueDataSource() { setClientOnly(false); setDataProtocol(DSProtocol.CLIENTCUSTOM); setDataFormat(DSDataFormat.CUSTOM); DataSourceTextField idField = new DataSourceTextField("id", MSG.common_title_id()); idField.setPrimaryKey(true); DataSourceTextField parentIdField = new DataSourceTextField("parentId", MSG.view_autoDiscoveryQ_field_parentId()); parentIdField.setForeignKey("id"); DataSourceTextField resourceNameField = new DataSourceTextField("name", MSG.common_title_resource_name()); DataSourceTextField resourceKeyField = new DataSourceTextField("resourceKey", MSG.common_title_resource_key()); DataSourceTextField resourceTypeField = new DataSourceTextField("typeName", MSG.common_title_resource_type()); DataSourceTextField descriptionField = new DataSourceTextField("description", MSG.common_title_description()); DataSourceTextField timestampField = new DataSourceTextField("ctime", MSG.view_autoDiscoveryQ_field_discoveryTime()); DataSourceTextField statusField = new DataSourceTextField("statusLabel", MSG.view_autoDiscoveryQ_field_inventoryStatus()); setFields(idField, parentIdField, resourceNameField, resourceKeyField, resourceTypeField, descriptionField, statusField, timestampField); } public AutodiscoveryQueueDataSource(TreeGrid treeGrid) { this(); this.dataContainerReference = treeGrid; } protected Object transformRequest(DSRequest request) { DSResponse response = new DSResponse(); response.setAttribute("clientContext", request.getAttributeAsObject("clientContext")); // assume success response.setStatus(0); switch (request.getOperationType()) { case FETCH: executeFetch(request, response); break; default: break; } return request.getData(); } protected void executeFetch(final DSRequest request, final DSResponse response) { final String platformId = request.getCriteria().getAttribute("parentId"); final ArrayList<InventoryStatus> statuses = new ArrayList<InventoryStatus>(); String statusesString = request.getCriteria().getAttributeAsString("status"); if (statusesString != null) { if (NEW.equals(statusesString)) { statuses.add(InventoryStatus.NEW); } else if (IGNORED.equals(statusesString)) { statuses.add(InventoryStatus.IGNORED); } else { statuses.add(InventoryStatus.NEW); statuses.add(InventoryStatus.IGNORED); } } else { statuses.add(InventoryStatus.NEW); } //determine if has manage inventory perms, if so then chain and proceed with getting Q resources permissionsLoader.loadExplicitGlobalPermissions(new PermissionsLoadedListener() { @Override public void onPermissionsLoaded(Set<Permission> permissions) { if (permissions != null) { if (!permissions.contains(MANAGE_INVENTORY)) { Log.debug("(User does not have required managed inventory permissions. " + EMPTY_MESSAGE); response.setTotalRows(0); if (dataContainerReference != null) { Log.trace("Setting better empty container message." + NO_MANAGE_INVENTORY_PERMS_EMPTY_MESSAGE); dataContainerReference.setEmptyMessage(NO_MANAGE_INVENTORY_PERMS_EMPTY_MESSAGE); } processResponse(request.getRequestId(), response); return; } if (dataContainerReference != null) { dataContainerReference.setEmptyMessage(EMPTY_MESSAGE); } if (null == platformId) { // query for platforms final PageControl pc = getPageControl(request); resourceService.getQueuedPlatforms(statuses, pc, new AsyncCallback<PageList<Resource>>() { public void onFailure(Throwable caught) { CoreGUI.getErrorHandler().handleError(MSG.view_autoDiscoveryQ_loadFailure(), caught); for (AsyncCallback failedFetchListener : failedFetchListeners) { failedFetchListener.onFailure(caught); } } public void onSuccess(PageList<Resource> result) { response.setData(buildPlatformNodes(result)); processResponse(request.getRequestId(), response); } }); } else { final int platformResourceId = Integer.valueOf(platformId); final Resource parentResourceStub = new Resource(platformResourceId); ResourceCriteria fetchCriteria = new ResourceCriteria(); fetchCriteria.addFilterParentResourceId(platformResourceId); fetchCriteria.addFilterResourceCategories(ResourceCategory.SERVER); fetchCriteria.addFilterInventoryStatuses(statuses); fetchCriteria.clearPaging(); fetchCriteria.addSortName(PageOrdering.ASC); resourceService.findResourcesByCriteria(fetchCriteria, new AsyncCallback<PageList<Resource>>() { public void onFailure(Throwable caught) { CoreGUI.getErrorHandler().handleError(MSG.view_autoDiscoveryQ_loadFailure(), caught); for (AsyncCallback failedFetchListener : failedFetchListeners) { failedFetchListener.onFailure(caught); } } public void onSuccess(PageList<Resource> result) { response.setData(buildServerNodes(parentResourceStub, result)); processResponse(request.getRequestId(), response); } }); } } } }); } /** * @param callback The onFailure() method will be invoked if the DS fails a fetch operation. */ public void addFailedFetchListener(AsyncCallback callback) { failedFetchListeners.add(callback); } private TreeNode[] buildPlatformNodes(PageList<Resource> platforms) { ArrayList<ResourceTreeNode> nodes = new ArrayList<ResourceTreeNode>(); for (Resource platform : platforms) { nodes.add(new ResourceTreeNode(platform)); } TreeNode[] treeNodes = nodes.toArray(new TreeNode[nodes.size()]); return treeNodes; } private TreeNode[] buildServerNodes(Resource parentResource, PageList<Resource> servers) { ArrayList<ResourceTreeNode> nodes = new ArrayList<ResourceTreeNode>(); for (Resource server : servers) { server.setParentResource(parentResource); // set the parent so the tree relationship gets set nodes.add(new ResourceTreeNode(server)); } TreeNode[] treeNodes = nodes.toArray(new TreeNode[nodes.size()]); return treeNodes; } /** * Returns a pre-populated PageControl based on the provided DSRequest. This will set sort fields, * pagination, but *not* filter fields. * * @param request the request to turn into a page control * @return the page control for passing to criteria and other queries */ protected PageControl getPageControl(DSRequest request) { // Initialize paging. PageControl pageControl; if (getMaximumPlatformsToDisplay() > -1) { pageControl = new PageControl(0, getMaximumPlatformsToDisplay()); } else { pageControl = new PageControl(0, unlimited); } // Initialize sorting. String sortBy = request.getAttribute("sortBy"); if (sortBy != null) { String[] sorts = sortBy.split(","); for (String sort : sorts) { PageOrdering ordering = (sort.startsWith("-")) ? PageOrdering.DESC : PageOrdering.ASC; String columnName = (ordering == PageOrdering.DESC) ? sort.substring(1) : sort; pageControl.addDefaultOrderingField(columnName, ordering); } } return pageControl; } public static class ResourceTreeNode extends TreeNode { private Resource resource; private ResourceTreeNode(Resource resource) { this.resource = resource; String id = String.valueOf(resource.getId()); String parentId = resource.getParentResource() == null ? null : String.valueOf((resource .getParentResource().getId())); setID(id); setParentID(parentId); setIsFolder(null == parentId); setAttribute("id", id); setAttribute("parentId", parentId); setAttribute("name", resource.getName()); setAttribute("typeName", ResourceTypeUtility.displayName(resource.getResourceType())); setAttribute("resourceKey", resource.getResourceKey()); setAttribute("description", resource.getDescription()); setAttribute("ctime", new Date(resource.getCtime())); setAttribute("status", resource.getInventoryStatus().name()); switch (resource.getInventoryStatus()) { case NEW: setAttribute("statusLabel", MSG.common_button_new()); break; case COMMITTED: setAttribute("statusLabel", MSG.view_autoDiscoveryQ_committed()); break; case IGNORED: setAttribute("statusLabel", MSG.view_autoDiscoveryQ_ignored()); break; case UNINVENTORIED: setAttribute("statusLabel", MSG.view_autoDiscoveryQ_uninventoried()); break; } } public Resource getResource() { return resource; } public void setResource(Resource resource) { this.resource = resource; } public ResourceType getResourceType() { return resource.getResourceType(); } public String getParentId() { return getAttribute("parentId"); } } public int getMaximumPlatformsToDisplay() { return maximumPlatformsToDisplay; } public void setMaximumPlatformsToDisplay(int maximumPlatformsToDisplay) { this.maximumPlatformsToDisplay = maximumPlatformsToDisplay; } }