org.hyperic.hq.autoinventory.agent.server.AICommandsService.java Source code

Java tutorial

Introduction

Here is the source code for org.hyperic.hq.autoinventory.agent.server.AICommandsService.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-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.autoinventory.agent.server;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeSet;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hyperic.hq.agent.AgentRemoteException;
import org.hyperic.hq.agent.AgentRemoteValue;
import org.hyperic.hq.autoinventory.AutoinventoryException;
import org.hyperic.hq.autoinventory.ScanConfiguration;
import org.hyperic.hq.autoinventory.ScanConfigurationCore;
import org.hyperic.hq.autoinventory.ScanManager;
import org.hyperic.hq.autoinventory.ScanMethod;
import org.hyperic.hq.autoinventory.ScanState;
import org.hyperic.hq.autoinventory.ScanStateCore;
import org.hyperic.hq.autoinventory.ServerSignature;
import org.hyperic.hq.autoinventory.agent.client.AICommandsClient;
import org.hyperic.hq.autoinventory.agent.client.AICommandsUtils;
import org.hyperic.hq.autoinventory.scanimpl.NullScan;
import org.hyperic.hq.autoinventory.scanimpl.WindowsRegistryScan;
import org.hyperic.hq.product.AutoServerDetector;
import org.hyperic.hq.product.AutoinventoryPluginManager;
import org.hyperic.hq.product.GenericPlugin;
import org.hyperic.hq.product.HypericOperatingSystem;
import org.hyperic.hq.product.PlatformDetector;
import org.hyperic.hq.product.ProductPlugin;
import org.hyperic.hq.product.RegistryServerDetector;
import org.hyperic.hq.product.ServerDetector;
import org.hyperic.hq.product.TypeInfo;
import org.hyperic.util.ArrayUtil;
import org.hyperic.util.config.ConfigResponse;

/**
 * The AI Commands service.
 */
public class AICommandsService implements AICommandsClient {

    private static final Log _log = LogFactory.getLog(AICommandsService.class);

    private final AutoinventoryPluginManager _pluginManager;
    private final RuntimeAutodiscoverer _rtAutodiscoverer;
    private final ScanManager _scanManager;

    private final Object _lock = new Object();

    private ScanState _mostRecentState;

    public AICommandsService(AutoinventoryPluginManager pluginManager, RuntimeAutodiscoverer rtAutodiscoverer,
            ScanManager scanManager) {
        _pluginManager = pluginManager;
        _rtAutodiscoverer = rtAutodiscoverer;
        _scanManager = scanManager;
    }

    /**
     * @see org.hyperic.hq.autoinventory.agent.client.AICommandsClient#getScanStatus()
     */
    public ScanStateCore getScanStatus() throws AgentRemoteException {
        return getScanStatus(true);
    }

    ScanStateCore getScanStatus(boolean interruptHangingScan) throws AgentRemoteException {

        if (interruptHangingScan) {
            _scanManager.interruptHangingScan();
        }

        ScanState state;

        try {
            state = doGetScanStatus();

            // Fix bug 7004 -- set endtime so that duration appears 
            // correctly on the serverside when viewing status
            // Fix bug 7134 -- only set endtime if the scan is not yet done
            if (!state.getIsDone())
                state.initEndTime();
        } catch (Exception e) {
            _log.error("Error getting scan state.", e);
            throw new AgentRemoteException("Error getting scan status: " + e.toString());
        }

        return state.getCore();
    }

    /**
     * @see org.hyperic.hq.autoinventory.agent.client.AICommandsClient#pushRuntimeDiscoveryConfig(int, int, java.lang.String, java.lang.String, org.hyperic.util.config.ConfigResponse)
     */
    public void pushRuntimeDiscoveryConfig(int type, int id, String typeName, String name, ConfigResponse response)
            throws AgentRemoteException {

        AgentRemoteValue args = AICommandsUtils.createArgForRuntimeDiscoveryConfig(type, id, typeName, name,
                response);
        pushRuntimeDiscoveryConfig(args, true);
    }

    void pushRuntimeDiscoveryConfig(AgentRemoteValue args, boolean interruptHangingScan)
            throws AgentRemoteException {

        if (interruptHangingScan) {
            _scanManager.interruptHangingScan();
        }

        _rtAutodiscoverer.updateConfig(args);
    }

    /**
     * @see org.hyperic.hq.autoinventory.agent.client.AICommandsClient#startScan(org.hyperic.hq.autoinventory.ScanConfigurationCore)
     */
    public void startScan(ScanConfigurationCore scanConfigCore) throws AgentRemoteException {

        startScan(scanConfigCore, true);
    }

    void startScan(ScanConfigurationCore scanConfigCore, boolean interruptHangingScan) throws AgentRemoteException {

        if (interruptHangingScan) {
            _scanManager.interruptHangingScan();
        }

        if (scanConfigCore == null) {
            throw new AgentRemoteException("No scan configuration exists.");
        }

        ScanConfiguration scanConfig = new ScanConfiguration(scanConfigCore);

        startScan(scanConfig);
    }

