Search in sources :

Example 16 with TimeoutTracker

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

the class TcpMonitor method poll.

/**
 * {@inheritDoc}
 *
 * Poll the specified address for service availability.
 *
 * During the poll an attempt is made to connect on the specified port. If
 * the connection request is successful, the banner line generated by the
 * interface is parsed and if the banner text indicates that we are talking
 * to 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) {
    // 
    // Process parameters
    // 
    // 
    // Get interface address from NetworkInterface
    // 
    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("TcpMonitor: required parameter 'port' is not present in supplied properties.");
    }
    // BannerMatch
    // 
    String strBannerMatch = ParameterMap.getKeyedString(parameters, PARAMETER_BANNER, null);
    // Get the address instance.
    // 
    InetAddress ipAddr = svc.getAddress();
    final String hostAddress = InetAddressUtils.str(ipAddr);
    LOG.debug("poll: address = {}, port = {}, {}", hostAddress, port, 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("TcpMonitor: connected to host: {} on port: {}", ipAddr, port);
            // We're connected, so upgrade status to unresponsive
            serviceStatus = PollStatus.unresponsive();
            if (strBannerMatch == null || strBannerMatch.length() == 0 || strBannerMatch.equals("*")) {
                serviceStatus = PollStatus.available(tracker.elapsedTimeInMillis());
                break;
            }
            BufferedReader rdr = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            // 
            // Tokenize the Banner Line, and check the first
            // line for a valid return.
            // 
            String response = rdr.readLine();
            double responseTime = tracker.elapsedTimeInMillis();
            if (response == null)
                continue;
            LOG.debug("poll: banner = {}", response);
            LOG.debug("poll: responseTime= {}ms", responseTime);
            // Could it be a regex?
            if (strBannerMatch.charAt(0) == '~') {
                if (!response.matches(strBannerMatch.substring(1)))
                    serviceStatus = PollStatus.unavailable("Banner does not match Regex '" + strBannerMatch + "'");
                else
                    serviceStatus = PollStatus.available(responseTime);
            } else {
                if (response.indexOf(strBannerMatch) > -1) {
                    serviceStatus = PollStatus.available(responseTime);
                } else {
                    serviceStatus = PollStatus.unavailable("Banner: '" + response + "' does not contain match string '" + strBannerMatch + "'");
                }
            }
        } 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 {
                // Close the socket
                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) InputStreamReader(java.io.InputStreamReader) InetSocketAddress(java.net.InetSocketAddress) IOException(java.io.IOException) InterruptedIOException(java.io.InterruptedIOException) NoRouteToHostException(java.net.NoRouteToHostException) TimeoutTracker(org.opennms.core.utils.TimeoutTracker) BufferedReader(java.io.BufferedReader) InetAddress(java.net.InetAddress) Socket(java.net.Socket) ConnectException(java.net.ConnectException)

Example 17 with TimeoutTracker

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

the class AbstractPoll method poll.

/**
 * <p>poll</p>
 *
 * @return a {@link org.opennms.netmgt.poller.PollStatus} object.
 * @throws org.opennms.netmgt.protocols.InsufficientParametersException if any.
 */
@Override
public PollStatus poll() throws InsufficientParametersException {
    Map<String, ?> emptyMap = Collections.emptyMap();
    TimeoutTracker tracker = new TimeoutTracker(emptyMap, 1, getTimeout());
    return poll(tracker);
}
Also used : TimeoutTracker(org.opennms.core.utils.TimeoutTracker)

Example 18 with TimeoutTracker

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

the class AvailabilityMonitor method poll.

/**
 * {@inheritDoc}
 */
@Override
public PollStatus poll(MonitoredService svc, Map<String, Object> parameters) {
    TimeoutTracker timeoutTracker = new TimeoutTracker(parameters, DEFAULT_RETRY, DEFAULT_TIMEOUT);
    for (timeoutTracker.reset(); timeoutTracker.shouldRetry(); timeoutTracker.nextAttempt()) {
        try {
            timeoutTracker.startAttempt();
            if (svc.getAddress().isReachable(timeoutTracker.getSoTimeout())) {
                return PollStatus.available(timeoutTracker.elapsedTimeInMillis());
            }
        } catch (IOException e) {
            LOG.debug("Unable to contact {}", svc.getIpAddr(), e);
        }
    }
    String reason = svc + " failed to respond";
    LOG.debug(reason);
    return PollStatus.unavailable(reason);
}
Also used : TimeoutTracker(org.opennms.core.utils.TimeoutTracker) IOException(java.io.IOException)

