I am writing an application that provides a user-friendly GUI alternative to replace the current CLI users are using to communicate with remote devices. This application will send and receive all of the CLI I/O and convert it into easily understandable language for the user.
Since there is an open SSH connection between the application and the remote device at (almost) all times during execution, a background Thread
is processing the InputStream from the remote side and caching it so that my application may use it.
The problem I am running into is that when I call for the cached data, it is always behind where it should be and then is displayed as such.
Background Thread Class
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class ASAOutputStreamReader implements Runnable {
public volatile boolean stopNow;
private InputStream in;
public volatile String opString;
public volatile List<String> cachedOut = new ArrayList<String>();
ASAOutputStreamReader(InputStream in) {
this.in = in;
}
@Override
public void run() {
Scanner scan = new Scanner(in);
while (true) {
scan.useDelimiter("\r");
opString = scan.next();
System.out.println(opString);
// Add processed output to cache
cachedOut.add(opString);
if (stopNow) {
scan.close();
break;
}
}//end while
}
/* getNAT() - List<String>
* Method to return the cached strings
* from the ASA console, up to the point
* that the command was submitted
* NOTE: THIS WILL RETURN IN REVERSE ORDER
* But does not affect functionality
*/
public synchronized List<String> getNAT() {
List<String> str = new ArrayList<String>();
if (cachedOut.isEmpty() == false) {
for (int i = cachedOut.size()-1; i >= 0; i--) {
if (cachedOut.get(i).contains("show run static")) {
break;
}
str.add(cachedOut.get(i));
}
}
return str;
}
}
UI Button & Method
send_btn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// Defined separately to ensure Thread safety
updateNAT(listNATs, ip_tf.getText());
}
});
private void updateNAT(final JTextArea jta, final String host) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
ACL1.sendCmd("show run static | include " + host + "\r");
String str = "";
for (String s : ACL1.asaOSMonitor.getNAT()) {
str = str.concat(s).concat("\n");
}
jta.setText(str);
}
});
}
How can I guarantee that my data cache will be "up to date" before the call to update the UI to display it to the user?