You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by cm...@apache.org on 2013/07/05 19:16:45 UTC

git commit: CAMEL-6266: Support for SFTP through a proxy Thanks to Joakim Ek for the patch

Updated Branches:
  refs/heads/master a2f4f6c1d -> 3ff26cdc4


CAMEL-6266: Support for SFTP through a proxy
Thanks to Joakim Ek for the patch


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/3ff26cdc
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/3ff26cdc
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/3ff26cdc

Branch: refs/heads/master
Commit: 3ff26cdc42ff545dd990adc9cff2c4a4a0287b92
Parents: a2f4f6c
Author: cmueller <cm...@apache.org>
Authored: Fri Jul 5 19:16:41 2013 +0200
Committer: cmueller <cm...@apache.org>
Committed: Fri Jul 5 19:16:41 2013 +0200

----------------------------------------------------------------------
 components/camel-ftp/pom.xml                    |   7 ++
 .../component/file/remote/SftpEndpoint.java     |   9 +-
 .../component/file/remote/SftpOperations.java   |  15 +++
 .../sftp/SftpSimpleConsumeThroughProxyTest.java |  89 +++++++++++++
 .../sftp/SftpSimpleProduceThroughProxyTest.java | 125 +++++++++++++++++++
 5 files changed, 244 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/3ff26cdc/components/camel-ftp/pom.xml
----------------------------------------------------------------------
diff --git a/components/camel-ftp/pom.xml b/components/camel-ftp/pom.xml
index 305613c..62393d5 100644
--- a/components/camel-ftp/pom.xml
+++ b/components/camel-ftp/pom.xml
@@ -96,6 +96,13 @@
       <version>${sshd-version}</version>
       <scope>test</scope>
     </dependency>
+    <!-- for testing sftp through http proxy -->
+    <dependency>
+      <groupId>org.littleshoot</groupId>
+      <artifactId>littleproxy</artifactId>
+      <version>0.4</version>
+      <scope>test</scope>
+    </dependency>
     <!-- needed for sftp server -->
     <dependency>
       <groupId>org.bouncycastle</groupId>

http://git-wip-us.apache.org/repos/asf/camel/blob/3ff26cdc/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpEndpoint.java
----------------------------------------------------------------------
diff --git a/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpEndpoint.java b/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpEndpoint.java
index b2b62ae..257e240 100644
--- a/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpEndpoint.java
+++ b/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpEndpoint.java
@@ -17,6 +17,7 @@
 package org.apache.camel.component.file.remote;
 
 import com.jcraft.jsch.ChannelSftp;
+import com.jcraft.jsch.Proxy;
 import org.apache.camel.Processor;
 import org.apache.camel.component.file.GenericFileProducer;
 
@@ -25,6 +26,8 @@ import org.apache.camel.component.file.GenericFileProducer;
  */
 public class SftpEndpoint extends RemoteFileEndpoint<ChannelSftp.LsEntry> {
 
+    Proxy proxy;
+    
     public SftpEndpoint() {
     }
 
@@ -47,7 +50,7 @@ public class SftpEndpoint extends RemoteFileEndpoint<ChannelSftp.LsEntry> {
     }
 
     public RemoteFileOperations<ChannelSftp.LsEntry> createRemoteFileOperations() {
-        SftpOperations operations = new SftpOperations();
+        SftpOperations operations = new SftpOperations(proxy);
         operations.setEndpoint(this);
         return operations;
     }
@@ -56,4 +59,8 @@ public class SftpEndpoint extends RemoteFileEndpoint<ChannelSftp.LsEntry> {
     public String getScheme() {
         return "sftp";
     }
+
+    public void setProxy(Proxy proxy) {
+        this.proxy = proxy;
+    }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/3ff26cdc/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpOperations.java
----------------------------------------------------------------------
diff --git a/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpOperations.java b/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpOperations.java
index cdf6e05..f3e4c39 100644
--- a/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpOperations.java
+++ b/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpOperations.java
@@ -38,6 +38,7 @@ import java.util.regex.Pattern;
 import com.jcraft.jsch.ChannelSftp;
 import com.jcraft.jsch.JSch;
 import com.jcraft.jsch.JSchException;
+import com.jcraft.jsch.Proxy;
 import com.jcraft.jsch.Session;
 import com.jcraft.jsch.SftpException;
 import com.jcraft.jsch.UIKeyboardInteractive;
@@ -68,10 +69,18 @@ import static org.apache.camel.util.ObjectHelper.isNotEmpty;
 public class SftpOperations implements RemoteFileOperations<ChannelSftp.LsEntry> {
     private static final transient Logger LOG = LoggerFactory.getLogger(SftpOperations.class);
     private static final Pattern UP_DIR_PATTERN = Pattern.compile("/[^/]+");
+    private Proxy proxy;
     private SftpEndpoint endpoint;
     private ChannelSftp channel;
     private Session session;
 
+    public SftpOperations() {
+    }
+
+    public SftpOperations(Proxy proxy) {
+        this.proxy = proxy;
+    }
+
     /**
      * Extended user info which supports interactive keyboard mode, by entering the password.
      */
@@ -296,6 +305,12 @@ public class SftpOperations implements RemoteFileOperations<ChannelSftp.LsEntry>
             }
 
         });
