I want to test if a given file exists at a remote SFTP server using Apache Camel. The method has to return true if exists, false if not and an Exception in case the client cannot get connected (timeout, wrong username/password, etc).
In fact to test if I can get logged in to the server is not a major problem
to test if the given file exists. Just send a request to the SFTP server, download=false
and noop=true
and this is pretty much what it has to be done. An empty file will be downloaded to my TMP directory
in case the file exists, no file will be downloaded. In case I cannot logged in to the server an own Exception is thrown
(CannotConnectException
).
My point is that I cannot catch this exception at my client.
I am pretty sure I am doing something wrong, but I do not know what.
I was thinking as a work around to set some error value in returned file is case I cannot get connected, but
this looks like a "hack" to me. Is there any way to catch the thrown exception? If not, what is the best way to
get an Exception my client in case I cannot get connected?
My code is as follows:
public final class MyFtpClient {
private static final Logger LOG = LoggerFactory.getLogger(MyFtpClient.class);
// Client settings
static String localPath = File.separator + "tmp";
public enum Existence{
EXIST, NOT_EXIST, UNKNOWN
}
private MyFtpClient() {
}
private static Existence doesFileExistAtServer(Main main, String protocol, String user, String password,
String server, int port, String filePathAtServer, String filenameAtServer, String localPath)
{
boolean fileExist = false;
try {
main.addRouteBuilder(new MyFtpClientRouteBuilder(protocol, user, password, server, port, filePathAtServer,
filenameAtServer, localPath));
main.start();
Thread.sleep(5000);
main.stop();
String filePath = localPath + File.separator + filenameAtServer;
File f = new File(filePath);
fileExist = f.exists();
if (fileExist) {
f.delete(); // Just delete it.
return Existence.EXIST;
} else {
return Existence.NOT_EXIST;
}
// I CANNOT CATCH THIS EXCEPTION
} catch (Exception e) {
System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>Cannot Connect to the Sftp Server " + server);
LOG.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>Cannot Connect to the Sftp Server " + server);
LOG.info(e.getMessage());
return Existence.UNKNOWN;
}
}
public static void main(String[] args) throws Exception {
String protocol = "sftp";
int port = 22;
String server;
String user;
String password;
String filePathAtServer;
String filenameAtServer;
boolean fileExist;
Main main = new Main();
server = "unknown.com";
user = "demo";
password = "password";
filePathAtServer = "/";
filenameAtServer = "readme.txt";
doesFileExistAtServer(main, protocol, user, password, server, port, filePathAtServer, filenameAtServer, localPath);
LOG.info("\nThe accesibility of the file 1 " + filenameAtServer + " at the server " + server + " is " + fileExist + "\n")
}
Whereas my RouteBuilder looks as follows:
public class MyFtpClientRouteBuilder extends RouteBuilder {
private static final Logger LOG =
LoggerFactory.getLogger(MyFtpClientRouteBuilder.class);
String protocol = "sftp";
int port = 22;
String server;
String user;
String password;
String filePathAtServer;
String filenameAtServer;
String localPath;
boolean fileExist;
public MyFtpClientRouteBuilder(String protocol, String user, String password, String server, int port,
String filePathAtServer, String filenameAtServer, String localPath) {
super();
this.protocol = protocol;
this.user = user;
this.password = password;
this.server = server;
this.port = port;
this.filePathAtServer = filePathAtServer;
this.filenameAtServer = filenameAtServer;
this.localPath = localPath;
}
private static String generateFromUri(String protocol, String user, String password, String server, int port,
String path, String filename) {
final String downloadFalse = "download=false"; // NO, DO NOT Download the file
final String fastExistsCheck = "fastExistsCheck=true";
final String doNothing = "noop=true"; // Just connect, but DO NOTHING
final String connectFail = "throwExceptionOnConnectFailed=true"; // Just in case a connection fails
final String maxReconnect = "maximumReconnectAttempts=0";
final String bridgeError = "consumer.bridgeErrorHandler=true";
return protocol + "://" + user + "@" + server + ":" + port + path + "?" + "fileName=" + filename + "&"
+ downloadFalse + "&"
+ "password=" + password
+ "&" + fastExistsCheck
+ "&" + connectFail
+ "&" + doNothing
+ "&" + maxReconnect
+ "&" + bridgeError;
}
private static String generateLocalUri(String path) {
final String protocol = "file";
final String allowNullBody = "allowNullBody=true";
final String doNothing = "noop=true";
final String fileExist = "fileExist=move";
final String moveExisting = "moveExisting=oldFile";
return protocol + ":" + path + "?" + allowNullBody + "&" + doNothing + "&" + fileExist + "&" + moveExisting;
}
@Override
public void configure() throws CannotConnectException {
final String fromSftpServer = generateFromUri(protocol, user, password, server, port, filePathAtServer, filenameAtServer);
LOG.info("From: " + fromSftpServer);
final String toLocal = generateLocalUri(localPath);
LOG.info("To: " + toLocal);
onException(GenericFileOperationFailedException.class, JSchException.class)
//.handled(true)
.throwException(new CannotConnectException("Cannot connect to the remote SFTP server " + server))
.log("Cannot connect to the remote SFTP server " + server)
.maximumRedeliveries(0)
.to(toLocal)
.continued(false) // Either handled(true) or continue(false) but NOT both together
.end();
from(fromSftpServer).to(toLocal);
}
}