Search in sources :

Example 1 with FtpResponse

use of org.opennms.netmgt.poller.monitors.support.FtpResponse 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)

Aggregations

BufferedReader (java.io.BufferedReader)1 IOException (java.io.IOException)1 InputStreamReader (java.io.InputStreamReader)1 InterruptedIOException (java.io.InterruptedIOException)1 ConnectException (java.net.ConnectException)1 InetAddress (java.net.InetAddress)1 InetSocketAddress (java.net.InetSocketAddress)1 NoRouteToHostException (java.net.NoRouteToHostException)1 Socket (java.net.Socket)1 TimeoutTracker (org.opennms.core.utils.TimeoutTracker)1 PollStatus (org.opennms.netmgt.poller.PollStatus)1 FtpResponse (org.opennms.netmgt.poller.monitors.support.FtpResponse)1