Search in sources :

Example 1 with TimeoutTracker

use of org.opennms.core.utils.TimeoutTracker in project opennms by OpenNMS.

the class TimeoutTrackerTest method testElapsedTime.

public void testElapsedTime() throws InterruptedException {
    long sleepTime = 200L;
    Map<String, ?> emptyMap = Collections.emptyMap();
    TimeoutTracker tracker = new TimeoutTracker(emptyMap, 0, 3000);
    tracker.startAttempt();
    Thread.sleep(sleepTime, 0);
    double elapsedTimeInMillis = tracker.elapsedTimeInMillis();
    long minTime = sleepTime;
    long maxTime = 2 * sleepTime;
    assertTrue("Expected value for elapsedTimeInMillis should be greater than " + minTime, elapsedTimeInMillis > (minTime - 1));
    assertTrue("Expected value for elapsedTimeInMillis should be less than " + maxTime, elapsedTimeInMillis < (maxTime + 1));
}
Also used : TimeoutTracker(org.opennms.core.utils.TimeoutTracker)

Example 2 with TimeoutTracker

use of org.opennms.core.utils.TimeoutTracker in project opennms by OpenNMS.

the class SshIT method setUp.

@Override
public void setUp() throws Exception {
    Map<String, String> parameters = new HashMap<String, String>();
    parameters.put("retries", "0");
    parameters.put("port", "22");
    parameters.put("timeout", Integer.toString(TIMEOUT));
    tt = new TimeoutTracker(parameters, 0, TIMEOUT);
    ssh = new Ssh();
    ssh.setPort(PORT);
    ssh.setTimeout(TIMEOUT);
    good = InetAddressUtils.addr(GOOD_HOST);
}
Also used : HashMap(java.util.HashMap) TimeoutTracker(org.opennms.core.utils.TimeoutTracker) Ssh(org.opennms.netmgt.poller.monitors.support.Ssh)

Example 3 with TimeoutTracker

use of org.opennms.core.utils.TimeoutTracker in project opennms by OpenNMS.

the class FtpMonitor method poll.

// read()
/**
 * {@inheritDoc}
 *
 * Poll the specified address for FTP service availability.
 *
 * During the poll an attempt is made to connect on the specified port (by
 * default TCP port 21). If the connection request is successful, the banner
 * line generated by the interface is parsed and if the extracted return
 * code indicates that we are talking to an FTP server we continue. Next, an
 * FTP 'QUIT' command is sent. Provided that the interface's response is
 * valid we set the service status to SERVICE_AVAILABLE and return.
 */