    void startScan(ScanConfiguration scanConfig) {
        _log.debug("[startScan] scanConfig=" + scanConfig);
        ConfigResponse platformConfig = scanConfig.getConfigResponse();
        String platformType = null;
        boolean isDefault = scanConfig.getIsDefaultScan();
        String type = isDefault ? "auto" : "user";

        ServerSignature[] autoSigs, rgySigs;

        autoSigs = rgySigs = scanConfig.getServerSignatures();

        //user scan, default to all if no servers specified.
        boolean userDefault = ((autoSigs == null) || (autoSigs.length == 0));

        if (platformConfig != null) {
            platformType = platformConfig.getValue(ProductPlugin.PROP_PLATFORM_TYPE);
        }
        if (platformType == null) {
            platformType = HypericOperatingSystem.getInstance().getName();
        }

        boolean isWin32 = PlatformDetector.isWin32(platformType);

        if (isDefault || userDefault) {
            autoSigs = getAutoScanners(platformType);

            if (isWin32) {
                rgySigs = getWindowsRegistryScanners();
            }
        }

        addScanners(scanConfig, new NullScan(), autoSigs);
        if (isWin32 && (rgySigs != null)) {
            addScanners(scanConfig, new WindowsRegistryScan(), rgySigs);
        }

        if (_log.isDebugEnabled()) {
            ServerSignature[] sigs = scanConfig.getServerSignatures();
            ArrayList types = new ArrayList();
            for (int i = 0; i < sigs.length; i++) {
                types.add(sigs[i].getServerTypeName());
            }
            _log.debug(type + " scan for: " + types);
        }

        synchronized (_scanManager) {
            _scanManager.queueScan(scanConfig);
        }
    }

    /**
     * @see org.hyperic.hq.autoinventory.agent.client.AICommandsClient#stopScan()
     */
    public void stopScan() throws AgentRemoteException {
        stopScan(true);
    }

    void stopScan(boolean interruptHangingScan) throws AgentRemoteException {
        if (interruptHangingScan) {
            _scanManager.interruptHangingScan();
        }

        try {
            if (!doStopScan()) {
                throw new AgentRemoteException("No scan is currently running.");
            }
        } catch (Exception e) {
            _log.error("Error stopping scan.", e);
            throw new AgentRemoteException("Error stopping scan: " + e.toString());
        }
    }

    void setMostRecentState(ScanState scanState) {
        synchronized (_lock) {
            _mostRecentState = scanState;
        }
    }

    private ServerSignature[] getAutoScanners(String type) {
        ArrayList sigs = new ArrayList();
        Map plugins = _pluginManager.getPlatformPlugins(type);
        //XXX hack.  we want the jboss plugin to run before tomcat
        //so jboss can drop a hint about the embedded tomcat.
        TreeSet detectors = new TreeSet(new Comparator() {
            public int compare(Object o1, Object o2) {
                String name1 = ((GenericPlugin) o1).getName();
                String name2 = ((GenericPlugin) o2).getName();
                return name1.compareTo(name2);
            }
        });

        for (Iterator i = plugins.entrySet().iterator(); i.hasNext();) {
            Map.Entry entry = (Map.Entry) i.next();
            ServerDetector detector;

            if (!(entry.getValue() instanceof ServerDetector)) {
                continue;
            }

            detector = (ServerDetector) entry.getValue();

            TypeInfo info = ((GenericPlugin) detector).getTypeInfo();

            if (info.getType() != TypeInfo.TYPE_SERVER) {
                continue;
            }

            if (!(detector instanceof AutoServerDetector)) {
                continue;
            }

            detectors.add(detector);
        }

        for (Iterator i = detectors.iterator(); i.hasNext();) {
            ServerDetector detector = (ServerDetector) i.next();
            sigs.add(detector.getServerSignature());
        }

        return (ServerSignature[]) sigs.toArray(new ServerSignature[0]);
    }

    private ServerSignature[] getWindowsRegistryScanners() {
        ArrayList sigs = new ArrayList();
        Map plugins = _pluginManager.getPlatformPlugins();

        for (Iterator it = plugins.entrySet().iterator(); it.hasNext();) {
            Map.Entry entry = (Map.Entry) it.next();
            ServerDetector detector;

            if (!(entry.getValue() instanceof RegistryServerDetector)) {
                continue;
            }

            detector = (ServerDetector) entry.getValue();

            TypeInfo info = ((GenericPlugin) detector).getTypeInfo();

            if (info.getType() != TypeInfo.TYPE_SERVER) {
                continue;
            }

            sigs.add(detector.getServerSignature());
        }

        return (ServerSignature[]) sigs.toArray(new ServerSignature[0]);
    }

    private void addScanners(ScanConfiguration scanConfig, ScanMethod method, ServerSignature[] sigs) {

        ServerSignature[] signatures = scanConfig.getServerSignatures();

        signatures = (ServerSignature[]) ArrayUtil.combine(signatures, sigs);

        scanConfig.setServerSignatures(signatures);
        scanConfig.setScanMethodConfig(method, new ConfigResponse());
    }

    /**
     * @return true if a scan was actually running, false otherwise.
     */
    private boolean doStopScan() {

        // A best-effort attempt to grab the most recent scanState we can
        try {
            doGetScanStatus();
        } catch (Exception e) {
        }

        synchronized (_scanManager) {
            try {
                return _scanManager.stopScan();

            } catch (AutoinventoryException e) {
                // Error stopping scan - restart the entire scan manager
                _log.error("Error stopping scan, restarting scan manager: " + e);
                _scanManager.shutdown(1000);
                _scanManager.startup();
            }
            return true;
        }
    }

    private ScanState doGetScanStatus() throws AutoinventoryException {

        ScanState scanState = _scanManager.getStatus();

        synchronized (_lock) {
            if (scanState == null) {
                if (_mostRecentState == null) {
                    throw new AutoinventoryException("No autoinventory scan has been started.");
                } else {
                    return _mostRecentState;
                }
            }
            _mostRecentState = scanState;
        }

        return scanState;
    }

}