/* * 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.plugin.system; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import org.hyperic.sigar.Sigar; import org.hyperic.sigar.SigarException; import org.hyperic.sigar.win32.Service; import org.hyperic.sigar.win32.ServiceConfig; import org.hyperic.sigar.win32.Win32Exception; import org.hyperic.util.StringUtil; import org.hyperic.util.config.ConfigResponse; import org.hyperic.util.config.EncodingException; import org.hyperic.hq.appdef.shared.AIServiceValue; import org.hyperic.hq.product.MeasurementPlugin; import org.hyperic.hq.product.PluginException; import org.hyperic.hq.product.ProductPluginManager; public class WindowsDetector extends SystemServerDetector { protected String getServerType() { return SystemPlugin.WINDOWS_SERVER_NAME; } public List getServerResources(ConfigResponse platformConfig) throws PluginException { if (isWin32()) { return super.getServerResources(platformConfig); } //should not get invoked if !win32, but just incase. return null; } private boolean setCustomProperty(String type, ConfigResponse cprops, String key, String val) { //XXX code below does not work for the builtin //service type because the cprops are defined by //the SystemPlugin/ProductPlugin rather than hq-plugin.xml if (type.equals(SystemPlugin.SVC_NAME)) { cprops.setValue(key, val); return true; } ProductPluginManager manager = (ProductPluginManager)getManager().getParent(); MeasurementPlugin plugin = manager.getMeasurementPlugin(type); if (plugin == null) { return false; } if (plugin.getCustomPropertiesSchema().getOption(key) == null) { return false; } else { cprops.setValue(key, val); return true; } } private ServiceConfig setServiceInventoryProperties(String serviceName, AIServiceValue svc, boolean exists) { ConfigResponse cprops = new ConfigResponse(); ServiceConfig config; Service service = null; int status; String statusString; try { service = new Service(serviceName); config = service.getConfig(); status = service.getStatus(); statusString = service.getStatusString(); } catch (Win32Exception e) { String msg = "Error getting config for service=" + serviceName + ": " + e.getMessage(); if (exists) { log.error(msg); } else { log.debug(serviceName + " does not exist"); } return null; } finally { if (service != null){ service.close(); } } if (!exists) { if (config.getStartType() != ServiceConfig.START_AUTO) { log.debug("Skipping " + serviceName + ", start type=" + config.getStartTypeString()); return null; } if (status != Service.SERVICE_RUNNING) { log.debug("Skipping " + serviceName + ", status=" + statusString); return null; } } String desc = config.getDescription(); if (desc == null) { desc = config.getDisplayName(); } svc.setDescription(desc); String type = svc.getServiceTypeName(); setCustomProperty(type, cprops, "path", config.getPath()); setCustomProperty(type, cprops, "startupType", config.getStartTypeString()); setCustomProperty(type, cprops, "displayName", config.getDisplayName()); try { svc.setCustomProperties(cprops.encode()); } catch (EncodingException e) { log.error("Error encoding cprops: " + e.getMessage()); return null; } return config; } private AIServiceValue findWindowsService(String type, String serviceName, boolean enableControl) { AIServiceValue svc = createSystemService(type, serviceName); ServiceConfig config = setServiceInventoryProperties(serviceName, svc, false); if (config == null) { return null; } svc.setName(getFullServiceName(config.getDisplayName())); log.debug("Found service " + svc.getName() + " - " + svc.getDescription()); ConfigResponse productConfig = new ConfigResponse(); productConfig.setValue(SystemPlugin.PROP_SVC, serviceName); try { svc.setProductConfig(productConfig.encode()); svc.setMeasurementConfig(ConfigResponse.EMPTY_CONFIG); if (enableControl) { svc.setControlConfig(ConfigResponse.EMPTY_CONFIG); } } catch (EncodingException e) { log.error("Error encoding config: " + e.getMessage()); return null; } return svc; } private void discoverWindowsServices(String names, ArrayList services) throws Win32Exception { List serviceNames; if ("true".equals(names)) { serviceNames = Service.getServiceNames(); } else { serviceNames = StringUtil.explode(names, ","); } for (int i=0; i<serviceNames.size(); i++) { String name = (String)serviceNames.get(i); AIServiceValue svc = findWindowsService(SystemPlugin.SVC_NAME, name, true); if (svc != null) { services.add(svc); } } } boolean hasControlPlugin(String type) { ProductPluginManager ppm = (ProductPluginManager)getManager().getParent(); return ppm.getControlPlugin(type) != null; } private void discoverPluginServices(List services) { //auto-discovery of services (plugin defined types) Map plugins = getServiceInventoryPlugins(); if (plugins == null) { return; } for (Iterator it = plugins.keySet().iterator(); it.hasNext();) { String type = (String)it.next(); String name = getTypeProperty(type, SystemPlugin.PROP_SVC); if (name == null) { log.warn("Service type '" + type + "' has autoinventory plugin " + "without '" + SystemPlugin.PROP_SVC + "' property defined."); continue; } boolean enableControl = hasControlPlugin(type); log.debug("Looking for " + type + " service=" + name + " (control=" + enableControl + ")"); AIServiceValue svc = findWindowsService(type, name, enableControl); if (svc != null) { services.add(svc); } } } protected ArrayList getSystemServiceValues(Sigar sigar, ConfigResponse serverConfig) throws SigarException { String type = SystemPlugin.SVC_NAME; List serviceConfigs = getServiceConfigs(type); ArrayList services = new ArrayList(); //set cprops for manually create resources for (int i=0; i<serviceConfigs.size(); i++) { ConfigResponse serviceConfig = (ConfigResponse)serviceConfigs.get(i); String name = serviceConfig.getValue(SystemPlugin.PROP_RESOURCE_NAME); String serviceName = serviceConfig.getValue(SystemPlugin.PROP_SVC); AIServiceValue svc = createSystemService(type, name); setServiceInventoryProperties(serviceName, svc, true); services.add(svc); } discoverPluginServices(services); //auto-discover of any generic windows service String windowsServices = getManager().getProperty("windows.services.discover"); if (windowsServices != null) { discoverWindowsServices(windowsServices, services); } return services; } }