public async Task <FtpClientResponse> WriteAsync(FtpConfig config, Func <string, Task <string> > securePasswordFunc, byte[] data, string fileName)
        {
            var response = new FtpClientResponse {
                ErrorMessage = FtpConstants.NoError, Status = FtpConstants.SuccessStatus, FileData = new List <FtpClientResponseFile>()
            };

            try
            {
                await CreateFtpClientAsync(config, securePasswordFunc);

                _ftpPolicyRegistry.GetPolicy(FtpPolicyName.FtpCommandPolicy)
                .Execute((context) => _ftpClient.Upload(data, $"{config.Ftp.Path}/{fileName}"),
                         new Polly.Context("WRITE_FILE"));
            }
            catch (FtpNotConnectException e)
            {
                response.ErrorMessage = response.ErrorMessage + e.Message;
                response.Status       = FtpConstants.FailureStatus;
            }
            catch (FtpSecurityNotAvailableException e)
            {
                response.ErrorMessage = response.ErrorMessage + e.Message;
                response.Status       = FtpConstants.FailureStatus;
            }
            catch (Exception)
            {
                throw;
            }
            return(response);
        }
예제 #2
0
        private async Task CreateFtpClientAsync(FtpConfig config, Func <string, Task <string> > securePasswordCallBack)
        {
            var passwd = await securePasswordCallBack.Invoke(config.Ftp.Credentials.AzureKeyVault.SecretName);

            _ftpClient = (config.Ftp.Protocol.Equals(FtpConstants.Ftps, StringComparison.InvariantCultureIgnoreCase) || config.Ftp.Port.Equals(990)) ?
                         new FluentFTP.FtpClient(config.Ftp.Host)
            {            //FTPS explicitly or Port = 990 => automatically create FTPS
                Credentials = new NetworkCredential(config.Ftp.Credentials.Username, passwd),
                Port        = config.Ftp.Port,
                EnableThreadSafeDataConnections = true,
                DataConnectionType        = config.Ftp.DataConnectionType == FtpConstants.FtpActiveMode ? FtpDataConnectionType.AutoActive : FtpDataConnectionType.AutoPassive,
                EncryptionMode            = config.Ftp.Port.Equals(990) ? FtpEncryptionMode.Implicit : FtpEncryptionMode.Explicit,
                DataConnectionReadTimeout = 30000
            }
                     :
            new FluentFTP.FtpClient(config.Ftp.Host)
            {
                Credentials = new NetworkCredential(config.Ftp.Credentials.Username, await securePasswordCallBack.Invoke(config.Ftp.Credentials.AzureKeyVault.SecretName)),
                Port        = config.Ftp.Port,
                EnableThreadSafeDataConnections = true,
                Encoding                  = Encoding.UTF8,
                DataConnectionType        = config.Ftp.DataConnectionType == FtpConstants.FtpActiveMode ? FtpDataConnectionType.AutoActive : FtpDataConnectionType.AutoPassive,
                DataConnectionReadTimeout = 30000
            };

            _ftpClient.ValidateCertificate += (control, e) =>
            {
                e.Accept = (string.IsNullOrEmpty(config.Ftp.ValidateServerCertificate) ||
                            config.Ftp.ValidateServerCertificate.Equals("false", StringComparison.InvariantCultureIgnoreCase)) ? true
                    : (e.Certificate.GetRawCertDataString() == config.Ftp.ValidateServerCertificate || e.PolicyErrors == SslPolicyErrors.None);
            };

            _ftpPolicyRegistry.GetPolicy(FtpPolicyName.FtpConnectPolicy).Execute(() => _ftpClient.Connect());
        }
예제 #3
0
 private async Task <ConnectionInfo> SetUpSftpAsync(FtpConfig config, Func <string, Task <string> > securePassword)
 {
     try
     {
         var passAuthenMethod       = new PasswordAuthenticationMethod(config.Ftp.Credentials.Username, await securePassword.Invoke(config.Ftp.Credentials.AzureKeyVault.SecretName));
         var privateKeyAuthenMethod = new PrivateKeyAuthenticationMethod(config.Ftp.Credentials.Username);
         var connectionInfo         = new ConnectionInfo(config.Ftp.Host, config.Ftp.Port, config.Ftp.Credentials.Username, passAuthenMethod, privateKeyAuthenMethod);
         return(connectionInfo);
     }
     catch (Exception ex)
     {
         throw ex;
     }
 }
