All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ow2.petals.bc.ftp.service.FTPService Maven / Gradle / Ivy

There is a newer version: 3.9.0
Show newest version
/**
 * Copyright (c) 2007-2012 EBM WebSourcing, 2012-2016 Linagora
 * 
 * This program/library is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 2.1 of the License, or (at your
 * option) any later version.
 * 
 * This program/library 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 Lesser General Public License
 * for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program/library; If not, see http://www.gnu.org/licenses/
 * for the GNU Lesser General Public License version 2.1.
 */
package org.ow2.petals.bc.ftp.service;

import java.io.IOException;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.logging.Logger;

import javax.activation.DataHandler;
import javax.jbi.messaging.MessagingException;

import org.ow2.petals.bc.ftp.FTPConstants;
import org.ow2.petals.bc.ftp.FTPUtil;
import org.ow2.petals.bc.ftp.FtpProvideExtFlowStepBeginLogData;
import org.ow2.petals.bc.ftp.FtpProvideExtFlowStepEndLogData;
import org.ow2.petals.bc.ftp.MissingElementException;
import org.ow2.petals.bc.ftp.connection.WrappedFTPClient;
import org.ow2.petals.commons.log.FlowAttributes;
import org.ow2.petals.commons.log.Level;
import org.ow2.petals.commons.log.PetalsExecutionContext;
import org.ow2.petals.component.framework.api.Message;
import org.ow2.petals.component.framework.api.Message.MEPConstants;
import org.ow2.petals.component.framework.api.message.Exchange;
import org.ow2.petals.component.framework.logger.ProvideExtFlowStepFailureLogData;
import org.ow2.petals.component.framework.util.MtomUtil;
import org.ow2.petals.component.framework.util.MtomUtil.MtomMapping;
import org.ow2.petals.component.framework.util.SourceUtil;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.ebmwebsourcing.easycommons.lang.StringHelper;
import com.ebmwebsourcing.easycommons.uuid.SimpleUUIDGenerator;
import com.ebmwebsourcing.easycommons.xml.XMLHelper;

/**
 * The FTP JBI listener. Writes a file to FTP server on incoming JBI message.
 * 
 * @author Mathieu CARROLLE - EBM WebSourcing
 * @author Adrien Louis - EBM WebSourcing
 * @author Roland Naudin - EBM WebSourcing
 */
public class FTPService {

    /**
     * An UUID generator.
     */
    private final SimpleUUIDGenerator simpleUUIDGenerator = new SimpleUUIDGenerator();

    private final Logger logger;

    public FTPService(final Logger logger) {
        super();
        this.logger = logger;
    }

