You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by he...@apache.org on 2013/02/03 05:04:13 UTC

svn commit: r1441854 - in /airavata/trunk/modules/gfac-core/src/main/java/org/apache/airavata/core/gfac/external: ContactInfo.java DataIDType.java FileTransferService.java SSHClient.java SshFileTransferService.java

Author: heshan
Date: Sun Feb  3 04:04:13 2013
New Revision: 1441854

URL: http://svn.apache.org/viewvc?rev=1441854&view=rev
Log:
AIRAVATA-202 
Adding logic necessary to make ssh connection with the Amazon instances (Required by the EC2Provider). 
I'm waiting till Lahiru finishes the GFac refactoring. Once it is done will use the refactored classes with the EC2Provider. Then I can start testing the EC2Provider with Airavata. 

Added:
    airavata/trunk/modules/gfac-core/src/main/java/org/apache/airavata/core/gfac/external/ContactInfo.java
    airavata/trunk/modules/gfac-core/src/main/java/org/apache/airavata/core/gfac/external/DataIDType.java
    airavata/trunk/modules/gfac-core/src/main/java/org/apache/airavata/core/gfac/external/FileTransferService.java
    airavata/trunk/modules/gfac-core/src/main/java/org/apache/airavata/core/gfac/external/SSHClient.java
    airavata/trunk/modules/gfac-core/src/main/java/org/apache/airavata/core/gfac/external/SshFileTransferService.java

Added: airavata/trunk/modules/gfac-core/src/main/java/org/apache/airavata/core/gfac/external/ContactInfo.java
URL: http://svn.apache.org/viewvc/airavata/trunk/modules/gfac-core/src/main/java/org/apache/airavata/core/gfac/external/ContactInfo.java?rev=1441854&view=auto
==============================================================================
--- airavata/trunk/modules/gfac-core/src/main/java/org/apache/airavata/core/gfac/external/ContactInfo.java (added)
+++ airavata/trunk/modules/gfac-core/src/main/java/org/apache/airavata/core/gfac/external/ContactInfo.java Sun Feb  3 04:04:13 2013
@@ -0,0 +1,42 @@
+package org.apache.airavata.core.gfac.external;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class ContactInfo {
+    public static final Logger log = LoggerFactory.getLogger(ContactInfo.class);
+    public String hostName;
+    public int port;
+    public static final int GSI_FTP_PORT = 2811;
+
+    public ContactInfo(String hostName, int port) {
+        if (port <= 0 || port == 80) {
+            log.info(hostName + "port recived " + port + " setting it to " + GSI_FTP_PORT);
+            port = GSI_FTP_PORT;
+        }
+        this.hostName = hostName;
+        this.port = port;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof ContactInfo) {
+            return hostName.equals(((ContactInfo) obj).hostName) && port == ((ContactInfo) obj).port;
+        } else {
+            return false;
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        return hostName.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        StringBuffer buf = new StringBuffer();
+        buf.append(hostName).append(":").append(port);
+        return buf.toString();
+    }
+}
+