+        
+        // set proxy if configured
+        if (proxy != null) {
+            session.setProxy(proxy);
+        }
+        
         return session;
     }
 

http://git-wip-us.apache.org/repos/asf/camel/blob/3ff26cdc/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/sftp/SftpSimpleConsumeThroughProxyTest.java
----------------------------------------------------------------------
diff --git a/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/sftp/SftpSimpleConsumeThroughProxyTest.java b/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/sftp/SftpSimpleConsumeThroughProxyTest.java
new file mode 100644
index 0000000..d9258fb
--- /dev/null
+++ b/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/sftp/SftpSimpleConsumeThroughProxyTest.java
@@ -0,0 +1,89 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.file.remote.sftp;
+
+import com.jcraft.jsch.ProxyHTTP;
+import org.apache.camel.Exchange;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.impl.JndiRegistry;
+import org.apache.camel.test.AvailablePortFinder;
+import org.junit.Test;
+import org.littleshoot.proxy.DefaultHttpProxyServer;
+import org.littleshoot.proxy.HttpProxyServer;
+import org.littleshoot.proxy.ProxyAuthorizationHandler;
+
+public class SftpSimpleConsumeThroughProxyTest extends SftpServerTestSupport {
+
+    private final int proxyPort = AvailablePortFinder.getNextAvailable(25000);
+    
+    
+    @Test
+    public void testSftpSimpleConsumeThroughProxy() throws Exception {
+        if (!canTest()) {
+            return;
+        }
+
+        // start http proxy
+        HttpProxyServer proxyServer = new DefaultHttpProxyServer(proxyPort);
+        proxyServer.addProxyAuthenticationHandler(new ProxyAuthorizationHandler() {
+            @Override
+            public boolean authenticate(String userName, String password) {
+                return "user".equals(userName) && "password".equals(password);
+            }
+        });
+        proxyServer.start();
+
+        String expected = "Hello World";
+
+        // create file using regular file
+        template.sendBodyAndHeader("file://" + FTP_ROOT_DIR, expected, Exchange.FILE_NAME, "hello.txt");
+
+        MockEndpoint mock = getMockEndpoint("mock:result");
+        mock.expectedMessageCount(1);
+        mock.expectedHeaderReceived(Exchange.FILE_NAME, "hello.txt");
+        mock.expectedBodiesReceived(expected);
+        
+        context.startRoute("foo");
+
+        assertMockEndpointsSatisfied();
+        
+        proxyServer.stop();
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("sftp://localhost:" + getPort() + "/" + FTP_ROOT_DIR + "?username=admin&password=admin&delay=10s&disconnect=true&proxy=#proxy")
+                    .routeId("foo").noAutoStartup()
+                    .to("mock:result");
+            }
+        };
+    }
+
+    @Override
+    protected JndiRegistry createRegistry() throws Exception {
+        JndiRegistry jndi = super.createRegistry();
+
+        final ProxyHTTP proxyHTTP = new ProxyHTTP("localhost", proxyPort);
+        proxyHTTP.setUserPasswd("user", "password");
+        jndi.bind("proxy", proxyHTTP);
+        return jndi;
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/3ff26cdc/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/sftp/SftpSimpleProduceThroughProxyTest.java
----------------------------------------------------------------------
diff --git a/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/sftp/SftpSimpleProduceThroughProxyTest.java b/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/sftp/SftpSimpleProduceThroughProxyTest.java
new file mode 100644
index 0000000..fb79d55
--- /dev/null
+++ b/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/sftp/SftpSimpleProduceThroughProxyTest.java
@@ -0,0 +1,125 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.file.remote.sftp;
+
+import java.io.File;
+
+import com.jcraft.jsch.ProxyHTTP;
+import org.apache.camel.Exchange;
+import org.apache.camel.impl.JndiRegistry;
+import org.apache.camel.test.AvailablePortFinder;
+import org.junit.Test;
+import org.littleshoot.proxy.DefaultHttpProxyServer;
+import org.littleshoot.proxy.HttpProxyServer;
+import org.littleshoot.proxy.ProxyAuthorizationHandler;
+
+public class SftpSimpleProduceThroughProxyTest extends SftpServerTestSupport {
+
+    private final int proxyPort = AvailablePortFinder.getNextAvailable(25000);
+
+    @Override
+    public boolean isUseRouteBuilder() {
+        return false;
+    }
+
+    @Test
+    public void testSftpSimpleProduceThroughProxy() throws Exception {
+        if (!canTest()) {
+            return;
+        }
+
+        // start http proxy
+        HttpProxyServer proxyServer = new DefaultHttpProxyServer(proxyPort);
+        proxyServer.addProxyAuthenticationHandler(new ProxyAuthorizationHandler() {
+            @Override
+            public boolean authenticate(String userName, String password) {
+                return "user".equals(userName) && "password".equals(password);
+            }
+        });
+        proxyServer.start();
+
+        template.sendBodyAndHeader("sftp://localhost:" + getPort() + "/" + FTP_ROOT_DIR + "?username=admin&password=admin&proxy=#proxy", "Hello World", Exchange.FILE_NAME, "hello.txt");
+
+        File file = new File(FTP_ROOT_DIR + "/hello.txt");
+        assertTrue("File should exist: " + file, file.exists());
+        assertEquals("Hello World", context.getTypeConverter().convertTo(String.class, file));
+        
+        proxyServer.stop();
+    }
+
+    @Test
+    public void testSftpSimpleSubPathProduceThroughProxy() throws Exception {
+        if (!canTest()) {
+            return;
+        }
+
+        // start http proxy
+        HttpProxyServer proxyServer = new DefaultHttpProxyServer(proxyPort);
+        proxyServer.addProxyAuthenticationHandler(new ProxyAuthorizationHandler() {
+            @Override
+            public boolean authenticate(String userName, String password) {
+                return "user".equals(userName) && "password".equals(password);
+            }
+        });
+        proxyServer.start();
+
+        template.sendBodyAndHeader("sftp://localhost:" + getPort() + "/" + FTP_ROOT_DIR + "/mysub?username=admin&password=admin&proxy=#proxy", "Bye World", Exchange.FILE_NAME, "bye.txt");
+
+        File file = new File(FTP_ROOT_DIR + "/mysub/bye.txt");
+        assertTrue("File should exist: " + file, file.exists());
+        assertEquals("Bye World", context.getTypeConverter().convertTo(String.class, file));
+
+        proxyServer.stop();
+    }
+
+    @Test
+    public void testSftpSimpleTwoSubPathProduceThroughProxy() throws Exception {
+        if (!canTest()) {
+            return;
+        }
+
+        // start http proxy
+        HttpProxyServer proxyServer = new DefaultHttpProxyServer(proxyPort);
+        proxyServer.addProxyAuthenticationHandler(new ProxyAuthorizationHandler() {
+            @Override
+            public boolean authenticate(String userName, String password) {
+                return "user".equals(userName) && "password".equals(password);
+            }
+        });
+        proxyServer.start();
+
+        template.sendBodyAndHeader("sftp://localhost:" + getPort() + "/" + FTP_ROOT_DIR + "/mysub/myother?username=admin&password=admin&proxy=#proxy", "Farewell World", Exchange.FILE_NAME,
+            "farewell.txt");
+
+        File file = new File(FTP_ROOT_DIR + "/mysub/myother/farewell.txt");
+        assertTrue("File should exist: " + file, file.exists());
+        assertEquals("Farewell World", context.getTypeConverter().convertTo(String.class, file));
+
+        proxyServer.stop();
+    }
+
+    @Override
+    protected JndiRegistry createRegistry() throws Exception {
+        JndiRegistry jndi = super.createRegistry();
+
+        final ProxyHTTP proxyHTTP = new ProxyHTTP("localhost", proxyPort);
+        proxyHTTP.setUserPasswd("user", "password");
+        jndi.bind("proxy", proxyHTTP);
+        return jndi;
+    }
+
+}