/* * RHQ Management Platform * Copyright (C) 2005-2008 Red Hat, Inc. * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.rhq.enterprise.gui.legacy.action.resource.common.monitor.visibility; import java.util.ArrayList; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.apache.struts.tiles.ComponentContext; import org.apache.struts.tiles.actions.TilesAction; import org.rhq.core.domain.auth.Subject; import org.rhq.core.domain.measurement.DataType; import org.rhq.core.domain.measurement.ui.MetricDisplaySummary; import org.rhq.core.domain.resource.Resource; import org.rhq.core.domain.resource.ResourceType; import org.rhq.core.domain.resource.composite.ResourceWithAvailability; import org.rhq.core.domain.resource.group.composite.AutoGroupComposite; import org.rhq.enterprise.gui.legacy.AttrConstants; import org.rhq.enterprise.gui.legacy.MessageConstants; import org.rhq.enterprise.gui.legacy.WebUser; import org.rhq.enterprise.gui.legacy.util.RequestUtils; import org.rhq.enterprise.gui.legacy.util.SessionUtils; import org.rhq.enterprise.gui.uibeans.AutoGroupCompositeDisplaySummary; import org.rhq.enterprise.gui.util.WebUtility; import org.rhq.enterprise.server.measurement.MeasurementChartsManagerLocal; import org.rhq.enterprise.server.measurement.MeasurementDataManagerLocal; import org.rhq.enterprise.server.measurement.MeasurementException; import org.rhq.enterprise.server.measurement.MeasurementPreferences; import org.rhq.enterprise.server.measurement.MeasurementPreferences.MetricRangePreferences; import org.rhq.enterprise.server.resource.ResourceManagerLocal; import org.rhq.enterprise.server.resource.ResourceTypeManagerLocal; import org.rhq.enterprise.server.resource.ResourceTypeNotFoundException; import org.rhq.enterprise.server.util.LookupUtil; /** * Fetch the children resources for the server */ public class ListChildrenAction extends TilesAction { protected static final Log log = LogFactory.getLog(ListChildrenAction.class); MeasurementDataManagerLocal dataManager; MeasurementChartsManagerLocal chartsManager; @SuppressWarnings("unchecked") @Override public ActionForward execute(ComponentContext context, ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { dataManager = LookupUtil.getMeasurementDataManager(); chartsManager = LookupUtil.getMeasurementChartsManager(); WebUser user = SessionUtils.getWebUser(request.getSession()); Subject subject = user.getSubject(); Resource resource = (Resource) request.getAttribute(AttrConstants.RESOURCE_ATTR); // Get metric time range MeasurementPreferences preferences = user.getMeasurementPreferences(); MetricRangePreferences rangePreferences = preferences.getMetricRangePreferences(); long begin = rangePreferences.begin; long end = rangePreferences.end; List<AutoGroupComposite> children; List<AutoGroupCompositeDisplaySummary> displaySummary; int parentId = -1; int resourceTypeId = -1; if (resource == null) { parentId = WebUtility.getOptionalIntRequestParameter(request, AttrConstants.AUTOGROUP_PARENT_ATTR, -1); if (parentId > 0) // get data for individual autogroup children { resourceTypeId = WebUtility.getOptionalIntRequestParameter(request, AttrConstants.AUTOGROUP_TYPE_ATTR, -1); children = getAutoGroupChildren(subject, parentId, resourceTypeId); if (children == null) children = new ArrayList<AutoGroupComposite>(); displaySummary = new ArrayList<AutoGroupCompositeDisplaySummary>(children.size() + 1); // get the parent ResourceManagerLocal resourceManager = LookupUtil.getResourceManager(); AutoGroupComposite parentComposite = resourceManager.getResourceAutoGroup(subject, parentId); if (parentComposite != null) { parentComposite.setMainResource(true); List<MetricDisplaySummary> metricSummaries = null; metricSummaries = chartsManager.getMetricDisplaySummariesForMetrics(subject, parentId, DataType.MEASUREMENT, begin, end, true, true); displaySummary.add(0, new AutoGroupCompositeDisplaySummary(parentComposite, metricSummaries)); } /* We have n children with each child representing exactly 1 resource. * As we are in an autogroup, all children have the same type, so we can just feed them to the backend * in one call with all n resources. */ // Loop over children, get resources, call some ..forMultiMetrics.. List<Integer> resourceIds = new ArrayList<Integer>(); for (AutoGroupComposite child : children) { List resources = child.getResources(); ResourceWithAvailability rwa = (ResourceWithAvailability) resources.get(0); resourceIds.add(rwa.getResource().getId()); } // Map<ResourceId, List<Summaries for that resource> Map<Integer, List<MetricDisplaySummary>> summaries = dataManager .findNarrowedMetricDisplaySummariesForResourcesAndParent(subject, resourceTypeId, parentId, resourceIds, begin, end); for (AutoGroupComposite child : children) { if (parentComposite != null) child.increaseDepth(1); List resources = child.getResources(); ResourceWithAvailability rwa = (ResourceWithAvailability) resources.get(0); List<MetricDisplaySummary> sumList = summaries.get(rwa.getResource().getId()); displaySummary.add(new AutoGroupCompositeDisplaySummary(child, sumList)); } } else { RequestUtils.setError(request, MessageConstants.ERR_RESOURCE_NOT_FOUND); return null; } } else { // resource != null // get children of that single resource, which can be individual resources or autogroups children = getResourceChildren(resource, subject); displaySummary = new ArrayList<AutoGroupCompositeDisplaySummary>(children.size()); for (AutoGroupComposite child : children) { List<MetricDisplaySummary> metrics = getMetrics(resource, child, subject, begin, end); displaySummary.add(new AutoGroupCompositeDisplaySummary(child, metrics)); } } context.putAttribute(AttrConstants.CTX_SUMMARIES, displaySummary); return null; } public List<MetricDisplaySummary> getMetrics(Resource parentResource, AutoGroupComposite resourceGroupComposite, Subject subject, long beginTime, long endTime) throws MeasurementException { if (log.isTraceEnabled()) { log.trace("finding metric summaries for resourceType [" + resourceGroupComposite.getResourceType().getName()); } List<MetricDisplaySummary> metricSummaries = null; // TODO GH: Why are we only getting the first one? --> single resource case // List resources = resourceGroupComposite.getResources(); if ((resources != null) && (resources.size() == 1)) { ResourceWithAvailability resource = (ResourceWithAvailability) resources.get(0); metricSummaries = chartsManager.getMetricDisplaySummariesForMetrics(subject, resource.getResource().getId(), DataType.MEASUREMENT, beginTime, endTime, true, true); } else if ((resources != null) && (resources.size() > 1)) { List<Resource> res = new ArrayList<Resource>(); for (Object o : resources) { if (o instanceof ResourceWithAvailability) { ResourceWithAvailability rwa = (ResourceWithAvailability) o; res.add(rwa.getResource()); } } Map<Integer, List<MetricDisplaySummary>> sumMap = dataManager .findNarrowedMetricDisplaySummariesForCompatibleResources(subject, res, beginTime, endTime); metricSummaries = sumMap.values().iterator().next(); // fill in some data that does not come from the backend for (MetricDisplaySummary tmp : metricSummaries) { tmp.setParentId(parentResource.getId()); tmp.setChildTypeId(resourceGroupComposite.getResourceType().getId()); } } return metricSummaries; } private List<AutoGroupComposite> getResourceChildren(Resource resource, Subject subject) { ResourceManagerLocal resourceManager = LookupUtil.getResourceManager(); List<AutoGroupComposite> children = resourceManager.findChildrenAutoGroups(subject, resource.getId()); AutoGroupComposite resourceGroupComposite = resourceManager.getResourceAutoGroup(subject, resource.getId()); if (resourceGroupComposite != null) resourceGroupComposite.setMainResource(true); else return new ArrayList<AutoGroupComposite>(); // now increase everyone's depth by one to account for the resource for (AutoGroupComposite child : children) { child.setDepth(child.getDepth() + 1); } children.add(0, resourceGroupComposite); Resource parentResource = resourceManager.getParentResource(resource.getId()); AutoGroupComposite parentGroupComposite = null; if (parentResource != null) { parentGroupComposite = resourceManager.getResourceAutoGroup(subject, parentResource.getId()); } if (parentGroupComposite != null) { // now increase everyone's depth by one to account for the parent for (AutoGroupComposite child : children) { child.increaseDepth(1); } children.add(0, parentGroupComposite); } return children; } /** * Get a list of the individual 'child resources' of that autogroup. */ private List<AutoGroupComposite> getAutoGroupChildren(Subject subject, int parentId, int resourceTypeId) { List<AutoGroupComposite> children = new ArrayList<AutoGroupComposite>(); ResourceManagerLocal resourceManager = LookupUtil.getResourceManager(); ResourceTypeManagerLocal resourceTypeMananger = LookupUtil.getResourceTypeManager(); Resource parentResource = resourceManager.getResourceById(subject, parentId); ResourceType resourceType = null; try { resourceType = resourceTypeMananger.getResourceTypeById(subject, resourceTypeId); } catch (ResourceTypeNotFoundException e) { return children; // empty list if we don't know the child type } if ((resourceType != null) && (parentResource != null)) { // first get the resources in the autogroup List<ResourceWithAvailability> resourcesForAutoGroup = resourceManager.findResourcesByParentAndType(subject, parentResource, resourceType); int i = 0; int[] resourceIds = new int[resourcesForAutoGroup.size()]; for (ResourceWithAvailability resourceInAutoGroup : resourcesForAutoGroup) { int id = resourceInAutoGroup.getResource().getId(); resourceIds[i++] = id; } // And then the composite to return List<AutoGroupComposite> composites = resourceManager.findResourcesAutoGroups(subject, resourceIds); return composites; } return children; // empty } }