Updating
This commit is contained in:
+22
@@ -0,0 +1,22 @@
|
||||
using System.Collections.Generic;
|
||||
namespace LCU.Api.Internal.ArchiverApi.Configuration;
|
||||
|
||||
public class ArchiverApiConfig
|
||||
{
|
||||
public string SeqUrl { get; set; }
|
||||
public string SeqApiKey { get; set; }
|
||||
public string ApplicationName { get; set; }
|
||||
public string NotificationApiEmail { get; set; }
|
||||
public string FileOperationApiBulkMoveFile { get; set; }
|
||||
public string FileOperationApiBuildDynamicFileList { get; set; }
|
||||
public string FileOperationApiValidateFileExists { get; set; }
|
||||
public string CoreApiWrapperGetApplicationHistory { get; set; }
|
||||
public string DnaBasePath { get; set; }
|
||||
public string ReportPathDateFormat { get; set; }
|
||||
public string ErrorMonitoringTemplate { get; set; }
|
||||
public string ErrorRowTemplate { get; set; }
|
||||
public string ErrorMonitoringSubject { get; set; }
|
||||
public List<string> ErrorRecipients { get; set; }
|
||||
public string TimeZone { get; set; }
|
||||
public FeatureFlags FeatureFlags { get; set; }
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
using LCU.Library.Internal.LcuMassTransitModels;
|
||||
namespace LCU.Api.Internal.ArchiverApi.Configuration;
|
||||
|
||||
public class ReceiveEndpointConfigurations
|
||||
{
|
||||
public ReceiveEndpointConfiguration ArchiverReceiveEndpoint { get; set; }
|
||||
public ReceiveEndpointConfiguration ResponseReceiveEndpoint { get; set; }
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
namespace LCU.Api.Internal.ArchiverApi.Configuration;
|
||||
|
||||
public class FeatureFlags
|
||||
{
|
||||
public bool RunArchiverConsumer { get; set; }
|
||||
public bool RunResponseConsumer { get; set; }
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Serilog;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using MassTransit;
|
||||
using LCU.Library.Internal.ArchiverApiModel.Models;
|
||||
using LCU.Api.Internal.ArchiverApi.Services;
|
||||
using LCU.Library.Internal.Exceptions;
|
||||
namespace LCU.Api.Internal.ArchiverApi.Consumers;
|
||||
|
||||
public class ArchiverConsumer : IConsumer<ArchiveRequest>
|
||||
{
|
||||
private readonly IServiceScopeFactory _scopeFactory;
|
||||
|
||||
public ArchiverConsumer(IServiceScopeFactory scopeFactory)
|
||||
{
|
||||
_scopeFactory = scopeFactory;
|
||||
}
|
||||
|
||||
public async Task Consume(ConsumeContext<ArchiveRequest> context)
|
||||
{
|
||||
try
|
||||
{
|
||||
using var scope = _scopeFactory.CreateScope();
|
||||
await Task.Run(() => scope.ServiceProvider.GetRequiredService<IArchiverService>().ExecuteRequest(context.Message));
|
||||
}
|
||||
catch (ServiceException)
|
||||
{
|
||||
return;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Fatal(exception, $"Unexpected Failure");
|
||||
}
|
||||
}
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Serilog;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using MassTransit;
|
||||
using LCU.Api.Internal.ArchiverApi.Services;
|
||||
using ApiResponse = LCU.Library.Internal.ApiResponse.Models;
|
||||
using LCU.Library.Internal.Exceptions;
|
||||
namespace LCU.Api.Internal.ArchiverApi.Consumers;
|
||||
|
||||
public class ResponseConsumer : IConsumer<ApiResponse.Response>
|
||||
{
|
||||
private readonly IServiceScopeFactory _scopeFactory;
|
||||
|
||||
public ResponseConsumer(IServiceScopeFactory scopeFactory)
|
||||
{
|
||||
_scopeFactory = scopeFactory;
|
||||
}
|
||||
|
||||
public async Task Consume(ConsumeContext<ApiResponse.Response> context)
|
||||
{
|
||||
try
|
||||
{
|
||||
using var scope = _scopeFactory.CreateScope();
|
||||
await Task.Run(() => scope.ServiceProvider.GetRequiredService<IArchiveCompletionService>().HandleReportArchiveCompletedRequest(context.Message));
|
||||
}
|
||||
catch (ServiceException)
|
||||
{
|
||||
return;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Fatal(exception, $"Unexpected Failure");
|
||||
}
|
||||
}
|
||||
}
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.Generic;
|
||||
using Serilog;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using LCU.Api.Internal.ArchiverApi.Services;
|
||||
using LCU.Api.Internal.ArchiverApi.Extensions;
|
||||
using LCU.Library.Internal.ArchiverApiModel.Entities;
|
||||
using LCU.Library.Internal.Exceptions;
|
||||
namespace LCU.Api.Internal.ArchiverApi.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("[controller]")]
|
||||
public class ApplicationMappingController : ControllerBase
|
||||
{
|
||||
private readonly IApplicationMappingService _applicationMappingService;
|
||||
|
||||
public ApplicationMappingController(IApplicationMappingService applicationMappingService)
|
||||
{
|
||||
_applicationMappingService = applicationMappingService;
|
||||
}
|
||||
|
||||
[HttpGet(Name = "GetAllJobs")]
|
||||
[ProducesResponseType(typeof(IEnumerable<ApplicationMapping>), 200)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> Get()
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = await _applicationMappingService.GetAsync();
|
||||
return Ok(result);
|
||||
}
|
||||
catch (ServiceException)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet("{id:int}", Name = "GetById")]
|
||||
[ProducesResponseType(201)]
|
||||
[ProducesResponseType(typeof(ApplicationMapping), 400)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> GetById(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = await _applicationMappingService.GetByIdAsync(id);
|
||||
return Ok(result);
|
||||
}
|
||||
catch (ServiceException)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[ProducesResponseType(201)]
|
||||
[ProducesResponseType(typeof(ApplicationMapping), 400)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> Post([FromBody] ApplicationMapping applicationMapping)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
return BadRequest(ModelState.GetErrorMessages());
|
||||
}
|
||||
|
||||
var result = await _applicationMappingService.SaveAsync(applicationMapping);
|
||||
return Ok(result);
|
||||
}
|
||||
catch (ServiceException)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPut("Update", Name = "Update")]
|
||||
[ProducesResponseType(typeof(ApplicationMapping), 200)]
|
||||
[ProducesResponseType(500)]
|
||||
public IActionResult Update([FromBody] ApplicationMapping applicationMapping)
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = _applicationMappingService.Update(applicationMapping);
|
||||
return Ok(result);
|
||||
}
|
||||
catch (ServiceException)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpDelete()]
|
||||
[ProducesResponseType(typeof(ApplicationMapping), 200)]
|
||||
[ProducesResponseType(500)]
|
||||
public IActionResult Delete(int jobId)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (jobId <= 0)
|
||||
{
|
||||
return BadRequest("Invalid Id");
|
||||
}
|
||||
|
||||
_applicationMappingService.DeleteAsync(jobId);
|
||||
return Ok();
|
||||
}
|
||||
catch (ServiceException)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Serilog;
|
||||
using LCU.Api.Internal.ArchiverApi.Services;
|
||||
using LCU.Library.Internal.ArchiverApiModel.Models;
|
||||
using LCU.Library.Internal.Exceptions;
|
||||
namespace LCU.Api.Internal.ArchiverApi.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("[controller]")]
|
||||
public class QueueArchiverController : ControllerBase
|
||||
{
|
||||
private readonly IQueueArchiverService _queueArchiverService;
|
||||
|
||||
public QueueArchiverController(IQueueArchiverService queueArchiverService)
|
||||
{
|
||||
_queueArchiverService = queueArchiverService;
|
||||
}
|
||||
|
||||
[HttpPost("QueueArchiver")]
|
||||
public IActionResult QueueArchiver(ArchiveRequest archiveRequest)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
return BadRequest(ModelState.Values);
|
||||
}
|
||||
|
||||
_queueArchiverService.QueueArchiver(archiveRequest);
|
||||
return Ok();
|
||||
}
|
||||
catch (ServiceException)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
}
|
||||
+185
@@ -0,0 +1,185 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.Generic;
|
||||
using Serilog;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using LCU.Api.Internal.ArchiverApi.Services;
|
||||
using LCU.Api.Internal.ArchiverApi.Extensions;
|
||||
using LCU.Library.Internal.ArchiverApiModel.Entities;
|
||||
using LCU.Library.Internal.Exceptions;
|
||||
namespace LCU.Api.Internal.ArchiverApi.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("[controller]")]
|
||||
public class RegexMappingController : ControllerBase
|
||||
{
|
||||
IRegexMappingService _regexMappingService;
|
||||
public RegexMappingController(IRegexMappingService regexMappingService)
|
||||
{
|
||||
_regexMappingService = regexMappingService;
|
||||
}
|
||||
|
||||
[HttpGet(Name = "GetAllRegex")]
|
||||
[ProducesResponseType(typeof(IEnumerable<RegexMapping>), 200)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> Get()
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = await _regexMappingService.GetAsync();
|
||||
return Ok(result);
|
||||
}
|
||||
catch (ServiceException)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet("GetByRegexId/{regexMappingId:int}", Name = "GetByRegexId")]
|
||||
[ProducesResponseType(201)]
|
||||
[ProducesResponseType(204)]
|
||||
[ProducesResponseType(typeof(RegexMapping), 400)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> GetByRegexMappingId(int regexMappingId)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (regexMappingId <= 0)
|
||||
{
|
||||
return BadRequest("Invalid Id");
|
||||
}
|
||||
var result = await _regexMappingService.GetByRegexMappingIdAsync(regexMappingId);
|
||||
if (result == null)
|
||||
{
|
||||
return NoContent();
|
||||
}
|
||||
return Ok(result);
|
||||
}
|
||||
catch (ServiceException)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet("GetByApplicationMappingId/{applicationMappingid:int}", Name = "GetByApplicationMappingId")]
|
||||
[ProducesResponseType(201)]
|
||||
[ProducesResponseType(204)]
|
||||
[ProducesResponseType(typeof(RegexMapping), 400)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> GetByApplicationMappingId(int applicationMappingId)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (applicationMappingId <= 0)
|
||||
{
|
||||
return BadRequest("Invalid Id");
|
||||
}
|
||||
var result = await _regexMappingService.GetByApplicationMappingIdAsync(applicationMappingId);
|
||||
if (result == null)
|
||||
{
|
||||
return NoContent();
|
||||
}
|
||||
return Ok(result);
|
||||
}
|
||||
catch (ServiceException)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
[ProducesResponseType(201)]
|
||||
[ProducesResponseType(typeof(RegexMapping), 400)]
|
||||
[ProducesResponseType(406)]
|
||||
[ProducesResponseType(500)]
|
||||
public async Task<IActionResult> Post([FromBody] RegexMapping regexMapping)
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = await _regexMappingService.SaveAsync(regexMapping);
|
||||
if (result == null)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status406NotAcceptable);
|
||||
}
|
||||
return Ok(result);
|
||||
}
|
||||
catch (ServiceException)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPut("UpdateRegex", Name = "UpdateRegex")]
|
||||
[ProducesResponseType(typeof(RegexMapping), 200)]
|
||||
[ProducesResponseType(406)]
|
||||
[ProducesResponseType(500)]
|
||||
public IActionResult Update([FromBody] RegexMapping regexMapping)
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = _regexMappingService.Update(regexMapping);
|
||||
if (result == null)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status406NotAcceptable);
|
||||
}
|
||||
return Ok(result);
|
||||
}
|
||||
catch (ServiceException)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpDelete()]
|
||||
[ProducesResponseType(typeof(RegexMapping), 200)]
|
||||
[ProducesResponseType(400)]
|
||||
[ProducesResponseType(500)]
|
||||
public IActionResult Delete(int regexId)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (regexId <= 0)
|
||||
{
|
||||
return BadRequest("Invalid Id");
|
||||
}
|
||||
|
||||
_regexMappingService.DeleteAsync(regexId);
|
||||
return Ok();
|
||||
}
|
||||
catch (ServiceException)
|
||||
{
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Unexpected Exception");
|
||||
return StatusCode(StatusCodes.Status500InternalServerError);
|
||||
}
|
||||
}
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Serilog;
|
||||
using LCU.Api.Internal.ArchiverApi.Models;
|
||||
namespace LCU.Api.Internal.ArchiverApi.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("[controller]")]
|
||||
public class StatusController : ControllerBase
|
||||
{
|
||||
private readonly IEnvironmentView _environmentView;
|
||||
|
||||
public StatusController(IEnvironmentView environmentView)
|
||||
{
|
||||
_environmentView = environmentView;
|
||||
}
|
||||
|
||||
[HttpGet()]
|
||||
[ProducesResponseType(200)]
|
||||
[ProducesResponseType(500)]
|
||||
public IActionResult Get()
|
||||
{
|
||||
try
|
||||
{
|
||||
Log.Verbose($"{_environmentView.Application}'s status endpoint was hit in {_environmentView.Environment}");
|
||||
return Ok(_environmentView);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.Error("Failure return status, message: {0} {1}", e.Message, e.StackTrace);
|
||||
return StatusCode((int)System.Net.HttpStatusCode.InternalServerError);
|
||||
}
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
using System;
|
||||
namespace LCU.Api.Internal.ArchiverApi.Exceptions;
|
||||
|
||||
public class FailedToParseException : Exception
|
||||
{
|
||||
public FailedToParseException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
namespace LCU.Api.Internal.ArchiverApi.Exceptions;
|
||||
|
||||
/**
|
||||
* If an entity cannot be found, that specific error can allow for a 404 or 400 with more detail to be
|
||||
* returned. So specify that to the API layer.
|
||||
*/
|
||||
public class NotFoundException : ApplicationException
|
||||
{
|
||||
public NotFoundException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
using System;
|
||||
namespace LCU.Api.Internal.ArchiverApi.Exceptions;
|
||||
|
||||
/**
|
||||
* Do not want to expose database and related exceptions to the controllers / web layer.
|
||||
* The lower layers log what happened for developers, then return a general error; unless
|
||||
* a more specific error can be returned in a way to allow the client to act (such as NotFound).
|
||||
*/
|
||||
public class ServerErrorException : Exception
|
||||
{
|
||||
public ServerErrorException() : base("A server error occured, and a response could not be produced.") { }
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace LCU.Api.Internal.ArchiverApi.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();
|
||||
}
|
||||
}
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Description>
|
||||
1.0.0 - Initial Versioning
|
||||
1.1.0 - Notice, Statments, and Reports
|
||||
1.1.1 - Fix regex to only look for extensions at end. Fix path for error templates.\
|
||||
1.2.0 - Added ReturnResponse to ArchiveRequest and updated nugets.
|
||||
1.3.0 - Change QueueArchiveRequest to use DaysFromDate.
|
||||
1.4.0 - Update to use MassTransit and ApiResponse upgrade.
|
||||
1.5.0 - Upgraded FileOperations package version
|
||||
</Description>
|
||||
<Version>1.4.0</Version>
|
||||
<PackageReleaseNotes>
|
||||
1.0.0 - Initial Versioning
|
||||
1.1.0 - Notice, Statments, and Reports
|
||||
1.1.1 - Fix regex to only look for extensions at end. Fix path for error templates.
|
||||
1.2.0 - Added ReturnResponse to ArchiveRequest and updated nugets.
|
||||
1.3.0 - Change QueueArchiveRequest to use DaysFromDate.
|
||||
1.4.0 - Update to use MassTransit and ApiResponse upgrade.
|
||||
1.5.0 - Upgraded FileOperations package version
|
||||
</PackageReleaseNotes>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="LCU.Api.Internal.MaidBotLib" Version="1.0.0" />
|
||||
<PackageReference Include="LCU.API.Internal.NotificationsApiLib" Version="2.1.0" />
|
||||
<PackageReference Include="LCU.Library.Internal.ApiResponse" Version="3.3.0" />
|
||||
<PackageReference Include="LCU.Library.Internal.ApiResponse.Models" Version="3.3.0" />
|
||||
<PackageReference Include="LCU.Library.Internal.CoreApiWrapperModel" Version="2.2.0" />
|
||||
<PackageReference Include="LCU.Library.Internal.Exceptions" Version="1.0.0" />
|
||||
<PackageReference Include="LCU.Library.Internal.FileOperationsModels" Version="4.1.0" />
|
||||
<PackageReference Include="LCU.Library.Internal.LcuMassTransit" Version="1.0.0" />
|
||||
<PackageReference Include="LCU.Library.Internal.LcuMassTransitModels" Version="1.1.0" />
|
||||
<PackageReference Include="LCU.Library.Internal.Logging" Version="1.1.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="5.0.1">
|
||||
<NoWarn>NU1605</NoWarn>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.9" />
|
||||
<PackageReference Include="Serilog" Version="2.10.0" />
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="4.1.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Async" Version="1.5.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Seq" Version="5.0.1" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.6.3" />
|
||||
<PackageReference Include="TimeZoneConverter" Version="5.0.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\LCU.Library.Internal.ArchiverApiLib\LCU.Library.Internal.ArchiverApiLib.csproj" />
|
||||
<ProjectReference Include="..\LCU.Library.Internal.ArchiverApiModel\LCU.Library.Internal.ArchiverApiModel.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="Templates\ErrorMonitoringTemplate.html">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="Templates\ErrorRowTemplate.html">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
namespace LCU.Api.Internal.ArchiverApi.Models;
|
||||
|
||||
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,11 @@
|
||||
using System;
|
||||
namespace LCU.Api.Internal.ArchiverApi.Models;
|
||||
|
||||
public interface IEnvironmentView
|
||||
{
|
||||
string Application { get; }
|
||||
DateTime CurrentDate { get; }
|
||||
string BuildVersion { get; }
|
||||
DateTime BuildDate { get; }
|
||||
string Environment { get; }
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Serilog;
|
||||
using System;
|
||||
|
||||
namespace LCU.Api.Internal.ArchiverApi;
|
||||
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
CreateHostBuilder(args).Build().Run();
|
||||
}
|
||||
|
||||
public static IHostBuilder CreateHostBuilder(string[] args) =>
|
||||
Host.CreateDefaultBuilder(args)
|
||||
.ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); })
|
||||
.ConfigureAppConfiguration((context,builder) =>
|
||||
{
|
||||
builder.AddJsonFile("/app/config/mapped-appsettings/primary.json", optional: true, reloadOnChange: true);
|
||||
builder.AddJsonFile("/vault/secrets/archiver-api-database-connection.json", optional: true, reloadOnChange: true);
|
||||
builder.AddJsonFile("/vault/secrets/archiver-api-seq-api-key.json", optional: true, reloadOnChange: true);
|
||||
builder.AddJsonFile("/vault/secrets/archiver-api-queue-username.json", optional: true, reloadOnChange: true);
|
||||
builder.AddJsonFile("/vault/secrets/archiver-api-queue-password.json", optional: true, reloadOnChange: true);
|
||||
builder.AddJsonFile("/vault/secrets/archiverapi_configuration.json", optional: true, reloadOnChange: true);
|
||||
|
||||
var config = builder.Build();
|
||||
})
|
||||
.UseSerilog();
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:56414",
|
||||
"sslPort": 44353
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "swagger",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"LCU.Api.Internal.AutomicApiWrapper": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": "true",
|
||||
"launchBrowser": true,
|
||||
"launchUrl": "swagger",
|
||||
"applicationUrl": "https://localhost:5001;http://localhost:5000",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SqlClient;
|
||||
using System.Threading.Tasks;
|
||||
using Serilog;
|
||||
using LCU.Library.Internal.ArchiverApiLib.Repositories;
|
||||
using LCU.Library.Internal.ArchiverApiModel.Entities;
|
||||
using LCU.Library.Internal.Exceptions;
|
||||
namespace LCU.Api.Internal.ArchiverApi.Services;
|
||||
|
||||
public class ApplicationMappingService : IApplicationMappingService
|
||||
{
|
||||
private readonly IApplicationMappingRepository _applicationMappingRepository;
|
||||
private readonly IUnitOfWork _unitOfWork;
|
||||
|
||||
public ApplicationMappingService(IUnitOfWork unitOfWork,
|
||||
IApplicationMappingRepository applicationMappingRepository)
|
||||
{
|
||||
_unitOfWork = unitOfWork;
|
||||
_applicationMappingRepository = applicationMappingRepository;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ApplicationMapping>> GetAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _applicationMappingRepository.ListAsync();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Failure retrieving application mappings.");
|
||||
throw new ServiceException("Failure retrieving application mappings.");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<ApplicationMapping> GetByIdAsync(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var applicationMapping = await _applicationMappingRepository.FindByIdAsync(id);
|
||||
ArgumentNullException.ThrowIfNull(applicationMapping);
|
||||
return applicationMapping;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, $"Failure retrieving application mapping with id {id}.");
|
||||
throw new ServiceException($"Failure retrieving application mapping with id {id}.");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ApplicationMapping>> GetByIdentifierAsync(string identifier)
|
||||
{
|
||||
try
|
||||
{
|
||||
var applicationMapping = await _applicationMappingRepository.FindByIdentifierAsync(identifier);
|
||||
ArgumentNullException.ThrowIfNull(applicationMapping);
|
||||
return applicationMapping;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, $"Failure retrieving application mapping with id {identifier}.");
|
||||
throw new ServiceException($"Failure retrieving application mapping with id {identifier}.");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<ApplicationMapping> SaveAsync(ApplicationMapping applicationMapping)
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = await _applicationMappingRepository.AddAsync(applicationMapping);
|
||||
await _unitOfWork.CompleteAsync();
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Failure saving application mapping");
|
||||
throw new ServiceException("Failure saving application mapping");
|
||||
}
|
||||
}
|
||||
|
||||
public ApplicationMapping Update(ApplicationMapping applicationMapping)
|
||||
{
|
||||
try
|
||||
{
|
||||
var existing = GetByIdAsync(applicationMapping.ApplicationMappingId).Result;
|
||||
ArgumentNullException.ThrowIfNull(existing);
|
||||
|
||||
existing.Identifier = applicationMapping.Identifier;
|
||||
existing.DesignatedName = applicationMapping.DesignatedName;
|
||||
existing.ApplicationOverrideName = applicationMapping.ApplicationOverrideName;
|
||||
existing.ParameterMappings = applicationMapping.ParameterMappings;
|
||||
|
||||
_applicationMappingRepository.Update(existing);
|
||||
_unitOfWork.Complete();
|
||||
|
||||
return existing;
|
||||
}
|
||||
catch (SqlException sqlException)
|
||||
{
|
||||
Log.Error(sqlException, "SQL Failure updating application mapping");
|
||||
throw new ServiceException("SQL Failure updating application mapping");
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Failure updating application mapping");
|
||||
throw new ServiceException("Failure updating application mapping");
|
||||
}
|
||||
}
|
||||
|
||||
public void DeleteAsync(int applicationMappingId)
|
||||
{
|
||||
try
|
||||
{
|
||||
var applicationMapping = _applicationMappingRepository.FindByIdAsync(applicationMappingId).Result;
|
||||
ArgumentNullException.ThrowIfNull(applicationMapping);
|
||||
_applicationMappingRepository.Remove(applicationMapping);
|
||||
_unitOfWork.Complete();
|
||||
}
|
||||
catch (SqlException sqlException)
|
||||
{
|
||||
Log.Error(sqlException, $"SQL failure removing application mapping. ApplicationMappingId: {applicationMappingId}");
|
||||
throw new ServiceException($"SQL failure removing application mapping. ApplicationMappingId: {applicationMappingId}");
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, $"Failure removing application mapping. ApplicationMappingId: {applicationMappingId}");
|
||||
throw new ServiceException($"Failure removing application mapping. ApplicationMappingId: {applicationMappingId}");
|
||||
}
|
||||
}
|
||||
}
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Serilog;
|
||||
using Newtonsoft.Json;
|
||||
using LCU.Api.Internal.MaidBotLib.Models;
|
||||
using LCU.Library.Internal.ApiResponse.Models;
|
||||
using LCU.Library.Internal.ApiResponse.Services;
|
||||
using LCU.Library.Internal.ArchiverApiModel.Models;
|
||||
namespace LCU.Api.Internal.ArchiverApi.Services;
|
||||
|
||||
public class ArchiveCompletionService : IArchiveCompletionService
|
||||
{
|
||||
private readonly IFileOperationsService _fileOperationsService;
|
||||
private readonly INotificationService _notificationService;
|
||||
|
||||
public ArchiveCompletionService(IFileOperationsService fileOperationsService,
|
||||
INotificationService notificationService)
|
||||
{
|
||||
_fileOperationsService = fileOperationsService;
|
||||
_notificationService = notificationService;
|
||||
}
|
||||
|
||||
public void HandleReportArchiveCompletedRequest(Response response)
|
||||
{
|
||||
try
|
||||
{
|
||||
var payLoadString = response.ResponsePayload;
|
||||
var archiveResponsePayload = JsonConvert.DeserializeObject<ArchiveResponsePayload>(payLoadString);
|
||||
var archiveRequestResponse = archiveResponsePayload.ArchiveRequestResponse;
|
||||
archiveRequestResponse.IsSuccessful = response.Successful;
|
||||
archiveRequestResponse.MessageStack.AddRange(response.ResponseStack);
|
||||
|
||||
var requestResult = PopulateErrorDetailsAndRequestResponse(archiveResponsePayload, archiveRequestResponse);
|
||||
|
||||
QueueReturnResponse.QueueResponse(archiveResponsePayload.ArchiveRequest,
|
||||
requestResult.archiveRequestResponse.IsSuccessful,
|
||||
requestResult.archiveRequestResponse.MessageStack);
|
||||
|
||||
var errorsSent = _notificationService.SendErrorEmailAsync(requestResult.errorDetails).Result;
|
||||
if (!errorsSent)
|
||||
{
|
||||
Log.ForContext(nameof(PropertyEnum.Group),
|
||||
nameof(GroupEnum.ITDevelopment))
|
||||
.Error($"Failure to send error details for {requestResult.errorDetails.Count} errors.");
|
||||
throw new Exception($"Failure to send error details for {requestResult.errorDetails.Count} errors.");
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, $"Error while archiving reports. " +
|
||||
$"Message:{exception.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public (List<ErrorDetail> errorDetails, ArchiveRequestResponse archiveRequestResponse) PopulateErrorDetailsAndRequestResponse(ArchiveResponsePayload archiveResponsePayload,
|
||||
ArchiveRequestResponse archiveRequestResponse)
|
||||
{
|
||||
var errorDetails = new List<ErrorDetail>();
|
||||
foreach (var request in archiveResponsePayload.BulkOperationRequest.OperationRequests)
|
||||
{
|
||||
var errorMessage = "";
|
||||
try
|
||||
{
|
||||
//If file still exist move did not occur.
|
||||
var fileExists = _fileOperationsService.ValidateFileExists(request.Source).Result;
|
||||
if (fileExists)
|
||||
{
|
||||
errorMessage = $"File {request.SourceFile} was not archived to the path of {request.Destination} ";
|
||||
archiveRequestResponse.IsSuccessful = false;
|
||||
archiveRequestResponse.MessageStack.Add(errorMessage);
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var loggingMessage = $"Exception thrown while looking for the file at path {request.Source}.";
|
||||
errorMessage = $"{loggingMessage}. Message: {exception.Message}";
|
||||
Log.Error(exception, loggingMessage);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(errorMessage))
|
||||
{
|
||||
var newErrorDetail = new ErrorDetail()
|
||||
{
|
||||
FileLocation = request.SourcePath,
|
||||
Filename = request.FinalSourceFile,
|
||||
Destination = request.Destination,
|
||||
Description = errorMessage
|
||||
};
|
||||
errorDetails.Add(newErrorDetail);
|
||||
}
|
||||
}
|
||||
|
||||
return (errorDetails, archiveRequestResponse);
|
||||
}
|
||||
}
|
||||
+284
@@ -0,0 +1,284 @@
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using Serilog;
|
||||
using Newtonsoft.Json;
|
||||
using LCU.Library.Internal.ApiResponse.Models;
|
||||
using LCU.Library.Internal.FileOperationsModels.Models.NameSettings;
|
||||
using LCU.Library.Internal.FileOperationsModels.Models;
|
||||
using LCU.Api.Internal.ArchiverApi.Configuration;
|
||||
using LCU.Api.Internal.MaidBotLib.Models;
|
||||
using LCU.Library.Internal.ApiResponse.Services;
|
||||
using LCU.Library.Internal.ArchiverApiModel.Models;
|
||||
using LCU.Library.Internal.LcuMassTransitModels;
|
||||
|
||||
namespace LCU.Api.Internal.ArchiverApi.Services;
|
||||
|
||||
public class ArchiverService : IArchiverService
|
||||
{
|
||||
private readonly ArchiverApiConfig _ArchiverApiConfig;
|
||||
private readonly IReportService _reportService;
|
||||
private readonly IFileOperationsService _fileOperationsService;
|
||||
private readonly ConnectionConfiguration _connectionConfiguration;
|
||||
private readonly ReceiveEndpointConfiguration _receiveEndpointsConfiguration;
|
||||
|
||||
private const string NameRegexStartTag = "{Regex0}";
|
||||
private const string NameRegexStart = "^(" + RegexStartCaseInsenstive;
|
||||
private const string NameRegexEndTag = "{Regex1}";
|
||||
private const string NameRegexEnd = RegexStopCaseInsenstive + ")";
|
||||
private const string AnyWordAndPeriodRegexTag = "{Regex2}";
|
||||
private const string AnyWordAndPeriodRegex = "\\w*\\.";
|
||||
private const string ExtensionRegexTag = "{Regex3}";
|
||||
private const string ExtensionRegexStart = "(";
|
||||
private const string ExtensionRegexEnd = ")$";
|
||||
private const string RegexPipe = "|";
|
||||
private const string RegexStartCaseInsenstive = "(?i)";
|
||||
private const string RegexStopCaseInsenstive = "(?-i)";
|
||||
|
||||
public ArchiverService(ArchiverApiConfig ArchiverApiConfig,
|
||||
IReportService reportService,
|
||||
IFileOperationsService fileOperationsService,
|
||||
ConnectionConfiguration connectionConfiguration,
|
||||
ReceiveEndpointConfigurations receiveEndpointsConfiguration)
|
||||
{
|
||||
_ArchiverApiConfig = ArchiverApiConfig;
|
||||
_reportService = reportService;
|
||||
_fileOperationsService = fileOperationsService;
|
||||
_connectionConfiguration = connectionConfiguration;
|
||||
_receiveEndpointsConfiguration = receiveEndpointsConfiguration.ResponseReceiveEndpoint;
|
||||
}
|
||||
|
||||
public void ExecuteRequest(ArchiveRequest archiveRequest)
|
||||
{
|
||||
try
|
||||
{
|
||||
var archiveResult = HandleArchiveRequest(archiveRequest);
|
||||
if (!archiveResult.archiveRequestResponse.IsSuccessful)
|
||||
{
|
||||
var errorMessage = String.Join("; ", archiveResult.archiveRequestResponse.MessageStack.ToArray());
|
||||
Log.Error($"Archive Request was not successful. MessaggeStack:{errorMessage}");
|
||||
}
|
||||
|
||||
//Happy path we queue return response later in ArchivecompletionService after the BulkOperations has been preformed.
|
||||
if (archiveResult.queueReturnResponse)
|
||||
{
|
||||
QueueReturnResponse.QueueResponse(archiveRequest,
|
||||
archiveResult.archiveRequestResponse.IsSuccessful,
|
||||
archiveResult.archiveRequestResponse.MessageStack);
|
||||
}
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.ForContext(nameof(PropertyEnum.Group),
|
||||
nameof(GroupEnum.ITDevelopment))
|
||||
.Error(exception, $"Error while archiving reports. Look into failed ArchiveRequest. " +
|
||||
$"ArchiveRequest: {JsonConvert.SerializeObject(archiveRequest)}");
|
||||
}
|
||||
}
|
||||
|
||||
public (ArchiveRequestResponse archiveRequestResponse, bool queueReturnResponse) HandleArchiveRequest(ArchiveRequest archiveRequest)
|
||||
{
|
||||
var archiveRequestResponse = new ArchiveRequestResponse();
|
||||
try
|
||||
{
|
||||
var reports = _reportService.GetReportsToArchiveAsync(archiveRequest).Result;
|
||||
if (!reports.Any())
|
||||
{
|
||||
Log.Information("No reports to bulk move.");
|
||||
archiveRequestResponse.MessageStack.Add("No application histories retrieved from DNA database to move.");
|
||||
archiveRequestResponse.IsSuccessful = archiveRequest.SucceedIfEmpty;
|
||||
return (archiveRequestResponse, true);
|
||||
}
|
||||
|
||||
var bulkOperationRequest = BuildBulkOperationRequest(reports, archiveRequest);
|
||||
if (!bulkOperationRequest.OperationRequests.Any())
|
||||
{
|
||||
Log.Information("There are no files to bulk move.");
|
||||
archiveRequestResponse.MessageStack.Add("There are no files to bulk move.");
|
||||
archiveRequestResponse.IsSuccessful = archiveRequest.SucceedIfEmpty;
|
||||
return (archiveRequestResponse, true);
|
||||
}
|
||||
|
||||
bulkOperationRequest = SetUpResponse(bulkOperationRequest, archiveRequest, archiveRequestResponse);
|
||||
_fileOperationsService.SendBulkOperationsAsync(bulkOperationRequest);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
archiveRequestResponse.IsSuccessful = false;
|
||||
var anyIdentifiers = archiveRequest.ArchiveIdentifiers != null && archiveRequest.ArchiveIdentifiers.Any();
|
||||
var identifiers = anyIdentifiers ? String.Join(", ", archiveRequest.ArchiveIdentifiers.ToArray()) : "";
|
||||
archiveRequestResponse.MessageStack.Add($"Failure to execute archive request. " +
|
||||
$"EffectiveDate: [{archiveRequest.EffectiveDate}], " +
|
||||
$"DaysFromDate: [{archiveRequest.DaysFromDate}], " +
|
||||
$"ArchiveDestinationBase: [{archiveRequest.ArchiveDestinationBase}], " +
|
||||
$"Identifiers: [{identifiers}], " +
|
||||
$"Exception: {exception} ");
|
||||
}
|
||||
|
||||
return (archiveRequestResponse, !archiveRequestResponse.IsSuccessful);
|
||||
}
|
||||
|
||||
public BulkOperationRequest<MoveFileRequest> BuildBulkOperationRequest(IEnumerable<Report> reports, ArchiveRequest archiveRequest)
|
||||
{
|
||||
try
|
||||
{
|
||||
var bulkOperationRequest = new BulkOperationRequest<MoveFileRequest>();
|
||||
bulkOperationRequest.OperationRequests = new List<MoveFileRequest>();
|
||||
var extensionRegex = new RegexSetting()
|
||||
{
|
||||
Tag = ExtensionRegexTag,
|
||||
Regex = BuildExtensionRegexString(archiveRequest)
|
||||
};
|
||||
var anyWordAndPeriodRegex = new RegexSetting()
|
||||
{
|
||||
Tag = AnyWordAndPeriodRegexTag,
|
||||
Regex = AnyWordAndPeriodRegex
|
||||
};
|
||||
|
||||
foreach (var report in reports)
|
||||
{
|
||||
var nameSettings = SetUpNameSettings(report);
|
||||
|
||||
nameSettings.RegexSettings.Add(anyWordAndPeriodRegex);
|
||||
nameSettings.RegexSettings.Add(extensionRegex);
|
||||
var dynamicallyNamedRequests = CreateOperationRequests(report, nameSettings, archiveRequest);
|
||||
bulkOperationRequest.OperationRequests.AddRange(dynamicallyNamedRequests);
|
||||
}
|
||||
|
||||
return bulkOperationRequest;
|
||||
}
|
||||
catch (AggregateException exception)
|
||||
{
|
||||
throw new AggregateException($"Error while attempting to build bulk operation request. " +
|
||||
$"Exception Message: {exception.Message}");
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
throw new Exception($"Error while attempting to build bulk operation request. " +
|
||||
$"Exception Message: {exception.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public string BuildExtensionRegexString(ArchiveRequest archiveRequest)
|
||||
{
|
||||
var regexStringBuilder = new StringBuilder();
|
||||
regexStringBuilder.Append(ExtensionRegexStart);
|
||||
|
||||
for (int index = 0; index < archiveRequest.AllowedExensions.Count; ++index)
|
||||
{
|
||||
var pipe = index == archiveRequest.AllowedExensions.Count ? "" : RegexPipe;
|
||||
regexStringBuilder.Append(RegexStartCaseInsenstive +
|
||||
archiveRequest.AllowedExensions[index] +
|
||||
RegexStopCaseInsenstive +
|
||||
pipe);
|
||||
}
|
||||
|
||||
regexStringBuilder.Append(ExtensionRegexEnd);
|
||||
return regexStringBuilder.ToString();
|
||||
}
|
||||
|
||||
public List<MoveFileRequest> CreateOperationRequests(Report report, DynamicNameSetting nameSettings, ArchiveRequest archiveRequest)
|
||||
{
|
||||
var fileName = report.HasRegexMapping ? report.DisplayReportName : report.FinalReportName;
|
||||
|
||||
DateTime effectiveDate = archiveRequest.EffectiveDate == null ? DateTime.MinValue : (DateTime)archiveRequest.EffectiveDate;
|
||||
var reportPath = $"{_ArchiverApiConfig.DnaBasePath}\\" +
|
||||
$"{effectiveDate.ToString(_ArchiverApiConfig.ReportPathDateFormat)}\\" +
|
||||
$"{report.QueueNumber}";
|
||||
var sourceFile = $"{NameRegexStartTag}{fileName}{NameRegexEndTag}{AnyWordAndPeriodRegexTag}{ExtensionRegexTag}";
|
||||
var files = _fileOperationsService.BuildDynamicFileListAsync(reportPath, sourceFile, nameSettings).Result;
|
||||
var dynamicallyNamedRequests = new List<MoveFileRequest>();
|
||||
|
||||
foreach (var file in files)
|
||||
{
|
||||
var request = new MoveFileRequest()
|
||||
{
|
||||
SourcePath = reportPath,
|
||||
SourceFile = file,
|
||||
DestinationPath = archiveRequest.ArchiveDestinationBase,
|
||||
FileNameSetting = nameSettings
|
||||
};
|
||||
SetDestinationName(report, request, archiveRequest);
|
||||
dynamicallyNamedRequests.Add(request);
|
||||
}
|
||||
|
||||
return dynamicallyNamedRequests;
|
||||
}
|
||||
|
||||
public void SetDestinationName(Report report, MoveFileRequest request, ArchiveRequest archiveRequest)
|
||||
{
|
||||
var extention = archiveRequest.AllowedExensions
|
||||
.FirstOrDefault(fe => request.SourceFile.Contains($".{fe}", StringComparison.OrdinalIgnoreCase));
|
||||
if (extention != null)
|
||||
{
|
||||
request.DestinationName = report.BuildDestinationName(request.FinalSourceFile, extention);
|
||||
}
|
||||
}
|
||||
|
||||
public DynamicNameSetting SetUpNameSettings(Report report) {
|
||||
var nameSettings = new DynamicNameSetting();
|
||||
nameSettings.RegexSettings = new List<RegexSetting>()
|
||||
{
|
||||
new RegexSetting()
|
||||
{
|
||||
Tag = NameRegexStartTag,
|
||||
Regex = NameRegexStart
|
||||
},
|
||||
new RegexSetting()
|
||||
{
|
||||
Tag = NameRegexEndTag,
|
||||
Regex = NameRegexEnd
|
||||
}
|
||||
};
|
||||
|
||||
if (report.ApplicationMapping == null)
|
||||
{
|
||||
return nameSettings;
|
||||
};
|
||||
|
||||
foreach (var regex in report.ApplicationMapping.RegexMappings)
|
||||
{
|
||||
nameSettings.RegexSettings.Add(new RegexSetting()
|
||||
{
|
||||
Tag = regex.Tag,
|
||||
Regex = regex.Regex,
|
||||
});
|
||||
}
|
||||
return nameSettings;
|
||||
}
|
||||
|
||||
public BulkOperationRequest<MoveFileRequest> SetUpResponse(BulkOperationRequest<MoveFileRequest> bulkOperationRequest,
|
||||
ArchiveRequest archiveRequest,
|
||||
ArchiveRequestResponse archiveRequestResponse)
|
||||
{
|
||||
var archiveResponsePayload = new ArchiveResponsePayload()
|
||||
{
|
||||
ArchiveRequest = archiveRequest,
|
||||
BulkOperationRequest = bulkOperationRequest,
|
||||
ArchiveRequestResponse = archiveRequestResponse
|
||||
};
|
||||
|
||||
var responseItem = new ResponseItem
|
||||
{
|
||||
ReturnQueueConsumerConfig = new QueueConsumerConfig()
|
||||
{
|
||||
ExchangeName = _receiveEndpointsConfiguration.ReceiveEndpoint
|
||||
},
|
||||
ReturnQueueConnectionConfig = new QueueConnectionConfig()
|
||||
{
|
||||
Url = _connectionConfiguration.HostUrl,
|
||||
Username = _connectionConfiguration.UserName,
|
||||
Password = _connectionConfiguration.Password
|
||||
},
|
||||
ResponsePayload = JsonConvert.SerializeObject(archiveResponsePayload)
|
||||
};
|
||||
|
||||
bulkOperationRequest.ResponseItems = new List<ResponseItem>()
|
||||
{
|
||||
responseItem
|
||||
};
|
||||
|
||||
return bulkOperationRequest;
|
||||
}
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using System.Text;
|
||||
using Newtonsoft.Json;
|
||||
using LCU.Api.Internal.ArchiverApi.Configuration;
|
||||
using LCU.Library.Internal.ArchiverApi.Utilities;
|
||||
using LCU.Library.Internal.ArchiverApiModel.Models;
|
||||
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.CoreRequests;
|
||||
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.ApplicationHistories;
|
||||
namespace LCU.Api.Internal.ArchiverApi.Services;
|
||||
|
||||
public class CoreApiWrapperService : ICoreApiWrapperService
|
||||
{
|
||||
private readonly ArchiverApiConfig _ArchiverApiConfig;
|
||||
|
||||
public CoreApiWrapperService(ArchiverApiConfig ArchiverApiConfig)
|
||||
{
|
||||
_ArchiverApiConfig = ArchiverApiConfig;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ApplicationHistory>> GetApplicationHistories(ArchiveRequest archiveRequest)
|
||||
{
|
||||
try
|
||||
{
|
||||
var applicationHistoryRequest = new ApplicationHistoryRequest()
|
||||
{
|
||||
ApplicationNumbers = archiveRequest.ArchiveIdentifiers,
|
||||
EffectiveDate = archiveRequest.EffectiveDate.ToString()
|
||||
};
|
||||
|
||||
var url = SetUpUrl(applicationHistoryRequest);
|
||||
var client = HttpUtilities.GetClient(url);
|
||||
var response = await client.GetAsync(url);
|
||||
response.EnsureSuccessStatusCode();
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
throw new Exception($"Issue retrieving Application History from Core Api Wrapper. " +
|
||||
$"Request: {JsonConvert.SerializeObject(applicationHistoryRequest)}");
|
||||
}
|
||||
|
||||
var stringResponse = await response.Content.ReadAsStringAsync();
|
||||
var applicationHistories = JsonConvert.DeserializeObject<List<ApplicationHistory>>(stringResponse);
|
||||
return applicationHistories;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
throw new Exception($"Failure to get application histories. Exception Message: {exception.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public string SetUpUrl(ApplicationHistoryRequest applicationHistoryRequest)
|
||||
{
|
||||
var endpointBuilder = new StringBuilder();
|
||||
endpointBuilder.Append(_ArchiverApiConfig.CoreApiWrapperGetApplicationHistory);
|
||||
|
||||
var propertyCounter = 0;
|
||||
var propertyName = nameof(applicationHistoryRequest.ApplicationNumbers);
|
||||
HttpUtilities.AppendListOfValuesToEndpoint(endpointBuilder, propertyCounter, applicationHistoryRequest.ApplicationNumbers, propertyName);
|
||||
endpointBuilder.Append($"&{nameof(applicationHistoryRequest.EffectiveDate)}={applicationHistoryRequest.EffectiveDate}");
|
||||
return endpointBuilder.ToString();
|
||||
}
|
||||
}
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using Newtonsoft.Json;
|
||||
using LCU.Library.Internal.FileOperationsModels.Models.NameSettings;
|
||||
using LCU.Library.Internal.ArchiverApi.Utilities;
|
||||
using LCU.Library.Internal.FileOperationsModels.Models;
|
||||
using LCU.Api.Internal.ArchiverApi.Configuration;
|
||||
namespace LCU.Api.Internal.ArchiverApi.Services;
|
||||
|
||||
public class FileOperationsService : IFileOperationsService
|
||||
{
|
||||
private readonly ArchiverApiConfig _ArchiverApiConfig;
|
||||
|
||||
public FileOperationsService(ArchiverApiConfig ArchiverApiConfig)
|
||||
{
|
||||
_ArchiverApiConfig = ArchiverApiConfig;
|
||||
}
|
||||
|
||||
public void SendBulkOperationsAsync(BulkOperationRequest<MoveFileRequest> bulkOperationRequest)
|
||||
{
|
||||
try
|
||||
{
|
||||
var encoded = JsonConvert.SerializeObject(bulkOperationRequest);
|
||||
var client = HttpUtilities.GetClient(_ArchiverApiConfig.FileOperationApiBulkMoveFile);
|
||||
var content = new StringContent(encoded, Encoding.UTF8, "application/json");
|
||||
|
||||
HttpResponseMessage response = client.PostAsync(_ArchiverApiConfig.FileOperationApiBulkMoveFile, content).Result;
|
||||
response.EnsureSuccessStatusCode();
|
||||
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
throw new Exception($"IsSuccessStatusCode: {response.IsSuccessStatusCode}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception($"Failure to use the Bulk Operations. Message{ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<List<string>> BuildDynamicFileListAsync(string path, string file, DynamicNameSetting dynamicNameSetting)
|
||||
{
|
||||
try
|
||||
{
|
||||
var dynamicFileListRequest = new DynamicFileListRequest()
|
||||
{
|
||||
Path = path,
|
||||
Filename = file,
|
||||
DynamicFileSettings = dynamicNameSetting
|
||||
};
|
||||
|
||||
var encoded = JsonConvert.SerializeObject(dynamicFileListRequest);
|
||||
var client = HttpUtilities.GetClient(_ArchiverApiConfig.FileOperationApiBuildDynamicFileList);
|
||||
var content = new StringContent(encoded, Encoding.UTF8, "application/json");
|
||||
HttpResponseMessage response = await client.PostAsync(_ArchiverApiConfig.FileOperationApiBuildDynamicFileList, content);
|
||||
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
throw new Exception($"IsSuccessStatusCode: {response.IsSuccessStatusCode}");
|
||||
}
|
||||
|
||||
var stringResponse = await response.Content.ReadAsStringAsync();
|
||||
var fileList = JsonConvert.DeserializeObject<List<string>>(stringResponse);
|
||||
return fileList;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
throw new Exception($"Unable to build dynamic list of files. Exception Message: {exception}");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<bool> ValidateFileExists(string sourceFilePath)
|
||||
{
|
||||
try
|
||||
{
|
||||
var encoded = JsonConvert.SerializeObject(sourceFilePath);
|
||||
var client = HttpUtilities.GetClient(_ArchiverApiConfig.FileOperationApiValidateFileExists);
|
||||
var content = new StringContent(encoded, Encoding.UTF8, "application/json");
|
||||
HttpResponseMessage response = await client.PostAsync(_ArchiverApiConfig.FileOperationApiValidateFileExists, content);
|
||||
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
throw new Exception($"IsSuccessStatusCode: {response.IsSuccessStatusCode}");
|
||||
}
|
||||
|
||||
var stringResponse = await response.Content.ReadAsStringAsync();
|
||||
var result = JsonConvert.DeserializeObject<bool>(stringResponse);
|
||||
return result;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
throw new Exception($"Failure to validate files exist. " +
|
||||
$"Exception Message:{exception.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using LCU.Library.Internal.ArchiverApiModel.Entities;
|
||||
namespace LCU.Api.Internal.ArchiverApi.Services;
|
||||
|
||||
public interface IApplicationMappingService
|
||||
{
|
||||
Task<IEnumerable<ApplicationMapping>> GetAsync();
|
||||
Task<ApplicationMapping> GetByIdAsync(int id);
|
||||
Task<IEnumerable<ApplicationMapping>> GetByIdentifierAsync(string identifier);
|
||||
Task<ApplicationMapping> SaveAsync(ApplicationMapping applicationMapping);
|
||||
ApplicationMapping Update(ApplicationMapping applicationMapping);
|
||||
void DeleteAsync(int applicationMappingId);
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
using LCU.Library.Internal.ApiResponse.Models;
|
||||
namespace LCU.Api.Internal.ArchiverApi.Services;
|
||||
|
||||
public interface IArchiveCompletionService
|
||||
{
|
||||
void HandleReportArchiveCompletedRequest(Response response);
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
using System.Collections.Generic;
|
||||
using LCU.Library.Internal.FileOperationsModels.Models;
|
||||
using LCU.Library.Internal.FileOperationsModels.Models.NameSettings;
|
||||
using LCU.Library.Internal.ArchiverApiModel.Models;
|
||||
namespace LCU.Api.Internal.ArchiverApi.Services;
|
||||
|
||||
public interface IArchiverService
|
||||
{
|
||||
void ExecuteRequest(ArchiveRequest archiveRequest);
|
||||
(ArchiveRequestResponse archiveRequestResponse, bool queueReturnResponse) HandleArchiveRequest(ArchiveRequest archiveRequest);
|
||||
BulkOperationRequest<MoveFileRequest> BuildBulkOperationRequest(IEnumerable<Report> reports, ArchiveRequest archiveRequest);
|
||||
string BuildExtensionRegexString(ArchiveRequest archiveRequest);
|
||||
List<MoveFileRequest> CreateOperationRequests(Report report, DynamicNameSetting nameSettings, ArchiveRequest archiveRequest);
|
||||
void SetDestinationName(Report report, MoveFileRequest request, ArchiveRequest archiveRequest);
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using LCU.Library.Internal.ArchiverApiModel.Models;
|
||||
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.ApplicationHistories;
|
||||
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.CoreRequests;
|
||||
namespace LCU.Api.Internal.ArchiverApi.Services;
|
||||
|
||||
public interface ICoreApiWrapperService
|
||||
{
|
||||
Task<IEnumerable<ApplicationHistory>> GetApplicationHistories(ArchiveRequest archiveRequest);
|
||||
string SetUpUrl(ApplicationHistoryRequest applicationHistoryRequest);
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using LCU.Library.Internal.FileOperationsModels.Models;
|
||||
using LCU.Library.Internal.FileOperationsModels.Models.NameSettings;
|
||||
namespace LCU.Api.Internal.ArchiverApi.Services;
|
||||
|
||||
public interface IFileOperationsService
|
||||
{
|
||||
void SendBulkOperationsAsync(BulkOperationRequest<MoveFileRequest> bulkOperationRequest);
|
||||
Task<List<string>> BuildDynamicFileListAsync(string path, string file, DynamicNameSetting dynamicNameSetting);
|
||||
Task<bool> ValidateFileExists(string sourceFilePath);
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using LCU.Library.Internal.ArchiverApiModel.Models;
|
||||
namespace LCU.Api.Internal.ArchiverApi.Services;
|
||||
|
||||
public interface INotificationService
|
||||
{
|
||||
Task<bool> SendEmailAsync(List<string> recipients, string subject, string emailTemplate);
|
||||
Task<bool> SendErrorEmailAsync(List<ErrorDetail> errorDetails);
|
||||
string CreateErrorRow(ErrorDetail errorDetail, string basePath);
|
||||
string CreateErrorMonitoringEmail(string errorRows, string basePath);
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
using LCU.Library.Internal.ArchiverApiModel.Models;
|
||||
namespace LCU.Api.Internal.ArchiverApi.Services;
|
||||
|
||||
public interface IQueueArchiverService
|
||||
{
|
||||
void QueueArchiver(ArchiveRequest archiveRequest);
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
using LCU.Library.Internal.ArchiverApiModel.Entities;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace LCU.Api.Internal.ArchiverApi.Services;
|
||||
|
||||
public interface IRegexMappingService
|
||||
{
|
||||
Task<IEnumerable<RegexMapping>> GetAsync();
|
||||
Task<RegexMapping> GetByApplicationMappingIdAsync(int id);
|
||||
Task<RegexMapping> SaveAsync(RegexMapping regexMapping);
|
||||
RegexMapping Update(RegexMapping regexMapping);
|
||||
void DeleteAsync(int regexMappingId);
|
||||
public Task<RegexMapping> GetByRegexMappingIdAsync(int id);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using LCU.Library.Internal.ArchiverApiModel.Models;
|
||||
namespace LCU.Api.Internal.ArchiverApi.Services;
|
||||
|
||||
public interface IReportService
|
||||
{
|
||||
Task<IEnumerable<Report>> GetReportsToArchiveAsync(ArchiveRequest archiveRequest);
|
||||
}
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
using Serilog;
|
||||
using LCU.Api.Internal.ArchiverApi.Configuration;
|
||||
using LCU.API.Internal.NotificationsApiLib.Models;
|
||||
using LCU.Library.Internal.ArchiverApi.Utilities;
|
||||
using LCU.Library.Internal.ArchiverApiModel.Models;
|
||||
namespace LCU.Api.Internal.ArchiverApi.Services;
|
||||
|
||||
public class NotificationService : INotificationService
|
||||
{
|
||||
private readonly ArchiverApiConfig _ArchiverApiConfig;
|
||||
private const string TableRowsTag = "{TableRows}";
|
||||
|
||||
public NotificationService(ArchiverApiConfig ArchiverApiConfig)
|
||||
{
|
||||
_ArchiverApiConfig = ArchiverApiConfig;
|
||||
}
|
||||
|
||||
public async Task<bool> SendEmailAsync(List<string> recipients, string subject, string emailTemplate)
|
||||
{
|
||||
try
|
||||
{
|
||||
var emailRequest = new EmailRequest
|
||||
{
|
||||
Recipient = recipients,
|
||||
Subject = subject,
|
||||
Body = emailTemplate
|
||||
};
|
||||
|
||||
var encoded = JsonConvert.SerializeObject(emailRequest);
|
||||
var client = HttpUtilities.GetClient(_ArchiverApiConfig.NotificationApiEmail);
|
||||
var content = new StringContent(encoded, Encoding.UTF8, "application/json");
|
||||
HttpResponseMessage response = await client.PostAsync(_ArchiverApiConfig.NotificationApiEmail, content);
|
||||
response.EnsureSuccessStatusCode();
|
||||
return response.IsSuccessStatusCode;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, $"Failure to send email from Archiver Api");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<bool> SendErrorEmailAsync(List<ErrorDetail> errorDetails)
|
||||
{
|
||||
if (!errorDetails.Any())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var basePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory);
|
||||
string rowsOfErrors = "";
|
||||
foreach (var errorDetail in errorDetails)
|
||||
{
|
||||
rowsOfErrors += CreateErrorRow(errorDetail, basePath);
|
||||
}
|
||||
|
||||
var emailTemplate = CreateErrorMonitoringEmail(rowsOfErrors, basePath);
|
||||
var successfullySent = await SendEmailAsync(_ArchiverApiConfig.ErrorRecipients,
|
||||
_ArchiverApiConfig.ErrorMonitoringSubject,
|
||||
emailTemplate);
|
||||
return successfullySent;
|
||||
}
|
||||
|
||||
public string CreateErrorRow(ErrorDetail errorDetail, string basePath)
|
||||
{
|
||||
var errorRowReader = new StreamReader($"{basePath}{_ArchiverApiConfig.ErrorRowTemplate}");
|
||||
string errorRowOutput = errorRowReader.ReadToEnd();
|
||||
|
||||
foreach (var property in errorDetail.GetType().GetProperties())
|
||||
{
|
||||
string value = property.GetValue(errorDetail) == null ?
|
||||
string.Empty :
|
||||
property.GetValue(errorDetail).ToString();
|
||||
errorRowOutput = errorRowOutput.Replace($"{{{property.Name}}}", value);
|
||||
}
|
||||
|
||||
return errorRowOutput;
|
||||
}
|
||||
|
||||
public string CreateErrorMonitoringEmail(string errorRows, string basePath)
|
||||
{
|
||||
var errorMonitoringReader = new StreamReader($"{basePath}{_ArchiverApiConfig.ErrorMonitoringTemplate}");
|
||||
string errorMonitoringOutput = errorMonitoringReader.ReadToEnd();
|
||||
return errorMonitoringOutput.Replace(TableRowsTag, errorRows);
|
||||
}
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using Serilog;
|
||||
using MassTransit;
|
||||
using TimeZoneConverter;
|
||||
using LCU.Library.Internal.ArchiverApiModel.Models;
|
||||
using LCU.Api.Internal.ArchiverApi.Configuration;
|
||||
using LCU.Library.Internal.LcuMassTransitModels;
|
||||
using LCU.Library.Internal.Exceptions;
|
||||
namespace LCU.Api.Internal.ArchiverApi.Services;
|
||||
|
||||
public class QueueArchiverService : IQueueArchiverService
|
||||
{
|
||||
private readonly ISendEndpoint _sendEndpoint;
|
||||
private readonly ReceiveEndpointConfiguration _receiveEndpointsConfiguration;
|
||||
private readonly ArchiverApiConfig _archiverApiConfig;
|
||||
|
||||
public QueueArchiverService(IBusControl busControl,
|
||||
ReceiveEndpointConfigurations receiveEndpointsConfiguration,
|
||||
ArchiverApiConfig archiverApiConfig)
|
||||
{
|
||||
_receiveEndpointsConfiguration = receiveEndpointsConfiguration.ArchiverReceiveEndpoint;
|
||||
_archiverApiConfig = archiverApiConfig;
|
||||
_sendEndpoint = busControl.GetSendEndpoint(_receiveEndpointsConfiguration.ReceiveEndpointUri).Result;
|
||||
}
|
||||
|
||||
public void QueueArchiver(ArchiveRequest archiveRequest)
|
||||
{
|
||||
try
|
||||
{
|
||||
var dateToConvert = archiveRequest.EffectiveDate == null ?
|
||||
DateTime.Now.AddDays(archiveRequest.DaysFromDate) :
|
||||
Convert.ToDateTime(archiveRequest.EffectiveDate).AddDays(archiveRequest.DaysFromDate);
|
||||
|
||||
var assumedTimezone = TZConvert.GetTimeZoneInfo(_archiverApiConfig.TimeZone);
|
||||
archiveRequest.EffectiveDate = TimeZoneInfo.ConvertTime(dateToConvert, assumedTimezone).Date;
|
||||
_sendEndpoint.Send(archiveRequest);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, $"Failed to queue archive request with effective date. Effective Date: {archiveRequest.EffectiveDate}");
|
||||
throw new ServiceException($"Failed to queue archive request with effective date. Effective Date: {archiveRequest.EffectiveDate}");
|
||||
}
|
||||
}
|
||||
}
|
||||
+150
@@ -0,0 +1,150 @@
|
||||
using LCU.Library.Internal.ArchiverApiLib.Repositories;
|
||||
using LCU.Library.Internal.ArchiverApiModel.Entities;
|
||||
using System.Data.SqlClient;
|
||||
using LCU.Library.Internal.Exceptions;
|
||||
using Serilog;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace LCU.Api.Internal.ArchiverApi.Services;
|
||||
|
||||
public class RegexMappingService : IRegexMappingService
|
||||
{
|
||||
private readonly IRegexMappingRepository _regexMappingRepository;
|
||||
private readonly IUnitOfWork _unitOfWork;
|
||||
|
||||
public RegexMappingService(IUnitOfWork unitOfWork,
|
||||
IRegexMappingRepository regexMappingRepository)
|
||||
{
|
||||
_unitOfWork = unitOfWork;
|
||||
_regexMappingRepository = regexMappingRepository;
|
||||
}
|
||||
public void DeleteAsync(int regexMappingId)
|
||||
{
|
||||
try
|
||||
{
|
||||
var regexMapping = _regexMappingRepository.FindByRegexMappingIdAsync(regexMappingId).Result;
|
||||
ArgumentNullException.ThrowIfNull(regexMapping);
|
||||
_regexMappingRepository.Remove(regexMapping);
|
||||
_unitOfWork.Complete();
|
||||
}
|
||||
catch (SqlException sqlException)
|
||||
{
|
||||
Log.Error(sqlException, $"SQL failure removing regex mapping. RegexMappingId: {regexMappingId}");
|
||||
throw new ServiceException($"SQL failure removing regex mapping. RegexMappingId: {regexMappingId}");
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, $"Failure removing regex mapping. RegexMappingId: {regexMappingId}");
|
||||
throw new ServiceException($"Failure removing regex mapping. RegexMappingId: {regexMappingId}");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<RegexMapping>> GetAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _regexMappingRepository.ListAsync();
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Failure retrieving regex mappings.");
|
||||
throw new ServiceException("Failure retrieving regex mappings.");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<RegexMapping> GetByApplicationMappingIdAsync(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var regexMapping = await _regexMappingRepository.FindByApplicationMappingIdAsync(id);
|
||||
ArgumentNullException.ThrowIfNull(regexMapping);
|
||||
return regexMapping;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, $"Failure retrieving regex mapping with id {id}.");
|
||||
throw new ServiceException($"Failure retrieving regex mapping with id {id}.");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<RegexMapping> GetByRegexMappingIdAsync(int id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var regexMapping = await _regexMappingRepository.FindByRegexMappingIdAsync(id);
|
||||
ArgumentNullException.ThrowIfNull(regexMapping);
|
||||
return regexMapping;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, $"Failure retrieving regex mapping with id {id}.");
|
||||
throw new ServiceException($"Failure retrieving regex mapping with id {id}.");
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<RegexMapping> SaveAsync(RegexMapping regexMapping)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (CheckTagInvalid(regexMapping.Tag))
|
||||
{
|
||||
throw new Exception("Invalid Tag: "+regexMapping.Tag);
|
||||
}
|
||||
var result = await _regexMappingRepository.AddAsync(regexMapping);
|
||||
await _unitOfWork.CompleteAsync();
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Failure saving regex mapping");
|
||||
throw new ServiceException("Failure saving regex mapping");
|
||||
}
|
||||
}
|
||||
|
||||
public RegexMapping Update(RegexMapping regexMapping)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (CheckTagInvalid(regexMapping.Tag))
|
||||
{
|
||||
throw new Exception("Invalid Tag: "+regexMapping.Tag);
|
||||
}
|
||||
var existing = GetByRegexMappingIdAsync(regexMapping.RegexMappingId).Result;
|
||||
ArgumentNullException.ThrowIfNull(existing);
|
||||
|
||||
existing.ApplicationMappingId = regexMapping.ApplicationMappingId;
|
||||
existing.Regex = regexMapping.Regex;
|
||||
existing.Tag = regexMapping.Tag;
|
||||
|
||||
_regexMappingRepository.Update(existing);
|
||||
_unitOfWork.Complete();
|
||||
|
||||
return existing;
|
||||
}
|
||||
catch (SqlException sqlException)
|
||||
{
|
||||
Log.Error(sqlException, "SQL Failure updating regex mapping");
|
||||
throw new ServiceException("SQL Failure updating regex mapping");
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
Log.Error(exception, "Failure updating regex mapping");
|
||||
throw new ServiceException("Failure updating regex mapping");
|
||||
}
|
||||
}
|
||||
|
||||
private bool CheckTagInvalid(string tag)
|
||||
{
|
||||
var endIndex = tag.IndexOf('}');
|
||||
var sub = tag.Substring(0, 6);
|
||||
if (tag.Substring(0,6) == "{Regex" && endIndex >= 7)
|
||||
{
|
||||
var tagNumber = Int32.Parse(tag.Substring(6, endIndex - 6));
|
||||
return tagNumber >= 0 && tagNumber <= 3;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using System.Linq;
|
||||
using LCU.Library.Internal.ArchiverApiModel.Models;
|
||||
using LCU.Library.Internal.ArchiverApiModel.Entities;
|
||||
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.ApplicationHistories;
|
||||
|
||||
namespace LCU.Api.Internal.ArchiverApi.Services;
|
||||
|
||||
public class ReportService : IReportService
|
||||
{
|
||||
private readonly ICoreApiWrapperService _coreApiWrapperService;
|
||||
private readonly IApplicationMappingService _applicationMappingService;
|
||||
private readonly IRegexMappingService _regexMappingService;
|
||||
|
||||
public ReportService(ICoreApiWrapperService coreApiWrapperService,
|
||||
IApplicationMappingService applicationMappingService,
|
||||
IRegexMappingService regexMappingService)
|
||||
{
|
||||
_coreApiWrapperService = coreApiWrapperService;
|
||||
_applicationMappingService = applicationMappingService;
|
||||
_regexMappingService = regexMappingService;
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<Report>> GetReportsToArchiveAsync(ArchiveRequest archiveRequest)
|
||||
{
|
||||
try
|
||||
{
|
||||
var applicationHistories = await _coreApiWrapperService.GetApplicationHistories(archiveRequest);
|
||||
var reports = new List<Report>();
|
||||
foreach (var applicationHistory in applicationHistories)
|
||||
{
|
||||
var applicationMappings = await _applicationMappingService.GetByIdentifierAsync(applicationHistory.ApplicationNumber.ToString());
|
||||
var report = new Report()
|
||||
{
|
||||
ReportName = applicationHistory.ApplicationName,
|
||||
QueueNumber = applicationHistory.QueueNumber.ToString(),
|
||||
StopDateTime = applicationHistory.StopDateTime,
|
||||
ApplicationMapping = DeteriminApplicationMapping(applicationMappings.ToList(), applicationHistory),
|
||||
};
|
||||
|
||||
reports.Add(report);
|
||||
}
|
||||
|
||||
return reports;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
throw new Exception($"Error while trying to get reports ready for archiving. " +
|
||||
$"Message: {exception.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
public ApplicationMapping DeteriminApplicationMapping(List<ApplicationMapping> applicationMappings, ApplicationHistory applicationHistory)
|
||||
{
|
||||
var applicationMapping = DeteriminApplicationMappingWithoutParameters(applicationMappings);
|
||||
if(applicationMapping != null)
|
||||
{
|
||||
return applicationMapping;
|
||||
}
|
||||
|
||||
applicationMapping = DeteriminApplicationMappingByParameters(applicationMappings, applicationHistory);
|
||||
return applicationMapping;
|
||||
}
|
||||
|
||||
public ApplicationMapping DeteriminApplicationMappingWithoutParameters(List<ApplicationMapping> possibleApplicationMappings)
|
||||
{
|
||||
var onlyASingleApplicationMapping = possibleApplicationMappings.Count == 1;
|
||||
if (onlyASingleApplicationMapping)
|
||||
{
|
||||
var singleApplicationMapping = possibleApplicationMappings.First();
|
||||
if (singleApplicationMapping.ParameterMappings == null ||
|
||||
!singleApplicationMapping.ParameterMappings.Any())
|
||||
{
|
||||
return singleApplicationMapping;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public ApplicationMapping DeteriminApplicationMappingByParameters(List<ApplicationMapping> possibleApplicationMappings, ApplicationHistory applicationHistory)
|
||||
{
|
||||
foreach (var applicationMapping in possibleApplicationMappings)
|
||||
{
|
||||
bool containsAllParameter = false;
|
||||
foreach (var parameterMapping in applicationMapping.ParameterMappings)
|
||||
{
|
||||
containsAllParameter = applicationHistory.QueueApplicationParameters.Any(qap => qap.ParameterCode == parameterMapping.ParameterCode &&
|
||||
qap.ParameterValue == parameterMapping.ParameterValue);
|
||||
|
||||
if (!containsAllParameter)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (containsAllParameter)
|
||||
{
|
||||
return applicationMapping;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Serilog;
|
||||
using MassTransit;
|
||||
using LCU.Library.Internal.Logging.Models;
|
||||
using LCU.Library.Internal.Logging;
|
||||
using LCU.Library.Internal.Logging.Middleware;
|
||||
using LCU.Api.Internal.ArchiverApi.Configuration;
|
||||
using LCU.Api.Internal.ArchiverApi.Models;
|
||||
using LCU.Api.Internal.ArchiverApi.Services;
|
||||
using LCU.Library.Internal.ArchiverApiLib.Repositories;
|
||||
using LCU.Library.Internal.ArchiverApiLib.Persistence;
|
||||
using LCU.Library.Internal.LcuMassTransit;
|
||||
using LCU.Library.Internal.LcuMassTransitModels;
|
||||
using LCU.Api.Internal.ArchiverApi.Consumers;
|
||||
namespace LCU.Api.Internal.ArchiverApi;
|
||||
|
||||
public class Startup
|
||||
{
|
||||
public Startup(IConfiguration configuration)
|
||||
{
|
||||
Configuration = configuration;
|
||||
}
|
||||
|
||||
public IConfiguration Configuration { get; }
|
||||
|
||||
// This method gets called by the runtime. Use this method to add services to the container.
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddControllers();
|
||||
services.AddHttpClient();
|
||||
services.AddDbContext<AppDbContext>(options =>
|
||||
{
|
||||
options.UseSqlServer(
|
||||
Configuration.GetSection("Primary").GetSection("Connections").GetSection("SQL").GetSection("ArchiverApiDb").Value
|
||||
);
|
||||
});
|
||||
|
||||
var archiverApiConfig = new ArchiverApiConfig();
|
||||
Configuration.GetSection("Primary").Bind(archiverApiConfig);
|
||||
services.AddSingleton(archiverApiConfig);
|
||||
|
||||
var loggerConfiguration = new LoggingConfiguration(archiverApiConfig.ApplicationName,
|
||||
archiverApiConfig.SeqApiKey,
|
||||
archiverApiConfig.SeqUrl);
|
||||
var lcuLogging = new LcuLogging(loggerConfiguration);
|
||||
lcuLogging.UseLcuLogging();
|
||||
|
||||
var connectionConfiguration = MassTransitConfigurationSetUp.AddConnectionConfiguration(ref services, Configuration);
|
||||
var receiveEndpointConfigurations = new ReceiveEndpointConfigurations()
|
||||
{
|
||||
ArchiverReceiveEndpoint = MassTransitConfigurationSetUp.GetReceiveEndpointConfiguration(Configuration,
|
||||
"ArchiverReceiveEndpoint"),
|
||||
ResponseReceiveEndpoint = MassTransitConfigurationSetUp.GetReceiveEndpointConfiguration(Configuration,
|
||||
"ResponseReceiveEndpoint")
|
||||
};
|
||||
services.AddSingleton(receiveEndpointConfigurations);
|
||||
AddMassTransitServices(ref services, connectionConfiguration, receiveEndpointConfigurations, archiverApiConfig);
|
||||
|
||||
services.AddScoped<IEnvironmentView, EnvironmentView>();
|
||||
|
||||
//Services
|
||||
services.AddScoped<IReportService, ReportService>();
|
||||
services.AddScoped<IApplicationMappingService, ApplicationMappingService>();
|
||||
services.AddScoped<IRegexMappingService, RegexMappingService>();
|
||||
services.AddScoped<IArchiverService, ArchiverService>();
|
||||
services.AddScoped<IQueueArchiverService, QueueArchiverService>();
|
||||
services.AddScoped<IArchiveCompletionService, ArchiveCompletionService>();
|
||||
services.AddScoped<IFileOperationsService, FileOperationsService>();
|
||||
services.AddScoped<INotificationService, NotificationService>();
|
||||
services.AddScoped<ICoreApiWrapperService, CoreApiWrapperService>();
|
||||
|
||||
//Repositories
|
||||
services.AddScoped<IApplicationMappingRepository, ApplicationMappingRepository>();
|
||||
services.AddScoped<IRegexMappingRepository, RegexMappingRepository>();
|
||||
services.AddScoped<IUnitOfWork, UnitOfWork>();
|
||||
|
||||
services.AddControllers().AddJsonOptions(options => options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()));
|
||||
services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = $"{archiverApiConfig.ApplicationName}", Version = "v1" }); });
|
||||
|
||||
}
|
||||
|
||||
public void AddMassTransitServices(ref IServiceCollection services,
|
||||
ConnectionConfiguration connectionConfiguration,
|
||||
ReceiveEndpointConfigurations receiveEndpointConfigurations,
|
||||
ArchiverApiConfig archiverApiConfig)
|
||||
{
|
||||
services.AddMassTransit(x =>
|
||||
{
|
||||
x.AddConsumer<ArchiverConsumer>();
|
||||
x.AddConsumer<ResponseConsumer>();
|
||||
|
||||
x.UsingRabbitMq((context, cfg) =>
|
||||
{
|
||||
cfg.Host(connectionConfiguration.HostUrl, "/", host =>
|
||||
{
|
||||
host.Username(connectionConfiguration.UserName);
|
||||
host.Password(connectionConfiguration.Password);
|
||||
});
|
||||
|
||||
if (archiverApiConfig.FeatureFlags.RunArchiverConsumer)
|
||||
{
|
||||
cfg.ReceiveEndpoint(receiveEndpointConfigurations.ArchiverReceiveEndpoint.ReceiveEndpoint, e =>
|
||||
{
|
||||
e.ConfigureConsumer<ArchiverConsumer>(context);
|
||||
e.PrefetchCount = receiveEndpointConfigurations.ArchiverReceiveEndpoint.PrefetchLimit;
|
||||
e.SetQuorumQueue();
|
||||
});
|
||||
}
|
||||
|
||||
if (archiverApiConfig.FeatureFlags.RunResponseConsumer)
|
||||
{
|
||||
cfg.ReceiveEndpoint(receiveEndpointConfigurations.ResponseReceiveEndpoint.ReceiveEndpoint, e =>
|
||||
{
|
||||
e.ConfigureConsumer<ResponseConsumer>(context);
|
||||
e.PrefetchCount = receiveEndpointConfigurations.ResponseReceiveEndpoint.PrefetchLimit;
|
||||
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)
|
||||
{
|
||||
if (env.IsDevelopment())
|
||||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
}
|
||||
|
||||
app.UseSwagger();
|
||||
app.UseSwaggerUI(c => c.SwaggerEndpoint("v1/swagger.json", "LCU.Api.Internal.ArchiverApi v1"));
|
||||
app.UseMiddleware<RequestResponseLoggingMiddleware>();
|
||||
app.UseSerilogRequestLogging(options => { options.EnrichDiagnosticContext = RequestResponseLoggingMiddleware.RequestDataParser.EnrichFromRequest; });
|
||||
app.UseHttpsRedirection();
|
||||
app.UseRouting();
|
||||
app.UseAuthorization();
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
endpoints.MapControllers();
|
||||
});
|
||||
}
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<style>
|
||||
#errors {
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#errors td, #errors th {
|
||||
border: 1px solid #ddd;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
#errors tr:nth-child(even) {
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
|
||||
#errors th {
|
||||
padding-top: 12px;
|
||||
padding-bottom: 12px;
|
||||
text-align: left;
|
||||
background-color: #4CAF50;
|
||||
color: white;
|
||||
}
|
||||
|
||||
#emailHeader {
|
||||
color: #0054a2;
|
||||
}
|
||||
|
||||
#errorTableHeader {
|
||||
background-color: #0054a2;
|
||||
color: white;
|
||||
}
|
||||
</style>
|
||||
|
||||
<meta charset="utf-8">
|
||||
<title>Archiver Api: Error Monitoring</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1><span id="emailHeader">Archiver Api: Error Monitoring</span></h1>
|
||||
<table id="errors">
|
||||
<thead id="errorTableHeader">
|
||||
<tr style="height: 17px;">
|
||||
<td style="max-width: 250px;font-weight: bolder;">Filename</td>
|
||||
<td style="max-width: 200px;font-weight: bolder;">File Location</td>
|
||||
<td style="max-width: 79px;font-weight: bolder;">Destination</td>
|
||||
<td style="max-width: 150px;font-weight: bolder;">Description</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="errorRows">
|
||||
{TableRows}
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
<tr id="errorRow" style="height: 22px;">
|
||||
<td style="max-width: 250px;">{Filename}</td>
|
||||
<td style="max-width: 200px;">{FileLocation}</td>
|
||||
<td style="max-width: 79px;">{Destination}</td>
|
||||
<td style="max-width: 150px;">{Description}</td>
|
||||
</tr>
|
||||
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
namespace LCU.Library.Internal.ArchiverApi.Utilities;
|
||||
|
||||
public static class HttpUtilities
|
||||
{
|
||||
private const int ParamCounterDefault = 1;
|
||||
|
||||
public static HttpClient GetClient(string url)
|
||||
{
|
||||
var handler = new HttpClientHandler
|
||||
{
|
||||
SslProtocols = System.Security.Authentication.SslProtocols.Tls12 |
|
||||
System.Security.Authentication.SslProtocols.Tls11 |
|
||||
System.Security.Authentication.SslProtocols.Tls,
|
||||
ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true
|
||||
};
|
||||
|
||||
var httpClient = new HttpClient(handler)
|
||||
{
|
||||
Timeout = TimeSpan.FromSeconds(60),
|
||||
BaseAddress = new Uri(url)
|
||||
};
|
||||
|
||||
return httpClient;
|
||||
}
|
||||
|
||||
public static void AppendListOfValuesToEndpoint<T>(StringBuilder endpointBuilder, int currentIndex, List<T> listOfValues, string propertyName)
|
||||
{
|
||||
foreach (var value in listOfValues)
|
||||
{
|
||||
var splitter = currentIndex == 0 ? "?" : "&";
|
||||
endpointBuilder.Append($"{splitter}{propertyName}={value}");
|
||||
currentIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"Primary": {
|
||||
"SeqUrl": "https://qa-seq.lcu-internal.com",
|
||||
"SeqApiKey": "STORED_IN_VAULT",
|
||||
"ApplicationName": "ArchiverApi",
|
||||
"NotificationApiEmail": "https://qa-notifications-api.apps.azure.lcu-internal.com/api/Email",
|
||||
"FileOperationApiBulkMoveFile": "https://localhost:44323/api/FileOperations/BulkMoveFile",
|
||||
"FileOperationApiBuildDynamicFileList": "https://qa-fileoperationsapi.lcu-internal.com/DynamicFile/BuildDynamicFileList",
|
||||
"FileOperationApiValidateFileExists": "https://qa-fileoperationsapi.lcu-internal.com/FileValidation/ValidateFileExists",
|
||||
"CoreApiWrapperGetApplicationHistory": "https://qa-core-api-wrapper-api.apps.azure.lcu-internal.com/api/core/ApplicationHistory/GetApplicationHistory",
|
||||
"DnaBasePath": "\\\\zeus\\DataIntegrationsQA\\AutomicArchive\\TEST_DNA",
|
||||
"ReportPathDateFormat": "yyyyMMdd",
|
||||
"ErrorMonitoringTemplate": "/Templates/ErrorMonitoringTemplate.html",
|
||||
"ErrorRowTemplate": "/Templates/ErrorRowTemplate.html",
|
||||
"ErrorMonitoringSubject": "Archiver Api: Error Monitoring",
|
||||
"ErrorRecipients": [ "[email protected]", "[email protected]" ],
|
||||
"TimeZone": "America/Chicago",
|
||||
"Connections": {
|
||||
"SQL": {
|
||||
"ArchiverApiDb": "data source=localhost;initial catalog=ArchiverApi;Integrated Security=SSPI;MultipleActiveResultSets=True;App=EntityFramework"
|
||||
}
|
||||
},
|
||||
"FeatureFlags": {
|
||||
"RunArchiverConsumer": true,
|
||||
"RunResponseConsumer": true
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*",
|
||||
"ConnectionConfiguration": {
|
||||
"HostUrl": "localhost",
|
||||
"UserName": "guest",
|
||||
"Password": "guest"
|
||||
},
|
||||
"ArchiverReceiveEndpoint": {
|
||||
"ReceiveEndpoint": "LCU.Archiver",
|
||||
"ReceiveEndpointType": "exchange",
|
||||
"PrefetchLimit": 1
|
||||
},
|
||||
"ResponseReceiveEndpoint": {
|
||||
"ReceiveEndpoint": "LCU.Archiver.Response",
|
||||
"ReceiveEndpointType": "exchange",
|
||||
"PrefetchLimit": 1
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user