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