Added: airavata/trunk/modules/gfac-core/src/main/java/org/apache/airavata/core/gfac/external/DataIDType.java
URL: http://svn.apache.org/viewvc/airavata/trunk/modules/gfac-core/src/main/java/org/apache/airavata/core/gfac/external/DataIDType.java?rev=1441854&view=auto
==============================================================================
--- airavata/trunk/modules/gfac-core/src/main/java/org/apache/airavata/core/gfac/external/DataIDType.java (added)
+++ airavata/trunk/modules/gfac-core/src/main/java/org/apache/airavata/core/gfac/external/DataIDType.java Sun Feb  3 04:04:13 2013
@@ -0,0 +1,74 @@
+package org.apache.airavata.core.gfac.external;
+
+import org.apache.airavata.core.gfac.exception.GfacException;
+import org.xmlpull.v1.builder.XmlElement;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+
+/**
+ * Represents a DataID (A schema with real names), currently it only sends a one
+ * location value.
+ */
+public class DataIDType {
+    public static final String LOCATION_ATTRIBUTE = "location";
+
+    private URI dataID;
+
+    private ArrayList<URI> dataLocations = new ArrayList<URI>();
+
+    public URI getRealLocation() {
+        if (dataLocations.size() > 0) {
+            return dataLocations.get(0);
+        } else {
+            return null;
+        }
+    }
+
+    public DataIDType(XmlElement ele) throws GfacException {
+        try {
+            String value = ele.requiredTextContent();
+            if (value != null) {
+                this.dataID = new URI(value);
+            } else {
+                throw new GfacException(
+                        "Illegal InputMessage, No value content found for the parameter "
+                                + ele.getName() + "/value. Invalid Local Argument");
+            }
+            String location = ele.getAttributeValue(null, DataIDType.LOCATION_ATTRIBUTE);
+            if (location != null) {
+                addDataLocation(new URI(location));
+            }
+        } catch (URISyntaxException e) {
+            throw new GfacException("Invalid Local Argument", e);
+        }
+    }
+
+    public DataIDType(URI dataID) {
+        super();
+        this.dataID = dataID;
+    }
+
+    public void addDataLocation(URI dataLocation) {
+        dataLocations.add(dataLocation);
+    }
+
+    public ArrayList<URI> getDataLocations() {
+        return dataLocations;
+    }
+
+    public URI getDataID() {
+        return dataID;
+    }
+
+    public void fillData(XmlElement ele) {
+        ele.addChild(dataID.toString());
+        URI location = getRealLocation();
+        if (location != null) {
+            ele.addAttribute(DataIDType.LOCATION_ATTRIBUTE, location.toString());
+        }
+    }
+
+}
+

Added: airavata/trunk/modules/gfac-core/src/main/java/org/apache/airavata/core/gfac/external/FileTransferService.java
URL: http://svn.apache.org/viewvc/airavata/trunk/modules/gfac-core/src/main/java/org/apache/airavata/core/gfac/external/FileTransferService.java?rev=1441854&view=auto
==============================================================================
--- airavata/trunk/modules/gfac-core/src/main/java/org/apache/airavata/core/gfac/external/FileTransferService.java (added)
+++ airavata/trunk/modules/gfac-core/src/main/java/org/apache/airavata/core/gfac/external/FileTransferService.java Sun Feb  3 04:04:13 2013
@@ -0,0 +1,35 @@
+package org.apache.airavata.core.gfac.external;
+
+import org.apache.airavata.core.gfac.exception.GfacException;
+import org.ietf.jgss.GSSCredential;
+
+import java.io.File;
+import java.net.URI;
+import java.util.Vector;
+
+public interface FileTransferService {
+    public URI copy(URI src, URI dest, GSSCredential gssCred) throws GfacException;
+
+    public URI forcedCopy(URI src, URI dest, GSSCredential gssCred) throws GfacException;
+
+    public URI copyToDir(URI src, URI destDir, GSSCredential gssCred) throws GfacException;
+
+    public void makeDir(URI destURI, GSSCredential gssCred) throws GfacException;
+
+    public Vector<URI> listDir(URI srcURI, GSSCredential gssCred) throws GfacException;
+
+    public String readRemoteFile(URI destURI, GSSCredential gsCredential,
+                                 File localFile) throws GfacException;
+
+    public boolean isExisits(URI uri, GSSCredential gssCred) throws GfacException;
+
+    public URI copyWithDataID(DataIDType src, URI destURL, GSSCredential gssCred)
+            throws GfacException;
+
+    public DataIDType store(URI src) throws GfacException;
+
+    public ContactInfo findContact(URI uri) throws GfacException;
+
+    public URI[] copyToDir(URI[] srcList, URI destDir, GSSCredential gssCred) throws GfacException;
+}
+

