Changed to unmaintained
[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 bufferSize = 512000;
72     char[] charBuffer = new char[bufferSize];
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), bufferSize);
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), bufferSize);
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, bufferSize);
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             while (rr.hasMoreTokens()) {
658                 sb.append(rr.nextToken() + '\n');
659             }
660         }
661         return (sb.toString());
662     }
663
664     public void setRouterCommandType(String type) {
665         String fn = "SshJcraftWrapper.setRouterCommandType";
666         this.routerCmdType = type;
667         DebugLog.printRTAriDebug(fn, "Setting routerCmdType to a value of '" + type + "'");
668     }
669
670     public String getLastFewLinesOfFile(File file, int linesToRead) throws IOException {
671         String fn = "SshJcraftWrapper.getLastFewLinesOfFile";
672         String tail = "";
673         try(RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r")) {
674             int lines = 0;
675             StringBuilder builder = new StringBuilder();
676             long length = file.length();
677             length--;
678             randomAccessFile.seek(length);
679             for (long seek = length; seek >= 0; --seek) {
680                 randomAccessFile.seek(seek);
681                 char c = (char) randomAccessFile.read();
682                 builder.append(c);
683                 if (c == '\n') {
684                     builder = builder.reverse();
685                     tail = builder.toString() + tail;
686                     lines++;
687                     builder.setLength(0);
688                     if (lines == linesToRead) {
689                         break;
690                     }
691                 }
692             }
693         }
694         if (!jcraftReadSwConfigFileFromDisk()) {
695             DebugLog.printRTAriDebug(fn, "tail='" + tail + "'");
696         }
697         appendToFile(debugLogFileName, "tail='" + tail + "'\n");
698         return tail;
699     }
700
701     public boolean jcraftReadSwConfigFileFromDisk() {
702         if (jcraftReadSwConfigFileFromDisk.exists()) {
703             return (true);
704         } else {
705             return (false);
706         }
707     }
708
709     public String getEquipNameCode() {
710         return (equipNameCode);
711
712     }
713
714     public void setEquipNameCode(String equipNameCode) {
715         this.equipNameCode = equipNameCode;
716     }
717
718     public String getRouterName() {
719         return (routerName);
720     }
721
722     // Routine does reads until it has read 'nchars' or times out.
723     public void receiveUntilBufferFlush(int ncharsSent, int timeout, String message)
724         throws TimedOutException, IOException {
725         String fn = "SshJcraftWrapper.receiveUntilBufferFlush";
726         DebugLog.printRTAriDebug(fn, "ncharsSent=" + ncharsSent + " timeout=" + timeout + " " + message);
727         int ncharsTotalReceived = 0;
728         int ncharsRead = 0;
729         charactersFromBufferFlush.setLength(0);
730
731         long deadline = new Date().getTime() + timeout;
732         logMemoryUsage();
733         try {
734             session.setTimeout(timeout);  // This is the socket timeout value.
735             while (true) {
736                 if (new Date().getTime() > deadline) {
737                     DebugLog.printRTAriDebug(fn,
738                         "Throwing a TimedOutException: time in routine has exceed our deadline: ncharsSent="
739                             + ncharsSent + " ncharsTotalReceived=" + ncharsTotalReceived);
740                     throw new TimedOutException("Timeout: time in routine has exceed our deadline");
741                 }
742                 ncharsRead = reader.read(charBuffer, 0, bufferSize);
743                 if (listener != null) {
744                     listener.receivedString(String.copyValueOf(charBuffer, 0, ncharsRead));
745                 }
746                 appendToRouterFile("/tmp/" + routerName, ncharsRead);
747                 ncharsTotalReceived = ncharsTotalReceived + ncharsRead;
748                 if (ncharsTotalReceived >= ncharsSent) {
749                     DebugLog.printRTAriDebug(fn,
750                         "Received the correct number of characters, ncharsSent=" + ncharsSent + " ncharsTotalReceived="
751                             + ncharsTotalReceived);
752                     logMemoryUsage();
753                     return;
754                 }
755             }
756         } catch (JSchException e) {
757             DebugLog.printRTAriDebug(fn, "Caught an JSchException e=" + e);
758             DebugLog.printRTAriDebug(fn,
759                 "ncharsSent=" + ncharsSent + " ncharsTotalReceived=" + ncharsTotalReceived + " ncharsRead="
760                     + ncharsRead);
761             throw new TimedOutException(e.toString());
762         }
763     }
764
765     public String getHostName() {
766         return (hostName);
767     }
768
769     public String getUserName() {
770         return (userName);
771     }
772
773     public String getPassWord() {
774         return (passWord);
775     }
776
777     public void sftpPut(String sourcePath, String destDirectory) throws IOException {
778         // delegate to duplicate method
779         put(sourcePath, destDirectory);
780     }
781
782
783     public void SftpPut(String stringOfData, String fullPathDest) throws IOException {
784         String fn = "SshJcraftWrapper.Sftp";
785         try {
786             Session sftpSession = jsch.getSession(userName, hostName, 22);
787             UserInfo ui = new MyUserInfo();
788             sftpSession.setPassword(passWord);
789             sftpSession.setUserInfo(ui);
790             sftpSession.connect(30 * 1000);
791             DebugLog.printRTAriDebug(fn, "Opening up an sftp channel....");
792             ChannelSftp sftp = (ChannelSftp) sftpSession.openChannel("sftp");
793             DebugLog.printRTAriDebug(fn, "Connecting....");
794             sftp.connect();
795             InputStream is = new ByteArrayInputStream(stringOfData.getBytes());
796             DebugLog.printRTAriDebug(fn, "Sending stringOfData --> " + fullPathDest);
797             sftp.put(is, fullPathDest, ChannelSftp.OVERWRITE);
798             DebugLog.printRTAriDebug(fn, "Sent successfully");
799             sftpSession.disconnect();
800         } catch (Exception e) {
801             DebugLog.printRTAriDebug(fn, "Caught an Exception, e=" + e);
802             throw new IOException(e.toString());
803         }
804     }
805
806     public String sftpGet(String fullFilePathName) throws IOException {
807         String fn = "SshJcraftWrapper.Sftp";
808         try {
809             Session sftpSession = jsch.getSession(userName, hostName, 22);
810             UserInfo ui = new MyUserInfo();
811             sftpSession.setPassword(passWord);
812             sftpSession.setUserInfo(ui);
813             sftpSession.connect(30 * 1000);
814             DebugLog.printRTAriDebug(fn, "Opening up an sftp channel....");
815             ChannelSftp sftp = (ChannelSftp) sftpSession.openChannel("sftp");
816             DebugLog.printRTAriDebug(fn, "Connecting....");
817             sftp.connect();
818             InputStream in = null;
819             in = sftp.get(fullFilePathName);
820             String sftpFileString = readInputStreamAsString(in);
821             DebugLog.printRTAriDebug(fn, "Retreived successfully");
822             sftpSession.disconnect();
823             return (sftpFileString);
824         } catch (Exception e) {
825             DebugLog.printRTAriDebug(fn, "Caught an Exception, e=" + e);
826             throw new IOException(e.toString());
827         }
828     }
829
830     public static String readInputStreamAsString(InputStream in) throws IOException {
831         BufferedInputStream bis = new BufferedInputStream(in);
832         ByteArrayOutputStream buf = new ByteArrayOutputStream();
833         int result = bis.read();
834         while (result != -1) {
835             byte b = (byte) result;
836             buf.write(b);
837             result = bis.read();
838         }
839         return buf.toString();
840     }
841
842
843     public void logMemoryUsage() {
844         String fn = "SshJcraftWrapper.logMemoryUsage";
845         int mb = 1024 * 1024;
846         long usedMemory;
847         long maxMemoryAdvailable;
848         long memoryLetfOnHeap;
849         maxMemoryAdvailable = (runtime.maxMemory() / mb);
850         usedMemory = ((runtime.totalMemory() / mb) - (runtime.freeMemory() / mb));
851         memoryLetfOnHeap = maxMemoryAdvailable - usedMemory;
852         DebugLog.printAriDebug(fn,
853             "maxMemoryAdvailable=" + maxMemoryAdvailable + " usedMemory=" + usedMemory + " memoryLetfOnHeap="
854                 + memoryLetfOnHeap);
855     }
856
857     // ----------------------------------------------------------------------------
858     // ----------------------------------------------------------------------------
859     // ----------------------------------------------------------------------------
860     // ----------------------------------------------------------------------------
861
862
863     // User specifies the port number, and the subsystem
864     public void connect(String hostname, String username, String password, String prompt, int timeOut, int portNum,
865         String subsystem) throws IOException {
866         String fn = "SshJcraftWrapper.connect";
867
868         DebugLog.printRTAriDebug(fn,
869             ":::Attempting to connect to " + hostname + " username=" + username + " prompt='"
870                 + prompt + "' timeOut=" + timeOut + " portNum=" + portNum + " subsystem=" + subsystem);
871         routerName = hostname;
872         jsch = getJSch();
873         try {
874             session = jsch.getSession(username, hostname, portNum);
875             UserInfo ui = new MyUserInfo();
876             session.setPassword(password);
877             session.setUserInfo(ui);
878             session.setConfig("StrictHostKeyChecking", "no");
879             session.connect(timeOut);
880             session.setServerAliveCountMax(
881                 0); // If this is not set to '0', then socket timeout on all reads will not work!!!!
882             channel = session.openChannel("subsystem");
883             ((ChannelSubsystem) channel).setSubsystem(subsystem);
884             ((ChannelSubsystem) channel).setPty(true);
885
886             inputStream = channel.getInputStream();
887             dis = new DataInputStream(inputStream);
888             reader = new BufferedReader(new InputStreamReader(dis), bufferSize);
889             channel.connect();
890             DebugLog.printRTAriDebug(fn, "Successfully connected.");
891             DebugLog.printRTAriDebug(fn, "Five second sleep....");
892             try {
893                 delay(5000);
894             } catch (java.lang.InterruptedException ee) {
895                 Thread.currentThread().interrupt();
896             }
897         } catch (Exception e) {
898             DebugLog.printRTAriDebug(fn, "Caught an Exception. e=" + e);
899             throw new IOException(e.toString());
900         }
901     }
902
903     public void connect(String hostName, String username, String password, int portNumber) throws IOException {
904         String fn = "SshJcraftWrapper.connect";
905         jsch = getJSch();
906         DebugLog.printRTAriDebug(fn,
907             "::Attempting to connect to " + hostName + " username=" + username + " portNumber=" + portNumber);
908         DebugLog.printRTAriDebug(fn, "Trace C");
909         routerName = hostName;
910         this.hostName = hostName;
911         userName = username;
912         passWord = password;
913         try {
914             java.util.Properties config = new java.util.Properties();
915             config.put("StrictHostKeyChecking", "no");
916             session = jsch.getSession(username, hostName, 22);
917             UserInfo ui = new MyUserInfo();
918             session.setConfig(config);
919             session.setPassword(password);
920             session.setUserInfo(ui);
921             session.connect(30000);
922             channel = session.openChannel("shell");
923             session.setServerAliveCountMax(
924                 0); // If this is not set to '0', then socket timeout on all reads will not work!!!!
925             ((ChannelShell) channel).setPtyType("vt102");
926             inputStream = channel.getInputStream();
927             dis = new DataInputStream(inputStream);
928             reader = new BufferedReader(new InputStreamReader(dis), bufferSize);
929             channel.connect();
930             DebugLog.printRTAriDebug(fn, "::Successfully connected.");
931             DebugLog.printRTAriDebug(fn, "::Flushing input buffer");
932             try {
933                 receiveUntil(":~#", 9000, "No cmd was sent, just waiting, but we can stop on a '~#'");
934             } catch (Exception e) {
935                 DebugLog.printRTAriDebug(fn, "Caught an Exception::: Nothing to flush out.");
936             }
937
938         } catch (Exception e) {
939             DebugLog.printRTAriDebug(fn, "Caught an Exception. e=" + e);
940             throw new IOException(e.toString());
941         }
942     }
943
944
945     public void put(String sourcePath, String destDirectory) throws IOException {
946         String fn = "SshJcraftWrapper.sftp";
947         try {
948             Session sftpSession = jsch.getSession(userName, hostName, 22);
949             UserInfo ui = new MyUserInfo();
950             sftpSession.setPassword(passWord);
951             sftpSession.setUserInfo(ui);
952             sftpSession.connect(30 * 1000);
953             DebugLog.printRTAriDebug(fn, "Opening up an sftp channel....");
954             ChannelSftp sftp = (ChannelSftp) sftpSession.openChannel("sftp");
955             DebugLog.printRTAriDebug(fn, "Connecting....");
956             sftp.connect();
957             DebugLog.printRTAriDebug(fn, "Sending " + sourcePath + " --> " + destDirectory);
958             sftp.put(sourcePath, destDirectory, ChannelSftp.OVERWRITE);
959             DebugLog.printRTAriDebug(fn, "Sent successfully");
960             sftpSession.disconnect();
961         } catch (Exception e) {
962             DebugLog.printRTAriDebug(fn, "Caught an Exception, e=" + e);
963             throw new IOException(e.toString());
964         }
965     }
966
967     public void put(InputStream is, String fullPathDest, String hostName, String userName, String passWord)
968         throws IOException {
969         String fn = "SshJcraftWrapper.put";
970         Session sftpSession = null;
971         try {
972             DebugLog.printRTAriDebug(fn, "userName=" + userName + " hostName=" + hostName);
973             jsch = getJSch();
974             java.util.Properties config = new java.util.Properties();
975             config.put("StrictHostKeyChecking", "no");
976             sftpSession = jsch.getSession(userName, hostName, 22);
977             UserInfo ui = new MyUserInfo();
978             sftpSession.setPassword(passWord);
979             sftpSession.setUserInfo(ui);
980             sftpSession.setConfig(config);
981             sftpSession.connect(30 * 1000);
982             DebugLog.printRTAriDebug(fn, "Opening up an sftp channel....");
983             ChannelSftp sftp = (ChannelSftp) sftpSession.openChannel("sftp");
984             DebugLog.printRTAriDebug(fn, "Connecting....");
985             sftp.connect();
986             String oldFiles = fullPathDest + "*";
987             DebugLog.printRTAriDebug(fn, "Deleting old files --> " + oldFiles);
988             try {
989                 sftp.rm(oldFiles);
990                 DebugLog.printRTAriDebug(fn, "Sending stringOfData --> " + fullPathDest);
991             } catch (SftpException sft) {
992                 String exp = "No such file";
993                 if (sft.getMessage() != null && sft.getMessage().contains(exp)) {
994                     DebugLog.printRTAriDebug(fn, "No files found -- Continue");
995                 } else {
996                     DebugLog.printRTAriDebug(fn, "Exception while sftp.rm " + sft.getMessage());
997                     throw sft;
998                 }
999             }
1000             sftp.put(is, fullPathDest, ChannelSftp.OVERWRITE);
1001             DebugLog.printRTAriDebug(fn, "Sent successfully");
1002         } catch (Exception e) {
1003             DebugLog.printRTAriDebug(fn, "Caught an Exception, e=" + e);
1004             throw new IOException(e.toString());
1005         } finally {
1006             if(sftpSession != null) {
1007                 sftpSession.disconnect();
1008             }
1009         }
1010     }
1011
1012
1013     public String get(String fullFilePathName, String hostName, String userName, String passWord) throws IOException {
1014         String fn = "SshJcraftWrapper.get";
1015         Session sftpSession = null;
1016         try {
1017             DebugLog.printRTAriDebug(fn, "userName=" + userName + " hostName=" + hostName);
1018             jsch = getJSch();
1019             sftpSession = jsch.getSession(userName, hostName, 22);
1020             java.util.Properties config = new java.util.Properties();
1021             config.put("StrictHostKeyChecking", "no");
1022             UserInfo ui = new MyUserInfo();
1023             sftpSession.setPassword(passWord);
1024             sftpSession.setUserInfo(ui);
1025             sftpSession.setConfig(config);
1026             sftpSession.connect(30 * 1000);
1027             DebugLog.printRTAriDebug(fn, "Opening up an sftp channel....");
1028             ChannelSftp sftp = (ChannelSftp) sftpSession.openChannel("sftp");
1029             DebugLog.printRTAriDebug(fn, "Connecting....");
1030             sftp.connect();
1031             InputStream in = sftp.get(fullFilePathName);
1032             String sftpFileString = readInputStreamAsString(in);
1033             DebugLog.printRTAriDebug(fn, "Retreived successfully");
1034             return sftpFileString;
1035         } catch (Exception e) {
1036             DebugLog.printRTAriDebug(fn, "Caught an Exception, e=" + e);
1037             throw new IOException(e.toString());
1038         } finally {
1039             if(sftpSession != null) {
1040                 sftpSession.disconnect();
1041             }
1042         }
1043     }
1044
1045     public String send(String cmd, String delimiter) throws IOException {
1046         String fn = "SshJcraftWrapper.send";
1047         OutputStream out = channel.getOutputStream();
1048         DataOutputStream dos = getDataOutputStream(out);
1049
1050         if ((cmd.charAt(cmd.length() - 1) != '\n') && (cmd.charAt(cmd.length() - 1) != '\r')) {
1051             cmd += "\n";
1052         }
1053         int length = cmd.length();
1054         int i = -1;
1055         int nchars = 300000;
1056         int ncharsTotalSent = 0;
1057         int ncharsSent = 0;
1058
1059         DebugLog.printRTAriDebug(fn, "Length of cmd is:" + length); // 2,937,706
1060         try {
1061             if (length > 600000) {
1062                 int timeout = 9000;
1063                 for (i = 0; i < length; i += nchars) {
1064                     String Cmd = cmd.substring(i, Math.min(length, i + nchars));
1065                     ncharsSent = Cmd.length();
1066                     ncharsTotalSent = ncharsTotalSent + Cmd.length();
1067                     DebugLog.printRTAriDebug(fn, "i=" + i + " Sending Cmd: ncharsSent=" + ncharsSent);
1068                     dos.writeBytes(Cmd);
1069                     dos.flush();
1070                     try {
1071                         DebugLog.printRTAriDebug(fn, ":::i=" + i + " length=" + length);
1072                         if (ncharsSent < length) {
1073                             receiveUntilBufferFlush(ncharsSent, timeout, "buffer flush  i=" + i);
1074                         } else {
1075                             DebugLog.printRTAriDebug(fn, "i=" + i + " No Waiting this time....");
1076                             dos.flush();
1077                         }
1078                     } catch (Exception e) {
1079                         DebugLog.printRTAriDebug(fn, "Caught an Exception: Nothing to flush out.");
1080                     }
1081                 }
1082             } else {
1083                 DebugLog.printRTAriDebug(fn, "Before executing the dos.writeBytes");
1084                 dos.writeBytes(cmd);
1085             }
1086             dos.flush();
1087             // Now lets get the response.
1088             String response = receiveUntil(delimiter, 300000, cmd);
1089             DebugLog.printRTAriDebug(fn, "Leaving method");
1090             return (response);
1091         } catch (IOException e) {
1092             DebugLog.printRTAriDebug(fn, "Caught an IOException. e=" + e);
1093             throw new IOException(e.toString());
1094         }
1095     }
1096
1097     protected JSch getJSch() {
1098         return new JSch();
1099     }
1100
1101     protected DataOutputStream getDataOutputStream(OutputStream out) {
1102         return new DataOutputStream(out);
1103     }
1104
1105     protected void delay(int milliseconds) throws InterruptedException {
1106         Thread.sleep(5000);
1107     }
1108 }