use of org.apache.commons.net.io.CRLFLineReader 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;
}
Aggregations