Added: airavata/trunk/modules/gfac-core/src/main/java/org/apache/airavata/core/gfac/external/SSHClient.java
URL: http://svn.apache.org/viewvc/airavata/trunk/modules/gfac-core/src/main/java/org/apache/airavata/core/gfac/external/SSHClient.java?rev=1441854&view=auto
==============================================================================
--- airavata/trunk/modules/gfac-core/src/main/java/org/apache/airavata/core/gfac/external/SSHClient.java (added)
+++ airavata/trunk/modules/gfac-core/src/main/java/org/apache/airavata/core/gfac/external/SSHClient.java Sun Feb  3 04:04:13 2013
@@ -0,0 +1,138 @@
+package org.apache.airavata.core.gfac.external;
+
+import com.sshtools.j2ssh.SshClient;
+import com.sshtools.j2ssh.authentication.AuthenticationProtocolState;
+import com.sshtools.j2ssh.authentication.PublicKeyAuthenticationClient;
+import com.sshtools.j2ssh.io.IOStreamConnector;
+import com.sshtools.j2ssh.io.IOStreamConnectorState;
+import com.sshtools.j2ssh.session.SessionChannelClient;
+import com.sshtools.j2ssh.transport.ConsoleKnownHostsKeyVerification;
+import com.sshtools.j2ssh.transport.HostKeyVerification;
+import com.sshtools.j2ssh.transport.IgnoreHostKeyVerification;
+import com.sshtools.j2ssh.transport.publickey.InvalidSshKeyException;
+import com.sshtools.j2ssh.transport.publickey.SshPrivateKey;
+import com.sshtools.j2ssh.transport.publickey.SshPrivateKeyFile;
+import com.sshtools.j2ssh.util.InvalidStateException;
+import org.apache.airavata.core.gfac.exception.GfacException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import xsul.MLogger;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+public class SSHClient {
+
+    protected static final Logger log = LoggerFactory.getLogger(SSHClient.class);
+
+    public static void main(String[] args) {
+        try {
+            String username = "biovlab";
+            String hostname = "gw40.quarry.iu.teragrid.org";
+            String password = "";
+            String keyFileName = "/home/ptangcha/.ssh/id_rsa";
+            String knownHostsFileName = "/home/ptangcha/.ssh/known_hosts";
+            SshClient ssh = loginToServer(username, hostname, password, keyFileName, knownHostsFileName);
+
+            SessionChannelClient session = ssh.openSessionChannel();
+
+            if (!session.requestPseudoTerminal("vt100", 80, 24, 0, 0, ""))
+                System.out.println("Failed to allocate a pseudo terminal");
+            if (session.startShell()) {
+                session.setEnvironmentVariable("foo1", "HelloA");
+                session.setEnvironmentVariable("foo2", "HelloB");
+
+                InputStream in = session.getInputStream();
+                OutputStream out = session.getOutputStream();
+                IOStreamConnector input = new IOStreamConnector(System.in, session
+                        .getOutputStream());
+                IOStreamConnector output = new IOStreamConnector(session.getInputStream(),
+                        System.out);
+                out.write("/u/hperera/temp/test.sh Hello".getBytes());
+                output.getState().waitForState(IOStreamConnectorState.CLOSED);
+            } else
+                System.out.println("Failed to start the users shell");
+            System.out.println("done");
+
+            ssh.disconnect();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+    }
+
+    /**
+     * Log in to the remote host and retun a authenticated Ssh Client
+     *
+     * @param username
+     * @param hostname
+     * @param password
+     * @param keyFileName
+     * @param knownHostsFileName
+     * @return
+     * @throws GfacException
+     */
+
+    public static SshClient loginToServer(String username, String hostname, String password,
+                                          String keyFileName, String knownHostsFileName) throws GfacException {
+        try {
+
+            log.info("SSH host:" + hostname);
+            log.info("SSH username:" + username);
+            log.info("SSH password:" + password);
+            log.info("SSH keyfile:" + keyFileName);
+            log.info("SSH hostfile:" + knownHostsFileName);
+
+            SshClient ssh = new SshClient();
+            // Connect to the host
+            HostKeyVerification hostKeyVerification;
+            if (knownHostsFileName != null) {
+                hostKeyVerification = new ConsoleKnownHostsKeyVerification(knownHostsFileName);
+            } else {
+                hostKeyVerification = new IgnoreHostKeyVerification();
+            }
+
+            ssh.connect(hostname, hostKeyVerification);
+            PublicKeyAuthenticationClient pk = new PublicKeyAuthenticationClient();
+            pk.setUsername(username);
+            // Get the private key file
+            // Open up the private key file
+            SshPrivateKeyFile file = SshPrivateKeyFile.parse(new File(keyFileName));
+            // If the private key is passphrase protected then ask for the
+            // passphrase
+            String passphrase = null;
+            if (file.isPassphraseProtected()) {
+                if (password == null) {
+                    throw new GfacException(
+                            "Key file is encrypted, but password has not found in configuration. Invalid Config.");
+                }
+                passphrase = password;
+            }
+            // Get the key
+            SshPrivateKey key = file.toPrivateKey(passphrase);
+            pk.setKey(key);
+            // Try the authentication
+            int result = ssh.authenticate(pk);
+            // Evaluate the result
+            if (result == AuthenticationProtocolState.COMPLETE) {
+                // System.out.println("authenication completed");
+                return ssh;
+            } else if (result == AuthenticationProtocolState.PARTIAL) {
+                throw new GfacException("Further authentication requried!. Invalid Config.");
+            } else if (result == AuthenticationProtocolState.FAILED) {
+                throw new GfacException("Authentication failed!. Invalid Config.");
+            } else {
+                throw new GfacException("Authentication failed!, Unknown state. Invalid Config.");
+            }
+        } catch (InvalidSshKeyException e) {
+            throw new GfacException("Invalid Config!", e);
+        } catch (InvalidStateException e) {
+            throw new GfacException("Invalid Config!", e);
+        } catch (IOException e) {
+            throw new GfacException("Invalid Config!", e);
+        }
+    }
+
+}

Added: airavata/trunk/modules/gfac-core/src/main/java/org/apache/airavata/core/gfac/external/SshFileTransferService.java
URL: http://svn.apache.org/viewvc/airavata/trunk/modules/gfac-core/src/main/java/org/apache/airavata/core/gfac/external/SshFileTransferService.java?rev=1441854&view=auto
==============================================================================
--- airavata/trunk/modules/gfac-core/src/main/java/org/apache/airavata/core/gfac/external/SshFileTransferService.java (added)
+++ airavata/trunk/modules/gfac-core/src/main/java/org/apache/airavata/core/gfac/external/SshFileTransferService.java Sun Feb  3 04:04:13 2013
@@ -0,0 +1,322 @@
+package org.apache.airavata.core.gfac.external;
+
+import com.sshtools.j2ssh.SftpClient;
+import com.sshtools.j2ssh.SshClient;
+import com.sshtools.j2ssh.sftp.SftpFile;
+import org.apache.airavata.core.gfac.context.invocation.ExecutionContext;
+import org.apache.airavata.core.gfac.context.invocation.InvocationContext;
+import org.apache.airavata.core.gfac.context.security.impl.SSHSecurityContextImpl;
+import org.apache.airavata.core.gfac.exception.GfacException;
+import org.apache.airavata.core.gfac.utils.GfacUtils;
+import org.apache.airavata.schemas.wec.ContextHeaderDocument;
+import org.apache.airavata.schemas.wec.SecurityContextDocument;
+import org.apache.airavata.core.gfac.context.invocation.ExecutionContext;
+import org.apache.axiom.om.OMElement;
+import org.apache.xmlbeans.XmlException;
+import org.ietf.jgss.GSSCredential;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import xsul.MLogger;
+
+import javax.xml.stream.XMLStreamException;
+import java.io.*;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.List;
+import java.util.Random;
+import java.util.Vector;
+
+/**
+ * This class provides SSH based remote file operations. It needs ssh keys to be
+ * setup to autenticate with remote host. It uses
+ * SSH_USERNAME,SSH_PASSWD,SSH_KEYFILE,SSH_KNOWN_HOSTFILE from gfac options.
+ * However if they does not present it uses ${user.name}, and
+ * ${user.home}/.ssh/id_rsa as default. If you have setup ssh keys and they do
+ * not need a password, then you do not need to do any configuration at all.
+ *
+ */
+public class SshFileTransferService implements FileTransferService {
+    public static final Logger log = LoggerFactory.getLogger(SshFileTransferService.class);
+    private String username;
+
+    private String password;
+
+    private String keyFileName;
+
+    private String knownHostsFileName;
+
+    private ExecutionContext executionContext;
+
+    private static final String SSH_SECURITY_CONTEXT = "ssh";
+
+    public SshFileTransferService(InvocationContext invocationContext) {
+        // --------------------- testing --------------------------------------------
+        ExecutionContext execContext = invocationContext.getExecutionContext();
+        OMElement omSecurityContextHeader = execContext.getSecurityContextHeader();
+
+        ContextHeaderDocument document = null;
+        try {
+            document = ContextHeaderDocument.Factory.parse(omSecurityContextHeader.toStringWithConsume());
+        } catch (XMLStreamException e) {
+            e.printStackTrace();
+        } catch (XmlException e) {
+            e.printStackTrace();
+        }
+        SecurityContextDocument.SecurityContext.AmazonWebservices amazonWebservices =
+                document.getContextHeader().getSecurityContext().getAmazonWebservices();
+
+        //            TODO
+/*
+        // MMEEE
+        sshContext = ((SSHSecurityContextImpl) context.getSecurityContext(SSH_SECURITY_CONTEXT));
+        // MMEEE
+
+
+        this.executionContext = invocationContext.getExecutionContext();
+        GlobalConfiguration configuration = invocationContext.getGlobalConfig();
+        username = configuration.getProperty(SSH_USERNAME);
+        password = configuration.getProperty(SSH_PASSWD);
+        keyFileName = configuration.getProperty(SSH_KEYFILE);
+        knownHostsFileName = configuration.getProperty(SSH_KNOWN_HOSTFILE);
+
+        if (username == null) {
+            username = System.getProperty("user.name");
+        }
+        if (keyFileName == null) {
+            keyFileName = System.getProperty("user.home") + "/.ssh/id_rsa";
+        }*/
+    }
+
+    public SshFileTransferService(InvocationContext invocationContext, String username, String keyFileName) {
+        this(invocationContext);
+        this.username = username;
+        this.password = null;
+        this.keyFileName = keyFileName;
+        this.knownHostsFileName = null;
+    }
+
+    public URI forcedCopy(URI src, URI dest, GSSCredential gssCred) throws GfacException {
+        return copy(src, dest, gssCred);
+    }
+
+    public URI copy(URI src, URI dest, GSSCredential gssCred) throws GfacException {
+        log.info("Copying " + src + "->" + dest);
+        SshClient sshClient = null;
+        SshClient sshClient2 = null;
+        try {
+            String srchost = src.getHost();
+            String srcfile = src.getPath();
+            String desthost = dest.getHost();
+            String destfile = dest.getPath();
+
+            if (GfacUtils.isLocalHost(srchost) && GfacUtils.isLocalHost(desthost)) {
+                FileInputStream in = new FileInputStream(srcfile);
+                FileOutputStream out = new FileOutputStream(destfile);
+                byte[] buf = new byte[1024];
+                int read;
+                while ((read = in.read(buf)) > 0) {
+                    out.write(buf, 0, read);
+                }
+                out.close();
+                in.close();
+            } else if (GfacUtils.isLocalHost(srchost)) {
+                sshClient = SSHClient.loginToServer(username, desthost, password, keyFileName,
+                        knownHostsFileName);
+                SftpClient sftpClient = sshClient.openSftpClient();
+                sftpClient.put(srcfile, destfile);
+            } else if (GfacUtils.isLocalHost(desthost)) {
+                sshClient = SSHClient.loginToServer(username, srchost, password, keyFileName,
+                        knownHostsFileName);
+                SftpClient sftpClient = sshClient.openSftpClient();
+                sftpClient.get(srcfile, destfile);
+            } else {
+                File tempFile = File.createTempFile(String.valueOf(System.currentTimeMillis()
+                        + new Random().nextLong()), "temp");
+                sshClient = SSHClient.loginToServer(username, srchost, password, keyFileName,
+                        knownHostsFileName);
+                SftpClient sftpClient1 = sshClient.openSftpClient();
+                sftpClient1.get(srcfile, tempFile.getAbsolutePath());
+                sftpClient1.quit();
+
+                sshClient2 = SSHClient.loginToServer(username, desthost, password, keyFileName,
+                        knownHostsFileName);
+                SftpClient sftpClient2 = sshClient2.openSftpClient();
+                sftpClient2.put(tempFile.getAbsolutePath(), destfile);
+                sftpClient2.quit();
+                tempFile.delete();
+            }
+        } catch (FileNotFoundException e) {
+//            TODO
+//            throw new FileTransferFault(e,FileTransferServiceType.SSH,executionContext.getGlobalConfig().getLocalHost(),src,dest,"");
+        } catch (IOException e) {
+//            TODO
+//            throw new FileTransferFault(e,FileTransferServiceType.SSH,executionContext.getGlobalConfig().getLocalHost(),src,dest,"");
+        } finally {
+            if (sshClient != null) {
+                sshClient.disconnect();
+            }
+            if (sshClient2 != null) {
+                sshClient2.disconnect();
+            }
+        }
+        return dest;
+    }
+
+    public URI copyToDir(URI src, URI destDir, GSSCredential gssCred) throws GfacException {
+        try {
+            URI destFile = new URI(destDir.toString() + "/" + new File(src.getPath()).getName());
+            return copy(src, destFile, gssCred);
+        } catch (URISyntaxException e) {
+            //            TODO
+//            throw new GfacException(e,FaultCode.InvaliedLocalArgumnet);
+        }
+        //            TODO : Remove
+        return null;
+    }
+
+    public URI copyWithDataID(DataIDType src, URI destURL, GSSCredential gssCred)
+            throws GfacException {
+        throw new UnsupportedOperationException();
+    }
+
+    public boolean isExisits(URI srcURI, GSSCredential gssCred) throws GfacException {
+        String desthost = srcURI.getHost();
+        String destfile = srcURI.getPath();
+
+        File destFileAsFile = new File(destfile);
+        String fileNamePart = destFileAsFile.getName();
+        String filepathPart = destFileAsFile.getParent();
+
+        SshClient sshClient = SSHClient.loginToServer(username, desthost, password, keyFileName,
+                knownHostsFileName);
+        try {
+            SftpClient sftpClient = sshClient.openSftpClient();
+            List<SftpFile> files = (List<SftpFile>) sftpClient.ls(filepathPart);
+            for (SftpFile file : files) {
+                String returnedFileName = file.getFilename().replaceAll("/", "");
+                if (returnedFileName.equals(fileNamePart)) {
+                    return true;
+                }
+            }
+            return files.contains(fileNamePart);
+        } catch (IOException e) {
+            //            TODO
+//            throw new FileSystemFault(e,FileTransferServiceType.SSH,"exits",srcURI.toString());
+        } finally {
+            if (sshClient != null) {
+                sshClient.disconnect();
+            }
+        }
+        //            TODO : Remove
+        return false;
+    }
+
+    public Vector<URI> listDir(URI srcURI, GSSCredential gssCred) throws GfacException {
+        String desthost = srcURI.getHost();
+        String destfile = srcURI.getPath();
+        SshClient sshClient = SSHClient.loginToServer(username, desthost, password, keyFileName,
+                knownHostsFileName);
+        try {
+            SftpClient sftpClient = sshClient.openSftpClient();
+            List files = sftpClient.ls(destfile);
+            if (files != null) {
+                Vector<URI> results = new Vector<URI>();
+                for (Object sftpfile : files) {
+                    String filePart = ((SftpFile) sftpfile).getFilename();
+                    if (!filePart.endsWith(".")) {
+                        results.add(new URI(srcURI.toString() + "/" + filePart));
+                    }
+                }
+                return results;
+            }
+            return null;
+        } catch (IOException e) {
+            //            TODO
+//            throw new FileSystemFault(e,FileTransferServiceType.SSH,"listDir",srcURI.toString());
+        } catch (URISyntaxException e) {
+            //            TODO
+            // throw new GfacException(e,FaultCode.InvaliedLocalArgumnet);
+        } finally {
+            if (sshClient != null) {
+                sshClient.disconnect();
+            }
+        }
+        //            TODO : Remove
+        return null;
+    }
+
+    public void makeDir(URI destURI, GSSCredential gssCred) throws GfacException {
+        String desthost = destURI.getHost();
+        String destfile = destURI.getPath();
+        log.info("SFTP to Host:" + desthost);
+        log.info("SFTP to Dir:" + destfile);
+        SshClient sshClient = SSHClient.loginToServer(username, desthost, password, keyFileName,
+                knownHostsFileName);
+        try {
+            SftpClient sftpClient = sshClient.openSftpClient();
+            sftpClient.mkdir(destfile);
+            log.info("Create directory " + destURI);
+        } catch (IOException e) {
+            //            TODO
+            // throw new FileSystemFault(e,FileTransferServiceType.SSH,"mkdir",destURI.toString());
+        } finally {
+            if (sshClient != null) {
+                sshClient.disconnect();
+            }
+        }
+    }
+
+    public String readRemoteFile(URI destURI, GSSCredential gsCredential,
+                                 File localFile) throws GfacException {
+        SshClient sshClient1 = null;
+        SftpClient sftpClient1 = null;
+        String fileAsStr = null;
+        try {
+            String desthost = destURI.getHost();
+            String destfile = destURI.getPath();
+
+            File tempFile = File.createTempFile(String.valueOf(System.currentTimeMillis()
+                    + new Random().nextLong()), "temp");
+            sshClient1 = SSHClient.loginToServer(username, desthost, password, keyFileName,
+                    knownHostsFileName);
+            sftpClient1 = sshClient1.openSftpClient();
+            sftpClient1.get(destfile, tempFile.getAbsolutePath());
+            sftpClient1.quit();
+            sshClient1.disconnect();
+            //            TODO
+//            fileAsStr = GfacUtils.readFile(tempFile.getAbsolutePath());
+            tempFile.delete();
+        } catch (IOException e) {
+            //            TODO
+            // throw new FileSystemFault(e,FileTransferServiceType.SSH,"readRemoteFile",destURI.toString());
+        } finally {
+            try {
+                if (sftpClient1 != null) {
+                    sftpClient1.quit();
+                }
+                if (sshClient1 != null) {
+                    sshClient1.disconnect();
+                }
+            } catch (IOException e) {
+            }
+        }
+        return fileAsStr;
+    }
+
+    public DataIDType store(URI src) throws GfacException {
+        throw new UnsupportedOperationException();
+    }
+
+    public ContactInfo findContact(URI uri) throws GfacException {
+        return new ContactInfo(uri.getHost(),uri.getPort());
+    }
+
+    public URI[] copyToDir(URI[] srcList, URI destURL, GSSCredential gssCred) throws GfacException {
+        URI[] destFiles = new URI[srcList.length];
+        for (int i = 0; i < srcList.length; i++) {
+            destFiles[i] = copy(srcList[i], destURL, gssCred);
+        }
+        return destFiles;
+    }
+
+}