org.peace_tools.core.session
Class RemoteServerSession

java.lang.Object
  extended by org.peace_tools.core.session.ServerSession
      extended by org.peace_tools.core.session.RemoteServerSession
All Implemented Interfaces:
ch.ethz.ssh2.ServerHostKeyVerifier

public class RemoteServerSession
extends ServerSession
implements ch.ethz.ssh2.ServerHostKeyVerifier

A remote server session based on the secure shell (SSH) protocol.

This class provides an implementation of the ServerSession API. Specifically, this class provides a session that can be used to interact with a remote host via the secure shell (SSH) protocol. The secure shell protocol is a defacto standard for interacting with remote servers via the Internet today. It provides all the necessary security features to safely interact with remote hosts and almost all super computing clusters mandate the use of SSH for interactions.

This class uses the Ganymede SSH implementation for establishing SSH connections. Ganymede SSH supports only ssh-2 protocol. Please refer to Genymede SSH website for further details: http://www.ganymed.ethz.ch/ssh2/. PEACE distributes Ganymede license file as per Ganymede licensing requirements.


Nested Class Summary
 
Nested classes/interfaces inherited from class org.peace_tools.core.session.ServerSession
ServerSession.OSType
 
Field Summary
private  ch.ethz.ssh2.Connection connection
          The connection to the remote server via which the remote server can be accessed for performing various operations.
private static java.lang.String KnownHostPath
          The OS-specific path where the list of known hosts (that is the servers to which we have connected before) is stored.
private static ch.ethz.ssh2.KnownHosts knownHosts
          This is a convenience class that is provided by Ganymede SSH to store information about servers/hosts that we have already connected to.
private static java.lang.Object knownHostsLock
          This object is merely used to arbitrate access to the knownHosts object so that operations on knownHosts is MT-Safe.
private  ServerSession.OSType osType
          The last known OS type for the remote server.
private  java.lang.String purpose
          A simple textual information indicating the purpose for this session.
 
Fields inherited from class org.peace_tools.core.session.ServerSession
parent, server
 
Constructor Summary
protected RemoteServerSession(java.awt.Component parent, Server server)
          The constructor merely passes parameters to the base class that initializes the instance variables.
 
Method Summary
private  void addKnownHost(java.lang.String hostname, int port, java.lang.String serverHostKeyAlgorithm, byte[] serverHostKey)
          Method to add a new host entry to the list of known hosts.
 void connect()
          Connect to the server in order to perform various operations.
 void copy(java.io.InputStream srcData, java.lang.String destDirectory, java.lang.String destFileName, java.lang.String mode)
          Copy given data from an input stream to a given file on the remote machine.
 void copy(java.io.OutputStream destData, java.lang.String srcDirectory, java.lang.String srcFileName, javax.swing.JProgressBar progBar)
          Copy file from a remote machine to a given output stream.
 void disconnect()
          Method to disconnect from a remote server.
 int exec(java.lang.String command, javax.swing.text.DefaultStyledDocument output)
          This method can be used to run a long running command that may produce verbose output.
 int exec(java.lang.String command, java.lang.String[] outputs)
          This method can be used to run a brief command that produces succinct output.
 FileInfo fstat(java.lang.String path)
          Obtain information about a given path on the remote machine.
 ServerSession.OSType getOSType()
          Determine the type of OS that this session is connected to.
private  void getPassword()
          Helper method to check and get password from the user.
private  void loadKnownHosts()
          This is a helper method that is invoked just before a remote session establishes connection with a server.
 void mkdir(java.lang.String directory)
          Creates a directory on the server.
 void rmdir(java.lang.String directory)
          Deletes an empty directory on the server.
 void setPurpose(java.lang.String text)
          A simple method to set a purpose message for this session.
 boolean verifyServerHostKey(java.lang.String hostname, int port, java.lang.String serverHostKeyAlgorithm, byte[] serverHostKey)
          Interactive verifier for use with Ganymede SSH callback.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

connection

private ch.ethz.ssh2.Connection connection
The connection to the remote server via which the remote server can be accessed for performing various operations. The connection is created via the connect() method.


osType

private ServerSession.OSType osType
The last known OS type for the remote server. This value is set after the getOSType() method is called. If a connection is lost or closed, then this value is reset.


knownHosts

private static ch.ethz.ssh2.KnownHosts knownHosts
This is a convenience class that is provided by Ganymede SSH to store information about servers/hosts that we have already connected to. This data is loaded once initially and is shared by all RemoteServerSession instances. This enables us to load the data once and keep updating and using it rather than loading it each time (which should save some CPU cycles).


knownHostsLock

private static java.lang.Object knownHostsLock
This object is merely used to arbitrate access to the knownHosts object so that operations on knownHosts is MT-Safe.


purpose

private java.lang.String purpose
A simple textual information indicating the purpose for this session. This string is more meanigful to the user and is merely used to provide additional information when prompting for inputs from the user.


