Search in sources :

Example 6 with TimeoutTracker

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

the class SmtpMonitor method poll.

/**
     * {@inheritDoc}
     *
     * <P>
     * Poll the specified address for SMTP service availability.
     * </P>
     *
     * <P>
     * During the poll an attempt is made to connect on the specified port (by
     * default TCP port 25). 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 SMTP server we continue. Next,
     * an SMTP 'HELO' command is sent to the interface. Again the response is
     * parsed and a return code extracted and verified. Finally, an SMTP 'QUIT'
     * command is sent. Provided that the interface's response is valid we set
     * the service status to SERVICE_AVAILABLE and return.
     * </P>
     */
@Override
public PollStatus poll(MonitoredService svc, Map<String, Object> parameters) {
    TimeoutTracker tracker = new TimeoutTracker(parameters, DEFAULT_RETRY, DEFAULT_TIMEOUT);
    int port = ParameterMap.getKeyedInteger(parameters, "port", DEFAULT_PORT);
    InetAddress ipAddr = svc.getAddress();
    final String hostAddress = InetAddressUtils.str(ipAddr);
    LOG.debug("poll: address = {}, port = {}, {}", hostAddress, port, tracker);
    PollStatus serviceStatus = PollStatus.unavailable();
    for (tracker.reset(); tracker.shouldRetry() && !serviceStatus.isAvailable(); tracker.nextAttempt()) {
        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("SmtpMonitor: connected to host: {} on port: {}", ipAddr, port);
            // We're connected, so upgrade status to unresponsive
            serviceStatus = PollStatus.unresponsive();
            // Forcing to check for CRLF instead of any other line terminator as per RFC specification
            CRLFLineReader rdr = new CRLFLineReader(new InputStreamReader(socket.getInputStream(), "ASCII"));
            //
            // Tokenize the Banner Line, and check the first
            // line for a valid return.
            //
            String banner = sendMessage(socket, rdr, null);
            LOG.debug("poll: banner = {}", banner);
            StringTokenizer t = new StringTokenizer(banner);
            int rc = Integer.parseInt(t.nextToken());
            if (rc == 220) {
                //
                // Send the HELO command
                //
                String cmd = "HELO " + LOCALHOST_NAME + "\r\n";
                socket.getOutputStream().write(cmd.getBytes());
                //
                // get the returned string, tokenize, and
                // verify the correct output.
                //
                String response = rdr.readLine();
                double responseTime = tracker.elapsedTimeInMillis();
                if (response == null) {
                    continue;
                }
                if (MULTILINE.matcher(response).find()) {
                    // Ok we have a multi-line response...first three
                    // chars of the response line are the return code.
                    // The last line of the response will start with
                    // return code followed by a space.
                    String multiLineRC = new String(response.getBytes("ASCII"), 0, 3, "ASCII");
                    // Create new regExp to look for last line
                    // of this multi line response
                    Pattern endMultiline = null;
                    try {
                        endMultiline = Pattern.compile(multiLineRC);
                    } catch (PatternSyntaxException ex) {
                        throw new java.lang.reflect.UndeclaredThrowableException(ex);
                    }
                    // response
                    do {
                        response = rdr.readLine();
                    } while (response != null && !endMultiline.matcher(response).find());
                    if (response == null) {
                        continue;
                    }
                }
                t = new StringTokenizer(response);
                rc = Integer.parseInt(t.nextToken());
                if (rc == 250) {
                    response = sendMessage(socket, rdr, "QUIT\r\n");
                    t = new StringTokenizer(response);
                    rc = Integer.parseInt(t.nextToken());
                    if (rc == 221) {
                        serviceStatus = PollStatus.available(responseTime);
                    }
                }
            } else if (rc == 554) {
                String response = sendMessage(socket, rdr, "QUIT\r\n");
                serviceStatus = PollStatus.unavailable("Server rejecting transactions with 554");
            }
            // checking or HELO/QUIT comand process.
            if (!serviceStatus.isAvailable()) {
                serviceStatus = PollStatus.unavailable(serviceStatus.getReason());
            }
        } catch (NumberFormatException e) {
            String reason = "NumberFormatException while polling address " + hostAddress;
            LOG.debug(reason, e);
            serviceStatus = PollStatus.unavailable(reason);
        } catch (NoRouteToHostException e) {
            String reason = "No route to host exception for address " + hostAddress;
            LOG.debug(reason, e);
            serviceStatus = PollStatus.unavailable(reason);
            // Break out of for(;;)
            break;
        } catch (InterruptedIOException e) {
            String reason = "Did not receive expected response within timeout " + tracker;
            LOG.debug(reason);
            serviceStatus = PollStatus.unavailable(reason);
        } catch (ConnectException e) {
            String reason = "Unable to connect to address " + hostAddress;
            LOG.debug(reason, e);
            serviceStatus = PollStatus.unavailable(reason);
        } catch (IOException e) {
            String reason = "IOException while polling address " + hostAddress;
            LOG.debug(reason, e);
            serviceStatus = PollStatus.unavailable(reason);
        } finally {
            try {
                // Close the socket
                if (socket != null) {
                    socket.close();
                }
            } catch (IOException e) {
                e.fillInStackTrace();
                LOG.debug("poll: Error closing socket.", e);
            }
        }
    }
    //
    return serviceStatus;
}
Also used : Pattern(java.util.regex.Pattern) InterruptedIOException(java.io.InterruptedIOException) PollStatus(org.opennms.netmgt.poller.PollStatus) InputStreamReader(java.io.InputStreamReader) InetSocketAddress(java.net.InetSocketAddress) CRLFLineReader(org.apache.commons.net.io.CRLFLineReader) IOException(java.io.IOException) InterruptedIOException(java.io.InterruptedIOException) NoRouteToHostException(java.net.NoRouteToHostException) StringTokenizer(java.util.StringTokenizer) TimeoutTracker(org.opennms.core.utils.TimeoutTracker) InetAddress(java.net.InetAddress) Socket(java.net.Socket) PatternSyntaxException(java.util.regex.PatternSyntaxException) ConnectException(java.net.ConnectException)