@Override
public PollStatus poll(MonitoredService svc, Map<String, Object> parameters) {
    // Get the parameters
    TimeoutTracker tracker = new TimeoutTracker(parameters, DEFAULT_RETRY, DEFAULT_TIMEOUT);
    int port = ParameterMap.getKeyedInteger(parameters, "port", DEFAULT_PORT);
    String userid = ParameterMap.getKeyedString(parameters, "userid", null);
    String password = ParameterMap.getKeyedString(parameters, "password", null);
    // Extract the address
    InetAddress ipAddr = svc.getAddress();
    PollStatus serviceStatus = PollStatus.unavailable();
    for (tracker.reset(); tracker.shouldRetry() && !serviceStatus.isAvailable(); tracker.nextAttempt()) {
        LOG.debug("FtpMonitor.poll: Polling interface: {} {}", InetAddressUtils.str(ipAddr), tracker);
        Socket socket = null;
        try {
            // create a connected socket
            tracker.startAttempt();
            socket = new Socket();
            socket.connect(new InetSocketAddress(ipAddr, port), tracker.getConnectionTimeout());
            socket.setSoTimeout(tracker.getSoTimeout());
            LOG.debug("FtpMonitor: connected to host: {} on port: {}", ipAddr, port);
            // We're connected, so upgrade status to unresponsive
            serviceStatus = PollStatus.unresponsive();
            BufferedReader lineRdr = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            FtpResponse bannerResponse = FtpResponse.readResponse(lineRdr);
            if (bannerResponse.isSuccess()) {
                // Attempt to login if userid and password available
                boolean loggedInSuccessfully = false;
                LOG.debug("FtpMonitor: Banner response successful.");
                if (userid == null || userid.length() == 0 || password == null || password.length() == 0) {
                    loggedInSuccessfully = true;
                } else {
                    FtpResponse.sendCommand(socket, "USER " + userid);
                    FtpResponse userResponse = FtpResponse.readResponse(lineRdr);
                    if (userResponse.isSuccess() || userResponse.isIntermediate()) {
                        LOG.debug("FtpMonitor: User response successful.");
                        FtpResponse.sendCommand(socket, "PASS " + password);
                        FtpResponse passResponse = FtpResponse.readResponse(lineRdr);
                        if (passResponse.isSuccess()) {
                            LOG.debug("FtpMonitor.poll: Login successful, parsed return code: {}", passResponse.getCode());
                            loggedInSuccessfully = true;
                        } else {
                            LOG.debug("FtpMonitor.poll: Login failed, parsed return code: {}, full response: {}", passResponse.getCode(), passResponse);
                            loggedInSuccessfully = false;
                        }
                    }
                }
                // Store the response time before we try to quit
                double responseTime = tracker.elapsedTimeInMillis();
                if (loggedInSuccessfully) {
                    FtpResponse.sendCommand(socket, "QUIT");
                    FtpResponse quitResponse = FtpResponse.readResponse(lineRdr);
                    /*
                         * Special Cases for success:
                         * 
                         * Also want to accept the following
                         * ERROR message generated by some FTP servers
                         * following a QUIT command without a previous
                         * successful login:
                         *
                         * "530 QUIT : User not logged in. Please login with
                         * USER and PASS first."
                         * 
                         * Also want to accept the following ERROR
                         * message generated by some FTP servers following a
                         * QUIT command without a previously successful login:
                         *
                         * "425 Session is disconnected."
                         */
                    if (quitResponse.isSuccess() || (quitResponse.getCode() == 530) || (quitResponse.getCode() == 425)) {
                        serviceStatus = PollStatus.available(responseTime);
                    }
                }
            }
            /*
                 * If we get this far and the status has not been set
                 * to available, then something didn't verify during
                 * the banner checking or login/QUIT command process.
                 */
            if (!serviceStatus.isAvailable()) {
                serviceStatus = PollStatus.unavailable();
            }
        } catch (NumberFormatException e) {
            String reason = "NumberFormatException while polling address: " + ipAddr;
            LOG.debug(reason, e);
            serviceStatus = PollStatus.unavailable(reason);
        } catch (NoRouteToHostException e) {
            String reason = "No route to host exception for address: " + ipAddr;
            LOG.debug(reason, e);
            serviceStatus = PollStatus.unavailable(reason);
        } catch (InterruptedIOException e) {
            String reason = "did not connect to host with " + tracker;
            LOG.debug(reason);
            serviceStatus = PollStatus.unavailable(reason);
        } catch (ConnectException e) {
            String reason = "Connection exception for address: " + ipAddr;
            LOG.debug(reason, e);
            serviceStatus = PollStatus.unavailable(reason);
        } catch (IOException e) {
            String reason = "IOException while polling address: " + ipAddr;
            LOG.debug(reason, e);
            serviceStatus = PollStatus.unavailable(reason);
        } finally {
            try {
                // Close the socket
                if (socket != null) {
                    socket.close();
                }
            } catch (IOException e) {
                LOG.debug("FtpMonitor.poll: Error closing socket", e);
            }
        }
    }
    return serviceStatus;
}
Also used : InterruptedIOException(java.io.InterruptedIOException) PollStatus(org.opennms.netmgt.poller.PollStatus) InputStreamReader(java.io.InputStreamReader) InetSocketAddress(java.net.InetSocketAddress) IOException(java.io.IOException) InterruptedIOException(java.io.InterruptedIOException) NoRouteToHostException(java.net.NoRouteToHostException) FtpResponse(org.opennms.netmgt.poller.monitors.support.FtpResponse) TimeoutTracker(org.opennms.core.utils.TimeoutTracker) BufferedReader(java.io.BufferedReader) InetAddress(java.net.InetAddress) Socket(java.net.Socket) ConnectException(java.net.ConnectException)

