Java tutorial
/** * Copyright 2014 Comcast Cable Communications Management, LLC * * This file is part of CATS. * * CATS is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * CATS is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with CATS. If not, see <http://www.gnu.org/licenses/>. */ package com.comcast.cats.telnet; import java.io.IOException; import java.io.InputStream; import java.io.PrintStream; import java.net.SocketException; import java.util.Date; import org.apache.commons.net.telnet.TelnetClient; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Represents a generic telnet connection. * * @author skurup00c * */ public class TelnetConnection { private InputStream is; private PrintStream os; private String host; private Integer port; private String defaultPromptString; private TelnetClient telnetClient; private Integer defaultReadTimeout; protected Date lastActiveTime; protected Boolean isConnected = false; private boolean isBusy = false; public static final int DEFAULT_READ_TIMEOUT = 60000;//1 * 60 * 1000; one minute public static final int DEFAULT_TIMEOUT = 300000;//5 * 60 * 1000; private static Logger logger = LoggerFactory.getLogger(TelnetConnection.class); /** * Creates a TelnetConnection insatnce. * * @param ip * : of the telnet device * @param port * : telnet port * @param defaultPromptString * : default prompt string to be used. Usually ">". * */ public TelnetConnection(String host, Integer port, String defaultPromptString) { this.host = host; this.port = port; this.defaultPromptString = defaultPromptString; this.telnetClient = new TelnetClient(); setDefaultReadTimeout(DEFAULT_READ_TIMEOUT); lastActiveTime = new Date(); } /** * Connect to the telnet client. * * @param isEnterRequired * : sometime an ENTER key maybe required to reach the prompt. * * @return true: if connected. * * @throws SocketException * @throws IOException */ public synchronized Boolean connect(Boolean isEnterRequired) throws SocketException, IOException { if (!isConnected) { try { telnetClient.connect(getHost(), getPort()); logger.info("connected to telnet host " + host + " port " + port + " defaultPromptString " + defaultPromptString); } catch (SocketException e) { logger.warn("Could not connect to telnetSession " + e.getMessage()); throw new SocketException(e.getMessage()); } is = telnetClient.getInputStream(); os = new PrintStream(telnetClient.getOutputStream()); if (isEnterRequired) { os.println(); } isConnected = true; lastActiveTime = new Date(); } return isConnected; } /** * Connect to the telnet client with a password. * * @param isEnterRequired * : sometime an ENTER key maybe required to reach the prompt. * * @param password * @param passwordPromptString * : the prompt that asks for a password : usually something like * "Enter Password :" * @return true if connected successfully * @throws SocketException * @throws IOException */ public synchronized Boolean connectWithPassword(String password, String passwordPromptString, Boolean isEnterRequired) throws SocketException, IOException { if (!isConnected && password != null && passwordPromptString != null) { try { telnetClient.connect(getHost(), getPort()); logger.info("connected to telnet host " + host + " port " + port); } catch (SocketException e) { logger.warn("Could not connect to telnetSession " + e.getMessage()); throw new SocketException(e.getMessage()); } is = telnetClient.getInputStream(); os = new PrintStream(telnetClient.getOutputStream()); if (isEnterRequired) { os.println(); } String passwordPrompt = readUntil(passwordPromptString); logger.debug("passwordPrompt " + passwordPrompt); if (passwordPrompt != null) { write(password); isConnected = true; lastActiveTime = new Date(); } else { logger.info("Prompt string could not be reached"); disconnect(); } } return isConnected; } /** * Disconnects a telnet session. * * @throws IOException */ public synchronized void disconnect() throws IOException { if (is != null) { is.close(); } if (os != null) { os.close(); } logger.trace("dicsonnecting telnetClient"); if (telnetClient.isConnected()) { telnetClient.disconnect(); } is = null; os = null; isConnected = false; logger.info("disconnected telnetConnection " + host + " port " + port); } /** * Status of telnet connection * * @return true if connected. */ public synchronized Boolean isConnected() { return isConnected; } /** * Send a command to the telnet session. Requires * TelnetConnection.isConnected() to be true. * * @param command * to send * @return returned value in telnet client after execution of command. * @throws IOException */ public synchronized String sendCommand(String command) throws IOException { return sendCommand(command, defaultPromptString); } /** * Send a command to the telnet session, and read till the following prompt * instead of the default prompt. * * Requires TelnetConnection.isConnected() to be true. * * @param command * @param prompt * @return * @throws IOException */ public synchronized String sendCommand(String command, String prompt) throws IOException { isBusy = true; logger.trace("sendCommand " + command + " prompt " + prompt); String result = null; if (isConnected && command != null) { write(command); result = readUntil(prompt); } lastActiveTime = new Date(); isBusy = false; return result; } /** * if prompt string is not recieved within the default timeout value, the * read will be interrupted. This is important to avoid the connection to * hang on a read when the prompt string does not arrive. Default value is 1 * minute. * * @return defaultTimeout value */ public Integer getDefaultReadTimeout() { return defaultReadTimeout; } /** * Timeout to that closes the socket during a period of inactivity. * */ public void setDefaultReadTimeout(Integer defaultReadTimeout) { this.defaultReadTimeout = defaultReadTimeout; } /** * This just provides the Output stream to write to the telnet connection. * Should be called only after a connect is called. This is to provide users * with an option to write stuff to the telnet connection other than what is * provided through this class. Its the responsibility of the user to * understand the working of TelnetConnection and the proper use of the * PrintStream * */ public PrintStream getPrintStream() { return os; } /** * This just provides the input stream to write to the telnet connection. * Should be called only after a connect is called. This is to provide users * with an option to read stuff from the telnet connection other than what * is provided through this class. Its the responsibility of the user to * understand the working of TelnetConnection and the proper use of the * input * */ public InputStream getInputStream() { return is; } /** * Get the last time a connect, or sendCommand was sent. can be used to * determine timeout to disconnect based on inactivity etc. * * @return */ public Date getLastActiveTime() { return lastActiveTime; } public String getHost() { return host; } public Integer getPort() { return port; } public boolean isBusy() { return isBusy; } /** * * Reads Telnet response. * * @param pattern * @return * @throws IOException */ private synchronized String readUntil(String pattern) throws IOException { logger.trace("readUntil " + pattern); String retVal = null; if (is != null) { StringBuffer sb = new StringBuffer(); char lastChar = pattern.charAt(pattern.length() - 1); char ch; telnetClient.setSoTimeout(defaultReadTimeout); logger.trace("getDefaultReadTimeout() " + defaultReadTimeout); while (true) { try { int readByte = is.read(); if (readByte != -1) { ch = (char) readByte; } else { logger.warn("TelnetConnection: End of stream reached. Maybe remote end crashed "); disconnect(); throw new IOException("TelnetConnection: End of stream reached. Maybe remote end crashed "); } } catch (IOException e) { logger.warn("Error occured in TelnetConnect readUntil " + e.getMessage()); disconnect(); throw new IOException(e); } sb.append(ch); if (ch == lastChar) { if (sb.toString().endsWith(pattern)) { String string = sb.toString(); retVal = string.substring(0, string.length() - pattern.length()); logger.trace("readUntil string " + retVal); break; } } } } return retVal; } /** * Sends actual Telnet command. * * @param value */ private synchronized void write(String value) { if (null != os) { logger.trace("write value " + value); os.println(value); os.flush(); } } }