Skip to content

Instantly share code, notes, and snippets.

@ran488
Created April 15, 2014 13:19
Show Gist options
  • Save ran488/10731967 to your computer and use it in GitHub Desktop.
Save ran488/10731967 to your computer and use it in GitHub Desktop.
Class to use in place of Spring's DefaultSftpSessionFactory class for when your key file is inside your WAR file. The Spring implementation will eventually try to get the full file path to send into Jsch constructor, but since the file is in the WAR instead of on filesystem, that will fail. This overrides the setPrivateKey() method to take the c…
package com.XXXXXXXX.filetransfer;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.integration.sftp.session.DefaultSftpSessionFactory;
/**
*
* Override the Spring DefaultSftpSessionFactory so I can pull a resource from
* the classpath for the private key file. The Spring implementation does a
* getFile() from the Resource that is passed in and tries to get absolute path
* and then passes that in to Jsch constructor. That fails with a file not found
* exception when the key file is inside the WAR or JAR.
*
* @author ranichol
*
*/
public class SftpSessionFactory extends DefaultSftpSessionFactory {
/**
* Note there are other constructors for the parent class, but this is the
* only one we need for wiring up in Spring right now. At a later date, we
* can address the others if needed (shared session flags, etc.).
*/
public SftpSessionFactory() {
super();
}
/**
* Override the setPrivateKey() method of the super class to act as an
* "adapter". Take the classpath Resource from the WAR file and write a
* temporary file on the filesystem to get a full filesystem absolute path
* that Jsch will like.
*
* @see org.springframework.integration.sftp.session.DefaultSftpSessionFactory#setPrivateKey(org.springframework.core.io.Resource)
*/
@Override
public void setPrivateKey(Resource privateKey) {
_log.info(String.format("privateKey Resource is really a.....%s",
privateKey.getClass().getName()));
Resource tempPrivateKey = privateKey;
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
try {
File tempFile = File.createTempFile("tempkey_", ".key");
_log.debug(String.format("Temporary key file: %s",
tempFile.getAbsoluteFile()));
bis = new BufferedInputStream(privateKey.getInputStream());
bos = new BufferedOutputStream(new FileOutputStream(tempFile));
int b;
while ((b = bis.read()) != -1) {
bos.write(b);
}
_log.debug("Re-assigning the privateKey Resource to the temp file URI instead of classpath URI");
tempPrivateKey = new FileSystemResource(tempFile);
tempFile.deleteOnExit();
} catch (IOException e) {
_log.error("Could not create temp SSH key file on filesystem.", e);
e.printStackTrace();
} finally {
if (bis!=null) close(bis);
if (bos!=null) close(bos);
}
super.setPrivateKey(tempPrivateKey);
}
/**
*
* @param bis
*/
private void close(BufferedInputStream bis) {
try {
bis.close();
} catch (Throwable t) {
_log.warn("Could not close input stream");
}
}
/**
*
* @param bos
*/
private void close(BufferedOutputStream bos) {
try {
bos.close();
} catch (Throwable t) {
_log.warn("Could not close output stream");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment