/* * * * RHQ Management Platform * * Copyright (C) 2005-2012 Red Hat, Inc. * * All rights reserved. * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation version 2 of the License. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ package org.rhq.enterprise.server.resource; import static java.util.Arrays.asList; import static javax.ejb.TransactionAttributeType.REQUIRES_NEW; import static org.rhq.core.domain.resource.InventoryStatus.COMMITTED; import static org.rhq.core.domain.resource.ResourceCategory.PLATFORM; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeSet; import javax.ejb.EJB; import javax.ejb.Stateless; import javax.ejb.TransactionAttribute; import org.rhq.core.domain.auth.Subject; import org.rhq.core.domain.criteria.ResourceCriteria; import org.rhq.core.domain.criteria.ResourceTypeCriteria; import org.rhq.core.domain.measurement.AvailabilityType; import org.rhq.core.domain.measurement.MeasurementData; import org.rhq.core.domain.measurement.MeasurementDefinition; import org.rhq.core.domain.resource.Resource; import org.rhq.core.domain.resource.ResourceType; import org.rhq.core.domain.resource.composite.PlatformMetricsSummary; import org.rhq.core.domain.resource.composite.PlatformMetricsSummary.CPUMetric; import org.rhq.core.domain.resource.composite.PlatformMetricsSummary.MemoryMetric; import org.rhq.core.domain.resource.composite.PlatformMetricsSummary.SwapMetric; import org.rhq.core.domain.util.PageList; import org.rhq.core.util.collection.ArrayUtils; import org.rhq.enterprise.server.measurement.MeasurementDataManagerLocal; import org.rhq.enterprise.server.util.CriteriaQuery; import org.rhq.enterprise.server.util.CriteriaQueryExecutor; /** * @author jsanda */ @Stateless public class PlatformUtilizationManagerBean implements PlatformUtilizationManagerLocal { @EJB private ResourceTypeManagerLocal resourceTypeMgr; @EJB private ResourceManagerLocal resourceMgr; @EJB private MeasurementDataManagerLocal measurementDataMgr; @EJB private PlatformUtilizationManagerLocal platformUtilizationMgr; @Override public PageList<PlatformMetricsSummary> loadPlatformMetrics(final Subject subject) { final ResourceTypeCriteria typeCriteria = new ResourceTypeCriteria(); typeCriteria.addFilterIgnored(false); // don't load metrics for ignored types typeCriteria.addFilterCategory(PLATFORM); typeCriteria.fetchMetricDefinitions(true); //Use CriteriaQuery to automatically chunk/page through criteria query results CriteriaQueryExecutor<ResourceType, ResourceTypeCriteria> queryExecutor = new CriteriaQueryExecutor<ResourceType, ResourceTypeCriteria>() { @Override public PageList<ResourceType> execute(ResourceTypeCriteria criteria) { return resourceTypeMgr.findResourceTypesByCriteria(subject, typeCriteria); } }; CriteriaQuery<ResourceType, ResourceTypeCriteria> resourceTypes = new CriteriaQuery<ResourceType, ResourceTypeCriteria>( typeCriteria, queryExecutor); Map<Integer, Set<Integer>> platformMetricDefs = new HashMap<Integer, Set<Integer>>(); for (ResourceType resourceType : resourceTypes) { platformMetricDefs.put(resourceType.getId(), getPlatformMetricDefIds(resourceType)); } final ResourceCriteria resourceCriteria = new ResourceCriteria(); resourceCriteria.addFilterResourceCategories(PLATFORM); resourceCriteria.addFilterInventoryStatus(COMMITTED); resourceCriteria.fetchCurrentAvailability(true); //Use CriteriaQuery to automatically chunk/page through criteria query results CriteriaQueryExecutor<Resource, ResourceCriteria> resourceQueryExecutor = new CriteriaQueryExecutor<Resource, ResourceCriteria>() { @Override public PageList<Resource> execute(ResourceCriteria criteria) { return resourceMgr.findResourcesByCriteria(subject, resourceCriteria); } }; CriteriaQuery<Resource, ResourceCriteria> platforms = new CriteriaQuery<Resource, ResourceCriteria>( resourceCriteria, resourceQueryExecutor); PageList<PlatformMetricsSummary> summaries = new PageList<PlatformMetricsSummary>(); for (Resource platform : platforms) { Set<Integer> metricDefIds = platformMetricDefs.get(platform.getResourceType().getId()); try { // don't try to contact platforms that are down or questionable. In that case, just return the // platform marked with no metrics available if (AvailabilityType.UP == platform.getCurrentAvailability().getAvailabilityType()) { // Don't wait for more than 10s for any one agent, even that may be too long. Set<MeasurementData> measurementDataSet = platformUtilizationMgr .loadLiveMetricsForPlatformInNewTransaction(subject, platform, metricDefIds, 10000L); summaries.add(createSummary(platform, measurementDataSet)); } else { summaries.add(createSummary(platform, null)); } } catch (RuntimeException e) { PlatformMetricsSummary summary = new PlatformMetricsSummary(); summary.setResource(platform); summary.setMetricsAvailable(false); summaries.add(summary); } } return summaries; } @Override @TransactionAttribute(REQUIRES_NEW) public Set<MeasurementData> loadLiveMetricsForPlatformInNewTransaction(Subject subject, Resource platform, Set<Integer> metricDefinitionIds, Long timeout) { return measurementDataMgr.findLiveData(subject, platform.getId(), ArrayUtils.unwrapArray(metricDefinitionIds.toArray(new Integer[metricDefinitionIds.size()])), timeout); } private Set<Integer> getPlatformMetricDefIds(ResourceType resourceType) { Set<Integer> metricDefIds = new TreeSet<Integer>(); List<String> metricDefNames = asList(MemoryMetric.Used.getProperty(), MemoryMetric.ActualUsed.getProperty(), MemoryMetric.Free.getProperty(), MemoryMetric.ActualFree.getProperty(), MemoryMetric.Total.getProperty(), CPUMetric.Idle.getProperty(), CPUMetric.System.getProperty(), CPUMetric.User.getProperty(), SwapMetric.Free.getProperty(), SwapMetric.Used.getProperty(), SwapMetric.Total.getProperty()); for (String metricDefName : metricDefNames) { Integer metricDefId = findMetricDefId(resourceType.getMetricDefinitions(), metricDefName); if (metricDefId != null) { metricDefIds.add(metricDefId); } } return metricDefIds; } private Integer findMetricDefId(Set<MeasurementDefinition> measurementDefs, String name) { for (MeasurementDefinition definition : measurementDefs) { if (name.equals(definition.getName())) { return definition.getId(); } } return null; } private PlatformMetricsSummary createSummary(Resource resource, Set<MeasurementData> measurementDataSet) { PlatformMetricsSummary summary = new PlatformMetricsSummary(); summary.setResource(resource); if (null == measurementDataSet || measurementDataSet.isEmpty()) { summary.setMetricsAvailable(false); } else { summary.setIdleCPU(findMeasurementData(measurementDataSet, CPUMetric.Idle.getProperty())); summary.setSystemCPU(findMeasurementData(measurementDataSet, CPUMetric.System.getProperty())); summary.setUserCPU(findMeasurementData(measurementDataSet, CPUMetric.User.getProperty())); summary.setFreeMemory(findMeasurementData(measurementDataSet, MemoryMetric.Free.getProperty())); summary.setActualFreeMemory(findMeasurementData(measurementDataSet, MemoryMetric.ActualFree.getProperty())); summary.setUsedMemory(findMeasurementData(measurementDataSet, MemoryMetric.Used.getProperty())); summary.setActualUsedMemory(findMeasurementData(measurementDataSet, MemoryMetric.ActualUsed.getProperty())); summary.setTotalMemory(findMeasurementData(measurementDataSet, MemoryMetric.Total.getProperty())); summary.setFreeSwap(findMeasurementData(measurementDataSet, SwapMetric.Free.getProperty())); summary.setTotalSwap(findMeasurementData(measurementDataSet, SwapMetric.Total.getProperty())); summary.setUsedSwap(findMeasurementData(measurementDataSet, SwapMetric.Used.getProperty())); } return summary; } private MeasurementData findMeasurementData(Set<MeasurementData> measurementDataSet, String name) { for (MeasurementData measurementData : measurementDataSet) { if (name.equals(measurementData.getName())) { return measurementData; } } return null; } }