package evoker; import com.sshtools.j2ssh.SshClient; import com.sshtools.j2ssh.SftpClient; import com.sshtools.j2ssh.sftp.SftpFile; import com.sshtools.j2ssh.session.SessionChannelClient; import com.sshtools.j2ssh.authentication.PasswordAuthenticationClient; import com.sshtools.j2ssh.authentication.AuthenticationProtocolState; import com.sshtools.j2ssh.configuration.SshConnectionProperties; import com.sshtools.j2ssh.transport.IgnoreHostKeyVerification; import javax.swing.*; import java.io.*; import java.util.logging.Logger; import java.util.logging.Level; import java.util.List; import java.util.Iterator; public class DataClient{ static PasswordAuthenticationClient pwd = new PasswordAuthenticationClient(); private SshClient ssh; private SftpClient ftp; private String remoteDir; private String displayName; private List files; private boolean oxFormat; private String oxPlatform; private Genoplot gp; ProgressMonitor pm; public String getLocalDir() { return localDir; } public String getDisplayName(){ return displayName; } private String localDir; public DataClient(DataConnectionDialog dcd, Genoplot genoplot) throws IOException{ Logger.getLogger("com.sshtools").setLevel(Level.WARNING); this.gp = genoplot; // Create a password authentication instance if (dcd.getUsername() != null){ localDir = dcd.getLocalDirectory(); oxFormat = dcd.isOxformat(); pwd.setUsername(dcd.getUsername()); pwd.setPassword(new String(dcd.getPassword())); ssh = new SshClient(); try{ ssh.connect(dcd.getHost(), dcd.getPort(), new IgnoreHostKeyVerification()); remoteDir = dcd.getRemoteDirectory(); }finally{ dcd.clearPassword(); } // Try the authentication int result = ssh.authenticate(pwd); // Evaluate the result if (result == AuthenticationProtocolState.COMPLETE) { Genoplot.ld.log("Successful connection to " + dcd.getHost()); ftp = ssh.openSftpClient(); ftp.cd(remoteDir); ftp.lcd(localDir); try{ String perms = ftp.stat("evoker-helper.pl").getPermissionsString(); if (!perms.endsWith("x")){ throw new IOException("must be fully executable"); } }catch (IOException ioe){ ssh.disconnect(); throw new IOException("Problem with evoker-helper.pl on remote server:\n"+ioe.getMessage()); } // check if the localdir contains files already File[] localFiles = new File(localDir).listFiles(); if (localFiles.length > 0){ Genoplot.ld.log("Files in the local directory"); // ask the user if they wants it emptied int n = JOptionPane.showConfirmDialog( genoplot.getContentPane(), "The local directory selected is not empty.\n Would you like to clear all files in this directory?", "Clear the local directory?", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE ); // n 0 = yes 1 = no if (n == 0) { for (File localFile : localFiles){ try { localFile.delete(); }catch (SecurityException se){ JOptionPane.showMessageDialog(null,se.getMessage(), "File delete error", JOptionPane.ERROR_MESSAGE); } } } } displayName = dcd.getHost()+":"+remoteDir; }else{ throw new IOException("Authentication to host '"+dcd.getHost()+"' failed."); } } } public String[] getFilesInRemoteDir() throws IOException{ if (files != null){ String[] out = new String[files.size()]; for (int i = 0; i < files.size(); i++){ out[i] = ((SftpFile)files.get(i)).getFilename(); } return out; }else{ throw new IOException("Cannot ls files in remote directory"); } } public boolean getConnectionStatus(){ return (ssh != null); } public void getSNPFiles(String snp, String chrom, String collection, int index, int numinds, int totNumSNPs) throws IOException{ String filestem = collection+"."+snp; if (!(new File(localDir+File.separator+filestem+".bed").exists() && new File(localDir+File.separator+filestem+".bnt").exists())){ long prev = System.currentTimeMillis(); SessionChannelClient session = ssh.openSessionChannel(); session.startShell(); // variable to pass to the evoker-helper.pl script int oxStatus; if (oxFormat){ oxStatus = 1; } else { oxStatus = 0; } //Fire off the script on the remote server to get the requested slice of data OutputStream out = session.getOutputStream(); String cmd = "cd "+ remoteDir + "\nperl evoker-helper.pl "+ snp + " " + chrom + " " + collection + " " + index + " " + numinds + " " + totNumSNPs + " " + oxStatus+ " " + this.getOxPlatform() + "\n"; out.write(cmd.getBytes()); //monitor the remote server for news that the script has been finished //this is pretty slow -- is there a better way? InputStream in = session.getInputStream(); byte buffer[] = new byte[1024]; int read; long start = System.currentTimeMillis(); while((System.currentTimeMillis() - start)/1000 < 120) { try{ read = in.read(buffer); String outstr = new String(buffer, 0, read); if (outstr.contains(snp)){ break; } else if (outstr.contains("write_error")) { throw new IOException("user does not have write privileges"); } }catch (IOException ioe){ ssh.disconnect(); throw new IOException("Problem with remote directory permissions:\n"+ioe.getMessage()); } } if ((System.currentTimeMillis() - start)/1000 >= 120) { // if nothing is output from evoker-helper.pl in 2 minutes then die throw new IOException("evoker-helper.pl is not responsive check the script will run"); } session.close(); ftp.get(filestem+".bed"); ftp.get(filestem+".bnt"); ftp.rm(filestem+".bed"); ftp.rm(filestem+".bnt"); double time = ((double)(System.currentTimeMillis() - prev))/1000; Genoplot.ld.log(snp +" for "+ collection +" was fetched in "+ time + "s."); }else{ Genoplot.ld.log(snp +" for "+ collection +" was cached."); } } public boolean isOxFormat() { return oxFormat; } public File prepMetaFiles() throws IOException { files = ftp.ls(); String famending = ".fam"; String bimending = ".bim"; if (oxFormat) { famending = ".sample"; bimending = ".snp"; } Iterator i = files.iterator(); while (i.hasNext()) { String filename = ((SftpFile) i.next()).getFilename(); if (filename.endsWith(famending)) { if (!new File(localDir + File.separator + filename).exists()) { try { ftp.get(filename); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } i = files.iterator(); while (i.hasNext()) { String filename = ((SftpFile) i.next()).getFilename(); if (filename.endsWith(bimending)) { if (!new File(localDir + File.separator + filename).exists()) { try { ftp.get(filename); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } i = files.iterator(); while (i.hasNext()) { String filename = ((SftpFile) i.next()).getFilename(); if (filename.endsWith(".qc")) { if (!new File(localDir + File.separator + filename).exists()) { try { ftp.get(filename); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } return new File(localDir); } public void setOxPlatform(String oxPlatform) { this.oxPlatform = oxPlatform; } public String getOxPlatform() { return oxPlatform; } public SftpClient getFTP() { return ftp; } }