/* * 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.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.Enumeration; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.apache.xpath.XPathAPI; import org.hyperic.hq.appdef.shared.*; import org.hyperic.hq.autoinventory.ServerSignature; import org.hyperic.sigar.NetFlags; import org.hyperic.sigar.ProcExe; import org.hyperic.sigar.Sigar; import org.hyperic.sigar.SigarException; import org.hyperic.sigar.SigarProxy; import org.hyperic.sigar.SigarProxyCache; import org.hyperic.sigar.ptql.ProcessFinder; import org.hyperic.util.AutoApproveConfig; import org.hyperic.util.PluginLoader; import org.hyperic.util.config.ConfigOption; import org.hyperic.util.config.ConfigResponse; import org.hyperic.util.config.ConfigSchema; import org.hyperic.util.config.EncodingException; import org.hyperic.util.file.FileUtil; import org.w3c.dom.Document; import org.w3c.dom.Node; /** * Encapsulate the know-how to determine all kinds of * server-specific information about a single type of server. */ public abstract class ServerDetector extends GenericPlugin implements RuntimeDiscoverer { private static final String SERVER_SIGS = "etc/hq-server-sigs.properties"; static final String VERSION_FILE = "VERSION_FILE"; static final String INSTALLPATH_MATCH = "INSTALLPATH_MATCH"; static final String INSTALLPATH_NOMATCH = "INSTALLPATH_NOMATCH"; protected static final String INSTALLPATH = "INSTALLPATH"; protected static final String INVENTORY_ID = "INVENTORY_ID"; protected static final String AUTOINVENTORY_NAME = "AUTOINVENTORY_NAME"; private static final String[] NO_ARGS = new String[0]; private static final long[] NO_PIDS = new long[0]; private static final List NO_MODULES = Arrays.asList(NO_ARGS); private static final Set EMPTY_SET = new HashSet(0,1); private static Sigar sigarImpl = null; private static SigarProxy sigar = null; private ServerSignature sig = null; private ProductPluginManager ppm; private AutoinventoryPluginManager manager; private ConfigResponse cprops = null; private String description = null; private Properties properties; private PluginUpdater pluginUpdater = new PluginUpdater(); private AutoApproveConfig autoApproveConfig; public ServerDetector() {} public void setAutoApproveConfig(AutoApproveConfig autoApproveConfig) { this.autoApproveConfig = autoApproveConfig; } /** * @deprecated - Plugins should not use this method. * @see #discoverServers * @see #discoverServices */ public RuntimeDiscoverer getRuntimeDiscoverer() { //XXX get rid of this method. return this; } /** * If plugins do not override discoverServers or discoverServices, * returning false here will prevent those methods from being called. * * @return true by default. */ public boolean isRuntimeDiscoverySupported() { return true; } private AIPlatformValue getPlatform(HashMap platforms, String fqdn) { AIPlatformValue platform = (AIPlatformValue)platforms.get(fqdn); if (platform != null) { return platform; } platform = new AIPlatformValue(); platform.setFqdn(fqdn); platforms.put(fqdn, platform); return platform; } private RuntimeResourceReport discoverServerResources(int serverId, AIPlatformValue sPlatform, ConfigResponse config, List servers) throws PluginException { if (servers.size() == 0) { return null; } HashMap platforms = new HashMap(); RuntimeResourceReport rrr = new RuntimeResourceReport(serverId); for (int i=0; i<servers.size(); i++) { AIPlatformValue platform; ServerResource server = (ServerResource)servers.get(i); AIServerExtValue resource = (AIServerExtValue)server.getResource(); String fqdn = server.getPlatformFqdn(); if (fqdn != null) { platform = getPlatform(platforms, fqdn); } else { platform = sPlatform; platforms.put("__DEFAULT__", platform); } //this server does not have runtime ai enable since //we discovered it and its services. resource.setServicesAutomanaged(true); AIServiceValue[] services = new AIServiceValue[server.services.size()]; server.services.toArray(services); resource.setAIServiceValues(services); resource.setAiServiceTypes((AIServiceTypeValue[])server.serviceTypes. toArray(new AIServiceTypeValue[server.serviceTypes.size()])); platform.addAIServerValue(resource); } for (Iterator it=platforms.values().iterator(); it.hasNext();) { AIPlatformValue platform = (AIPlatformValue)it.next(); rrr.addAIPlatform(platform); } return rrr; } /** * @deprecated - Plugins should not use this method. * @see #discoverServers * @see #discoverServices * @see #discoverServiceTypes */ public RuntimeResourceReport discoverResources(int serverId, AIPlatformValue platform, ConfigResponse config) throws PluginException { this.cprops = null; //uncommon, weblogic, websphere and iplanet discover servers List servers = discoverServers(config); if (servers != null) { getLog().debug("discovered " + servers.size() + " servers"); return discoverServerResources(serverId, platform, config, servers); } final Set serviceTypes = discoverServiceTypes(config); final List serviceTypeValues = new ArrayList(serviceTypes.size()); for (Iterator iterator = serviceTypes.iterator();iterator.hasNext();) { final ServiceType serviceType = (ServiceType)iterator.next(); serviceType.getAIServiceTypeValue().setServerId(serverId); serviceTypeValues.add(serviceType.getAIServiceTypeValue()); } pluginUpdater.updateServiceTypes(getProductPlugin(), serviceTypes); //common case discover services only List services = discoverServices(config); if (services == null) { getLog().debug("no services discovered"); return null; } getLog().debug("discovered " + services.size() + " services"); Long timeNow = new Long(System.currentTimeMillis()); RuntimeResourceReport rrr = new RuntimeResourceReport(serverId); AIServiceValue[] values = new AIServiceValue[services.size()]; for (int i=0; i<services.size(); i++) { ServiceResource service = (ServiceResource)services.get(i); service.resource.setCTime(timeNow); //XXX do we actually need to do this? service.resource.setServerId(serverId); values[i] = service.resource; } AIServerExtValue server = new AIServerExtValue(); if (this.cprops != null) { try { server.setCustomProperties(cprops.encode()); } catch (EncodingException e) { getLog().error("Error encoding cprops: " + e.getMessage()); } } if (this.description != null) { server.setDescription(this.description); } server.setPlaceholder(true); server.setId(new Integer(serverId)); server.setAIServiceValues(values); server.setAiServiceTypes((AIServiceTypeValue[])serviceTypeValues.toArray( new AIServiceTypeValue[serviceTypeValues.size()])); platform.addAIServerValue(server); rrr.addAIPlatform(platform); return rrr; } protected void setDescription(String description) { this.description = description; } protected void setCustomProperties(ConfigResponse cprops) { this.cprops = cprops; } /** * Override to discover servers for the server type of * the plugin instance. In most cases plugins will override * discoverServices rather than this method. * The general use of this method is where a plugin * FileServerDetector or AutoServerDetector finds * the Admin server and this method discovers the managed server nodes. * Such plugins include WebLogic, WebSphere and iPlanet. * * @param config Configuration of the parent server resource. * @return List of type <a href="ServerResource">ServerResource</a> * @throws PluginException If an error occured during discovery. * @see #discoverServices * @see ServerResource * @since 1.7 */ protected List discoverServers(ConfigResponse config) throws PluginException { return null; } /** * Override to discover services for the server type of * the plugin instance. * @param config Configuration of the parent server resource. * @return List of type ServiceResource. * @throws PluginException If an error occured during discovery. */ protected List discoverServices(ConfigResponse config) throws PluginException { return null; } protected Set discoverServiceTypes(ConfigResponse config) throws PluginException { return EMPTY_SET; } public void init(PluginManager manager) throws PluginException { super.init(manager); this.manager = (AutoinventoryPluginManager)manager; this.ppm = (ProductPluginManager)manager.getParent(); this.properties = manager.getProperties(); } /** * @return The plugin manager for this plugin. */ public AutoinventoryPluginManager getManager() { return this.manager; } public String getTypeProperty(String type, String name) { //check for agent.properties override String value = this.ppm.getProperty(type + "." + name); if (value != null) { return value; } return super.getTypeProperty(type, name); } /** * Helper for RegistryServerDetector implementors. * Gets the scan keys from hq-plugin.xml */ public List getRegistryScanKeys() { if (this.data != null) { List keys = this.data.getRegistryScanKeys(getTypeInfo().getName()); if (keys != null){ return keys; } } return new ArrayList(); } /** * The server signature is defined by plugins in * etc/hq-plugin.xml if the plugin implements * FileServerDetector or RegistryServerDetector. */ public ServerSignature getServerSignature() { if (this.sig != null) { return this.sig; } //XXX we will be moving the hq-server-sigs.properties functionality //to hq-plugin.xml Properties props = loadProperties(); if (props == null) { String name = getTypeInfo().getName(); if (this.data != null) { List matches = this.data.getFileScanIncludes(name); List regkeys = this.data.getRegistryScanIncludes(name); //XXX nobody uses exclude, should we support it? this.sig = new ServerSignature(name, matches, null, regkeys); } //just need a sig w/ the server type to make the auto scan run else if (this instanceof AutoServerDetector) { this.sig = new ServerSignature(name, new String[0], new String[0], new String[0]); } else { this.sig = new ServerSignature(); } return this.sig; } List matches = new ArrayList(); List excludes = new ArrayList(); List regkeys = new ArrayList(); Enumeration propNames = props.propertyNames(); String type = getTypeInfo().getName(); String typeName = TypeInfo.formatName(type); String matchPrefix = typeName + ".filescan.include."; String excludePrefix = typeName + ".filescan.exclude."; String regMatchPrefix = typeName + ".regscan.include."; while (propNames.hasMoreElements()) { String prop = (String)propNames.nextElement(); if (prop.startsWith(matchPrefix)) { matches.add(props.getProperty(prop)); } else if (prop.startsWith(excludePrefix)) { excludes.add(props.getProperty(prop)); } else if (prop.startsWith(regMatchPrefix)) { regkeys.add(props.getProperty(prop)); } } this.sig = new ServerSignature(type, matches, excludes, regkeys); getLog().debug("Loaded ServerSignature for: " + getName()); return this.sig; } private Properties loadProperties() { InputStream is = null; ClassLoader cl = this.getClass().getClassLoader(); try { is = cl.getResourceAsStream(SERVER_SIGS); if (is == null) { return null; } Properties props = new Properties(); props.load(is); String msg = "Loaded " + SERVER_SIGS + " for: " + getName(); getLog().debug(msg); return props; } catch (IOException e) { String msg = "Unable to load " + SERVER_SIGS + " for: " + getName() + ": " + e.getMessage(); getLog().error(msg, e); return null; } finally { if (is != null) { try { is.close(); } catch (IOException e) { } } } } protected File findVersionFile(File dir, Pattern pattern) { if (dir.isDirectory() && dir.canRead()) { File[] files = dir.listFiles(); Set<File> subDirs = new HashSet<File>(); for (File file : files) { if (file.isDirectory()) { subDirs.add(file); } else if (pattern.matcher(file.getAbsolutePath()).find()) { return file; } } for (File subDir : subDirs) { File versionFile = findVersionFile(subDir, pattern); if (versionFile != null) { return versionFile; } } } else { getLog().debug("[findVersionFile] Unable to acces to '" + dir + "'"); } return null; } /** * Test if server type version filters apply: * VERSION_FILE - Return true if given file exists within installpath * INSTALLPATH_MATCH - Return true if installpath matches given substring * INSTALLPATH_NOMATCH - Return false if installpath matches given substring * @param installpath The server instance installpath * @return false installpath does not match type version criteria, true otherwise */ protected boolean isInstallTypeVersion(String installpath) { String versionFile = getTypeProperty(VERSION_FILE); String installPathMatch = getTypeProperty(INSTALLPATH_MATCH); String installPathNoMatch = getTypeProperty(INSTALLPATH_NOMATCH); if (versionFile != null) { if (versionFile.startsWith("**/")) { // recursive & regexpr versionFile=versionFile.substring(3); Pattern pattern=Pattern.compile(versionFile); File f=findVersionFile(new File(installpath),pattern); if (f==null) { return false; } getLog().debug(VERSION_FILE + "=" + versionFile + " matches -> " + f); Matcher m = pattern.matcher(f.getAbsolutePath()); m.find(); if(m.groupCount()!=0){ // have version group if(!getTypeInfo().getVersion().equals(m.group(1))){ getLog().debug(installpath + " not a match for version " + getTypeInfo().getVersion() + ", skipping"); return false; } } } else { File instPath = new File(installpath); if (instPath.isFile() && !instPath.isDirectory()) { instPath = instPath.getParentFile(); } File file = (instPath != null) ? new File(instPath, versionFile) : new File(versionFile); if (!file.exists()) { String[] expanded = PluginLoader.expand(file); if ((expanded == null) || (expanded.length == 0)) { getLog().debug(file + " does not exist, skipping"); return false; } else { getLog().debug(VERSION_FILE + "=" + versionFile + " matches -> " + expanded[0]); } } } } if (installPathMatch != null) { if (!(installpath.indexOf(installPathMatch) != -1)) { getLog().debug(installpath + " not a match for " + installPathMatch + ", skipping"); return false; } } if (installPathNoMatch != null) { if (installpath.indexOf(installPathNoMatch) != -1) { getLog().debug(installpath + " is a match for " + installPathNoMatch + ", skipping"); return false; } } return true; } /** * Initialize an ServerResource with default values. * Defaults are set for: * <ul> * <li> Type - Using getTypeInfo().getName() * <li> Name - Using getPlatformName() + " " + Type * <li> InstallPath - The installpath param passed to getCanonicalPath. * <li> Identifier - The installpath param. * </ul> * @param installpath Used to set InstallPath and Identifier */ protected ServerResource createServerResource(String installpath) { ServerResource server = new ServerResource(); String type = getTypeInfo().getName(); server.setType(type); server.setName(getPlatformName() + " " + type); //dont canonicalize relative paths, else installpath //will be made absolute relative to the agent's //working directory if (new File(installpath).isAbsolute()) { installpath = getCanonicalPath(installpath); } server.setInstallPath(installpath); //allow hardcoded property to override discovered installpath installpath = getTypeProperty(INSTALLPATH); if (installpath != null) { server.setInstallPath(installpath); } String aiid = getTypeProperty(INVENTORY_ID); if (aiid == null) { aiid = server.getInstallPath(); } server.setIdentifier(aiid); return server; } /** * @return ServiceResource with setType(this, type) */ protected ServiceResource createServiceResource(String type) { ServiceResource service = new ServiceResource(); service.setType(this, type); return service; } protected String formatName(String name, ConfigResponse parentConfig, ConfigResponse config, ConfigResponse cprops) { if (parentConfig != null) { name = Metric.translate(name, parentConfig); } if (config != null) { name = Metric.translate(name, config); } if (cprops != null) { name = Metric.translate(name, cprops); } return name; } /** * Format the auto-inventory name as defined by the plugin, for example: * <property name="AUTOINVENTORY_NAME" value="My %Name% Service @ %Location%"/> * %value%s are replaced using the ConfigResponse parameters. * @param type The resource type name used to lookup AUTOINVENTORY_NAME * @param parentConfig The platform or server configuration * @param config The server or services configuration * @param cprops Custom properties * @return The formatted name or null if AUTOINVENTORY_NAME is not defined * for the given resource type name */ protected String formatAutoInventoryName(String type, ConfigResponse parentConfig, ConfigResponse config, ConfigResponse cprops) { String name = getTypeProperty(type, AUTOINVENTORY_NAME); if (name == null) { if (cprops != null) { //defined outside plugin, e.g. process cmdline args name = cprops.getValue(AUTOINVENTORY_NAME); } if (name == null) { return null; } } return formatName(name, parentConfig, config, cprops); } /** * @see FileUtil#getParentDir(String) */ protected static String getParentDir(String path) { return FileUtil.getParentDir(path); } /** * @see FileUtil#getParentDir(String, int) */ protected static String getParentDir(String path, int levels) { return FileUtil.getParentDir(path, levels); } /** * Fixup the installpath. * Quotes are removed. * Canonicalized to removing double slashes, uppercase drive letter, etc. */ protected static String getCanonicalPath(String installpath) { if (installpath.charAt(0) == '"') { int idx = installpath.indexOf("\"", 1); if (idx == -1) { installpath = installpath.substring(1); } else { installpath = installpath.substring(1, idx); } } try { installpath = new File(installpath).getCanonicalPath(); } catch (IOException e) { } return installpath; } /** * @return A SigarProxyCache instance with an expiration time of * 10 minutes. The cache is cleared by the plugin manager after * all AutoServerDetectors have been run. */ protected static SigarProxy getSigar() { if (sigar == null) { //long timeout, we are not using this to gather metrics //but to discover running processes int timeout = 10 * 60 * 1000; //10 minutes sigarImpl = new Sigar(); sigar = SigarProxyCache.newInstance(sigarImpl, timeout); } return sigar; } protected String getListenAddress(String port) { return getListenAddress(Long.parseLong(port)); } protected String getListenAddress(long port) { String address = null; if (isNetStatEnabled()) { try { address = getSigar().getNetListenAddress(port); } catch (SigarException e) {} } else { getLog().debug("ListenAddress detection for port " + port + " is disabled"); } String type; if ((address == null) || NetFlags.isLoopback(address) || NetFlags.isAnyAddress(address)) { address = "localhost"; type = "default"; } else { type = "discovered"; } getLog().debug("ListenAddress for port " + port + "=" + address + " (" + type + ")"); return address; } static void clearSigarCache() { if (sigar == null) { return; } SigarProxyCache.clear(sigar); sigarImpl.close(); sigar = null; } /** * Wrapper for Sigar.getProcArgs which catches SigarException * and returns a String[] with length 0 if the SigarException * is caught. * @param pid Process identifier * @return Arguments that were passed to the process. */ protected static String[] getProcArgs(long pid) { try { return getSigar().getProcArgs(pid); } catch (SigarException e) { return NO_ARGS; } } /** * Wrapper for Sigar.getProcModules which catches SigarException * and returns a String[] with length 0 if the SigarException * is caught. * @param pid Process identifier */ protected static List getProcModules(long pid) { try { return getSigar().getProcModules(pid); } catch (SigarException e) { return NO_MODULES; } } protected static String getProcExe(long pid) { return getProcExe(pid, null); } /** * Attempt to find the absolute name of the process executable. * If the name cannot be determined, <code>null</code> is returned. * @param pid Process identifier * @param name Binary base name to match against * @return The process executable name. */ protected static String getProcExe(long pid, String name) { ProcExe pexe = null; try { pexe = getSigar().getProcExe(pid); String exe = pexe.getName(); if (new File(exe).exists()) { return exe; } } catch (SigarException e) { //likely permission denied } String argv0 = null; String[] args = getProcArgs(pid); if (args.length != 0) { //might not be absolute path. argv0 = args[0]; File bin = new File(argv0); if (bin.exists() && bin.isAbsolute()) { return argv0; } if (pexe != null) { //try exe.name relative to exe.cwd bin = new File(pexe.getCwd(), argv0); if (bin.exists() && bin.isAbsolute()) { try { return bin.getCanonicalPath(); } catch (IOException e) { return bin.getPath(); } } } } List modules = getProcModules(pid); if (modules.size() > 0) { if (name == null) { return (String)modules.get(0); } name = File.separator + name; for (int i=0; i<modules.size(); i++) { String bin = (String)modules.get(i); if (bin.endsWith(name)) { return bin; } } } return argv0; } /** * Attempt to get the current working directory of a process. * If the directory cannot be determined, <code>null</code> is returned. * @param pid Process identifier * @return The process current working directory. */ protected static String getProcCwd(long pid) { try { return getSigar().getProcExe(pid).getCwd(); } catch (SigarException e) { return null; } } /** * Wrapper for Sigar's ProcessFinder.find method. * @param query SIGAR Process Table Query * @return Array of pids that match the query, length == 0 if * there were no matches. */ protected static long[] getPids(String query) { try { return ProcessFinder.find(getSigar(), query); } catch (SigarException e) { return NO_PIDS; } } /** * @param name The Service name shown in the Windows service panel * Properties General tab, not the Display name. For example, * "Terminal Services" is the Display name, "TermService" is the * Service name that should be used here. * @return true If the service exists and is running, false otherwise. */ public boolean isWin32ServiceRunning(String name) { if (!isWin32()) { return false; } return Win32MeasurementPlugin.isServiceRunning(name); } public boolean isSSLPort(String port) { return port.endsWith(Collector.DEFAULT_HTTPS_PORT); } public String getConnectionProtocol(String port) { if (port.equals(Collector.DEFAULT_FTP_PORT)) { return Collector.PROTOCOL_FTP; } else { //note: for 'https' we use the 'http' protocol //with flag ssl=true return Collector.PROTOCOL_HTTP; } } /** * DocumentBuilder.parse() wrapper * @param file File to parse * @return parsed Document * @throws IOException For any exception */ protected Document getDocument(File file) throws IOException { FileInputStream fis = new FileInputStream(file); try { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); return db.parse(fis); } catch (Exception e) { throw new IOException(e.getMessage()); } finally { fis.close(); } } /** * XPathAPI.eval() wrapper. XPathAPI.eval never returns null, * however this wrapper method will return null if * XObject.toString().length() == 0 * @param node Node to search * @param xpath XPath string * @return XObject.toString() or null if Exception is caught */ protected String getXPathValue(Node node, String xpath) { try { String val = XPathAPI.eval(node, xpath).toString(); if ((val == null) || (val.length() == 0)) { return null; } return val; } catch (Exception e) { return null; } } protected String getXPathValue(File file, String xpath) { try { return getXPathValue(getDocument(file), xpath); } catch (Exception e) { return null; } } protected ConfigSchema getConfigSchema(String name, int type) { if (this.data == null) { return null; } return this.data.getConfigSchema(name, type); } private void mergeConfigDefaults(ConfigResponse config, ConfigSchema schema) { mergeConfigDefaults(config, schema, true); } private void mergeConfigDefaults(ConfigResponse config, ConfigSchema schema, boolean allowOverride) { List options = schema.getOptions(); for (int i=0; i<options.size(); i++) { ConfigOption opt = (ConfigOption)options.get(i); String key = opt.getName(); if (allowOverride) { //commandline or agent.properties String propValue = this.properties.getProperty(key); if (propValue != null) { config.setValue(key, propValue); continue; } } if (config.getValue(key) == null) { String defval = opt.getDefault(); if ((defval != null) && (defval.length() != 0)) { config.setValue(key, opt.getDefault()); } } } } //can't use PluginManager/getTypeInfo() combo since //the TypeInfo will be that of the server. lookup //directly in PluginData for services. private void mergeConfigDefaults(String name, int type, ConfigResponse config) { ConfigSchema schema = getConfigSchema(name, type); if (schema == null){ return; } mergeConfigDefaults(config, schema); } private void mergeConfigDefaults(String name, PluginManager manager, ConfigResponse config) { TypeInfo type = getTypeInfo(); ConfigSchema schema; try { GenericPlugin plugin = manager.getPlugin(name); schema = plugin.getConfigSchema(type, config); } catch (PluginNotFoundException e) { getLog().error("'" + name + "' " + manager.getName() + " plugin not found", e); return; } mergeConfigDefaults(config, schema); } /** * Merge default values from server's product ConfigSchema and * saves to ServerResource.setProductConfig. */ protected void setProductConfig(ServerResource server, ConfigResponse config) { String name = getProductPlugin(server.getType()).getName(); mergeConfigDefaults(name, this.ppm, config); AIServerValue aiServerValue = (AIServerValue) server.getResource(); String resourceName = aiServerValue.getServerTypeName(); if(autoApproveConfig!=null){ // don't needed Properties autoApproveProps = autoApproveConfig.getPropertiesForResource(resourceName); for (Object keyRef : autoApproveProps.keySet()) { String key = (String) keyRef; config.setValue(key, autoApproveProps.getProperty(key)); } } server.setProductConfig(config); } //NOTE we pass getName() to mergeConfigDefaults, important for //platform-specific ConfigSchemas /** * Merge default values from server's measurement ConfigSchema and * saves to ServerResource.setMeasurementConfig. */ protected void setMeasurementConfig(ServerResource server, ConfigResponse config) { PluginManager manager = this.ppm.getMeasurementPluginManager(); mergeConfigDefaults(getName(), manager, config); manager = this.ppm.getLogTrackPluginManager(); if (manager.getPlugins().get(getName()) != null) { mergeConfigDefaults(getName(), manager, config); } manager = this.ppm.getConfigTrackPluginManager(); if (manager.getPlugins().get(getName()) != null) { mergeConfigDefaults(getName(), manager, config); } server.setMeasurementConfig(config); } /** * Merge default values from server's Custom Properties schema and * saves to ServerResource.setCustomProperties. */ protected void setCustomProperties(ServerResource server, ConfigResponse config) { ConfigSchema cprops = getCustomPropertiesSchema(); mergeConfigDefaults(config, cprops, false); server.setCustomProperties(config); } /** * Merge default values from server's control ConfigSchema and * saves to ServerResource.setControlConfig. */ protected void setControlConfig(ServerResource server, ConfigResponse config) { PluginManager manager = this.ppm.getControlPluginManager(); mergeConfigDefaults(getName(), manager, config); server.setControlConfig(config); } /** * Merge default values from service's product ConfigSchema and * saves to ServiceResource.setProductConfig. */ protected void setProductConfig(ServiceResource service, ConfigResponse config) { mergeConfigDefaults(service.getType(), ProductPlugin.CFGTYPE_IDX_PRODUCT, config); service.setProductConfig(config); } /** * Merge default values from service's measurement ConfigSchema and * saves to ServiceResource.setMeasurementConfig. */ protected void setMeasurementConfig(ServiceResource service, ConfigResponse config) { mergeConfigDefaults(service.getType(), ProductPlugin.CFGTYPE_IDX_MEASUREMENT, config); service.setMeasurementConfig(config); } /** * Merge default values from services's control ConfigSchema and * saves to ServiceResource.setControlConfig. */ protected void setControlConfig(ServiceResource service, ConfigResponse config) { mergeConfigDefaults(service.getType(), ProductPlugin.CFGTYPE_IDX_CONTROL, config); service.setControlConfig(config); } public Map getServiceInventoryPlugins() { TypeInfo type = getTypeInfo(); return this.data.getServiceInventoryPlugins(type.getName()); } public List getServiceConfigs(String type) { return ((AutoinventoryPluginManager)getManager()). getServiceConfigs(type); } /** * * @return The order in which this ServerDetector should be executed as compared with other ServerDetectors in the same scan. * This allows for one ServerDetector to "win" if multiple plugins detect Servers with the same autoinventory identifier. * The ServerDetector that returns the lowest number will call the shots. If the same server is detected later, it will * be ignored and not sent back to the Hyperic server. */ public int getScanOrder() { return Integer.MAX_VALUE; } }