You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ha...@apache.org on 2012/02/23 21:48:48 UTC
svn commit: r1292947 - in /camel/trunk/components: ./ camel-jsch/
camel-jsch/src/ camel-jsch/src/main/ camel-jsch/src/main/java/
camel-jsch/src/main/java/org/ camel-jsch/src/main/java/org/apache/
camel-jsch/src/main/java/org/apache/camel/ camel-jsch/sr...
Author: hadrian
Date: Thu Feb 23 20:48:47 2012
New Revision: 1292947
URL: http://svn.apache.org/viewvc?rev=1292947&view=rev
Log:
CAMEL-5020. Add support for the scp protocol
Added:
camel/trunk/components/camel-jsch/
camel/trunk/components/camel-jsch/pom.xml
camel/trunk/components/camel-jsch/src/
camel/trunk/components/camel-jsch/src/main/
camel/trunk/components/camel-jsch/src/main/java/
camel/trunk/components/camel-jsch/src/main/java/org/
camel/trunk/components/camel-jsch/src/main/java/org/apache/
camel/trunk/components/camel-jsch/src/main/java/org/apache/camel/
camel/trunk/components/camel-jsch/src/main/java/org/apache/camel/component/
camel/trunk/components/camel-jsch/src/main/java/org/apache/camel/component/jsch/
camel/trunk/components/camel-jsch/src/main/java/org/apache/camel/component/jsch/JschComponent.java
camel/trunk/components/camel-jsch/src/main/java/org/apache/camel/component/jsch/ScpConfiguration.java
camel/trunk/components/camel-jsch/src/main/java/org/apache/camel/component/jsch/ScpEndpoint.java
camel/trunk/components/camel-jsch/src/main/java/org/apache/camel/component/jsch/ScpFile.java
camel/trunk/components/camel-jsch/src/main/java/org/apache/camel/component/jsch/ScpOperations.java
camel/trunk/components/camel-jsch/src/main/java/org/apache/camel/component/jsch/ScpProcessStrategyFactory.java
camel/trunk/components/camel-jsch/src/main/java/org/apache/camel/component/jsch/ScpProducer.java
camel/trunk/components/camel-jsch/src/main/resources/
camel/trunk/components/camel-jsch/src/main/resources/META-INF/
camel/trunk/components/camel-jsch/src/main/resources/META-INF/services/
camel/trunk/components/camel-jsch/src/main/resources/META-INF/services/org/
camel/trunk/components/camel-jsch/src/main/resources/META-INF/services/org/apache/
camel/trunk/components/camel-jsch/src/main/resources/META-INF/services/org/apache/camel/
camel/trunk/components/camel-jsch/src/main/resources/META-INF/services/org/apache/camel/component/
camel/trunk/components/camel-jsch/src/main/resources/META-INF/services/org/apache/camel/component/scp
camel/trunk/components/camel-jsch/src/main/resources/log4j.properties
camel/trunk/components/camel-jsch/src/test/
camel/trunk/components/camel-jsch/src/test/java/
camel/trunk/components/camel-jsch/src/test/java/org/
camel/trunk/components/camel-jsch/src/test/java/org/apache/
camel/trunk/components/camel-jsch/src/test/java/org/apache/camel/
camel/trunk/components/camel-jsch/src/test/java/org/apache/camel/component/
camel/trunk/components/camel-jsch/src/test/java/org/apache/camel/component/jsch/
camel/trunk/components/camel-jsch/src/test/java/org/apache/camel/component/jsch/ScpServerTestSupport.java
camel/trunk/components/camel-jsch/src/test/java/org/apache/camel/component/jsch/ScpSimpleProduceTest.java
camel/trunk/components/camel-jsch/src/test/resources/
camel/trunk/components/camel-jsch/src/test/resources/client.jks
camel/trunk/components/camel-jsch/src/test/resources/hostkey.pem
camel/trunk/components/camel-jsch/src/test/resources/log4j.properties
camel/trunk/components/camel-jsch/src/test/resources/server.jks
Modified:
camel/trunk/components/pom.xml
Added: camel/trunk/components/camel-jsch/pom.xml
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jsch/pom.xml?rev=1292947&view=auto
==============================================================================
--- camel/trunk/components/camel-jsch/pom.xml (added)
+++ camel/trunk/components/camel-jsch/pom.xml Thu Feb 23 20:48:47 2012
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ 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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+ <parent>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-parent</artifactId>
+ <version>2.10-SNAPSHOT</version>
+ <relativePath>../../parent</relativePath>
+ </parent>
+
+ <artifactId>camel-jsch</artifactId>
+ <packaging>bundle</packaging>
+ <name>Camel :: Jsch</name>
+ <description>Camel SCP Support</description>
+
+ <properties>
+ <camel.osgi.import.before.defaults>
+ com.jcraft.jsch.*;version="[0.1.40,0.1.50)",
+ org.apache.camel.component.file.strategy;${camel.osgi.import.strict.version}
+ </camel.osgi.import.before.defaults>
+ <camel.osgi.export.pkg>org.apache.camel.component.jsch.*</camel.osgi.export.pkg>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-ftp</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>com.jcraft</groupId>
+ <artifactId>jsch</artifactId>
+ <version>${jsch-version}</version>
+ </dependency>
+
+ <!-- logging -->
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-log4j12</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ <scope>test</scope>
+ </dependency>
+
+ <!-- for testing -->
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-test</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.sshd</groupId>
+ <artifactId>sshd-core</artifactId>
+ <version>${sshd-version}</version>
+ <scope>test</scope>
+ </dependency>
+ <!-- needed by sshd server -->
+ <dependency>
+ <groupId>org.apache.mina</groupId>
+ <artifactId>mina-core</artifactId>
+ <version>${mina2-version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.bouncycastle</groupId>
+ <artifactId>bcprov-jdk16</artifactId>
+ <version>${bouncycastle-version}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+ <build>
+ <defaultGoal>install</defaultGoal>
+ </build>
+</project>
Added: camel/trunk/components/camel-jsch/src/main/java/org/apache/camel/component/jsch/JschComponent.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jsch/src/main/java/org/apache/camel/component/jsch/JschComponent.java?rev=1292947&view=auto
==============================================================================
--- camel/trunk/components/camel-jsch/src/main/java/org/apache/camel/component/jsch/JschComponent.java (added)
+++ camel/trunk/components/camel-jsch/src/main/java/org/apache/camel/component/jsch/JschComponent.java Thu Feb 23 20:48:47 2012
@@ -0,0 +1,84 @@
+/**
+ * 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.jsch;
+
+import com.jcraft.jsch.JSch;
+
+import java.net.URI;
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.component.file.GenericFileEndpoint;
+import org.apache.camel.component.file.remote.RemoteFileComponent;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Component providing secure messaging using JSch
+ */
+public class JschComponent extends RemoteFileComponent<ScpFile> {
+ private static final transient Logger LOG = LoggerFactory.getLogger(JschComponent.class);
+ static {
+ JSch.setConfig("StrictHostKeyChecking", "yes");
+ JSch.setLogger(new com.jcraft.jsch.Logger() {
+ @Override
+ public boolean isEnabled(int level) {
+ return level == FATAL || level == ERROR ? LOG.isErrorEnabled()
+ : level == WARN ? LOG.isWarnEnabled()
+ : level == INFO ? LOG.isInfoEnabled() : LOG.isDebugEnabled();
+ }
+ @Override
+ public void log(int level, String message) {
+ if (level == FATAL || level == ERROR) {
+ LOG.error("[JSCH] {}", message);
+ } else if (level == WARN) {
+ LOG.warn("[JSCH] {}", message);
+ } else if (level == INFO) {
+ LOG.info("[JSCH] {}", message);
+ } else {
+ LOG.debug("[JSCH] {}", message);
+ }
+ }
+ });
+ }
+
+ public JschComponent() {
+ }
+
+ public JschComponent(CamelContext context) {
+ super(context);
+ }
+
+ @Override
+ protected GenericFileEndpoint<ScpFile> buildFileEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception {
+ // TODO: revisit stripping the query part; should not be needed with valid uris
+ int query = uri.indexOf("?");
+ return new ScpEndpoint(uri, this, new ScpConfiguration(new URI(query >= 0 ? uri.substring(0, query) : uri)));
+ }
+
+ protected void afterPropertiesSet(GenericFileEndpoint<ScpFile> endpoint) throws Exception {
+ // noop
+ }
+
+ @Override
+ public void doStop() throws Exception {
+ // TODO: close all sessions
+ super.doStop();
+ }
+}
+
Added: camel/trunk/components/camel-jsch/src/main/java/org/apache/camel/component/jsch/ScpConfiguration.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jsch/src/main/java/org/apache/camel/component/jsch/ScpConfiguration.java?rev=1292947&view=auto
==============================================================================
--- camel/trunk/components/camel-jsch/src/main/java/org/apache/camel/component/jsch/ScpConfiguration.java (added)
+++ camel/trunk/components/camel-jsch/src/main/java/org/apache/camel/component/jsch/ScpConfiguration.java Thu Feb 23 20:48:47 2012
@@ -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.jsch;
+
+import java.net.URI;
+
+import org.apache.camel.component.file.remote.RemoteFileConfiguration;
+
+/**
+ * Secure FTP configuration
+ */
+public class ScpConfiguration extends RemoteFileConfiguration {
+
+ public static final int DEFAULT_SFTP_PORT = 22;
+ private String knownHostsFile;
+ private String privateKeyFile;
+ private String privateKeyFilePassphrase;
+ private String strictHostKeyChecking = "no";
+ private int serverAliveInterval;
+ private int serverAliveCountMax = 1;
+ private String chmod;
+ // comma separated list of ciphers.
+ // null means default jsch list will be used
+ private String ciphers;
+ private int compression;
+
+ public ScpConfiguration() {
+ setProtocol("sftp");
+ }
+
+ public ScpConfiguration(URI uri) {
+ super(uri);
+ }
+
+ @Override
+ protected void setDefaultPort() {
+ setPort(DEFAULT_SFTP_PORT);
+ }
+
+ public String getKnownHostsFile() {
+ return knownHostsFile;
+ }
+
+ public void setKnownHostsFile(String knownHostsFile) {
+ this.knownHostsFile = knownHostsFile;
+ }
+
+ public String getPrivateKeyFile() {
+ return privateKeyFile;
+ }
+
+ public void setPrivateKeyFile(String privateKeyFile) {
+ this.privateKeyFile = privateKeyFile;
+ }
+
+ public String getPrivateKeyFilePassphrase() {
+ return privateKeyFilePassphrase;
+ }
+
+ public void setPrivateKeyFilePassphrase(String privateKeyFilePassphrase) {
+ this.privateKeyFilePassphrase = privateKeyFilePassphrase;
+ }
+
+ public String getStrictHostKeyChecking() {
+ return strictHostKeyChecking;
+ }
+
+ public void setStrictHostKeyChecking(String strictHostKeyChecking) {
+ this.strictHostKeyChecking = strictHostKeyChecking;
+ }
+
+ public void setServerAliveInterval(int serverAliveInterval) {
+ this.serverAliveInterval = serverAliveInterval;
+ }
+
+ public int getServerAliveInterval() {
+ return serverAliveInterval;
+ }
+
+ public void setServerAliveCountMax(int serverAliveCountMax) {
+ this.serverAliveCountMax = serverAliveCountMax;
+ }
+
+ public int getServerAliveCountMax() {
+ return serverAliveCountMax;
+ }
+
+ public void setChmod(String chmod) {
+ this.chmod = chmod;
+ }
+
+ public String getChmod() {
+ return chmod;
+ }
+
+ public void setCiphers(String ciphers) {
+ this.ciphers = ciphers;
+ }
+
+ public String getCiphers() {
+ return ciphers;
+ }
+
+ public int getCompression() {
+ return compression;
+ }
+
+ public void setCompression(int compression) {
+ this.compression = compression;
+ }
+}
Added: camel/trunk/components/camel-jsch/src/main/java/org/apache/camel/component/jsch/ScpEndpoint.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jsch/src/main/java/org/apache/camel/component/jsch/ScpEndpoint.java?rev=1292947&view=auto
==============================================================================
--- camel/trunk/components/camel-jsch/src/main/java/org/apache/camel/component/jsch/ScpEndpoint.java (added)
+++ camel/trunk/components/camel-jsch/src/main/java/org/apache/camel/component/jsch/ScpEndpoint.java Thu Feb 23 20:48:47 2012
@@ -0,0 +1,69 @@
+/**
+ * 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.jsch;
+
+import org.apache.camel.Expression;
+import org.apache.camel.Processor;
+import org.apache.camel.component.file.GenericFileProducer;
+import org.apache.camel.component.file.remote.RemoteFileConfiguration;
+import org.apache.camel.component.file.remote.RemoteFileConsumer;
+import org.apache.camel.component.file.remote.RemoteFileEndpoint;
+import org.apache.camel.component.file.remote.RemoteFileOperations;
+
+/**
+ * Secure Copy Endpoint
+ */
+public class ScpEndpoint extends RemoteFileEndpoint<ScpFile> {
+
+ public ScpEndpoint() {
+ }
+
+ public ScpEndpoint(String uri, JschComponent component, RemoteFileConfiguration configuration) {
+ super(uri, component, configuration);
+ }
+
+ @Override
+ public ScpConfiguration getConfiguration() {
+ return (ScpConfiguration) this.configuration;
+ }
+
+ @Override
+ protected RemoteFileConsumer<ScpFile> buildConsumer(Processor processor) {
+ return null; // new ScpConsumer(this, processor, createRemoteFileOperations());
+ }
+
+ protected GenericFileProducer<ScpFile> buildProducer() {
+ return new ScpProducer(this, createRemoteFileOperations());
+ }
+
+ public RemoteFileOperations<ScpFile> createRemoteFileOperations() {
+ ScpOperations operations = new ScpOperations();
+ operations.setEndpoint(this);
+ return operations;
+ }
+
+ @Override
+ public String getScheme() {
+ return "scp";
+ }
+
+ @Override
+ public Expression getTempFileName() {
+ log.debug("Creation of temporary files not supported by the scp: protocol.");
+ return null;
+ }
+}
Added: camel/trunk/components/camel-jsch/src/main/java/org/apache/camel/component/jsch/ScpFile.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jsch/src/main/java/org/apache/camel/component/jsch/ScpFile.java?rev=1292947&view=auto
==============================================================================
--- camel/trunk/components/camel-jsch/src/main/java/org/apache/camel/component/jsch/ScpFile.java (added)
+++ camel/trunk/components/camel-jsch/src/main/java/org/apache/camel/component/jsch/ScpFile.java Thu Feb 23 20:48:47 2012
@@ -0,0 +1,71 @@
+/**
+ * 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.jsch;
+
+
+/**
+ * SFTP remote file operations
+ */
+public class ScpFile {
+ private boolean directory;
+ private int attrs;
+ private int length;
+ private String name;
+ private String parent;
+
+ public String header() {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append(directory ? "D" : "C");
+ buffer.append(" ");
+ return buffer.toString();
+ }
+
+ public boolean isDirectory() {
+ return directory;
+ }
+ public void setDirectory(boolean directory) {
+ this.directory = directory;
+ }
+ public int getAttrs() {
+ return attrs;
+ }
+ public void setAttrs(int attrs) {
+ this.attrs = attrs;
+ }
+ public int getLength() {
+ return length;
+ }
+ public void setLength(int length) {
+ this.length = length;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getParent() {
+ return parent;
+ }
+
+ public void setParent(String parent) {
+ this.parent = parent;
+ }
+}
Added: camel/trunk/components/camel-jsch/src/main/java/org/apache/camel/component/jsch/ScpOperations.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jsch/src/main/java/org/apache/camel/component/jsch/ScpOperations.java?rev=1292947&view=auto
==============================================================================
--- camel/trunk/components/camel-jsch/src/main/java/org/apache/camel/component/jsch/ScpOperations.java (added)
+++ camel/trunk/components/camel-jsch/src/main/java/org/apache/camel/component/jsch/ScpOperations.java Thu Feb 23 20:48:47 2012
@@ -0,0 +1,302 @@
+/**
+ * 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.jsch;
+
+import static org.apache.camel.util.ObjectHelper.isNotEmpty;
+import com.jcraft.jsch.ChannelExec;
+import com.jcraft.jsch.JSch;
+import com.jcraft.jsch.JSchException;
+import com.jcraft.jsch.Session;
+import com.jcraft.jsch.UIKeyboardInteractive;
+import com.jcraft.jsch.UserInfo;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Hashtable;
+import java.util.List;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.component.file.GenericFileEndpoint;
+import org.apache.camel.component.file.GenericFileOperationFailedException;
+import org.apache.camel.component.file.remote.RemoteFileConfiguration;
+import org.apache.camel.component.file.remote.RemoteFileOperations;
+import org.apache.camel.util.ObjectHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * SCP remote file operations
+ */
+public class ScpOperations implements RemoteFileOperations<ScpFile> {
+ private static final String DEFAULT_KNOWN_HOSTS = "META-INF/.ssh/known_hosts";
+ private static final transient Logger LOG = LoggerFactory.getLogger(ScpOperations.class);
+
+ private ScpEndpoint endpoint;
+ private Session session;
+ private ChannelExec channel;
+
+ @Override
+ public void setEndpoint(GenericFileEndpoint<ScpFile> endpoint) {
+ this.endpoint = (ScpEndpoint)endpoint;
+ }
+
+ @Override
+ public boolean deleteFile(String name) throws GenericFileOperationFailedException {
+ throw new GenericFileOperationFailedException("Operation 'delete' not supported by the scp: protocol");
+ }
+
+ @Override
+ public boolean existsFile(String name) throws GenericFileOperationFailedException {
+ // maybe... cannot determine using the scp: protocol
+ return false;
+ }
+
+ @Override
+ public boolean renameFile(String from, String to) throws GenericFileOperationFailedException {
+ throw new GenericFileOperationFailedException("Operation 'rename' not supported by the scp: protocol");
+ }
+
+ @Override
+ public boolean buildDirectory(String directory, boolean absolute) throws GenericFileOperationFailedException {
+ // done by the server
+ return true;
+ }
+
+ @Override
+ public boolean retrieveFile(String name, Exchange exchange) throws GenericFileOperationFailedException {
+ // TODO: implement
+ return false;
+ }
+
+ @Override
+ public boolean storeFile(String name, Exchange exchange) throws GenericFileOperationFailedException {
+ ObjectHelper.notNull(session, "session");
+ ScpConfiguration cfg = endpoint.getConfiguration();
+
+ int timeout = cfg.getConnectTimeout();
+ LOG.trace("Opening channel to {} with {} timeout...", cfg.remoteServerInformation(),
+ timeout > 0 ? (Integer.toString(timeout) + " ms") : "no");
+ String target = getRemoteTarget(cfg);
+ String file = getRemoteFile(name, cfg);
+ try {
+ channel = (ChannelExec) session.openChannel("exec");
+ // TODO: need config for scp *-p* (preserves modification times, access times, and modes from the original file)
+ // String command="scp " + (ptimestamp ? "-p " : "") + "-t " + configuration.getDirectory();
+ // TODO: refactor to use generic command
+ String command="scp -t " + target;
+ channel.setCommand(command);
+ channel.connect(timeout);
+ LOG.trace("Channel connected to {}", cfg.remoteServerInformation());
+
+ try {
+ writeFile(channel, file, "foo");
+ } catch (IOException e) {
+ throw new GenericFileOperationFailedException("Failed to write file " + file, e);
+ }
+ } catch (JSchException e) {
+ LOG.warn("Failed to secure copy file " + file, e);
+ return false;
+ } finally {
+ if (channel != null) {
+ LOG.trace("Disconnecting 'exec' scp channel");
+ channel.disconnect();
+ channel = null;
+ LOG.trace("Channel disconnected from {}", cfg.remoteServerInformation());
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public String getCurrentDirectory() throws GenericFileOperationFailedException {
+ return endpoint.getConfiguration().getDirectory();
+ }
+
+ @Override
+ public void changeCurrentDirectory(String path) throws GenericFileOperationFailedException {
+ throw new GenericFileOperationFailedException("Operation 'cd " + path + "' not supported by the scp: protocol");
+ }
+
+ @Override
+ public void changeToParentDirectory() throws GenericFileOperationFailedException {
+ throw new GenericFileOperationFailedException("Operation 'cd ..' not supported by the scp: protocol");
+ }
+
+ @Override
+ public List<ScpFile> listFiles() throws GenericFileOperationFailedException {
+ throw new GenericFileOperationFailedException("Operation 'ls' not supported by the scp: protocol");
+ }
+
+ @Override
+ public List<ScpFile> listFiles(String path) throws GenericFileOperationFailedException {
+ throw new GenericFileOperationFailedException("Operation 'ls " + path + "' not supported by the scp: protocol");
+ }
+
+ @Override
+ public boolean connect(RemoteFileConfiguration configuration) throws GenericFileOperationFailedException {
+ if (!isConnected()) {
+ session = createSession(configuration instanceof ScpConfiguration ? (ScpConfiguration)configuration : null);
+ // TODO: deal with reconnection attempts
+ if (!isConnected()) {
+ session = null;
+ throw new GenericFileOperationFailedException("Failed to connect to " + configuration.remoteServerInformation());
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public boolean isConnected() throws GenericFileOperationFailedException {
+ return session != null && session.isConnected();
+ }
+
+ @Override
+ public void disconnect() throws GenericFileOperationFailedException {
+ if (isConnected()) {
+ session.disconnect();
+ }
+ session = null;
+ }
+
+ @Override
+ public boolean sendNoop() throws GenericFileOperationFailedException {
+ // not supported by scp:
+ return true;
+ }
+
+ @Override
+ public boolean sendSiteCommand(String command) throws GenericFileOperationFailedException {
+ // TODO: not really used, maybe implement at a later time
+ return true;
+ }
+
+ private Session createSession(ScpConfiguration config) {
+ ObjectHelper.notNull(config, "ScpConfiguration");
+ try {
+ final JSch jsch = new JSch();
+ // get from configuration
+ if (isNotEmpty(config.getCiphers())) {
+ LOG.debug("Using ciphers: {}", config.getCiphers());
+ Hashtable<String, String> ciphers = new Hashtable<String, String>();
+ ciphers.put("cipher.s2c", config.getCiphers());
+ ciphers.put("cipher.c2s", config.getCiphers());
+ JSch.setConfig(ciphers);
+ }
+
+
+
+
+ String knownHostsFile = config.getKnownHostsFile();
+ jsch.setKnownHosts(ObjectHelper.isEmpty(knownHostsFile) ? DEFAULT_KNOWN_HOSTS : knownHostsFile);
+ session = jsch.getSession(config.getUsername(), config.getHost(), config.getPort());
+ session.setTimeout(config.getTimeout());
+ session.setUserInfo(new SessionUserInfo(config));
+
+ int timeout = config.getConnectTimeout();
+ LOG.debug("Connecting to {} with {} timeout...", config.remoteServerInformation(),
+ timeout > 0 ? (Integer.toString(timeout) + " ms") : "no");
+ if (timeout > 0) {
+ session.connect(timeout);
+ } else {
+ session.connect();
+ }
+ } catch (JSchException e) {
+ session = null;
+ LOG.warn("Could not create ssh session for " + config.remoteServerInformation(), e);
+ }
+ return session;
+ }
+
+ private void writeFile(ChannelExec c, String name, String data) throws IOException {
+ data = "Hello World";
+ OutputStream os = c.getOutputStream();
+ InputStream is = c.getInputStream();
+
+ os.write(("C7777 " + data.length() + " " + name + "\n").getBytes());
+ os.flush();
+ is.read();
+
+ os.write(data.getBytes());
+ os.flush();
+ is.read();
+
+ os.write(0);
+ os.flush();
+ os.close();
+ is.close();
+ }
+
+ private static String getRemoteTarget(ScpConfiguration config) {
+ // use current dir (".") if target directory not specified in uri
+ return config.getDirectory().isEmpty() ? "." : config.getDirectory();
+ }
+
+ private static String getRemoteFile(String name, ScpConfiguration config) {
+ // assume that the directory path of 'name' is the same as config.getDirectory()
+ int pos = name.lastIndexOf('/');
+ return pos >= 0 ? name.substring(pos + 1) : name;
+ }
+
+
+ protected static final class SessionUserInfo implements UserInfo, UIKeyboardInteractive {
+ private final ScpConfiguration config;
+ public SessionUserInfo(ScpConfiguration config) {
+ ObjectHelper.notNull(config, "config");
+ this.config = config;
+ }
+
+ @Override
+ public String getPassphrase() {
+ LOG.info("Private Key authentication not supported");
+ return null;
+ }
+ @Override
+ public String getPassword() {
+ LOG.debug("Providing password for ssh authentication of user '{}'", config.getUsername());
+ return config.getPassword();
+ }
+ @Override
+ public boolean promptPassword(String message) {
+ LOG.debug(message);
+ return true;
+ }
+ @Override
+ public boolean promptPassphrase(String message) {
+ LOG.debug(message);
+ return true;
+ }
+ @Override
+ public boolean promptYesNo(String message) {
+ LOG.debug(message);
+ return false;
+ }
+ @Override
+ public void showMessage(String message) {
+ LOG.debug(message);
+ }
+
+ @Override
+ public String[] promptKeyboardInteractive(String destination, String name,
+ String instruction, String[] prompt, boolean[] echo) {
+ LOG.debug(instruction);
+ // Called for either SSH_MSG_USERAUTH_INFO_REQUEST or SSH_MSG_USERAUTH_PASSWD_CHANGEREQ
+ // The most secure choice (especially for the second case) is to return null
+ return null;
+ }
+ }
+}
Added: camel/trunk/components/camel-jsch/src/main/java/org/apache/camel/component/jsch/ScpProcessStrategyFactory.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jsch/src/main/java/org/apache/camel/component/jsch/ScpProcessStrategyFactory.java?rev=1292947&view=auto
==============================================================================
--- camel/trunk/components/camel-jsch/src/main/java/org/apache/camel/component/jsch/ScpProcessStrategyFactory.java (added)
+++ camel/trunk/components/camel-jsch/src/main/java/org/apache/camel/component/jsch/ScpProcessStrategyFactory.java Thu Feb 23 20:48:47 2012
@@ -0,0 +1,85 @@
+/**
+ * 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.jsch;
+
+import java.util.Map;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.component.file.GenericFileExclusiveReadLockStrategy;
+import org.apache.camel.component.file.GenericFileProcessStrategy;
+import org.apache.camel.component.file.strategy.GenericFileNoOpProcessStrategy;
+
+public final class ScpProcessStrategyFactory {
+
+ private ScpProcessStrategyFactory() {
+ }
+
+ @SuppressWarnings("unchecked")
+ public static <LsEntry> GenericFileProcessStrategy<LsEntry> createGenericFileProcessStrategy(CamelContext context, Map<String, Object> params) {
+
+ /*
+ // We assume a value is present only if its value not null for String and 'true' for boolean
+ Expression moveExpression = (Expression) params.get("move");
+ Expression moveFailedExpression = (Expression) params.get("moveFailed");
+ Expression preMoveExpression = (Expression) params.get("preMove");
+ boolean isNoop = params.get("noop") != null;
+ boolean isDelete = params.get("delete") != null;
+ boolean isMove = moveExpression != null || preMoveExpression != null || moveFailedExpression != null;
+ */
+
+ // default strategy will do nothing
+ GenericFileNoOpProcessStrategy<LsEntry> strategy = new GenericFileNoOpProcessStrategy<LsEntry>();
+ strategy.setExclusiveReadLockStrategy((GenericFileExclusiveReadLockStrategy<LsEntry>) getExclusiveReadLockStrategy(params));
+ return strategy;
+ }
+
+ @SuppressWarnings({"unchecked"})
+ private static <LsEntry> GenericFileExclusiveReadLockStrategy<LsEntry> getExclusiveReadLockStrategy(Map<String, Object> params) {
+ GenericFileExclusiveReadLockStrategy<LsEntry> strategy = (GenericFileExclusiveReadLockStrategy<LsEntry>) params.get("exclusiveReadLockStrategy");
+ if (strategy != null) {
+ return strategy;
+ }
+/*
+ // no explicit strategy set then fallback to readLock option
+ String readLock = (String) params.get("readLock");
+ if (ObjectHelper.isNotEmpty(readLock)) {
+ if ("none".equals(readLock) || "false".equals(readLock)) {
+ return null;
+ } else if ("rename".equals(readLock)) {
+ GenericFileRenameExclusiveReadLockStrategy<LsEntry> readLockStrategy = new GenericFileRenameExclusiveReadLockStrategy<LsEntry>();
+ Long timeout = (Long) params.get("readLockTimeout");
+ if (timeout != null) {
+ readLockStrategy.setTimeout(timeout);
+ }
+ return readLockStrategy;
+ } else if ("changed".equals(readLock)) {
+ GenericFileExclusiveReadLockStrategy readLockStrategy = new SftpChangedExclusiveReadLockStrategy();
+ Long timeout = (Long) params.get("readLockTimeout");
+ if (timeout != null) {
+ readLockStrategy.setTimeout(timeout);
+ }
+ Long checkInterval = (Long) params.get("readLockCheckInterval");
+ if (checkInterval != null) {
+ readLockStrategy.setCheckInterval(checkInterval);
+ }
+ return readLockStrategy;
+ }
+ }
+*/
+ return null;
+ }
+}
Added: camel/trunk/components/camel-jsch/src/main/java/org/apache/camel/component/jsch/ScpProducer.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jsch/src/main/java/org/apache/camel/component/jsch/ScpProducer.java?rev=1292947&view=auto
==============================================================================
--- camel/trunk/components/camel-jsch/src/main/java/org/apache/camel/component/jsch/ScpProducer.java (added)
+++ camel/trunk/components/camel-jsch/src/main/java/org/apache/camel/component/jsch/ScpProducer.java Thu Feb 23 20:48:47 2012
@@ -0,0 +1,28 @@
+/**
+ * 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.jsch;
+
+import org.apache.camel.component.file.remote.RemoteFileEndpoint;
+import org.apache.camel.component.file.remote.RemoteFileOperations;
+import org.apache.camel.component.file.remote.RemoteFileProducer;
+
+public class ScpProducer extends RemoteFileProducer<ScpFile> {
+
+ protected ScpProducer(RemoteFileEndpoint<ScpFile> endpoint, RemoteFileOperations<ScpFile> operations) {
+ super(endpoint, operations);
+ }
+}
Added: camel/trunk/components/camel-jsch/src/main/resources/META-INF/services/org/apache/camel/component/scp
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jsch/src/main/resources/META-INF/services/org/apache/camel/component/scp?rev=1292947&view=auto
==============================================================================
--- camel/trunk/components/camel-jsch/src/main/resources/META-INF/services/org/apache/camel/component/scp (added)
+++ camel/trunk/components/camel-jsch/src/main/resources/META-INF/services/org/apache/camel/component/scp Thu Feb 23 20:48:47 2012
@@ -0,0 +1,19 @@
+#
+# 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.
+#
+
+class=org.apache.camel.component.jsch.JschComponent
+strategy.factory.class=org.apache.camel.component.jsch.ScpProcessStrategyFactory
Added: camel/trunk/components/camel-jsch/src/main/resources/log4j.properties
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jsch/src/main/resources/log4j.properties?rev=1292947&view=auto
==============================================================================
--- camel/trunk/components/camel-jsch/src/main/resources/log4j.properties (added)
+++ camel/trunk/components/camel-jsch/src/main/resources/log4j.properties Thu Feb 23 20:48:47 2012
@@ -0,0 +1,16 @@
+
+#
+# The logging properties used
+#
+log4j.rootLogger=INFO, out
+
+# uncomment the following line to turn on Camel debugging
+#log4j.logger.org.apache.camel=DEBUG
+
+# CONSOLE appender not used by default
+log4j.appender.out=org.apache.log4j.ConsoleAppender
+log4j.appender.out.layout=org.apache.log4j.PatternLayout
+log4j.appender.out.layout.ConversionPattern=[%30.30t] %-30.30c{1} %-5p %m%n
+#log4j.appender.out.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n
+
+log4j.throwableRenderer=org.apache.log4j.EnhancedThrowableRenderer
\ No newline at end of file
Added: camel/trunk/components/camel-jsch/src/test/java/org/apache/camel/component/jsch/ScpServerTestSupport.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jsch/src/test/java/org/apache/camel/component/jsch/ScpServerTestSupport.java?rev=1292947&view=auto
==============================================================================
--- camel/trunk/components/camel-jsch/src/test/java/org/apache/camel/component/jsch/ScpServerTestSupport.java (added)
+++ camel/trunk/components/camel-jsch/src/test/java/org/apache/camel/component/jsch/ScpServerTestSupport.java Thu Feb 23 20:48:47 2012
@@ -0,0 +1,206 @@
+/**
+ * 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.jsch;
+
+import com.jcraft.jsch.JSch;
+import com.jcraft.jsch.JSchException;
+import com.jcraft.jsch.Session;
+import com.jcraft.jsch.UserInfo;
+
+import java.io.File;
+import java.io.IOException;
+import java.security.Provider;
+import java.security.Provider.Service;
+import java.security.Security;
+
+import org.apache.camel.test.AvailablePortFinder;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.apache.camel.util.FileUtil;
+import org.apache.sshd.SshServer;
+import org.apache.sshd.common.keyprovider.FileKeyPairProvider;
+import org.apache.sshd.server.PasswordAuthenticator;
+import org.apache.sshd.server.command.ScpCommandFactory;
+import org.apache.sshd.server.session.ServerSession;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @version
+ */
+public abstract class ScpServerTestSupport extends CamelTestSupport {
+ protected static final Logger LOG = LoggerFactory.getLogger(ScpServerTestSupport.class);
+ protected static final String SCP_ROOT_DIR = "target/scp";
+ protected static final String KNOWN_HOSTS = "known_hosts";
+ protected static int port;
+
+ private boolean acceptLocalhostConnections = true;
+ private String knownHostsFile;
+
+ private boolean setupComplete;
+ private SshServer sshd;
+
+ protected ScpServerTestSupport() {
+ this(true);
+ }
+
+ protected ScpServerTestSupport(boolean acceptLocalhostConnections) {
+ this.acceptLocalhostConnections = acceptLocalhostConnections;
+ }
+
+ protected int getPort() {
+ return port;
+ }
+
+ protected SshServer getSshd() {
+ return sshd;
+ }
+
+ @BeforeClass
+ public static void initPort() throws Exception {
+ port = AvailablePortFinder.getNextAvailable(21000);
+ }
+
+ @Override
+ @Before
+ public void setUp() throws Exception {
+ File root = new File(SCP_ROOT_DIR);
+ root.mkdirs();
+
+ setupComplete = startSshd();
+ setupKnownHosts();
+ super.setUp();
+ }
+
+ @Override
+ @After
+ public void tearDown() throws Exception {
+ super.tearDown();
+
+ if (sshd != null) {
+ try {
+ sshd.stop();
+ sshd = null;
+ } catch (Exception e) {
+ // ignore while shutting down as we could be polling during shutdown
+ // and get errors when the ssh server is stopping.
+ }
+ }
+ FileUtil.deleteFile(new File(knownHostsFile));
+ }
+
+ protected boolean startSshd() {
+ sshd = SshServer.setUpDefaultServer();
+ sshd.setPort(getPort());
+ sshd.setKeyPairProvider(new FileKeyPairProvider(new String[]{"src/test/resources/hostkey.pem"}));
+ sshd.setCommandFactory(new ScpCommandFactory());
+ sshd.setPasswordAuthenticator(new PasswordAuthenticator() {
+ @Override
+ public boolean authenticate(String username, String password, ServerSession session) {
+ // dummy authentication: allow any user whose password is the same as the username
+ return username != null && username.equals(password);
+ }
+ });
+
+ try {
+ sshd.start();
+ return true;
+ } catch (IOException e) {
+ LOG.info("Failed to start ssh server.", e);
+ }
+ return false;
+ }
+
+ protected void setupKnownHosts() {
+ knownHostsFile = SCP_ROOT_DIR + "/" + KNOWN_HOSTS + "-" + getPort();
+ FileUtil.deleteFile(new File(knownHostsFile));
+ if (!acceptLocalhostConnections) {
+ return;
+ }
+
+ // For security reasons (avoiding man in the middle attacks),
+ // camel-jsch will only connect to known hosts. For unit testing
+ // we use a known key, but since the port it dynamic, the
+ // known_hosts file will be generated by the following code and
+ // should should contain a line like below (if
+ // "HashKnownHosts"=="yes" the hostname:port part will look
+ // a bit more complicated).
+ //
+ // [localhost]:21000 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDd \
+ // fIWeSV4o68dRrKSzFd/Bk51E65UTmmSrmW0O1ohtzi6HzsDPjXgCtlTt3F \
+ // qTcfFfI92IlTr4JWqC9UK1QT1ZTeng0MkPQmv68hDANHbt5CpETZHjW5q4 \
+ // OOgWhVvj5IyOC2NZHtKlJBkdsMAa15ouOOJLzBvAvbqOR/yUROsEiQ==
+
+ JSch jsch = new JSch();
+ try {
+ LOG.debug("Using '{}' for known hosts.", knownHostsFile);
+ jsch.setKnownHosts(knownHostsFile);
+ Session s = jsch.getSession("admin", "localhost", getPort());
+ s.setConfig("StrictHostKeyChecking", "ask");
+ s.setConfig("HashKnownHosts", "yes");
+ s.setUserInfo(new UserInfo() {
+ @Override
+ public String getPassphrase() {
+ return null;
+ }
+ @Override
+ public String getPassword() {
+ return "admin";
+ }
+ @Override
+ public boolean promptPassword(String message) {
+ return true;
+ }
+ @Override
+ public boolean promptPassphrase(String message) {
+ return false;
+ }
+ @Override
+ public boolean promptYesNo(String message) {
+ // accept host authenticity
+ return true;
+ }
+ @Override
+ public void showMessage(String message) {
+ }
+ });
+ // in the process of connecting, "[localhost]:<port>" is added to the knownHostsFile
+ s.connect();
+ s.disconnect();
+ } catch (JSchException e) {
+ LOG.info("Could not add [localhost] to known hosts", e);
+ }
+ }
+
+ public String getKnownHostsFile() {
+ return knownHostsFile;
+ }
+
+ public boolean isSetupComplete() {
+ return setupComplete;
+ }
+
+ protected static void traceSecurityProviders() {
+ for (Provider p : Security.getProviders()) {
+ for (Service s : p.getServices()) {
+ LOG.trace("Security provider {} for '{}' algorithm", s.getClassName(), s.getAlgorithm());
+ }
+ }
+ }
+}
Added: camel/trunk/components/camel-jsch/src/test/java/org/apache/camel/component/jsch/ScpSimpleProduceTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jsch/src/test/java/org/apache/camel/component/jsch/ScpSimpleProduceTest.java?rev=1292947&view=auto
==============================================================================
--- camel/trunk/components/camel-jsch/src/test/java/org/apache/camel/component/jsch/ScpSimpleProduceTest.java (added)
+++ camel/trunk/components/camel-jsch/src/test/java/org/apache/camel/component/jsch/ScpSimpleProduceTest.java Thu Feb 23 20:48:47 2012
@@ -0,0 +1,73 @@
+/**
+ * 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.jsch;
+
+import java.io.File;
+
+import org.apache.camel.Exchange;
+import org.junit.Assume;
+import org.junit.Ignore;
+import org.junit.Test;
+
+/**
+ * @version
+ */
+public class ScpSimpleProduceTest extends ScpServerTestSupport {
+
+ @Override
+ public boolean isUseRouteBuilder() {
+ return false;
+ }
+
+ @Test
+ public void testScpSimpleProduce() throws Exception {
+ Assume.assumeTrue(this.isSetupComplete());
+
+ String uri = "scp://localhost:" + getPort() + "/target/scp?username=admin&password=admin&knownHostsFile=" + getKnownHostsFile();
+ template.sendBodyAndHeader(uri, "Hello World", Exchange.FILE_NAME, "hello.txt");
+
+ File file = new File(SCP_ROOT_DIR + "/hello.txt").getAbsoluteFile();
+ assertTrue("File should exist: " + file, file.exists());
+ assertEquals("Hello World", context.getTypeConverter().convertTo(String.class, file));
+ }
+
+ @Test
+ @Ignore("Scenario not supported by scp but could be emulated with recursive copy")
+ public void testScpSimpleSubPathProduce() throws Exception {
+ Assume.assumeTrue(this.isSetupComplete());
+
+ String uri = "scp://localhost:" + getPort() + "/target/scp?username=admin&password=admin&knownHostsFile=" + getKnownHostsFile();
+ template.sendBodyAndHeader(uri, "Bye World", Exchange.FILE_NAME, "bye.txt");
+
+ File file = new File(SCP_ROOT_DIR + "/mysub/bye.txt").getAbsoluteFile();
+ assertTrue("File should exist: " + file, file.exists());
+ assertEquals("Bye World", context.getTypeConverter().convertTo(String.class, file));
+ }
+
+ @Test
+ @Ignore("Scenario not supported by scp but could be emulated with recursive copy")
+ public void testScpSimpleTwoSubPathProduce() throws Exception {
+ Assume.assumeTrue(this.isSetupComplete());
+
+ String uri = "scp://localhost:" + getPort() + "/target/scp?username=admin&password=admin&knownHostsFile=" + getKnownHostsFile();
+ template.sendBodyAndHeader(uri, "Farewell World", Exchange.FILE_NAME, "farewell.txt");
+
+ File file = new File(SCP_ROOT_DIR + "/mysub/myother/farewell.txt").getAbsoluteFile();
+ assertTrue("File should exist: " + file, file.exists());
+ assertEquals("Farewell World", context.getTypeConverter().convertTo(String.class, file));
+ }
+}
Added: camel/trunk/components/camel-jsch/src/test/resources/client.jks
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jsch/src/test/resources/client.jks?rev=1292947&view=auto
==============================================================================
Files camel/trunk/components/camel-jsch/src/test/resources/client.jks (added) and camel/trunk/components/camel-jsch/src/test/resources/client.jks Thu Feb 23 20:48:47 2012 differ
Added: camel/trunk/components/camel-jsch/src/test/resources/hostkey.pem
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jsch/src/test/resources/hostkey.pem?rev=1292947&view=auto
==============================================================================
--- camel/trunk/components/camel-jsch/src/test/resources/hostkey.pem (added)
+++ camel/trunk/components/camel-jsch/src/test/resources/hostkey.pem Thu Feb 23 20:48:47 2012
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQDdfIWeSV4o68dRrKSzFd/Bk51E65UTmmSrmW0O1ohtzi6HzsDP
+jXgCtlTt3FqTcfFfI92IlTr4JWqC9UK1QT1ZTeng0MkPQmv68hDANHbt5CpETZHj
+W5q4OOgWhVvj5IyOC2NZHtKlJBkdsMAa15ouOOJLzBvAvbqOR/yUROsEiQIDAQAB
+AoGBANG3JDW6NoP8rF/zXoeLgLCj+tfVUPSczhGFVrQkAk4mWfyRkhN0WlwHFOec
+K89MpkV1ij/XPVzU4MNbQ2yod1KiDylzvweYv+EaEhASCmYNs6LS03punml42SL9
+97tOmWfVJXxlQoLiY6jHPU97vTc65k8gL+gmmrpchsW0aqmZAkEA/c8zfmKvY37T
+cxcLLwzwsqqH7g2KZGTf9aRmx2ebdW+QKviJJhbdluDgl1TNNFj5vCLznFDRHiqJ
+wq0wkZ39cwJBAN9l5v3kdXj21UrurNPdlV0n2GZBt2vblooQC37XHF97r2zM7Ou+
+Lg6MyfJClyguhWL9dxnGbf3btQ0l3KDstxMCQCRaiEqjAfIjWVATzeNIXDWLHXso
+b1kf5cA+cwY+vdKdTy4IeUR+Y/DXdvPWDqpf0C11aCVMohdLCn5a5ikFUycCQDhV
+K/BuAallJNfmY7JxN87r00fF3ojWMJnT/fIYMFFrkQrwifXQWTDWE76BSDibsosJ
+u1TGksnm8zrDh2UVC/0CQFrHTiSl/3DHvWAbOJawGKg46cnlDcAhSyV8Frs8/dlP
+7YGG3eqkw++lsghqmFO6mRUTKsBmiiB2wgLGhL5pyYY=
+-----END RSA PRIVATE KEY-----
\ No newline at end of file
Added: camel/trunk/components/camel-jsch/src/test/resources/log4j.properties
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jsch/src/test/resources/log4j.properties?rev=1292947&view=auto
==============================================================================
--- camel/trunk/components/camel-jsch/src/test/resources/log4j.properties (added)
+++ camel/trunk/components/camel-jsch/src/test/resources/log4j.properties Thu Feb 23 20:48:47 2012
@@ -0,0 +1,38 @@
+## ------------------------------------------------------------------------
+## 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.
+## ------------------------------------------------------------------------
+
+#
+# The logging properties used for eclipse testing, We want to see debug output on the console.
+#
+log4j.rootLogger=INFO, file
+
+# uncomment the following to enable camel debugging
+# log4j.logger.org.apache.camel=DEBUG
+# log4j.logger.org.apache.camel.component.jsch=TRACE
+# log4j.logger.org.apache.sshd=DEBUG
+
+# CONSOLE appender not used by default
+log4j.appender.out=org.apache.log4j.ConsoleAppender
+log4j.appender.out.layout=org.apache.log4j.PatternLayout
+#log4j.appender.out.layout.ConversionPattern=[%30.30t] %-30.30c{1} %-5p %m%n
+log4j.appender.out.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n
+
+# File appender
+log4j.appender.file=org.apache.log4j.FileAppender
+log4j.appender.file.layout=org.apache.log4j.PatternLayout
+log4j.appender.file.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n
+log4j.appender.file.file=target/camel-jsch-test.log
\ No newline at end of file
Added: camel/trunk/components/camel-jsch/src/test/resources/server.jks
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jsch/src/test/resources/server.jks?rev=1292947&view=auto
==============================================================================
Files camel/trunk/components/camel-jsch/src/test/resources/server.jks (added) and camel/trunk/components/camel-jsch/src/test/resources/server.jks Thu Feb 23 20:48:47 2012 differ
Modified: camel/trunk/components/pom.xml
URL: http://svn.apache.org/viewvc/camel/trunk/components/pom.xml?rev=1292947&r1=1292946&r2=1292947&view=diff
==============================================================================
--- camel/trunk/components/pom.xml (original)
+++ camel/trunk/components/pom.xml Thu Feb 23 20:48:47 2012
@@ -99,6 +99,7 @@
<module>camel-jmx</module>
<module>camel-josql</module>
<module>camel-jpa</module>
+ <module>camel-jsch</module>
<module>camel-jt400</module>
<module>camel-juel</module>
<module>camel-jxpath</module>