Example 7 with TimeoutTracker

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

the class SnmpMonitor method poll.

/**
     * {@inheritDoc}
     *
     * <P>
     * The poll() method is responsible for polling the specified address for
     * SNMP service availability.
     * </P>
     * @exception RuntimeException
     *                Thrown for any unrecoverable errors.
     */
@Override
public PollStatus poll(MonitoredService svc, Map<String, Object> parameters) {
    PollStatus status = PollStatus.unavailable();
    InetAddress ipaddr = svc.getAddress();
    // Retrieve this interface's SNMP peer object
    //
    final SnmpAgentConfig agentConfig = getAgentConfig(svc, parameters);
    final String hostAddress = InetAddressUtils.str(ipaddr);
    // Get configuration parameters
    //
    String oid = ParameterMap.getKeyedString(parameters, "oid", DEFAULT_OBJECT_IDENTIFIER);
    String operator = ParameterMap.getKeyedString(parameters, "operator", null);
    String operand = ParameterMap.getKeyedString(parameters, "operand", null);
    String walkstr = ParameterMap.getKeyedString(parameters, "walk", "false");
    String matchstr = ParameterMap.getKeyedString(parameters, "match-all", "true");
    int countMin = ParameterMap.getKeyedInteger(parameters, "minimum", 0);
    int countMax = ParameterMap.getKeyedInteger(parameters, "maximum", 0);
    String reasonTemplate = ParameterMap.getKeyedString(parameters, "reason-template", DEFAULT_REASON_TEMPLATE);
    String hexstr = ParameterMap.getKeyedString(parameters, "hex", "false");
    hex = "true".equalsIgnoreCase(hexstr);
    // 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()));
    // Squirrel the configuration parameters away in a Properties for later expansion if service is down
    Properties svcParams = new Properties();
    svcParams.setProperty("oid", oid);
    svcParams.setProperty("operator", String.valueOf(operator));
    svcParams.setProperty("operand", String.valueOf(operand));
    svcParams.setProperty("walk", walkstr);
    svcParams.setProperty("matchAll", matchstr);
    svcParams.setProperty("minimum", String.valueOf(countMin));
    svcParams.setProperty("maximum", String.valueOf(countMax));
    svcParams.setProperty("timeout", String.valueOf(agentConfig.getTimeout()));
    svcParams.setProperty("retry", String.valueOf(agentConfig.getRetries()));
    svcParams.setProperty("retries", svcParams.getProperty("retry"));
    svcParams.setProperty("ipaddr", hostAddress);
    svcParams.setProperty("port", String.valueOf(agentConfig.getPort()));
    svcParams.setProperty("hex", hexstr);
    //
    try {
        TimeoutTracker tracker = new TimeoutTracker(parameters, agentConfig.getRetries(), agentConfig.getTimeout());
        tracker.reset();
        tracker.startAttempt();
        SnmpObjId snmpObjectId = SnmpObjId.get(oid);
        // the parameter "matchall" to "count" will act as if "walk" has been set to "true".
        if ("count".equals(matchstr)) {
            if (DEFAULT_REASON_TEMPLATE.equals(reasonTemplate)) {
                reasonTemplate = "Value: ${matchCount} outside of range Min: ${minimum} to Max: ${maximum}";
            }
            int matchCount = 0;
            List<SnmpValue> results = SnmpUtils.getColumns(agentConfig, "snmpPoller", snmpObjectId);
            for (SnmpValue result : results) {
                if (result != null) {
                    LOG.debug("poll: SNMPwalk poll succeeded, addr={} oid={} value={}", hostAddress, oid, result);
                    if (meetsCriteria(result, operator, operand)) {
                        matchCount++;
                    }
                }
            }
            svcParams.setProperty("matchCount", String.valueOf(matchCount));
            LOG.debug("poll: SNMPwalk count succeeded, total={} min={} max={}", matchCount, countMin, countMax);
            if ((countMin <= matchCount) && (matchCount <= countMax)) {
                status = PollStatus.available(tracker.elapsedTimeInMillis());
            } else {
                String reason = PropertiesUtils.substitute(reasonTemplate, svcParams);
                LOG.debug(reason);
                status = PollStatus.unavailable(reason);
                return status;
            }
        } else if ("true".equals(walkstr)) {
            if (DEFAULT_REASON_TEMPLATE.equals(reasonTemplate)) {
                reasonTemplate = "SNMP poll failed, addr=${ipaddr} oid=${oid}";
            }
            List<SnmpValue> results = SnmpUtils.getColumns(agentConfig, "snmpPoller", snmpObjectId);
            for (SnmpValue result : results) {
                if (result != null) {
                    svcParams.setProperty("observedValue", getStringValue(result));
                    if (meetsCriteria(result, operator, operand)) {
                        status = PollStatus.available(tracker.elapsedTimeInMillis());
                        if ("false".equals(matchstr)) {
                            return status;
                        }
                    } else if ("true".equals(matchstr)) {
                        String reason = PropertiesUtils.substitute(reasonTemplate, svcParams);
                        LOG.debug(reason);
                        status = PollStatus.unavailable(reason);
                        return status;
                    }
                }
            }
        } else {
            if (DEFAULT_REASON_TEMPLATE.equals(reasonTemplate)) {
                if (operator != null) {
                    reasonTemplate = "Observed value '${observedValue}' does not meet criteria '${operator} ${operand}'";
                } else {
                    reasonTemplate = "Observed value '${observedValue}' was null";
                }
            }
            SnmpValue result = SnmpUtils.get(agentConfig, snmpObjectId);
            if (result != null) {
                svcParams.setProperty("observedValue", getStringValue(result));
                LOG.debug("poll: SNMP poll succeeded, addr={} oid={} value={}", hostAddress, oid, result);
                if (meetsCriteria(result, operator, operand)) {
                    status = PollStatus.available(tracker.elapsedTimeInMillis());
                } else {
                    status = PollStatus.unavailable(PropertiesUtils.substitute(reasonTemplate, svcParams));
                }
            } else {
                String reason = "SNMP poll failed, addr=" + hostAddress + " oid=" + oid;
                LOG.debug(reason);
                status = PollStatus.unavailable(reason);
            }
        }
    } 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);
    }
    return status;
}
Also used : SnmpAgentConfig(org.opennms.netmgt.snmp.SnmpAgentConfig) PollStatus(org.opennms.netmgt.poller.PollStatus) SnmpObjId(org.opennms.netmgt.snmp.SnmpObjId) Properties(java.util.Properties) SnmpValue(org.opennms.netmgt.snmp.SnmpValue) TimeoutTracker(org.opennms.core.utils.TimeoutTracker) List(java.util.List) InetAddress(java.net.InetAddress)

