/* * NOTE: This copyright does *not* cover user programs that use HQ * program services by normal system calls through the application * program interfaces provided as part of the Hyperic Plug-in Development * Kit or the Hyperic Client Development Kit - this is merely considered * normal use of the program, and does *not* fall under the heading of * "derived work". * * Copyright (C) [2004, 2005, 2006], Hyperic, Inc. * This file is part of HQ. * * HQ is free software; you can redistribute it and/or modify * it under the terms version 2 of the GNU General Public License 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA. */ package org.hyperic.hq.product; import java.io.File; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Properties; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hyperic.hq.product.pluginxml.PluginData; import org.hyperic.util.config.ConfigResponse; import org.hyperic.util.config.ConfigSchema; public abstract class ProductPlugin extends GenericPlugin { public static final String TYPE_AUTOINVENTORY = "autoinventory"; public static final String TYPE_CONTROL = "control"; public static final String TYPE_MEASUREMENT = "measurement"; public static final String TYPE_PRODUCT = "product"; public static final String TYPE_RESPONSE_TIME = "responsetime"; public static final String TYPE_LOG_TRACK = "log_track"; public static final String TYPE_CONFIG_TRACK = "config_track"; public static final String TYPE_LIVE_DATA = "livedata"; //server import attribute propagated by ConfigManager public static final String PROP_INSTALLPATH = "installpath"; public static final String PROP_RESOURCE_NAME = "resource.name"; //platform attributes propogated by ConfigManager public static final String PROP_PLATFORM_NAME = "platform.name"; public static final String PROP_PLATFORM_TYPE = "platform.type"; public static final String PROP_PLATFORM_FQDN = "platform.fqdn"; public static final String PROP_PLATFORM_IP = "platform.ip"; public static final String PROP_PLATFORM_ID = "platform.id"; public static final String PROP_PLATFORM_MACADDR = "platform.macaddr"; public static final int DEPLOYMENT_ORDER_LAST = TypeInfo.TYPE_SERVICE + 1; //XXX could be something else for windows or in general.. //but if everything uses this constant, we can keep things consistent public static final String DEFAULT_INSTALLPATH = "/usr/local/apps"; public static final String[] TYPES = { TYPE_AUTOINVENTORY, TYPE_CONTROL, TYPE_MEASUREMENT, TYPE_PRODUCT, TYPE_RESPONSE_TIME, TYPE_LOG_TRACK, TYPE_CONFIG_TRACK, TYPE_LIVE_DATA }; public static final String[] CONFIGURABLE_TYPES = { TYPE_PRODUCT, TYPE_MEASUREMENT, TYPE_CONTROL, TYPE_RESPONSE_TIME, }; public static final int CFGTYPE_IDX_PRODUCT = 0; public static final int CFGTYPE_IDX_MEASUREMENT = 1; public static final int CFGTYPE_IDX_CONTROL = 2; public static final int CFGTYPE_IDX_RESPONSE_TIME = 3; protected ProductPluginManager manager; private static Map scriptLanguagePlugins = new HashMap(); private static final Log _log = LogFactory.getLog(ProductPlugin.class.getName()); public String getInstallPath() { //e.g. geronimo.installpath=/usr/local/geronimo-1.0 String prop = getName() + "." + PROP_INSTALLPATH; return getManager().getProperty(prop); } protected void addScriptLanguage(ScriptLanguagePlugin plugin) { scriptLanguagePlugins.put("." + plugin.getExtension(), plugin); _log.debug(ScriptLanguagePlugin.class.getName() + " " + plugin.getExtension() + " registered"); } public void init(PluginManager manager) throws PluginException { this.manager = (ProductPluginManager)manager; String installpath = getInstallPath(); if (installpath != null) { adjustClassPath(installpath); } } protected ProductPluginManager getManager() { return this.manager; } static String[] getDataClassPath(PluginData data) { if (data == null) { return new String[0]; } List cp = data.getClassPath(); if (cp == null) { return new String[0]; } return (String[])cp.toArray(new String[0]); } public String[] getClassPath(ProductPluginManager manager) { return getDataClassPath(this.data); } private static Class loadClass(ClassLoader loader, String name) throws ClassNotFoundException { try { return loader.loadClass(name); } catch (ClassNotFoundException nfe) { //provide backward compat for custom plugins //still using net.hyperic package if (name.startsWith("net.hyperic")) { String orgName = "org" + name.substring(3); try { return loader.loadClass(orgName); } catch (ClassNotFoundException e) { //fallthru } } throw nfe; } } private static Class loadJavaClass(ClassLoader loader, PluginData data, String name, String pluginName) { try { return loadClass(loader, name); } catch (ClassNotFoundException e) { //we get here if the server's implementation is a class loaded //from hq-pdk.jar rather than the plugin's ClassLoader try { _log.debug("Trying data ClassLoader to load: " + name + " for plugin " + pluginName); return loadClass(data.getClassLoader(), name); } catch (ClassNotFoundException e2) { String msg = "Unable to load " + name + " for plugin " + pluginName; if (PluginData.getServiceExtension(pluginName) == null) { _log.error(pluginName + " - " + msg); } else { //plugin class is likely in another plugin //see PluginManager.getPlugin where we try later. _log.debug(pluginName + " - " + msg + ": " + e); } return null; } } } private static Class getScriptClass(ScriptLanguagePlugin plugin, ClassLoader loader, PluginData data, String className) throws PluginException { Properties props = data.getProperties(); String script = props.getProperty(className, className); File file = new File(script); if (file.exists()) { _log.debug(className + "->" + file); } else { //unpacked from .jar XXX should not have to figure the path here String pluginName = data.getPluginName(); String work = ProductPluginManager.getPdkWorkDir() + "/" + "scripts/" + pluginName + "/" + file.getName(); _log.debug(className + " (" + pluginName + "-plugin.jar) -> " + work); file = new File(work); if (!file.exists()) { _log.error("Unable to locate: " + className); } } try { return plugin.loadClass(loader, props, file); } catch (Exception e) { throw new PluginException(e.toString(), e); } } static Class getPluginClass(ClassLoader loader, PluginData data, String name, String pluginName) { for (Iterator it = scriptLanguagePlugins.entrySet().iterator(); it.hasNext();) { Map.Entry ent = (Map.Entry)it.next(); String ext = (String)ent.getKey(); if (!name.endsWith(ext)) { continue; } ScriptLanguagePlugin plugin = (ScriptLanguagePlugin)ent.getValue(); try { return getScriptClass(plugin, loader, data, name); } catch (PluginException e) { _log.error(pluginName + " - " + e.getMessage(), e); return null; } } return loadJavaClass(loader, data, name, pluginName); } static GenericPlugin getPlugin(GenericPlugin plugin, String name, String type, TypeInfo info) { String pluginName = info.getName(); Class pluginClass = getPluginClass(plugin.getClass().getClassLoader(), plugin.data, name, pluginName); if (pluginClass == null) { return null; } try { return (GenericPlugin)pluginClass.newInstance(); } catch (Exception e) { _log.error(pluginName + " - Error creating " + pluginClass.getName() + ": " + e, e); } return null; } public GenericPlugin getPlugin(String type, TypeInfo info) { if (this.data == null) { return null; } String name = this.data.getPlugin(type, info); if (name == null) { return null; } return getPlugin(this, name, type, info); } public ConfigSchema getConfigSchema(TypeInfo info, ConfigResponse config) { if (this.data != null) { ConfigSchema schema = this.data.getConfigSchema(info, CFGTYPE_IDX_PRODUCT); if (schema != null) { return schema; } } return super.getConfigSchema(info, config); } public TypeInfo[] getTypes() { if (this.data != null) { return this.data.getTypes(); } return new TypeInfo[0]; } protected File getWorkDir(String type) { String pdk = ProductPluginManager.getPdkDir(); if (pdk == null) { return null; } return ClientPluginDeployer.getSubDirectory(pdk, type, getName()); } protected int getDeploymentOrder() { TypeInfo[] types = getTypes(); int order = DEPLOYMENT_ORDER_LAST; if (types == null) { return order; } for (TypeInfo type : types) { order = Math.min(order, type.getType()); } return order; } }