KnownHostPath

private static final java.lang.String KnownHostPath
The OS-specific path where the list of known hosts (that is the servers to which we have connected before) is stored. This list is applicable only for remote hosts.

Constructor Detail

RemoteServerSession

protected RemoteServerSession(java.awt.Component parent,
                              Server server)
The constructor merely passes parameters to the base class that initializes the instance variables. No special operations are performed in the constructor.

Parameters:
server - The server data entry that provides the necessary information to connect to the server.
parent - The parent component that should be used to create GUI elements that may be needed for any interactive operations.
Method Detail

connect

public void connect()
             throws java.io.IOException
Connect to the server in order to perform various operations. This method must be used to establish a connection to a server before performing any tasks. This method is overridden in the derived class to perform the following operations:
  1. It first initializes the list of known hosts (servers we have connected to before) from the ".KnownHosts" file.
  2. It ensures that the host name for the remote host can be resolved, thereby establishing its basic validity.
  3. It connects to the remote server by creating a Ganymede connection object.
  4. It then authenticates with the user by providing the user name and password stored in the Server object supplied when this class was instantiated.

Note: The process of establishing a connection can be a time consuming task. In some cases incorrect host names can cause long connection times (until the connection times out which can be in minutes). Consequently, it is best to call this method from a separate daemon thread.

Specified by:
connect in class ServerSession
Throws:
java.io.IOException - This method throws IO exceptions in the case of errors. If an error occurs, then a connection was not established and the caller will have to try again to establish a connection.

getPassword

private void getPassword()
                  throws java.io.IOException
Helper method to check and get password from the user.

Throws:
java.io.IOException

disconnect

public void disconnect()
Method to disconnect from a remote server. This method disconnects from the remote server if it is connected. All current sessions will be terminated.

Specified by:
disconnect in class ServerSession

exec

public int exec(java.lang.String command,
                java.lang.String[] outputs)
         throws java.lang.Exception
This method can be used to run a brief command that produces succinct output. This method provides a convenient API to execute a command on a remote server, buffer the output, and return the resulting output as a string. Since this method buffers and returns the output, it must be used only for jobs that return small volumes of data. In addition, since the method returns the results only after the command has fully executed, it does not provide any interactive features to the user. Consequently, it should be used only for jobs that run for a short period of time.

Note: The connection to the remote server must have been established successfully via a call to connect method.

Specified by:
exec in class ServerSession
Parameters:
command - The command line to be executed. This command must be compatible with the target machine's OS. Otherwise this method will generate an exception.
outputs - The buffered results from the standard output and standard error streams of the remote process.
Returns:
The exit code from the remote command that was run.
Throws:
java.lang.Exception - If the execution produces an error then this method throws an exception.

exec

public int exec(java.lang.String command,
                javax.swing.text.DefaultStyledDocument output)
         throws java.lang.Exception
This method can be used to run a long running command that may produce verbose output. This method provides a convenient API to execute a command on a remote server, stream the output, and return the exit code from the remote command. The outputs are streamed to a given StyledDocument. This method uses styles named "stdout", "stderr", and "warning" (if available in the given output document)

Note: The connection to the remote server must have been established successfully via a call to connect method.

Specified by:
exec in class ServerSession
Parameters:
command - The command line to be executed. This command must be compatible with the target machine's OS. Otherwise this method will generate an exception.
output - The styled document to which the standard output and standard error streams are to be written.
Returns:
The exit code from the remote command that was run.
Throws:
java.lang.Exception - If the execution produces an error then this method throws an exception.

verifyServerHostKey

public boolean verifyServerHostKey(java.lang.String hostname,
                                   int port,
                                   java.lang.String serverHostKeyAlgorithm,
                                   byte[] serverHostKey)
                            throws java.lang.Exception
Interactive verifier for use with Ganymede SSH callback. This method is called by the Ganymede SSH layer once it has established initial communication with the remote server. This method is invoked to verify if the SSH client should proceed with the connection, given the server's credentials. This method checks the credentials of the server against the values in the KnownHosts file. If the value is present then this method proceeds with the connection. Otherwise it provides the necessary information to the user to determine if the user wants to proceed. If the user wants to proceed then this method adds the host information to the KnownHosts file and returns true.

Specified by:
verifyServerHostKey in interface ch.ethz.ssh2.ServerHostKeyVerifier
Parameters:
hostname - The host name to be added to the list.
port - The port associated with the remote connection. Currently this is not used.
serverHostKeyAlgorithm - The string name for the certificate encryption algorithm (such as: ssh-rsa2 etc.)
serverHostKey - The host key (actual digest/figerprint)
Returns:
This method returns true to indicate that the connection should proceed further.
Throws:
java.lang.Exception

addKnownHost

private void addKnownHost(java.lang.String hostname,
                          int port,
                          java.lang.String serverHostKeyAlgorithm,
                          byte[] serverHostKey)
