/* * Author: Gerry O'Rourke, similar to Cisco's standard FTP element to uses FTPS */ package ie.purplepi.cisco.cvp.callstudio; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import org.apache.commons.net.ftp.FTPSClient; import com.audium.server.AudiumException; import com.audium.server.session.DecisionElementData; import com.audium.server.session.ElementAPI; import com.audium.server.voiceElement.DecisionElementBase; import com.audium.server.voiceElement.ElementData; import com.audium.server.voiceElement.ElementException; import com.audium.server.voiceElement.ElementInterface; import com.audium.server.voiceElement.ExitState; import com.audium.server.voiceElement.Setting; import com.audium.server.xml.DecisionElementConfig; public class FTPS extends DecisionElementBase implements ElementInterface { public final String doDecision(String name, DecisionElementData data) throws AudiumException { DecisionElementConfig config = data.getDecisionElementConfig(); //String sourceFilePath = data.getSessionData("sourceFilePath").toString(); String filename = config.getSettingValue("filename", (ElementAPI) data); data.addToLog("filename", filename); if (filename == null || filename.isEmpty()) { data.addToLog("filename", "filename not set. Exiting with Error"); return "error"; } String remote_filename = config.getSettingValue("remote_filename", (ElementAPI) data); if (remote_filename != null && !remote_filename.isEmpty()) { data.addToLog("remote_filename_is_empty", "false"); data.addToLog("remote_filename", remote_filename); }else { File file = new File(filename); String sourceFileName = file.getName(); remote_filename = sourceFileName; data.addToLog("remote_filename_is_empty", "true"); //because remote_filename is NOT set - we will use the source filename data.addToLog("remote_filename", remote_filename); } String username = config.getSettingValue("ftps_user", (ElementAPI) data); data.addToLog("username", username); if (username == null || username.isEmpty()) { data.addToLog("username", "username not set. Use anonymous if not using a username. Exiting with Error."); return "error"; } String password = config.getSettingValue("ftps_password", (ElementAPI) data); if (password != null && !password.isEmpty()) { char firstLetterPassword = password.charAt(0); data.addToLog("password", firstLetterPassword + "*******"); }else { data.addToLog("password", "empty password been used"); } String ftps_host = config.getSettingValue("ftps_hosts", (ElementAPI) data); if (ftps_host == null || ftps_host.isEmpty()) { data.addToLog("ftps_host", "FTPS Server not set. At least one FTP Server hostname or IP Address must be set."); return "error"; } data.addToLog("ftps_host", ftps_host); String[] hosts = ftps_host.trim().split("\\s+"); String semicolonSeparated = ""; for (int i = 0; i < hosts.length; i++) { semicolonSeparated += hosts[i]; if (i < hosts.length - 1) { semicolonSeparated += ";"; } } data.addToLog("ftps_host semicolon seperated", semicolonSeparated); String ftps_path = config.getSettingValue("ftps_path", (ElementAPI) data); data.addToLog("ftps_path", ftps_path); String ftpsFilePath = ""; if (ftps_path != null && !ftps_path.isEmpty() && ftps_path.charAt(ftps_path.length() - 1) == '/') { ftpsFilePath = ftps_path + remote_filename; }else if (ftps_path == null || ftps_path.isEmpty()) { ftpsFilePath = remote_filename; }else { ftpsFilePath = ftps_path + "/" + remote_filename; } String delete_file_on_success_string = config.getSettingValue("delete_file_on_success", (ElementAPI) data); boolean delete_file_on_success = Boolean.parseBoolean(delete_file_on_success_string); data.addToLog("delete_file_on_success", Boolean.toString(delete_file_on_success)); // Call Function to upload file to one SFTP server String sftpResponse = ""; int SuccessCount = 0; for (int i = 0; i < hosts.length; i++) { sftpResponse = uploadFileToFTPS(hosts[i], filename, ftpsFilePath, username, password, data); if (sftpResponse.equalsIgnoreCase("Success")) { SuccessCount ++; } } if (SuccessCount == hosts.length) { data.addToLog("Upload Status", "All uploads Successfully"); if (delete_file_on_success ) { File fileToDelete = new File(filename); if (fileToDelete.delete()) { data.addToLog("File Delete", "Successful"); } else { data.addToLog("File Delete", "Failed"); } } return "done"; }else if(SuccessCount == 0) { data.addToLog("Upload Status", "All uploads Failed"); return "error"; }else { data.addToLog("Upload Status", "Only some uploads Successfully"); return "partial_success"; } } /** * This method returns the name the decision element will have in the Element * Pane in the Audium Builder for Studio. */ public String getElementName() { return "FTPS_Client"; } /** * This method returns the name of the folder in which this decision element * resides. Return null if it is to appear directly under the Elements folder. */ public String getDisplayFolderName() { return "Integration"; } /** * This method returns the text of a description of the decision element that * will appear as a popup when the cursor points to the element. */ public String getDescription() { return "Transfers a file to one or more FTPS servers."; } /** * This method returns an array of Setting objects representing all the settings * this decision element expects. Return null if the decision element does not * need any settings. */ public Setting[] getSettings() throws ElementException { Setting[] settings = { new Setting("filename", "Name of file to be transferred", "Full path of file to be transferred.", true, true, true, 3), new Setting("remote_filename", "Remote Filename", "FTPS server target filename. If not specified, the filename used will be the same as the input filename.", false, true, true, 3), new Setting("ftps_hosts", "FTPS Server(s)", "List of FTPS server host names or IP addresses that the file will be transferred to. " + NEW_LINE + "Each FTPS server entry delimited by a space character. Using TCP Port 990 (implicit FTPS) to connect to each FTPS Server.", true, false, true, 3), new Setting("ftps_user", "Default Username", "Username to use when transferring the file." + NEW_LINE + "If left blank, \"anonymous\" will be assumed. This must be set if there is a default password.", false, true, true, 3), new Setting("ftps_password", "Default Password", "Password to use when transferring the file.", false, true, true, 3), new Setting("ftps_path", "FTPS Path", "Directory on FTPS server in which to transfer the file. Use the forward slash as directory delimiter e.g. 'dir/subdir'. Directory will be created if it does not currently exist.", false, true, true, 3), new Setting("delete_file_on_success", "Delete file if successful", "Delete the original file after it has been successfully transferred to all FTP Server(s).", false, true, true, 4) }; // settings[0].setCustomValidator(new WindowsFilePathValidator()) // settings[1].setCustomValidator(new FilenameValidator()); // settings[2].setCustomValidator(new ServerListValidator()); settings[0].setDefaultValue(""); settings[1].setDefaultValue(""); settings[2].setDefaultValue(""); settings[3].setDefaultValue("anonymous"); // settings[3].setCustomValidator(new UsernameValidator()); settings[4].setDefaultValue(""); settings[5].setDefaultValue(""); // settings[5].setCustomValidator(new FTPPathValidator()); settings[6].setDefaultValue("true"); return settings; } /** * This method returns an array of ExitState objects representing all the * possible exit states the decision element can return. There must be at least * one exit state. */ public ExitState[] getExitStates() throws ElementException { return new ExitState[] { new ExitState("done", "done", "This exit state means there the file was successfully transferred to all FTP Server(s)."), new ExitState("partial_success", "partial_success", "This exit state is used when not all ftp transfers were successful."), new ExitState("error", "error", "This exit state is used if an error occurred and the file was not transferred to any FTP Server(s).") }; } public ElementData[] getElementData() throws ElementException { return new ElementData[] { new ElementData("failed_servers", "File was not transferred to these FTP Server(s)."), new ElementData("failed_servers_reasons", "Reason why FTPS transfers failed."), new ElementData("failed_servers_count", "Number of failed FTPS transfers.") }; } public String uploadFileToFTPS(String ftpsServer, String sourceFilePath, String ftpsFilePath, String username, String password, DecisionElementData data) throws AudiumException { FTPSClient ftpsClient = new FTPSClient("TLS", true); FileInputStream fis = null; try { data.addToLog("Connecting to FTPS Server", ftpsServer); // ftpsClient.addProtocolCommandListener(new PrintCommandListener(new // PrintWriter(System.out), true)); // System.out.println("Connecting to FTPS Server: " + ftpsServer); ftpsClient.connect(ftpsServer, 990); ftpsClient.enterLocalPassiveMode(); ftpsClient.login(username, password); // Enable UTF-8 (optional, some servers require it) //ftpsClient.setControlEncoding("UTF-8"); ftpsClient.execPROT("P"); // **Enable encryption for data channel** ftpsClient.execPBSZ(0); // **Set protection buffer size** // Set binary mode for file transfer (match TYPE I) //ftpsClient.setFileType(FTPSClient.BINARY_FILE_TYPE); int replyCode = ftpsClient.getReplyCode(); if (!ftpsClient.isConnected()) { data.addToLog("Failed to connect. Reply code", Integer.toString(replyCode)); return ("Fail"); } File file = new File(sourceFilePath); data.addToLog("sourceFilePath", sourceFilePath); String remoteFilePath = ftpsFilePath; // String fileName = file.getName(); data.addToLog("remoteFilePath", remoteFilePath); fis = new FileInputStream(file); // System.out.println("Uploading file: " + file.getName()); // boolean uploaded = ftpsClient.storeFile(remoteFilePath, fis); boolean uploaded = ftpsClient.storeFile(remoteFilePath, fis); if (uploaded) { data.addToLog("SFTP outcome", "Successfully Uploaded"); return ("Success"); } else { data.addToLog("SFTP outcome", "File upload failed."); return ("Fail"); } } catch (IOException e) { // System.err.println("Error: " + e.getMessage()); data.addToLog("Error: ", e.getMessage()); //throw new AudiumException("Error", e); return ("Fail"); } finally { try { if (fis != null) fis.close(); if (ftpsClient.isConnected()) { ftpsClient.logout(); ftpsClient.disconnect(); } } catch (IOException e) { data.addToLog("Error closing connection", e.getMessage()); return ("Fail"); } } } }