-
Notifications
You must be signed in to change notification settings - Fork 41
SFTP Logging Example
FDOT has some experiences integrating with cubic controllers using SFTP. There are two components I added to the original UDOT solution to make SFTP work.
Step 0: Install SSH.NET from Nuget package, I am using the library written by Renci, which has 33.8M downloads. Step 1: Under MOE.Common application, add two SFTP handler functions: (you can name the function as you fit)
public void GetCubicFilesAsync()
{
// run the sftp fetch operation async
Thread sftpFetch = new Thread(delegate () {
// to-do: replace with common data access to access signal IP in batch from ATSPM DB
string host = "signal IP";
string username = "SFTP signal user name";
string password = "SFTP signal password";
string remoteDirectory = "SFTP remote directory";
string localDirectory = "local path to store dat files from remote directory";
using (SftpClient sftp = new SftpClient(host, username, password))
{
try
{
sftp.Connect();
`var files = sftp.ListDirectory(remoteDirectory);`
`var cubicFiles = files.Where(x => x.FullName.Contains(".dat")).ToList();`
`//download current files, remove files from remote directory`
`TransferCubicFiles(cubicFiles, localDirectory, sftp);`
`sftp.Disconnect();`
`}`
`catch (Exception ex)`
`{`
`//to-do: add some custom error handling as fit `
`throw ex;`
`}`
`}`
`});`
`sftpFetch.Start();`
}
private void TransferCubicFiles(List receivedFiles, string directory, SftpClient client) { var errorRepository = ApplicationEventRepositoryFactory.Create(); try { foreach (var ret in receivedFiles) { // FullName will include full path in sFTP // Name will just include the file name without path
string fileName = ret.Name;
string remoteFileName = ret.FullName;
using (Stream fileStream = File.OpenWrite(Path.Combine(directory, fileName)))
{
Console.WriteLine("Downloading {0}", fileName);
//copy file and get to local diretory
client.DownloadFile(remoteFileName, fileStream);
//remove file in remote directory
Console.WriteLine("deleting {0} in sFTP instance", remoteFileName);
//delete file in remote sFTP directory
if (client.Exists(remoteFileName))
{
client.DeleteFile(remoteFileName);
}
}
string newFileName = RenameDatFiles(fileName, Signal.SignalID);
File.Move(Path.Combine(directory, fileName), Path.Combine(directory, newFileName));
}
}
catch (FTPException ex)
{
//capture if there is any sFTP related exception
errorRepository.QuickAdd("sFTPFromControllers", "SignalFtp", "TransferCubicFiles", ApplicationEvent.SeverityLevels.Medium, Signal.SignalID + " @ " + Signal.IPAddress + " - " + ex.Message);
Console.WriteLine(Signal.SignalID + " @ " + Signal.IPAddress + " - " + ex.Message);
}
catch (IOException ex)
{
//capture if there is any file IO exception
errorRepository.QuickAdd("sFTPFromControllers", "SignalFtp", "TransferCubicFiles", ApplicationEvent.SeverityLevels.Medium, Signal.SignalID + " @ " + Signal.IPAddress + " - " + ex.Message);
Console.WriteLine(Signal.SignalID + " @ " + Signal.IPAddress + " - " + ex.Message);
}
}