Adding
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
namespace LCU.Api.Internal.FTP.Configuration;
|
||||
|
||||
public class EnvironmentView : IEnvironmentView
|
||||
{
|
||||
public string Application => _env.ApplicationName;
|
||||
public DateTime CurrentDate => DateTime.Now;
|
||||
public string BuildVersion => Assembly.GetExecutingAssembly().GetName().Version.ToString();
|
||||
public DateTime BuildDate => AssemblyBuildDate();
|
||||
public string Environment => _env.EnvironmentName;
|
||||
private readonly IWebHostEnvironment _env;
|
||||
|
||||
public EnvironmentView(IWebHostEnvironment env)
|
||||
{
|
||||
_env = env;
|
||||
}
|
||||
|
||||
public static DateTime AssemblyBuildDate()
|
||||
{
|
||||
//https://stackoverflow.com/a/804310/266594
|
||||
System.Reflection.Assembly assembly = System.Reflection.Assembly.GetExecutingAssembly();
|
||||
System.IO.FileInfo fileInfo = new System.IO.FileInfo(assembly.Location);
|
||||
DateTime lastModified = fileInfo.LastWriteTime;
|
||||
|
||||
return lastModified;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
namespace LCU.Api.Internal.FTP.Configuration;
|
||||
|
||||
public class FtpApiConfiguration
|
||||
{
|
||||
public int AttemptsLimit { get; set; }
|
||||
public Apis Apis { get; set; }
|
||||
}
|
||||
|
||||
public class Apis
|
||||
{
|
||||
public FileOperationApi FileOperationApi { get; set; }
|
||||
}
|
||||
public class FileOperationApi
|
||||
{
|
||||
public string BuildDynamicFileRequest { get; set; }
|
||||
public string ValidateFileExists { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
namespace LCU.Api.Internal.FTP.Configuration;
|
||||
|
||||
public interface IEnvironmentView
|
||||
{
|
||||
string Application { get; }
|
||||
DateTime CurrentDate { get; }
|
||||
string BuildVersion { get; }
|
||||
DateTime BuildDate { get; }
|
||||
string Environment { get; }
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Serilog;
|
||||
using MassTransit;
|
||||
using LCU.Api.Internal.FTP.Services;
|
||||
using LCU.Api.Internal.FTPLib.Models;
|
||||
using LCU.Library.Internal.Exceptions;
|
||||
using LCU.Api.Internal.MaidBotLib.Models;
|
||||
namespace LCU.Api.Internal.FTP.Consumers;
|
||||
|
||||
public class SftpConsumer : IConsumer<QueueRequest>
|
||||
{
|
||||
private readonly IServiceScopeFactory _scopeFactory;
|
||||
|
||||
public SftpConsumer(IServiceScopeFactory scopeFactory)
|
||||
{
|
||||
_scopeFactory = scopeFactory;
|
||||
}
|
||||
|
||||
public async Task Consume(ConsumeContext<QueueRequest> context)
|
||||
{
|
||||
try
|
||||
{
|
||||
using var scope = _scopeFactory.CreateScope();
|
||||
await Task.Run(() => scope.ServiceProvider.GetRequiredService<IFtpService>().HandleFtpRequest(context.Message));
|
||||
}
|
||||
catch (ServiceException)
|
||||
{
|
||||
//Masstransit handles the exception. https://masstransit-project.com/usage/exceptions.html#retry
|
||||
throw;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
|
||||
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
|
||||
.Fatal(exception, $"Unexpected Failure");
|
||||
//Masstransit handles the exception. https://masstransit-project.com/usage/exceptions.html#retry
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Serilog;
|
||||
using LCU.Api.Internal.FTP.Extensions;
|
||||
using LCU.Api.Internal.FTP.Helpers;
|
||||
using LCU.Api.Internal.FTP.Services;
|
||||
using LCU.Api.Internal.FTPLib.Models;
|
||||
using LCU.Api.Internal.FTP.Services.FtpOpertionServices;
|
||||
using LCU.Library.Internal.Exceptions;
|
||||
namespace LCU.Api.Internal.FTP.Controllers;
|
||||
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
public class SftpController : ControllerBase
|
||||
{
|
||||
private readonly IQueueFtpService _queueFtpService;
|
||||
private readonly IWinScpListDirectoryService _winScpSftpListDirectoryService;
|
||||
|
||||
public SftpController(IQueueFtpService queueFtpService,
|
||||
IWinScpListDirectoryService winScpSftpListDirectoryService)
|
||||
{
|
||||
_queueFtpService = queueFtpService;
|
||||
_winScpSftpListDirectoryService = winScpSftpListDirectoryService;
|
||||
}
|
||||
|
||||
[Obsolete("01/04/2022 - Please use QueueSftpUploadRequest Endpoint for Sftp Request and SshFtpController QueueSshFtpRequest Endpoint")]
|
||||
[HttpPost]
|
||||
[ProducesResponseType(201)]
|
||||
[ProducesResponseType(typeof(List<string>), 400)]
|
||||
[ProducesResponseType(500)]
|
||||
public IActionResult Post([FromBody] SftpRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
return BadRequest(ModelState.GetErrorMessages());
|
||||
}
|
||||
|
||||
if (!WinScpSessionOptionValidators.IsValidSessionOptions(request))
|
||||
{
|
||||
Log.Error("Sftp request can not be created into a valid session options.");
|
||||
return BadRequest("Sftp request can not be created into a valid session options.");
|
||||
}
|
||||
|
||||
|
||||
_queueFtpService.QueueSftp(request);
|
||||
return Ok();
|
||||
}
|
||||
catch (ServiceException)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete("01/04/2022 - Please use QueueSftpUploadRequest Endpoint")]
|
||||
[HttpPost("QueueSftpDynamicFileRequest")]
|
||||
[ProducesResponseType(201)]
|
||||
[ProducesResponseType(typeof(List<string>), 400)]
|
||||
[ProducesResponseType(500)]
|
||||
public IActionResult QueueSftpDynamicFileRequest([FromBody] SftpDynamicFileRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
return BadRequest(ModelState.GetErrorMessages());
|
||||
}
|
||||
|
||||
if (!WinScpSessionOptionValidators.IsValidSessionOptions(request))
|
||||
{
|
||||
return BadRequest("Sftp request can not be created into a valid session options.");
|
||||
}
|
||||
|
||||
_queueFtpService.QueueSftpDynamicFileRequest(request);
|
||||
return Ok();
|
||||
}
|
||||
catch (ServiceException)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost("QueueSftpUploadRequest")]
|
||||
[ProducesResponseType(201)]
|
||||
[ProducesResponseType(typeof(List<string>), 400)]
|
||||
[ProducesResponseType(500)]
|
||||
public IActionResult QueueSftpUploadRequest([FromBody] SftpUploadFileRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
return BadRequest(ModelState.GetErrorMessages());
|
||||
}
|
||||
|
||||
_queueFtpService.QueueSftpUploadRequest(request);
|
||||
return Ok();
|
||||
}
|
||||
catch (ServiceException)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost("QueueSftpDownloadRequest")]
|
||||
[ProducesResponseType(201)]
|
||||
[ProducesResponseType(typeof(List<string>), 400)]
|
||||
[ProducesResponseType(500)]
|
||||
public IActionResult QueueSftpDownloadRequest([FromBody] SftpDownloadFileRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
return BadRequest(ModelState.GetErrorMessages());
|
||||
}
|
||||
|
||||
_queueFtpService.QueueSftpDownloadRequest(request);
|
||||
return Ok();
|
||||
}
|
||||
catch (ServiceException)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet("ListFilesInDirectory")]
|
||||
[ProducesResponseType(201)]
|
||||
[ProducesResponseType(500)]
|
||||
public IActionResult ListFilesInDirectory([FromQuery] ListDirectoryRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
return BadRequest(ModelState.GetErrorMessages());
|
||||
}
|
||||
|
||||
var result = _winScpSftpListDirectoryService.GetListOfFilesInDirectory(request);
|
||||
return Ok(result);
|
||||
}
|
||||
catch (ServiceException)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using Serilog;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using LCU.Api.Internal.FTP.Extensions;
|
||||
using LCU.Api.Internal.FTP.Services;
|
||||
using LCU.Api.Internal.FTPLib.Models;
|
||||
using LCU.Library.Internal.Exceptions;
|
||||
namespace LCU.Api.Internal.FTP.Controllers;
|
||||
|
||||
[Route("[controller]")]
|
||||
[ApiController]
|
||||
public class SshFtpController : ControllerBase
|
||||
{
|
||||
private readonly IQueueSshFtpService _queueSshFtpService;
|
||||
|
||||
public SshFtpController(IQueueSshFtpService queueSshFtpService)
|
||||
{
|
||||
_queueSshFtpService = queueSshFtpService;
|
||||
}
|
||||
|
||||
[HttpPost("QueueSshFtpRequest")]
|
||||
[ProducesResponseType(201)]
|
||||
[ProducesResponseType(typeof(List<string>), 400)]
|
||||
[ProducesResponseType(500)]
|
||||
public IActionResult QueueSshFtpRequest([FromBody] SshFtpRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
return BadRequest(ModelState.GetErrorMessages());
|
||||
}
|
||||
|
||||
_queueSshFtpService.QueueSshFtpRequest(request);
|
||||
return Ok();
|
||||
}
|
||||
catch (ServiceException)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using System;
|
||||
using LCU.Api.Internal.FTP.Configuration;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Serilog;
|
||||
|
||||
namespace LCU.Api.Internal.FTP.Controllers;
|
||||
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
public class StatusController : ControllerBase
|
||||
{
|
||||
private readonly IEnvironmentView _environmentView;
|
||||
|
||||
public StatusController(IEnvironmentView environmentView)
|
||||
{
|
||||
_environmentView = environmentView;
|
||||
}
|
||||
|
||||
[HttpGet()]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(500)]
|
||||
public IActionResult Get()
|
||||
{
|
||||
try
|
||||
{
|
||||
return Ok(_environmentView);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, "Failure to return status");
|
||||
return StatusCode((int)System.Net.HttpStatusCode.InternalServerError);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||
|
||||
namespace LCU.Api.Internal.FTP.Extensions
|
||||
{
|
||||
public static class ModelStateMessages
|
||||
{
|
||||
public static List<string> GetErrorMessages(this ModelStateDictionary dictionary)
|
||||
{
|
||||
return dictionary.SelectMany(m => m.Value.Errors)
|
||||
.Select(m => m.ErrorMessage)
|
||||
.ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using LCU.Api.Internal.FTPLib.Models.Enums;
|
||||
using LCU.Api.Internal.FTPLib.Models;
|
||||
namespace LCU.Api.Internal.FTP.Helpers;
|
||||
|
||||
public class FtpRequestResponseHelper
|
||||
{
|
||||
public static FtpRequestResponse ExceptionUpdateRequestResponse(FtpRequestResponse requestResponse,
|
||||
FtpType ftpType,
|
||||
string exception)
|
||||
{
|
||||
requestResponse.IsSuccessful = false;
|
||||
requestResponse.MessageStack.Add($"Failure to execute ftp action. " +
|
||||
$"FtpType: {ftpType}, " +
|
||||
$"Exception: {exception} ");
|
||||
return requestResponse;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using LCU.Api.Internal.FTPLib.Models;
|
||||
namespace LCU.Api.Internal.FTP.Helpers;
|
||||
|
||||
[Obsolete("01/04/2022 - After the SftpController endpoints are no longer using this validation it can be removed. The model validation covers validation enough.")]
|
||||
public static class WinScpSessionOptionValidators
|
||||
{
|
||||
public static bool IsValidSessionOptions(SftpRequest sftpRequest)
|
||||
{
|
||||
if (!IsValidHostInfo(sftpRequest) || !IsValidFileInfo(sftpRequest))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return WinScpSessionOptionsHelper.CreateSessionOptions(sftpRequest) != null;
|
||||
}
|
||||
|
||||
private static bool IsValidFileInfo(SftpRequest sftpRequest)
|
||||
{
|
||||
return !string.IsNullOrWhiteSpace(sftpRequest.RemoteFilePath) &&
|
||||
(!string.IsNullOrWhiteSpace(sftpRequest.LocalFilePath) || sftpRequest.LocalFileData != null);
|
||||
}
|
||||
|
||||
private static bool IsValidHostInfo(SftpRequest sftpRequest)
|
||||
{
|
||||
return !string.IsNullOrWhiteSpace(sftpRequest.Password) &&
|
||||
!string.IsNullOrWhiteSpace(sftpRequest.UserName) &&
|
||||
!string.IsNullOrWhiteSpace(sftpRequest.HostName) && sftpRequest.PortNumber > 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
using System;
|
||||
using Serilog;
|
||||
using WinSCP;
|
||||
using LCU.Api.Internal.FTPLib.Models;
|
||||
namespace LCU.Api.Internal.FTP.Helpers;
|
||||
|
||||
public static class WinScpSessionOptionsHelper
|
||||
{
|
||||
public static SessionOptions CreateSessionOptions(SftpRequest sftpRequest)
|
||||
{
|
||||
try
|
||||
{
|
||||
var protocol = FindWinScpProtocol(sftpRequest.Protocol);
|
||||
|
||||
SessionOptions sessionOptions = new SessionOptions
|
||||
{
|
||||
Protocol = protocol,
|
||||
HostName = sftpRequest.HostName,
|
||||
PortNumber = sftpRequest.PortNumber,
|
||||
UserName = sftpRequest.UserName,
|
||||
Password = sftpRequest.Password,
|
||||
SshHostKeyFingerprint = sftpRequest.SshHostKeyFingerprint
|
||||
};
|
||||
|
||||
return sessionOptions;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Error creating SessionOptions for Sftp Request");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static SessionOptions CreateSessionOptions(SessionInformation sessionInformation)
|
||||
{
|
||||
try
|
||||
{
|
||||
var protocol = FindWinScpProtocol(sessionInformation.Protocol);
|
||||
|
||||
SessionOptions sessionOptions = new SessionOptions
|
||||
{
|
||||
Protocol = protocol,
|
||||
HostName = sessionInformation.HostName,
|
||||
PortNumber = sessionInformation.PortNumber,
|
||||
UserName = sessionInformation.UserName,
|
||||
Password = sessionInformation.Password,
|
||||
SshHostKeyFingerprint = sessionInformation.SshHostKeyFingerprint
|
||||
};
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(sessionInformation.SshKeyFilePath))
|
||||
{
|
||||
sessionOptions.SshPrivateKeyPath = sessionInformation.SshKeyFilePath;
|
||||
}
|
||||
|
||||
return sessionOptions;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Error creating SessionOptions for Sftp Request");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static Protocol FindWinScpProtocol(ProtocolType protocolType)
|
||||
{
|
||||
switch (protocolType)
|
||||
{
|
||||
case ProtocolType.Sftp:
|
||||
return Protocol.Sftp;
|
||||
default:
|
||||
return Protocol.Sftp;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
|
||||
<PackageVersion>1.1.0</PackageVersion>
|
||||
<PackageReleaseNotes>1.1.0 - Added GUID, byte[] upload, refactoring, tests</PackageReleaseNotes>
|
||||
<Version>1.0.0</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DocumentationFile>C:\dev\projects\LCU.API.Internal.FTP\LCU.Api.Internal.FTP\LCU.Api.Internal.FTP.xml</DocumentationFile>
|
||||
<NoWarn>1701;1702;1591</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<DocumentationFile>C:\dev\projects\LCU.API.Internal.FTP\LCU.Api.Internal.FTP\LCU.Api.Internal.FTP.xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="LCU.Api.Internal.MaidBotLib" Version="1.0.0" />
|
||||
<PackageReference Include="LCU.Library.Internal.ApiResponse" Version="3.3.0" />
|
||||
<PackageReference Include="LCU.Library.Internal.Exceptions" Version="1.0.0" />
|
||||
<PackageReference Include="LCU.Library.Internal.LcuMassTransit" Version="1.0.0" />
|
||||
<PackageReference Include="LCU.Library.Internal.LcuMassTransitModels" Version="1.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="3.1.10" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.2.3" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="Serilog" Version="2.10.0" />
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="3.4.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Async" Version="1.4.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />
|
||||
<PackageReference Include="Serilog.Sinks.Seq" Version="4.0.0" />
|
||||
<PackageReference Include="SSH.NET" Version="2020.0.1" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.6.3" />
|
||||
<PackageReference Include="WinSCP" Version="5.17.8" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\LCU.Api.Internal.FTPLib\LCU.Api.Internal.FTPLib.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Properties\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0"?>
|
||||
<doc>
|
||||
<assembly>
|
||||
<name>LCU.Api.Internal.FTP</name>
|
||||
</assembly>
|
||||
<members>
|
||||
</members>
|
||||
</doc>
|
||||
@@ -0,0 +1,20 @@
|
||||
using Microsoft.AspNetCore;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Serilog;
|
||||
|
||||
namespace LCU.Api.Internal.FTP
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
var host = CreateWebHost(args);
|
||||
host.Run();
|
||||
}
|
||||
|
||||
public static IWebHost CreateWebHost(string[] args) =>
|
||||
WebHost.CreateDefaultBuilder(args).UseSerilog((hostingContext, loggerConfiguration) => loggerConfiguration
|
||||
.ReadFrom.Configuration(hostingContext.Configuration))
|
||||
.UseStartup<Startup>().Build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
|
||||
namespace LCU.Api.Internal.FTP.Security
|
||||
{
|
||||
public class AzureActiveDirectoryOptions
|
||||
{
|
||||
public string ClientId { get; set; }
|
||||
public string ClientSecret { get; set; }
|
||||
public string Instance { get; set; }
|
||||
public string Domain { get; set; }
|
||||
public string TenantId { get; set; }
|
||||
public string ValidAudience { get; set; }
|
||||
}
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
|
||||
namespace LCU.Api.Internal.FTP.Security
|
||||
{
|
||||
public static class AzureAdServiceCollectionExtensions
|
||||
{
|
||||
public static AuthenticationBuilder AddAzureAdBearer(this AuthenticationBuilder builder)
|
||||
=> builder.AddAzureAdBearer(_ => { });
|
||||
|
||||
public static AuthenticationBuilder AddAzureAdBearer(this AuthenticationBuilder builder, Action<AzureActiveDirectoryOptions> configureOptions)
|
||||
{
|
||||
builder.Services.Configure(configureOptions);
|
||||
builder.Services.AddSingleton<IConfigureOptions<JwtBearerOptions>, ConfigureAzureOptions>();
|
||||
builder.AddJwtBearer();
|
||||
return builder;
|
||||
}
|
||||
|
||||
private class ConfigureAzureOptions : IConfigureNamedOptions<JwtBearerOptions>
|
||||
{
|
||||
private readonly AzureActiveDirectoryOptions _azureOptions;
|
||||
|
||||
public ConfigureAzureOptions(IOptions<AzureActiveDirectoryOptions> azureOptions)
|
||||
{
|
||||
_azureOptions = azureOptions.Value;
|
||||
}
|
||||
|
||||
public void Configure(string name, JwtBearerOptions options)
|
||||
{
|
||||
options.Audience = _azureOptions.ClientId;
|
||||
options.Authority = $"{_azureOptions.Instance}{_azureOptions.TenantId}";
|
||||
|
||||
options.TokenValidationParameters = new TokenValidationParameters
|
||||
{
|
||||
ValidAudience = _azureOptions.ValidAudience
|
||||
};
|
||||
}
|
||||
|
||||
public void Configure(JwtBearerOptions options)
|
||||
{
|
||||
Configure(Options.DefaultName, options);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+116
@@ -0,0 +1,116 @@
|
||||
using Newtonsoft.Json;
|
||||
using Serilog;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using LCU.Library.Internal.FileOperationsModels.Models;
|
||||
using LCU.Api.Internal.FTP.Configuration;
|
||||
using LCU.Api.Internal.FTPLib.Models;
|
||||
using LCU.Library.Internal.Exceptions;
|
||||
using System.Linq;
|
||||
|
||||
namespace LCU.Api.Internal.FTP.Services.FtpOpertionServices;
|
||||
|
||||
public class FileOperationsService : IFileOperationsService
|
||||
{
|
||||
private readonly IHttpClientFactory _httpFactory;
|
||||
private readonly FtpApiConfiguration _ftpApiConfiguration;
|
||||
|
||||
public FileOperationsService(IHttpClientFactory httpFactory, FtpApiConfiguration ftpApiConfiguration)
|
||||
{
|
||||
|
||||
_httpFactory = httpFactory;
|
||||
_ftpApiConfiguration = ftpApiConfiguration;
|
||||
|
||||
}
|
||||
public async Task<List<string>> GetListOfFilesInDirectory(SftpUploadFileRequest uploadRequest)
|
||||
{
|
||||
List<string> files = new List<string>();
|
||||
try
|
||||
{
|
||||
var shouldBuildDynamicFileRequest = uploadRequest?.DynamicNameSetting?.RegexSettings != null && uploadRequest.DynamicNameSetting.RegexSettings.Any();
|
||||
if (shouldBuildDynamicFileRequest)
|
||||
{
|
||||
files = await BuildDynamicFileRequest(uploadRequest);
|
||||
}
|
||||
else
|
||||
{
|
||||
files = await ValidateFileExists(uploadRequest);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, "Error Generating File List");
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
public async Task<List<string>> BuildDynamicFileRequest(SftpUploadFileRequest uploadRequest)
|
||||
{
|
||||
List<string> files = new List<string>();
|
||||
try
|
||||
{
|
||||
var dynamicFileRequest = new DynamicFileListRequest()
|
||||
{
|
||||
Filename = uploadRequest.FinalLocalFileName,
|
||||
DynamicFileSettings = uploadRequest.DynamicNameSetting,
|
||||
Path = uploadRequest.FinalLocalFilePath.EndsWith("\\") ? uploadRequest.FinalLocalFilePath : $"{uploadRequest.FinalLocalFilePath}\\"
|
||||
};
|
||||
|
||||
var encodedContent = JsonConvert.SerializeObject(dynamicFileRequest);
|
||||
var content = new StringContent(encodedContent, Encoding.UTF8, "application/json");
|
||||
var client = _httpFactory.CreateClient();
|
||||
HttpResponseMessage response = await client.PostAsync(_ftpApiConfiguration.Apis.FileOperationApi.BuildDynamicFileRequest, content);
|
||||
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
throw new ServiceException($"StatusCode:{response.StatusCode}, " +
|
||||
$"Content: {response.Content.ReadAsStringAsync().Result}");
|
||||
}
|
||||
|
||||
var jsonString = await response.Content.ReadAsStringAsync();
|
||||
files = JsonConvert.DeserializeObject<List<string>>(jsonString);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, "Error Building Dynamic File List");
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
public async Task<List<string>> ValidateFileExists(SftpUploadFileRequest uploadRequest)
|
||||
{
|
||||
List<string> files = new List<string>();
|
||||
try
|
||||
{
|
||||
var path = uploadRequest.FinalLocalFilePath.EndsWith("\\") ? uploadRequest.FinalLocalFilePath : $"{uploadRequest.FinalLocalFilePath}\\";
|
||||
var finalFilePath = $"{path}{uploadRequest.FinalLocalFileName}";
|
||||
|
||||
var encodedContent = JsonConvert.SerializeObject(finalFilePath);
|
||||
var content = new StringContent(encodedContent, Encoding.UTF8, "application/json");
|
||||
var client = _httpFactory.CreateClient();
|
||||
HttpResponseMessage response = await client.PostAsync(_ftpApiConfiguration.Apis.FileOperationApi.ValidateFileExists, content);
|
||||
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
throw new ServiceException($"StatusCode:{response.StatusCode}, " +
|
||||
$"Content: {response.Content.ReadAsStringAsync().Result}");
|
||||
}
|
||||
|
||||
var jsonString = await response.Content.ReadAsStringAsync();
|
||||
var result = JsonConvert.DeserializeObject<bool>(jsonString);
|
||||
if (result)
|
||||
{
|
||||
files.Add(uploadRequest.FinalLocalFileName);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, "Error Validating if File Exist");
|
||||
}
|
||||
return files;
|
||||
}
|
||||
}
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using LCU.Api.Internal.FTPLib.Models;
|
||||
|
||||
namespace LCU.Api.Internal.FTP.Services.FtpOpertionServices
|
||||
{
|
||||
public interface IFileOperationsService
|
||||
{
|
||||
Task<List<string>> GetListOfFilesInDirectory(SftpUploadFileRequest uploadRequest);
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
using LCU.Api.Internal.FTPLib.Models;
|
||||
namespace LCU.Api.Internal.FTP.Services.FtpOpertionServices;
|
||||
|
||||
public interface ISshFtpService
|
||||
{
|
||||
FtpRequestResponse ExecuteAction(QueueRequest queueRequest);
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
using LCU.Api.Internal.FTPLib.Models;
|
||||
using System.Collections.Generic;
|
||||
namespace LCU.Api.Internal.FTP.Services.FtpOpertionServices;
|
||||
|
||||
public interface IWinScpListDirectoryService
|
||||
{
|
||||
List<string> GetListOfFilesInDirectory(ListDirectoryRequest listDirectoryRequest);
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
using LCU.Api.Internal.FTPLib.Models;
|
||||
namespace LCU.Api.Internal.FTP.Services.FtpOpertionServices;
|
||||
|
||||
public interface IWinScpSftpDownloadFilesService
|
||||
{
|
||||
FtpRequestResponse ExecuteAction(QueueRequest queueRequest);
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
using LCU.Api.Internal.FTPLib.Models;
|
||||
namespace LCU.Api.Internal.FTP.Services.FtpOpertionServices;
|
||||
|
||||
public interface IWinScpSftpUploadFileService
|
||||
{
|
||||
FtpRequestResponse ExecuteAction(QueueRequest queueRequest);
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using Renci.SshNet;
|
||||
using Serilog;
|
||||
using Newtonsoft.Json;
|
||||
using LCU.Api.Internal.FTPLib.Models;
|
||||
namespace LCU.Api.Internal.FTP.Services.FtpOpertionServices;
|
||||
|
||||
public class SshFtpService : ISshFtpService
|
||||
{
|
||||
public FtpRequestResponse ExecuteAction(QueueRequest queueRequest)
|
||||
{
|
||||
var ftpRequestResponse = new FtpRequestResponse();
|
||||
try
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(queueRequest);
|
||||
var request = JsonConvert.DeserializeObject<SshFtpRequest>(queueRequest.Request);
|
||||
ArgumentNullException.ThrowIfNull(request);
|
||||
ftpRequestResponse.ReturnResponse = request;
|
||||
TransferFiles(request);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
ftpRequestResponse.IsSuccessful = false;
|
||||
ftpRequestResponse.MessageStack.Add(exception.Message);
|
||||
}
|
||||
return ftpRequestResponse;
|
||||
}
|
||||
|
||||
public void TransferFiles(SshFtpRequest request)
|
||||
{
|
||||
using var client = new SftpClient(request.HostName,
|
||||
request.PortNumber == 0 ? 22 : request.PortNumber,
|
||||
request.UserName, request.Password);
|
||||
|
||||
try
|
||||
{
|
||||
client.Connect();
|
||||
using var stream = new MemoryStream(request.LocalFileData);
|
||||
client.UploadFile(stream, request.RemoteFilePath);
|
||||
Log.Information(
|
||||
$"Uploaded [{request.RemoteFilePath}]");
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
throw new Exception($"Failed uploading [{request.RemoteFilePath}]" +
|
||||
$"ExceptionMessage: {exception.Message}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
client.Disconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using Serilog;
|
||||
using WinSCP;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using LCU.Api.Internal.FTPLib.Models;
|
||||
using LCU.Api.Internal.FTP.Helpers;
|
||||
namespace LCU.Api.Internal.FTP.Services.FtpOpertionServices;
|
||||
|
||||
public class WinScpListDirectoryService : IWinScpListDirectoryService
|
||||
{
|
||||
private const char FileTypeFiles = '-';
|
||||
|
||||
public List<string> GetListOfFilesInDirectory(ListDirectoryRequest listDirectoryRequest)
|
||||
{
|
||||
try
|
||||
{
|
||||
var remoteDirectoryInfo = GetRemoteDirectoryInfo(listDirectoryRequest);
|
||||
var fileNamesInDirectory = remoteDirectoryInfo.Files.Where(file => file.FileType == FileTypeFiles)
|
||||
.Select(file => file.Name)
|
||||
.ToList();
|
||||
return fileNamesInDirectory;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, $"Failed to get directory list with WinSCP. " +
|
||||
$"Host: {listDirectoryRequest.SessionInformation.HostName}, " +
|
||||
$"RemotePath: {listDirectoryRequest.RemotePath}");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public RemoteDirectoryInfo GetRemoteDirectoryInfo(ListDirectoryRequest listDirectoryRequest)
|
||||
{
|
||||
RemoteDirectoryInfo remoteDirectoryInfo = null;
|
||||
try
|
||||
{
|
||||
var sessionOptions = WinScpSessionOptionsHelper.CreateSessionOptions(listDirectoryRequest.SessionInformation);
|
||||
using (var session = new Session())
|
||||
{
|
||||
session.Open(sessionOptions);
|
||||
var transferOptions = new TransferOptions { TransferMode = TransferMode.Binary, PreserveTimestamp = false };
|
||||
remoteDirectoryInfo = session.ListDirectory(listDirectoryRequest.RemotePath);
|
||||
ArgumentNullException.ThrowIfNull(remoteDirectoryInfo);
|
||||
}
|
||||
|
||||
return remoteDirectoryInfo;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, $"Failed to get directory list with WinSCP. " +
|
||||
$"Host: {listDirectoryRequest.SessionInformation.HostName}, " +
|
||||
$"RemotePath: {listDirectoryRequest.RemotePath}");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
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<SftpDownloadFileRequest>(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<string> 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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
using Newtonsoft.Json;
|
||||
using Serilog;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using WinSCP;
|
||||
using LCU.Api.Internal.FTPLib.Models;
|
||||
using LCU.Api.Internal.FTP.Helpers;
|
||||
|
||||
namespace LCU.Api.Internal.FTP.Services.FtpOpertionServices;
|
||||
|
||||
public class WinScpSftpUploadFileService : IWinScpSftpUploadFileService
|
||||
{
|
||||
IFileOperationsService _fileOperationsService;
|
||||
|
||||
public WinScpSftpUploadFileService(IFileOperationsService fileOperationsService)
|
||||
{
|
||||
_fileOperationsService = fileOperationsService;
|
||||
}
|
||||
|
||||
public FtpRequestResponse ExecuteAction(QueueRequest queueRequest)
|
||||
{
|
||||
var ftpRequestResponse = new FtpRequestResponse();
|
||||
try
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(queueRequest);
|
||||
var request = JsonConvert.DeserializeObject<SftpUploadFileRequest>(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(SftpUploadFileRequest winScpUploadFileRequest, FtpRequestResponse ftpRequestResponse)
|
||||
{
|
||||
try
|
||||
{
|
||||
var filesInDirectory = _fileOperationsService.GetListOfFilesInDirectory(winScpUploadFileRequest).Result;
|
||||
if (!filesInDirectory.Any())
|
||||
{
|
||||
ftpRequestResponse.MessageStack.Add($"No files available to be uploaded. " +
|
||||
$"RegexFileName: {winScpUploadFileRequest.LocalFileName}. " +
|
||||
$"Succeed On Empty?: {winScpUploadFileRequest.SucceedOnEmpty}");
|
||||
ftpRequestResponse.IsSuccessful = winScpUploadFileRequest.SucceedOnEmpty;
|
||||
return ftpRequestResponse;
|
||||
}
|
||||
var sessionOptions = WinScpSessionOptionsHelper.CreateSessionOptions(winScpUploadFileRequest.SessionInformation);
|
||||
WinScpFile(sessionOptions, winScpUploadFileRequest.FinalLocalFilePath, winScpUploadFileRequest.FinalRemoteFilePath, filesInDirectory, winScpUploadFileRequest.ResumeSupportStateOn);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
ftpRequestResponse.MessageStack.Add($"Failed to upload file with WinSCP. " +
|
||||
$"Host: {winScpUploadFileRequest.SessionInformation.HostName}, " +
|
||||
$"File: {winScpUploadFileRequest.FinalLocalFilePath}" +
|
||||
$"ExceptionMessage: {exception.Message}");
|
||||
ftpRequestResponse.IsSuccessful = false;
|
||||
}
|
||||
|
||||
return ftpRequestResponse;
|
||||
}
|
||||
|
||||
private void WinScpFile(SessionOptions sessionOptions, string filePath, string RemotePath, List<string> localFileNames, bool supportStateOn)
|
||||
{
|
||||
using (var session = new Session())
|
||||
{
|
||||
session.Open(sessionOptions);
|
||||
var transferOptions = new TransferOptions { TransferMode = TransferMode.Binary, PreserveTimestamp = false };
|
||||
|
||||
if(!supportStateOn)
|
||||
{
|
||||
transferOptions.ResumeSupport.State = TransferResumeSupportState.Off;
|
||||
}
|
||||
|
||||
var addedSlash = filePath.EndsWith(@"\") ? "" : @"\";
|
||||
foreach (string fileName in localFileNames)
|
||||
{
|
||||
var localfilePath = $"{filePath}{addedSlash}{fileName}";
|
||||
var transferResult = session.PutFiles(localfilePath, RemotePath, false, transferOptions);
|
||||
|
||||
transferResult.Check();
|
||||
foreach (TransferEventArgs transfer in transferResult.Transfers)
|
||||
{
|
||||
Log.Debug($"Upload of {transfer.FileName} succeeded");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
using System;
|
||||
using Serilog;
|
||||
using LCU.Library.Internal.ApiResponse.Services;
|
||||
using LCU.Api.Internal.FTP.Configuration;
|
||||
using LCU.Api.Internal.FTPLib.Models.Enums;
|
||||
using LCU.Api.Internal.FTP.Services.FtpOpertionServices;
|
||||
using LCU.Api.Internal.FTPLib.Models;
|
||||
using LCU.Api.Internal.FTP.Helpers;
|
||||
using LCU.Library.Internal.Exceptions;
|
||||
namespace LCU.Api.Internal.FTP.Services;
|
||||
|
||||
public class FtpService : IFtpService
|
||||
{
|
||||
private readonly IQueueFtpService _queueSftpService;
|
||||
private readonly IWinScpSftpUploadFileService _winScpSftpUploadFilesService;
|
||||
private readonly IWinScpSftpDownloadFilesService _winScpSftpDownloadFilesService;
|
||||
private readonly ISshFtpService _sshFtpService;
|
||||
private readonly FtpApiConfiguration _ftpApiConfiguration;
|
||||
|
||||
public FtpService(IQueueFtpService queueSftpService,
|
||||
IWinScpSftpUploadFileService winScpSftpUploadFilesService,
|
||||
IWinScpSftpDownloadFilesService winScpSftpDownloadFilesService,
|
||||
ISshFtpService sshFtpService,
|
||||
FtpApiConfiguration ftpApiConfiguration)
|
||||
{
|
||||
_queueSftpService = queueSftpService;
|
||||
_winScpSftpUploadFilesService = winScpSftpUploadFilesService;
|
||||
_winScpSftpDownloadFilesService = winScpSftpDownloadFilesService;
|
||||
_sshFtpService = sshFtpService;
|
||||
_ftpApiConfiguration = ftpApiConfiguration;
|
||||
}
|
||||
|
||||
public void HandleFtpRequest(QueueRequest queueRequest)
|
||||
{
|
||||
var result = PerformFtpOperation(queueRequest);
|
||||
|
||||
if (ShouldPerformFtpRequestAgain(queueRequest, result))
|
||||
{
|
||||
Log.Information($"Attempting to requeue ftp request. FtpType: {queueRequest.FtpType}");
|
||||
queueRequest.Attempts++;
|
||||
_queueSftpService.QueueFtpRequest(queueRequest);
|
||||
return;
|
||||
}
|
||||
|
||||
QueueReturnResponse.QueueResponse(result.ReturnResponse, result.IsSuccessful, result.MessageStack);
|
||||
|
||||
if (!result.IsSuccessful)
|
||||
{
|
||||
var errorMessage = String.Join("; ", result.MessageStack.ToArray());
|
||||
Log.Error($"Ftp Request was not successful. MessageStack:{errorMessage}");
|
||||
throw new ServiceException($"Ftp Request was not successful. MessageStack:{errorMessage}");
|
||||
}
|
||||
}
|
||||
|
||||
public FtpRequestResponse PerformFtpOperation(QueueRequest queueRequest)
|
||||
{
|
||||
var ftpRequestResponse = new FtpRequestResponse();
|
||||
try
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(queueRequest);
|
||||
|
||||
ftpRequestResponse = queueRequest.FtpType switch
|
||||
{
|
||||
FtpType.WinScpSftpUpload => _winScpSftpUploadFilesService.ExecuteAction(queueRequest),
|
||||
FtpType.WinScpSftpDownload => _winScpSftpDownloadFilesService.ExecuteAction(queueRequest),
|
||||
FtpType.SshFtp => _sshFtpService.ExecuteAction(queueRequest),
|
||||
_ => throw new NotImplementedException()
|
||||
};
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var failureMessage = $"Failed to perform ftp request.";
|
||||
Log.Error(exception, failureMessage);
|
||||
|
||||
var fileOperationType = queueRequest?.FtpType;
|
||||
if (fileOperationType == null)
|
||||
{
|
||||
ftpRequestResponse.MessageStack.Add($"{failureMessage}. FtpType is Null. " +
|
||||
$"ExceptionMessage: {exception.Message}");
|
||||
return ftpRequestResponse;
|
||||
}
|
||||
|
||||
ftpRequestResponse = FtpRequestResponseHelper.ExceptionUpdateRequestResponse(ftpRequestResponse, queueRequest.FtpType, exception.Message);
|
||||
}
|
||||
|
||||
return ftpRequestResponse;
|
||||
}
|
||||
|
||||
public bool ShouldPerformFtpRequestAgain(QueueRequest request, FtpRequestResponse ftpRequestResponse)
|
||||
{
|
||||
return !ftpRequestResponse.IsSuccessful &&
|
||||
request.Attempts != null &&
|
||||
request.Attempts < _ftpApiConfiguration.AttemptsLimit;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
using System.Threading;
|
||||
using LCU.Api.Internal.FTPLib.Models;
|
||||
namespace LCU.Api.Internal.FTP.Services;
|
||||
|
||||
public interface IFtpService
|
||||
{
|
||||
void HandleFtpRequest(QueueRequest queueRequest);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using LCU.Api.Internal.FTPLib.Models;
|
||||
namespace LCU.Api.Internal.FTP.Services;
|
||||
|
||||
public interface IQueueFtpService
|
||||
{
|
||||
[Obsolete("01/04/2022 - After the SftpController endpoints are no longer in use this can be removed.")]
|
||||
void QueueSftp(SftpRequest request);
|
||||
[Obsolete("01/04/2022 - After the SftpController endpoints are no longer in use this can be removed.")]
|
||||
void QueueSftpDynamicFileRequest(SftpDynamicFileRequest sftpDynamicFileRequest);
|
||||
void QueueSftpUploadRequest(SftpUploadFileRequest winScpUploadFileRequest);
|
||||
void QueueSftpDownloadRequest(SftpDownloadFileRequest winScpDownloadFileRequest);
|
||||
void QueueFtpRequest(QueueRequest queueRequest);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
using LCU.Api.Internal.FTPLib.Models;
|
||||
namespace LCU.Api.Internal.FTP.Services;
|
||||
|
||||
public interface IQueueSshFtpService
|
||||
{
|
||||
void QueueSshFtpRequest(SshFtpRequest request);
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
using Serilog;
|
||||
using MassTransit;
|
||||
using LCU.Api.Internal.FTP.Configuration;
|
||||
using LCU.Api.Internal.FTPLib.Models.Enums;
|
||||
using LCU.Api.Internal.FTPLib.Models;
|
||||
using LCU.Library.Internal.Exceptions;
|
||||
using LCU.Library.Internal.LcuMassTransitModels;
|
||||
namespace LCU.Api.Internal.FTP.Services;
|
||||
|
||||
public class QueueFtpService : IQueueFtpService
|
||||
{
|
||||
private readonly IQueueSshFtpService _queueSshFtpService;
|
||||
private readonly ISendEndpoint _sendEndpoint;
|
||||
|
||||
public QueueFtpService(IQueueSshFtpService queueSshFtpService,
|
||||
IBusControl busControl,
|
||||
ReceiveEndpointConfiguration receiveEndpointsConfiguration)
|
||||
{
|
||||
_queueSshFtpService = queueSshFtpService;
|
||||
_sendEndpoint = busControl.GetSendEndpoint(receiveEndpointsConfiguration.ReceiveEndpointUri).Result;
|
||||
}
|
||||
|
||||
[Obsolete("01/04/2022 - After the SftpController endpoints that call this method are no longer in use this can be removed.")]
|
||||
public void QueueSftp(SftpRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
//If it has localfiledata then we need to use sshftp to accommodate old endpoints.
|
||||
if (request.LocalFileData != null && request.LocalFileData.Length > 0)
|
||||
{
|
||||
var sshFtpRequest = new SshFtpRequest()
|
||||
{
|
||||
Protocol = request.Protocol,
|
||||
HostName = request.HostName,
|
||||
PortNumber = request.PortNumber,
|
||||
UserName = request.UserName,
|
||||
Password = request.Password,
|
||||
RemoteFilePath = request.RemoteFilePath,
|
||||
LocalFileData = request.LocalFileData
|
||||
};
|
||||
|
||||
_queueSshFtpService.QueueSshFtpRequest(sshFtpRequest);
|
||||
return;
|
||||
}
|
||||
|
||||
var winScpUploadFileRequest = new SftpUploadFileRequest()
|
||||
{
|
||||
SessionInformation = new SessionInformation()
|
||||
{
|
||||
Protocol = request.Protocol,
|
||||
HostName = request.HostName,
|
||||
PortNumber = request.PortNumber,
|
||||
UserName = request.UserName,
|
||||
Password = request.Password,
|
||||
SshHostKeyFingerprint = request.SshHostKeyFingerprint
|
||||
},
|
||||
LocalFilePath = request.LocalFilePath,
|
||||
LocalFileName = null,
|
||||
RemoteFilePath = request.RemoteFilePath,
|
||||
DynamicNameSetting = null,
|
||||
ResponseItems = request.ResponseItems
|
||||
};
|
||||
|
||||
var queueRequest = new QueueRequest()
|
||||
{
|
||||
Request = JsonConvert.SerializeObject(winScpUploadFileRequest),
|
||||
FtpType = FtpType.WinScpSftpUpload
|
||||
};
|
||||
|
||||
_sendEndpoint.Send(queueRequest);
|
||||
Log.Debug($"Queued The Following Sftp Request {request}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, $"Failed to Queue Sftp Request. Request: {request}");
|
||||
throw new ServiceException($"Failed to Queue Sftp Request. Request: {request}");
|
||||
}
|
||||
}
|
||||
|
||||
[Obsolete("01/04/2022 - After the SftpController endpoints that call this method are no longer in use this can be removed.")]
|
||||
public void QueueSftpDynamicFileRequest(SftpDynamicFileRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
var winScpUploadFileRequest = new SftpUploadFileRequest()
|
||||
{
|
||||
SessionInformation = new SessionInformation()
|
||||
{
|
||||
Protocol = request.Protocol,
|
||||
HostName = request.HostName,
|
||||
PortNumber = request.PortNumber,
|
||||
UserName = request.UserName,
|
||||
Password = request.Password,
|
||||
SshHostKeyFingerprint = request.SshHostKeyFingerprint
|
||||
},
|
||||
LocalFilePath = request.LocalFilePath,
|
||||
LocalFileName = request.LocalFileName,
|
||||
RemoteFilePath = request.RemoteFilePath,
|
||||
DynamicNameSetting = request.DynamicNameSetting,
|
||||
ResponseItems = request.ResponseItems
|
||||
};
|
||||
|
||||
var queueRequest = new QueueRequest()
|
||||
{
|
||||
Request = JsonConvert.SerializeObject(winScpUploadFileRequest),
|
||||
FtpType = FtpType.WinScpSftpUpload
|
||||
};
|
||||
|
||||
_sendEndpoint.Send(queueRequest);
|
||||
Log.Debug($"Queued The Following Sftp Request to host {request.HostName}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, $"Failed to Queue Sftp dynamic file request. " +
|
||||
$"Host: {request.HostName}");
|
||||
throw new ServiceException($"Failed to Queue Sftp dynamic file request. " +
|
||||
$"Host: {request.HostName}");
|
||||
}
|
||||
}
|
||||
|
||||
public void QueueSftpUploadRequest(SftpUploadFileRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
var queueRequest = new QueueRequest()
|
||||
{
|
||||
Request = JsonConvert.SerializeObject(request),
|
||||
FtpType = FtpType.WinScpSftpUpload
|
||||
};
|
||||
|
||||
_sendEndpoint.Send(queueRequest);
|
||||
Log.Debug($"Queued sftp upload request to " +
|
||||
$"host {request.SessionInformation.HostName}");
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, $"Failed to Queue Sftp Upload Request. " +
|
||||
$"Host: {request.SessionInformation.HostName}");
|
||||
throw new ServiceException($"Failed to Queue Sftp Upload Request. " +
|
||||
$"Host: {request.SessionInformation.HostName}");
|
||||
}
|
||||
}
|
||||
|
||||
public void QueueSftpDownloadRequest(SftpDownloadFileRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
var queueRequest = new QueueRequest()
|
||||
{
|
||||
Request = JsonConvert.SerializeObject(request),
|
||||
FtpType = FtpType.WinScpSftpDownload
|
||||
};
|
||||
|
||||
_sendEndpoint.Send(queueRequest);
|
||||
Log.Debug($"Queued sftp download request from " +
|
||||
$"host {request.SessionInformation.HostName}");
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, $"Failed to Queue Sftp Download Request. " +
|
||||
$"Host: {request.SessionInformation.HostName}");
|
||||
throw new ServiceException($"Failed to Queue Sftp Download Request. " +
|
||||
$"Host: {request.SessionInformation.HostName}");
|
||||
}
|
||||
}
|
||||
|
||||
public void QueueFtpRequest(QueueRequest queueRequest)
|
||||
{
|
||||
try
|
||||
{
|
||||
_sendEndpoint.Send(queueRequest);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, $"Failed to Queue ftp request. FtpType: {queueRequest.FtpType}");
|
||||
throw new ServiceException($"Failed to Queue ftp request. FtpType: {queueRequest.FtpType}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using Newtonsoft.Json;
|
||||
using Serilog;
|
||||
using MassTransit;
|
||||
using LCU.Api.Internal.FTP.Configuration;
|
||||
using LCU.Api.Internal.FTPLib.Models.Enums;
|
||||
using LCU.Api.Internal.FTPLib.Models;
|
||||
using LCU.Library.Internal.Exceptions;
|
||||
using LCU.Library.Internal.LcuMassTransitModels;
|
||||
namespace LCU.Api.Internal.FTP.Services;
|
||||
|
||||
public class QueueSshFtpService : IQueueSshFtpService
|
||||
{
|
||||
private readonly ISendEndpoint _sendEndpoint;
|
||||
|
||||
public QueueSshFtpService(IBusControl busControl, ReceiveEndpointConfiguration receiveEndpointsConfiguration)
|
||||
{
|
||||
_sendEndpoint = busControl.GetSendEndpoint(receiveEndpointsConfiguration.ReceiveEndpointUri).Result;
|
||||
}
|
||||
|
||||
public void QueueSshFtpRequest(SshFtpRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
var queueRequest = new QueueRequest();
|
||||
|
||||
queueRequest = new QueueRequest()
|
||||
{
|
||||
Request = JsonConvert.SerializeObject(request),
|
||||
FtpType = FtpType.SshFtp
|
||||
};
|
||||
|
||||
_sendEndpoint.Send(queueRequest);
|
||||
Log.Debug($"Queued ssh ftp request to host {request.HostName}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, $"Failed to queue ssh ftp request to host {request.HostName}");
|
||||
throw new ServiceException($"Failed to queue ssh ftp request to host {request.HostName}");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
//System
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
//Microsoft
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.OpenApi.Models;
|
||||
//Others
|
||||
using MassTransit;
|
||||
//FTP
|
||||
using LCU.Api.Internal.FTP.Configuration;
|
||||
using LCU.Api.Internal.FTP.Security;
|
||||
using LCU.Api.Internal.FTP.Services.FtpOpertionServices;
|
||||
using LCU.Api.Internal.FTP.Services;
|
||||
using LCU.Api.Internal.FTP.Consumers;
|
||||
using LCU.Library.Internal.LcuMassTransitModels;
|
||||
using LCU.Library.Internal.LcuMassTransit;
|
||||
namespace LCU.Api.Internal.FTP;
|
||||
|
||||
public class Startup
|
||||
{
|
||||
public Startup(IConfiguration configuration)
|
||||
{
|
||||
Configuration = configuration;
|
||||
}
|
||||
|
||||
public IConfiguration Configuration { get; }
|
||||
readonly string MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
|
||||
|
||||
// This method gets called by the runtime. Use this method to add services to the container.
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddControllers();
|
||||
services.AddCors(options =>
|
||||
{
|
||||
options.AddPolicy(MyAllowSpecificOrigins,
|
||||
builder =>
|
||||
{
|
||||
builder.WithOrigins("http://localhost:3000", "https://localhost:5001",
|
||||
"http://lcu-internal.com", "https://lcu-internal.com").AllowAnyHeader()
|
||||
.AllowAnyMethod();
|
||||
});
|
||||
});
|
||||
|
||||
//Configurations
|
||||
FtpApiConfiguration ftpApiConfiguration = new FtpApiConfiguration();
|
||||
Configuration.GetSection("Primary").Bind(ftpApiConfiguration);
|
||||
services.AddSingleton(ftpApiConfiguration);
|
||||
services.AddHttpClient();
|
||||
|
||||
var connectionConfiguration = MassTransitConfigurationSetUp.AddConnectionConfiguration(ref services, Configuration);
|
||||
var receiveEndpointConfiguration = MassTransitConfigurationSetUp.GetReceiveEndpointConfiguration(Configuration,
|
||||
"FtpReceiveEndpoint");
|
||||
services.AddSingleton(receiveEndpointConfiguration);
|
||||
AddMassTransitServices(ref services, connectionConfiguration, receiveEndpointConfiguration);
|
||||
|
||||
//Services
|
||||
services.AddScoped<IEnvironmentView, EnvironmentView>();
|
||||
services.AddScoped<IQueueFtpService, QueueFtpService>();
|
||||
services.AddScoped<IQueueSshFtpService, QueueSshFtpService>();
|
||||
services.AddScoped<IFtpService, FtpService>();
|
||||
services.AddScoped<IWinScpSftpUploadFileService, WinScpSftpUploadFileService>();
|
||||
services.AddScoped<IWinScpSftpDownloadFilesService, WinScpSftpDownloadFilesService>();
|
||||
services.AddScoped<IWinScpListDirectoryService, WinScpListDirectoryService>();
|
||||
services.AddScoped<ISshFtpService, SshFtpService>();
|
||||
services.AddScoped<IFileOperationsService, FileOperationsService>();
|
||||
|
||||
// Register the Swagger generator, defining 1 or more Swagger documents
|
||||
services.AddSwaggerGen(c =>
|
||||
{
|
||||
c.SwaggerDoc("v1", new OpenApiInfo { Title = "Ftp API", Version = "v1" });
|
||||
// For this to work, I also had to check the generate xml box in build options.
|
||||
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.XML";
|
||||
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
|
||||
c.IncludeXmlComments(xmlPath);
|
||||
});
|
||||
|
||||
services.Configure<ApiBehaviorOptions>(options =>
|
||||
{
|
||||
options.SuppressModelStateInvalidFilter = true;
|
||||
});
|
||||
|
||||
//Set up Authentication
|
||||
services
|
||||
.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
|
||||
// AzureAD config
|
||||
.AddAzureAdBearer(options => Configuration.GetSection("AzureActiveDirectory").Bind(options));
|
||||
|
||||
services.AddIdentity<IdentityUser, IdentityRole>()
|
||||
.AddDefaultTokenProviders();
|
||||
}
|
||||
|
||||
public void AddMassTransitServices(ref IServiceCollection services,
|
||||
ConnectionConfiguration connectionConfiguration,
|
||||
ReceiveEndpointConfiguration receiveEndpointConfiguration)
|
||||
{
|
||||
services.AddMassTransit(x =>
|
||||
{
|
||||
x.AddConsumer<SftpConsumer>();
|
||||
|
||||
x.UsingRabbitMq((context, cfg) =>
|
||||
{
|
||||
cfg.Host(connectionConfiguration.HostUrl, "/", host =>
|
||||
{
|
||||
host.Username(connectionConfiguration.UserName);
|
||||
host.Password(connectionConfiguration.Password);
|
||||
});
|
||||
|
||||
cfg.ReceiveEndpoint(receiveEndpointConfiguration.ReceiveEndpoint, e =>
|
||||
{
|
||||
e.ConfigureConsumer<SftpConsumer>(context);
|
||||
e.SetQuorumQueue();
|
||||
});
|
||||
});
|
||||
});
|
||||
services.AddMassTransitHostedService();
|
||||
}
|
||||
|
||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
||||
{
|
||||
// Enable middleware to serve generated Swagger as a JSON endpoint.
|
||||
app.UseSwagger();
|
||||
|
||||
// Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
|
||||
// specifying the Swagger JSON endpoint.
|
||||
app.UseSwaggerUI(c =>
|
||||
{
|
||||
c.SwaggerEndpoint("/swagger/v1/swagger.json", "Ftp API");
|
||||
});
|
||||
|
||||
if (env.IsDevelopment())
|
||||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
}
|
||||
else
|
||||
{
|
||||
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
|
||||
app.UseHsts();
|
||||
}
|
||||
|
||||
app.UseAuthentication();
|
||||
app.UseCors(MyAllowSpecificOrigins);
|
||||
app.UseHttpsRedirection();
|
||||
app.UseRouting();
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.MapControllers();
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"Serilog": {
|
||||
"LevelSwitches": { "$controlSwitch": "Information" },
|
||||
"MinimumLevel": {
|
||||
"ControlledBy": "$controlSwitch",
|
||||
"Override": {
|
||||
"Microsoft": "Information",
|
||||
"System": "Warning",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"WriteTo": [
|
||||
{
|
||||
"Name": "Seq",
|
||||
"Args": {
|
||||
"serverUrl": "https://qa-seq.lcu-internal.com",
|
||||
"apiKey": "vG5LVLks9L5ae7oWAISN",
|
||||
"controlLevelSwitch": "$controlSwitch"
|
||||
}
|
||||
}
|
||||
],
|
||||
"Enrich": [ "FromLogContext", "WithMachineName", "WithThreadId" ],
|
||||
"Properties": {
|
||||
"Application": "FTP Api",
|
||||
"Environment": "Debug"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*",
|
||||
"Primary": {
|
||||
"AttemptsLimit": 1,
|
||||
"Apis": {
|
||||
"FileOperationApi": {
|
||||
"BuildDynamicFileRequest": "https://localhost:44310/DynamicFile/BuildDynamicFileList",
|
||||
"ValidateFileExists": "https://localhost:44310/FileValidation/ValidateFileExists"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ConnectionConfiguration": {
|
||||
"HostUrl": "localhost",
|
||||
"UserName": "guest",
|
||||
"Password": "guest"
|
||||
},
|
||||
"FtpReceiveEndpoint": {
|
||||
"ReceiveEndpoint": "LCU.FTP",
|
||||
"ReceiveEndpointType": "exchange"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user