Example 8 with TimeoutTracker

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

the class SSLCertMonitor method poll.

/**
     * {@inheritDoc}
     *
     * Poll the specified address for HTTP service availability.
     *
     * During the poll an attempt is made to connect on the specified port. If
     * the connection request is successful, check the X509Certificates provided
     * by our peer and check that our time is between the certificates start and
     * end time.
     * Provided that the interface's response is valid we set the service status to
     * SERVICE_AVAILABLE and return.
     */
@Override
public PollStatus poll(final MonitoredService svc, final Map<String, Object> parameters) {
    TimeoutTracker tracker = new TimeoutTracker(parameters, DEFAULT_RETRY, DEFAULT_TIMEOUT);
    // Port
    int port = ParameterMap.getKeyedInteger(parameters, PARAMETER_PORT, DEFAULT_PORT);
    if (port == DEFAULT_PORT) {
        throw new RuntimeException("Required parameter 'port' is not present in supplied properties.");
    }
    // Remaining days
    int validityDays = ParameterMap.getKeyedInteger(parameters, PARAMETER_DAYS, DEFAULT_DAYS);
    if (validityDays <= 0) {
        throw new RuntimeException("Required parameter 'days' must be a positive value.");
    }
    // Server name (optional)
    final String serverName = PropertiesUtils.substitute(ParameterMap.getKeyedString(parameters, PARAMETER_SERVER_NAME, ""), getServiceProperties(svc));
    // Calculate validity range
    Calendar calValid = this.getCalendarInstance();
    Calendar calCurrent = this.getCalendarInstance();
    calValid.setTimeInMillis(calCurrent.getTimeInMillis());
    calValid.add(Calendar.DAY_OF_MONTH, validityDays);
    Calendar calBefore = this.getCalendarInstance();
    Calendar calAfter = this.getCalendarInstance();
    // Get the address instance
    InetAddress ipAddr = svc.getAddress();
    final String hostAddress = InetAddressUtils.str(ipAddr);
    LOG.debug("poll: address={}, port={}, serverName={}, {}", hostAddress, port, serverName, tracker);
    // Give it a whirl
    PollStatus serviceStatus = PollStatus.unavailable();
    for (tracker.reset(); tracker.shouldRetry() && !serviceStatus.isAvailable(); tracker.nextAttempt()) {
        Socket socket = null;
        try {
            tracker.startAttempt();
            socket = new Socket();
            socket.connect(new InetSocketAddress(ipAddr, port), tracker.getConnectionTimeout());
            socket.setSoTimeout(tracker.getSoTimeout());
            LOG.debug("Connected to host: {} on port: {}", ipAddr, port);
            SSLSocket sslSocket = SocketUtils.wrapSocketInSslContext(socket, null, null);
            // We're connected, so upgrade status to unresponsive
            serviceStatus = PollStatus.unresponsive();
            // Use the server name as as SNI host name if available
            if (!Strings.isNullOrEmpty(serverName)) {
                final SSLParameters sslParameters = sslSocket.getSSLParameters();
                sslParameters.setServerNames(ImmutableList.of(new SNIHostName(serverName)));
                sslSocket.setSSLParameters(sslParameters);
                // Check certificates host name
                if (!new StrictHostnameVerifier().verify(serverName, sslSocket.getSession())) {
                    serviceStatus = PollStatus.unavailable("Host name verification failed - certificate common name is invalid");
                    continue;
                }
            }
            Certificate[] certs = sslSocket.getSession().getPeerCertificates();
            for (int i = 0; i < certs.length && !serviceStatus.isAvailable(); i++) {
                if (certs[i] instanceof X509Certificate) {
                    X509Certificate certx = (X509Certificate) certs[i];
                    LOG.debug("Checking validity against dates: [current: {}, valid: {}], NotBefore: {}, NotAfter: {}", calCurrent.getTime(), calValid.getTime(), certx.getNotBefore(), certx.getNotAfter());
                    calBefore.setTime(certx.getNotBefore());
                    calAfter.setTime(certx.getNotAfter());
                    if (calCurrent.before(calBefore)) {
                        LOG.debug("Certificate is invalid, current time is before start time");
                        serviceStatus = PollStatus.unavailable("Certificate is invalid, current time is before start time");
                        break;
                    } else if (calCurrent.before(calAfter)) {
                        if (calValid.before(calAfter)) {
                            LOG.debug("Certificate is valid, and does not expire before validity check date");
                            serviceStatus = PollStatus.available(tracker.elapsedTimeInMillis());
                            break;
                        } else {
                            String reason = "Certificate is valid, but will expire in " + validityDays + " days.";
                            LOG.debug(reason);
                            serviceStatus = PollStatus.unavailable(reason);
                            break;
                        }
                    } else {
                        LOG.debug("Certificate has expired.");
                        serviceStatus = PollStatus.unavailable("Certificate has expired.");
                        break;
                    }
                }
            }
        } catch (NoRouteToHostException e) {
            String reason = "No route to host exception for address " + hostAddress;
            LOG.debug(reason, e);
            serviceStatus = PollStatus.unavailable(reason);
            // Break out of for(;;)
            break;
        } 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 {
                if (socket != null) {
                    socket.close();
                }
            } catch (IOException e) {
                e.fillInStackTrace();
                LOG.debug("poll: Error closing socket.", e);
            }
        }
    }
    return serviceStatus;
}
Also used : InterruptedIOException(java.io.InterruptedIOException) PollStatus(org.opennms.netmgt.poller.PollStatus) InetSocketAddress(java.net.InetSocketAddress) Calendar(java.util.Calendar) GregorianCalendar(java.util.GregorianCalendar) SSLSocket(javax.net.ssl.SSLSocket) InterruptedIOException(java.io.InterruptedIOException) IOException(java.io.IOException) NoRouteToHostException(java.net.NoRouteToHostException) X509Certificate(java.security.cert.X509Certificate) SSLParameters(javax.net.ssl.SSLParameters) TimeoutTracker(org.opennms.core.utils.TimeoutTracker) StrictHostnameVerifier(org.apache.http.conn.ssl.StrictHostnameVerifier) SNIHostName(javax.net.ssl.SNIHostName) InetAddress(java.net.InetAddress) Socket(java.net.Socket) SSLSocket(javax.net.ssl.SSLSocket) X509Certificate(java.security.cert.X509Certificate) Certificate(java.security.cert.Certificate) ConnectException(java.net.ConnectException)

