Problems in session.connect() in a method that does SFTP upload - java

I have a class that uploads a file by SFTP. It uses private key-public keyy pair SSH for authentication. Below is method that uploads the file. I am writing a test method for it. When I call this method from the test class, it fails at session.connect and no line of code gets executed after that.
Method that uploads the file by SFTP:
try (FileInputStream fileInputStream = new FileInputStream(new File(fileName));){
JSch jsch = new JSch();
Session session = jsch.getSession(sftpUser, sftpHost, sftpPort);
if(sshKey.isEmpty()) {
session.setPassword(sftpPass);
} else {
jsch.addIdentity(sftpHost, sshKey.getBytes(StandardCharsets.US_ASCII), null, null);
}
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
config.put("PreferredAuthentications", "publickey,keyboard-interactive,password");
session.setConfig(config);
session.connect();
log.info("Host connected.");
Channel channel = session.openChannel("sftp");
channel.connect();
log.info("sftp channel opened and connected.");
ChannelSftp channelSftp = (ChannelSftp) channel;
channelSftp.cd(sftpWorkingFolder);
channelSftp.put(fileInputStream, new File(fileName).getName());
channel.disconnect();
session.disconnect();
} catch (JSchException | SftpException | IOException e) {
e.printStackTrace();
}
Below is the Test Method:
#Mock
private JSch jSch;
#Mock
FileInputStream fileInputStream;
#Mock
File file;
#Mock
private Session session;
#Mock
private Channel channel;
#Mock
private ChannelSftp channelSftp;
#Mock
private Properties properties;
#Test
public void testSend() throws Exception {
PowerMockito.whenNew(JSch.class).withNoArguments().thenReturn(jSch);
PowerMockito.whenNew(Properties.class).withNoArguments().thenReturn(properties);
PowerMockito.whenNew(FileInputStream.class).withAnyArguments().thenReturn(fileInputStream);
when(jSch.getSession(any(String.class), any(String.class), anyInt())).thenReturn(session);
doNothing().when(session).connect();
when(session.openChannel("sftp")).thenReturn(channel);
doNothing().when(channel).connect();
doNothing().when(channelSftp).cd(any(String.class));
FileUtil.send("src/test/resources/testFile.txt","abc",22,"admin","pass","fold", StringUtils.EMPTY);
}
This is the exception I get:
com.jcraft.jsch.JSchException: java.net.ConnectException: Connection timed out: connect

Related

How to mock connection for SFTP Connection

My program opens sftp connection and connects to the server to get a file which is then processed.
I am writing a test case for this method, trying to mock the connection.
My actual class is:
public void getFile() {
Session session = null;
Channel channel = null;
ChannelSftp channelSftp = null;
String path = ftpurl;
try {
JSch jsch = new JSch();
session = jsch.getSession(username, host, port);
session.setConfig("StrictHostKeyChecking", "no");session.setPassword(JaspytPasswordEncryptor.getDecryptedString(jaspytEncryptionKey, jaspytEncryptionAlgorithm, password));
session.connect();
channel = session.openChannel("sftp");
channel.connect();
channelSftp = (ChannelSftp) channel;
channelSftp.cd(path);
Vector<ChannelSftp.LsEntry> list = channelSftp.ls("*.csv");
for (ChannelSftp.LsEntry entry : list) {
if (entry.getFilename().startsWith("A...")) {
findByFileName(entry.getFilename());
}
}
channelSftp.exit();
session.disconnect();
} catch (JSchException e) {
LOGGER.error("JSch exception"+e);
} catch (SftpException e) {
LOGGER.error("Sftp Exception"+e);
}
}
Test class so far:
#Test
public void getNamesTestValid() throws IOException, JSchException {
JSch jsch = new JSch();
Hashtable config = new Hashtable();
config.put("StrictHostKeyChecking", "no");
JSch.setConfig(config);
Session session = jsch.getSession( "remote-username", "localhost", 22999);
session.setPassword("remote-password");
session.connect();
Channel channel = session.openChannel( "sftp" );
channel.connect();
ChannelSftp sftpChannel = (ChannelSftp) channel;
Mockito.when(fileRepository.findByFileName(fileName)).thenReturn(fileDetail);
scheduler.getCSVFileNames();
}
When trying to mock the connection, it searches for the actual port and the error is port invalid, connection refused.
I only want to mock the connection.
My other doubt is after mocking the connection from where should i read the file details.
That's because you're creating an actual connection with new Jsch(). You need to mock the connection with a library such as Mockito. For example:
#RunWith(MockitoJUnitRunner.class)
class Test {
#Mock(answer = Answers.RETURNS_DEEP_STUBS)
private JSch mockJsch;
..
void test() {
Session mockSession = mockJsch.getSession("username", "localhost", 22999);
..
}
}

Transfer a file through SFTP with a different user using JSch in java