Example 4 with TimeoutTracker

use of org.opennms.core.utils.TimeoutTracker in project opennms by OpenNMS.

the class GpMonitor method poll.

// read()
/**
 * {@inheritDoc}
 *
 * Poll the specified address for service availability.
 *
 * During the poll an attempt is made to call the specified external script
 * or program. If the connection request is successful, the banner line
 * returned as standard output by the script or program is parsed for a
 * partial match with the banner string specified in the poller
 * configuration. Provided that the script's response is valid we set the
 * service status to SERVICE_AVAILABLE and return.
 *
 * The timeout is handled by ExecRunner and is also passed as a parameter to
 * the script or program being called.
 */
@Override
public PollStatus poll(MonitoredService svc, Map<String, Object> parameters) {
    LOG.warn("GpMonitor: This poller monitor is deprecated in favor of SystemExecuteMonitor. GpMonitor will be removed in a future release.");
    // 
    // Process parameters
    // 
    TimeoutTracker tracker = new TimeoutTracker(parameters, DEFAULT_RETRY, DEFAULT_TIMEOUT);
    String hoption = ParameterMap.getKeyedString(parameters, "hoption", "--hostname");
    String toption = ParameterMap.getKeyedString(parameters, "toption", "--timeout");
    // 
    // convert timeout to seconds for ExecRunner
    // 
    String args = ParameterMap.getKeyedString(parameters, "args", null);
    // Script
    // 
    String script = ParameterMap.getKeyedString(parameters, "script", null);
    if (script == null) {
        throw new RuntimeException("GpMonitor: required parameter 'script' is not present in supplied properties.");
    }
    // BannerMatch
    // 
    String strBannerMatch = (String) parameters.get("banner");
    // Script standard output
    // 
    String scriptoutput = "";
    // Script error output
    // 
    String scripterror = "";
    // Get the address instance.
    // 
    InetAddress ipAddr = svc.getAddress();
    final String hostAddress = InetAddressUtils.str(ipAddr);
    LOG.debug("poll: address = {}, script = {}, arguments = {}, {}", hostAddress, script, args, tracker);
    // Give it a whirl
    // 
    PollStatus serviceStatus = PollStatus.unavailable();
    for (tracker.reset(); tracker.shouldRetry() && !serviceStatus.isAvailable(); tracker.nextAttempt()) {
        try {
            tracker.startAttempt();
            int exitStatus = 100;
            // Some scripts, such as Nagios check scripts, look for -H and -t versus --hostname and
            // --timeout. If the optional parameter option-type is set to short, then the former
            // will be used.
            int timeoutInSeconds = (int) tracker.getTimeoutInSeconds();
            ExecRunner er = new ExecRunner();
            er.setMaxRunTimeSecs(timeoutInSeconds);
            if (args == null)
                exitStatus = er.exec(script + " " + hoption + " " + hostAddress + " " + toption + " " + timeoutInSeconds);
            else
                exitStatus = er.exec(script + " " + hoption + " " + hostAddress + " " + toption + " " + timeoutInSeconds + " " + args);
            double responseTime = tracker.elapsedTimeInMillis();
            if (exitStatus != 0) {
                scriptoutput = er.getOutString();
                String reason = script + " failed with exit code " + exitStatus + ". Standard out: " + scriptoutput;
                LOG.debug(reason);
                serviceStatus = PollStatus.unavailable(reason);
            }
            if (er.isMaxRunTimeExceeded()) {
                String reason = script + " failed. Timeout exceeded";
                LOG.debug(reason);
                serviceStatus = PollStatus.unavailable(reason);
            } else {
                if (exitStatus == 0) {
                    scriptoutput = er.getOutString();
                    scripterror = er.getErrString();
                    if (!scriptoutput.equals(""))
                        LOG.debug("{} output  = {}", script, scriptoutput);
                    else
                        LOG.debug("{} returned no output", script);
                    if (!scripterror.equals(""))
                        LOG.debug("{} error = {}", script, scripterror);
                    if (strBannerMatch == null || strBannerMatch.equals("*")) {
                        serviceStatus = PollStatus.available(responseTime);
                    } else {
                        if (scriptoutput.indexOf(strBannerMatch) > -1) {
                            serviceStatus = PollStatus.available(responseTime);
                        } else {
                            serviceStatus = PollStatus.unavailable(script + "banner not contained in output banner='" + strBannerMatch + "' output='" + scriptoutput + "'");
                        }
                    }
                }
            }
        } catch (ArrayIndexOutOfBoundsException e) {
            String reason = script + " ArrayIndexOutOfBoundsException";
            LOG.debug(reason, e);
            serviceStatus = PollStatus.unavailable(reason);
        } catch (IOException e) {
            String reason = "IOException occurred. Check for proper operation of " + script;
            LOG.debug(reason, e);
            serviceStatus = PollStatus.unavailable(reason);
        } catch (Throwable e) {
            String reason = script + "Exception occurred";
            LOG.debug(reason, e);
            serviceStatus = PollStatus.unavailable(reason);
        }
    }
    // 
    // return the status of the service
    // 
    LOG.debug("poll: GP - serviceStatus= {} {}", serviceStatus, hostAddress);
    return serviceStatus;
}
Also used : ExecRunner(org.opennms.core.utils.ExecRunner) PollStatus(org.opennms.netmgt.poller.PollStatus) TimeoutTracker(org.opennms.core.utils.TimeoutTracker) IOException(java.io.IOException) InetAddress(java.net.InetAddress)

