org.hyperic.hq.plugin.dotnet.DotNetDetector.java Source code

Java tutorial

Introduction

Here is the source code for org.hyperic.hq.plugin.dotnet.DotNetDetector.java

Source

/*
 * 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.dotnet;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hyperic.util.config.ConfigResponse;
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.Win32Exception;

public class DotNetDetector extends ServerDetector implements AutoServerDetector {

    /**
     * service type, performance counter group, use service type on service
     * name, name prefix (back compatibility)
     */
    private static final String[][] aspAppServices = { { "Application", ".NET CLR Loading", "false", "" },
            { "ASP.NET App", "ASP.NET Applications", "true", "" },
            { "ASP.NET App", "ASP.NET Apps v4.0.30319", "true", "V4 " },
            { "ASP.NET App", "ASP.NET Apps v2.0.50727", "true", "V2 " } };
    static final String PROP_APP = "app.name";
    static final String PROP_PATH = "app.path";
    private static final String REG_KEY = "SOFTWARE\\Microsoft\\.NETFramework";
    private static Log log = LogFactory.getLog(DotNetDetector.class.getName());

    private RegistryKey getRegistryKey(String path) throws Win32Exception {

        return RegistryKey.LocalMachine.openSubKey(path);
    }

    protected final static String ORACLE_PROVIDER_STR = "Oracle Data Provider for .NET";
    protected final static String SQL_SERVER_PROVIDER_STR = ".NET Data Provider for SqlServer";
    protected final static String SQL_SERVER_PROVIDER_TYPE_STR = "Data Provider for SqlServer";
    protected final static String ORACLE_SERVER_PROVIDER_TYPE_STR = "Oracle Data Provider for .Net";

    private String getVersion() {
        RegistryKey key = null;
        RegistryKey versionKey = null;
        SortedSet<String> versions = new TreeSet<String>();

        try {
            key = getRegistryKey("SOFTWARE\\Microsoft\\NET Framework Setup\\NDP");
            String[] names = key.getSubKeyNames();

            for (String versionKeyName : names) {
                if (versionKeyName.startsWith("v") && !versionKeyName.startsWith("v4")) {

                    versionKey = key.openSubKey(versionKeyName);
                    findVersion(versionKey, versions);

                } else if (versionKeyName.startsWith("v4")) {
                    versionKey = key.openSubKey(versionKeyName);
                    for (String subKeyName : versionKey.getSubKeyNames()) {

                        RegistryKey subKey = versionKey.openSubKey(subKeyName);
                        findVersion(subKey, versions);

                    }

                }

            }

        } catch (Win32Exception e) {
            log.debug(e, e);
            return null;
        } finally {
            if (key != null) {
                key.close();
            }
        }

        log.debug("Found .NET versions=" + versions);
        //all runtime versions have the same metrics,
        //so just discover the highest version
        return (versions.size() > 0) ? versions.last() : "";
    }

    private void findVersion(RegistryKey versionKey, SortedSet versions) {
        String versionValue = null;
        String installPath = null;

        Pattern regex = Pattern.compile("(\\d*\\.\\d*).*");

        versionValue = versionKey.getStringValue("Version", "").trim();
        installPath = versionKey.getStringValue("InstallPath", "").trim();

        if (!"".equals(installPath)) {
            Matcher m = regex.matcher(versionValue);
            if (m.find()) {
                versions.add(m.group(1));
            }
        }
    }

    private String getInstallPath() {
        RegistryKey key = null;
        try {
            key = getRegistryKey(REG_KEY);
            return key.getStringValue("InstallRoot").trim();
        } catch (Win32Exception e) {
            return null;
        } finally {
            if (key != null) {
                key.close();
            }
        }
    }

    public List getServerResources(ConfigResponse platformConfig) throws PluginException {

        String expectedVersion = getTypeInfo().getVersion();
        String version = getVersion();
        if (version == null) {
            return null;
        }

        String path = getInstallPath();
        boolean valid = ((version.startsWith(expectedVersion)) && (path != null));

        log.debug("Found .NET version=" + version + " (expectedVersion=" + expectedVersion + "), path=" + path
                + ", valid=" + valid);

        if (!valid) {
            return null;
        }

        ServerResource server = createServerResource(path);

        server.setProductConfig();
        //server.setControlConfig(...); N/A
        server.setMeasurementConfig();

        List servers = new ArrayList();
        servers.add(server);
        return servers;
    }

    private Collection<ServiceResource> addDataProvidersServices(String dataProviderStr,
            String dataProviderTypeStr) {
        try {
            String[] instances = Pdh.getInstances(dataProviderStr);
            Pattern regex = Pattern.compile("([^\\[]*).*");
            Set<String> names = new HashSet<String>();
            for (int i = 0; i < instances.length; i++) {
                String instance = instances[i];
                Matcher m = regex.matcher(instance);
                if (m.find()) {
                    String n = m.group(1).trim();
                    log.debug("[discoverServices] instance = " + instance + " (" + n + ")");
                    if (n.length() > 0) {
                        log.debug("[discoverServices] instance = " + instance + " (" + n + ") valid.");
                        names.add(n);
                    }
                } else {
                    log.debug("[discoverServices] instance = " + instance + " skiped.");
                }
            }
            List<ServiceResource> services = new ArrayList<ServiceResource>();
            for (Iterator<String> it = names.iterator(); it.hasNext();) {
                String name = it.next();
                ServiceResource service = new ServiceResource();
                service.setType(this, dataProviderTypeStr);
                service.setServiceName(dataProviderTypeStr + " " + name);

                ConfigResponse pc = new ConfigResponse();
                pc.setValue(PROP_APP, name);
                service.setProductConfig(pc);
                service.setMeasurementConfig();
                services.add(service);
            }
            return services;
        } catch (Win32Exception e) {
            log.debug("Error getting pdh data for '.NET Data Provider for:" + dataProviderStr + ":" + e, e);
            return Collections.emptyList();
        }

    }

    @Override
    protected List discoverServices(ConfigResponse serverConfig) throws PluginException {
        List<ServiceResource> services = new ArrayList<ServiceResource>();

        //Data providers.
        services.addAll(addDataProvidersServices(SQL_SERVER_PROVIDER_STR, SQL_SERVER_PROVIDER_TYPE_STR));
        services.addAll(addDataProvidersServices(ORACLE_PROVIDER_STR, ORACLE_SERVER_PROVIDER_TYPE_STR));

        // apps
        String instancesToSkipStr = getProperties().getProperty("dotnet.instances.to.skip", "_Global_");
        List<String> instancesToSkip = Arrays.asList(instancesToSkipStr.toUpperCase().split(","));
        log.debug("dotnet.instances.to.skip = " + instancesToSkip);
        for (int i = 0; i < aspAppServices.length; i++) {
            String serviceType = aspAppServices[i][0];
            String counterName = aspAppServices[i][1];
            boolean useServiceType = aspAppServices[i][2].equals("true");

            try {
                String[] apps = Pdh.getInstances(counterName);

                for (int idx = 0; idx < apps.length; idx++) {
                    String name = apps[idx];
                    if (!instancesToSkip.contains(name.toUpperCase())) {
                        log.debug("instace '" + name + "' (" + counterName + ") valid.");
                        ServiceResource service = new ServiceResource();
                        service.setType(this, serviceType);
                        if (useServiceType) {
                            service.setServiceName(serviceType + " " + aspAppServices[i][3] + name);
                        } else {
                            service.setServiceName(name);
                        }

                        ConfigResponse pc = new ConfigResponse();
                        pc.setValue(PROP_APP, name);
                        pc.setValue(PROP_PATH, counterName);
                        service.setProductConfig(pc);

                        service.setMeasurementConfig();

                        services.add(service);
                    } else {
                        log.debug("instace '" + name + "' (" + counterName + ") skiped.");
                    }
                }
            } catch (Win32Exception e) {
                log.debug("Error getting pdh data for '" + serviceType + "': " + e, e);
            }
        }
        return services;
    }
}