2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Copyright (C) 2017 Amdocs
8 * =============================================================================
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
21 * ECOMP is a trademark and service mark of AT&T Intellectual Property.
22 * ============LICENSE_END=========================================================
25 package org.onap.appc.ccadaptor;
27 import com.jcraft.jsch.Channel;
28 import com.jcraft.jsch.ChannelSftp;
29 import com.jcraft.jsch.ChannelShell;
30 import com.jcraft.jsch.ChannelSubsystem;
31 import com.jcraft.jsch.JSch;
32 import com.jcraft.jsch.JSchException;
33 import com.jcraft.jsch.Session;
34 import com.jcraft.jsch.SftpException;
35 import com.jcraft.jsch.UIKeyboardInteractive;
36 import com.jcraft.jsch.UserInfo;
37 import java.io.BufferedInputStream;
38 import java.io.BufferedReader;
39 import java.io.BufferedWriter;
40 import java.io.ByteArrayInputStream;
41 import java.io.ByteArrayOutputStream;
42 import java.io.DataInputStream;
43 import java.io.DataOutputStream;
45 import java.io.FileNotFoundException;
46 import java.io.FileWriter;
47 import java.io.IOException;
48 import java.io.InputStream;
49 import java.io.InputStreamReader;
50 import java.io.OutputStream;
51 import java.io.RandomAccessFile;
52 import java.text.DateFormat;
53 import java.text.SimpleDateFormat;
54 import java.util.Calendar;
55 import java.util.Date;
56 import java.util.StringTokenizer;
57 import javax.annotation.Nonnull;
58 import org.apache.commons.lang.StringUtils;
60 public class SshJcraftWrapper {
62 private static final int BUFFER_SIZE = 512000;
63 private InputStream inputStream = null;
64 private String debugLogFileName = "/tmp/sshJcraftWrapperDebug";
65 private TelnetListener listener = null;
66 private String routerLogFileName = null;
67 private String host = null;
68 private String routerName = null;
69 private char[] charBuffer = new char[BUFFER_SIZE];
70 private DataInputStream dis = null;
71 private BufferedReader reader = null;
72 private BufferedWriter out = null;
73 private File tmpFile = null;
74 private JSch jsch = null;
75 private Session session = null;
76 private Channel channel = null;
77 private String aggregatedReceivedString = "";
78 private File extraDebugFile = new File("/tmp/sshJcraftWrapperDEBUG");
79 private String routerCmdType = "XML";
80 private String routerFileName = null;
81 private File jcraftReadSwConfigFileFromDisk = new File("/tmp/jcraftReadSwConfigFileFromDisk");
82 private String equipNameCode = null;
83 private String hostName = null;
84 private String userName = null;
85 private String passWord = null;
86 private Runtime runtime = Runtime.getRuntime();
87 private DebugLog dbLog = new DebugLog();
89 public void SshJcraftWrapper() {
90 String fn = "SshJcraftWrapper.SshJcraftWrapper";
91 DebugLog.printRTAriDebug(fn, "SshJcraftWrapper has been instantated");
92 routerLogFileName = "/tmp/" + host;
96 public void connect(String hostname, String username, String password, String prompt, int timeOut)
98 String fn = "SshJcraftWrapper.connect";
100 DebugLog.printRTAriDebug(fn,
101 "Attempting to connect to " + hostname + " username=" + username + " password=" + password + " prompt='"
102 + prompt + "' timeOut=" + timeOut);
103 DebugLog.printRTAriDebug(fn, "Trace A");
104 routerName = hostname;
109 session = jsch.getSession(username, hostname, 22);
110 UserInfo ui = new MyUserInfo();
111 session.setPassword(password);
112 session.setUserInfo(ui);
113 session.connect(timeOut);
114 channel = session.openChannel("shell");
115 session.setServerAliveCountMax(
116 0); // If this is not set to '0', then socket timeout on all reads will not work!!!!
117 ((ChannelShell) channel).setPtyType("vt102");
118 inputStream = channel.getInputStream();
119 dis = new DataInputStream(inputStream);
120 reader = new BufferedReader(new InputStreamReader(dis), BUFFER_SIZE);
122 DebugLog.printRTAriDebug(fn, "Successfully connected.");
123 DebugLog.printRTAriDebug(fn, "Flushing input buffer");
125 receiveUntil(prompt, 3000, "No cmd was sent, just waiting");
126 } catch (Exception e) {
127 DebugLog.printRTAriDebug(fn, "Caught an Exception: Nothing to flush out.");
129 } catch (Exception e) {
130 DebugLog.printRTAriDebug(fn, "Caught an Exception. e=" + e);
131 // dbLog.storeData("ErrorMsg= Exception trying to connect to "+hostname +" "+e);
132 throw new IOException(e.toString());
136 // User specifies the port number.
137 public void connect(String hostname, String username, String password, String prompt, int timeOut, int portNum)
139 String fn = "SshJcraftWrapper.connect";
140 DebugLog.printRTAriDebug(fn,
141 ":Attempting to connect to " + hostname + " username=" + username + " password=" + password + " prompt='"
142 + prompt + "' timeOut=" + timeOut + " portNum=" + portNum);
143 routerName = hostname;
147 routerName = hostname;
150 session = jsch.getSession(username, hostname, portNum);
151 UserInfo ui = new MyUserInfo();
152 session.setPassword(password);
153 session.setUserInfo(ui);
154 session.setConfig("StrictHostKeyChecking", "no");
155 DebugLog.printRTAriDebug(fn, ":StrictHostKeyChecking set to 'no'");
157 session.connect(timeOut);
158 session.setServerAliveCountMax(
159 0); // If this is not set to '0', then socket timeout on all reads will not work!!!!
160 channel = session.openChannel("shell");
161 ((ChannelShell) channel).setPtyType("vt102");
162 inputStream = channel.getInputStream();
163 dis = new DataInputStream(inputStream);
164 reader = new BufferedReader(new InputStreamReader(dis), BUFFER_SIZE);
166 DebugLog.printRTAriDebug(fn, ":Successfully connected.");
167 DebugLog.printRTAriDebug(fn, ":Flushing input buffer");
169 if (prompt.equals("]]>]]>")) {
170 receiveUntil("]]>]]>", 10000, "No cmd was sent, just waiting");
172 receiveUntil(":~#", 5000, "No cmd was sent, just waiting");
174 } catch (Exception e) {
175 DebugLog.printRTAriDebug(fn, "Caught an Exception::: Nothing to flush out.");
177 } catch (Exception e) {
178 DebugLog.printRTAriDebug(fn, ":Caught an Exception. e=" + e);
179 dbLog.outputStackTrace(e);
181 // dbLog.storeData("ErrorMsg= Exception trying to connect to "+hostname +" "+e);
182 throw new IOException(e.toString());
187 public String receiveUntil(String delimeters, int timeout, String cmdThatWasSent) throws IOException {
188 String fn = "SshJcraftWrapper.receiveUntil";
189 boolean match = false;
190 boolean cliPromptCmd = false;
191 StringBuffer sb2 = new StringBuffer();
192 StringBuffer sbReceive = new StringBuffer();
193 DebugLog.printRTAriDebug(fn,
194 "delimeters='" + delimeters + "' timeout=" + timeout + " cmdThatWasSent='" + cmdThatWasSent + "'");
195 appendToFile(debugLogFileName,
196 fn + " delimeters='" + delimeters + "' timeout=" + timeout + " cmdThatWasSent='" + cmdThatWasSent + "'\n");
197 String CmdThatWasSent = removeWhiteSpaceAndNewLineCharactersAroundString(cmdThatWasSent);
199 aggregatedReceivedString = "";
200 FileWriter fileWriter = null;
202 long deadline = new Date().getTime() + timeout;
204 session.setTimeout(timeout); // This is the socket timeout value.
206 if (new Date().getTime() > deadline) {
207 DebugLog.printRTAriDebug(fn,
208 "Throwing a TimedOutException: time in routine has exceed our deadline: routerName:"
209 + routerName + " CmdThatWasSent=" + CmdThatWasSent);
210 throw new TimedOutException("Timeout: time in routine has exceed our deadline");
214 } catch (java.lang.InterruptedException ee) {
215 boolean ignore = true;
217 int len = reader.read(charBuffer, 0, BUFFER_SIZE);
218 appendToFile(debugLogFileName, fn + " After reader.read cmd: len=" + len + "\n");
220 DebugLog.printRTAriDebug(fn,
221 "Reader read " + len + " bytes. Looks like we timed out, router=" + routerName);
222 throw new TimedOutException("Received a SocketTimeoutException router=" + routerName);
225 if (cmdThatWasSent.indexOf("IOS_XR_uploadedSwConfigCmd") != -1) {
227 // This is a IOS XR sw config file. We will write it to the disk.
228 timeout = timeout * 2;
229 deadline = new Date().getTime() + timeout;
230 DebugLog.printRTAriDebug(fn, "IOS XR upload for software config: timeout=" + timeout);
231 StringTokenizer st = new StringTokenizer(cmdThatWasSent);
233 routerFileName = st.nextToken();
234 fileWriter = new FileWriter(routerFileName);
235 out = new BufferedWriter(fileWriter);
236 routerLogFileName = "/tmp/" + routerName;
237 tmpFile = new File(routerLogFileName);
238 DebugLog.printRTAriDebug(fn,
239 "Will write the swConfigFile to disk, routerFileName=" + routerFileName);
242 out.write(charBuffer, 0, len);
244 appendToFile(debugLogFileName, fn + " Wrote " + len + " bytes to the disk\n");
245 if (tmpFile.exists()) {
246 appendToRouterFile(routerLogFileName, len);
248 match = checkIfReceivedStringMatchesDelimeter(len, "\nXML>");
257 appendToFile(debugLogFileName,
258 fn + " readCounts=" + readCounts + " Reader read " + len + " of data\n");
261 for (int i = 0; i < len; i++) {
263 if ((c != 7) && (c != 13) && (c != 0) && (c != 27)) {
264 sbReceive.append((char) charBuffer[i]);
265 sb2.append((char) charBuffer[i]);
268 appendToRouterFile("/tmp/" + routerName, len);
269 if (listener != null) {
270 listener.receivedString(sb2.toString());
273 appendToFile(debugLogFileName, fn + " Trace 1\n");
274 match = checkIfReceivedStringMatchesDelimeter(delimeters, sb2.toString(), cmdThatWasSent);
275 appendToFile(debugLogFileName, fn + " Trace 2\n");
277 appendToFile(debugLogFileName, fn + " Match was true, breaking...\n");
282 DebugLog.printRTAriDebug(fn, "cliPromptCmd, Trace 2");
284 for (int i = 0; i < len; i++) {
285 sbReceive.append((char) charBuffer[i]);
286 sb2.append((char) charBuffer[i]);
288 appendToRouterFile("/tmp/" + routerName, sb2);
289 if (listener != null) {
290 listener.receivedString(sb2.toString());
292 DebugLog.printRTAriDebug(fn, "sb2='" + sb2.toString() + "' delimeters='" + delimeters + "'");
293 if (sb2.toString().indexOf("\nariPrompt>") != -1) {
294 DebugLog.printRTAriDebug(fn, "Found our prompt");
300 } catch (JSchException e) {
301 DebugLog.printRTAriDebug(fn, "Caught an JSchException e=" + e.toString());
302 dbLog.outputStackTrace(e);
303 throw new TimedOutException(e.toString());
304 } catch (IOException ee) {
305 DebugLog.printRTAriDebug(fn, "Caught an IOException: ee=" + ee.toString());
306 dbLog.outputStackTrace(ee);
307 throw new TimedOutException(ee.toString());
310 if (fileWriter != null) {
313 } catch (IOException ex) {
314 DebugLog.printRTAriDebug(fn, "Failed to close fileWriter output stream: ex=" + ex);
317 String result = stripOffCmdFromRouterResponse(sbReceive.toString());
318 DebugLog.printRTAriDebug(fn, "Leaving method successfully");
322 public boolean checkIfReceivedStringMatchesDelimeter(String delimeters, String receivedString,
323 String cmdThatWasSent) {
324 // The delimeters are in a '|' seperated string. Return true on the first match.
325 String fn = "SshJcraftWrapper.checkIfReceivedStringMatchesDelimeter";
326 appendToFile(debugLogFileName,
327 fn + " Entered: delimeters='" + delimeters + " cmdThatWasSent='" + cmdThatWasSent + "' receivedString='"
328 + receivedString + "'\n");
329 StringTokenizer st = new StringTokenizer(delimeters, "|");
331 if ((delimeters.indexOf("#$") != -1) || (routerCmdType.equals("CLI"))) // This would be an IOS XR, CLI command.
333 int x = receivedString.lastIndexOf("#");
334 int y = receivedString.length() - 1;
335 appendToFile(debugLogFileName, fn + " IOS XR, CLI command\n");
336 if (extraDebugFile.exists()) {
337 appendToFile(debugLogFileName,
338 fn + " :::cmdThatWasSent='" + cmdThatWasSent + "' x=" + x + " y=" + y + "\n");
340 return (x != -1) && (y == x);
342 if (cmdThatWasSent.indexOf("show config") != -1) {
343 appendToFile(debugLogFileName, fn + "In the block for 'show config'\n");
344 while (st.hasMoreTokens()) {
345 String delimeter = st.nextToken();
346 // Make sure we don't get faked out by a response of " #".
348 // # signaling-local-address ipv6 FD00:F4D5:EA06:1::110:136:254
350 int x = receivedString.lastIndexOf(delimeter);
351 if ((receivedString.lastIndexOf(delimeter) != -1) && (receivedString.lastIndexOf(" #") != x - 1)) {
352 appendToFile(debugLogFileName, fn + "receivedString=\n'" + receivedString + "'\n");
353 appendToFile(debugLogFileName,
354 fn + "Returning true for the 'show config' command. We found our real delmeter. \n\n");
359 aggregatedReceivedString = aggregatedReceivedString + receivedString;
360 _appendToFile("/tmp/aggregatedReceivedString.debug", aggregatedReceivedString);
362 while (st.hasMoreTokens()) {
363 String delimeter = st.nextToken();
364 appendToFile(debugLogFileName, fn + " Looking for an delimeter of:'" + delimeter + "'\n");
365 appendToFile(debugLogFileName, fn + " receivedString='" + receivedString);
366 if (aggregatedReceivedString.indexOf(delimeter) != -1) {
367 DebugLog.printRTAriDebug(fn, "Found our delimeter, which was: '" + delimeter + "'");
368 aggregatedReceivedString = "";
376 public boolean checkIfReceivedStringMatchesDelimeter(int len, String delimeter) {
377 String fnName = "SshJcraftWrapper.checkIfReceivedStringMatchesDelimeter:::";
380 String str = StringUtils.EMPTY;
382 if (jcraftReadSwConfigFileFromDisk()) {
383 DebugLog.printAriDebug(fnName, "jcraftReadSwConfigFileFromDisk block");
384 File fileName = new File(routerFileName);
385 appendToFile(debugLogFileName,
386 fnName + " jcraftReadSwConfigFileFromDisk::: Will read the tail end of the file from the disk");
388 str = getLastFewLinesOfFile(fileName, 3);
389 } catch (IOException e) {
390 DebugLog.printAriDebug(fnName, "Caught an Exception, e=" + e);
391 dbLog.outputStackTrace(e);
395 // DebugLog.printAriDebug(fnName, "TRACE 1: ******************************");
396 // When looking at the end of the charBuffer, don't include any linefeeds or spaces. We only want to make the smallest string possible.
397 for (x = len - 1; x >= 0; x--) {
399 if (extraDebugFile.exists()) {
400 appendToFile(debugLogFileName, fnName + " x=" + x + " c=" + c + "\n");
402 if ((c != 10) && (c != 32)) // Not a line feed nor a space.
407 if ((x + 1 - 13) >= 0) {
408 str = new String(charBuffer, (x + 1 - 13), 13);
409 appendToFile(debugLogFileName, fnName + " str:'" + str + "'\n");
411 File fileName = new File(routerFileName);
412 appendToFile(debugLogFileName,
413 fnName + " Will read the tail end of the file from the disk, x=" + x + " len=" + len + " str::'"
414 + str + "' routerFileName='" + routerFileName + "'\n");
415 DebugLog.printAriDebug(fnName,
416 "Will read the tail end of the file from the disk, x=" + x + " len=" + len + " str::'" + str
417 + "' routerFileName='" + routerFileName + "'");
419 str = getLastFewLinesOfFile(fileName, 3);
420 } catch (IOException e) {
421 DebugLog.printAriDebug(fnName, "Caught an Exception, e=" + e);
422 dbLog.outputStackTrace(e);
428 if (str.indexOf(delimeter) != -1) {
429 DebugLog.printAriDebug(fnName, "str in break is:'" + str + "'" + " delimeter='" + delimeter + "'");
430 appendToFile(debugLogFileName,
431 fnName + " str in break is:'" + str + " delimeter='" + delimeter + "'" + "'\n");
434 appendToFile(debugLogFileName, fnName + " Returning false");
440 public void closeConnection() {
441 String fn = "SshJcraftWrapper.closeConnection";
442 DebugLog.printRTAriDebug(fn, "Executing the closeConnection....");
446 session.disconnect();
450 public void send(String cmd) throws IOException {
451 String fn = "SshJcraftWrapper.send";
453 try (OutputStream os = channel.getOutputStream(); DataOutputStream dos = new DataOutputStream(os)) {
454 sendSshCommand(cmd, dos);
455 } catch (IOException e) {
456 DebugLog.printRTAriDebug(fn, "Caught an IOException. e=" + e);
457 dbLog.outputStackTrace(e);
458 throw new IOException(e.toString());
463 public void sendChar(int v) throws IOException {
464 String fn = "SshJcraftWrapper.sendChar";
465 OutputStream out = channel.getOutputStream();
466 DataOutputStream dos = new DataOutputStream(out);
468 DebugLog.printRTAriDebug(fn, "Sending: '" + v + "'");
471 } catch (IOException e) {
472 DebugLog.printRTAriDebug(fn, "Caught an IOException. e=" + e);
473 throw new IOException(e.toString());
477 public void send(byte[] b, int off, int len) throws IOException {
478 String fn = "SshJcraftWrapper.send:byte[]";
479 OutputStream out = channel.getOutputStream();
480 DataOutputStream dos = new DataOutputStream(out);
482 dos.write(b, off, len);
484 } catch (IOException e) {
485 DebugLog.printRTAriDebug(fn, "Caught an IOException. e=" + e);
486 throw new IOException(e.toString());
490 public static class MyUserInfo implements UserInfo, UIKeyboardInteractive {
492 public String getPassword() {
496 public boolean promptYesNo(String str) {
500 public String getPassphrase() {
504 public boolean promptPassphrase(String message) {
508 public boolean promptPassword(String message) {
512 public void showMessage(String message) {
515 public String[] promptKeyboardInteractive(String destination,
524 public void addListener(TelnetListener listener) {
525 this.listener = listener;
528 public void appendToFile(String fileName, String dataToWrite) {
529 String fn = "SshJcraftWrapper.appendToFile";
532 // First check to see if a file 'fileName' exist, if it does
533 // write to it. If it does not exist, don't write to it.
534 File tmpFile = new File(fileName);
535 if (tmpFile.exists()) {
536 BufferedWriter out = new BufferedWriter(new FileWriter(fileName, true));
537 // out.write(dataToWrite);
538 // out.write(getTheDate() +": " +Thread.currentThread().getName() +": "+dataToWrite);
540 out.write(getTheDate() + ": " + tId + ": " + dataToWrite);
543 } catch (IOException e) {
544 DebugLog.printRTAriDebug(fn, "Caught an IOException: e=" + e);
545 } catch (Exception e) {
546 DebugLog.printRTAriDebug(fn, "Caught an Exception: e=" + e);
550 public void _appendToFile(String fileName, String dataToWrite) {
551 String fn = "SshJcraftWrapper.appendToFile";
554 // First check to see if a file 'fileName' exist, if it does
555 // write to it. If it does not exist, don't write to it.
556 File tmpFile = new File(fileName);
557 if (tmpFile.exists()) {
558 BufferedWriter out = new BufferedWriter(new FileWriter(fileName, true));
559 out.write(dataToWrite);
562 } catch (IOException e) {
563 DebugLog.printRTAriDebug(fn, "Caught an IOException: e=" + e);
564 } catch (Exception e) {
565 DebugLog.printRTAriDebug(fn, "Caught an Exception: e=" + e);
570 public String getTheDate() {
571 Calendar cal = Calendar.getInstance();
572 java.util.Date today = cal.getTime();
573 DateFormat df1 = DateFormat.getDateInstance();
574 DateFormat df3 = new SimpleDateFormat("MM/dd/yyyy H:mm:ss ");
575 return (df3.format(today));
579 public void appendToRouterFile(String fileName, StringBuffer dataToWrite) {
580 String fnName = "SshJcraftWrapper.appendToRouterFile";
581 DebugLog.printRTAriDebug(fnName, "Entered.... ");
583 // First check to see if a file 'fileName' exist, if it does
584 // write to it. If it does not exist, don't write to it.
585 File tmpFile = new File(fileName);
587 // if ((tmpFile.exists()) && (tmpFile.setWritable(true, true)))
588 if (tmpFile.exists()) {
589 BufferedWriter out = new BufferedWriter(new FileWriter(fileName, true));
590 // out.write("<!-- "+getTheDate() +": " +tId +" -->\n");
591 out.write(dataToWrite.toString());
595 } catch (IOException e) {
596 System.err.println("writeToFile() exception: " + e);
601 public void appendToRouterFile(String fileName, int len) {
602 String fnName = "SshJcraftWrapper.appendToFile";
603 // DebugLog.printRTAriDebug (fnName, "Entered.... len="+len);
605 // First check to see if a file 'fileName' exist, if it does
606 // write to it. If it does not exist, don't write to it.
607 File tmpFile = new File(fileName);
608 // if ((tmpFile.exists()) && (tmpFile.setWritable(true, true)))
609 if (tmpFile.exists()) {
610 BufferedWriter out = new BufferedWriter(new FileWriter(fileName, true));
611 // out.write("<!-- "+getTheDate() +": " +tId +" -->\n");
612 out.write(charBuffer, 0, len);
615 } catch (IOException e) {
616 System.err.println("writeToFile() exception: " + e);
621 public String removeWhiteSpaceAndNewLineCharactersAroundString(String str) {
623 StringTokenizer strTok = new StringTokenizer(str, "\n");
624 StringBuffer sb = new StringBuffer();
626 while (strTok.hasMoreTokens()) {
627 String line = strTok.nextToken();
630 return (sb.toString().trim());
636 public String stripOffCmdFromRouterResponse(String routerResponse) {
637 String fn = "SshJcraftWrapper.stripOffCmdFromRouterResponse";
638 // appendToFile(debugLogFileName, fn+": routerResponse='"+routerResponse +"'\n");
640 // The session of SSH will echo the command sent to the router, in the router's response.
641 // Since all our commands are terminated by a '\n', strip off the first line
642 // of the response from the router. This first line contains the orginal command.
644 StringTokenizer rr = new StringTokenizer(routerResponse, "\n");
645 StringBuffer sb = new StringBuffer();
647 int numTokens = rr.countTokens();
648 // DebugLog.printRTAriDebug (fn, "Number of lines in the response from the router is:" +numTokens);
650 rr.nextToken(); //Skip the first line.
651 while (rr.hasMoreTokens()) {
652 sb.append(rr.nextToken() + '\n');
655 return (sb.toString());
658 public void setRouterCommandType(String type) {
659 String fn = "SshJcraftWrapper.setRouterCommandType";
660 this.routerCmdType = type;
661 DebugLog.printRTAriDebug(fn, "Setting routerCmdType to a value of '" + type + "'");
664 public String getLastFewLinesOfFile(File file, int linesToRead) throws FileNotFoundException, IOException {
665 String fn = "SshJcraftWrapper.getLastFewLinesOfFile";
666 RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r");
668 StringBuilder builder = new StringBuilder();
670 long length = file.length();
672 randomAccessFile.seek(length);
673 for (long seek = length; seek >= 0; --seek) {
674 randomAccessFile.seek(seek);
675 char c = (char) randomAccessFile.read();
678 builder = builder.reverse();
679 // System.out.println(builder.toString());
680 tail = builder.toString() + tail;
682 builder.setLength(0);
683 if (lines == linesToRead) {
688 randomAccessFile.close();
689 if (!jcraftReadSwConfigFileFromDisk()) {
690 DebugLog.printRTAriDebug(fn, "tail='" + tail + "'");
692 appendToFile(debugLogFileName, "tail='" + tail + "'\n");
696 public boolean jcraftReadSwConfigFileFromDisk() {
697 if (jcraftReadSwConfigFileFromDisk.exists()) {
704 public String getEquipNameCode() {
705 return (equipNameCode);
709 public void setEquipNameCode(String equipNameCode) {
710 this.equipNameCode = equipNameCode;
713 public String getRouterName() {
717 // Routine does reads until it has read 'nchars' or times out.
718 public void receiveUntilBufferFlush(int ncharsSent, int timeout, String message)
719 throws TimedOutException, IOException {
720 String fn = "SshJcraftWrapper.receiveUntilBufferFlush";
721 StringBuffer sb2 = new StringBuffer();
722 StringBuffer sbReceive = new StringBuffer();
723 DebugLog.printRTAriDebug(fn, "ncharsSent=" + ncharsSent + " timeout=" + timeout + " " + message);
724 int ncharsTotalReceived = 0;
726 boolean flag = false;
728 long deadline = new Date().getTime() + timeout;
731 session.setTimeout(timeout); // This is the socket timeout value.
733 if (new Date().getTime() > deadline) {
734 DebugLog.printRTAriDebug(fn,
735 "Throwing a TimedOutException: time in routine has exceed our deadline: ncharsSent="
736 + ncharsSent + " ncharsTotalReceived=" + ncharsTotalReceived);
738 throw new TimedOutException("Timeout: time in routine has exceed our deadline");
740 ncharsRead = reader.read(charBuffer, 0, BUFFER_SIZE);
741 if (listener != null) {
742 listener.receivedString(String.copyValueOf(charBuffer, 0, ncharsRead));
744 appendToRouterFile("/tmp/" + routerName, ncharsRead);
745 ncharsTotalReceived = ncharsTotalReceived + ncharsRead;
746 // DebugLog.printRTAriDebug (fn, "::ncharsSent="+ncharsSent+" ncharsTotalReceived="+ncharsTotalReceived +" ncharsRead="+ncharsRead);
747 if (ncharsTotalReceived >= ncharsSent) {
748 DebugLog.printRTAriDebug(fn,
749 "Received the correct number of characters, ncharsSent=" + ncharsSent + " ncharsTotalReceived="
750 + ncharsTotalReceived);
755 } catch (JSchException e) {
756 DebugLog.printRTAriDebug(fn, "Caught an JSchException e=" + e);
757 DebugLog.printRTAriDebug(fn,
758 "ncharsSent=" + ncharsSent + " ncharsTotalReceived=" + ncharsTotalReceived + " ncharsRead="
760 throw new TimedOutException(e.toString());
764 public String getHostName() {
768 public String getUserName() {
772 public String getPassWord() {
776 public void sftpPut(String sourcePath, String destDirectory) throws IOException {
777 String fn = "SshJcraftWrapper.sftp";
779 Session sftpSession = jsch.getSession(userName, hostName, 22);
780 UserInfo ui = new MyUserInfo();
781 sftpSession.setPassword(passWord);
782 sftpSession.setUserInfo(ui);
783 sftpSession.connect(30 * 1000);
784 DebugLog.printRTAriDebug(fn, "Opening up an sftp channel....");
785 ChannelSftp sftp = (ChannelSftp) sftpSession.openChannel("sftp");
786 DebugLog.printRTAriDebug(fn, "Connecting....");
788 DebugLog.printRTAriDebug(fn, "Sending " + sourcePath + " --> " + destDirectory);
789 sftp.put(sourcePath, destDirectory, ChannelSftp.OVERWRITE);
790 DebugLog.printRTAriDebug(fn, "Sent successfully");
791 sftpSession.disconnect();
792 } catch (Exception e) {
793 DebugLog.printRTAriDebug(fn, "Caught an Exception, e=" + e);
794 // dbLog.storeData("ErrorMsg= sftp threw an Exception. error is:"+e);
795 throw new IOException(e.toString());
800 public void SftpPut(String stringOfData, String fullPathDest) throws IOException {
801 String fn = "SshJcraftWrapper.Sftp";
803 Session sftpSession = jsch.getSession(userName, hostName, 22);
804 UserInfo ui = new MyUserInfo();
805 sftpSession.setPassword(passWord);
806 sftpSession.setUserInfo(ui);
807 sftpSession.connect(30 * 1000);
808 DebugLog.printRTAriDebug(fn, "Opening up an sftp channel....");
809 ChannelSftp sftp = (ChannelSftp) sftpSession.openChannel("sftp");
810 DebugLog.printRTAriDebug(fn, "Connecting....");
812 InputStream is = new ByteArrayInputStream(stringOfData.getBytes());
813 DebugLog.printRTAriDebug(fn, "Sending stringOfData --> " + fullPathDest);
814 sftp.put(is, fullPathDest, ChannelSftp.OVERWRITE);
815 DebugLog.printRTAriDebug(fn, "Sent successfully");
816 sftpSession.disconnect();
817 } catch (Exception e) {
818 DebugLog.printRTAriDebug(fn, "Caught an Exception, e=" + e);
819 // dbLog.storeData("ErrorMsg= sftp threw an Exception. error is:"+e);
820 throw new IOException(e.toString());
824 public String sftpGet(String fullFilePathName) throws IOException {
825 String fn = "SshJcraftWrapper.Sftp";
827 Session sftpSession = jsch.getSession(userName, hostName, 22);
828 UserInfo ui = new MyUserInfo();
829 sftpSession.setPassword(passWord);
830 sftpSession.setUserInfo(ui);
831 sftpSession.connect(30 * 1000);
832 DebugLog.printRTAriDebug(fn, "Opening up an sftp channel....");
833 ChannelSftp sftp = (ChannelSftp) sftpSession.openChannel("sftp");
834 DebugLog.printRTAriDebug(fn, "Connecting....");
836 InputStream in = null;
837 in = sftp.get(fullFilePathName);
838 String sftpFileString = readInputStreamAsString(in);
839 DebugLog.printRTAriDebug(fn, "Retreived successfully");
840 // DebugLog.printRTAriDebug (fn, "sftpFileString="+sftpFileString);
841 sftpSession.disconnect();
842 return (sftpFileString);
843 } catch (Exception e) {
844 DebugLog.printRTAriDebug(fn, "Caught an Exception, e=" + e);
845 throw new IOException(e.toString());
849 public static String readInputStreamAsString(InputStream in) throws IOException {
850 BufferedInputStream bis = new BufferedInputStream(in);
851 ByteArrayOutputStream buf = new ByteArrayOutputStream();
852 int result = bis.read();
853 while (result != -1) {
854 byte b = (byte) result;
858 return buf.toString();
862 public void logMemoryUsage() {
863 String fn = "SshJcraftWrapper.logMemoryUsage";
864 int mb = 1024 * 1024;
866 long maxMemoryAdvailable;
867 long memoryLetfOnHeap;
868 maxMemoryAdvailable = (runtime.maxMemory() / mb);
869 usedMemory = ((runtime.totalMemory() / mb) - (runtime.freeMemory() / mb));
870 memoryLetfOnHeap = maxMemoryAdvailable - usedMemory;
871 DebugLog.printAriDebug(fn,
872 "maxMemoryAdvailable=" + maxMemoryAdvailable + " usedMemory=" + usedMemory + " memoryLetfOnHeap="
876 // User specifies the port number, and the subsystem
877 public void connect(String hostname, String username, String password, String prompt, int timeOut, int portNum,
878 String subsystem) throws IOException {
879 String fn = "SshJcraftWrapper.connect";
881 DebugLog.printRTAriDebug(fn,
882 ":::Attempting to connect to " + hostname + " username=" + username + " password=" + password + " prompt='"
883 + prompt + "' timeOut=" + timeOut + " portNum=" + portNum + " subsystem=" + subsystem);
884 routerName = hostname;
887 session = jsch.getSession(username, hostname, portNum);
888 UserInfo ui = new MyUserInfo();
889 session.setPassword(password);
890 session.setUserInfo(ui);
891 session.setConfig("StrictHostKeyChecking", "no");
892 session.connect(timeOut);
893 session.setServerAliveCountMax(
894 0); // If this is not set to '0', then socket timeout on all reads will not work!!!!
895 channel = session.openChannel("subsystem");
896 ((ChannelSubsystem) channel).setSubsystem(subsystem);
897 // ((ChannelSubsystem)channel).setPtyType("vt102");
898 ((ChannelSubsystem) channel).setPty(true);
900 inputStream = channel.getInputStream();
901 dis = new DataInputStream(inputStream);
902 reader = new BufferedReader(new InputStreamReader(dis), BUFFER_SIZE);
904 DebugLog.printRTAriDebug(fn, "Successfully connected.");
905 DebugLog.printRTAriDebug(fn, "Five second sleep....");
908 } catch (java.lang.InterruptedException ee) {
909 boolean ignore = true;
911 } catch (Exception e) {
912 DebugLog.printRTAriDebug(fn, "Caught an Exception. e=" + e);
913 throw new IOException(e.toString());
917 public void connect(String hostName, String username, String password, int portNumber) throws IOException {
918 String fn = "SshJcraftWrapper.connect";
920 DebugLog.printRTAriDebug(fn,
921 "::Attempting to connect to " + hostName + " username=" + username + " password=" + password
922 + " portNumber=" + portNumber);
923 DebugLog.printRTAriDebug(fn, "Trace C");
924 routerName = hostName;
925 this.hostName = hostName;
929 java.util.Properties config = new java.util.Properties();
930 config.put("StrictHostKeyChecking", "no");
931 session = jsch.getSession(username, hostName, 22);
932 UserInfo ui = new MyUserInfo();
933 session.setConfig(config);
934 session.setPassword(password);
935 session.setUserInfo(ui);
936 session.connect(30000);
937 channel = session.openChannel("shell");
938 session.setServerAliveCountMax(
939 0); // If this is not set to '0', then socket timeout on all reads will not work!!!!
940 ((ChannelShell) channel).setPtyType("vt102");
941 inputStream = channel.getInputStream();
942 dis = new DataInputStream(inputStream);
943 reader = new BufferedReader(new InputStreamReader(dis), BUFFER_SIZE);
945 DebugLog.printRTAriDebug(fn, "::Successfully connected.");
946 DebugLog.printRTAriDebug(fn, "::Flushing input buffer");
948 receiveUntil(":~#", 9000, "No cmd was sent, just waiting, but we can stop on a '~#'");
949 } catch (Exception e) {
950 DebugLog.printRTAriDebug(fn, "Caught an Exception::: Nothing to flush out.");
953 } catch (Exception e) {
954 DebugLog.printRTAriDebug(fn, "Caught an Exception. e=" + e);
955 // dbLog.storeData("ErrorMsg= Exception trying to connect to "+hostName +" "+e);
956 throw new IOException(e.toString());
961 public void put(String sourcePath, String destDirectory) throws IOException {
962 String fn = "SshJcraftWrapper.sftp";
964 Session sftpSession = jsch.getSession(userName, hostName, 22);
965 UserInfo ui = new MyUserInfo();
966 sftpSession.setPassword(passWord);
967 sftpSession.setUserInfo(ui);
968 sftpSession.connect(30 * 1000);
969 DebugLog.printRTAriDebug(fn, "Opening up an sftp channel....");
970 ChannelSftp sftp = (ChannelSftp) sftpSession.openChannel("sftp");
971 DebugLog.printRTAriDebug(fn, "Connecting....");
973 DebugLog.printRTAriDebug(fn, "Sending " + sourcePath + " --> " + destDirectory);
974 sftp.put(sourcePath, destDirectory, ChannelSftp.OVERWRITE);
975 DebugLog.printRTAriDebug(fn, "Sent successfully");
976 sftpSession.disconnect();
977 } catch (Exception e) {
978 DebugLog.printRTAriDebug(fn, "Caught an Exception, e=" + e);
979 // dbLog.storeData("ErrorMsg= sftp threw an Exception. error is:"+e);
980 throw new IOException(e.toString());
984 public void put(InputStream is, String fullPathDest, String hostName, String userName, String passWord)
986 String fn = "SshJcraftWrapper.put";
987 Session sftpSession = null;
989 DebugLog.printRTAriDebug(fn, "userName=" + userName + " hostName=" + hostName + " passWord=" + passWord);
991 java.util.Properties config = new java.util.Properties();
992 config.put("StrictHostKeyChecking", "no");
993 sftpSession = jsch.getSession(userName, hostName, 22);
994 UserInfo ui = new MyUserInfo();
995 sftpSession.setPassword(passWord);
996 sftpSession.setUserInfo(ui);
997 sftpSession.setConfig(config);
998 sftpSession.connect(30 * 1000);
999 DebugLog.printRTAriDebug(fn, "Opening up an sftp channel....");
1000 ChannelSftp sftp = (ChannelSftp) sftpSession.openChannel("sftp");
1001 DebugLog.printRTAriDebug(fn, "Connecting....");
1003 String oldFiles = fullPathDest + "*";
1004 DebugLog.printRTAriDebug(fn, "Deleting old files --> " + oldFiles);
1007 DebugLog.printRTAriDebug(fn, "Sending stringOfData --> " + fullPathDest);
1008 } catch (SftpException sft) {
1009 String exp = "No such file";
1010 if (sft.getMessage() != null && sft.getMessage().contains(exp)) {
1011 DebugLog.printRTAriDebug(fn, "No files found -- Continue");
1013 DebugLog.printRTAriDebug(fn, "Exception while sftp.rm " + sft.getMessage());
1014 sft.printStackTrace();
1018 sftp.put(is, fullPathDest, ChannelSftp.OVERWRITE);
1019 DebugLog.printRTAriDebug(fn, "Sent successfully");
1020 } catch (Exception e) {
1021 DebugLog.printRTAriDebug(fn, "Caught an Exception, e=" + e);
1022 throw new IOException(e.toString());
1024 if (sftpSession != null) {
1025 sftpSession.disconnect();
1031 public String get(String fullFilePathName, String hostName, String userName, String passWord) throws IOException {
1032 String fn = "SshJcraftWrapper.get";
1033 Session sftpSession = null;
1035 DebugLog.printRTAriDebug(fn, "userName=" + userName + " hostName=" + hostName + " passWord=" + passWord);
1037 sftpSession = jsch.getSession(userName, hostName, 22);
1038 java.util.Properties config = new java.util.Properties();
1039 config.put("StrictHostKeyChecking", "no");
1040 UserInfo ui = new MyUserInfo();
1041 sftpSession.setPassword(passWord);
1042 sftpSession.setUserInfo(ui);
1043 sftpSession.setConfig(config);
1044 sftpSession.connect(30 * 1000);
1045 DebugLog.printRTAriDebug(fn, "Opening up an sftp channel....");
1046 ChannelSftp sftp = (ChannelSftp) sftpSession.openChannel("sftp");
1047 DebugLog.printRTAriDebug(fn, "Connecting....");
1049 InputStream in = sftp.get(fullFilePathName);
1050 String sftpFileString = readInputStreamAsString(in);
1051 DebugLog.printRTAriDebug(fn, "Retreived successfully");
1052 return sftpFileString;
1053 } catch (Exception e) {
1054 DebugLog.printRTAriDebug(fn, "Caught an Exception, e=" + e);
1055 throw new IOException(e.toString());
1057 if (sftpSession != null) {
1058 sftpSession.disconnect();
1063 public String send(String cmd, String delimiter) throws IOException {
1064 String fn = "SshJcraftWrapper.send";
1066 try (OutputStream os = channel.getOutputStream(); DataOutputStream dos = new DataOutputStream(os)) {
1067 sendSshCommand(cmd, dos);
1068 String response = receiveUntil(delimiter, 300000, cmd);
1069 DebugLog.printRTAriDebug(fn, "Leaving method");
1071 } catch (IOException e) {
1072 DebugLog.printRTAriDebug(fn, "Caught an IOException. e=" + e);
1073 dbLog.outputStackTrace(e);
1074 throw new IOException(e.toString());
1078 private void sendSshCommand(@Nonnull String originalCommand, @Nonnull DataOutputStream channelOutputStream)
1079 throws IOException {
1080 String fn = "SshJcraftWrapper.sendSshCommand";
1081 String command = enhanceCommandWithEOL(originalCommand);
1082 int length = command.length();
1083 int charsChunkSize = 300000;
1084 int charsTotalSent = 0;
1086 appendToFile(debugLogFileName, fn + ": Sending: '" + command);
1087 DebugLog.printRTAriDebug(fn, "Length of command is:" + length); // 2,937,706
1088 if (isCmdLengthEnoughToSendInChunks(length, charsChunkSize)) {
1090 for (int i = 0; i < length; i += charsChunkSize) {
1091 String commandChunk = command.substring(i, Math.min(length, i + charsChunkSize));
1092 int numCharsSentInChunk = commandChunk.length();
1093 charsTotalSent = charsTotalSent + commandChunk.length();
1094 DebugLog.printRTAriDebug(fn, "i=" + i + " Sending command: ncharsSent=" + numCharsSentInChunk);
1095 channelOutputStream.writeBytes(commandChunk);
1096 channelOutputStream.flush();
1098 DebugLog.printRTAriDebug(fn, ":::i=" + i + " length=" + length);
1099 if (numCharsSentInChunk < length) {
1100 receiveUntilBufferFlush(numCharsSentInChunk, timeout, "buffer flush i=" + i);
1102 DebugLog.printRTAriDebug(fn, "i=" + i + " No Waiting this time....");
1103 channelOutputStream.flush();
1105 } catch (Exception e) {
1106 DebugLog.printRTAriDebug(fn, "Caught an Exception: Nothing to flush out.");
1110 DebugLog.printRTAriDebug(fn, "Before executing the channelOutputStream.writeBytes");
1111 channelOutputStream.writeBytes(command);
1113 channelOutputStream.flush();
1114 DebugLog.printRTAriDebug(fn, "Leaving method");
1115 appendToFile(debugLogFileName, fn + ": Leaving method\n");
1118 private boolean isCmdLengthEnoughToSendInChunks(int length, int chunkSize) {
1119 return length > 2 * chunkSize;
1122 private String enhanceCommandWithEOL(@Nonnull String originalCommand) {
1123 char commandEnding = originalCommand.charAt(originalCommand.length() - 1);
1124 if (commandEnding != '\n' && commandEnding != '\r') {
1125 return originalCommand + "\n";
1127 return originalCommand;