Example 5 with TimeoutTracker

use of org.opennms.core.utils.TimeoutTracker in project opennms by OpenNMS.

the class HostResourceSwRunMonitor method poll.

/**
 * {@inheritDoc}
 *
 * <P>
 * The poll() method is responsible for polling the specified address for
 * SNMP service availability.
 * </P>
 * @exception RuntimeException
 *                Thrown for any uncrecoverable errors.
 */
@Override
public PollStatus poll(MonitoredService svc, Map<String, Object> parameters) {
    InetAddress ipaddr = svc.getAddress();
    // Retrieve this interface's SNMP peer object
    // 
    final SnmpAgentConfig agentConfig = getAgentConfig(svc, parameters);
    final String hostAddress = InetAddressUtils.str(ipaddr);
    LOG.debug("poll: setting SNMP peer attribute for interface {}", hostAddress);
    // Get configuration parameters
    // 
    // This should never need to be overridden, but it can be in order to be used with similar tables.
    String serviceNameOid = ParameterMap.getKeyedString(parameters, "service-name-oid", HOSTRESOURCE_SW_NAME_OID);
    // This should never need to be overridden, but it can be in order to be used with similar tables.
    String serviceStatusOid = ParameterMap.getKeyedString(parameters, "service-status-oid", HOSTRESOURCE_SW_STATUS_OID);
    // This is the string that represents the service name to be monitored.
    String serviceName = ParameterMap.getKeyedString(parameters, "service-name", null);
    // The service name may appear in the table more than once. If this is set to true, all values must match the run level.
    String matchAll = ParameterMap.getKeyedString(parameters, "match-all", "false");
    // This is one of:
    // running(1),
    // runnable(2),    -- waiting for resource
    // -- (i.e., CPU, memory, IO)
    // notRunnable(3), -- loaded but waiting for event
    // invalid(4)      -- not loaded
    // 
    // This represents the maximum run-level, i.e. 2 means either running(1) or runnable(2) pass.
    String runLevel = ParameterMap.getKeyedString(parameters, "run-level", "2");
    // If "match-all" is true, there can be an optional "min-services" and "max-services" parameters that can define a range. The service is up if:
    // a) services_count >= min-services and services_count <= max-services
    // b) either one is not defined, then only one has to pass.
    // c) neither are defined, the monitor acts just like it used to - checking all instances to see if they are all running.
    // It is assumed that all services would have to pass the minimum run state test, no matter what the count.
    int minServices = ParameterMap.getKeyedInteger(parameters, "min-services", -1);
    int maxServices = ParameterMap.getKeyedInteger(parameters, "max-services", -1);
    // set timeout and retries on SNMP peer object
    // 
    agentConfig.setTimeout(ParameterMap.getKeyedInteger(parameters, "timeout", agentConfig.getTimeout()));
    agentConfig.setRetries(ParameterMap.getKeyedInteger(parameters, "retry", ParameterMap.getKeyedInteger(parameters, "retries", agentConfig.getRetries())));
    agentConfig.setPort(ParameterMap.getKeyedInteger(parameters, "port", agentConfig.getPort()));
    LOG.debug("poll: service= SNMP address= {}", agentConfig);
    PollStatus status = PollStatus.unavailable("HostResourceSwRunMonitor service not found, addr=" + hostAddress + ", service-name=" + serviceName);
    // Establish SNMP session with interface
    // 
    int matches = 0;
    try {
        LOG.debug("HostResourceSwRunMonitor.poll: SnmpAgentConfig address: {}", agentConfig);
        if (serviceName == null) {
            status.setReason("HostResourceSwRunMonitor no service-name defined, addr=" + hostAddress);
            LOG.warn("HostResourceSwRunMonitor.poll: No Service Name Defined! ");
            return status;
        }
        if (minServices > 0 && maxServices > 0 && minServices >= maxServices) {
            String reason = "min-services(" + minServices + ") should be less than max-services(" + maxServices + ")";
            status.setReason("HostResourceSwRunMonitor " + reason + ", addr=" + hostAddress + ", service-name=" + serviceName);
            LOG.warn("HostResourceSwRunMonitor.poll: {}.", reason);
            return status;
        }
        // This updates two maps: one of instance and service name, and one of instance and status.
        final SnmpObjId serviceNameOidId = SnmpObjId.get(serviceNameOid);
        final SnmpObjId serviceStatusOidId = SnmpObjId.get(serviceStatusOid);
        final Map<SnmpInstId, SnmpValue> nameResults = new HashMap<SnmpInstId, SnmpValue>();
        final Map<SnmpInstId, SnmpValue> statusResults = new HashMap<SnmpInstId, SnmpValue>();
        RowCallback callback = new RowCallback() {

            @Override
            public void rowCompleted(SnmpRowResult result) {
                nameResults.put(result.getInstance(), result.getValue(serviceNameOidId));
                statusResults.put(result.getInstance(), result.getValue(serviceStatusOidId));
            }
        };
        TimeoutTracker tracker = new TimeoutTracker(parameters, agentConfig.getRetries(), agentConfig.getTimeout());
        tracker.reset();
        tracker.startAttempt();
        TableTracker tableTracker = new TableTracker(callback, serviceNameOidId, serviceStatusOidId);
        try (SnmpWalker walker = SnmpUtils.createWalker(agentConfig, "HostResourceSwRunMonitor", tableTracker)) {
            walker.start();
            walker.waitFor();
            String error = walker.getErrorMessage();
            if (error != null && !error.trim().equals("")) {
                LOG.warn(error);
                return PollStatus.unavailable(error);
            }
        }
        // Iterate over the list of running services
        for (SnmpInstId nameInstance : nameResults.keySet()) {
            final SnmpValue name = nameResults.get(nameInstance);
            final SnmpValue value = statusResults.get(nameInstance);
            // See if the service name is in the list of running services
            if (name != null && value != null && match(serviceName, StringUtils.stripExtraQuotes(name.toString()))) {
                matches++;
                LOG.debug("poll: HostResourceSwRunMonitor poll succeeded, addr={}, service-name={}, value={}", hostAddress, serviceName, nameResults.get(nameInstance));
                // Using the instance of the service, get its status and see if it meets the criteria
                if (meetsCriteria(value, "<=", runLevel)) {
                    status = PollStatus.available(tracker.elapsedTimeInMillis());
                    // If we get here, that means the service passed the criteria, if only one match is desired we exit.
                    if ("false".equals(matchAll)) {
                        return status;
                    }
                // if we get here, that means the meetsCriteria test failed.
                } else {
                    String reason = "HostResourceSwRunMonitor poll failed, addr=" + hostAddress + ", service-name=" + serviceName + ", status=" + statusResults.get(nameInstance);
                    LOG.debug(reason);
                    status = PollStatus.unavailable(reason);
                    return status;
                }
            }
        }
        LOG.debug("poll: HostResourceSwRunMonitor the number of matches found for {} was {}", serviceName, matches);
    } catch (NumberFormatException e) {
        String reason = "Number operator used on a non-number " + e.getMessage();
        LOG.debug(reason);
        status = PollStatus.unavailable(reason);
    } catch (IllegalArgumentException e) {
        String reason = "Invalid SNMP Criteria: " + e.getMessage();
        LOG.debug(reason);
        status = PollStatus.unavailable(reason);
    } catch (Throwable t) {
        String reason = "Unexpected exception during SNMP poll of interface " + hostAddress;
        LOG.debug(reason, t);
        status = PollStatus.unavailable(reason);
    }
    // This will be executed only if match-all=true
    boolean minOk = minServices > 0 ? matches >= minServices : true;
    boolean maxOk = maxServices > 0 ? matches <= maxServices : true;
    if (!minOk && maxServices < 0) {
        // failed min-services only
        String reason = "HostResourceSwRunMonitor poll failed: service-count(" + matches + ") >= min-services(" + minServices + "), addr=" + hostAddress + ", service-name=" + serviceName;
        LOG.debug(reason);
        status = PollStatus.unavailable(reason);
    }
    if (!maxOk && minServices < 0) {
        // failed max-services only
        String reason = "HostResourceSwRunMonitor poll failed: service-count(" + matches + ") <= max-services(" + maxServices + "), addr=" + hostAddress + ", service-name=" + serviceName;
        LOG.debug(reason);
        status = PollStatus.unavailable(reason);
    }
    if ((!minOk || !maxOk) && minServices > 0 && maxServices > 0) {
        // failed both (bad range)
        String reason = "HostResourceSwRunMonitor poll failed: min-services(" + minServices + ") >= service-count(" + matches + ") <= max-services(" + maxServices + "), addr=" + hostAddress + ", service-name=" + serviceName;
        LOG.debug(reason);
        status = PollStatus.unavailable(reason);
    }
    return status;
}
Also used : RowCallback(org.opennms.netmgt.snmp.RowCallback) SnmpAgentConfig(org.opennms.netmgt.snmp.SnmpAgentConfig) SnmpRowResult(org.opennms.netmgt.snmp.SnmpRowResult) PollStatus(org.opennms.netmgt.poller.PollStatus) SnmpWalker(org.opennms.netmgt.snmp.SnmpWalker) HashMap(java.util.HashMap) SnmpObjId(org.opennms.netmgt.snmp.SnmpObjId) SnmpValue(org.opennms.netmgt.snmp.SnmpValue) TableTracker(org.opennms.netmgt.snmp.TableTracker) TimeoutTracker(org.opennms.core.utils.TimeoutTracker) SnmpInstId(org.opennms.netmgt.snmp.SnmpInstId) InetAddress(java.net.InetAddress)

Aggregations

TimeoutTracker (org.opennms.core.utils.TimeoutTracker)42 PollStatus (org.opennms.netmgt.poller.PollStatus)29 InetAddress (java.net.InetAddress)24 IOException (java.io.IOException)16 InterruptedIOException (java.io.InterruptedIOException)13 ConnectException (java.net.ConnectException)13 NoRouteToHostException (java.net.NoRouteToHostException)13 InetSocketAddress (java.net.InetSocketAddress)11 Socket (java.net.Socket)11 InputStreamReader (java.io.InputStreamReader)7 BufferedReader (java.io.BufferedReader)6 HashMap (java.util.HashMap)4 MalformedURLException (java.net.MalformedURLException)3 Pattern (java.util.regex.Pattern)3 HostRuntimeInfo (com.vmware.vim25.HostRuntimeInfo)2 HostSystemPowerState (com.vmware.vim25.HostSystemPowerState)2 HostSystem (com.vmware.vim25.mo.HostSystem)2 SocketTimeoutException (java.net.SocketTimeoutException)2 RemoteException (java.rmi.RemoteException)2 Properties (java.util.Properties)2