I am currently doing a SFTP file transfer using JSch as follows,
public void send (String fileName) {
String SFTPHOST = "host:IP";
int SFTPPORT = 22;
String SFTPUSER = "username";
String SFTPPASS = "password";
String SFTPWORKINGDIR = "file/to/transfer";
Session session = null;
Channel channel = null;
ChannelSftp channelSftp = null;
System.out.println("preparing the host information for sftp.");
try {
JSch jsch = new JSch();
session = jsch.getSession(SFTPUSER, SFTPHOST, SFTPPORT);
session.setPassword(SFTPPASS);
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
System.out.println("Host connected.");
channel = session.openChannel("sftp");
channel.connect();
System.out.println("sftp channel opened and connected.");
channelSftp = (ChannelSftp) channel;
channelSftp.cd(SFTPWORKINGDIR);
File f = new File(fileName);
channelSftp.put(new FileInputStream(f), f.getName());
log.info("File transfered successfully to host.");
} catch (Exception ex) {
System.out.println("Exception found while tranfer the response.");
}
finally{
channelSftp.exit();
System.out.println("sftp Channel exited.");
channel.disconnect();
System.out.println("Channel disconnected.");
session.disconnect();
System.out.println("Host Session disconnected.");
}
}
I need to do this transfer as a different user i.e I need to trigger pbrun first and then perform the transfer using the new user. I could not find such an option in JSch or ChannelSftp. Is it possible to do the same using the mentioned APIs.

JSCH: closing channel and session

I'm doing some SFTP operation with JSCH:
JSch jsch = new JSch();
Session session = null;
ChannelSftp sftpChannel = null;
try {
session = jsch.getSession(user, host, Integer.valueOf(port));
session.setConfig(JSCH_OPTIONS);
session.setPassword(password);
session.connect();
Channel channel = session.openChannel(SFTP_CHANNEL_ID);
channel.connect();
sftpChannel = (ChannelSftp) channel;
// some sftp operations
} catch (Exception e) {
log.error("Error while SFTP session", e);
} finally {
sftpChannel.exit();
session.disconnect();
}
My question is: when I'm done is it enough to call disconnect() on the session object, or the exit() on channel is a must before?
Thanks!
Update: I checked the behavior and there are no errors, but I'm not quite sure the sockets/etc are cleaned up correctly.

How to reput on JSch SFTP?

I'm using JSch to upload files to a SFTP. It works but sometimes the TCP connection is shut down while a file is being uploaded resulting on a truncated file on the server.
I found out that the reput command on SFTP servers resumes the upload. How can I send a reput command with JSch? Is it even possible?
Here's my code:
public void upload(File file) throws Exception
{
JSch jsch = new JSch();
Session session = jsch.getSession(USER, HOST, PORT);
session.setPassword(PASSWORD);
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
Channel channel=session.openChannel("sftp");
channel.connect();
ChannelSftp sftpChannel = (ChannelSftp)channel;
sftpChannel.put(file.getAbsolutePath(), file.getName());
channel.disconnect();
session.disconnect();
}
I found a way. Use the "put" method with the RESUME parameter:
sftpChannel.put(file.getAbsolutePath(), file.getName(), ChannelSftp.RESUME);
My code became:
public static void upload(File file, boolean retry) {
try
{
System.out.println("Uplodaing file " + file.getName());
JSch jsch = new JSch();
Session session = jsch.getSession(USER, HOST, PORT);
session.setPassword(PASSWORD);
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
Channel channel = session.openChannel("sftp");
channel.connect();
ChannelSftp sftpChannel = (ChannelSftp) channel;
if (!retry)
sftpChannel.put(file.getAbsolutePath(), file.getName(), ChannelSftp.OVERWRITE);
else
sftpChannel.put(file.getAbsolutePath(), file.getName(), ChannelSftp.RESUME);
channel.disconnect();
session.disconnect();
}
catch (Exception e)
{
e.printStackTrace();
upload(file, true);
}
}

Not able to connect to Secured Channel when doing SFTP with JSch

I am trying to implement JSch to retrieve a file from remote windows sftp server to Linux.
Session session = null;
Channel channel = null;
ChannelSftp channelSftp = null;
try{
JSch jsch = new JSch();
session = jsch.getSession("userName","hostName",22);
session.setPassword("password");
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
System.out.println(session.sendKeepAliveMsg());
channel = session.openChannel("sftp");
channel.connect();
}catch(Exception e){
e.printstacktrace();
}
I am getting following exception while running this code.
com.jcraft.jsch.JSchException: java.io.IOException: inputstream is closed
at com.jcraft.jsch.ChannelSftp.start(ChannelSftp.java:288)
at com.jcraft.jsch.Channel.connect(Channel.java:152)
When I debug I found:
start();
method in Channel class is throwing the exception. Is there anyway I can prevent this? I don't understand why the method is there without doing nothing.
Try to cast your channel into ChannelSft before the connect:
Channel channel = session.openChannel("sftp");
ChannelSftp channelSftp = (ChannelSftp) channel;
channelSftp.connect();

Categories

Resources