/* * RHQ Management Platform * Copyright (C) 2005-2014 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., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ package org.rhq.core.pc.util; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; import java.util.Date; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeSet; import org.rhq.core.domain.content.transfer.ResourcePackageDetails; import org.rhq.core.domain.drift.DriftDefinition; import org.rhq.core.domain.measurement.Availability; import org.rhq.core.domain.measurement.AvailabilityType; import org.rhq.core.domain.measurement.MeasurementDefinition; import org.rhq.core.domain.measurement.MeasurementScheduleRequest; import org.rhq.core.domain.operation.OperationDefinition; import org.rhq.core.domain.resource.ProcessScan; 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.pc.PluginContainer; import org.rhq.core.pc.inventory.InventoryFile; import org.rhq.core.pc.inventory.InventoryManager; import org.rhq.core.pc.inventory.ResourceContainer; import org.rhq.core.pc.plugin.PluginManager; /** * @author John Mazzitelli * @author Ian Springer */ public class InventoryPrinter { public static void outputAllResourceTypes(PrintWriter exportWriter, boolean dumpXml, Set<ResourceType> rootTypes) { if (dumpXml) { exportWriter.printf("<?xml version=\"1.0\"?>\n"); exportWriter.printf("<inventory-types>\n"); } if (rootTypes != null) { for (ResourceType rootType : rootTypes) { outputResourceType(exportWriter, dumpXml, 0, rootType); } } if (dumpXml) { exportWriter.printf("</inventory-types>\n"); } } private static void outputResourceType(PrintWriter exportWriter, boolean dumpXml, int descendantDepth, ResourceType resourceType) { StringBuilder indent = new StringBuilder(); for (int i = 0; i < descendantDepth; i++) { indent.append(" "); if (dumpXml) { indent.append(" "); // add another three spaces since XML needs more indentation } } if (dumpXml) { exportWriter.printf("%s<resource-type>\n", indent); exportWriter.printf("%s <id>%d</id>\n", indent, resourceType.getId()); exportWriter.printf("%s <name>%s</name>\n", indent, resourceType.getName()); exportWriter.printf("%s <category>%s</category>\n", indent, resourceType.getCategory()); exportWriter.printf("%s <plugin>%s</plugin>\n", indent, resourceType.getPlugin()); exportWriter.printf("%s <description>%s</description>\n", indent, resourceType.getDescription()); exportWriter.printf("%s <sub-category>%s</sub-category>\n", indent, resourceType.getSubCategory()); exportWriter.printf("%s <process-scans>\n", indent); if (resourceType.getProcessScans() != null) { for (ProcessScan processScan : resourceType.getProcessScans()) { exportWriter.printf("%s <process-scans>%s</process-scans>\n", indent, processScan); } } exportWriter.printf("%s </process-scans>\n", indent); exportWriter.printf("%s <metrics>\n", indent); if (resourceType.getMetricDefinitions() != null) { for (MeasurementDefinition def : resourceType.getMetricDefinitions()) { exportWriter.printf("%s <metric>%s</metric>\n", indent, def.getName()); } } exportWriter.printf("%s </metrics>\n", indent); exportWriter.printf("%s <operations>\n", indent); if (resourceType.getOperationDefinitions() != null) { for (OperationDefinition def : resourceType.getOperationDefinitions()) { exportWriter.printf("%s <operation>%s</operation>\n", indent, def.getName()); } } exportWriter.printf("%s </operations>\n", indent); exportWriter.printf("%s <children>\n", indent); } else { String name = resourceType.getName(); String plugin = resourceType.getPlugin(); List<String> parents = new ArrayList<String>(); for (ResourceType parent : resourceType.getParentResourceTypes()) { parents.add(parent.getName() + '(' + parent.getPlugin() + ')'); } exportWriter.printf("%s+ %s(%s), parents=%s\n", indent, name, plugin, parents); } for (ResourceType child : resourceType.getChildResourceTypes()) { outputResourceType(exportWriter, dumpXml, descendantDepth + 1, child); } if (dumpXml) { exportWriter.printf("%s </children>\n", indent); exportWriter.printf("%s</resource-type>\n", indent); } return; } public static void outputInventory(PrintWriter exportWriter, boolean xml) { // we want to recurse children outputInventory(exportWriter, true, xml); } public static void outputInventory(PrintWriter exportWriter, boolean recurseChildren, boolean xml) { outputInventory(exportWriter, recurseChildren, xml, (ResourceContainer) null); } public static void outputInventory(PrintWriter exportWriter, boolean recurseChildren, boolean xml, ResourceContainer resourceContainer) { PluginContainer pc = PluginContainer.getInstance(); outputInventory(exportWriter, recurseChildren, xml, resourceContainer, 0, pc.getPluginManager(), pc .getInventoryManager(), null, null); exportWriter.flush(); } public static void outputInventory(PrintWriter exportWriter, boolean recurseChildren, boolean xml, InventoryFile file) { PluginContainer pc = PluginContainer.getInstance(); outputInventory(exportWriter, recurseChildren, xml, null, 0, pc.getPluginManager(), pc.getInventoryManager(), file, null); exportWriter.flush(); } private static void outputInventory(PrintWriter exportWriter, boolean recurseChildren, boolean dumpXml, ResourceContainer resourceContainer, int descendantDepth, PluginManager pluginManager, InventoryManager inventoryManager, InventoryFile inventoryFile, InventoryPrinter.ResourceCounter resourceCounter) { StringBuffer indent = new StringBuffer(); for (int i = 0; i < descendantDepth; i++) { indent.append(" "); if (dumpXml) { indent.append(" "); // add another three spaces since XML needs more indentation } } if (descendantDepth == 0) { if (resourceContainer == null) { if (inventoryFile == null) { // get the in-memory inventory resourceContainer = inventoryManager.getResourceContainer(inventoryManager.getPlatform()); } else { // get the inventory found in the inventory file resourceContainer = getResourceContainer(inventoryFile.getPlatform().getId(), inventoryFile .getResourceContainers()); } } if (resourceCounter == null) { resourceCounter = new ResourceCounter(); } if (dumpXml) { exportWriter.printf("<?xml version=\"1.0\"?>\n"); exportWriter.printf("<inventory>\n"); } } if (resourceContainer == null) { exportWriter.printf("!!!RESOURCE CONTAINER IS NULL!!!"); return; } Resource resource = resourceContainer.getResource(); if (resource == null) { exportWriter.printf("!!!RESOURCE IS NULL!!!"); return; } boolean disabledResource = false; // will be true if the plugin was disabled if (pluginManager != null) { disabledResource = pluginManager.getMetadataManager().getType(resource.getResourceType()) == null; } if (!disabledResource) { resourceCounter.tallyResource(resource); Availability avail = resourceContainer.getAvailability(); AvailabilityType availType = null; if (avail != null) { availType = avail.getAvailabilityType(); } String availString = (availType == null) ? "UNKNOWN" : availType.toString(); Set<ResourcePackageDetails> installedPackages = resourceContainer.getInstalledPackages(); int installedPackageCount = installedPackages == null ? 0 : installedPackages.size(); if (dumpXml) { exportWriter.printf("%s<resource>\n", indent); exportWriter.printf("%s <id>%d</id>\n", indent, resource.getId()); exportWriter.printf("%s <key>%s</key>\n", indent, resource.getResourceKey()); exportWriter.printf("%s <name>%s</name>\n", indent, resource.getName()); exportWriter.printf("%s <version>%s</version>\n", indent, resource.getVersion()); exportWriter.printf("%s <uuid>%s</uuid>\n", indent, resource.getUuid()); exportWriter.printf("%s <mtime>%s</mtime>\n", indent, resource.getMtime()); exportWriter.printf("%s <mtime-date>%s</mtime-date>\n", indent, new Date(resource.getMtime())); exportWriter.printf("%s <description>%s</description>\n", indent, resource.getDescription()); exportWriter.printf("%s <inventory-status>%s</inventory-status>\n", indent, resource .getInventoryStatus()); exportWriter.printf("%s <type>%s</type>\n", indent, (resource.getResourceType() != null) ? resource .getResourceType().getName() : "null"); exportWriter.printf("%s <availability-type>%s</availability-type>\n", indent, availString); exportWriter.printf("%s <category>%s</category>\n", indent, (resource.getResourceType() != null) ? resource.getResourceType().getCategory() : "null"); exportWriter.printf("%s <container>\n", indent); exportWriter.printf("%s <availability>%s</availability>\n", indent, avail); exportWriter.printf("%s <state>%s</state>\n", indent, resourceContainer .getResourceComponentState()); exportWriter.printf("%s <installed-package-count>%d</installed-package-count>\n", indent, installedPackageCount); exportWriter.printf("%s <schedules>\n", indent); Set<MeasurementScheduleRequest> schedules = resourceContainer.getMeasurementSchedule(); if (schedules != null) { for (MeasurementScheduleRequest schedule : schedules) { exportWriter.printf("%s <schedule>\n", indent); exportWriter.printf("%s <schedule-id>%d</schedule-id>\n", indent, schedule .getScheduleId()); exportWriter.printf("%s <name>%s</name>\n", indent, schedule.getName()); exportWriter.printf("%s <enabled>%s</enabled>\n", indent, schedule.isEnabled()); exportWriter.printf("%s <interval>%d</interval>\n", indent, schedule.getInterval()); exportWriter.printf("%s </schedule>\n", indent); } } exportWriter.printf("%s </schedules>\n", indent); exportWriter.printf("%s <drift-definitions>\n", indent); Collection<DriftDefinition> driftDefs = resourceContainer.getDriftDefinitions(); if (driftDefs != null) { for (DriftDefinition driftDef : driftDefs) { exportWriter.printf("%s <drift-definition>\n", indent); exportWriter.printf("%s <id>%s</id>\n", indent, driftDef.getId()); exportWriter.printf("%s <name>%s</name>\n", indent, driftDef.getName()); exportWriter.printf("%s <interval>%d</interval>\n", indent, driftDef.getInterval()); exportWriter .printf("%s <is-enabled>%s</is-enabled>\n", indent, driftDef.isEnabled()); exportWriter.printf("%s <is-attached>%s</is-attached>\n", indent, driftDef.isAttached()); exportWriter.printf("%s <is-pinned>%s</is-pinned>\n", indent, driftDef.isPinned()); exportWriter.printf("%s <drift-handling-mode>%s</drift-handling-mode>\n", indent, driftDef.getDriftHandlingMode()); exportWriter.printf("%s <compliance-status>%s</compliance-status>\n", indent, driftDef.getComplianceStatus()); exportWriter.printf("%s <base-dir>%s</base-dir>\n", indent, stringifyBaseDir(driftDef)); exportWriter.printf("%s <includes>%s</includes>\n", indent, driftDef.getIncludes()); exportWriter.printf("%s <excludes>%s</excludes>\n", indent, driftDef.getExcludes()); exportWriter.printf("%s </drift-definition>\n", indent); } } exportWriter.printf("%s </drift-definitions>\n", indent); exportWriter.printf("%s </container>\n", indent); if (recurseChildren) { exportWriter.printf("%s <children>\n", indent); } } else { Set<MeasurementScheduleRequest> schedules = resourceContainer.getMeasurementSchedule(); int enabled = 0; if (schedules != null) { for (MeasurementScheduleRequest schedule : schedules) { enabled += (schedule.isEnabled()) ? 1 : 0; } } exportWriter.printf("%s+ %s (sync=%s, state=%s, avail=%s, sched=%d/%d)\n", indent, resource, resourceContainer.getSynchronizationState(), resourceContainer.getResourceComponentState(), availString, enabled, (schedules != null) ? schedules.size() : 0); } if (recurseChildren) { Set<Resource> children = new TreeSet<Resource>(new Comparator<Resource>() { public int compare(Resource o1, Resource o2) { int result = o1.getResourceType().compareTo(o2.getResourceType()); if (result == 0) { // The types are the same - let the Resource.compareTo() break the tie. result = o1.compareTo(o2); } return result; } }); // wrap in new TreeSet to avoid CCMEs and to sort by type children.addAll(resource.getChildResources()); for (Resource child : children) { ResourceContainer childContainer; if (inventoryFile == null) { // get the child from the in-memory inventory childContainer = inventoryManager.getResourceContainer(child); } else { // get the child from the inventory found in the file childContainer = getResourceContainer(child.getId(), inventoryFile.getResourceContainers()); } // recursively call ourselves outputInventory(exportWriter, recurseChildren, dumpXml, childContainer, descendantDepth + 1, pluginManager, inventoryManager, inventoryFile, resourceCounter); } } if (dumpXml) { if (recurseChildren) { exportWriter.printf("%s </children>\n", indent); } exportWriter.printf("%s</resource>\n", indent); } } if (descendantDepth == 0) { if (dumpXml) { exportWriter.printf("</inventory>\n"); } else { exportWriter.printf("\nTotal Resources: %d (%d Platforms, %d Servers, %d Services)\n", resourceCounter .getTotalCount(), resourceCounter.getPlatformCount(), resourceCounter.getServerCount(), resourceCounter.getServiceCount()); } } return; } private static String stringifyBaseDir(DriftDefinition driftDef) { try { return driftDef.getBasedir().toString(); } catch (Exception e) { // there are several reasons why getBaseDir would throw an exception - reason is in the exception message return "BAD BASEDIR: " + e.toString(); } } /** * Finds the given resource in the map of containers - each container's resource is examined and the one whose * resource ID matches <code>resourceId</code> is returned. * * @param resourceId * @param containers * * @return the found container or <code>null</code> if there is none with the given resource ID */ private static ResourceContainer getResourceContainer(Integer resourceId, Map<String, ResourceContainer> containers) { for (ResourceContainer container : containers.values()) { if (resourceId.equals(container.getResource().getId())) { return container; } } return null; } public static class ResourceCounter { private int totalCount; private int platformCount; private int serverCount; private int serviceCount; public void tallyResource(Resource resource) { if (resource == null) { return; } totalCount++; if (resource.getResourceType() == null) { return; } ResourceCategory category = resource.getResourceType().getCategory(); switch (category) { case PLATFORM: platformCount++; break; case SERVER: serverCount++; break; case SERVICE: serviceCount++; break; } } public int getTotalCount() { return totalCount; } public int getPlatformCount() { return platformCount; } public int getServerCount() { return serverCount; } public int getServiceCount() { return serviceCount; } } }