Method to add a new host entry to the list of known hosts. This method provides an MT-safe approach to add a new remote server/host entry to the list of known hosts. This method adds a new entry to both the in-memory knownHosts list and to the persistent file containing the list of known hosts.

Note: This method checks to ensure that the host being added is indeed unique. This method consumes any exceptions generated by Ganymede (but logs it in the programmer log).

Parameters:
hostname - The host name to be added to the list.
port - The port associated with the remote connection. Currently this is not used.
serverHostKeyAlgorithm - The string name for the certificate encryption algorithm (such as: ssh-rsa2 etc.)
serverHostKey - The host key (actual digest/figerprint) as reported by the remote host.

loadKnownHosts

private void loadKnownHosts()
This is a helper method that is invoked just before a remote session establishes connection with a server. This method attempts to load the list of known servers from the "KnownHosts" file. This file is stored in the main PEACE folder in user's home directory.

Note: This method loads the known hosts file only once, the first time it is called in the GUI process. Subsequent calls to this method simply return. Therefore calling this method frequently is OK.


getOSType

public ServerSession.OSType getOSType()
                               throws java.lang.Exception
Determine the type of OS that this session is connected to. This method can be used to determine the type of the OS that this session is connected to.

Note: The session must be connected prior to this call.

Specified by:
getOSType in class ServerSession
Returns:
The type of OS this session is associated with.
Throws:
java.lang.Exception - If the detection of OS fails or a connection does not exist then this method throws an exception.

copy

public void copy(java.io.InputStream srcData,
                 java.lang.String destDirectory,
                 java.lang.String destFileName,
                 java.lang.String mode)
          throws java.io.IOException
Copy given data from an input stream to a given file on the remote machine.

Note: This method uses SFTP to copy the data. The connection to the remote host must have already been established before invoking this method.

Specified by:
copy in class ServerSession
Parameters:
srcData - The source stream that provides the data to be copied.
destDirectory - The destination directory to which the data is to be copied. This method assumes that the remote directory has already been created.
destFileName - The name of the destination file to which the data is to be copied.
mode - The POSIX compliant mode string (such as: "0600" or "0777" to be used as the mode for the target file.
Throws:
java.io.IOException - This method throws exceptions on errors.

copy

public void copy(java.io.OutputStream destData,
                 java.lang.String srcDirectory,
                 java.lang.String srcFileName,
                 javax.swing.JProgressBar progBar)
          throws java.io.IOException
Copy file from a remote machine to a given output stream.

Note: This method uses SFTP to copy the data. The connection to the remote host must have already been established before invoking this method.

Specified by:
copy in class ServerSession
Parameters:
destData - The destination stream to which the data is to be written.
srcDirectory - The source directory from where the file is to be copied.
srcFileName - The name of the source file from where the data is to be copied.
progBar - The progress bar to be used indicate the file copy progress.
Throws:
java.io.IOException - This method throws exceptions on errors.

fstat

public FileInfo fstat(java.lang.String path)
               throws java.io.IOException
Obtain information about a given path on the remote machine.

Note: This method uses SFTP to copy the data. The connection to the remote host must have already been established before invoking this method.

Specified by:
fstat in class ServerSession
Parameters:
path - The path (absolute or relative to home directory) of the file whose meta data is to be retrieved.
Returns:
A FileInfo object containing the information about the path.
Throws:
java.io.IOException - This method throws exceptions on errors.

mkdir

public void mkdir(java.lang.String directory)
           throws java.lang.Exception
Creates a directory on the server. This method must be used to create a directory entry on the server.

Note: The connection to the server must have already been successfully established via a call to the connect method before invoking this method.

Specified by:
mkdir in class ServerSession
Parameters:
directory - The fully path to the directory to be created.
Throws:
java.io.IOException - This method throws an exception if the directory could not be created.
java.lang.Exception

rmdir

public void rmdir(java.lang.String directory)
           throws java.lang.Exception
Deletes an empty directory on the server. This method must be used to delete a directory entry on the server. The directory must be empty.

Note: The connection to the server must have already been successfully established via a call to the connect method before invoking this method.

Specified by:
rmdir in class ServerSession
Parameters:
directory - The fully path to the directory to be deleted.
Throws:
java.io.IOException - This method throws an exception if the directory could not be deleted.
java.lang.Exception

setPurpose

public void setPurpose(java.lang.String text)
A simple method to set a purpose message for this session. This method can be used to set up a purpose message for a server session. The purpose message is displayed to the user when prompting for inputs from the user for credentials. The message serves the purpose of appraising the user about the purpose of the session.

Specified by:
setPurpose in class ServerSession
Parameters:
text - This string is used to create a label (possibly with an icon on it). So it can be plain text or HTML. If the message is long, then ensure it is properly broken into multiple lines so that dialog boxes don't get too large.