I'm currently working on to set up SFTP (password) based integration to upload a .csv file from ServiceNow table to first Mid server file and lastly to cloud server. While the first scenario is satisfied, I see the file stored under midserver/work, but later my sftp.put() function is not working throwing 'Sftp put: java.lang.NegativeArraySizeException: -168' (this number is changing sometimeds -175, sometimes -158).
Just to add If I'm running it from PowerShell, its working perfectly.
I'm pasting the code also, if anyone having any upper-hand please add some comments, been stuck into it for a week now.
var SNDataRetriever = Class.create();
SNDataRetriever.prototype = {
initialize: function() {
///// Parameters that can be set from this script
//
this.debug = false;
//If you would like to move processed files to a target location, set the next two parameters.
//Make sure your file name ends up being unique. We will not overwrite a file by the same name
//in the target directory...
this.moveProcessedFiles = false;
this.MIDSERVER_PROCESSED_FILE_PATH = "processed/";
//
/////
this.resLog = "FTP Log: \n";
this.log("Initializing SNDataRetriever");
this.MIDSERVER_FILE_PATH = "work" + Packages.java.io.File.separator;
this.MIDSERVER_FILE_NAME = probe.getParameter('targetFileName');
this.useProxy = this.getConfigParameter("mid.proxy.use_proxy");
if (this.useProxy) {
this.proxyHost = this.getConfigParameter("mid.proxy.host");
this.proxyPort = this.getConfigParameter("mid.proxy.port");
this.proxyUser = this.getConfigParameter("mid.proxy.username");
this.proxyPass = this.getConfigParameter("mid.proxy.password");
}
this.user = this.getConfigParameter("mid.instance.username");
this.password = this.getConfigParameter("mid.instance.password");
var ftpCredArr = this.decryptCredentials(probe.getParameter('ftpCred'));
this.ftpUser = ftpCredArr[0];
this.ftpPass = ftpCredArr[1];
this.ftpTargetServer = probe.getParameter('ftpTargetServer');
this.ftpPort = (this.isANumber(probe.getParameter('ftpPort'))) ? (probe.getParameter('ftpPort')) : null;
this.targetPath = probe.getParameter('targetPath');
this.targetFileName = probe.getParameter('targetFileName');
this.reportURL = probe.getParameter('reportURL');
this.lastRunDateTime = probe.getParameter('lastRunDateTime');
if (this.lastRunDateTime) {
this.reportURL += "&sysparm_query=sys_updated_on>" + this.lastRunDateTime;
}
this.host = probe.getParameter('host');
this.transportMethod = probe.getParameter('transportMethod');
if (this.debug) {
this.log("\n********** Debug Info **********\nuser: " + this.user + "\npass: " + this.password + "\ntransportMethod: " + this.transportMethod + "\nreport: " + this.reportURL + "\nhost: " + this.host);
this.log("\n********** Proxy Info **********\nproxyNeeded: " + this.proxyNeeded + "\nproxyUser : " + this.proxyUser + "\nproxyPass :" + this.proxyPass);
this.log("\nproxyHost: " + this.proxyHost + "\nproxyPort:" + this.proxyPort);
this.log("\n********** FTP Info ************\nftpUser: " + this.ftpUser + "\nftpPass: " + this.ftpPass + "\nftpPort: " + this.ftpPort);
this.log("\n********** End of Debug ********\n\n");
}
this.response = this.execute();
},
getConfigParameter: function(parm) {
var m = Packages.com.service_now.mid.MIDServer.get();
var config = m.getConfig();
var res = config.getParameter(parm);
var res2 = config.getProperty(parm);
if (res) {
return res;
} else if (res2) {
return res2;
} else {
config = Packages.com.service_now.mid.services.Config.get();
return config.getProperty(parm);
}
},
decryptCredentials: function(data) {
var cred = new String(data);
var e = new Packages.com.glide.util.Encrypter();
var jsCred = cred + '';
var usernamePass = e.decrypt(jsCred);
var credArr = usernamePass.split(":", 2);
return credArr;
},
saveToFile: function(data, targetPath) {
var tmpLoc;
var result = true;
try {
if (this.transportMethod == "Mid Server") {
tmpLoc = targetPath;
} else {
tmpLoc = this.MIDSERVER_FILE_PATH + this.MIDSERVER_FILE_NAME;
}
var out = new Packages.java.io.PrintWriter(new Packages.java.io.FileWriter(tmpLoc));
out.print(data);
this.log("File saved to: " + tmpLoc);
} catch (e) {
this.log("Exception caught in SNDataRetriever->saveToFile: " + e.getMessage());
result = false;
}
out.close();
return result;
},
copyToSFTP: function() {
this.log('Arriving to function copyToSFTP');
var tmpLoc;
var connectionType;
var connected = true;
var connectionLog = '';
var sftpSuccess = true;
if (this.transportMethod == "SFTP (RSA)") {
try {
keyfile = this.MIDSERVER_PRIVATE_KEY_PATH + 'id_rsa';
sshfile = new Packages.com.sshtools.j2ssh.transport.publickey.SshPrivateKeyFile.parse(new Packages.java.io.File(keyfile));
//this.log('key format'+sshfile.getFormat());
//this.log('key value'+sshfile.toString());
pk = new Packages.com.sshtools.j2ssh.authentication.PublicKeyAuthenticationClient();
//this.log('PUBLIC KEY METHOD'+pk.getMethodName());
pk.setUsername(this.ftpUser);
pk.setKey(sshfile.toPrivateKey(null));
} catch (e) {
connectionLog += "\nException Reading RSA Key: " + e;
sftpSuccess = false;
}
} else if (this.transportMethod == "SFTP (DSA)") {
try {
keyfile = this.MIDSERVER_PRIVATE_KEY_PATH + 'id_dsa';
sshfile = new Packages.com.sshtools.j2ssh.transport.publickey.SshPrivateKeyFile.parse(new Packages.java.io.File(keyfile));
//this.log('key format'+sshfile.getFormat());
//this.log('key value'+sshfile.toString());
pk = new Packages.com.sshtools.j2ssh.authentication.PublicKeyAuthenticationClient();
//this.log('PUBLIC KEY METHOD'+pk.getMethodName());
pk.setUsername(this.ftpUser);
pk.setKey(sshfile.toPrivateKey(null));
} catch (e) {
this.log("Exception Reading DSA Key: " + e);
sftpSuccess = false;
}
} else if (this.transportMethod == "SFTP (Password)") {
pk = new Packages.com.sshtools.j2ssh.authentication.PasswordAuthenticationClient();
pk.setUsername(this.ftpUser);
pk.setPassword(this.ftpPass);
}
var ssh = new Packages.com.sshtools.j2ssh.SshClient();
var ignoreHost = new Packages.com.sshtools.j2ssh.transport.IgnoreHostKeyVerification();
try {
//ssh.setSocketTimeout(15000); // 15 second timeout
ssh.connect(this.ftpTargetServer, this.ftpPort, ignoreHost);
} catch (e) {
this.log("Exception Connecting to SFTP Host: " + e);
sftpSuccess = false;
}
authState = new Packages.com.sshtools.j2ssh.authentication.AuthenticationProtocolState();
if (ssh.authenticate(pk) == authState.COMPLETE) {
this.log('SSH REMOTE AUTHENTICATE==TRUE');
var sftp = ssh.openSftpClient();
if (sftp == null) {
this.log("SFTP Client initialization failed. Check network/firewall from MID Server host.");
return false;
}
try {
var pwd = new Packages.java.io.File(".").getAbsolutePath(); // Work directory
pwd = pwd.slice(0, -1);
sftp.lcd(pwd + this.MIDSERVER_FILE_PATH);
this.log(pwd);
this.log(this.MIDSERVER_FILE_PATH);
this.log(pwd + this.MIDSERVER_FILE_PATH);
//sftp.lcd("C:\\agent\\work");
} catch (e) {
this.log('Error in Sftp set local directory: ' + e);
sftpSuccess = false;
}
try {
sftp.cd(this.targetPath);
this.log(this.targetPath);
} catch (e) {
this.log('Error in Sftp set remote directory: ' + e);
sftpSuccess = false;
}
if (sftpSuccess == true) {
try {
this.log(this.MIDSERVER_FILE_NAME);
sftp.put(this.MIDSERVER_FILE_NAME);
this.log('Successfully copied file: ' + this.MIDSERVER_FILE_NAME + ' to ' + this.ftpTargetServer + ':' + this.targetPath); // File (or directory) to be moved
} catch (e) {
this.log('Error in Sftp put: ' + e);
sftpSuccess = false;
}
}
} else {
connectionLog += "\n**********FAILURE: Connection to SFTP server failed**************\n";
}
this.log(connectionLog);
return sftpSuccess;
},
copyToFTP: function() {
var tmpLoc;
var connectionType;
var ftpSuccess = false;
if (this.transportMethod == "FTPS (Auth SSL)") {
connectionType = "AUTH_SSL_FTP_CONNECTION";
if (!this.ftpPort) {
this.ftpPort = 21;
}
} else if (this.transportMethod == "FTPS (Auth TLS)") {
connectionType = "AUTH_TLS_FTP_CONNECTION";
if (!this.ftpPort) {
this.ftpPort = 21;
}
} else if (this.transportMethod == "FTPS (Implicit SSL)") {
connectionType = "IMPLICIT_SSL_FTP_CONNECTION";
if (!this.ftpPort) {
this.ftpPort = 990;
}
} else if (this.transportMethod == "FTPS (Implicit TLS)") {
connectionType = "IMPLICIT_TLS_FTP_CONNECTION";
if (!this.ftpPort) {
this.ftpPort = 990;
}
} else {
connectionType = "FTP_CONNECTION";
if (!this.ftpPort) {
this.ftpPort = 21;
}
}
this.log("ConnectionType: " + connectionType + " and port: " + this.ftpPort);
var pt = new Packages.java.util.Properties();
pt.setProperty("connection.host", this.ftpTargetServer);
pt.setProperty("connection.port", this.ftpPort);
pt.setProperty("user.login", this.ftpUser);
pt.setProperty("user.password", this.ftpPass);
pt.setProperty("connection.type", connectionType);
pt.setProperty("connection.timeout", "10000");
pt.setProperty("connection.passive", "true");
try {
var connection = Packages.org.ftp4che.FTPConnectionFactory.getInstance(pt);
var fromFile = new Packages.org.ftp4che.util.ftpfile.FTPFile(this.MIDSERVER_FILE_PATH, this.MIDSERVER_FILE_NAME);
var toFile = new Packages.org.ftp4che.util.ftpfile.FTPFile(this.targetPath, this.targetFileName);
} catch (e) {
}
var connectionLog = "Connection Log:\n";
var connected = false;
try {
connection.connect();
this.log("Connecting to " + this.ftpTargetServer + " on port " + this.ftpPort);
connection.noOperation();
connected = true;
} catch (e) {
connectionLog += "\nException in block B: " + e;
connected = false;
}
if (connected == true) {
try {
this.log("Connected...");
this.log("Uploading " + fromFile + " to " + toFile);
connection.uploadFile(fromFile, toFile);
this.log("File successfully uploaded\n\n");
connection.disconnect();
ftpSuccess = true;
} catch (e) {
connectionLog += "\n**********FAILURE: Connection to FTP server failed**************\n";
connectionLog += "\nException in block C: \n" + e;
}
} else {
connectionLog += "\n**********FAILURE: Connection to FTP server failed**************\n";
}
this.log(connectionLog);
return ftpSuccess;
},
moveProcessedFile: function() {
file = new Packages.java.io.File(this.MIDSERVER_FILE_PATH + this.MIDSERVER_FILE_NAME); // Work directory
dir = new Packages.java.io.File(this.MIDSERVER_PROCESSED_FILE_PATH); // Move file to new (processed) directory
success = file.renameTo(new Packages.java.io.File(dir, file.getName()));
if (!success) {
this.log('File was not successfully moved!');
} else {
this.log("File was moved from TMP directory to a processed directory");
}
},
getReport: function() {
this.log("Arriving to getReport function");
var client = new Packages.org.apache.commons.httpclient.HttpClient();
////Set Proxy if (if there is one)
if (this.useProxy && this.useProxy.toLowerCase() == "true") {
client.getHostConfiguration().setProxy(this.proxyHost, this.proxyPort);
if (this.proxyUser) {
client.getState().setProxyCredentials(new Packages.org.apache.commons.httpclient.auth.AuthScope(this.proxyHost, this.proxyPort), new Packages.org.apache.commons.httpclient.UsernamePasswordCredentials(this.proxyUser, this.proxyPass));
}
}
client.getState().setCredentials(new Packages.org.apache.commons.httpclient.auth.AuthScope(null, 443, null), new Packages.org.apache.commons.httpclient.UsernamePasswordCredentials(this.user, this.password));
var method = new Packages.org.apache.commons.httpclient.methods.GetMethod((this.reportURL.replace(">", "%3E").replace(" ", "%20")));
method.setDoAuthentication(true);
try {
var statusCode = client.executeMethod(method);
if (statusCode != Packages.org.apache.commons.httpclient.HttpStatus.SC_OK) {
this.log("Method failed: " + method.getStatusLine());
}
// Read the response body.
var responseBody = method.getResponseBodyAsString();
//this.log("responseBody: " +responseBody);
} catch (e) {
this.log("Exception caught in SNDataRetriever->getReport: " + e.getMessage());
}
method.releaseConnection();
this.log("Releasing Connection");
return responseBody;
},
getLog: function() {
return this.resLog;
},
log: function(data) {
ms.log(data);
this.resLog += "\n" + data;
},
isANumber: function(data) {
data = data + '';
return ((data - 0) == data && data.length > 0);
},
execute: function() {
this.log("Running SNDataRetriever execute");
var pushRes = true;
var reportContents = this.getReport();
if (reportContents) {
var saveRes = this.saveToFile(reportContents, this.targetPath + this.targetFileName);
if (this.transportMethod.indexOf('SFTP') != -1) {
pushRes = this.copyToSFTP();
} else if (this.transportMethod.indexOf('FTP') != -1) {
pushRes = this.copyToFTP();
}
//Move tmp file to a processed directory
if (saveRes && pushRes && this.moveProcessedFiles && this.transportMethod.indexOf('Mid') == -1) {
this.moveProcessedFile();
}
} else {
this.log("The report was empty?");
}
},
type: 'SNDataRetriever'
};
Thank You
AD