/******************************************************************************* * Imixs Workflow Technology * Copyright (C) 2001, 2008 Imixs Software Solutions GmbH, * http://www.imixs.com * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You can receive a copy of the GNU General Public * License at http://www.gnu.org/licenses/gpl.html * * Contributors: * Imixs Software Solutions GmbH - initial API and implementation * Ralph Soika *******************************************************************************/ package com.alexanderlogistics; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.Optional; import java.util.logging.Logger; import org.apache.commons.compress.archivers.ArchiveException; import org.apache.commons.net.ftp.FTP; import org.apache.commons.net.ftp.FTPClient; import org.apache.commons.net.ftp.FTPSClient; import org.eclipse.microprofile.config.inject.ConfigProperty; import org.imixs.workflow.FileData; import org.imixs.workflow.exceptions.PluginException; import jakarta.ejb.Stateless; import jakarta.inject.Inject; /** * The FTPConnector service provides methods to push invoices to cargosoft * * @version 1.0 * @author rsoika */ @Stateless public class FTPConnector { public static final String FTP_ERROR = "FTP_ERROR"; public static final String ENV_EXPORT_FTP_HOST = "cargosoft.export.ftp.host"; public static final String ENV_EXPORT_FTP_PATH = "cargosoft.export.ftp.path"; public static final String ENV_EXPORT_FTP_PORT = "cargosoft.export.ftp.port"; public static final String ENV_EXPORT_FTP_USER = "cargosoft.export.ftp.user"; public static final String ENV_EXPORT_FTP_PASSWORD = "cargosoft.export.ftp.password"; public static final String ENV_EXPORT_FTP_MAX_ATTACHMENT_SIZED = "cargosoft.export.ftp.maxattachmentsize"; private static Logger logger = Logger.getLogger(FTPConnector.class.getName()); @Inject @ConfigProperty(name = ENV_EXPORT_FTP_HOST) Optional ftpServer; @Inject @ConfigProperty(name = ENV_EXPORT_FTP_PATH) Optional ftpPath; @Inject @ConfigProperty(name = ENV_EXPORT_FTP_PORT, defaultValue = "21") Optional ftpPort; @Inject @ConfigProperty(name = ENV_EXPORT_FTP_USER) Optional ftpUser; @Inject @ConfigProperty(name = ENV_EXPORT_FTP_PASSWORD) Optional ftpPassword; /** * This method transfers a snapshot to a ftp server. * * @param fileData object * @throws PluginException */ public void put(FileData fileData) throws PluginException { if (!ftpServer.isPresent()) { throw new PluginException(CargosoftExportAdapter.class.getSimpleName(), FTP_ERROR, "FTP file transfer failed: no ftp host name provided (" + ENV_EXPORT_FTP_HOST + ")!"); } String fileName = fileData.getName(); // Compute file path String ftpWorkingPath = ftpPath.get(); if (!ftpWorkingPath.startsWith("/")) { ftpWorkingPath = "/" + ftpWorkingPath; } if (!ftpWorkingPath.endsWith("/")) { ftpWorkingPath = ftpWorkingPath + "/"; } InputStream writer = null; FTPClient ftpClient = null; try { logger.finest("......put " + fileName + " to FTP server: " + ftpServer + "..."); ftpClient = new FTPSClient("TLS", false); ftpClient.setBufferSize(8192); ftpClient.connect(ftpServer.get(), ftpPort.get().intValue()); if (ftpClient.login(ftpUser.get(), ftpPassword.get()) == false) { throw new PluginException(CargosoftExportAdapter.class.getSimpleName(), FTP_ERROR, "FTP file transfer failed: login failed!"); } ftpClient.enterLocalPassiveMode(); ftpClient.setFileType(FTP.ASCII_FILE_TYPE); ftpClient.setControlEncoding("UTF-8"); // verify directories if (!ftpClient.changeWorkingDirectory(ftpWorkingPath)) { throw new PluginException(CargosoftExportAdapter.class.getSimpleName(), FTP_ERROR, "FTP file transfer failed: missing working directory '" + ftpWorkingPath + "' : " + ftpClient.getReplyString()); } // upload file to FTP server. writer = new ByteArrayInputStream(fileData.getContent()); if (!ftpClient.storeFile(fileName, writer)) { throw new PluginException(CargosoftExportAdapter.class.getSimpleName(), FTP_ERROR, "FTP file transfer failed: unable to write '" + ftpWorkingPath + fileName + "' : " + ftpClient.getReplyString()); } logger.finest("...." + ftpWorkingPath + fileName + " transfered successfull to " + ftpServer); } catch (IOException e) { throw new PluginException(CargosoftExportAdapter.class.getSimpleName(), FTP_ERROR, "FTP file transfer failed: " + e.getMessage(), e); } finally { // do logout.... try { if (writer != null) { writer.close(); } ftpClient.logout(); ftpClient.disconnect(); } catch (IOException e) { throw new PluginException(CargosoftExportAdapter.class.getSimpleName(), FTP_ERROR, "FTP file transfer failed: " + e.getMessage(), e); } } } /** * This method reads data form the current working directory * * @param snapshot * @throws ArchiveException * @return data */ public byte[] get(FTPClient ftpClient, String fileName) throws PluginException { if (ftpClient == null) { throw new PluginException(CargosoftExportAdapter.class.getSimpleName(), FTP_ERROR, "FTP file transfer failed: no ftpClient provided!"); } long l = System.currentTimeMillis(); ByteArrayOutputStream bos = null; try { bos = new ByteArrayOutputStream(); ftpClient.retrieveFile(fileName, bos); byte[] result = bos.toByteArray(); logger.finest("......" + fileName + " transfered successfull from " + ftpServer + " in " + (System.currentTimeMillis() - l) + "ms"); return result; } catch (IOException e) { throw new PluginException(CargosoftExportAdapter.class.getSimpleName(), FTP_ERROR, "FTP file transfer failed: " + e.getMessage(), e); } finally { // do logout.... try { if (bos != null) { bos.close(); } } catch (IOException e) { throw new PluginException(CargosoftExportAdapter.class.getSimpleName(), FTP_ERROR, "FTP file transfer failed: " + e.getMessage(), e); } } } /** * This method changes the current working sub-directy. If no corresponding * directory exits the method creats one. * * @throws ArchiveException */ @SuppressWarnings("unused") private void changeWorkingDirectory(FTPClient ftpClient, String subDirectory) throws PluginException { // test if we have the subdreictory try { if (!ftpClient.changeWorkingDirectory(subDirectory)) { // try to creat it.... if (!ftpClient.makeDirectory(subDirectory)) { throw new PluginException(CargosoftExportAdapter.class.getSimpleName(), FTP_ERROR, "FTP Error: unable to create sub-directory '" + subDirectory + "' : " + ftpClient.getReplyString()); } ftpClient.changeWorkingDirectory(subDirectory); } } catch (IOException e) { throw new PluginException(CargosoftExportAdapter.class.getSimpleName(), FTP_ERROR, "FTP file transfer failed: " + e.getMessage(), e); } } }