The company I work for recently received notification that one of our vendors was moving their SFTP server to a service which only supported WebDAV and FTPS. I've been trying to shift all our data exchanges from a hodge-podge of tools like WinSCP scripts, FTP Voyager, and Mirth Connect 3.X to a new server running Mirth Connect 4.X (Community Edition) and thought, "No problem! Mirth can do so much!"
I was wrong.
Out of the box Mirth Connect can easily handle TCP/IP transmissions, FTP transfers, SMB transfers, MLLP message, and many more BUT IT CANNOT HANDLE FTP OVER SSL/TLS! Mirth's corporate backer, Nextgen Healthcare, offers an extension which adds things like FTPS support, but that extension alone would cost $6,500 per year, which was more money than I wanted to request approval for just to consolidate our data exchanges
Since Mirth Connect is built on Java I was able to take a day to learn to leverage Java packages already included in Mirth Connect into an FTPS channel WITHOUT the plugin. Details are below for anyone in need of a similar solution:
Step 1
You'll need to set up a batch processor for the contents of the FTPS folder you're checking. I chose to use the default option that reads each line as a separate message until a blank line is reached.
return reader.readLine();
Step 2
After setting up the channel to handle batching we need to generate batches (i.e. lists) of files. To this end we need to configure a JavaScript channel reader to poll the FTPS server and output a list of files delimited with carriage returns. Below is a template based on what I came up with:
var ftpsServerAddress = "subdomain.domain.com"
// The next line is unnecessary for port 990 if implicit SSL/TLS is used, but I left this in case a future vendor uses a non-standard port
var ftpsServerPort = 990
var ftpsUsername = "username"
var ftpsPassword = "password"
var ftpsFolder = "folder/path/on/server"
// A string to hand off to the channel's batch processor
var batchResults = ""
// Parameter sets the connection to use Implicit SSL/TLS which defaults to port 990
var ftps = new Packages.org.apache.commons.net.ftp.FTPSClient(true);
// Even though the Implicit SSL/TLS sets the port to 990 ftpsServerPort was supplied to make code reuse on later projects easier
ftps.connect(ftpsServerAddress, ftpsServerPort);
// Needed to list files
ftps.enterLocalPassiveMode()
ftps.login(ftpsUsername, ftpsPassword)
// Get a list of all the objects in the ftpsFolder
filesList = ftps.listNames(ftpsFolder)
// Concatenate all the files into a string for handling by the batch processor
for each(filename in filesList){
var byteArrayStream = new java.io.ByteArrayOutputStream();
// Retrieve the remote file to the previously declared byteArrayStream
ftps.retrieveFile(ftpsFolder + filename, byteArrayStream)
file = {
"filename": filename,
"b64": FileUtil.encode(byteArrayStream.toByteArray())
}
batchResults = batchResults + JSON.stringify(file) + "\n"
}
ftps.disconnect();
return batchResults;
Step 3
Once the Javascript reader was passing file names to the destination, I set up a File Writer channel destination, but needed to retrieve each file found in the Channel Source via a Destination Transformer. Below is the code I used:
var message = JSON.parse(connectorMessage.getRawData())
channelMap.put("filename",message.filename)
channelMap.put("b64",message.b64)
Step 4
The Channel Destination needed to be set up to write the file to a destination folder
After all that I was able to set the File Writer as below and found the files flowing appropriately, saving us $6,500 per year!