예제 #4
0
        public async Task <FtpClientResponse> WriteAsync(FtpConfig config, Func <string, Task <string> > securePasswordFunc, byte[] data, string fileName)
        {
            var response = new FtpClientResponse {
                ErrorMessage = FtpConstants.NoError, Status = FtpConstants.SuccessStatus, FileData = new List <FtpClientResponseFile>()
            };
            var connectionInfo = await SetUpSftpAsync(config, securePasswordFunc);

            if (config.Encoding == null)
            {
                connectionInfo.Encoding = Encoding.UTF8;
            }
            else
            {
                if (config.Encoding == CommonConstants.ENCODING_DEFAULT_VALUE_TEXT)
                {
                    connectionInfo.Encoding = Encoding.Default;
                }
                else
                {
                    connectionInfo.Encoding = Encoding.GetEncoding(config.Encoding);
                }
            }

            _sftpClient = new SftpClient(connectionInfo);
            using (_sftpClient)
            {
                _ftpPolicyRegistry.GetPolicy(FtpPolicyName.FtpConnectPolicy).Execute(() => _sftpClient.Connect());

                var stream = new MemoryStream();
                stream.Write(data, 0, data.Length);
                stream.Position = 0;
                _ftpPolicyRegistry.GetPolicy(FtpPolicyName.FtpCommandPolicy).Execute(() =>
                {
                    _sftpClient.UploadFile(stream, $"{config.Ftp.Path}/{fileName}");
                });
            }

            return(response);
        }
예제 #5
0
        public async Task <FtpClientResponse> ReadAsync(FtpConfig config, Func <string, Task <string> > myFunc, Func <string, string, string, MemoryStream, string, string, bool> copyFileFunc)
        {
            var response = new FtpClientResponse {
                ErrorMessage = FtpConstants.NoError, Status = FtpConstants.SuccessStatus, FileData = new List <FtpClientResponseFile>()
            };

            try
            {
                var connectionInfo = await SetUpSftpAsync(config, myFunc);

                _sftpClient = new SftpClient(connectionInfo);
                using (_sftpClient)
                {
                    _ftpPolicyRegistry.GetPolicy(FtpPolicyName.FtpConnectPolicy).Execute(() => _sftpClient.Connect());

                    var listOfFiles = _sftpClient.ListDirectory(config.Ftp.Path).Where(f => !f.IsDirectory)
                                      .Select(f => f)
                                      .ToList();
                    if (!string.IsNullOrEmpty(config.Ftp.ArchivedPath))
                    {
                        var folderExisted = _sftpClient.Exists(config.Ftp.ArchivedPath);
                        if (!folderExisted)
                        {
                            _sftpClient.CreateDirectory(config.Ftp.ArchivedPath);
                        }
                    }
                    var resolvedStorageAccountKey =
                        await myFunc.Invoke(config.AzureBlobStorage.StorageKeyVault);


                    foreach (var item in listOfFiles)
                    {
                        bool copied     = false;
                        bool isArchived = false;

                        try
                        {
                            var fileName = item.Name;
                            using (var istream = _sftpClient.OpenRead(item.FullName))
                            {
                                MemoryStream memoryStream = new MemoryStream();
                                istream.CopyTo(memoryStream);
                                memoryStream.Position = 0;
                                copied = copyFileFunc.Invoke(config.AzureBlobStorage.ContainerName,
                                                             fileName,
                                                             config.Retry.StorageRetryPolicy, memoryStream, config.AzureBlobStorage.StorageAccountName, resolvedStorageAccountKey);

                                if (copied && !string.IsNullOrEmpty(config.Ftp.ArchivedPath))
                                {
                                    var fileNameSplit = item.Name.Split('.');
                                    var newFileName   =
                                        fileNameSplit[0] + "_" + DateTime.UtcNow.ToString("MMddyyyy_HHmmss") + "." +
                                        fileNameSplit[1];
                                    var path = config.Ftp.ArchivedPath + "/" + newFileName;

                                    item.MoveTo(path);
                                    isArchived = true;
                                }

                                var fres = new FtpClientResponseFile
                                {
                                    Status       = (copied && isArchived) ? FtpConstants.SuccessStatus : FtpConstants.FailureStatus,
                                    FileName     = fileName,
                                    ErrorMessage = (copied ? string.Empty : FtpConstants.BlobUploadError) + " " + (isArchived ? string.Empty : FtpConstants.ArchivedError)
                                };
                                response.FileData.Add(fres);
                            }
                        }
                        catch (Exception ex)
                        {
                            _logger.LogError(ex, $"{nameof(ActorSftpClient)} failed to process the file {item.Name}, copy: {copied}, archived {isArchived}. Error: {ex.Message}");
                        }
                    }
                }
                await Stop();
            }

            catch (Exception e)
            {
                response.ErrorMessage = response.ErrorMessage + e.Message;
                response.Status       = FtpConstants.FailureStatus;
                _logger.LogError(e, $"{nameof(ActorSftpClient)} failed to start creating the client of {config.Ftp.Host} : {e.Message}");
            }
            return(response);
        }
