How to reput on JSch SFTP? - java

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);
}
}

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 transfer a file through SFTP in java? [duplicate]

This question already has answers here:
How to retrieve a file from a server via SFTP?
(16 answers)
Closed 6 years ago.
How to transfer a file through SFTP in java? I want sample code for SFTP client.
I want to embed the SFTP server in my application and the client should able to send a file to my application.
PS: This was asked for SFTP client. And This question is not a duplicate of other two questions.
Find the below link to implement SFTP.
https://codetransient.wordpress.com/2019/06/22/sftp-secured-file-transfer-protocol/
Try this code.
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.");
}
}

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