Example 19 with TimeoutTracker

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

the class NsclientMonitor method poll.

/**
 * {@inheritDoc}
 *
 * Poll the specified address for service availability. During the poll an
 * attempt is made to connect on the specified port. If the connection
 * request is successful, the parameters are parsed and turned into
 * <code>NsclientCheckParams</code> and a check is performed against the
 * remote NSClient service. If the <code>NsclientManager</code> responds
 * with a <code>NsclientPacket</code> containing a result code of
 * <code>NsclientPacket.RES_STATE_OK</code> then we have determined that
 * we are talking to a valid service and we set the service status to
 * SERVICE_AVAILABLE and return.
 */
@Override
public PollStatus poll(MonitoredService svc, Map<String, Object> parameters) {
    // Holds the response reason.
    String reason = null;
    // Used to exit the retry loop early, if possible.
    int serviceStatus = PollStatus.SERVICE_UNRESPONSIVE;
    // This will hold the data the server sends back.
    NsclientPacket response = null;
    // Used to track how long the request took.
    Double responseTime = null;
    // NSClient related parameters.
    String command = ParameterMap.getKeyedString(parameters, "command", NsclientManager.convertTypeToString(NsclientManager.CHECK_CLIENTVERSION));
    int port = ParameterMap.getKeyedInteger(parameters, "port", NsclientManager.DEFAULT_PORT);
    String password = ParameterMap.getKeyedString(parameters, "password", NSClientAgentConfig.DEFAULT_PASSWORD);
    String params = ParameterMap.getKeyedString(parameters, "parameter", null);
    int critPerc = ParameterMap.getKeyedInteger(parameters, "criticalPercent", 0);
    int warnPerc = ParameterMap.getKeyedInteger(parameters, "warningPercent", 0);
    TimeoutTracker tracker = new TimeoutTracker(parameters, DEFAULT_RETRY, DEFAULT_TIMEOUT);
    // Get the address we're going to poll.
    InetAddress ipAddr = svc.getAddress();
    for (tracker.reset(); tracker.shouldRetry() && serviceStatus != PollStatus.SERVICE_AVAILABLE; tracker.nextAttempt()) {
        try {
            tracker.startAttempt();
            // Create a client, set up details and connect.
            NsclientManager client = new NsclientManager(InetAddressUtils.str(ipAddr), port, password);
            client.setTimeout(tracker.getSoTimeout());
            client.setPassword(password);
            client.init();
            // Set up the parameters the client will use to validate the
            // response.
            NsclientCheckParams clientParams = new NsclientCheckParams(critPerc, warnPerc, params);
            // Send the request to the server and receive the response.
            response = client.processCheckCommand(NsclientManager.convertStringToType(command), clientParams);
            // Now save the time it took to process the check command.
            responseTime = tracker.elapsedTimeInMillis();
            if (response == null) {
                continue;
            }
            if (response.getResultCode() == NsclientPacket.RES_STATE_OK) {
                serviceStatus = PollStatus.SERVICE_AVAILABLE;
                reason = response.getResponse();
            } else if (response.getResultCode() == NsclientPacket.RES_STATE_CRIT) {
                serviceStatus = PollStatus.SERVICE_UNAVAILABLE;
                reason = response.getResponse();
                // set this to null so we don't try to save data when the node is down
                responseTime = null;
            }
        } catch (NsclientException e) {
            LOG.debug("Nsclient Poller received exception from client", e);
            reason = "NsclientException: " + e.getMessage();
        }
    }
    // end for(;;)
    return PollStatus.get(serviceStatus, reason, responseTime);
}
Also used : NsclientPacket(org.opennms.protocols.nsclient.NsclientPacket) TimeoutTracker(org.opennms.core.utils.TimeoutTracker) NsclientCheckParams(org.opennms.protocols.nsclient.NsclientCheckParams) NsclientException(org.opennms.protocols.nsclient.NsclientException) NsclientManager(org.opennms.protocols.nsclient.NsclientManager) InetAddress(java.net.InetAddress)

Example 20 with TimeoutTracker

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

the class CiscoPingMibMonitor method poll.