예제 #6
0
 public Task <FtpClientResponse> ReadAsync(FtpConfig config, Func <string, Task <string> > securePassword, Func <string, string, string, MemoryStream, bool> copyFileFunc)
 {
     throw new NotImplementedException();
 }
        public async Task <FtpClientResponse> ReadAsync(FtpConfig config, Func <string, Task <string> > securePasswordCallBack,
                                                        Func <string, string, string, MemoryStream, string, string, bool> copyFileFunc)
        {
            var response = new FtpClientResponse {
                ErrorMessage = FtpConstants.NoError, Status = FtpConstants.SuccessStatus, FileData = new List <FtpClientResponseFile>()
            };

            try
            {
                if (_ftpClient == null)
                {
                    await CreateFtpClientAsync(config, securePasswordCallBack);
                }
                else
                {
                    if (!_ftpClient.IsConnected)
                    {
                        await CreateFtpClientAsync(config, securePasswordCallBack);
                    }
                }

                var listOfFiles = _ftpPolicyRegistry.GetPolicy(FtpPolicyName.FtpCommandPolicy).Execute((context) => _ftpClient.GetListing(config.Ftp.Path).Where(f => f.Type == FtpFileSystemObjectType.File), new Polly.Context($"LIST_FILE_{config.Ftp.Path}"));

                //config.Ftp.ArchivedPath != config.Ftp.Path is delete mode
                if (!string.IsNullOrEmpty(config.Ftp.ArchivedPath) && config.Ftp.ArchivedPath != config.Ftp.Path)
                {
                    var folderExisted = _ftpClient.DirectoryExists(config.Ftp.ArchivedPath);
                    if (!folderExisted)
                    {
                        _ftpPolicyRegistry.GetPolicy(FtpPolicyName.FtpCommandPolicy).Execute((context) => _ftpClient.CreateDirectory(config.Ftp.ArchivedPath), new Polly.Context("CREATE_ARCHIVE_FOLDER"));
                    }
                }

                var resolvedStorageAccountKey =
                    await securePasswordCallBack.Invoke(config.AzureBlobStorage.StorageKeyVault);

                Parallel.ForEach(
                    listOfFiles,
                    new ParallelOptions {
                    MaxDegreeOfParallelism = config.Parellelism
                },
                    item =>
                {
                    try
                    {
                        var fileName = item.Name;
                        using (var istream = _ftpPolicyRegistry.GetPolicy(FtpPolicyName.FtpCommandPolicy).Execute((context) => _ftpClient.OpenRead(item.FullName), new Polly.Context($"READ_FILE_{item.FullName}")))
                        {
                            bool isArchived           = false;
                            MemoryStream memoryStream = new MemoryStream();
                            istream.CopyTo(memoryStream);
                            memoryStream.Position = 0;
                            //_telemetryLogger.TrackTrace<FtpActor>("", "[ActorFtpClient] Reading File " + item.FullName, SeverityLevel.Information);
                            var copied = copyFileFunc.Invoke(config.AzureBlobStorage.ContainerName,
                                                             fileName,
                                                             config.Retry.StorageRetryPolicy, memoryStream, config.AzureBlobStorage.StorageAccountName, resolvedStorageAccountKey);

                            if (copied && !string.IsNullOrEmpty(config.Ftp.ArchivedPath) && config.Ftp.ArchivedPath != config.Ftp.Path)
                            {
                                isArchived = _ftpPolicyRegistry.GetPolicy(FtpPolicyName.FtpCommandPolicy).Execute((context) => _ftpClient.MoveFile(item.FullName, config.Ftp.ArchivedPath + "\\" + item.Name, FtpExists.Overwrite), new Polly.Context("COPY_FILE_TO_ARCHIVE"));
                            }
                            else if (config.Ftp.ArchivedPath == config.Ftp.Path)
                            {
                                //delete mode
                                isArchived = _ftpPolicyRegistry.GetPolicy(FtpPolicyName.FtpCommandPolicy).Execute((context) =>
                                {
                                    _ftpClient.DeleteFile(item.FullName);
                                    return(true);
                                }, new Polly.Context("DELETE_FILE_TO_ARCHIVE"));
                            }

                            var fres = new FtpClientResponseFile
                            {
                                Status       = (copied && isArchived) ? FtpConstants.SuccessStatus : FtpConstants.FailureStatus,
                                FileName     = item.Name,
                                ErrorMessage = (copied ? string.Empty : FtpConstants.BlobUploadError) + " " + (isArchived ? string.Empty : FtpConstants.ArchivedError)
                            };

                            var properties = new Dictionary <string, string> {
                                { "payload", JsonConvert.SerializeObject(fres) }
                            };
                            //_telemetryLogger.TrackEvent("", EventConstant.FtpCustomEventName, properties);
                            response.FileData.Add(fres);
                        }
                    }
                    catch (Exception)
                    {
                        throw;
                    }
                }
                    );

                //_telemetryLogger.TrackMetric("", EventConstant.FtpCustomEventName, 1);
                await Stop();
            }
            catch (FtpNotConnectException e)
            {
                response.ErrorMessage = response.ErrorMessage + e.Message;
                response.Status       = FtpConstants.FailureStatus;
            }
            catch (FtpSecurityNotAvailableException e)
            {
                response.ErrorMessage = response.ErrorMessage + e.Message;
                response.Status       = FtpConstants.FailureStatus;
            }
            catch (Exception e)
            {
                response.ErrorMessage = response.ErrorMessage + e.Message;
                response.Status       = FtpConstants.FailureStatus;
            }
            return(response);
        }
