/* * 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.plugins.platform; import java.net.InetAddress; import java.util.Collections; import java.util.HashSet; import java.util.Set; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.pluginapi.inventory.DiscoveredResourceDetails; import org.rhq.core.pluginapi.inventory.ResourceDiscoveryComponent; import org.rhq.core.pluginapi.inventory.ResourceDiscoveryContext; import org.rhq.core.system.SystemInfo; /** * Discovers the platform resource. This will discover one and only one resource. This is an abstract superclass to all * the natively supported platform discovery components and the fallback Java-only discovery component. * * @author John Mazzitelli */ public abstract class PlatformDiscoveryComponent implements ResourceDiscoveryComponent { /** * This will build the platform's resource details, where its name and key are by default * the plugin container's name. Subclasses of this platform discovery component * are free to override this behavior if they wish to make the platform name different, * but under normal circumstances, subclasses will not want to alter the key value. * * @see ResourceDiscoveryComponent#discoverResources(ResourceDiscoveryContext) */ public Set<DiscoveredResourceDetails> discoverResources(ResourceDiscoveryContext context) { if (!isPlatformSupported(context)) { return Collections.emptySet(); } SystemInfo systemInfo = context.getSystemInformation(); // platform resources will use the plugin container name as its key. // we are guaranteed this string is unique across all agents/plugin containers. // (it is usually the hostname, but is not guaranteed to be) String key = determineResourceKey(context); // build the resource name String name = determineResourceName(context); // use the platform type description as the description for this resource String description = context.getResourceType().getDescription(); String version; try { version = systemInfo.getOperatingSystemName() + " " + systemInfo.getOperatingSystemVersion(); } catch (Exception e) { version = "?"; } Configuration config = context.getDefaultPluginConfiguration(); discoverConfiguration(config); DiscoveredResourceDetails discoveredResource = new DiscoveredResourceDetails(context.getResourceType(), key, name, version, description, null, null); HashSet<DiscoveredResourceDetails> results = new HashSet<DiscoveredResourceDetails>(); results.add(discoveredResource); return results; } /** * Override this method to add additional configurations to discovered platforms * @param configuration */ protected void discoverConfiguration(Configuration configuration) { } /** * This will determine what the new platform's resource key should be. This default * implementation first tries to use the plugin container's name which is guaranteed * to be unique across all agents/plugin containers. If, for some odd reason, it is * <code>null</code>, the platform's hostname is used. This is less than optimal * but the plugin container's name will never be <code>null</code> under virtually * all use-cases (except perhaps in test scenarios). * * @param context the discovery context used to get the plugin container name or host name if its needed * * @return the new platform's resource key */ protected String determineResourceKey(ResourceDiscoveryContext context) { String pcName = context.getPluginContainerName(); String resourceKey = pcName; if (pcName == null) { resourceKey = getHostname(context.getSystemInformation()); } return resourceKey; } /** * This will determine what the new platform's resource name should be. This default * implementation first tries to use the plugin container's name which is guaranteed * to be unique across all agents/plugin containers. If, for some odd reason, it is * <code>null</code>, the platform's hostname is used. * * @param context the discovery context used to get the plugin container name or host name if its needed * * @return the new platform's resource key */ protected String determineResourceName(ResourceDiscoveryContext context) { String pcName = context.getPluginContainerName(); String resourceName = pcName; if (pcName == null) { resourceName = getHostname(context.getSystemInformation()); } return resourceName; } /** * Tries to determine this platform's hostname, using the (possibly native) * system info API. If, for whatever reason, this method cannot determine the * hostname, a generic "Unnamed Platform" String will be returned (this will * rarely, if ever, happen under normal situations). * * @param systemInformation * * @return the platform's hostname (will never be <code>null</code>) */ protected String getHostname(SystemInfo systemInformation) { String name; // ask the system info class to get us the hostname - possibly via the native library try { name = systemInformation.getHostname(); } catch (Exception e) { name = null; } // under certain conditions, we might not be able to natively get the hostname so try to get it via Java if (name == null) { try { name = InetAddress.getLocalHost().getHostAddress(); } catch (Exception e) { name = null; } // we fought the good fight but we just can't get this machine's hostname, give a generic platform name if (name == null) { name = "Unnamed Platform"; } } return name; } /** * Subclasses will implement this method to tell this class whether or not it can discover the platform of the * resource type found in the given context. If this returns <code>false</code>, this subclass discovery component * instance does not recognize the platform. * * <p>It is very important that all subclasses must return <code>false</code> <i>except one</i> for any given * platform. That is to say, if running on "RHEL 5", only the subclass that supports RHEL 5 must return <code> * true</code>, all others must return <code>false</code>. If running on "Windows XP", only the suclass that * supports Windows XP must return <code>true</code>. The only exception to this rule is the * {@link JavaPlatformDiscoveryComponent fallback Java platform discovery component}, which will always return * <code>true</code> because the fallback Java platform is always supported.</p> * * @param context * * @return <code>true</code> if this instance can support the platform this plugin is running on; <code>false</code> * otherwise */ protected abstract boolean isPlatformSupported(ResourceDiscoveryContext context); }