'Sftp fileupload not working with Apache MINA SSHD and JIMFS in Docker Container
I'm dealing with a tough one:
For testing purposes I use Apache Mina SSHD and JIMFS to mock a remote sftp server - only locally and in test environment. Never in production.
In my Spring Boot application I start a Apache Mina sshd during application startup. I create a virtual filesystem with jimfs (tried unix and osX) for the FileSystemFactory.
My business code calls a remote sftp server in production and in test environment it calls the mina sshd server on localhost instead.
It does nothing else than uploading a file to the sftp server.
This works very well on my machine locally but i get a "file or directory not found" error message when I run this in our test environment (a docker container).
com.jcraft.jsch.SftpException: No such file or directory
at com.jcraft.jsch.ChannelSftp.throwStatusError(ChannelSftp.java:2873)
at com.jcraft.jsch.ChannelSftp._put(ChannelSftp.java:594)
at com.jcraft.jsch.ChannelSftp.put(ChannelSftp.java:475)
at com.jcraft.jsch.ChannelSftp.put(ChannelSftp.java:365)
at our.service.core.client.sftp.SftpClient.upload(SftpClient.java:89)
Creation of JIMFS file system during Application startup:
public class MockSftpServerInitializer implements ApplicationListener<ApplicationReadyEvent> {
@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
SshServer sshd = SshServer.setUpDefaultServer();
sshd.setHost("localhost");
sshd.setPort(1234);
sshd.setCommandFactory(new ScpCommandFactory());
sshd.setKeyPairProvider(new SimpleGeneratorHostKeyProvider(new File("host-key.ser")));
sshd.setPublickeyAuthenticator(getPublickeyAuthenticator());
sshd.setFileSystemFactory(getInMemoryFileSystemFactory());
List<NamedFactory<Command>> sftpCommandFactory = new ArrayList<>();
sftpCommandFactory.add(new SftpSubsystemFactory());
sshd.setSubsystemFactories(sftpCommandFactory);
try {
sshd.start();
} catch (Exception e) {
throw new RuntimeException("Unable to start sshd", e);
}
}
private FileSystemFactory getInMemoryFileSystemFactory() {
return session -> getInMemoryFileSystem();
}
private FileSystem getInMemoryFileSystem() {
return Jimfs.newFileSystem(
Configuration.osX()
.toBuilder()
.setWorkingDirectory("/")
.setMaxSize(1024*1024*4)
.setDefaultAttributeValue("posix:permissions", "rwxrw-rw-")
.setAttributeViews("basic", "owner", "posix", "unix", "acl", "user")
.build());
}
}
File upload:
public class SftpClient {
public boolean upload(String source, String destination) {
Session session = null;
ChannelSftp sftpChannel = null;
try {
sftpProvider.addIdentity("Identity", privateKey.getBytes(), publicKey.getBytes(), null);
session = sftpProvider.getSession(username, host, port);
session.setConfig("StrictHostKeyChecking", "no");
session.connect();
Channel channel = session.openChannel("sftp");
channel.connect();
sftpChannel = (ChannelSftp) channel;
sftpChannel.put(source, destination);
log.info("Successful upload of file {} to SFTP server {}.", source, host);
return true;
} catch (SftpException | JSchException ex) {
log.error("Failed upload of file {} to SFTP server {}.", source, host);
log.error("{}", ex);
return false;
} finally {
if (sftpChannel != null) {
sftpChannel.disconnect();
}
if (session != null) {
session.disconnect();
}
}
}
}
I'm grateful for any hint on why this works locally but not in our docker container.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