예제 #8
0
        public async Task <FtpClientResponse> ReadAsync(FtpConfig config, Func <string, Task <string> > securePasswordCallBack,
                                                        Func <string, string, string, MemoryStream, string, string, bool> copyFileFunc)
        {
            var response = new FtpClientResponse {
                ErrorMessage = FtpConstants.NoError, Status = FtpConstants.SuccessStatus, FileData = new List <FtpClientResponseFile>()
            };

            try
            {
                await CreateFtpClientAsync(config, securePasswordCallBack);

                Func <FtpListItem, bool> predicate = f => f.Type == FtpFileSystemObjectType.File;
                if (!string.IsNullOrEmpty(config.Ftp.FilenameRegex))
                {
                    var rx = new Regex(config.Ftp.FilenameRegex, RegexOptions.IgnoreCase);
                    predicate = f => f.Type == FtpFileSystemObjectType.File && rx.IsMatch(f.Name);
                }

                var listOfFiles = _ftpPolicyRegistry.GetPolicy(FtpPolicyName.FtpCommandPolicy)
                                  .Execute((context) => _ftpClient.GetListing(config.Ftp.Path).Where(predicate), new Polly.Context($"LIST_FILE_{config.Ftp.Path}"));

                if (!string.IsNullOrEmpty(config.Ftp.ArchivedPath) && config.Ftp.ArchivedPath != config.Ftp.Path)
                {
                    var folderExisted = _ftpClient.DirectoryExists(config.Ftp.ArchivedPath);
                    if (!folderExisted)
                    {
                        _ftpPolicyRegistry.GetPolicy(FtpPolicyName.FtpCommandPolicy).Execute((context) => _ftpClient.CreateDirectory(config.Ftp.ArchivedPath), new Polly.Context("CREATE_ARCHIVE_FOLDER"));
                    }
                }

                var resolvedStorageAccountKey =
                    await securePasswordCallBack.Invoke(config.AzureBlobStorage.StorageKeyVault);

                foreach (var item in listOfFiles)
                {
                    bool copied     = false;
                    bool isArchived = false;
                    try
                    {
                        var fileName = item.Name;
                        using (var istream = await _ftpClient.OpenReadAsync(item.FullName))
                        {
                            MemoryStream memoryStream = new MemoryStream();
                            istream.CopyTo(memoryStream);
                            memoryStream.Position = 0;
                            copied = copyFileFunc.Invoke(config.AzureBlobStorage.ContainerName,
                                                         fileName,
                                                         config.Retry.StorageRetryPolicy, memoryStream, config.AzureBlobStorage.StorageAccountName, resolvedStorageAccountKey);
                        }
                        if (copied && !string.IsNullOrEmpty(config.Ftp.ArchivedPath) && config.Ftp.ArchivedPath != config.Ftp.Path)
                        {
                            isArchived = _ftpPolicyRegistry.GetPolicy(FtpPolicyName.FtpCommandPolicy).Execute((context) => _ftpClient.MoveFile(item.FullName, config.Ftp.ArchivedPath + "\\" + item.Name, FtpExists.Overwrite), new Polly.Context("COPY_FILE_TO_ARCHIVE"));
                        }
                        else if (config.Ftp.ArchivedPath == config.Ftp.Path)
                        {
                            //delete mode
                            isArchived = _ftpPolicyRegistry.GetPolicy(FtpPolicyName.FtpCommandPolicy).Execute((context) =>
                            {
                                _ftpClient.DeleteFile(item.FullName);
                                return(true);
                            }, new Polly.Context("DELETE_FILE_TO_ARCHIVE"));
                        }

                        var fres = new FtpClientResponseFile
                        {
                            Status       = (copied && isArchived) ? FtpConstants.SuccessStatus : FtpConstants.FailureStatus,
                            FileName     = item.Name,
                            ErrorMessage = (copied ? string.Empty : FtpConstants.BlobUploadError) + " " + (isArchived ? string.Empty : FtpConstants.ArchivedError)
                        };
                        response.FileData.Add(fres);
                    }
                    catch (Exception ex)
                    {
                        _logger.LogError(ex, $"ActorFtpClient failed to process the file {item.Name}, copy: {copied}, archived {isArchived}. Error: {ex.Message}");
                    }
                }
                await Stop();
            }
            catch (Exception e)
            {
                response.ErrorMessage = response.ErrorMessage + e.Message;
                response.Status       = FtpConstants.FailureStatus;
                _logger.LogError(e, $"ActorFtpClient failed to start creating the client of {config.Ftp.Host} : {e.Message}");
            }
            return(response);
        }
