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.InputStream;
020
021 import com.jcraft.jsch.ChannelSftp;
022 import com.jcraft.jsch.JSchException;
023 import com.jcraft.jsch.Session;
024
025 import org.apache.camel.Exchange;
026
027 public class SftpProducer extends RemoteFileProducer<RemoteFileExchange> {
028 private SftpEndpoint endpoint;
029 private ChannelSftp channel;
030 private Session session;
031
032 public SftpProducer(SftpEndpoint endpoint, Session session) {
033 super(endpoint);
034 this.endpoint = endpoint;
035 this.session = session;
036 }
037
038 public void process(Exchange exchange) throws Exception {
039 if (log.isTraceEnabled()) {
040 log.trace("Processing " + endpoint.getConfiguration());
041 }
042 connectIfNecessary();
043 // If the attempt to connect isn't successful, then the thrown
044 // exception will signify that we couldn't deliver
045 try {
046 process(endpoint.createExchange(exchange));
047 } catch (Exception e) {
048 if (isStopping() || isStopped()) {
049 // if we are stopping then ignore any exception during a poll
050 log.warn("Producer is stopping. Ignoring caught exception: "
051 + e.getClass().getCanonicalName() + " message: " + e.getMessage());
052 } else {
053 log.warn("Exception occured during processing: "
054 + e.getClass().getCanonicalName() + " message: " + e.getMessage());
055 disconnect();
056 // Rethrow to signify that we didn't poll
057 throw e;
058 }
059 }
060 }
061
062 protected void connectIfNecessary() throws JSchException {
063 if (channel == null || !channel.isConnected()) {
064 if (session == null || !session.isConnected()) {
065 log.trace("Session isn't connected, trying to recreate and connect.");
066 session = endpoint.createSession();
067 session.connect();
068 }
069 log.trace("Channel isn't connected, trying to recreate and connect.");
070 channel = endpoint.createChannelSftp(session);
071 channel.connect();
072 log.info("Connected to " + endpoint.getConfiguration().remoteServerInformation());
073 }
074 }
075
076 protected void disconnect() throws JSchException {
077 if (log.isDebugEnabled()) {
078 log.debug("Disconnecting from " + remoteServer());
079 }
080 if (session != null) {
081 session.disconnect();
082 }
083 if (channel != null) {
084 channel.disconnect();
085 }
086 }
087
088 public void process(RemoteFileExchange exchange) throws Exception {
089 InputStream payload = exchange.getIn().getBody(InputStream.class);
090 try {
091 String remoteServer = endpoint.getConfiguration().remoteServerInformation();
092 String fileName = createFileName(exchange.getIn(), endpoint.getConfiguration());
093
094 int lastPathIndex = fileName.lastIndexOf('/');
095 if (lastPathIndex != -1) {
096 String directory = fileName.substring(0, lastPathIndex);
097 boolean success = SftpUtils.buildDirectory(channel, directory);
098 if (!success) {
099 log.warn("Couldn't build directory: " + directory + " (could be because of denied permissions)");
100 }
101 }
102
103 channel.put(payload, fileName);
104
105 log.info("Sent: " + fileName + " to: " + remoteServer);
106 } finally {
107 if (payload != null) {
108 payload.close();
109 }
110 }
111 }
112
113 }