/* * 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-2008], 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.exchange; import java.io.File; import java.util.ArrayList; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hyperic.hq.product.AutoServerDetector; import org.hyperic.hq.product.PluginException; import org.hyperic.hq.product.ServerDetector; import org.hyperic.hq.product.ServerResource; import org.hyperic.hq.product.ServiceResource; import org.hyperic.sigar.win32.Pdh; import org.hyperic.sigar.win32.RegistryKey; import org.hyperic.sigar.win32.Service; import org.hyperic.sigar.win32.Win32Exception; import org.hyperic.util.config.ConfigResponse; import java.util.Arrays; import java.util.Collections; public class ExchangeDetector extends ServerDetector implements AutoServerDetector { private static final String IMAP4_NAME = "IMAP4"; private static final String POP3_NAME = "POP3"; private static final String MTA_NAME = "MTA"; private static final String WEB_NAME = "Web"; private static final String TRANSPORT_NAME = "Transport"; private static final String[] TRANSPORT_PERF_SERVICES = { ExchangeUtils.SMTP_SEND, ExchangeUtils.SMTP_RECEIVE }; private static final String EXCHANGE_KEY = "SOFTWARE\\Microsoft\\Exchange\\Setup"; static final String EX = "MSExchange"; private static final String WEBMAIL = EX + " Web Mail"; private static final String EXCHANGE_IS = EX + "IS"; private static final Log log = LogFactory.getLog(ExchangeDetector.class.getName()); private boolean isExchangeServiceRunning(String name) { if(name.equals(MTA_NAME)) { return isWin32ServiceRunning(EX + "MTA"); } return isWin32ServiceRunning(name + "Svc") || isWin32ServiceRunning(EX + name); // changed // in // 2007 } private ServiceResource createService(String name) { String svcName = name; if(name.equals(MTA_NAME)) { svcName = EX + "MTA"; }else if(isWin32ServiceRunning(name + "Svc")) { svcName = name + "Svc"; }else if(isWin32ServiceRunning(EX + name)) { // changed in 2007 svcName = EX + name; }else { svcName = EX + name; } ConfigResponse cfg = new ConfigResponse(); cfg.setValue("service_name", svcName); ServiceResource service = new ServiceResource(); service.setType(this, name); service.setServiceName(name); setProductConfig(service, new ConfigResponse()); setMeasurementConfig(service, new ConfigResponse()); setControlConfig(service, cfg); log.debug("=" + svcName + "=> " + service.getProductConfig()); return service; } public List getServerResources(ConfigResponse platformConfig) throws PluginException { List servers = new ArrayList(); String exe, installpath; Service exch = null; try { exch = new Service(EXCHANGE_IS); if(exch.getStatus() != Service.SERVICE_RUNNING) { log.debug("[getServerResources] service '" + EXCHANGE_IS + "' is not RUNNING (status='" + exch.getStatusString() + "')"); return null; } exe = exch.getConfig().getExe().trim(); }catch(Win32Exception e) { log.debug("[getServerResources] Error getting '" + EXCHANGE_IS + "' service information " + e, e); return null; }finally { if(exch != null) { exch.close(); } } File bin = new File(exe).getParentFile(); installpath = bin.getParent(); if(!isInstallTypeVersion(bin.getPath())) { log.debug("[getServerResources] exchange on '" + bin + "' is not a " + getTypeInfo().getName()); return null; } // check role // if role property exists (version 2007 and up - role must be // configured as well - in registry) ServerResource server = createServerResource(installpath); ConfigResponse cprops = new ConfigResponse(); ConfigResponse productProps = new ConfigResponse(); String roleRegKeyStr = getTypeProperty(ExchangeUtils.EXCHANGE_ROLE_REG_KEY); if(roleRegKeyStr != null) { if(!ExchangeUtils.checkRoleConfiguredAndSetVersion(roleRegKeyStr, cprops)) { if(log.isDebugEnabled()) { log.debug("role configured - but not found in registry - ignoring server:" + roleRegKeyStr); } return null; } String discoverSite = getTypeProperty(ExchangeUtils.SITE_DISCOVERY); if (discoverSite!=null){ String adSiteName = ExchangeUtils.fetchActiveDirectorySiteName(); if (adSiteName!=null){ productProps.setValue(ExchangeUtils.AD_SITE_PROP, adSiteName); } } String discoverDAG = getTypeProperty(ExchangeUtils.DAG_DISCOVERY); if (discoverDAG!=null){ String dagName = ExchangeDagDetector.getDagName(installpath,getPlatformName(),20); if (dagName != null){ productProps.setValue(ExchangeUtils.DAG_NAME, dagName); } } }else { // role does not exist - old exchange? setExchangeVersion(cprops); } // XXX does not work for 64-bit exchange running 32-bit agent server.setCustomProperties(cprops); setProductConfig(server,productProps); server.setMeasurementConfig(); servers.add(server); return servers; } protected void setExchangeVersion(ConfigResponse cprops) { RegistryKey key = null; try { key = RegistryKey.LocalMachine.openSubKey(EXCHANGE_KEY); // if "configured version exists - just set it (exchange 2010..) // otherwise set version and build cprops.setValue("version", key.getStringValue("Services Version")); cprops.setValue("build", key.getStringValue("NewestBuild")); }catch(Win32Exception e) { log.debug(e, e); }finally { if(key != null) { key.close(); } } } private List<String> getServicesNames() { List<String> servicesList = null; String roleRegKeyStr = getTypeProperty(ExchangeUtils.EXCHANGE_ROLE_REG_KEY); if(roleRegKeyStr == null) { //old exchange versions servicesList = Arrays.asList(MTA_NAME, POP3_NAME, IMAP4_NAME); } else { // new versions // pop3 and imap are in client access server servicesList = new ArrayList<String>(2); servicesList.add(MTA_NAME); if ( (!getTypeInfo().getVersion().equals("2007") ) && (!getTypeInfo().getVersion().equals("2010") ) ){ //bigger than 2010 servicesList.add(TRANSPORT_NAME); } } return servicesList; } private List<String> getTransportServices() { String roleRegKeyStr = getTypeProperty(ExchangeUtils.EXCHANGE_ROLE_REG_KEY); if ((roleRegKeyStr != null) && (!getTypeInfo().getVersion().equals("2007") ) && (!getTypeInfo().getVersion().equals("2010") ) ){ // bigger than 2010 return Arrays.asList(TRANSPORT_PERF_SERVICES); } else { return Collections.emptyList(); } } @Override protected List discoverServices(ConfigResponse config) throws PluginException { List<ServiceResource> actualServices = new ArrayList<ServiceResource>(); // POP3 + IMAP4 are disabled by default, only report the services // if they are enabled and running. List<String> servicesNames = getServicesNames(); for(String name:servicesNames) { if (isExchangeServiceRunning(name)) { log.debug(name + " is running, adding to inventory"); actualServices.add(createService(name)); } else { log.debug(name + " is not running"); } } try { String[] web = Pdh.getInstances(WEBMAIL); if(web.length != 0) { actualServices.add(createService(WEB_NAME)); } // else not enabled if no counters }catch(Win32Exception e) { log.debug(e, e); } List<String> transportServices = getTransportServices(); for (String name:transportServices) { actualServices.addAll(ExchangeUtils.discoverPerfTransportServices(name, this)); } return actualServices; } }