using System; using System.Collections.Generic; using System.Linq; using Newtonsoft.Json; using Serilog; using WinSCP; using System.Text.RegularExpressions; using LCU.Api.Internal.FTP.Helpers; using LCU.Api.Internal.FTPLib.Models; using LCU.Library.Internal.FileOperationsModels.Shared; namespace LCU.Api.Internal.FTP.Services.FtpOpertionServices; public class WinScpSftpDownloadFilesService : IWinScpSftpDownloadFilesService { private readonly IWinScpListDirectoryService _winScpListDirectoryService; public WinScpSftpDownloadFilesService(IWinScpListDirectoryService winScpListDirectoryService) { _winScpListDirectoryService = winScpListDirectoryService; } public FtpRequestResponse ExecuteAction(QueueRequest queueRequest) { var ftpRequestResponse = new FtpRequestResponse(); try { ArgumentNullException.ThrowIfNull(queueRequest); var request = JsonConvert.DeserializeObject(queueRequest.Request); ArgumentNullException.ThrowIfNull(request); ftpRequestResponse.ReturnResponse = request; ftpRequestResponse = TransferFiles(request, ftpRequestResponse); } catch (Exception exception) { ftpRequestResponse.IsSuccessful = false; ftpRequestResponse.MessageStack.Add(exception.Message); } return ftpRequestResponse; } private FtpRequestResponse TransferFiles(SftpDownloadFileRequest winScpDownloadFileRequest, FtpRequestResponse ftpRequestResponse) { try { var listDirectoryRequest = new ListDirectoryRequest() { SessionInformation = winScpDownloadFileRequest.SessionInformation, RemotePath = winScpDownloadFileRequest.FinalRemoteFilePath }; var filesInDirectory = _winScpListDirectoryService.GetListOfFilesInDirectory(listDirectoryRequest); var remoteFileNameRegex = winScpDownloadFileRequest.DynamicNameSetting != null ? RegexNameHandler.BuildRegexName(winScpDownloadFileRequest.FinalRemoteFileName, winScpDownloadFileRequest.DynamicNameSetting) : new Regex(winScpDownloadFileRequest.FinalRemoteFileName); var matchedDirectoryFiles = filesInDirectory.Where(fileName => remoteFileNameRegex.IsMatch(fileName)).ToList(); if (!matchedDirectoryFiles.Any()) { ftpRequestResponse.MessageStack.Add($"No files available to be downloaded. " + $"RegexFileName: {remoteFileNameRegex}. " + $"Succeed On Empty?: {winScpDownloadFileRequest.SucceedOnEmpty}"); ftpRequestResponse.IsSuccessful = winScpDownloadFileRequest.SucceedOnEmpty; return ftpRequestResponse; } var sessionOptions = WinScpSessionOptionsHelper.CreateSessionOptions(winScpDownloadFileRequest.SessionInformation); WinScpFile(sessionOptions, winScpDownloadFileRequest, matchedDirectoryFiles); } catch (Exception exception) { ftpRequestResponse.MessageStack.Add($"Failed to download file with WinSCP. " + $"Host: {winScpDownloadFileRequest.SessionInformation.HostName}, " + $"RemotePath: {winScpDownloadFileRequest.FinalRemoteFilePath} " + $"ExceptionMessage: { exception.Message }"); ftpRequestResponse.IsSuccessful = false; } return ftpRequestResponse; } private void WinScpFile(SessionOptions sessionOptions, SftpDownloadFileRequest winScpDownloadFileRequest, List remoteFileNames) { using (var session = new Session()) { session.Open(sessionOptions); var transferOptions = new TransferOptions { TransferMode = TransferMode.Binary, PreserveTimestamp = false }; if (!winScpDownloadFileRequest.ResumeSupportStateOn) { transferOptions.ResumeSupport.State = TransferResumeSupportState.Off; } foreach(string remoteFileName in remoteFileNames) { var addedSlash = winScpDownloadFileRequest.FinalRemoteFilePath.EndsWith('/') ? "" : "/"; var remotefilePath = $"{winScpDownloadFileRequest.FinalRemoteFilePath}{addedSlash}{remoteFileName}"; var transferResult = session.GetFiles(remotefilePath, winScpDownloadFileRequest.FinalLocalFilePath, winScpDownloadFileRequest.ShouldRemove, transferOptions); transferResult.Check(); foreach (TransferEventArgs transfer in transferResult.Transfers) { Log.Debug($"Download of {transfer.FileName} succeeded"); } } } } }