PageRenderTime 235ms CodeModel.GetById 36ms RepoModel.GetById 7ms app.codeStats 0ms

/SSIS.Extensions/SSIS.Extensions/SSIS.Extensions/SFTP/SFTPConnection.cs

#
C# | 288 lines | 200 code | 37 blank | 51 comment | 17 complexity | 303450061ed95a758ba898e32ee9ec2b MD5 | raw file
  1. using Microsoft.SqlServer.Dts.Runtime;
  2. using Renci.SshNet;
  3. using Renci.SshNet.Sftp;
  4. using System;
  5. using System.Collections;
  6. using System.Collections.Generic;
  7. using System.IO;
  8. namespace SSIS.Extensions.SFTP
  9. {
  10. /// <summary>
  11. /// This class is the SFTP interface to ssh net library.
  12. /// </summary>
  13. public class SFTPConnection
  14. {
  15. #region Properties
  16. public string hostName { get; set; }
  17. public string userName { get; set; }
  18. public string passWord { get; set; }
  19. public int portNumber { get; set; }
  20. //private int reTries { get; set; }
  21. private bool stopOnFailure { get; set; }
  22. public LogLevel logLevel { get; set; }
  23. public IDTSComponentEvents componentEvents { get; set; }
  24. #endregion
  25. #region Constructor
  26. /// <summary>
  27. /// Initializes a new instance of the <see cref="SFTPConnection"/> class.
  28. /// </summary>
  29. /// <param name="hostName">Name of the host.</param>
  30. /// <param name="userName">Name of the user.</param>
  31. /// <param name="passWord">The pass word.</param>
  32. /// <param name="portNumber">The port number.</param>
  33. /// <param name="reTries">The re tries.</param>
  34. /// <param name="componentEvents">The component events.</param>
  35. /// <param name="logLevel">The log level.</param>
  36. public SFTPConnection(string hostName, string userName, string passWord, int portNumber, bool stopOnFailure, IDTSComponentEvents componentEvents, LogLevel logLevel)
  37. {
  38. this.hostName = hostName;
  39. this.userName = userName;
  40. this.passWord = passWord;
  41. this.portNumber = portNumber;
  42. //this.reTries = reTries;
  43. this.componentEvents = componentEvents;
  44. this.logLevel = logLevel;
  45. this.stopOnFailure = stopOnFailure;
  46. }
  47. #endregion
  48. #region Private Members
  49. /// <summary>
  50. /// Logs the specified message.
  51. /// </summary>
  52. /// <param name="Message">The message.</param>
  53. /// <param name="minLogLevel">The min log level.</param>
  54. private void Log(string Message, LogLevel minLogLevel)
  55. {
  56. if (this.logLevel >= minLogLevel)
  57. Common.FireInfo(Message, componentEvents);
  58. }
  59. /// <summary>
  60. /// Throws the exception.
  61. /// </summary>
  62. /// <param name="Message">The message.</param>
  63. /// <param name="ex">The ex.</param>
  64. /// <exception cref="System.Exception">
  65. /// </exception>
  66. private void ThrowException(string Message, Exception ex)
  67. {
  68. string stackTrace = ex.StackTrace;
  69. if (ex.InnerException != null)
  70. {
  71. Message += ex.InnerException.Message;
  72. stackTrace += ex.InnerException.StackTrace;
  73. }
  74. Message += ex.Message + Environment.NewLine;
  75. stackTrace += Environment.NewLine;
  76. if (logLevel == LogLevel.Verbose)
  77. throw new Exception(String.Format("Error: {0}StackTrace: {1}", Message, stackTrace), ex);
  78. else
  79. throw new Exception(String.Format("Error: {0}", Message), ex);
  80. }
  81. #endregion
  82. #region Upload Files
  83. /// <summary>
  84. /// Uploads the files.
  85. /// </summary>
  86. /// <param name="fileList">The file list.</param>
  87. /// <exception cref="System.Exception">Remote File Already Exists.</exception>
  88. public void UploadFiles(List<ISFTPFileInfo> fileList)
  89. {
  90. try
  91. {
  92. this.Log(String.Format("Connecting to Host: [{0}].", this.hostName), LogLevel.Minimal);
  93. using (SftpClient sftp = new SftpClient(this.hostName, this.portNumber, this.userName, this.passWord))
  94. {
  95. sftp.Connect();
  96. this.Log(String.Format("Connected to Host: [{0}].", this.hostName), LogLevel.Verbose);
  97. // Upload each file
  98. foreach (SFTPFileInfo sftpFile in fileList)
  99. {
  100. FileInfo fileInfo = new FileInfo(sftpFile.LocalPath);
  101. if (sftpFile.RemotePath.EndsWith("/"))
  102. sftpFile.RemotePath = Path.Combine(sftpFile.RemotePath, fileInfo.Name).Replace(@"\", "/");
  103. // if file exists can we overwrite it.
  104. if (sftp.Exists(sftpFile.RemotePath))
  105. {
  106. if (sftpFile.OverwriteDestination)
  107. {
  108. this.Log(String.Format("Removing File: [{0}].", sftpFile.RemotePath), LogLevel.Verbose);
  109. sftp.Delete(sftpFile.RemotePath);
  110. this.Log(String.Format("Removed File: [{0}].", sftpFile.RemotePath), LogLevel.Verbose);
  111. }
  112. else
  113. {
  114. if (this.stopOnFailure)
  115. throw new Exception("Remote File Already Exists.");
  116. }
  117. }
  118. using (FileStream file = File.OpenRead(sftpFile.LocalPath))
  119. {
  120. this.Log(String.Format("Uploading File: [{0}] -> [{1}].", fileInfo.FullName, sftpFile.RemotePath), LogLevel.Minimal);
  121. sftp.UploadFile(file, sftpFile.RemotePath);
  122. this.Log(String.Format("Uploaded File: [{0}] -> [{1}].", fileInfo.FullName, sftpFile.RemotePath), LogLevel.Verbose);
  123. }
  124. }
  125. }
  126. this.Log(String.Format("Disconnected from Host: [{0}].", this.hostName), LogLevel.Minimal);
  127. }
  128. catch (Exception ex)
  129. {
  130. this.Log(String.Format("Disconnected from Host: [{0}].", this.hostName), LogLevel.Minimal);
  131. this.ThrowException("Unable to Upload: ", ex);
  132. }
  133. }
  134. #endregion
  135. #region Download Files
  136. /// <summary>
  137. /// Downloads the files.
  138. /// </summary>
  139. /// <param name="fileList">The file list.</param>
  140. /// <param name="failRemoteNotExists">if set to <c>true</c> [fail remote not exists].</param>
  141. /// <exception cref="System.Exception">
  142. /// Local File Already Exists.
  143. /// </exception>
  144. public void DownloadFiles(List<ISFTPFileInfo> fileList)
  145. {
  146. try
  147. {
  148. this.Log(String.Format("Connecting to Host: [{0}].", this.hostName), LogLevel.Minimal);
  149. using (SftpClient sftp = new SftpClient(this.hostName, this.portNumber, this.userName, this.passWord))
  150. {
  151. sftp.Connect();
  152. this.Log(String.Format("Connected to Host: [{0}].", this.hostName), LogLevel.Verbose);
  153. // Download each file
  154. foreach (SFTPFileInfo filePath in fileList)
  155. {
  156. if (!sftp.Exists(filePath.RemotePath))
  157. {
  158. this.Log(String.Format("Remote Path Does Not Exist: [{0}].", this.hostName), LogLevel.Verbose);
  159. if (this.stopOnFailure)
  160. throw new Exception(String.Format("Remote Path Does Not Exist: [{0}]", filePath.RemotePath));
  161. else
  162. continue;
  163. }
  164. if (Directory.Exists(filePath.LocalPath))
  165. filePath.LocalPath = Path.Combine(filePath.LocalPath, filePath.RemotePath.Substring(filePath.RemotePath.LastIndexOf("/") + 1));
  166. // Can we overwrite the local file
  167. if (!filePath.OverwriteDestination && File.Exists(filePath.LocalPath))
  168. throw new Exception("Local File Already Exists.");
  169. this.Log(String.Format("Downloading File: [{0}] -> [{1}].", filePath.RemotePath, filePath.LocalPath), LogLevel.Minimal);
  170. using (FileStream fileStream = File.OpenWrite(filePath.LocalPath))
  171. {
  172. sftp.DownloadFile(filePath.RemotePath, fileStream);
  173. }
  174. this.Log(String.Format("File Downloaded: [{0}]", filePath.LocalPath), LogLevel.Verbose);
  175. }
  176. }
  177. this.Log(String.Format("Disconnected from Host: [{0}].", this.hostName), LogLevel.Minimal);
  178. }
  179. catch (Exception ex)
  180. {
  181. this.Log(String.Format("Disconnected from Host: [{0}].", this.hostName), LogLevel.Minimal);
  182. this.ThrowException("Unable to Download: ", ex);
  183. }
  184. }
  185. #endregion
  186. #region Get File Listing
  187. /// <summary>
  188. /// Lists the files.
  189. /// </summary>
  190. /// <param name="remotePath">The remote path.</param>
  191. /// <param name="failRemoteNotExists">if set to <c>true</c> [fail remote not exists].</param>
  192. /// <returns></returns>
  193. /// <exception cref="System.Exception"></exception>
  194. public List<IRemoteFileInfo> ListFiles(string remotePath)
  195. {
  196. List<IRemoteFileInfo> fileList = new List<IRemoteFileInfo>();
  197. try
  198. {
  199. this.Log(String.Format("Connecting to Host: [{0}].", this.hostName), LogLevel.Minimal);
  200. using (SftpClient sftp = new SftpClient(this.hostName, this.portNumber, this.userName, this.passWord))
  201. {
  202. sftp.Connect();
  203. this.Log(String.Format("Connected to Host: [{0}].", this.hostName), LogLevel.Verbose);
  204. if (!sftp.Exists(remotePath))
  205. {
  206. this.Log(String.Format("Remote Path Does Not Exist: [{0}].", this.hostName), LogLevel.Verbose);
  207. if (this.stopOnFailure)
  208. throw new Exception(String.Format("Invalid Path: [{0}]", remotePath));
  209. }
  210. else
  211. {
  212. this.Log(String.Format("Listing Files: [{0}].", remotePath), LogLevel.Minimal);
  213. this.Log(String.Format("Getting Attributes: [{0}].", remotePath), LogLevel.Verbose);
  214. SftpFile sftpFileInfo = sftp.Get(remotePath);
  215. if (sftpFileInfo.IsDirectory)
  216. {
  217. this.Log(String.Format("Path is a Directory: [{0}].", remotePath), LogLevel.Verbose);
  218. IEnumerable<SftpFile> dirList = sftp.ListDirectory(remotePath);
  219. foreach (SftpFile sftpFile in dirList)
  220. fileList.Add(this.CreateFileInfo(sftpFile));
  221. }
  222. else
  223. {
  224. this.Log(String.Format("Path is a File: [{0}].", remotePath), LogLevel.Verbose);
  225. fileList.Add(this.CreateFileInfo(sftpFileInfo));
  226. }
  227. }
  228. }
  229. this.Log(String.Format("Disconnected from Host: [{0}].", this.hostName), LogLevel.Minimal);
  230. }
  231. catch (Exception ex)
  232. {
  233. this.Log(String.Format("Disconnected from Host: [{0}].", this.hostName), LogLevel.Minimal);
  234. this.ThrowException("Unable to List: ", ex);
  235. }
  236. return fileList;
  237. }
  238. private RemoteFileInfo CreateFileInfo(SftpFile sftpFile)
  239. {
  240. RemoteFileInfo fileInfo = new RemoteFileInfo();
  241. fileInfo.Name = sftpFile.Name;
  242. fileInfo.FullName = sftpFile.FullName;
  243. fileInfo.Extension = Path.GetExtension(sftpFile.FullName);
  244. fileInfo.IsDirectory = sftpFile.IsDirectory;
  245. fileInfo.Size = sftpFile.Length;
  246. fileInfo.ModifiedTime = sftpFile.LastWriteTime;
  247. return fileInfo;
  248. }
  249. #endregion
  250. }
  251. }