/**
 * {@inheritDoc}
 *
 * <P>
 * The poll() method is responsible for setting up and following up the IOS
 * ping entry that proxies monitoring of the specified address for ICMP
 * service availability.
 * </P>
 * @exception RuntimeException
 *                Thrown for any unrecoverable errors.
 */
@Override
public PollStatus poll(MonitoredService svc, Map<String, Object> parameters) {
    final InetAddress targetIpAddr = InetAddrUtils.addr(getKeyedString(parameters, "targetIpAddr", null));
    final InetAddress proxyIpAddr = InetAddrUtils.addr(getKeyedString(parameters, "proxyIpAddr", null));
    int pingProtocol = 0;
    try {
        pingProtocol = determineAddrType(targetIpAddr);
    } catch (RuntimeException e) {
        LOG.debug("Unknown address type - neither IPv4 nor IPv6", e);
        return PollStatus.unavailable("Unknown address type - neither IPv4 nor IPv6");
    }
    // Get configuration parameters into a CiscoPingEntry object
    // 
    CiscoPingEntry pingEntry = new CiscoPingEntry();
    pingEntry.setCiscoPingPacketCount(ParameterMap.getKeyedInteger(parameters, PARM_PACKET_COUNT, PARM_PACKET_COUNT_DEFAULT));
    pingEntry.setCiscoPingPacketSize(ParameterMap.getKeyedInteger(parameters, PARM_PACKET_SIZE, PARM_PACKET_SIZE_DEFAULT));
    pingEntry.setCiscoPingPacketTimeout(ParameterMap.getKeyedInteger(parameters, PARM_PACKET_TIMEOUT, PARM_PACKET_TIMEOUT_DEFAULT));
    pingEntry.setCiscoPingPacketDelay(ParameterMap.getKeyedInteger(parameters, PARM_PACKET_DELAY, PARM_PACKET_DELAY_DEFAULT));
    pingEntry.setCiscoPingEntryOwner(ParameterMap.getKeyedString(parameters, PARM_ENTRY_OWNER, PARM_ENTRY_OWNER_DEFAULT));
    pingEntry.setCiscoPingVrfName(ParameterMap.getKeyedString(parameters, PARM_VRF_NAME, PARM_VRF_NAME_DEFAULT));
    pingEntry.setCiscoPingSerialNumber(Double.valueOf(System.currentTimeMillis() / 1000d).intValue());
    pingEntry.setCiscoPingProtocol(pingProtocol);
    pingEntry.setCiscoPingAddress(targetIpAddr);
    pingEntry.setCiscoPingEntryStatus(ROWSTATUS_CREATE_AND_GO);
    int minSuccessPercent = ParameterMap.getKeyedInteger(parameters, PARM_SUCCESS_PERCENT, PARM_SUCCESS_PERCENT_DEFAULT);
    // FIXME: Should the cleanup stuff be fixed to actually use this? Not clear if it really matters.
    // int cleanupInterval = ParameterMap.getKeyedInteger(parameters, PARM_CLEANUP_INTERVAL, PARM_CLEANUP_INTERVAL_DEFAULT);
    // Retrieve the *proxy* interface's SNMP peer object
    // 
    SnmpAgentConfig agentConfig = getAgentConfig(svc, parameters);
    LOG.debug("poll: setting SNMP peer attribute for interface {}", proxyIpAddr.getHostAddress());
    // 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("Setting up CISCO-PING-MIB proxy poll for service {} on interface {} -- {}", svc.getSvcName(), targetIpAddr, pingEntry);
    PollStatus serviceStatus = null;
    TimeoutTracker timeoutTracker = new TimeoutTracker(parameters, DEFAULT_RETRY, DEFAULT_TIMEOUT);
    // Send the SET-REQUEST PDU to create the ciscoPingEntry in createAndGo mode
    SnmpValue[] setResult = SnmpUtils.set(agentConfig, pingEntry.generateCreateOids(), pingEntry.generateCreateValues());
    if (setResult == null) {
        LOG.warn("SNMP SET operation unsuccessful for proxy-ping entry for target {} -- {}", targetIpAddr, pingEntry);
        return PollStatus.unknown("SNMP SET failed for ciscoPingTable entry on proxy interface " + proxyIpAddr + " with instance ID " + pingEntry.getCiscoPingSerialNumber());
    }
    // a good starting point.
    try {
        Thread.sleep(pingEntry.calculateMinInitialWait() * 2L);
    } catch (InterruptedException e) {
    }
    // Now check whether the ping has completed and, if so, whether it succeeded and its times
    SnmpValue[] statusValues = null;
    for (timeoutTracker.reset(); (timeoutTracker.shouldRetry() && (statusValues == null || statusValues.length < 6 || statusValues[5].toInt() != 1)); timeoutTracker.nextAttempt()) {
        statusValues = SnmpUtils.get(agentConfig, pingEntry.generateResultsOids());
    }
    // If we didn't get the results back, mark the service as unknown
    if (statusValues == null || (statusValues.length == 1 && statusValues[0] == null)) {
        LOG.warn("SNMP GET operation unsuccessful for proxy-ping entry for target {} -- {}", targetIpAddr, pingEntry);
        return PollStatus.unknown("SNMP GET failed for ciscoPingTable entry on proxy interface " + proxyIpAddr + " with instance ID " + pingEntry.getCiscoPingSerialNumber());
    }
    // mark the service unknown
    if (statusValues.length < 6) {
        LOG.warn("Proxy-ping entry did not indicate whether ping completed after retries exhausted for target {} -- {}", targetIpAddr, pingEntry);
        return PollStatus.unknown("ciscoPingTable entry is missing pingCompleted column on proxy interface " + proxyIpAddr + " with instance ID " + pingEntry.getCiscoPingSerialNumber());
    }
    // mark the service unknown
    if (statusValues[5].toInt() != 1) {
        LOG.warn("Proxy-ping entry marked not completed after retries exhausted for target {} -- {}", targetIpAddr, pingEntry);
        return PollStatus.unknown("ciscoPingTable entry marked not completed on proxy interface " + proxyIpAddr + " with instance ID " + pingEntry.getCiscoPingSerialNumber());
    }
    // If the ping has completed, verify that the percent of completed pings meets our minimum
    // success percent.  If not, mark the service down.
    double sentPings = statusValues[0].toInt();
    double receivedPings = statusValues[1].toInt();
    double successPct = receivedPings / sentPings * 100;
    if (receivedPings == 0) {
        LOG.info("Proxy-ping entry indicates no pings succeeded for target {} -- {}", targetIpAddr, pingEntry);
        cleanupCurrentEntry(pingEntry, proxyIpAddr, agentConfig);
        return PollStatus.unavailable("All remote pings (" + sentPings + " of " + sentPings + ") failed");
    } else if (successPct < minSuccessPercent) {
        LOG.info("Proxy-ping entry indicates {}% success, which misses the success-percent target of {}% for target {} -- {}", successPct, minSuccessPercent, targetIpAddr, pingEntry);
        cleanupCurrentEntry(pingEntry, proxyIpAddr, agentConfig);
        return PollStatus.unavailable(successPct + " percent (" + receivedPings + "/" + sentPings + ") pings succeeded, less than target " + minSuccessPercent + " percent");
    }
    // If we've arrived here, then enough pings completed to consider the service up!
    Map<String, Number> pingProps = new HashMap<String, Number>();
    double minRtt = statusValues[2].toInt();
    double avgRtt = statusValues[3].toInt();
    double maxRtt = statusValues[4].toInt();
    LOG.debug("Logging successful poll: sent={}, received={}, minRtt={}, avgRtt={}, maxRtt={} for proxy-ping of target {} -- {}", sentPings, receivedPings, minRtt, avgRtt, maxRtt, targetIpAddr, pingEntry);
    pingProps.put("sent", sentPings);
    pingProps.put("received", receivedPings);
    pingProps.put("minRtt", minRtt);
    pingProps.put("avgRtt", avgRtt);
    pingProps.put("maxRtt", maxRtt);
    cleanupCurrentEntry(pingEntry, proxyIpAddr, agentConfig);
    // TODO: Find and clean up defunct rows before returning
    // Actually it's not clear that this is necessary, seems IOS cleans up old
    // entries on its own some minutes after their creation.  Need to investigate.
    serviceStatus = PollStatus.available(avgRtt);
    serviceStatus.setProperties(pingProps);
    return serviceStatus;
}
Also used : SnmpAgentConfig(org.opennms.netmgt.snmp.SnmpAgentConfig) PollStatus(org.opennms.netmgt.poller.PollStatus) HashMap(java.util.HashMap) SnmpValue(org.opennms.netmgt.snmp.SnmpValue) TimeoutTracker(org.opennms.core.utils.TimeoutTracker) 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