/* * Copyright 2005-2010 Ignis Software Tools Ltd. All rights reserved. */ package com.aqua.filetransfer.ftp; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import com.aqua.sysobj.conn.CliConnection; import com.aqua.sysobj.conn.CliFactory; import jsystem.framework.system.SystemObjectImpl; import jsystem.utils.FileUtils; /** * <b>Utility SystemObject for transferring files from the machine on which the * tests are running to any remote machine and the opposite direction.</b><br><br> * * FTPFileTransfer uses telnet/ssh and FTP protocols for the file transfer hence * it is multi-platform, in addition, it doesn't rely on a FTP server on the * remote machine; it activates an embedded FTP server which runs on the local * machine and uses the {@link TFTPRemoteClient} to open FTP connection from the * remote machine to the embedded FTP server. <u><b><br><br> * * Working with FTPFileTransfer:</b></u><br> * Make sure connectivity parameters are set correctly and use the different copy methods. * The copy operations identifies whether a connection is already open if not * a connection is opened.<br> * In many cases the remote server (telnet/ssh) limits number of connections; * use the {@link #closeFileTransferSession()} to close connection when needed.<br> * * <u>FTPFileTransfer members:</u><br> * remoteHost: the remote host to/from files will be copied.<br> * operatingSystem: the operating system of the remote host. By default the value is {@link CliFactory#OPERATING_SYSTEM_WINDOWS}<br> * protocol: the protocol for the connection with the remote host (one of * telnet/ssh/rs232). Default: telnet<br> * port: port for the connection to the remote host. Default is 23<br> * user: user for the connection to the remote host.<br> * password: password for the connection to the remote host.<br><br> * cliConnection - a CliConnection implementation for connecting to the remote * client. If defined, the connectivity members above are ignored. * localHostExternalName: the host name of the local machine. The default value * of this member is the host name as supplied by {@link java.net.InetAddress#getLocalHost}<br> * ftpUserName: ftp user name for the FTP connection which is opened from the * remote host to the ftp server. Default: aqua<br> * ftpPassword: ftp password for the FTP connection which is opened from the * remote host to the ftp server.Default: aqua<br> * ftpServerHome: user's FTP server home directory. Default=current directory/aquaftp21<br> * passivate: If true ftp sessions will work in passivate mode. Please note that * passivation mode is set in the initiation of the FTP session. Please note that passivation works * only on linux ftp clients. * FTP parameters should be used if an FTP server which is not aqua's FTP server * is already running on the machine.<br><br> * * <u><b>FTPFileTransfer implementation details:</b></u><br> * The FTPFileTransfer uses the {@link FTPServer} and the * {@link TFTPRemoteClient}. The {@link FTPServer} is used to run embedded FTP * server on the local machine; {@link TFTPRemoteClient} is used to open FTP * connection from the remote machine to this machine and to do the file * transfer operation.<br> * <br> * <u>Note:</u> The object is not thread safe. * * @author Golan Derazon * */ public class FTPFileTransfer extends SystemObjectImpl{ private FTPServer ftpServer; private FTPRemoteClient remoteHostClient; public CliConnection cliConnection; private String serverPropertiesPath; private String remoteHost; private String localHostExternalName; private boolean ascii ; private String operatingSystem = CliFactory.OPERATING_SYSTEM_WINDOWS; private String protocol="telnet"; private int port=23; private String user; private String password; private String ftpUserName; private String ftpPassword; private String ftpServerHome; private boolean prompt = true; /** * Constructs FTPFileTransfer object with CliConnection. */ public FTPFileTransfer(CliConnection cliConnection) throws Exception { this.cliConnection = cliConnection; } /** * Constructs FTPFileTransfer object which can copy files to/from local machine to local machine * (the default constructor will be used mainly for testing).<br> * When constructing FTPFileTransfer using this constructor it is assumed * that external FTP server is not running on this machine. */ public FTPFileTransfer() throws Exception { java.net.InetAddress localMachine = java.net.InetAddress.getLocalHost(); setRemoteHost(localMachine.getHostAddress()); } /** * Constructs FTPFileTransfer object which can copy files to/from <code>remoteHose</code>.<br> * When constructing FTPFileTransfer using this constructor it is assumed * that external FTP server is not running on this machine. */ public FTPFileTransfer(String remoteHost,String user,String password) throws Exception{ this(); setRemoteHost(remoteHost); setUser(user); setPassword(password); } /** * Initializes {@link FTPFileTransfer} members<br> * verifies that a connection can be opened to the remote client and * that the remote client can open a FTP connection to the server.<br> * All connections are closed at the end of the initialization. */ public void init() throws Exception { super.init(); ftpServer = new FTPServer(); if (getServerPropertiesPath() != null){ ftpServer.setPropertiesPath(getServerPropertiesPath()); } ftpServer.init(); ftpServer.startServer(); if (getFtpUserName() == null){ setFtpUserName(ftpServer.getDefaultUserName()); } if (getFtpPassword() == null){ setFtpPassword(ftpServer.getDefaultUserPassword()); } if (getFtpServerHome() == null){ setFtpServerHome(ftpServer.getDefaultUserHomeDirectory()); } if (cliConnection != null){ remoteHostClient = new FTPRemoteClient(cliConnection,ftpServer.getExternalName()); remoteHostClient.setOperatingSystem(getOperatingSystem()); }else { remoteHostClient = new FTPRemoteClient(getRemoteHost(),getUser(),getPassword(),ftpServer.getExternalName()); remoteHostClient.setPort(getPort()); remoteHostClient.setOperatingSystem(getOperatingSystem()); remoteHostClient.setProtocol(getProtocol()); } remoteHostClient.setFtpUserName(getFtpUserName()); remoteHostClient.setFtpPassword(getFtpPassword()); if (getLocalHostExternalName() != null){ remoteHostClient.setFtpServerHostName(getLocalHostExternalName()); } remoteHostClient.init(); } /** * Sets passivation mode */ public void passivate(boolean passive) throws Exception { remoteHostClient.passivate(passive); } /** * Closes connection to remote machine. */ public void closeFileTransferSession() throws Exception{ remoteHostClient.closeFTPSession(); } /** * Copies stream to remote machine.<br><br> * * Destination can be either absolute destination path or relative to client's * user directory.<br> * Examples:<br> * 1. Absolute destination: new File("C:/automation/test.txt"). Will copy the stream to c:/automation/test.txt * on the remote machine. If folder automation doesn't exist the operation will fail.<br> * 2. Relative destination: new File("test.txt"). Will copy the stream to user_dir/test.txt.<br><br> * * @see TFTPRemoteClient#copyFileFromLocalMachineToRemoteClient(String, String) */ public void copyFileFromLocalMachineToRemoteMachine(InputStream source,File destination) throws Exception { String fileName = destination.getPath(); File f = new File(getFtpServerHome(),""+System.currentTimeMillis()); f.deleteOnExit(); org.apache.commons.io.IOUtils.copy(source,new FileOutputStream(f)); remoteHostClient.setAscii(isAscii()); remoteHostClient.setPromptOn(isPrompt()); remoteHostClient.copyFileFromLocalMachineToRemoteClient(f.getName(), fileName); } /** * Copies file to remote machine. * @see #copyFileFromLocalMachineToRemoteMachine(InputStream, File) */ public void copyFileFromLocalMachineToRemoteMachine(File source,File destination) throws Exception { copyFileFromLocalMachineToRemoteMachine(new FileInputStream(source), destination); } /** * Copies Multiply files to remote machine.<br><br> * You may use wildcard ('*') or specific files path * @param filesPath - A files path array (java.lang.String...) * @throws Exception */ public void copyAllFilesFromLocalMachineToRemoteMachine(String... filesPath) throws Exception{ remoteHostClient.setPromptOn(isPrompt()); remoteHostClient.setAscii(isAscii()); remoteHostClient.copyAllFilesFromLocalMachineToLocalRemote(filesPath); } /** * Copies file from remote machine to this machine<br><br> * * Source can be either absolute destination path or relative to client's * user directory.<br> * Examples:<br> * 1. Absolute destination: new File("C:/automation/test.txt"). Will copy the stream to c:/automation/test.txt * on the remote machine. If folder automation doesn't exist the operation will fail.<br> * 2. Relative destination: new File("test.txt"). Will copy the stream to user_dir/test.txt.<br> * Destination can be either absolute destination path or relative to current dir<br> * <br> * * @see TFTPRemoteClient#copyFileFromRemoteClientToLocalMachine(String, String) */ public void copyFileFromRemoteMachineToLocalMachine(File source,File destination) throws Exception { String fileName = source.getPath(); File f = new File(""+System.currentTimeMillis()); f.deleteOnExit(); remoteHostClient.setPromptOn(isPrompt()); remoteHostClient.setAscii(isAscii()); remoteHostClient.copyFileFromRemoteClientToLocalMachine(fileName,f.getName()); File transferredFilePath= new File(getFtpServerHome(),f.getName()); if (!transferredFilePath.exists()){ throw new Exception("File transfer completed successfully but file was not found on local file system. Please check whether there is another none aqua active FTP" + "server on this machine. If so either shut it down or update the ftpServerHome to the server's home."); } FileUtils.copyFile(transferredFilePath,destination); } /** * Copies Multiply files from remote machine.<br><br> * You may use wildcard ('*') or specific files path * @param filesPath - A files path array (java.lang.String...) * @throws Exception */ public void copyAllFilesFromRemoteMachineToLocalMachine(String... filesPath) throws Exception{ remoteHostClient.setPromptOn(isPrompt()); remoteHostClient.setAscii(isAscii()); remoteHostClient.copyAllFilesFromRemoteMachineToLocalMachine(filesPath); } /** * Shuts down the FTP server and * closes connection to remote machine. */ public void close() { try { ftpServer.stopServer(); }catch (Exception e){ report.report("Failed closing FTP server",e); } remoteHostClient.close(); } /************************************************************************* * Setters & getters ************************************************************************/ public String getFtpPassword() { return ftpPassword; } public void setFtpPassword(String ftpPassword) { this.ftpPassword = ftpPassword; } public String getFtpUserName() { return ftpUserName; } public void setPrompt(boolean prompt){ this.prompt = prompt; } public boolean isPrompt() { return prompt; } public boolean isAscii() { return ascii; } public void setAscii(boolean ascii) { this.ascii = ascii; } public String getLocalHostExternalName() { return localHostExternalName; } public void setLocalHostExternalName(String localHostExternalName) { this.localHostExternalName = localHostExternalName; } public String getRemoteHost() { return remoteHost; } public void setRemoteHost(String remoteHost) { this.remoteHost = remoteHost; } public String getPassword() { return password; } public void setPassword(String telnetPassword) { this.password = telnetPassword; } public int getPort() { return port; } public void setPort(int telnetPort) { this.port = telnetPort; } public String getUser() { return user; } public void setUser(String telnetUser) { this.user = telnetUser; } public String getFtpServerHome() { return ftpServerHome; } public void setFtpServerHome(String ftpServerHome) { this.ftpServerHome = ftpServerHome; } public String getOperatingSystem() { return operatingSystem; } public void setOperatingSystem(String operatingSystem) { this.operatingSystem = operatingSystem; } public String getProtocol() { return protocol; } public void setProtocol(String protocol) { this.protocol = protocol; } public void setFtpUserName(String ftpUserName) { this.ftpUserName = ftpUserName; } public String getServerPropertiesPath() { return serverPropertiesPath; } public void setServerPropertiesPath(String serverPropertiesPath) { this.serverPropertiesPath = serverPropertiesPath; } }