Removed PrintStackTrace SshJcraftWrapper.java
[appc.git] / appc-config / appc-config-adaptor / provider / src / main / java / org / onap / appc / ccadaptor / SshJcraftWrapper.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * ONAP : APPC
4  * ================================================================================
5  * Copyright (C) 2017-2018 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Copyright (C) 2017 Amdocs
8  * ================================================================================
9  * Modifications Copyright (C) 2018 Ericsson
10  * ================================================================================
11  * Modifications Copyright (c) 2019 IBM
12  * ================================================================================
13  * Licensed under the Apache License, Version 2.0 (the "License");
14  * you may not use this file except in compliance with the License.
15  * You may obtain a copy of the License at
16  *
17  *      http://www.apache.org/licenses/LICENSE-2.0
18  *
19  * Unless required by applicable law or agreed to in writing, software
20  * distributed under the License is distributed on an "AS IS" BASIS,
21  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22  * See the License for the specific language governing permissions and
23  * limitations under the License.
24  *
25  * ============LICENSE_END=========================================================
26  */
27
28 package org.onap.appc.ccadaptor;
29
30 import com.jcraft.jsch.Channel;
31 import com.jcraft.jsch.ChannelSftp;
32 import com.jcraft.jsch.ChannelShell;
33 import com.jcraft.jsch.ChannelSubsystem;
34 import com.jcraft.jsch.JSch;
35 import com.jcraft.jsch.JSchException;
36 import com.jcraft.jsch.Session;
37 import com.jcraft.jsch.SftpException;
38 import com.jcraft.jsch.UIKeyboardInteractive;
39 import com.jcraft.jsch.UserInfo;
40 import java.io.BufferedInputStream;
41 import java.io.BufferedReader;
42 import java.io.BufferedWriter;
43 import java.io.ByteArrayInputStream;
44 import java.io.ByteArrayOutputStream;
45 import java.io.DataInputStream;
46 import java.io.DataOutputStream;
47 import java.io.File;
48 import java.io.FileWriter;
49 import java.io.IOException;
50 import java.io.InputStream;
51 import java.io.InputStreamReader;
52 import java.io.OutputStream;
53 import java.io.RandomAccessFile;
54 import java.text.DateFormat;
55 import java.text.SimpleDateFormat;
56 import java.util.Calendar;
57 import java.util.Date;
58 import java.util.StringTokenizer;
59 import org.apache.commons.lang.StringUtils;
60
61 public class SshJcraftWrapper {
62
63     InputStream inputStream = null;
64     OutputStream outputStream = null;
65     DebugLog debugLog = new DebugLog();
66     private String debugLogFileName = "/tmp/sshJcraftWrapperDebug";
67     private TelnetListener listener = null;
68     private String routerLogFileName = null;
69     private String host = null;
70     private String RouterName = null;
71     private int BUFFER_SIZE = 512000;
72     char[] charBuffer = new char[BUFFER_SIZE];
73     private DataInputStream dis = null;
74     private BufferedReader reader = null;
75     private BufferedWriter out = null;
76     private File _tmpFile = null;
77     private JSch jsch = null;
78     private Session session = null;
79     private Channel channel = null;
80     private String tId = "";
81     private String aggregatedReceivedString = "";
82     private File extraDebugFile = new File("/tmp/sshJcraftWrapperDEBUG");
83     private String routerCmdType = "XML";
84     private String routerFileName = null;
85     private File jcraftReadSwConfigFileFromDisk = new File("/tmp/jcraftReadSwConfigFileFromDisk");
86     private String equipNameCode = null;
87     private String hostName = null;
88     private String userName = null;
89     private String passWord = null;
90     private StringBuffer charactersFromBufferFlush = new StringBuffer();
91     private Runtime runtime = Runtime.getRuntime();
92     private DebugLog dbLog = new DebugLog();
93
94     public SshJcraftWrapper() {
95         String fn = "SshJcraftWrapper.SshJcraftWrapper";
96         DebugLog.printRTAriDebug(fn, "SshJcraftWrapper has been instantated");
97         routerLogFileName = "/tmp/" + host;
98     }
99
100     public void connect(String hostname, String username, String password, String prompt, int timeOut)
101         throws IOException {
102         String fn = "SshJcraftWrapper.connect";
103         jsch = getJSch();
104         DebugLog.printRTAriDebug(fn,
105             "Attempting to connect to " + hostname + " username=" + username + " prompt='"
106                 + prompt + "' timeOut=" + timeOut);
107         DebugLog.printRTAriDebug(fn, "Trace A");
108         RouterName = hostname;
109         hostName = hostname;
110         userName = username;
111         passWord = password;
112         try {
113             session = jsch.getSession(username, hostname, 22);
114             UserInfo ui = new MyUserInfo();
115             session.setPassword(password);
116             session.setUserInfo(ui);
117             session.connect(timeOut);
118             channel = session.openChannel("shell");
119             session.setServerAliveCountMax(
120                 0); // If this is not set to '0', then socket timeout on all reads will not work!!!!
121             ((ChannelShell) channel).setPtyType("vt102");
122             inputStream = channel.getInputStream();
123             dis = new DataInputStream(inputStream);
124             reader = new BufferedReader(new InputStreamReader(dis), BUFFER_SIZE);
125             channel.connect();
126             DebugLog.printRTAriDebug(fn, "Successfully connected.");
127             DebugLog.printRTAriDebug(fn, "Flushing input buffer");
128             try {
129                 receiveUntil(prompt, 3000, "No cmd was sent, just waiting");
130             } catch (Exception e) {
131                 DebugLog.printRTAriDebug(fn, "Caught an Exception: Nothing to flush out.");
132             }
133         } catch (Exception e) {
134             DebugLog.printRTAriDebug(fn, "Caught an Exception. e=" + e);
135             throw new IOException(e.toString());
136         }
137     }
138
139     // User specifies the port number.
140     public void connect(String hostname, String username, String password, String prompt, int timeOut, int portNum)
141         throws IOException {
142         String fn = "SshJcraftWrapper.connect";
143         DebugLog.printRTAriDebug(fn,
144             ":Attempting to connect to " + hostname + " username=" + username + " prompt='"
145                 + prompt + "' timeOut=" + timeOut + " portNum=" + portNum);
146         RouterName = hostname;
147         hostName = hostname;
148         userName = username;
149         passWord = password;
150         RouterName = hostname;
151         jsch = getJSch();
152         try {
153             session = jsch.getSession(username, hostname, portNum);
154             UserInfo ui = new MyUserInfo();
155             session.setPassword(password);
156             session.setUserInfo(ui);
157             session.setConfig("StrictHostKeyChecking", "no");
158             DebugLog.printRTAriDebug(fn, ":StrictHostKeyChecking set to 'no'");
159
160             session.connect(timeOut);
161             session.setServerAliveCountMax(
162                 0); // If this is not set to '0', then socket timeout on all reads will not work!!!!
163             channel = session.openChannel("shell");
164             ((ChannelShell) channel).setPtyType("vt102");
165             inputStream = channel.getInputStream();
166             dis = new DataInputStream(inputStream);
167             reader = new BufferedReader(new InputStreamReader(dis), BUFFER_SIZE);
168             channel.connect();
169             DebugLog.printRTAriDebug(fn, ":Successfully connected.");
170             DebugLog.printRTAriDebug(fn, ":Flushing input buffer");
171             try {
172                 if (prompt.equals("]]>]]>")) {
173                     receiveUntil("]]>]]>", 10000, "No cmd was sent, just waiting");
174                 } else {
175                     receiveUntil(":~#", 5000, "No cmd was sent, just waiting");
176                 }
177             } catch (Exception e) {
178                 DebugLog.printRTAriDebug(fn, "Caught an Exception::: Nothing to flush out.");
179             }
180         } catch (Exception e) {
181             DebugLog.printRTAriDebug(fn, ":Caught an Exception. e=" + e);
182             dbLog.outputStackTrace(e);
183
184             throw new IOException(e.toString());
185         }
186     }
187
188
189     public String receiveUntil(String delimeters, int timeout, String cmdThatWasSent)
190         throws TimedOutException, IOException {
191         String fn = "SshJcraftWrapper.receiveUntil";
192         boolean match = false;
193         boolean cliPromptCmd = false;
194         StringBuffer sb2 = new StringBuffer();
195         StringBuffer sbReceive = new StringBuffer();
196         DebugLog.printRTAriDebug(fn,
197             "delimeters='" + delimeters + "' timeout=" + timeout + " cmdThatWasSent='" + cmdThatWasSent + "'");
198         appendToFile(debugLogFileName,
199             fn + " delimeters='" + delimeters + "' timeout=" + timeout + " cmdThatWasSent='" + cmdThatWasSent + "'\n");
200         String CmdThatWasSent = removeWhiteSpaceAndNewLineCharactersAroundString(cmdThatWasSent);
201         int readCounts = 0;
202         aggregatedReceivedString = "";
203         FileWriter fileWriter = null;
204
205         long deadline = new Date().getTime() + timeout;
206         try {
207             session.setTimeout(timeout);  // This is the socket timeout value.
208             while (!match) {
209                 if (new Date().getTime() > deadline) {
210                     DebugLog.printRTAriDebug(fn,
211                         "Throwing a TimedOutException: time in routine has exceed our deadline: RouterName:"
212                             + RouterName + " CmdThatWasSent=" + CmdThatWasSent);
213                     throw new TimedOutException("Timeout: time in routine has exceed our deadline");
214                 }
215                 try {
216                     delay(500);
217                 } catch (java.lang.InterruptedException ee) {
218                     Thread.currentThread().interrupt();
219                 }
220                 int len = reader.read(charBuffer, 0, BUFFER_SIZE);
221                 appendToFile(debugLogFileName, fn + " After reader.read cmd: len=" + len + "\n");
222                 if (len <= 0) {
223                     DebugLog.printRTAriDebug(fn,
224                         "Reader read " + len + " bytes. Looks like we timed out, router=" + RouterName);
225                     throw new TimedOutException("Received a SocketTimeoutException router=" + RouterName);
226                 }
227                 if (!cliPromptCmd) {
228                     if (cmdThatWasSent.indexOf("IOS_XR_uploadedSwConfigCmd") != -1) {
229                         if (out == null) {
230                             // This is a IOS XR sw config file. We will write it to the disk.
231                             timeout = timeout * 2;
232                             deadline = new Date().getTime() + timeout;
233                             DebugLog.printRTAriDebug(fn, "IOS XR upload for software config: timeout=" + timeout);
234                             StringTokenizer st = new StringTokenizer(cmdThatWasSent);
235                             st.nextToken();
236                             routerFileName = st.nextToken();
237                             fileWriter = new FileWriter(routerFileName);
238                             out = new BufferedWriter(fileWriter);
239                             routerLogFileName = "/tmp/" + RouterName;
240                             _tmpFile = new File(routerLogFileName);
241                             DebugLog.printRTAriDebug(fn,
242                                 "Will write the swConfigFile to disk, routerFileName=" + routerFileName);
243                         }
244                         out.write(charBuffer, 0, len);
245                         out.flush();
246                         appendToFile(debugLogFileName, fn + " Wrote " + len + " bytes to the disk\n");
247                         if (_tmpFile.exists()) {
248                             appendToRouterFile(routerLogFileName, len);
249                         }
250                         match = checkIfReceivedStringMatchesDelimeter(len, "\nXML>");
251                         if (match == true) {
252                             out.flush();
253                             out.close();
254                             out = null;
255                             return null;
256                         }
257                     } else {
258                         readCounts++;
259                         appendToFile(debugLogFileName,
260                             fn + " readCounts=" + readCounts + "  Reader read " + len + " of data\n");
261                         int c;
262                         sb2.setLength(0);
263                         for (int i = 0; i < len; i++) {
264                             c = charBuffer[i];
265                             if ((c != 7) && (c != 13) && (c != 0) && (c != 27)) {
266                                 sbReceive.append((char) charBuffer[i]);
267                                 sb2.append((char) charBuffer[i]);
268                             }
269                         }
270                         appendToRouterFile("/tmp/" + RouterName, len);
271                         if (listener != null) {
272                             listener.receivedString(sb2.toString());
273                         }
274
275                         appendToFile(debugLogFileName, fn + " Trace 1\n");
276                         match = checkIfReceivedStringMatchesDelimeter(delimeters, sb2.toString(), cmdThatWasSent);
277                         appendToFile(debugLogFileName, fn + " Trace 2\n");
278                         if (match == true) {
279                             appendToFile(debugLogFileName, fn + " Match was true, breaking...\n");
280                             break;
281                         }
282                     }
283                 }
284             }
285         } catch (JSchException e) {
286             DebugLog.printRTAriDebug(fn, "Caught an JSchException e=" + e.toString());
287             dbLog.outputStackTrace(e);
288             throw new TimedOutException(e.toString());
289         } catch (IOException ee) {
290             DebugLog.printRTAriDebug(fn, "Caught an IOException: ee=" + ee.toString());
291             dbLog.outputStackTrace(ee);
292             throw new TimedOutException(ee.toString());
293         } finally {
294             try {
295                 if (fileWriter != null) {
296                     fileWriter.close();
297                 }
298             } catch(IOException ex) {
299                 DebugLog.printRTAriDebug(fn, "Failed to close fileWriter output stream: ex=" + ex);
300             }
301         }
302         String result = stripOffCmdFromRouterResponse(sbReceive.toString());
303         DebugLog.printRTAriDebug(fn, "Leaving method successfully");
304         return result;
305     }
306
307     public boolean checkIfReceivedStringMatchesDelimeter(String delimeters, String receivedString,
308         String cmdThatWasSent) {
309         // The delimeters are in a '|' seperated string. Return true on the first match.
310         String fn = "SshJcraftWrapper.checkIfReceivedStringMatchesDelimeter";
311         appendToFile(debugLogFileName,
312             fn + " Entered:  delimeters='" + delimeters + " cmdThatWasSent='" + cmdThatWasSent + "' receivedString='"
313                 + receivedString + "'\n");
314         StringTokenizer st = new StringTokenizer(delimeters, "|");
315
316         if ((delimeters.indexOf("#$") != -1) || (routerCmdType.equals("CLI")))  // This would be an IOS XR, CLI command.
317         {
318             int x = receivedString.lastIndexOf("#");
319             int y = receivedString.length() - 1;
320             appendToFile(debugLogFileName, fn + " IOS XR, CLI command\n");
321             if (extraDebugFile.exists()) {
322                 appendToFile(debugLogFileName,
323                     fn + " :::cmdThatWasSent='" + cmdThatWasSent + "'  x=" + x + " y=" + y + "\n");
324             }
325             return (x != -1) && (y == x);
326         }
327         if (cmdThatWasSent.indexOf("show config") != -1) {
328             appendToFile(debugLogFileName, fn + "In the block for 'show config'\n");
329             while (st.hasMoreTokens()) {
330                 String delimeter = st.nextToken();
331                 // Make sure we don't get faked out by a response of " #".
332                 // Proc #0
333                 //   # signaling-local-address ipv6 FD00:F4D5:EA06:1::110:136:254
334                 // LAAR2#
335                 int x = receivedString.lastIndexOf(delimeter);
336                 if ((receivedString.lastIndexOf(delimeter) != -1) && (receivedString.lastIndexOf(" #") != x - 1)) {
337                     appendToFile(debugLogFileName, fn + "receivedString=\n'" + receivedString + "'\n");
338                     appendToFile(debugLogFileName,
339                         fn + "Returning true for the 'show config' command. We found our real delmeter. \n\n");
340                     return (true);
341                 }
342             }
343         } else {
344             aggregatedReceivedString = aggregatedReceivedString + receivedString;
345             _appendToFile("/tmp/aggregatedReceivedString.debug", aggregatedReceivedString);
346
347             while (st.hasMoreTokens()) {
348                 String delimeter = st.nextToken();
349                 appendToFile(debugLogFileName, fn + " Looking for an delimeter of:'" + delimeter + "'\n");
350                 appendToFile(debugLogFileName, fn + " receivedString='" + receivedString);
351                 if (aggregatedReceivedString.indexOf(delimeter) != -1) {
352                     DebugLog.printRTAriDebug(fn, "Found our delimeter, which was: '" + delimeter + "'");
353                     aggregatedReceivedString = "";
354                     return (true);
355                 }
356             }
357         }
358         return (false);
359     }
360
361     public boolean checkIfReceivedStringMatchesDelimeter(int len, String delimeter) {
362         String fnName = "SshJcraftWrapper.checkIfReceivedStringMatchesDelimeter:::";
363         int x;
364         int c;
365         String str = StringUtils.EMPTY;
366
367         if (jcraftReadSwConfigFileFromDisk()) {
368             DebugLog.printAriDebug(fnName, "jcraftReadSwConfigFileFromDisk block");
369             File fileName = new File(routerFileName);
370             appendToFile(debugLogFileName,
371                 fnName + " jcraftReadSwConfigFileFromDisk::: Will read the tail end of the file from the disk");
372             try {
373                 str = getLastFewLinesOfFile(fileName, 3);
374             } catch (IOException e) {
375                 DebugLog.printAriDebug(fnName, "Caught an Exception, e=" + e);
376                 dbLog.outputStackTrace(e);
377             }
378         } else {
379             // When looking at the end of the charBuffer, don't include any linefeeds or spaces. We only want to make the smallest string possible.
380             for (x = len - 1; x >= 0; x--) {
381                 c = charBuffer[x];
382                 if (extraDebugFile.exists()) {
383                     appendToFile(debugLogFileName, fnName + " x=" + x + " c=" + c + "\n");
384                 }
385                 if ((c != 10) && (c != 32)) // Not a line feed nor a space.
386                 {
387                     break;
388                 }
389             }
390             if ((x + 1 - 13) >= 0) {
391                 str = new String(charBuffer, (x + 1 - 13), 13);
392                 appendToFile(debugLogFileName, fnName + " str:'" + str + "'\n");
393             } else {
394                 File fileName = new File(routerFileName);
395                 appendToFile(debugLogFileName,
396                     fnName + " Will read the tail end of the file from the disk, x=" + x + " len=" + len + " str::'"
397                         + str + "' routerFileName='" + routerFileName + "'\n");
398                 DebugLog.printAriDebug(fnName,
399                     "Will read the tail end of the file from the disk, x=" + x + " len=" + len + " str::'" + str
400                         + "' routerFileName='" + routerFileName + "'");
401                 try {
402                     str = getLastFewLinesOfFile(fileName, 3);
403                 } catch (IOException e) {
404                     DebugLog.printAriDebug(fnName, "Caught an Exception, e=" + e);
405                     dbLog.outputStackTrace(e);
406                 }
407             }
408         }
409
410         if (str.indexOf(delimeter) != -1) {
411             DebugLog.printAriDebug(fnName, "str in break is:'" + str + "'" + " delimeter='" + delimeter + "'");
412             appendToFile(debugLogFileName,
413                 fnName + " str in break is:'" + str + " delimeter='" + delimeter + "'" + "'\n");
414             return (true);
415         } else {
416             appendToFile(debugLogFileName, fnName + " Returning false");
417             return (false);
418         }
419
420     }
421
422     public void closeConnection() {
423         String fn = "SshJcraftWrapper.closeConnection";
424         DebugLog.printRTAriDebug(fn, "Executing the closeConnection....");
425         inputStream = null;
426         outputStream = null;
427         dis = null;
428         charBuffer = null;
429         session.disconnect();
430         session = null;
431     }
432
433     public void send(String cmd) throws IOException {
434         String fn = "SshJcraftWrapper.send";
435         OutputStream out = channel.getOutputStream();
436         DataOutputStream dos = getDataOutputStream(out);
437         if ((cmd.charAt(cmd.length() - 1) != '\n') && (cmd.charAt(cmd.length() - 1) != '\r')) {
438             cmd += "\n";
439         }
440         int length = cmd.length();
441         int i = -1;
442         int nchars = 300000;
443         int ncharsTotalSent = 0;
444         int ncharsSent = 0;
445
446         appendToFile(debugLogFileName, fn + ": Sending: '" + cmd);
447         DebugLog.printRTAriDebug(fn, "Length of cmd is:" + length); // 2,937,706
448         try {
449             if (length > 600000) {
450                 int timeout = 9000;
451                 for (i = 0; i < length; i += nchars) {
452                     String Cmd = cmd.substring(i, Math.min(length, i + nchars));
453                     ncharsSent = Cmd.length();
454                     ncharsTotalSent = ncharsTotalSent + Cmd.length();
455                     DebugLog.printRTAriDebug(fn, "i=" + i + " Sending Cmd: ncharsSent=" + ncharsSent);
456                     dos.writeBytes(Cmd);
457                     dos.flush();
458                     try {
459                         DebugLog.printRTAriDebug(fn, ":::i=" + i + " length=" + length);
460                         if (ncharsSent < length) {
461                             receiveUntilBufferFlush(ncharsSent, timeout, "buffer flush  i=" + i);
462                         } else {
463                             DebugLog.printRTAriDebug(fn, "i=" + i + " No Waiting this time....");
464                             dos.flush();
465                         }
466                     } catch (Exception e) {
467                         DebugLog.printRTAriDebug(fn, "Caught an Exception: Nothing to flush out.");
468                     }
469                 }
470             } else {
471                 DebugLog.printRTAriDebug(fn, "Before executing the dos.writeBytes");
472                 dos.writeBytes(cmd);
473             }
474             dos.flush();
475             DebugLog.printRTAriDebug(fn, "Leaving method");
476             appendToFile(debugLogFileName, fn + ": Leaving method\n");
477         } catch (IOException e) {
478             DebugLog.printRTAriDebug(fn, "Caught an IOException. e=" + e);
479             dbLog.outputStackTrace(e);
480             throw new IOException(e.toString());
481         }
482     }
483
484
485     public void sendChar(int v) throws IOException {
486         String fn = "SshJcraftWrapper.sendChar";
487         OutputStream out = channel.getOutputStream();
488         DataOutputStream dos = getDataOutputStream(out);
489         try {
490             DebugLog.printRTAriDebug(fn, "Sending: '" + v + "'");
491             dos.writeChar(v);
492             dos.flush();
493         } catch (IOException e) {
494             DebugLog.printRTAriDebug(fn, "Caught an IOException. e=" + e);
495             throw new IOException(e.toString());
496         }
497     }
498
499     public void send(byte[] b, int off, int len) throws IOException {
500         String fn = "SshJcraftWrapper.send:byte[]";
501         OutputStream out = channel.getOutputStream();
502         DataOutputStream dos = getDataOutputStream(out);
503         try {
504             dos.write(b, off, len);
505             dos.flush();
506         } catch (IOException e) {
507             DebugLog.printRTAriDebug(fn, "Caught an IOException. e=" + e);
508             throw new IOException(e.toString());
509         }
510     }
511
512     public static class MyUserInfo implements UserInfo, UIKeyboardInteractive {
513
514         public String getPassword() {
515             return null;
516         }
517
518         public boolean promptYesNo(String str) {
519             return false;
520         }
521
522         public String getPassphrase() {
523             return null;
524         }
525
526         public boolean promptPassphrase(String message) {
527             return false;
528         }
529
530         public boolean promptPassword(String message) {
531             return false;
532         }
533
534         public void showMessage(String message) {
535         }
536
537         public String[] promptKeyboardInteractive(String destination,
538             String name,
539             String instruction,
540             String[] prompt,
541             boolean[] echo) {
542             return null;
543         }
544     }
545
546     public void addListener(TelnetListener listener) {
547         this.listener = listener;
548     }
549
550     public void appendToFile(String fileName, String dataToWrite) {
551         String fn = "SshJcraftWrapper.appendToFile";
552
553         try {
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                 try(BufferedWriter out = new BufferedWriter(new FileWriter(fileName, true))) {
559                     out.write(getTheDate() + ": " + tId + ": " + dataToWrite);
560                 }
561             }
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);
566         }
567     }
568
569     public void _appendToFile(String fileName, String dataToWrite) {
570         String fn = "SshJcraftWrapper.appendToFile";
571
572         try {
573             // First check to see if a file 'fileName' exist, if it does
574             // write to it. If it does not exist, don't write to it.
575             File tmpFile = new File(fileName);
576             if (tmpFile.exists()) {
577                 try(BufferedWriter out = new BufferedWriter(new FileWriter(fileName, true))) {
578                     out.write(dataToWrite);
579                 }
580             }
581         } catch (IOException e) {
582             DebugLog.printRTAriDebug(fn, "Caught an IOException: e=" + e);
583         } catch (Exception e) {
584             DebugLog.printRTAriDebug(fn, "Caught an Exception: e=" + e);
585         }
586     }
587
588
589     public String getTheDate() {
590         Calendar cal = Calendar.getInstance();
591         java.util.Date today = cal.getTime();
592         DateFormat df3 = new SimpleDateFormat("MM/dd/yyyy H:mm:ss  ");
593         return (df3.format(today));
594     }
595
596
597     public void appendToRouterFile(String fileName, StringBuffer dataToWrite) {
598         String fnName = "SshJcraftWrapper.appendToRouterFile";
599         DebugLog.printRTAriDebug(fnName, "Entered.... ");
600         try {
601             // First check to see if a file 'fileName' exist, if it does
602             // write to it. If it does not exist, don't write to it.
603             File tmpFile = new File(fileName);
604             {
605                 if (tmpFile.exists()) {
606                     try(BufferedWriter out = new BufferedWriter(new FileWriter(fileName, true))) {
607                         out.write(dataToWrite.toString());
608                     }
609                 }
610             }
611         } catch (IOException e) {
612             DebugLog.printAriDebug(fnName, "writeToFile() exception:, e=" + e);
613             dbLog.outputStackTrace(e);
614         }
615     }
616
617     public void appendToRouterFile(String fileName, int len) {
618         try {
619             // First check to see if a file 'fileName' exist, if it does
620             // write to it. If it does not exist, don't write to it.
621             File tmpFile = new File(fileName);
622             if (tmpFile.exists()) {
623                 try(BufferedWriter out = new BufferedWriter(new FileWriter(fileName, true))) {
624                     out.write(charBuffer, 0, len);
625                 }
626             }
627         } catch (IOException e) {
628             dbLog.outputStackTrace(e);
629         }
630     }
631
632     public String removeWhiteSpaceAndNewLineCharactersAroundString(String str) {
633         if (str != null) {
634             StringTokenizer strTok = new StringTokenizer(str, "\n");
635             StringBuffer sb = new StringBuffer();
636
637             while (strTok.hasMoreTokens()) {
638                 String line = strTok.nextToken();
639                 sb.append(line);
640             }
641             return (sb.toString().trim());
642         } else {
643             return (str);
644         }
645     }
646
647     public String stripOffCmdFromRouterResponse(String routerResponse) {
648         // The session of SSH will echo the command sent to the router, in the router's response.
649         // Since all our commands are terminated by a '\n', strip off the first line
650         // of the response from the router. This first line contains the original command.
651
652         StringTokenizer rr = new StringTokenizer(routerResponse, "\n");
653         StringBuffer sb = new StringBuffer();
654
655         int numTokens = rr.countTokens();
656         if (numTokens > 1) {
657             rr.nextToken(); //Skip the first line.
658             while (rr.hasMoreTokens()) {
659                 sb.append(rr.nextToken() + '\n');
660             }
661         }
662         return (sb.toString());
663     }
664
665     public void setRouterCommandType(String type) {
666         String fn = "SshJcraftWrapper.setRouterCommandType";
667         this.routerCmdType = type;
668         DebugLog.printRTAriDebug(fn, "Setting routerCmdType to a value of '" + type + "'");
669     }
670
671     public String getLastFewLinesOfFile(File file, int linesToRead) throws IOException {
672         String fn = "SshJcraftWrapper.getLastFewLinesOfFile";
673         String tail = "";
674         try(RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r")) {
675             int lines = 0;
676             StringBuilder builder = new StringBuilder();
677             long length = file.length();
678             length--;
679             randomAccessFile.seek(length);
680             for (long seek = length; seek >= 0; --seek) {
681                 randomAccessFile.seek(seek);
682                 char c = (char) randomAccessFile.read();
683                 builder.append(c);
684                 if (c == '\n') {
685                     builder = builder.reverse();
686                     tail = builder.toString() + tail;
687                     lines++;
688                     builder.setLength(0);
689                     if (lines == linesToRead) {
690                         break;
691                     }
692                 }
693             }
694         }
695         if (!jcraftReadSwConfigFileFromDisk()) {
696             DebugLog.printRTAriDebug(fn, "tail='" + tail + "'");
697         }
698         appendToFile(debugLogFileName, "tail='" + tail + "'\n");
699         return tail;
700     }
701
702     public boolean jcraftReadSwConfigFileFromDisk() {
703         if (jcraftReadSwConfigFileFromDisk.exists()) {
704             return (true);
705         } else {
706             return (false);
707         }
708     }
709
710     public String getEquipNameCode() {
711         return (equipNameCode);
712
713     }
714
715     public void setEquipNameCode(String equipNameCode) {
716         this.equipNameCode = equipNameCode;
717     }
718
719     public String getRouterName() {
720         return (RouterName);
721     }
722
723     // Routine does reads until it has read 'nchars' or times out.
724     public void receiveUntilBufferFlush(int ncharsSent, int timeout, String message)
725         throws TimedOutException, IOException {
726         String fn = "SshJcraftWrapper.receiveUntilBufferFlush";
727         DebugLog.printRTAriDebug(fn, "ncharsSent=" + ncharsSent + " timeout=" + timeout + " " + message);
728         int ncharsTotalReceived = 0;
729         int ncharsRead = 0;
730         charactersFromBufferFlush.setLength(0);
731
732         long deadline = new Date().getTime() + timeout;
733         logMemoryUsage();
734         try {
735             session.setTimeout(timeout);  // This is the socket timeout value.
736             while (true) {
737                 if (new Date().getTime() > deadline) {
738                     DebugLog.printRTAriDebug(fn,
739                         "Throwing a TimedOutException: time in routine has exceed our deadline: ncharsSent="
740                             + ncharsSent + " ncharsTotalReceived=" + ncharsTotalReceived);
741                     throw new TimedOutException("Timeout: time in routine has exceed our deadline");
742                 }
743                 ncharsRead = reader.read(charBuffer, 0, BUFFER_SIZE);
744                 if (listener != null) {
745                     listener.receivedString(String.copyValueOf(charBuffer, 0, ncharsRead));
746                 }
747                 appendToRouterFile("/tmp/" + RouterName, ncharsRead);
748                 ncharsTotalReceived = ncharsTotalReceived + ncharsRead;
749                 if (ncharsTotalReceived >= ncharsSent) {
750                     DebugLog.printRTAriDebug(fn,
751                         "Received the correct number of characters, ncharsSent=" + ncharsSent + " ncharsTotalReceived="
752                             + ncharsTotalReceived);
753                     logMemoryUsage();
754                     return;
755                 }
756             }
757         } catch (JSchException e) {
758             DebugLog.printRTAriDebug(fn, "Caught an JSchException e=" + e);
759             DebugLog.printRTAriDebug(fn,
760                 "ncharsSent=" + ncharsSent + " ncharsTotalReceived=" + ncharsTotalReceived + " ncharsRead="
761                     + ncharsRead);
762             throw new TimedOutException(e.toString());
763         }
764     }
765
766     public String getHostName() {
767         return (hostName);
768     }
769
770     public String getUserName() {
771         return (userName);
772     }
773
774     public String getPassWord() {
775         return (passWord);
776     }
777
778     public void sftpPut(String sourcePath, String destDirectory) throws IOException {
779         // delegate to duplicate method
780         put(sourcePath, destDirectory);
781     }
782
783
784     public void SftpPut(String stringOfData, String fullPathDest) throws IOException {
785         String fn = "SshJcraftWrapper.Sftp";
786         try {
787             Session sftpSession = jsch.getSession(userName, hostName, 22);
788             UserInfo ui = new MyUserInfo();
789             sftpSession.setPassword(passWord);
790             sftpSession.setUserInfo(ui);
791             sftpSession.connect(30 * 1000);
792             DebugLog.printRTAriDebug(fn, "Opening up an sftp channel....");
793             ChannelSftp sftp = (ChannelSftp) sftpSession.openChannel("sftp");
794             DebugLog.printRTAriDebug(fn, "Connecting....");
795             sftp.connect();
796             InputStream is = new ByteArrayInputStream(stringOfData.getBytes());
797             DebugLog.printRTAriDebug(fn, "Sending stringOfData --> " + fullPathDest);
798             sftp.put(is, fullPathDest, ChannelSftp.OVERWRITE);
799             DebugLog.printRTAriDebug(fn, "Sent successfully");
800             sftpSession.disconnect();
801         } catch (Exception e) {
802             DebugLog.printRTAriDebug(fn, "Caught an Exception, e=" + e);
803             throw new IOException(e.toString());
804         }
805     }
806
807     public String sftpGet(String fullFilePathName) throws IOException {
808         String fn = "SshJcraftWrapper.Sftp";
809         try {
810             Session sftpSession = jsch.getSession(userName, hostName, 22);
811             UserInfo ui = new MyUserInfo();
812             sftpSession.setPassword(passWord);
813             sftpSession.setUserInfo(ui);
814             sftpSession.connect(30 * 1000);
815             DebugLog.printRTAriDebug(fn, "Opening up an sftp channel....");
816             ChannelSftp sftp = (ChannelSftp) sftpSession.openChannel("sftp");
817             DebugLog.printRTAriDebug(fn, "Connecting....");
818             sftp.connect();
819             InputStream in = null;
820             in = sftp.get(fullFilePathName);
821             String sftpFileString = readInputStreamAsString(in);
822             DebugLog.printRTAriDebug(fn, "Retreived successfully");
823             sftpSession.disconnect();
824             return (sftpFileString);
825         } catch (Exception e) {
826             DebugLog.printRTAriDebug(fn, "Caught an Exception, e=" + e);
827             throw new IOException(e.toString());
828         }
829     }
830
831     public static String readInputStreamAsString(InputStream in) throws IOException {
832         BufferedInputStream bis = new BufferedInputStream(in);
833         ByteArrayOutputStream buf = new ByteArrayOutputStream();
834         int result = bis.read();
835         while (result != -1) {
836             byte b = (byte) result;
837             buf.write(b);
838             result = bis.read();
839         }
840         return buf.toString();
841     }
842
843
844     public void logMemoryUsage() {
845         String fn = "SshJcraftWrapper.logMemoryUsage";
846         int mb = 1024 * 1024;
847         long usedMemory;
848         long maxMemoryAdvailable;
849         long memoryLetfOnHeap;
850         maxMemoryAdvailable = (runtime.maxMemory() / mb);
851         usedMemory = ((runtime.totalMemory() / mb) - (runtime.freeMemory() / mb));
852         memoryLetfOnHeap = maxMemoryAdvailable - usedMemory;
853         DebugLog.printAriDebug(fn,
854             "maxMemoryAdvailable=" + maxMemoryAdvailable + " usedMemory=" + usedMemory + " memoryLetfOnHeap="
855                 + memoryLetfOnHeap);
856     }
857
858     // ----------------------------------------------------------------------------
859     // ----------------------------------------------------------------------------
860     // ----------------------------------------------------------------------------
861     // ----------------------------------------------------------------------------
862
863
864     // User specifies the port number, and the subsystem
865     public void connect(String hostname, String username, String password, String prompt, int timeOut, int portNum,
866         String subsystem) throws IOException {
867         String fn = "SshJcraftWrapper.connect";
868
869         DebugLog.printRTAriDebug(fn,
870             ":::Attempting to connect to " + hostname + " username=" + username + " prompt='"
871                 + prompt + "' timeOut=" + timeOut + " portNum=" + portNum + " subsystem=" + subsystem);
872         RouterName = hostname;
873         jsch = getJSch();
874         try {
875             session = jsch.getSession(username, hostname, portNum);
876             UserInfo ui = new MyUserInfo();
877             session.setPassword(password);
878             session.setUserInfo(ui);
879             session.setConfig("StrictHostKeyChecking", "no");
880             session.connect(timeOut);
881             session.setServerAliveCountMax(
882                 0); // If this is not set to '0', then socket timeout on all reads will not work!!!!
883             channel = session.openChannel("subsystem");
884             ((ChannelSubsystem) channel).setSubsystem(subsystem);
885             ((ChannelSubsystem) channel).setPty(true);
886
887             inputStream = channel.getInputStream();
888             dis = new DataInputStream(inputStream);
889             reader = new BufferedReader(new InputStreamReader(dis), BUFFER_SIZE);
890             channel.connect();
891             DebugLog.printRTAriDebug(fn, "Successfully connected.");
892             DebugLog.printRTAriDebug(fn, "Five second sleep....");
893             try {
894                 delay(5000);
895             } catch (java.lang.InterruptedException ee) {
896                 Thread.currentThread().interrupt();
897             }
898         } catch (Exception e) {
899             DebugLog.printRTAriDebug(fn, "Caught an Exception. e=" + e);
900             throw new IOException(e.toString());
901         }
902     }
903
904     public void connect(String hostName, String username, String password, int portNumber) throws IOException {
905         String fn = "SshJcraftWrapper.connect";
906         jsch = getJSch();
907         DebugLog.printRTAriDebug(fn,
908             "::Attempting to connect to " + hostName + " username=" + username + " portNumber=" + portNumber);
909         DebugLog.printRTAriDebug(fn, "Trace C");
910         RouterName = hostName;
911         this.hostName = hostName;
912         userName = username;
913         passWord = password;
914         try {
915             java.util.Properties config = new java.util.Properties();
916             config.put("StrictHostKeyChecking", "no");
917             session = jsch.getSession(username, hostName, 22);
918             UserInfo ui = new MyUserInfo();
919             session.setConfig(config);
920             session.setPassword(password);
921             session.setUserInfo(ui);
922             session.connect(30000);
923             channel = session.openChannel("shell");
924             session.setServerAliveCountMax(
925                 0); // If this is not set to '0', then socket timeout on all reads will not work!!!!
926             ((ChannelShell) channel).setPtyType("vt102");
927             inputStream = channel.getInputStream();
928             dis = new DataInputStream(inputStream);
929             reader = new BufferedReader(new InputStreamReader(dis), BUFFER_SIZE);
930             channel.connect();
931             DebugLog.printRTAriDebug(fn, "::Successfully connected.");
932             DebugLog.printRTAriDebug(fn, "::Flushing input buffer");
933             try {
934                 receiveUntil(":~#", 9000, "No cmd was sent, just waiting, but we can stop on a '~#'");
935             } catch (Exception e) {
936                 DebugLog.printRTAriDebug(fn, "Caught an Exception::: Nothing to flush out.");
937             }
938
939         } catch (Exception e) {
940             DebugLog.printRTAriDebug(fn, "Caught an Exception. e=" + e);
941             throw new IOException(e.toString());
942         }
943     }
944
945
946     public void put(String sourcePath, String destDirectory) throws IOException {
947         String fn = "SshJcraftWrapper.sftp";
948         try {
949             Session sftpSession = jsch.getSession(userName, hostName, 22);
950             UserInfo ui = new MyUserInfo();
951             sftpSession.setPassword(passWord);
952             sftpSession.setUserInfo(ui);
953             sftpSession.connect(30 * 1000);
954             DebugLog.printRTAriDebug(fn, "Opening up an sftp channel....");
955             ChannelSftp sftp = (ChannelSftp) sftpSession.openChannel("sftp");
956             DebugLog.printRTAriDebug(fn, "Connecting....");
957             sftp.connect();
958             DebugLog.printRTAriDebug(fn, "Sending " + sourcePath + " --> " + destDirectory);
959             sftp.put(sourcePath, destDirectory, ChannelSftp.OVERWRITE);
960             DebugLog.printRTAriDebug(fn, "Sent successfully");
961             sftpSession.disconnect();
962         } catch (Exception e) {
963             DebugLog.printRTAriDebug(fn, "Caught an Exception, e=" + e);
964             throw new IOException(e.toString());
965         }
966     }
967
968     public void put(InputStream is, String fullPathDest, String hostName, String userName, String passWord)
969         throws IOException {
970         String fn = "SshJcraftWrapper.put";
971         Session sftpSession = null;
972         try {
973             DebugLog.printRTAriDebug(fn, "userName=" + userName + " hostName=" + hostName);
974             jsch = getJSch();
975             java.util.Properties config = new java.util.Properties();
976             config.put("StrictHostKeyChecking", "no");
977             sftpSession = jsch.getSession(userName, hostName, 22);
978             UserInfo ui = new MyUserInfo();
979             sftpSession.setPassword(passWord);
980             sftpSession.setUserInfo(ui);
981             sftpSession.setConfig(config);
982             sftpSession.connect(30 * 1000);
983             DebugLog.printRTAriDebug(fn, "Opening up an sftp channel....");
984             ChannelSftp sftp = (ChannelSftp) sftpSession.openChannel("sftp");
985             DebugLog.printRTAriDebug(fn, "Connecting....");
986             sftp.connect();
987             String oldFiles = fullPathDest + "*";
988             DebugLog.printRTAriDebug(fn, "Deleting old files --> " + oldFiles);
989             try {
990                 sftp.rm(oldFiles);
991                 DebugLog.printRTAriDebug(fn, "Sending stringOfData --> " + fullPathDest);
992             } catch (SftpException sft) {
993                 String exp = "No such file";
994                 if (sft.getMessage() != null && sft.getMessage().contains(exp)) {
995                     DebugLog.printRTAriDebug(fn, "No files found -- Continue");
996                 } else {
997                     DebugLog.printRTAriDebug(fn, "Exception while sftp.rm " + sft.getMessage());
998                     throw sft;
999                 }
1000             }
1001             sftp.put(is, fullPathDest, ChannelSftp.OVERWRITE);
1002             DebugLog.printRTAriDebug(fn, "Sent successfully");
1003         } catch (Exception e) {
1004             DebugLog.printRTAriDebug(fn, "Caught an Exception, e=" + e);
1005             throw new IOException(e.toString());
1006         } finally {
1007             if(sftpSession != null) {
1008                 sftpSession.disconnect();
1009             }
1010         }
1011     }
1012
1013
1014     public String get(String fullFilePathName, String hostName, String userName, String passWord) throws IOException {
1015         String fn = "SshJcraftWrapper.get";
1016         Session sftpSession = null;
1017         try {
1018             DebugLog.printRTAriDebug(fn, "userName=" + userName + " hostName=" + hostName);
1019             jsch = getJSch();
1020             sftpSession = jsch.getSession(userName, hostName, 22);
1021             java.util.Properties config = new java.util.Properties();
1022             config.put("StrictHostKeyChecking", "no");
1023             UserInfo ui = new MyUserInfo();
1024             sftpSession.setPassword(passWord);
1025             sftpSession.setUserInfo(ui);
1026             sftpSession.setConfig(config);
1027             sftpSession.connect(30 * 1000);
1028             DebugLog.printRTAriDebug(fn, "Opening up an sftp channel....");
1029             ChannelSftp sftp = (ChannelSftp) sftpSession.openChannel("sftp");
1030             DebugLog.printRTAriDebug(fn, "Connecting....");
1031             sftp.connect();
1032             InputStream in = sftp.get(fullFilePathName);
1033             String sftpFileString = readInputStreamAsString(in);
1034             DebugLog.printRTAriDebug(fn, "Retreived successfully");
1035             return sftpFileString;
1036         } catch (Exception e) {
1037             DebugLog.printRTAriDebug(fn, "Caught an Exception, e=" + e);
1038             throw new IOException(e.toString());
1039         } finally {
1040             if(sftpSession != null) {
1041                 sftpSession.disconnect();
1042             }
1043         }
1044     }
1045
1046     public String send(String cmd, String delimiter) throws IOException {
1047         String fn = "SshJcraftWrapper.send";
1048         OutputStream out = channel.getOutputStream();
1049         DataOutputStream dos = getDataOutputStream(out);
1050
1051         if ((cmd.charAt(cmd.length() - 1) != '\n') && (cmd.charAt(cmd.length() - 1) != '\r')) {
1052             cmd += "\n";
1053         }
1054         int length = cmd.length();
1055         int i = -1;
1056         int nchars = 300000;
1057         int ncharsTotalSent = 0;
1058         int ncharsSent = 0;
1059
1060         DebugLog.printRTAriDebug(fn, "Length of cmd is:" + length); // 2,937,706
1061         try {
1062             if (length > 600000) {
1063                 int timeout = 9000;
1064                 for (i = 0; i < length; i += nchars) {
1065                     String Cmd = cmd.substring(i, Math.min(length, i + nchars));
1066                     ncharsSent = Cmd.length();
1067                     ncharsTotalSent = ncharsTotalSent + Cmd.length();
1068                     DebugLog.printRTAriDebug(fn, "i=" + i + " Sending Cmd: ncharsSent=" + ncharsSent);
1069                     dos.writeBytes(Cmd);
1070                     dos.flush();
1071                     try {
1072                         DebugLog.printRTAriDebug(fn, ":::i=" + i + " length=" + length);
1073                         if (ncharsSent < length) {
1074                             receiveUntilBufferFlush(ncharsSent, timeout, "buffer flush  i=" + i);
1075                         } else {
1076                             DebugLog.printRTAriDebug(fn, "i=" + i + " No Waiting this time....");
1077                             dos.flush();
1078                         }
1079                     } catch (Exception e) {
1080                         DebugLog.printRTAriDebug(fn, "Caught an Exception: Nothing to flush out.");
1081                     }
1082                 }
1083             } else {
1084                 DebugLog.printRTAriDebug(fn, "Before executing the dos.writeBytes");
1085                 dos.writeBytes(cmd);
1086             }
1087             dos.flush();
1088             // Now lets get the response.
1089             String response = receiveUntil(delimiter, 300000, cmd);
1090             DebugLog.printRTAriDebug(fn, "Leaving method");
1091             return (response);
1092         } catch (IOException e) {
1093             DebugLog.printRTAriDebug(fn, "Caught an IOException. e=" + e);
1094             throw new IOException(e.toString());
1095         }
1096     }
1097
1098     protected JSch getJSch() {
1099         return new JSch();
1100     }
1101
1102     protected DataOutputStream getDataOutputStream(OutputStream out) {
1103         return new DataOutputStream(out);
1104     }
1105
1106     protected void delay(int milliseconds) throws InterruptedException {
1107         Thread.sleep(5000);
1108     }
1109 }