Example 9 with TimeoutTracker

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

the class MailTransportMonitor method readTestMessage.

private PollStatus readTestMessage(final MailTransportParameters mailParms) {
    LOG.debug("readTestMessage: Beginning read mail test.");
    PollStatus status = PollStatus.unavailable("Test not completed.");
    final long interval = mailParms.getReadTestAttemptInterval();
    if (mailParms.isEnd2EndTestInProgress()) {
        LOG.debug("Initially delaying read test: {} because end to end test is in progress.", mailParms.getReadTestAttemptInterval());
        if (delayTest(status, interval) == PollStatus.SERVICE_UNKNOWN) {
            return status;
        }
    }
    Store mailStore = null;
    Folder mailFolder = null;
    try {
        final JavaMailer readMailer = new JavaMailer(mailParms.getJavamailProperties());
        setReadMailProperties(mailParms, readMailer);
        final TimeoutTracker tracker = new TimeoutTracker(mailParms.getParameterMap(), mailParms.getRetries(), mailParms.getTimeout());
        for (tracker.reset(); tracker.shouldRetry(); tracker.nextAttempt()) {
            tracker.startAttempt();
            if (tracker.getAttempt() > 0) {
                if (delayTest(status, interval) == PollStatus.SERVICE_UNKNOWN) {
                    LOG.warn("readTestMessage: Status set to: {} during delay, exiting test.", status);
                    break;
                }
            }
            LOG.debug("readTestMessage: reading mail attempt: {}, elapsed time: {}ms.", (tracker.getAttempt() + 1), String.format("%.2f", tracker.elapsedTimeInMillis()));
            try {
                mailStore = readMailer.getSession().getStore();
                mailFolder = retrieveMailFolder(mailParms, mailStore);
                mailFolder.open(Folder.READ_WRITE);
            } catch (final MessagingException e) {
                if (tracker.shouldRetry()) {
                    LOG.warn("readTestMessage: error reading INBOX", e);
                    closeStore(mailStore, mailFolder);
                    //try again to get mail Folder from Store
                    continue;
                } else {
                    LOG.warn("readTestMessage: error reading INBOX", e);
                    return PollStatus.down(e.getLocalizedMessage());
                }
            }
            if (mailFolder.isOpen() && (mailParms.getReadTest().getSubjectMatch() != null || mailParms.isEnd2EndTestInProgress())) {
                status = processMailSubject(mailParms, mailFolder);
                if (status.getStatusCode() == PollStatus.SERVICE_AVAILABLE) {
                    break;
                }
            }
        }
    } catch (final JavaMailerException e) {
        status = PollStatus.down(e.getLocalizedMessage());
    } finally {
        closeStore(mailStore, mailFolder);
    }
    return status;
}
Also used : PollStatus(org.opennms.netmgt.poller.PollStatus) TimeoutTracker(org.opennms.core.utils.TimeoutTracker) MessagingException(javax.mail.MessagingException) Store(javax.mail.Store) JavaMailerException(org.opennms.javamail.JavaMailerException) JavaMailer(org.opennms.javamail.JavaMailer) Folder(javax.mail.Folder)

Example 10 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