    /***
     * FTP DEL Operation 
* * @param exchange * @param connectionInfo * @param inMessage * @throws MissingElementException * @throws Exception */ public void processDel(final Exchange exchange, final Document inMessage, final WrappedFTPClient client) throws MessagingException, MissingElementException { if (this.logger.isLoggable(Level.FINE)) { this.logger.fine("JBI exchange received - Process DEL operation"); } try { // Checks the MEP of the incoming message if (!exchange.isInOnlyPattern()) { throw new MessagingException(FTPUtil.getOperationValidMep(FTPConstants.DEL_OPERATION, Message.MEPConstants.IN_ONLY_PATTERN)); } // retrieve the filename to get final Node filePatternNode = XMLHelper.findChild(inMessage.getFirstChild(), null, FTPConstants.FTP_FILENAME, false); final String filePattern; if (filePatternNode != null) { filePattern = filePatternNode.getTextContent(); } else { throw new MissingElementException(FTPConstants.FTP_FILENAME); } if (filePattern != null) { final String newFlowStepId = this.simpleUUIDGenerator.getNewID(); final FlowAttributes flowAttributes = PetalsExecutionContext.getFlowAttributes(); final String flowInstanceId; final String flowStepId; if (flowAttributes != null) { flowInstanceId = flowAttributes.getFlowInstanceId(); flowStepId = flowAttributes.getFlowStepId(); } else { flowInstanceId = null; flowStepId = null; } this.logger.log(Level.MONIT, "", new FtpProvideExtFlowStepBeginLogData(flowInstanceId, flowStepId, newFlowStepId, client.getConnectionInfo().getDirectory(), "(" + filePattern + ")")); try { // do the FTP DEL operation client.del(filePattern); this.logger .log(Level.MONIT, "", new FtpProvideExtFlowStepEndLogData(flowInstanceId, newFlowStepId)); } catch (final IOException e) { final StringBuilder errorSB = new StringBuilder(); errorSB.append("Can not delete file on FTP server ["); errorSB.append(client.getConnectionInfo().getServer()); errorSB.append("] : IOException : "); errorSB.append(e.getMessage()); this.logger.log(Level.MONIT, "", new ProvideExtFlowStepFailureLogData(flowInstanceId, newFlowStepId, errorSB.toString())); throw new MessagingException(errorSB.toString()); } } } finally { if (this.logger.isLoggable(Level.FINE)) { this.logger.fine("DEL operation ended"); } } } /** * FTP DIR operation.
* a Fault is returned for bad request or IO problems * * @param exchange * the message exchange, MUST be non null * @throws MessagingException * bad MEP */ public void processDir(final Exchange exchange, final WrappedFTPClient client) throws MessagingException { if (this.logger.isLoggable(Level.FINE)) { this.logger.fine("JBI exchange received - Process DIR operation"); } try { if (!exchange.isInOutPattern()) { throw new MessagingException(FTPUtil.getOperationValidMep(FTPConstants.DIR_OPERATION, MEPConstants.IN_OUT_PATTERN)); } final String newFlowStepId = this.simpleUUIDGenerator.getNewID(); final FlowAttributes flowAttributes = PetalsExecutionContext.getFlowAttributes(); final String flowInstanceId; final String flowStepId; if (flowAttributes != null) { flowInstanceId = flowAttributes.getFlowInstanceId(); flowStepId = flowAttributes.getFlowStepId(); } else { flowInstanceId = null; flowStepId = null; } this.logger.log(Level.MONIT, "", new FtpProvideExtFlowStepBeginLogData(flowInstanceId, flowStepId, newFlowStepId, client.getConnectionInfo().getDirectory())); try { // do the FTP DIR operation final List fileNames = client.listFolderContent(); this.logger.log(Level.MONIT, "", new FtpProvideExtFlowStepEndLogData(flowInstanceId, newFlowStepId)); // generate filename list final String result = FTPUtil.generateFileNameList(fileNames, exchange.getOperation()); exchange.getOutMessage().setContent(SourceUtil.createSource(result)); } catch (final IOException e) { final String errorMsg = "Can not list files on FTP server [" + client.getConnectionInfo().getServer() + "]. Cause : " + e.getMessage(); this.logger.log(Level.MONIT, "", new ProvideExtFlowStepFailureLogData(flowInstanceId, newFlowStepId, errorMsg)); FTPUtil.setIOFaultOnExchange(exchange, errorMsg); } } finally { if (this.logger.isLoggable(Level.FINE)) { this.logger.fine("DIR operation ended"); } } } /** * * FTP GET operation
* get the file as a source message a Fault is returned for bad request or IO problems * * @param exchange * the message exchange, MUST be non null * @param connectionInfo * @param inMessage * @throws MessagingException * bad MEP */ public void processGet(final Exchange exchange, final Document inMessage, final WrappedFTPClient client) throws MessagingException { if (this.logger.isLoggable(Level.FINE)) { this.logger.fine("JBI exchange received - Process GET operation"); } try { // Checks the MEP of the incoming message if (!exchange.isInOutPattern()) { throw new MessagingException(FTPUtil.getOperationValidMep(FTPConstants.GET_OPERATION, Message.MEPConstants.IN_OUT_PATTERN)); } // retrieve the filename to get final Node filePatternNode = XMLHelper.findChild(inMessage.getFirstChild(), null, FTPConstants.FTP_FILENAME, false); final String filePattern; if (filePatternNode != null) { filePattern = filePatternNode.getTextContent(); } else { filePattern = null; } if (StringHelper.isNullOrEmpty(filePattern)) { FTPUtil.setMissingElementFaultOnExchange(exchange, FTPConstants.FTP_FILENAME); } else { final String newFlowStepId = this.simpleUUIDGenerator.getNewID(); final FlowAttributes flowAttributes = PetalsExecutionContext.getFlowAttributes(); final String flowInstanceId; final String flowStepId; if (flowAttributes != null) { flowInstanceId = flowAttributes.getFlowInstanceId(); flowStepId = flowAttributes.getFlowStepId(); } else { flowInstanceId = null; flowStepId = null; } this.logger.log(Level.MONIT, "", new FtpProvideExtFlowStepBeginLogData(flowInstanceId, flowStepId, newFlowStepId, client.getConnectionInfo().getDirectory(), "(" + filePattern + ")")); try { // do the FTP GET operation final Document doc = client.get(filePattern); if (client.getConnectionInfo().getDeleteProcessedFile()) { // TODO: Perhaps should we log 2 MONIT traces, one for each interaction with FTP server ? client.del(filePattern); } this.logger .log(Level.MONIT, "", new FtpProvideExtFlowStepEndLogData(flowInstanceId, newFlowStepId)); final Element rootElt = doc.createElementNS(exchange.getOperation().getNamespaceURI(), "ver:getResponse"); rootElt.appendChild(doc.getDocumentElement()); doc.appendChild(rootElt); exchange.setOutMessageContent(doc); } catch (final IOException e) { final String errorMsg = "Can not get file [" + filePattern + "] on FTP server [" + client.getConnectionInfo().getServer() + "]. Cause : " + e.getMessage(); this.logger.log(Level.MONIT, "", new ProvideExtFlowStepFailureLogData(flowInstanceId, newFlowStepId, errorMsg)); FTPUtil.setIOFaultOnExchange(exchange, errorMsg); } } } finally { if (this.logger.isLoggable(Level.FINE)) { this.logger.fine("GET operation ended"); } } } /** * * FTP GET operation
* get the file as a source message a Fault is returned for bad request or IO problems * * @param exchange * the message exchange, MUST be non null * @param connectionInfo * @param inMessage * @throws MessagingException * bad MEP */ public void processGetAsAttachment(final Exchange exchange, final Document inMessage, final WrappedFTPClient client) throws MessagingException { this.logger.fine("JBI exchange received - Process GET AS ATTACHMENT operation"); try { // Checks the MEP of the incoming message if (!exchange.isInOutPattern()) { throw new MessagingException(FTPUtil.getOperationValidMep(FTPConstants.GET_ATTACHMENT_OPERATION, Message.MEPConstants.IN_OUT_PATTERN)); } // retrieve the filename to get final Node filePatternNode = XMLHelper.findChild(inMessage.getFirstChild(), null, FTPConstants.FTP_FILENAME, true); final String filePattern; if (filePatternNode != null) { filePattern = filePatternNode.getTextContent(); } else { filePattern = null; } if (StringHelper.isNullOrEmpty(filePattern)) { FTPUtil.setMissingElementFaultOnExchange(exchange, FTPConstants.FTP_FILENAME); } else { final String newFlowStepId = this.simpleUUIDGenerator.getNewID(); final FlowAttributes flowAttributes = PetalsExecutionContext.getFlowAttributes(); final String flowInstanceId; final String flowStepId; if (flowAttributes != null) { flowInstanceId = flowAttributes.getFlowInstanceId(); flowStepId = flowAttributes.getFlowStepId(); } else { flowInstanceId = null; flowStepId = null; } this.logger.log(Level.MONIT, "", new FtpProvideExtFlowStepBeginLogData(flowInstanceId, flowStepId, newFlowStepId, client.getConnectionInfo().getDirectory(), "(" + filePattern + ")")); try { // do the FTP GET operation final DataHandler file = client.getFileAsAttachment(filePattern); if (client.getConnectionInfo().getDeleteProcessedFile()) { // TODO: Perhaps should we log 2 MONIT traces, one for each interaction with FTP server ? client.del(file.getName()); } this.logger .log(Level.MONIT, "", new FtpProvideExtFlowStepEndLogData(flowInstanceId, newFlowStepId)); exchange.setOutMessageAttachment(file.getName(), file); final Document outDoc = FTPUtil.generateMTOMResponse(file.getName(), exchange.getOperation()); exchange.setOutMessageContent(outDoc); } catch (final IOException e) { final String errorMsg = "Can not get file [" + filePattern + "] on FTP server [" + client.getConnectionInfo().getServer() + "]. Cause : " + e.getMessage(); this.logger.log(Level.MONIT, "", new ProvideExtFlowStepFailureLogData(flowInstanceId, newFlowStepId, errorMsg)); FTPUtil.setIOFaultOnExchange(exchange, errorMsg); } } } finally { this.logger.fine("GET AS ATTACHMENT operation ended"); } } private final String filenamesAsPatterns(final Collection filenames) { assert !filenames.isEmpty(); final StringBuffer sb = new StringBuffer("("); for (final String filename : filenames) { sb.append(filename); sb.append("|"); } sb.deleteCharAt(sb.length() - 1); sb.append(")"); return sb.toString(); } /** * FTP MGET operation
* All files are getted as attachments * * @param exchange * @param connectionInfo * @param inMessage * @throws Exception */ public void processMGet(final Exchange exchange, final Document inMessage, final WrappedFTPClient client) throws MessagingException { if (this.logger.isLoggable(Level.FINE)) { this.logger.fine("JBI exchange received - Process MGET operation"); } try { if (!exchange.isInOutPattern()) { throw new MessagingException(FTPUtil.getOperationValidMep(FTPConstants.MGET_OPERATION, MEPConstants.IN_OUT_PATTERN)); } // retrieve filenames to get final NodeList list = inMessage.getFirstChild().getChildNodes(); final List filenames = new LinkedList(); for (int index = 0; index < list.getLength(); index++) { if (FTPConstants.FTP_FILENAME.equalsIgnoreCase(list.item(index).getLocalName())) { filenames.add(list.item(index).getTextContent()); } } if (filenames.size() == 0) { FTPUtil.setMissingElementFaultOnExchange(exchange, FTPConstants.FTP_FILENAME); } else { final String newFlowStepId = this.simpleUUIDGenerator.getNewID(); final FlowAttributes flowAttributes = PetalsExecutionContext.getFlowAttributes(); final String flowInstanceId; final String flowStepId; if (flowAttributes != null) { flowInstanceId = flowAttributes.getFlowInstanceId(); flowStepId = flowAttributes.getFlowStepId(); } else { flowInstanceId = null; flowStepId = null; } this.logger.log(Level.MONIT, "", new FtpProvideExtFlowStepBeginLogData(flowInstanceId, flowStepId, newFlowStepId, client.getConnectionInfo().getDirectory(), filenamesAsPatterns(filenames))); try { // do the FTP MGET operation final Map files = client.mGet(filenames); // add attachments on the OUT message for (Entry entry : files.entrySet()) { exchange.getOutMessage().addAttachment(entry.getKey(), entry.getValue()); } final List retrievedFilenames = new LinkedList(files.keySet()); final Document outDoc = FTPUtil.generateMTOMListResponse(retrievedFilenames, exchange.getOperation()); exchange.setOutMessageContent(outDoc); if (client.getConnectionInfo().getDeleteProcessedFile()) { client.mDel(retrievedFilenames); } this.logger .log(Level.MONIT, "", new FtpProvideExtFlowStepEndLogData(flowInstanceId, newFlowStepId)); } catch (final IOException e) { final String errorMsg = "Can not get files [" + filenames + "] on FTP server [" + client.getConnectionInfo().getServer() + "]. Cause : " + e.getMessage(); this.logger.log(Level.MONIT, "", new ProvideExtFlowStepFailureLogData(flowInstanceId, newFlowStepId, errorMsg)); FTPUtil.setIOFaultOnExchange(exchange, errorMsg); } } } finally { if (this.logger.isLoggable(Level.FINE)) { this.logger.fine("MGET operation ended"); } } } /** * Put attachments on the ftp server TODO an FTP connection is done for each file... * * @param exchange * @param connectionInfo * @throws MessagingException */ public void processMPut(final Exchange exchange, final Document inputDocument, final WrappedFTPClient client) throws MessagingException { if (this.logger.isLoggable(Level.FINE)) { this.logger.fine("JBI exchange received - Process MPUT operation"); } try { // Checks the MEP of the incoming message if (!exchange.isInOnlyPattern()) { throw new MessagingException(FTPUtil.getOperationValidMep(FTPConstants.MPUT_OPERATION, MEPConstants.IN_ONLY_PATTERN)); } // Check if the message has attachements if (exchange.getInMessageAttachments().isEmpty()) { final StringBuilder errorSB = new StringBuilder(); errorSB.append("One or more attachments expected."); throw new MessagingException(errorSB.toString()); } final String newFlowStepId = this.simpleUUIDGenerator.getNewID(); final FlowAttributes flowAttributes = PetalsExecutionContext.getFlowAttributes(); final String flowInstanceId; final String flowStepId; if (flowAttributes != null) { flowInstanceId = flowAttributes.getFlowInstanceId(); flowStepId = flowAttributes.getFlowStepId(); } else { flowInstanceId = null; flowStepId = null; } try { // rebuild a hashmap containing files and their names final MtomMapping mapping = MtomUtil.getMtomMapping(exchange, inputDocument.getDocumentElement()); final Map attachments = mapping.getContentIdToDataHandler(); if (this.logger.isLoggable(Level.FINE)) { this.logger.fine(mapping.toString()); } final String filenamesAsPatterns = filenamesAsPatterns(attachments.keySet()); this.logger.log(Level.MONIT, "", new FtpProvideExtFlowStepBeginLogData(flowInstanceId, flowStepId, newFlowStepId, client.getConnectionInfo().getDirectory(), filenamesAsPatterns)); client.mPut(attachments); this.logger.log(Level.MONIT, "", new FtpProvideExtFlowStepEndLogData(flowInstanceId, newFlowStepId)); } catch (final IOException e) { final StringBuilder errorSB = new StringBuilder(); errorSB.append("Can not put files on FTP server ["); errorSB.append(client.getConnectionInfo().getServer()); errorSB.append("] : IOException : "); errorSB.append(e.getMessage()); this.logger.log(Level.MONIT, "", new ProvideExtFlowStepFailureLogData(flowInstanceId, newFlowStepId, errorSB.toString())); throw new MessagingException(errorSB.toString()); } } finally { this.logger.fine("MPUT operation ended"); } } /** * Put the source on the ftp server with the given filename a Fault is returned on IO problems TODO the content to * send is a String, which is not optimal * * @param exchange * @param fileName * @param connectionInfo * @param inMessage * @throws MessagingException * @throws MissingElementException */ public void processPut(final Exchange exchange, final Document inMessage, final WrappedFTPClient client) throws MessagingException, MissingElementException { if (this.logger.isLoggable(Level.FINE)) { this.logger.fine("JBI exchange received - Process PUT operation"); } try { if (exchange == null) { throw new MessagingException("exchange parameter is null"); } // Checks the MEP of the incoming message if (!exchange.isInOnlyPattern()) { throw new MessagingException(FTPUtil.getOperationValidMep(FTPConstants.PUT_OPERATION, MEPConstants.IN_ONLY_PATTERN)); } // Check the root node final Node root = inMessage.getFirstChild(); if (root == null || !FTPConstants.PUT_OPERATION.equalsIgnoreCase(root.getLocalName())) { throw new MissingElementException(FTPConstants.PUT_OPERATION); } final Node fileNameNode = XMLHelper.findChild(root, null, FTPConstants.FTP_FILENAME, false); if (fileNameNode == null || !FTPConstants.FTP_FILENAME.equalsIgnoreCase(fileNameNode.getLocalName())) { throw new MissingElementException(FTPConstants.FTP_FILENAME); } final Node bodyNode = XMLHelper.findChild(root, null, FTPConstants.BODY, false); if (bodyNode == null) { throw new MissingElementException(FTPConstants.BODY); } final String newFlowStepId = this.simpleUUIDGenerator.getNewID(); final FlowAttributes flowAttributes = PetalsExecutionContext.getFlowAttributes(); final String flowInstanceId; final String flowStepId; if (flowAttributes != null) { flowInstanceId = flowAttributes.getFlowInstanceId(); flowStepId = flowAttributes.getFlowStepId(); } else { flowInstanceId = null; flowStepId = null; } try { final String body = XMLHelper.toString(bodyNode.getChildNodes()); this.logger.log(Level.MONIT, "", new FtpProvideExtFlowStepBeginLogData(flowInstanceId, flowStepId, newFlowStepId, client.getConnectionInfo().getDirectory(), fileNameNode.getTextContent())); client.putString(fileNameNode.getTextContent(), body); this.logger.log(Level.MONIT, "", new FtpProvideExtFlowStepEndLogData(flowInstanceId, newFlowStepId)); } catch (final IOException e) { final StringBuilder errorSB = new StringBuilder(); errorSB.append("Can not put XML content on FTP server ["); errorSB.append(client.getConnectionInfo().getServer()); errorSB.append("] : IOException : "); errorSB.append(e.getMessage()); this.logger.log(Level.MONIT, "", new ProvideExtFlowStepFailureLogData(flowInstanceId, newFlowStepId, errorSB.toString())); throw new MessagingException(errorSB.toString()); } catch (final DOMException e) { final StringBuilder errorSB = new StringBuilder(); errorSB.append("Can not put XML content on FTP server ["); errorSB.append(client.getConnectionInfo().getServer()); errorSB.append("] : DOMException : "); errorSB.append(e.getMessage()); this.logger.log(Level.MONIT, "", new ProvideExtFlowStepFailureLogData(flowInstanceId, newFlowStepId, errorSB.toString())); throw new MessagingException(errorSB.toString()); } } finally { if (this.logger.isLoggable(Level.FINE)) { this.logger.fine("PUT operation ended"); } } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy