001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.camel.component.file.remote;
018    
019    import java.io.IOException;
020    import java.io.InputStream;
021    
022    import org.apache.camel.Exchange;
023    import org.apache.commons.net.ftp.FTPClient;
024    
025    public class FtpProducer extends RemoteFileProducer<RemoteFileExchange> {
026    
027        private FtpEndpoint endpoint;
028        private FTPClient client;
029        private boolean loggedIn;
030    
031        public FtpProducer(FtpEndpoint endpoint, FTPClient client) {
032            super(endpoint);
033            this.endpoint = endpoint;
034            this.client = client;
035        }
036    
037        public void process(Exchange exchange) throws Exception {
038            if (log.isTraceEnabled()) {
039                log.trace("Processing " + endpoint.getConfiguration());
040            }
041    
042            try {
043                connectIfNecessary();
044    
045                if (!loggedIn) {
046                    String message = "Could not connect/login to " + endpoint.getConfiguration();
047                    log.warn(message);
048                    throw new FtpOperationFailedException(client.getReplyCode(), client.getReplyString(), message);
049                }
050    
051                process(endpoint.createExchange(exchange));
052            } catch (Exception e) {
053                loggedIn = false;
054                if (isStopping() || isStopped()) {
055                    // if we are stopping then ignore any exception during a poll
056                    log.warn("Producer is stopping. Ignoring caught exception: "
057                             + e.getClass().getCanonicalName() + " message: " + e.getMessage());
058                } else {
059                    log.warn("Exception occured during processing: "
060                             + e.getClass().getCanonicalName() + " message: " + e.getMessage());
061                    disconnect();
062                    // Rethrow to signify that we didn't poll
063                    throw e;
064                }
065            }
066        }
067    
068        protected void connectIfNecessary() throws IOException {
069            if (!client.isConnected() || !loggedIn) {
070                if (log.isDebugEnabled()) {
071                    log.debug("Not connected/logged in, connecting to " + remoteServer());
072                }
073                loggedIn = FtpUtils.connect(client, endpoint.getConfiguration());
074                if (!loggedIn) {
075                    return;
076                }
077            }
078    
079            log.info("Connected and logged in to " + remoteServer());
080        }
081    
082        public void disconnect() throws IOException {
083            loggedIn = false;
084            if (log.isDebugEnabled()) {
085                log.debug("Disconnecting from " + remoteServer());
086            }
087            FtpUtils.disconnect(client);
088        }
089    
090        public void process(RemoteFileExchange exchange) throws Exception {
091            InputStream payload = exchange.getIn().getBody(InputStream.class);
092            try {
093                String fileName = createFileName(exchange.getIn(), endpoint.getConfiguration());
094    
095                int lastPathIndex = fileName.lastIndexOf('/');
096                if (lastPathIndex != -1) {
097                    String directory = fileName.substring(0, lastPathIndex);
098                    if (!FtpUtils.buildDirectory(client, directory)) {
099                        log.warn("Couldn't build directory: " + directory + " (could be because of denied permissions)");
100                    }
101                }
102    
103                boolean success = client.storeFile(fileName, payload);
104                if (!success) {
105                    String message = "Error sending file: " + fileName + " to: " + remoteServer();
106                    throw new FtpOperationFailedException(client.getReplyCode(), client.getReplyString(), message);
107                }
108    
109                log.info("Sent: " + fileName + " to: " + remoteServer());
110            } finally {
111                if (payload != null) {
112                    payload.close();
113                }
114            }
115        }
116    
117    }