예제 #9
0
        public async Task <FtpClientResponse> ReadAsync(FtpConfig config, Func <string, Task <string> > securePasswordCallBack, Func <string, string, string, MemoryStream, bool> copyFileFunc)
        {
            var response = new FtpClientResponse {
                ErrorMessage = FtpConstants.NoError, Status = FtpConstants.SuccessStatus, FileData = new List <FtpClientResponseFile>()
            };

            try
            {
                await CreateFtpClientAsync(config, securePasswordCallBack);

                Func <FtpListItem, bool> predicate = f => f.Type == FtpFileSystemObjectType.File;
                if (!string.IsNullOrEmpty(config.Ftp.FilenameRegex))
                {
                    var rx = new Regex(config.Ftp.FilenameRegex, RegexOptions.IgnoreCase);
                    predicate = f => f.Type == FtpFileSystemObjectType.File && rx.IsMatch(f.Name);
                }

                var listOfFiles = _ftpPolicyRegistry.GetPolicy(FtpPolicyName.FtpCommandPolicy)
                                  .Execute((context) => _ftpClient.GetListing(config.Ftp.Path).Where(predicate), new Polly.Context($"LIST_FILE_{config.Ftp.Path}"));

                if (!string.IsNullOrEmpty(config.Ftp.ArchivedPath))
                {
                    var folderExisted = _ftpClient.DirectoryExists(config.Ftp.ArchivedPath);
                    if (!folderExisted)
                    {
                        _ftpPolicyRegistry.GetPolicy(FtpPolicyName.FtpCommandPolicy).Execute((context) => _ftpClient.CreateDirectory(config.Ftp.ArchivedPath), new Polly.Context("CREATE_ARCHIVE_FOLDER"));
                    }
                }

                Parallel.ForEach(
                    listOfFiles,
                    new ParallelOptions {
                    MaxDegreeOfParallelism = config.Parellelism
                },
                    item =>
                {
                    try
                    {
                        var fileName = item.FullName.Remove(0, 1);
                        using (var istream = _ftpPolicyRegistry.GetPolicy(FtpPolicyName.FtpCommandPolicy).Execute((context) => _ftpClient.OpenRead(fileName), new Polly.Context($"READ_FILE_{item.FullName}")))
                        {
                            bool isArchived           = false;
                            MemoryStream memoryStream = new MemoryStream();
                            istream.CopyTo(memoryStream);
                            memoryStream.Position = 0;
                            //_telemetryLogger.TrackTrace<FtpActor>("", "[ActorFtpClient] Reading File " + item.FullName, SeverityLevel.Information);
                            var copied = copyFileFunc.Invoke(config.AzureBlobStorage.ContainerName,
                                                             fileName,
                                                             config.Retry.StorageRetryPolicy, memoryStream);

                            if (copied && !string.IsNullOrEmpty(config.Ftp.ArchivedPath))
                            {
                                isArchived = _ftpPolicyRegistry.GetPolicy(FtpPolicyName.FtpCommandPolicy).Execute((context) => _ftpClient.MoveFile(item.FullName, config.Ftp.ArchivedPath + "\\" + item.Name, FtpExists.Overwrite), new Polly.Context("COPY_FILE_TO_ARCHIVE"));
                            }

                            var fres = new FtpClientResponseFile
                            {
                                Status       = (copied && isArchived) ? FtpConstants.SuccessStatus : FtpConstants.FailureStatus,
                                FileName     = item.Name,
                                ErrorMessage = (copied ? string.Empty : FtpConstants.BlobUploadError) + " " + (isArchived ? string.Empty : FtpConstants.ArchivedError)
                            };
                            response.FileData.Add(fres);
                        }
                    }
                    catch (Exception)
                    {
                        throw;
                    }
                }

                    );
                await Stop();
            }
            catch (FtpNotConnectException e)
            {
                response.ErrorMessage = response.ErrorMessage + e.Message;
                response.Status       = FtpConstants.FailureStatus;
            }
            catch (FtpSecurityNotAvailableException e)
            {
                response.ErrorMessage = response.ErrorMessage + e.Message;
                response.Status       = FtpConstants.FailureStatus;
            }
            catch (Exception e)
            {
                response.ErrorMessage = response.ErrorMessage + e.Message;
                response.Status       = FtpConstants.FailureStatus;
            }
            return(response);
        }
 public FtpWriterOption(FtpConfig ftpConfig, string writeData, string fileName) : base(ftpConfig)
 {
     WriteData = writeData;
     FileName  = fileName;
 }
예제 #11
0
 public FtpOption(FtpConfig ftpConfig)
 {
     FtpConfig = ftpConfig;
 }