This commit is contained in:
Zeeshaun
2026-03-25 14:50:13 -05:00
parent 883009770f
commit b690921fd7
592 changed files with 46618 additions and 0 deletions
@@ -0,0 +1,363 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# ASP.NET Scaffolding
ScaffoldingReadMe.txt
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Coverlet is a free, cross platform Code Coverage Tool
coverage*.json
coverage*.xml
coverage*.info
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
# Fody - auto-generated XML schema
FodyWeavers.xsd
.idea/**
@@ -0,0 +1,41 @@
# .NET Core SDK
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS aspnetcore-build
# Copy Projects
COPY LCU.API.Internal.DocumentIngestor/LCU.API.Internal.DocumentIngestor.csproj ./source/LCU.API.Internal.DocumentIngestor/
COPY LCU.API.Internal.DocumentIngestorLib/LCU.API.Internal.DocumentIngestorLib.csproj ./source/LCU.API.Internal.DocumentIngestorLib/
COPY LCU.Library.Internal.DocumentIngestorModels/LCU.Library.Internal.DocumentIngestorModels.csproj ./source/LCU.Library.Internal.DocumentIngestorModels/
# Install Credential Provider and set env variables to enable Nuget restore with auth
ARG PAT=bh2lq3jibktw67b2wdbqyfln7cd3je6lk52kijntpj43v6kimpgq
RUN curl -L https://raw.githubusercontent.com/Microsoft/artifacts-credprovider/master/helpers/installcredprovider.sh | sh
#RUN wget -qO- https://raw.githubusercontent.com/Microsoft/artifacts-credprovider/master/helpers/installcredprovider.sh | bash
ENV NUGET_CREDENTIALPROVIDER_SESSIONTOKENCACHE_ENABLED true
ENV VSS_NUGET_EXTERNAL_FEED_ENDPOINTS "{\"endpointCredentials\": [{\"endpoint\":\"https://landmarkcu.pkgs.visualstudio.com/_packaging/LCU-Internal/nuget/v3/index.json\", \"password\":\"${PAT}\"}]}"
# .NET Core Restore, use auth'd feed
RUN dotnet restore -s "https://landmarkcu.pkgs.visualstudio.com/_packaging/LCU-Internal/nuget/v3/index.json" -s "https://api.nuget.org/v3/index.json" ./source/LCU.API.Internal.DocumentIngestor/LCU.API.Internal.DocumentIngestor.csproj
# Copy All Files
COPY . ./source/
FROM aspnetcore-build AS test
LABEL test=true
COPY LCU.API.Internal.DocumentIngestorTests/LCU.API.Internal.DocumentIngestorTests.csproj ./source/LCU.API.Internal.DocumentIngestorTests/
RUN dotnet restore ./source/LCU.API.Internal.DocumentIngestorTests/LCU.API.Internal.DocumentIngestorTests.csproj
RUN dotnet test -c Release --results-directory /testresults --logger "trx;LogFileName=test_results.trx" ./source/LCU.API.Internal.DocumentIngestorTests/LCU.API.Internal.DocumentIngestorTests.csproj
# .NET Core Publish
FROM aspnetcore-build as publish
RUN dotnet publish ./source/LCU.API.Internal.DocumentIngestor/LCU.API.Internal.DocumentIngestor.csproj -c Release -o /dist
# ASP.NET Core
FROM mcr.microsoft.com/dotnet/aspnet:8.0-alpine3.20
RUN apk add --no-cache icu-libs && apk add --no-cache tzdata;
ENV TZ America/Chicago
ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=false
ENV ASPNETCORE_ENVIRONMENT=Development
WORKDIR /app
COPY --from=publish /dist .
ENTRYPOINT ["dotnet", "LCU.API.Internal.DocumentIngestor.dll"]
@@ -0,0 +1,71 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.32112.339
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LCU.API.Internal.DocumentIngestor", "LCU.API.Internal.DocumentIngestor\LCU.API.Internal.DocumentIngestor.csproj", "{9A992EC6-3DC7-40E8-B091-D1F5CB89DCBC}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LCU.Library.Internal.DocumentIngestorModels", "LCU.Library.Internal.DocumentIngestorModels\LCU.Library.Internal.DocumentIngestorModels.csproj", "{7CF884F8-E4AA-4AD4-8F18-839E917189C4}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LCU.API.Internal.DocumentIngestorLib", "LCU.API.Internal.DocumentIngestorLib\LCU.API.Internal.DocumentIngestorLib.csproj", "{8FD9C489-045E-4530-9980-F4ACBDFB71A4}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LCU.API.Internal.DocumentIngestorTests", "LCU.API.Internal.DocumentIngestorTests\LCU.API.Internal.DocumentIngestorTests.csproj", "{9CE57A4B-7C3E-4750-B2D5-8AF4590AADEE}"
EndProject
Project("{00D1A9C2-B5F0-4AF3-8072-F6C62B433612}") = "LCU.API.Internal.DocumentIngestorSql", "LCU.API.Internal.DocumentIngestorSql\LCU.API.Internal.DocumentIngestorSql.sqlproj", "{781F2DE1-9629-49D1-82A4-015B62EE92EF}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LCU.API.Internal.DocumentIngestorLibTests", "LCU.API.Internal.DocumentIngestorLibTests\LCU.API.Internal.DocumentIngestorLibTests.csproj", "{D91F57F1-CD10-497E-BB5B-99F421D8188C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
Test|Any CPU = Test|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{9A992EC6-3DC7-40E8-B091-D1F5CB89DCBC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9A992EC6-3DC7-40E8-B091-D1F5CB89DCBC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9A992EC6-3DC7-40E8-B091-D1F5CB89DCBC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9A992EC6-3DC7-40E8-B091-D1F5CB89DCBC}.Release|Any CPU.Build.0 = Release|Any CPU
{9A992EC6-3DC7-40E8-B091-D1F5CB89DCBC}.Test|Any CPU.ActiveCfg = Test|Any CPU
{9A992EC6-3DC7-40E8-B091-D1F5CB89DCBC}.Test|Any CPU.Build.0 = Test|Any CPU
{7CF884F8-E4AA-4AD4-8F18-839E917189C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7CF884F8-E4AA-4AD4-8F18-839E917189C4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7CF884F8-E4AA-4AD4-8F18-839E917189C4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7CF884F8-E4AA-4AD4-8F18-839E917189C4}.Release|Any CPU.Build.0 = Release|Any CPU
{7CF884F8-E4AA-4AD4-8F18-839E917189C4}.Test|Any CPU.ActiveCfg = Test|Any CPU
{7CF884F8-E4AA-4AD4-8F18-839E917189C4}.Test|Any CPU.Build.0 = Test|Any CPU
{8FD9C489-045E-4530-9980-F4ACBDFB71A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8FD9C489-045E-4530-9980-F4ACBDFB71A4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8FD9C489-045E-4530-9980-F4ACBDFB71A4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8FD9C489-045E-4530-9980-F4ACBDFB71A4}.Release|Any CPU.Build.0 = Release|Any CPU
{8FD9C489-045E-4530-9980-F4ACBDFB71A4}.Test|Any CPU.ActiveCfg = Test|Any CPU
{8FD9C489-045E-4530-9980-F4ACBDFB71A4}.Test|Any CPU.Build.0 = Test|Any CPU
{9CE57A4B-7C3E-4750-B2D5-8AF4590AADEE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9CE57A4B-7C3E-4750-B2D5-8AF4590AADEE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9CE57A4B-7C3E-4750-B2D5-8AF4590AADEE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9CE57A4B-7C3E-4750-B2D5-8AF4590AADEE}.Release|Any CPU.Build.0 = Release|Any CPU
{9CE57A4B-7C3E-4750-B2D5-8AF4590AADEE}.Test|Any CPU.ActiveCfg = Test|Any CPU
{9CE57A4B-7C3E-4750-B2D5-8AF4590AADEE}.Test|Any CPU.Build.0 = Test|Any CPU
{781F2DE1-9629-49D1-82A4-015B62EE92EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{781F2DE1-9629-49D1-82A4-015B62EE92EF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{781F2DE1-9629-49D1-82A4-015B62EE92EF}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{781F2DE1-9629-49D1-82A4-015B62EE92EF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{781F2DE1-9629-49D1-82A4-015B62EE92EF}.Release|Any CPU.Build.0 = Release|Any CPU
{781F2DE1-9629-49D1-82A4-015B62EE92EF}.Release|Any CPU.Deploy.0 = Release|Any CPU
{781F2DE1-9629-49D1-82A4-015B62EE92EF}.Test|Any CPU.ActiveCfg = Release|Any CPU
{781F2DE1-9629-49D1-82A4-015B62EE92EF}.Test|Any CPU.Build.0 = Release|Any CPU
{781F2DE1-9629-49D1-82A4-015B62EE92EF}.Test|Any CPU.Deploy.0 = Release|Any CPU
{D91F57F1-CD10-497E-BB5B-99F421D8188C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D91F57F1-CD10-497E-BB5B-99F421D8188C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D91F57F1-CD10-497E-BB5B-99F421D8188C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D91F57F1-CD10-497E-BB5B-99F421D8188C}.Release|Any CPU.Build.0 = Release|Any CPU
{D91F57F1-CD10-497E-BB5B-99F421D8188C}.Test|Any CPU.ActiveCfg = Test|Any CPU
{D91F57F1-CD10-497E-BB5B-99F421D8188C}.Test|Any CPU.Build.0 = Test|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {65B8A2AE-E03C-4F4D-80C3-8747BAC5B819}
EndGlobalSection
EndGlobal
@@ -0,0 +1,25 @@
namespace LCU.API.Internal.DocumentIngestor.Configurations;
public class ApiConfiguration
{
public string AppName { get; set; }
public string SeqUrl { get; set; }
public string SeqApiKey { get; set; }
public string TimeZone { get; set; }
public string[] CorsAllowedOrigins { get; set; }
public FeatureFlags FeatureFlags { get; set; }
public string ProcessStatusTypeEmailUrl { get; set; }
public int CriticalFailureReprocessLimit { get; set; }
public int NotificationDataFailureReprocessLimit { get; set; }
public int CompletionRetryCount { get; set; }
public int DocumentProcessingReQueueCountLimit { get; set; } = 0;
public string DocumentIngestorApiKey { get; set; }
public int FileUploadCutoffHours { get; set; }
public int MaxMemberNotificationAttempts { get; set; }
public int MaliciousFileSearchPaddingHours { get; set; }
public string NotificationEmailTemplate { get; set; }
public string NotificationEmailRowTemplate { get; set; }
public bool IsHistoric { get; set; }
public int BatchSkipAmount { get; set; }
public Notifications Notifications { get; set; } = new();
}
@@ -0,0 +1,58 @@
using System.ComponentModel.DataAnnotations.Schema;
namespace LCU.API.Internal.DocumentIngestor.Configurations;
public class CoreApiWrapperConfiguration
{
public string Url { get; set; }
public string GetPersonsTaxIdData { get; set; }
public string GetOrganizationsTaxIdData { get; set; }
public string GetOwnersByAccountNumber { get; set; }
public string GetOwnersByOrganizationName { get; set; }
public string GetOwnersByPersonName { get; set; }
public string GetAgreementByUserId { get; set; }
public string GetAgreeUsersByAccounts { get; set; }
public string GetAgreeUsersByPersonNumber { get; set; }
public string GetAgreeUserByOrganizationNumber { get; set; }
public string GetAgreementAccountByAccountId { get; set; }
public string GetAgreementAccountsByUserId { get; set; }
public string GetPersonOrOrganizationNumberByMemberId { get; set; }
public int RetryCount { get; set; }
[NotMapped]
public string GetPersonsTaxIdDataUrl => Url + GetPersonsTaxIdData;
[NotMapped]
public string GetOrganizationsTaxIdDataUrl => Url + GetOrganizationsTaxIdData;
[NotMapped]
public string GetOwnersByAccountNumberUrl => Url + GetOwnersByAccountNumber;
[NotMapped]
public string GetOwnersByOrganizationNameUrl => Url + GetOwnersByOrganizationName;
[NotMapped]
public string GetOwnersByPersonNameUrl => Url + GetOwnersByPersonName;
[NotMapped]
public string GetAgreementByUserIdUrl => Url + GetAgreementByUserId;
[NotMapped]
public string GetAgreeUsersByAccountsUrl => Url + GetAgreeUsersByAccounts;
[NotMapped]
public string GetAgreeUsersByPersonNumberUrl => Url + GetAgreeUsersByPersonNumber;
[NotMapped]
public string GetAgreeUserByOrganizationNumberUrl => Url + GetAgreeUserByOrganizationNumber;
[NotMapped]
public string GetAgreementAccountByAccountIdUrl => Url + GetAgreementAccountByAccountId;
[NotMapped]
public string GetAgreementAccountsByUserIdUrl => Url + GetAgreementAccountsByUserId;
[NotMapped]
public string GetPersonOrOrganizationNumberByMemberIdUrl => Url + GetPersonOrOrganizationNumberByMemberId;
}
@@ -0,0 +1,19 @@
using System.ComponentModel.DataAnnotations.Schema;
namespace LCU.API.Internal.DocumentIngestor.Configurations;
public class DigitalBankingConfiguration
{
public string DigitalBankingUrl { get; set; }
public string MobileBankingBaseUrl {get; set;}
public string MobileBankingApiKey { get; set; }
public string MobileBankingLinkId { get; set; }
[NotMapped]
public Uri MobileBankingUri
{
get
{
return new Uri(MobileBankingBaseUrl+"?Link="+MobileBankingLinkId+"&Key="+MobileBankingApiKey);
}
}
}
@@ -0,0 +1,8 @@
using LCU.Library.Internal.DispatcherModels.Entities;
namespace LCU.API.Internal.DocumentIngestor.Configurations;
public class DispatcherJobCreationConfiguration
{
public List<string> DocumentIngestorDispatcherErrorRecipients { get; set; }
public List<JobTag> JobTags { get; set; }
}
@@ -0,0 +1,8 @@
namespace LCU.API.Internal.DocumentIngestor.Configurations
{
public class DocumentCodeDetailCacheConfiguration
{
public string CacheName { get; set; }
public int ExpirationMinutes { get; set; }
}
}
@@ -0,0 +1,26 @@
using System.ComponentModel.DataAnnotations.Schema;
namespace LCU.API.Internal.DocumentIngestor.Configurations;
public class DocumentTypeRetrieverConfiguration
{
public string Url { get; set; }
public string GetDocumentCodeDetail { get; set; }
public string GetDocumentCodeDetails { get; set; }
public string GetListOfMaliciousDocuments { get; set; }
public string GetDocumentInformationById { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public int RetryCount { get; set; }
[NotMapped]
public string GetDocumentCodeDetailUrl => Url + GetDocumentCodeDetail;
[NotMapped]
public string GetDocumentCodeDetailsUrl => Url + GetDocumentCodeDetails;
[NotMapped]
public string GetListOfMaliciousDocumentsUrl => Url + GetListOfMaliciousDocuments;
[NotMapped]
public string GetDocumentInformationByIdUrl => Url + GetDocumentInformationById;
}
@@ -0,0 +1,38 @@
using System.ComponentModel.DataAnnotations.Schema;
namespace LCU.API.Internal.DocumentIngestor.Configurations;
public class DocumentTypeUploaderConfiguration
{
public string Url { get; set; }
public string QueuePrimaryOwnerDocumentUpload {get; set;}
public string QueueAccountDocumentUpload { get; set; }
public string QueueGenericDocumentUpload { get; set; }
public int RetryCount { get; set; }
[NotMapped]
public Uri QueuePrimaryOwnerDocumentUploadUri
{
get
{
return new Uri(Url+QueuePrimaryOwnerDocumentUpload);
}
}
[NotMapped]
public Uri QueueAccountDocumentUploadUri
{
get
{
return new Uri(Url + QueueAccountDocumentUpload);
}
}
[NotMapped]
public Uri QueueGenericDocumentUploadUri
{
get
{
return new Uri(Url + QueueGenericDocumentUpload);
}
}
}
@@ -0,0 +1,19 @@
namespace LCU.API.Internal.DocumentIngestor.Configurations;
public class FeatureFlags
{
public bool RunBatchIngestionConsumer { get; set; }
public bool RunIngestorIndexConsumer { get; set; }
public bool RunIngestorProcessingConsumer { get; set; }
public bool RunIngestorCompletionConsumer { get; set; }
public bool RunIngestionFolderCleanUpConsumer { get; set; }
public bool RunPdfPartitionerConsumer { get; set; }
public bool RunPdfPartitionerCompletionConsumer { get; set; }
public bool RunUploadCompletionConsumer { get; set; }
public bool RunMemberDocumentNotifierConsumer { get; set; }
public bool RunMemberNotificationCompletionConsumer { get; set; }
public bool RestrictNotificationRecipients { get; set; }
public bool RunGatherMemberNotificationInfoConsumer { get; set; }
public bool RunBatchUpdateMemberNotificationDataConsumer { get; set; }
public bool RunProcessStatusTypeSummaryConsumer { get; set; }
}
@@ -0,0 +1,64 @@
using System.ComponentModel.DataAnnotations.Schema;
namespace LCU.API.Internal.DocumentIngestor.Configurations;
public class FileOperationsApiConfiguration
{
public string Url { get; set; }
public string GetFileContentEndpoint { get; set; }
public string GetPdfContentEndpoint { get; set; }
public string ValidateFileExists { get; set; }
public string ValidatePdfPageExists { get; set; }
public string BuildDynamicDirectoryList { get; set; }
public string BuildDynamicFileList { get; set; }
public string QueueBatchPdfParser { get; set; }
public string DirectMoveFile { get; set; }
public string DirectWriteFile { get; set; }
public string DirectCreateDirectory { get; set; }
public string DirectUnzipFile { get; set; }
public string DirectZipFile { get; set; }
public string DirectDeleteDirectory { get; set; }
public string DirectDeleteFile { get; set; }
public int RetryCount { get; set; }
[NotMapped]
public Uri GetFileContentUri => new Uri(Url + GetFileContentEndpoint);
[NotMapped]
public Uri GetPdfContentUri => new Uri(Url + GetPdfContentEndpoint);
[NotMapped]
public Uri ValidateFileExistsUri => new Uri(Url + ValidateFileExists);
[NotMapped]
public Uri ValidatePdfPageExistsUri => new Uri(Url + ValidatePdfPageExists);
[NotMapped]
public Uri BuildDynamicDirectoryListUri => new Uri(Url + BuildDynamicDirectoryList);
[NotMapped]
public Uri BuildDynamicFileListUri => new Uri(Url + BuildDynamicFileList);
[NotMapped]
public Uri QueueBatchPdfParserUri => new Uri(Url + QueueBatchPdfParser);
[NotMapped]
public Uri DirectMoveFileUri => new Uri(Url + DirectMoveFile);
[NotMapped]
public Uri DirectWriteFileUri => new Uri(Url + DirectWriteFile);
[NotMapped]
public Uri DirectCreateDirectoryUri => new Uri(Url + DirectCreateDirectory);
[NotMapped]
public Uri DirectUnzipFileUri => new Uri(Url + DirectUnzipFile);
[NotMapped]
public Uri DirectZipFileUri => new Uri(Url + DirectZipFile);
[NotMapped]
public Uri DirectDeleteDirectoryUri => new Uri(Url + DirectDeleteDirectory);
[NotMapped]
public Uri DirectDeleteFileUri => new Uri(Url + DirectDeleteFile);
}
@@ -0,0 +1,25 @@
using System.ComponentModel.DataAnnotations.Schema;
namespace LCU.API.Internal.DocumentIngestor.Configurations;
public class MemberPreferencesApiConfiguration
{
public string Url { get; set; }
public string GetMemberOptInAgreementInfoByUserId { get; set; }
public string GetMemberOptInSettingsByUserId { get; set; }
public string EmailSuccessfulSend { get; set; }
public string EmailFailedSend { get; set; }
public int RetryCount { get; set; }
[NotMapped]
public string GetMemberOptInAgreementInfoByUserIdUrl => Url + GetMemberOptInAgreementInfoByUserId;
[NotMapped]
public string GetMemberOptInSettingsByUserIdUrl => Url + GetMemberOptInSettingsByUserId;
[NotMapped]
public string EmailSuccessfulSendUrl => Url + EmailSuccessfulSend;
[NotMapped]
public string EmailFailedSendUrl => Url + EmailFailedSend;
}
@@ -0,0 +1,12 @@
using System.ComponentModel.DataAnnotations.Schema;
namespace LCU.API.Internal.DocumentIngestor.Configurations;
public class NotificationApiConfiguration
{
public string Url { get; set; }
public string Email { get; set; }
public int RetryCount { get; set; }
[NotMapped]
public string EmailUrl => Url + Email;
}
@@ -0,0 +1,6 @@
namespace LCU.API.Internal.DocumentIngestor.Configurations;
public class Notifications
{
public string? AllowedRecipientExpression { get; set; }
}
@@ -0,0 +1,19 @@
using LCU.Library.Internal.LcuMassTransitModels;
namespace LCU.API.Internal.DocumentIngestor.Configurations;
public class ReceiveEndpointConfigurations
{
public ReceiveEndpointConfiguration BatchIngestionReceiveEndpoint { get; set; }
public ReceiveEndpointConfiguration DocumentIngestorReceiveEndpoint { get; set; }
public ReceiveEndpointConfiguration DocumentIngestorProcessingReceiveEndpoint { get; set; }
public ReceiveEndpointConfiguration DocumentIngestorCompletionReceiveEndpoint { get; set; }
public ReceiveEndpointConfiguration PdfPartitionerEndpoint { get; set; }
public ReceiveEndpointConfiguration PdfPartitionerCompletionEndpoint { get; set; }
public ReceiveEndpointConfiguration UploadCompletionEndpoint { get; set; }
public ReceiveEndpointConfiguration MemberDocumentNotifierEndpoint { get; set; }
public ReceiveEndpointConfiguration MemberNotificationCompletionEndpoint { get; set; }
public ReceiveEndpointConfiguration IngestionFolderCleanUpReceiveEndpoint { get; set; }
public ReceiveEndpointConfiguration GatherMemberNotificationInfoReceiveEndpoint { get; set; }
public ReceiveEndpointConfiguration BatchUpdateMemberNotificationDataEndpoint { get; set; }
public ReceiveEndpointConfiguration ProcessStatusTypeEmailReceiveEndpoint { get; set; }
}
@@ -0,0 +1,8 @@
namespace LCU.API.Internal.DocumentIngestor.Configurations;
public class SqlConnectionConfiguration
{
public string ConnectionString { get; set; }
public int MaxRetryCount { get; set; }
public TimeSpan MaxRetryDelay { get; set; }
}
@@ -0,0 +1,44 @@
using MassTransit;
using Serilog;
using LCU.Library.Internal.Exceptions;
using LCU.Api.Internal.MaidBotLib.Models;
using LCU.API.Internal.DocumentIngestor.Services.IngestionOperationServices;
using LCU.Library.Internal.DocumentIngestorModels.Models;
namespace LCU.API.Internal.DocumentIngestor.Consumers;
public class BatchIngestionConsumer : IConsumer<BatchIngestionRequest>
{
private readonly IServiceScopeFactory _scopeFactory;
public BatchIngestionConsumer(IServiceScopeFactory scopeFactory)
{
_scopeFactory = scopeFactory;
}
public async Task Consume(ConsumeContext<BatchIngestionRequest> context)
{
try
{
Log.Debug("Starting HandleBatchIngestion.");
using var scope = _scopeFactory.CreateScope();
await Task.Run(async () => await scope.ServiceProvider.GetRequiredService<IBatchIngestionService>().HandleBatchIngestion(context.Message));
Log.Debug("Starting HandleBatchIngestion.");
}
catch (ServiceException serviceException)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Error(serviceException, $"Batch Ingestion Failure. " +
$"The Batch Ingestion Request is placed on LCU.DocumentIngestor.BatchIngestion_error.");
throw;
}
catch (Exception exception)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Fatal(exception, $"Unexpected Batch Ingestion Failure. " +
$"The Batch Ingestion Request is placed on LCU.DocumentIngestor.BatchIngestion_error.");
throw;
}
}
}
@@ -0,0 +1,53 @@
using LCU.Api.Internal.MaidBotLib.Models;
using LCU.API.Internal.DocumentIngestor.Services.IngestionOperationServices;
using LCU.Library.Internal.DocumentIngestorModels.Models;
using LCU.Library.Internal.Exceptions;
using MassTransit;
using Serilog;
namespace LCU.API.Internal.DocumentIngestor.Consumers;
public class BatchUpdateMemberNotificationDataConsumer : IConsumer<Batch<BatchUpdateMemberNotificationDataRequest>>
{
private readonly IServiceScopeFactory _scopeFactory;
public BatchUpdateMemberNotificationDataConsumer(IServiceScopeFactory scopeFactory)
{
_scopeFactory = scopeFactory;
}
public async Task Consume(ConsumeContext<Batch<BatchUpdateMemberNotificationDataRequest>> context)
{
try
{
Log.Debug("Starting BatchUpdateMemberNotificationData");
using var scope = _scopeFactory.CreateScope();
var batchUpdateMemberNotificationDataRequests = new List<BatchUpdateMemberNotificationDataRequest>();
for (int index = 0; index < context.Message.Length; index++)
{
ConsumeContext<BatchUpdateMemberNotificationDataRequest> messageContext = context.Message[index];
batchUpdateMemberNotificationDataRequests.Add(messageContext.Message);
}
await Task.Run(async () => await scope.ServiceProvider.GetRequiredService<IBatchUpdateMemberNotificationDataService>().HandleBatchUpdateMemberNotificationData(batchUpdateMemberNotificationDataRequests));
Log.Debug("Ending BatchUpdateMemberNotificationData");
}
catch (ServiceException serviceException)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Error(serviceException, $"Document Ingestor Failure. " +
$"The BatchUpdateMemberNotificationDataRequest is placed on LCU.DocumentIngestor.BatchUpdateMemberNotificationData_error.");
throw;
}
catch (Exception exception)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Fatal(exception, $"Unexpected Document Ingestor Failure. " +
$"The BatchUpdateMemberNotificationDataRequest is placed on LCU.DocumentIngestor.BatchUpdateMemberNotificationData_error.");
throw;
}
}
}
@@ -0,0 +1,45 @@
using LCU.Api.Internal.MaidBotLib.Models;
using LCU.API.Internal.DocumentIngestor.Services.IngestionOperationServices;
using LCU.Library.Internal.DocumentIngestorModels.Models;
using LCU.Library.Internal.Exceptions;
using MassTransit;
using Serilog;
namespace LCU.API.Internal.DocumentIngestor.Consumers;
public class GatherMemberNotificationInfoConsumer : IConsumer<GatherMemberNotificationInfoRequest>
{
private readonly IServiceScopeFactory _scopeFactory;
public GatherMemberNotificationInfoConsumer(IServiceScopeFactory scopeFactory)
{
_scopeFactory = scopeFactory;
}
public async Task Consume(ConsumeContext<GatherMemberNotificationInfoRequest> context)
{
try
{
Log.Debug("Starting GatherMemberNotificationInfoRequest");
using var scope = _scopeFactory.CreateScope();
await Task.Run(async () => await scope.ServiceProvider.GetRequiredService<IGatherMemberNotificationInfoService>().HandleMemberNotificationInfoGathering(context.Message));
Log.Debug("Ending GatherMemberNotificationInfoRequest");
}
catch (ServiceException serviceException)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Error(serviceException, $"Document Ingestor Failure. " +
$"The GatherMemberNotificationInfoRequest is placed on LCU.DocumentIngestor.GatherMemberNotificationInfo_error.");
throw;
}
catch (Exception exception)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Fatal(exception, $"Unexpected Document Ingestor Failure. " +
$"The GatherMemberNotificationInfoRequest is placed on LCU.DocumentIngestor.GatherMemberNotificationInfo_error.");
throw;
}
}
}
@@ -0,0 +1,43 @@
using MassTransit;
using Serilog;
using LCU.Library.Internal.DocumentIngestorModels.Models;
using LCU.Library.Internal.Exceptions;
using LCU.Api.Internal.MaidBotLib.Models;
using LCU.API.Internal.DocumentIngestor.Services.IngestionOperationServices;
using LCU.API.Internal.DocumentIngestorLib.Exceptions;
namespace LCU.API.Internal.DocumentIngestor.Consumers;
public class IngestionFolderCleanUpConsumer : IConsumer<IngestionFolderCleanUpRequest>
{
private readonly IServiceScopeFactory _scopeFactory;
public IngestionFolderCleanUpConsumer(IServiceScopeFactory scopeFactory)
{
_scopeFactory = scopeFactory;
}
public async Task Consume(ConsumeContext<IngestionFolderCleanUpRequest> context)
{
try
{
using var scope = _scopeFactory.CreateScope();
await Task.Run(async () => await scope.ServiceProvider.GetRequiredService<IIngestionFolderCleanUpService>().HandleIngestionFolderCleanUp(context.Message));
}
catch (ServiceException serviceException)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Error(serviceException, $"IngestionFolderCleanUp Failure. " +
$"The Processing Request is placed on LCU.DocumentIngestor.IngestionFolderCleanUp_error.");
throw;
}
catch (Exception exception)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Fatal(exception, $"Unexpected IngestionFolderCleanUp Failure. " +
$"The Processing Request is placed on LCU.DocumentIngestor.IngestionFolderCleanUp_error.");
throw;
}
}
}
@@ -0,0 +1,52 @@
using MassTransit;
using Serilog;
using LCU.Library.Internal.Exceptions;
using LCU.Api.Internal.MaidBotLib.Models;
using LCU.API.Internal.DocumentIngestor.Services.IngestionOperationServices;
using ApiResponse = LCU.Library.Internal.ApiResponse.Models;
namespace LCU.API.Internal.DocumentIngestor.Consumers;
public class IngestorCompletionConsumer : IConsumer<Batch<ApiResponse.Response>>
{
private readonly IServiceScopeFactory _scopeFactory;
public IngestorCompletionConsumer(IServiceScopeFactory scopeFactory)
{
_scopeFactory = scopeFactory;
}
public async Task Consume(ConsumeContext<Batch<ApiResponse.Response>> context)
{
try
{
Log.Debug("Starting HandleCompletion");
using var scope = _scopeFactory.CreateScope();
var completionRequests = new List<ApiResponse.Response>();
for (int index = 0; index < context.Message.Length; index++)
{
ConsumeContext<ApiResponse.Response> messageContext = context.Message[index];
completionRequests.Add(messageContext.Message);
}
await Task.Run(async () => await scope.ServiceProvider.GetRequiredService<ICompletionService>().HandleCompletion(completionRequests));
Log.Debug("Ending HandleCompletion");
}
catch (ServiceException serviceException)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Error(serviceException, $"Document Ingestor Failure. " +
$"The List<ApiResponse.Response> is placed on LCU.DocumentIngestor.Completion_error.");
throw;
}
catch (Exception exception)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Fatal(exception, $"Unexpected Document Ingestor Failure. " +
$"The List<ApiResponse.Response> is placed on LCU.DocumentIngestor.Completion_error.");
throw;
}
}
}
@@ -0,0 +1,44 @@
using MassTransit;
using Serilog;
using LCU.Library.Internal.DocumentIngestorModels.Models;
using LCU.Library.Internal.Exceptions;
using LCU.Api.Internal.MaidBotLib.Models;
using LCU.API.Internal.DocumentIngestor.Services.IngestionOperationServices;
namespace LCU.API.Internal.DocumentIngestor.Consumers;
public class IngestorIndexConsumer : IConsumer<IngestorRequest>
{
private readonly IServiceScopeFactory _scopeFactory;
public IngestorIndexConsumer(IServiceScopeFactory scopeFactory)
{
_scopeFactory = scopeFactory;
}
public async Task Consume(ConsumeContext<IngestorRequest> context)
{
try
{
Log.Debug("Starting HandleIngestion.");
using var scope = _scopeFactory.CreateScope();
await Task.Run(async () => await scope.ServiceProvider.GetRequiredService<IIndexService>().HandleIngestion(context.Message));
Log.Debug("Starting HandleIngestion.");
}
catch (ServiceException serviceException)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Error(serviceException, $"Document Ingestor Failure. " +
$"The Document Ingestor Request is placed on LCU.DocumentIngestor.Indexing_error.");
throw;
}
catch (Exception exception)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Fatal(exception, $"Unexpected Document Ingestor Failure. " +
$"The Document Upload Request is placed on LCU.DocumentIngestor.Indexing_error.");
throw;
}
}
}
@@ -0,0 +1,50 @@
using MassTransit;
using Serilog;
using LCU.Library.Internal.DocumentIngestorModels.Models;
using LCU.Library.Internal.Exceptions;
using LCU.Api.Internal.MaidBotLib.Models;
using LCU.API.Internal.DocumentIngestor.Services.IngestionOperationServices;
using LCU.API.Internal.DocumentIngestorLib.Exceptions;
namespace LCU.API.Internal.DocumentIngestor.Consumers;
public class IngestorProcessingConsumer : IConsumer<ProcessingRequest>
{
private readonly IServiceScopeFactory _scopeFactory;
public IngestorProcessingConsumer(IServiceScopeFactory scopeFactory)
{
_scopeFactory = scopeFactory;
}
public async Task Consume(ConsumeContext<ProcessingRequest> context)
{
try
{
using var scope = _scopeFactory.CreateScope();
await Task.Run(async () => await scope.ServiceProvider.GetRequiredService<IDocumentProcessorService>().HandleProcessing(context.Message));
}
catch (ArchiveException archiveException)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Fatal(archiveException, $"Document Ingestor Failure. Failure to Archive!");
throw;
}
catch (ServiceException serviceException)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Error(serviceException, $"Document Ingestor Failure. " +
$"The Processing Request is placed on LCU.DocumentIngestor.Processing_error.");
throw;
}
catch (Exception exception)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Fatal(exception, $"Unexpected Document Ingestor Failure. " +
$"The Processing Request is placed on LCU.DocumentIngestor.Processing_error.");
throw;
}
}
}
@@ -0,0 +1,44 @@
using MassTransit;
using Serilog;
using LCU.Library.Internal.Exceptions;
using LCU.Library.Internal.DocumentIngestorModels.Models;
using LCU.Api.Internal.MaidBotLib.Models;
using LCU.API.Internal.DocumentIngestor.Services.IngestionOperationServices;
namespace LCU.API.Internal.DocumentIngestor.Consumers;
public class MemberDocumentNotifierConsumer : IConsumer<MemberDocumentNotificationRequest>
{
private readonly IServiceScopeFactory _scopeFactory;
public MemberDocumentNotifierConsumer(IServiceScopeFactory scopeFactory)
{
_scopeFactory = scopeFactory;
}
public async Task Consume(ConsumeContext<MemberDocumentNotificationRequest> context)
{
try
{
Log.Debug("Starting HandleMemberDocumentNotification");
using var scope = _scopeFactory.CreateScope();
await Task.Run(async () => await scope.ServiceProvider.GetRequiredService<IMemberDocumentNotifierService>().HandleMemberDocumentNotification(context.Message));
Log.Debug("Ending HandleMemberDocumentNotification");
}
catch (ServiceException serviceException)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Error(serviceException, $"Member Document Notifier Failure. " +
$"The request is placed on LCU.DocumentIngestor.MemberDocumentNotifier_error.");
throw;
}
catch (Exception exception)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Fatal(exception, $"Unexpected Member Document Notifier Failure. " +
$"The request is placed on LCU.DocumentIngestor.MemberDocumentNotifier_error.");
throw;
}
}
}
@@ -0,0 +1,44 @@
using MassTransit;
using Serilog;
using LCU.Library.Internal.Exceptions;
using ApiResponse = LCU.Library.Internal.ApiResponse.Models;
using LCU.Api.Internal.MaidBotLib.Models;
using LCU.API.Internal.DocumentIngestor.Services.IngestionOperationServices;
namespace LCU.API.Internal.DocumentIngestor.Consumers;
public class MemberNotificationCompletionConsumer : IConsumer<ApiResponse.Response>
{
private readonly IServiceScopeFactory _scopeFactory;
public MemberNotificationCompletionConsumer(IServiceScopeFactory scopeFactory)
{
_scopeFactory = scopeFactory;
}
public async Task Consume(ConsumeContext<ApiResponse.Response> context)
{
try
{
Log.Debug("Starting HandleMemberNotificationCompletion");
using var scope = _scopeFactory.CreateScope();
await Task.Run(async () => await scope.ServiceProvider.GetRequiredService<IMemberNotificationCompletionService>().HandleMemberNotificationCompletion(context.Message));
Log.Debug("Ending HandleMemberNotificationCompletion");
}
catch (ServiceException serviceException)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Error(serviceException, "Member Notification Completion Failure. " +
"The request is placed on LCU.DocumentIngestor.MemberNotificationCompletion_error.");
throw;
}
catch (Exception exception)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Fatal(exception, "Unexpected Member Notification Completion Failure. " +
"The request is placed on LCU.DocumentIngestor.MemberNotificationCompletion_error.");
throw;
}
}
}
@@ -0,0 +1,44 @@
using MassTransit;
using Serilog;
using LCU.Library.Internal.Exceptions;
using LCU.Api.Internal.MaidBotLib.Models;
using LCU.API.Internal.DocumentIngestor.Services.IngestionOperationServices;
using ApiResponse = LCU.Library.Internal.ApiResponse.Models.Response;
namespace LCU.API.Internal.DocumentIngestor.Consumers;
public class PdfPartitionerCompletionConsumer : IConsumer<ApiResponse>
{
private readonly IServiceScopeFactory _scopeFactory;
public PdfPartitionerCompletionConsumer(IServiceScopeFactory scopeFactory)
{
_scopeFactory = scopeFactory;
}
public async Task Consume(ConsumeContext<ApiResponse> context)
{
try
{
Log.Debug("Starting HandlePdfPartitionerCompletion.");
using var scope = _scopeFactory.CreateScope();
await Task.Run(async () => await scope.ServiceProvider.GetRequiredService<IPdfPartitionerCompletionService>().HandlePdfPartitionerCompletion(context.Message));
Log.Debug("Starting HandlePdfPartitionerCompletion.");
}
catch (ServiceException serviceException)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Error(serviceException, $"Handle Pdf Partitioner Completion Failure. " +
$"The Pdf Partitioner Response is placed on LCU.DocumentIngestor.PdfPartitioner.Completion_error.");
throw;
}
catch (Exception exception)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Fatal(exception, $"Unexpected Pdf Partitioner Completion Failure. " +
$"The Pdf Partitioner Response is placed on LCU.DocumentIngestor.PdfPartitioner.Completion_error.");
throw;
}
}
}
@@ -0,0 +1,44 @@
using MassTransit;
using Serilog;
using LCU.Library.Internal.Exceptions;
using LCU.Api.Internal.MaidBotLib.Models;
using LCU.API.Internal.DocumentIngestor.Services.IngestionOperationServices;
using LCU.Library.Internal.DocumentIngestorModels.Models;
namespace LCU.API.Internal.DocumentIngestor.Consumers;
public class PdfPartitionerConsumer : IConsumer<PdfPartitionerRequest>
{
private readonly IServiceScopeFactory _scopeFactory;
public PdfPartitionerConsumer(IServiceScopeFactory scopeFactory)
{
_scopeFactory = scopeFactory;
}
public async Task Consume(ConsumeContext<PdfPartitionerRequest> context)
{
try
{
Log.Debug("Starting HandlePdfPartitioner.");
using var scope = _scopeFactory.CreateScope();
await Task.Run(async () => await scope.ServiceProvider.GetRequiredService<IPdfPartitionerService>().HandlePdfPartition(context.Message));
Log.Debug("Starting HandleIngestorPdfPartitioner.");
}
catch (ServiceException serviceException)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Error(serviceException, $"Handle Pdf Partitioner Failure. " +
$"The Pdf Partitioner Request is placed on LCU.DocumentIngestor.PdfPartitioner_error.");
throw;
}
catch (Exception exception)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Fatal(exception, $"Unexpected Pdf Partitioner Failure. " +
$"The Pdf Partitioner Request is placed on LCU.DocumentIngestor.PdfPartitioner_error.");
throw;
}
}
}
@@ -0,0 +1,35 @@
using LCU.Api.Internal.MaidBotLib.Models;
using LCU.API.Internal.DocumentIngestor.Services.IngestionOperationServices;
using LCU.Library.Internal.DocumentIngestorModels.Requests;
using MassTransit;
using Serilog;
namespace LCU.API.Internal.DocumentIngestor.Consumers;
public class ProcessStatusTypeEmailConsumer : IConsumer<ProcessStatusTypeEmailRequest>
{
private readonly IServiceScopeFactory _scopeFactory;
public ProcessStatusTypeEmailConsumer(IServiceScopeFactory scopeFactory)
{
_scopeFactory = scopeFactory;
}
public async Task Consume(ConsumeContext<ProcessStatusTypeEmailRequest> context)
{
try
{
Log.Information("ProcessStatusType Email Consumer Listening");
using var scope = _scopeFactory.CreateScope();
await Task.Run(() => scope.ServiceProvider.GetRequiredService<IProcessStatusTypeEmailService>().HandleProcessStatusTypeEmailRequest(context.Message));
}
catch (Exception exception)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Fatal(exception, $"Unexpected Process Status Email Consumer Failure. " +
$"The List<ApiResponse.Response> is placed on LCU.DocumentIngestor.ProcessStatusTypeEmail.");
throw;
}
}
}
@@ -0,0 +1,61 @@
using MassTransit;
using Serilog;
using LCU.Library.Internal.Exceptions;
using LCU.Api.Internal.MaidBotLib.Models;
using LCU.API.Internal.DocumentIngestor.Services.IngestionOperationServices;
using ApiResponse = LCU.Library.Internal.ApiResponse.Models;
using LCU.API.Internal.DocumentIngestorLib.Exceptions;
using Response = LCU.Library.Internal.ApiResponse.Models.Response;
namespace LCU.API.Internal.DocumentIngestor.Consumers;
public class UploadCompletionConsumer : IConsumer<Batch<ApiResponse.Response>>
{
private readonly IServiceScopeFactory _scopeFactory;
public UploadCompletionConsumer(IServiceScopeFactory scopeFactory)
{
_scopeFactory = scopeFactory;
}
public async Task Consume(ConsumeContext<Batch<ApiResponse.Response>> context)
{
try
{
Log.Debug("Starting HandleUploadCompletion");
using var scope = _scopeFactory.CreateScope();
var uploadCompletionRequests = new List<Response>();
for (int index = 0; index < context.Message.Length; index++)
{
ConsumeContext<Response> messageContext = context.Message[index];
uploadCompletionRequests.Add(messageContext.Message);
}
await Task.Run(async () => await scope.ServiceProvider.GetRequiredService<IUploadCompletionService>().HandleUploadCompletion(uploadCompletionRequests));
Log.Debug("Ending HandleUploadCompletion");
}
catch (ArchiveException archiveException)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Fatal(archiveException, $"Upload Completion Failure. Failure to Archive!");
throw;
}
catch (ServiceException serviceException)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Error(serviceException, $"Upload Completion Failure. " +
$"The List<ApiResponse.Response> is placed on LCU.DocumentIngestor.UploadCompletion_error.");
throw;
}
catch (Exception exception)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Fatal(exception, $"Unexpected Upload Completion Failure. " +
$"The List<ApiResponse.Response> is placed on LCU.DocumentIngestor.UploadCompletion_error.");
throw;
}
}
}
@@ -0,0 +1,40 @@
using Microsoft.AspNetCore.Mvc;
using Serilog;
using LCU.Library.Internal.Exceptions;
using LCU.Library.Internal.DocumentIngestorModels.Models;
using LCU.API.Internal.DocumentIngestor.Services.QueueServices;
namespace LCU.API.Internal.DocumentIngestor.Controllers;
[ApiController]
[Route("[controller]")]
public class BatchIngestionController : ControllerBase
{
private readonly IQueueBatchIngestionService _queueBatchIngestionService;
public BatchIngestionController(IQueueBatchIngestionService queueBatchIngestionService)
{
_queueBatchIngestionService = queueBatchIngestionService;
}
[HttpPost("QueueBatchIngestion")]
[ProducesResponseType(202)]
[ProducesResponseType(400)]
[ProducesResponseType(500)]
public async Task<IActionResult> QueueBatchIngestion([FromBody] BatchIngestionRequest request)
{
try
{
await _queueBatchIngestionService.QueueBatchIngestionRequest(request);
return Accepted();
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
}
@@ -0,0 +1,41 @@
using Microsoft.AspNetCore.Mvc;
using Serilog;
using LCU.Library.Internal.Exceptions;
using LCU.Library.Internal.DocumentIngestorModels.Models;
using LCU.API.Internal.DocumentIngestor.Services.QueueServices;
namespace LCU.API.Internal.DocumentIngestor.Controllers;
[ApiController]
[Route("[controller]")]
public class DocumentIngestorController : ControllerBase
{
private readonly IQueueDocumentIngestorService _queueDocumentIngestorService;
public DocumentIngestorController(IQueueDocumentIngestorService queueDocumentIngestorService)
{
_queueDocumentIngestorService = queueDocumentIngestorService;
}
[HttpPost("QueueDocumentIngestor")]
[ProducesResponseType(202)]
[ProducesResponseType(400)]
[ProducesResponseType(500)]
public async Task<IActionResult> QueueDocumentIngestor([FromBody] IngestorRequest request)
{
try
{
await _queueDocumentIngestorService.QueueDocumentIngestorRequest(request);
return Accepted();
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
}
@@ -0,0 +1,292 @@
using Serilog;
using Microsoft.AspNetCore.Mvc;
using LCU.API.Internal.DocumentIngestor.Services;
using LCU.Library.Internal.DocumentIngestorModels.Entities;
using LCU.Library.Internal.DocumentIngestorModels.Models;
using LCU.Library.Internal.Exceptions;
using LCU.Library.Internal.DocumentIngestorModels.Models.Pagination;
namespace LCU.API.Internal.DocumentIngestor.Controllers;
[ApiController]
[Route("[controller]")]
public class DocumentProcessingInfoController : ControllerBase
{
private readonly IDocumentProcessingInfoService _documentProcessingInfoService;
public DocumentProcessingInfoController(IDocumentProcessingInfoService documentProcessingInfoService)
{
_documentProcessingInfoService = documentProcessingInfoService;
}
[HttpGet()]
[ProducesResponseType(200)]
[ProducesResponseType(204)]
[ProducesResponseType(typeof(DocumentProcessingInfo), 400)]
[ProducesResponseType(500)]
public async Task<IActionResult> Get()
{
try
{
var result = await _documentProcessingInfoService.GetAsync();
if (result == null || !result.Any())
{
return NoContent();
}
return Ok(result);
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("{id:int}")]
[ProducesResponseType(200)]
[ProducesResponseType(204)]
[ProducesResponseType(typeof(DocumentProcessingInfo), 400)]
[ProducesResponseType(500)]
public async Task<IActionResult> GetById(int id)
{
try
{
if (id <= 0)
{
return BadRequest($"Id {id} is invalid.");
}
var result = await _documentProcessingInfoService.GetByIdAsync(id);
if (result == null)
{
return NoContent();
}
return Ok(result);
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPost("ByDocumentId")]
[ProducesResponseType(typeof(IDictionary<Guid, DocumentProcessingInfo?>), 200)]
[ProducesResponseType(500)]
public async Task<IActionResult> GetByDocumentIds([FromBody]Guid[] ids)
{
try
{
var result = await _documentProcessingInfoService.GetByDocumentIdsAsync(ids);
return Ok(result);
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("GetByIngestorRunInfoId/{ingestorRunInfoId:guid}")]
[ProducesResponseType(200)]
[ProducesResponseType(204)]
[ProducesResponseType(typeof(DocumentProcessingInfo), 400)]
[ProducesResponseType(500)]
public async Task<IActionResult> GetByIngestorRunInfoId(Guid ingestorRunInfoId)
{
try
{
if (ingestorRunInfoId == Guid.Empty)
{
return BadRequest($"IngestorRunInfoId {ingestorRunInfoId} is invalid.");
}
var result = await _documentProcessingInfoService.GetByIngestorRunInfoIdAsync(ingestorRunInfoId);
if (result == null || !result.Any())
{
return NoContent();
}
return Ok(result);
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPost]
[ProducesResponseType(201)]
[ProducesResponseType(typeof(DocumentProcessingInfo), 400)]
[ProducesResponseType(500)]
public async Task<IActionResult> Post([FromBody] DocumentProcessingInfo documentProcessingInfo)
{
try
{
var result = await _documentProcessingInfoService.SaveAsync(documentProcessingInfo);
return CreatedAtAction(nameof(GetById), new { id = result.DocumentProcessingInfoId }, result);
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPut()]
[ProducesResponseType(200)]
[ProducesResponseType(400)]
[ProducesResponseType(404)]
[ProducesResponseType(500)]
public async Task<IActionResult> Put([FromBody] DocumentProcessingInfo documentProcessingInfo)
{
try
{
var result = await _documentProcessingInfoService.Update(documentProcessingInfo);
if (result == null)
{
return NotFound($"The DocumentProcessingInfo with " +
$"DocumentProcessingInfoId:{documentProcessingInfo.DocumentProcessingInfoId} " +
$"could not be found.");
}
return Ok(result);
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpDelete("{id:int}")]
[ProducesResponseType(200)]
[ProducesResponseType(500)]
public async Task<IActionResult> Delete(int id)
{
try
{
await _documentProcessingInfoService.Delete(id);
return Ok();
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPost("GetFilteredDocumentProcessingInfo")]
[ProducesResponseType(typeof(PagedResponse<DocumentProcessingInfo>), 200)]
[ProducesResponseType(500)]
public async Task<IActionResult> GetFilteredDocumentProcessingInfo([FromBody] Filter filter)
{
try
{
var filterResult = await _documentProcessingInfoService.GetFilteredDocumentProcessingInfo(filter);
var result = new PagedResponse<DocumentProcessingInfo>(filterResult, filter);
return Ok(result);
}
catch (ServiceException)
{
return StatusCode(StatusCodes.Status500InternalServerError);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPost("SetDocumentsToEntityUnknown")]
[ProducesResponseType(200)]
[ProducesResponseType(400)]
[ProducesResponseType(404)]
[ProducesResponseType(500)]
public async Task<IActionResult> SetDocumentsToEntityUnknown(EntityUnknownRequest request)
{
try
{
var results = await _documentProcessingInfoService.SetDocumentsToEntityUnknown(request);
if (!results.Any())
{
return NoContent();
}
return Ok(results);
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPost("UpdateStatus")]
[ProducesResponseType(typeof(DocumentProcessingInfo), 200)]
[ProducesResponseType(204)]
[ProducesResponseType(400)]
[ProducesResponseType(404)]
[ProducesResponseType(500)]
public async Task<IActionResult> UpdateDocumentProcessingInfoStatus(DocumentProcessingInfoStatusRequest request)
{
try
{
var result = await _documentProcessingInfoService.UpdateDocumentProcessingInfoStatus(request);
if (result is null)
{
return NoContent();
}
return Ok(result);
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
}
@@ -0,0 +1,111 @@
using LCU.API.Internal.DocumentIngestor.Services;
using LCU.API.Internal.DocumentIngestor.Services.QueueServices;
using LCU.Library.Internal.ApiSecurity.Attributes;
using LCU.Library.Internal.DocumentIngestorModels.Entities;
using LCU.Library.Internal.Exceptions;
using Microsoft.AspNetCore.Mvc;
using Serilog;
namespace LCU.API.Internal.DocumentIngestor.Controllers;
[ApiController]
[Route("[controller]")]
public class DocumentReprocessingController : ControllerBase
{
private readonly IDocumentReprocessingService _reprocessingService;
public DocumentReprocessingController(IDocumentReprocessingService reprocessingService)
{
_reprocessingService = reprocessingService;
}
[ApiKey]
[HttpPost("QueueReprocessDocumentByDocumentProcessingInfoId/{documentProcessingInfoId:int}/{userName}")]
[ProducesResponseType(200)]
[ProducesResponseType(400)]
[ProducesResponseType(404)]
[ProducesResponseType(500)]
public async Task<IActionResult> QueueReprocessDocumentByDocumentProcessingInfoId(int documentProcessingInfoId, string userName)
{
try
{
if (documentProcessingInfoId <= 0 || string.IsNullOrWhiteSpace(userName))
{
return BadRequest($"documentProcessingInfoId and userName are required.");
}
await _reprocessingService.QueueReprocessDocumentByDocumentProcessingInfoId(documentProcessingInfoId, userName);
return Accepted();
}
catch (ArgumentNullException exception)
{
return StatusCode(StatusCodes.Status404NotFound, exception.Message);
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[ApiKey]
[HttpPost("QueueOverrideDocumentByDocumentProcessingInfoId")]
[ProducesResponseType(200)]
[ProducesResponseType(400)]
[ProducesResponseType(404)]
[ProducesResponseType(500)]
public async Task<IActionResult> QueueOverrideDocumentByDocumentProcessingInfoId(OwnerOverrideInfo ownerOverrideRequest)
{
try
{
await _reprocessingService.QueueOverrideDocumentByDocumentProcessingInfoId(ownerOverrideRequest);
return Accepted();
}
catch (ArgumentNullException exception)
{
return StatusCode(StatusCodes.Status404NotFound, exception.Message);
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[ApiKey]
[HttpPost("QueueReprocessAllCriticalFailures/{userName}")]
[ProducesResponseType(202)]
[ProducesResponseType(400)]
[ProducesResponseType(404)]
[ProducesResponseType(500)]
public async Task<IActionResult> QueueReprocessAllCriticalFailures(string userName)
{
try
{
if (string.IsNullOrWhiteSpace(userName))
{
return BadRequest($"UserName is required.");
}
await _reprocessingService.QueueReprocessAllCriticalFailures(userName);
return Accepted();
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
}
@@ -0,0 +1,159 @@
using Serilog;
using Microsoft.AspNetCore.Mvc;
using LCU.API.Internal.DocumentIngestor.Services;
using LCU.Library.Internal.DocumentIngestorModels.Entities;
using LCU.Library.Internal.Exceptions;
namespace LCU.API.Internal.DocumentIngestor.Controllers;
[Obsolete]
[ApiController]
[Route("[controller]")]
public class DocumentTypeArchiveDeleteInfoController : ControllerBase
{
private readonly IDocumentTypeArchiveDeleteInfoService _documentTypeArchiveDeleteInfoService;
public DocumentTypeArchiveDeleteInfoController(IDocumentTypeArchiveDeleteInfoService documentTypeArchiveDeleteInfoService)
{
_documentTypeArchiveDeleteInfoService = documentTypeArchiveDeleteInfoService;
}
[HttpGet()]
[ProducesResponseType(200)]
[ProducesResponseType(204)]
[ProducesResponseType(typeof(DocumentTypeArchiveDeleteInfo), 400)]
[ProducesResponseType(500)]
public async Task<IActionResult> Get()
{
try
{
var result = await _documentTypeArchiveDeleteInfoService.GetAsync();
if (result == null || !result.Any())
{
return NoContent();
}
return Ok(result);
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("GetByDocumentTypeName/{documentTypeName}")]
[ProducesResponseType(200)]
[ProducesResponseType(204)]
[ProducesResponseType(typeof(DocumentTypeArchiveDeleteInfo), 400)]
[ProducesResponseType(500)]
public async Task<IActionResult> GetByDocumentTypeName(string documentTypeName)
{
try
{
if (string.IsNullOrWhiteSpace(documentTypeName))
{
return BadRequest($"DocumentTypeName {documentTypeName} is invalid.");
}
var result = await _documentTypeArchiveDeleteInfoService.GetByDocumentTypeNameAsync(documentTypeName);
if (result == null)
{
return NoContent();
}
return Ok(result);
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPost]
[ProducesResponseType(201)]
[ProducesResponseType(typeof(DocumentTypeArchiveDeleteInfo), 400)]
[ProducesResponseType(500)]
public async Task<IActionResult> Post([FromBody] DocumentTypeArchiveDeleteInfo documentTypeArchiveDeleteInfo)
{
try
{
var result = await _documentTypeArchiveDeleteInfoService.SaveAsync(documentTypeArchiveDeleteInfo);
return CreatedAtAction(nameof(GetByDocumentTypeName), new { documentTypeName = result.DocumentTypeName }, result);
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPut()]
[ProducesResponseType(200)]
[ProducesResponseType(400)]
[ProducesResponseType(404)]
[ProducesResponseType(500)]
public async Task<IActionResult> Put([FromBody] DocumentTypeArchiveDeleteInfo documentTypeArchiveDeleteInfo)
{
try
{
var result = await _documentTypeArchiveDeleteInfoService.Update(documentTypeArchiveDeleteInfo);
if (result == null)
{
return NotFound($"The DocumentTypeArchiveDeleteInfo with " +
$"DocumentTypeName: {documentTypeArchiveDeleteInfo.DocumentTypeName} " +
$"could not be found.");
}
return Ok(result);
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpDelete("{documentTypeName}")]
[ProducesResponseType(200)]
[ProducesResponseType(500)]
public async Task<IActionResult> Delete(string documentTypeName)
{
try
{
if (string.IsNullOrWhiteSpace(documentTypeName))
{
return BadRequest($"DocumentTypeName {documentTypeName} is invalid.");
}
await _documentTypeArchiveDeleteInfoService.Delete(documentTypeName);
return Ok();
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
}
@@ -0,0 +1,48 @@
using LCU.API.Internal.DocumentIngestor.Services;
using LCU.API.Internal.DocumentIngestor.Services.QueueServices;
using LCU.Library.Internal.ApiSecurity.Attributes;
using LCU.Library.Internal.DocumentIngestorModels.Entities;
using LCU.Library.Internal.DocumentIngestorModels.Models;
using LCU.Library.Internal.Exceptions;
using Microsoft.AspNetCore.Mvc;
using Serilog;
namespace LCU.API.Internal.DocumentIngestor.Controllers;
[ApiController]
[Route("[controller]")]
public class IngestionFolderCleanUpController : ControllerBase
{
private readonly IQueueIngestionFolderCleanUpService _queueIngestionFolderCleanUpService;
public IngestionFolderCleanUpController(IQueueIngestionFolderCleanUpService queueIngestionFolderCleanUpService)
{
_queueIngestionFolderCleanUpService = queueIngestionFolderCleanUpService;
}
[HttpPost("QueueIngestionFolderCleanUp")]
[ProducesResponseType(202)]
[ProducesResponseType(400)]
[ProducesResponseType(500)]
public async Task<IActionResult> QueueIngestionFolderCleanUp([FromBody] IngestionFolderCleanUpRequest request)
{
try
{
if (string.IsNullOrWhiteSpace(request.ArchiveRootPath))
{
return BadRequest($"ArchiveRootPath is required.");
}
await _queueIngestionFolderCleanUpService.QueueIngestionFolderCleanUpRequest(request);
return Accepted();
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
}
@@ -0,0 +1,118 @@
using Serilog;
using Microsoft.AspNetCore.Mvc;
using LCU.API.Internal.DocumentIngestor.Services;
using LCU.Library.Internal.DocumentIngestorModels.Entities;
using LCU.Library.Internal.Exceptions;
namespace LCU.API.Internal.DocumentIngestor.Controllers;
[ApiController]
[Route("[controller]")]
public class IngestorRunInfoController : ControllerBase
{
private readonly IIngestorRunInfoService _ingestorRunInfoService;
public IngestorRunInfoController(IIngestorRunInfoService ingestorRunInfoService)
{
_ingestorRunInfoService = ingestorRunInfoService;
}
[HttpGet("{ingestorRunInfoId:guid}")]
[ProducesResponseType(200)]
[ProducesResponseType(204)]
[ProducesResponseType(typeof(IngestorRunInfo), 400)]
[ProducesResponseType(500)]
public async Task<IActionResult> GetByIngestorRunInfoId(Guid ingestorRunInfoId)
{
try
{
var result = await _ingestorRunInfoService.GetByIdAsync(ingestorRunInfoId);
if (result == null)
{
return NoContent();
}
return Ok(result);
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPost]
[ProducesResponseType(200)]
[ProducesResponseType(typeof(IngestorRunInfo), 400)]
[ProducesResponseType(500)]
public async Task<IActionResult> Post([FromBody] IngestorRunInfo ingestorRunInfo)
{
try
{
var result = await _ingestorRunInfoService.SaveAsync(ingestorRunInfo);
return Ok(result);
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPut()]
[ProducesResponseType(200)]
[ProducesResponseType(400)]
[ProducesResponseType(404)]
[ProducesResponseType(500)]
public async Task<IActionResult> Put([FromBody] IngestorRunInfo ingestorRunInfo)
{
try
{
var result = await _ingestorRunInfoService.Update(ingestorRunInfo);
if (result == null)
{
return NotFound($"The ingestorRunInfo with IngestorRunInfoId:{ingestorRunInfo.IngestorRunInfoId} " +
$"could not be found.");
}
return Ok(result);
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpDelete("{ingestorRunInfoId:guid}")]
[ProducesResponseType(200)]
[ProducesResponseType(500)]
public async Task<IActionResult> Delete(Guid ingestorRunInfoId)
{
try
{
await _ingestorRunInfoService.Delete(ingestorRunInfoId);
return Ok();
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
}
@@ -0,0 +1,40 @@
using Microsoft.AspNetCore.Mvc;
using Serilog;
using LCU.Library.Internal.Exceptions;
using LCU.Library.Internal.DocumentIngestorModels.Models;
using LCU.API.Internal.DocumentIngestor.Services.QueueServices;
namespace LCU.API.Internal.DocumentIngestor.Controllers;
[ApiController]
[Route("[controller]")]
public class MemberDocumentNotifierController : ControllerBase
{
private readonly IQueueMemberDocumentNotifierService _queueMemberDocumentNotifierService;
public MemberDocumentNotifierController(IQueueMemberDocumentNotifierService queueMemberDocumentNotifierService)
{
_queueMemberDocumentNotifierService = queueMemberDocumentNotifierService;
}
[HttpPost("QueueMemberDocumentNotifier")]
[ProducesResponseType(202)]
[ProducesResponseType(400)]
[ProducesResponseType(500)]
public async Task<IActionResult> QueueMemberDocumentNotifier([FromBody] MemberDocumentNotificationRequest memberDocumentNotificationRequest)
{
try
{
await _queueMemberDocumentNotifierService.QueueMemberDocumentNotifierRequest(memberDocumentNotificationRequest);
return Accepted();
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
}
@@ -0,0 +1,330 @@
using LCU.API.Internal.DocumentIngestor.Configurations;
using LCU.API.Internal.DocumentIngestor.Security;
using LCU.API.Internal.DocumentIngestor.Services;
using LCU.Api.Internal.DocumentIngestorLib.Extensions;
using LCU.Library.Internal.DocumentIngestorModels.Entities;
using LCU.Library.Internal.DocumentIngestorModels.Enums;
using LCU.Library.Internal.DocumentIngestorModels.Models;
using LCU.Library.Internal.Exceptions;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Serilog;
namespace LCU.API.Internal.DocumentIngestor.Controllers;
[ApiController]
[Route("[controller]")]
public class MemberNotificationInfoController : ControllerBase
{
private readonly IMemberNotificationInfoService _memberNotificationInfoService;
private readonly ApiConfiguration _apiConfiguration;
public MemberNotificationInfoController(IMemberNotificationInfoService memberNotificationInfoService,
ApiConfiguration apiConfiguration)
{
_memberNotificationInfoService = memberNotificationInfoService;
_apiConfiguration = apiConfiguration;
}
[HttpGet()]
[ProducesResponseType(200)]
[ProducesResponseType(204)]
[ProducesResponseType(typeof(MemberNotificationInfo), 400)]
[ProducesResponseType(500)]
public async Task<IActionResult> Get()
{
try
{
var result = await _memberNotificationInfoService.GetAsync();
if (result == null || !result.Any())
{
return NoContent();
}
return Ok(result);
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("{id:int}")]
[ProducesResponseType(200)]
[ProducesResponseType(204)]
[ProducesResponseType(typeof(MemberNotificationInfo), 400)]
[ProducesResponseType(500)]
public async Task<IActionResult> GetById(int id)
{
try
{
if (id <= 0)
{
return BadRequest($"Id {id} is invalid.");
}
var result = await _memberNotificationInfoService.GetByIdAsync(id);
if (result == null)
{
return NoContent();
}
return Ok(result);
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("GetByDocumentProcessingInfoId/{documentProcessingInfoId:int}")]
[ProducesResponseType(200)]
[ProducesResponseType(204)]
[ProducesResponseType(typeof(IEnumerable<MemberNotificationInfo>), 400)]
[ProducesResponseType(500)]
public async Task<IActionResult> GetByDocumentProcessingInfoId(int documentProcessingInfoId)
{
try
{
if (documentProcessingInfoId <= 0)
{
return BadRequest($"DocumentProcessingInfoId {documentProcessingInfoId} is invalid.");
}
var result = await _memberNotificationInfoService.GetByDocumentProcessingInfoIdAsync(documentProcessingInfoId);
if (result == null || !result.Any())
{
return NoContent();
}
return Ok(result);
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPost]
[ProducesResponseType(201)]
[ProducesResponseType(typeof(MemberNotificationInfo), 400)]
[ProducesResponseType(500)]
public async Task<IActionResult> Post([FromBody] MemberNotificationInfo memberNotificationInfo)
{
try
{
var result = await _memberNotificationInfoService.SaveAsync(memberNotificationInfo);
return CreatedAtAction(nameof(GetById), new { id = result.DocumentProcessingInfoId }, result);
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPut()]
[ProducesResponseType(200)]
[ProducesResponseType(400)]
[ProducesResponseType(404)]
[ProducesResponseType(500)]
public async Task<IActionResult> Put([FromBody] MemberNotificationInfo memberNotificationInfo)
{
try
{
var result = await _memberNotificationInfoService.Update(memberNotificationInfo);
if (result == null)
{
return NotFound($"The MemberNotificationInfo with " +
$"MemberNotificationInfoId:{memberNotificationInfo.MemberNotificationInfoId} " +
$"could not be found.");
}
return Ok(result);
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPut("UpdateRange")]
[ProducesResponseType(200)]
[ProducesResponseType(400)]
[ProducesResponseType(404)]
[ProducesResponseType(500)]
public async Task<IActionResult> Put([FromBody] List<MemberNotificationInfo> memberNotificationInfos)
{
try
{
var result = await _memberNotificationInfoService.UpdateRange(memberNotificationInfos);
if (result == null)
{
return NotFound($"MemberNotificationInfos could not be found.");
}
return Ok(result);
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpDelete("{id:int}")]
[ProducesResponseType(200)]
[ProducesResponseType(500)]
public async Task<IActionResult> Delete(int id)
{
try
{
if (id <= 0)
{
return BadRequest($"MemberNotificationInfoId {id} is invalid.");
}
await _memberNotificationInfoService.Delete(id);
return Ok();
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPost("GetByNotificationStatus")]
[ProducesResponseType(typeof(IEnumerable<MemberNotificationInfo>), 200)]
[ProducesResponseType(500)]
public async Task<IActionResult> GetByNotificationStatus(NotificationStatusTypes status)
{
try
{
var result = await _memberNotificationInfoService.GetByNotificationStatusAsync(status);
return Ok(result);
}
catch (ServiceException)
{
return StatusCode(StatusCodes.Status500InternalServerError);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPost("GetSendableMemberNotificationInfos")]
[ProducesResponseType(typeof(IEnumerable<MemberNotificationInfo>), 200)]
[ProducesResponseType(500)]
public async Task<IActionResult> GetSendableMemberNotificationInfos(DateTime minimumUploadDate)
{
try
{
var uploadDate = minimumUploadDate.ConvertToTimeZone(_apiConfiguration.TimeZone);
var result = await _memberNotificationInfoService.GetSendableMemberNotificationInfosAsync(uploadDate,
_apiConfiguration.MaxMemberNotificationAttempts);
return Ok(result);
}
catch (ServiceException)
{
return StatusCode(StatusCodes.Status500InternalServerError);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[Authorize(SetDocumentNotificationStatusPolicy.Name)]
[HttpPut("{memberNotificationInfoId:int}/{notificationStatus}")]
[ProducesResponseType(200)]
[ProducesResponseType(400)]
[ProducesResponseType(401)]
[ProducesResponseType(500)]
public async Task<IActionResult> SetDocumentNotificationStatus(int memberNotificationInfoId, NotificationStatusTypes notificationStatus, [FromBody]string reason)
{
try
{
var userName = HttpContext.User.Claims.Single(c => c.Type == "name").Value;
if (!await _memberNotificationInfoService.SetDocumentNotificationStatus(memberNotificationInfoId, notificationStatus, userName, reason))
{
return BadRequest();
}
return Ok();
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[Authorize(SetDocumentNotificationStatusPolicy.Name)]
[HttpPut("BulkSetDocumentNotificationStatus")]
[ProducesResponseType(200)]
[ProducesResponseType(400)]
[ProducesResponseType(401)]
[ProducesResponseType(500)]
public async Task<IActionResult> BulkSetDocumentNotificationStatus([FromBody] BulkNotificationStatusRequest request)
{
try
{
var userName = HttpContext.User.Claims.Single(c => c.Type == "name").Value;
if (!await _memberNotificationInfoService.BulkSetDocumentNotificationStatus(request, userName))
{
return BadRequest();
}
return Ok();
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
}
@@ -0,0 +1,44 @@
using Microsoft.AspNetCore.Mvc;
using Serilog;
using LCU.Library.Internal.Exceptions;
using LCU.Library.Internal.DocumentIngestorModels.Models;
using LCU.API.Internal.DocumentIngestor.Services.QueueServices;
using LCU.API.Internal.DocumentIngestor.Services.IngestionOperationServices;
namespace LCU.API.Internal.DocumentIngestor.Controllers;
[Obsolete("06/02/2023 - Used to prepare historical documents for ingestion. No longer in use.")]
[ApiController]
[Route("[controller]")]
public class OsgPreprocessorController : ControllerBase
{
private readonly IOsgPreprocessorService _osgPreprocessorService;
public OsgPreprocessorController(IOsgPreprocessorService osgPreprocessorService)
{
_osgPreprocessorService = osgPreprocessorService;
}
[HttpPost("PreprocessOsgIndexFile")]
[ProducesResponseType(202)]
[ProducesResponseType(204)]
[ProducesResponseType(400)]
[ProducesResponseType(500)]
public async Task<IActionResult> PreprocessOsgIndexFile([FromBody] OsgPreprocessorRequest request)
{
try
{
await _osgPreprocessorService.HandleOsgPreprocessing(request);
return Accepted();
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
}
@@ -0,0 +1,40 @@
using Microsoft.AspNetCore.Mvc;
using Serilog;
using LCU.Library.Internal.Exceptions;
using LCU.Library.Internal.DocumentIngestorModels.Models;
using LCU.API.Internal.DocumentIngestor.Services.QueueServices;
namespace LCU.API.Internal.DocumentIngestor.Controllers;
[ApiController]
[Route("[controller]")]
public class PdfPartitionerController : ControllerBase
{
private readonly IQueuePdfPartitionerService _queuePdfPartitionerService;
public PdfPartitionerController(IQueuePdfPartitionerService queuePdfPartitionerService)
{
_queuePdfPartitionerService = queuePdfPartitionerService;
}
[HttpPost("QueueIngestorPdfPartitioner")]
[ProducesResponseType(202)]
[ProducesResponseType(400)]
[ProducesResponseType(500)]
public async Task<IActionResult> QueueIngestorPdfPartitioner([FromBody] PdfPartitionerRequest request)
{
try
{
await _queuePdfPartitionerService.QueuePdfPartitionerRequest(request);
return Accepted();
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
}
@@ -0,0 +1,150 @@
using Serilog;
using Microsoft.AspNetCore.Mvc;
using LCU.API.Internal.DocumentIngestor.Services;
using LCU.Library.Internal.DocumentIngestorModels.Entities;
using LCU.Library.Internal.Exceptions;
namespace LCU.API.Internal.DocumentIngestor.Controllers;
[ApiController]
[Route("[controller]")]
public class PdfPartitionerLogController : ControllerBase
{
private readonly IPdfPartitionerLogService _pdfPartitionerLogServiceService;
public PdfPartitionerLogController(IPdfPartitionerLogService pdfPartitionerLogServiceService)
{
_pdfPartitionerLogServiceService = pdfPartitionerLogServiceService;
}
[HttpGet()]
[ProducesResponseType(200)]
[ProducesResponseType(204)]
[ProducesResponseType(typeof(PdfPartitionerLog), 400)]
[ProducesResponseType(500)]
public async Task<IActionResult> Get()
{
try
{
var result = await _pdfPartitionerLogServiceService.GetAsync();
if (result == null || !result.Any())
{
return NoContent();
}
return Ok(result);
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("{id:int}")]
[ProducesResponseType(200)]
[ProducesResponseType(204)]
[ProducesResponseType(typeof(PdfPartitionerLog), 400)]
[ProducesResponseType(500)]
public async Task<IActionResult> GetById(int id)
{
try
{
if (id <= 0)
{
return BadRequest($"Id {id} is invalid.");
}
var result = await _pdfPartitionerLogServiceService.GetByIdAsync(id);
if (result == null)
{
return NoContent();
}
return Ok(result);
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("GetByPdfPartitionerRunInfoId/{pdfPartitionerRunInfoId:guid}")]
[ProducesResponseType(200)]
[ProducesResponseType(204)]
[ProducesResponseType(typeof(PdfPartitionerLog), 400)]
[ProducesResponseType(500)]
public async Task<IActionResult> GetByPdfPartitionerRunInfoId(Guid pdfPartitionerRunInfoId)
{
try
{
var result = await _pdfPartitionerLogServiceService.GetByPdfPartitionerRunInfoIdAsync(pdfPartitionerRunInfoId);
if (result == null || !result.Any())
{
return NoContent();
}
return Ok(result);
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPost]
[ProducesResponseType(201)]
[ProducesResponseType(typeof(PdfPartitionerLog), 400)]
[ProducesResponseType(500)]
public async Task<IActionResult> Post([FromBody] PdfPartitionerLog pdfPartitionerLog)
{
try
{
var result = await _pdfPartitionerLogServiceService.SaveAsync(pdfPartitionerLog);
return CreatedAtAction(nameof(GetById), new { id = result.PdfPartitionerLogId }, result);
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpDelete("{id:int}")]
[ProducesResponseType(200)]
[ProducesResponseType(500)]
public async Task<IActionResult> Delete(int id)
{
try
{
await _pdfPartitionerLogServiceService.Delete(id);
return Ok();
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
}
@@ -0,0 +1,118 @@
using Serilog;
using Microsoft.AspNetCore.Mvc;
using LCU.API.Internal.DocumentIngestor.Services;
using LCU.Library.Internal.DocumentIngestorModels.Entities;
using LCU.Library.Internal.Exceptions;
namespace LCU.API.Internal.DocumentIngestor.Controllers;
[ApiController]
[Route("[controller]")]
public class PdfPartitionerRunInfoController : ControllerBase
{
private readonly IPdfPartitionerRunInfoService _pdfPartitionerRunInfoService;
public PdfPartitionerRunInfoController(IPdfPartitionerRunInfoService pdfPartitionerRunInfoService)
{
_pdfPartitionerRunInfoService = pdfPartitionerRunInfoService;
}
[HttpGet("{pdfPartitionerRunInfoId:guid}")]
[ProducesResponseType(200)]
[ProducesResponseType(204)]
[ProducesResponseType(typeof(PdfPartitionerRunInfo), 400)]
[ProducesResponseType(500)]
public async Task<IActionResult> GetByPdfPartitionerRunInfoId(Guid pdfPartitionerRunInfoId)
{
try
{
var result = await _pdfPartitionerRunInfoService.GetByIdAsync(pdfPartitionerRunInfoId);
if (result == null)
{
return NoContent();
}
return Ok(result);
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPost]
[ProducesResponseType(200)]
[ProducesResponseType(typeof(PdfPartitionerRunInfo), 400)]
[ProducesResponseType(500)]
public async Task<IActionResult> Post([FromBody] PdfPartitionerRunInfo pdfPartitionerRunInfo)
{
try
{
var result = await _pdfPartitionerRunInfoService.SaveAsync(pdfPartitionerRunInfo);
return Ok(result);
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPut()]
[ProducesResponseType(200)]
[ProducesResponseType(400)]
[ProducesResponseType(404)]
[ProducesResponseType(500)]
public async Task<IActionResult> Put([FromBody] PdfPartitionerRunInfo pdfPartitionerRunInfo)
{
try
{
var result = await _pdfPartitionerRunInfoService.Update(pdfPartitionerRunInfo);
if (result == null)
{
return NotFound($"The pdfPartitionerRunInfo with PdfPartitionerRunInfoId:{pdfPartitionerRunInfo.PdfPartitionerRunInfoId} " +
$"could not be found.");
}
return Ok(result);
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpDelete("{pdfPartitionerRunInfoId:guid}")]
[ProducesResponseType(200)]
[ProducesResponseType(500)]
public async Task<IActionResult> Delete(Guid pdfPartitionerRunInfoId)
{
try
{
await _pdfPartitionerRunInfoService.Delete(pdfPartitionerRunInfoId);
return Ok();
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
}
@@ -0,0 +1,185 @@
using Serilog;
using Microsoft.AspNetCore.Mvc;
using LCU.API.Internal.DocumentIngestor.Services;
using LCU.Library.Internal.DocumentIngestorModels.Entities;
using LCU.Library.Internal.Exceptions;
namespace LCU.API.Internal.DocumentIngestor.Controllers;
[ApiController]
[Route("[controller]")]
public class ProcessingLogController : ControllerBase
{
private readonly IProcessingLogService _processingLogService;
public ProcessingLogController(IProcessingLogService processingLogService)
{
_processingLogService = processingLogService;
}
[HttpGet()]
[ProducesResponseType(200)]
[ProducesResponseType(204)]
[ProducesResponseType(typeof(ProcessingLog), 400)]
[ProducesResponseType(500)]
public async Task<IActionResult> Get()
{
try
{
var result = await _processingLogService.GetAsync();
if (result == null || !result.Any())
{
return NoContent();
}
return Ok(result);
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("{id:int}")]
[ProducesResponseType(200)]
[ProducesResponseType(204)]
[ProducesResponseType(typeof(ProcessingLog), 400)]
[ProducesResponseType(500)]
public async Task<IActionResult> GetById(int id)
{
try
{
if (id <= 0)
{
return BadRequest($"Id {id} is invalid.");
}
var result = await _processingLogService.GetByIdAsync(id);
if (result == null)
{
return NoContent();
}
return Ok(result);
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpGet("GetByDocumentProcessingInfoId/{documentProcessingInfoId:int}")]
[ProducesResponseType(200)]
[ProducesResponseType(204)]
[ProducesResponseType(typeof(ProcessingLog), 400)]
[ProducesResponseType(500)]
public async Task<IActionResult> GetByDocumentProcessingInfoId(int documentProcessingInfoId)
{
try
{
if (documentProcessingInfoId <= 0)
{
return BadRequest($"DocumentProcessingInfoId {documentProcessingInfoId} is invalid.");
}
var result = await _processingLogService.GetByDocumentProcessingInfoIdAsync(documentProcessingInfoId);
if (result == null || !result.Any())
{
return NoContent();
}
return Ok(result);
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPost]
[ProducesResponseType(201)]
[ProducesResponseType(typeof(ProcessingLog), 400)]
[ProducesResponseType(500)]
public async Task<IActionResult> Post([FromBody] ProcessingLog processingLog)
{
try
{
var result = await _processingLogService.SaveAsync(processingLog);
return CreatedAtAction(nameof(GetById), new { id = result.ProcessingLogId }, result);
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpPut()]
[ProducesResponseType(200)]
[ProducesResponseType(400)]
[ProducesResponseType(404)]
[ProducesResponseType(500)]
public async Task<IActionResult> Put([FromBody] ProcessingLog processingLog)
{
try
{
var result = await _processingLogService.Update(processingLog);
if (result == null)
{
return NotFound($"The ProcessingLog with " +
$"ProcessingLogId: {processingLog.ProcessingLogId} " +
$"could not be found.");
}
return Ok(result);
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[HttpDelete("{id:int}")]
[ProducesResponseType(200)]
[ProducesResponseType(500)]
public async Task<IActionResult> Delete(int id)
{
try
{
await _processingLogService.Delete(id);
return Ok();
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
}
@@ -0,0 +1,51 @@
using LCU.API.Internal.DocumentIngestor.Services.QueueServices;
using LCU.Library.Internal.DocumentIngestorModels.Requests;
using LCU.Library.Internal.Exceptions;
using Microsoft.AspNetCore.Mvc;
using Serilog;
namespace LCU.API.Internal.DocumentIngestor.Controllers;
[ApiController]
[Route("[controller]")]
public class QueueProcessStatusTypeEmailController : ControllerBase
{
private readonly IQueueProcessStatusTypeEmailService _queueProcessTypeEmailService;
public QueueProcessStatusTypeEmailController(IQueueProcessStatusTypeEmailService queueProcessTypeEmailService)
{
_queueProcessTypeEmailService = queueProcessTypeEmailService;
}
[HttpPost("QueueProcessStatusTypeEmailRequest", Name = "QueueProcessStatusTypeEmailRequest")]
[ProducesResponseType(200)]
[ProducesResponseType(400)]
[ProducesResponseType(500)]
public async Task<IActionResult> QueueProcessStatusTypeEmailByRequest(ProcessStatusTypeEmailRequest request)
{
try
{
if (!request.EmailAddresses.Any())
{
return BadRequest("ProcessStatusType Email Request had no recipients.");
}
if (request.HasInvalidStatuses(out var invalid))
{
return BadRequest($"The following process statuses are not allowed: {string.Join(", ", invalid)}");
}
await _queueProcessTypeEmailService.QueueProcessStatusTypeEmailRequest(request);
return Ok($"ProcessStatusType Email Request Queued Successfully");
}
catch (ServiceException)
{
return StatusCode(StatusCodes.Status500InternalServerError);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
}
@@ -0,0 +1,37 @@
using Microsoft.AspNetCore.Mvc;
using Serilog;
using LCU.Library.Internal.Status.Services;
using LCU.Library.Internal.Exceptions;
namespace LCU.API.Internal.DocumentIngestor.Controllers;
[ApiController]
[Route("[controller]")]
public class StatusController : ControllerBase
{
private readonly IApiHealthCheckService _apiHealthCheckService;
public StatusController(IApiHealthCheckService apiHealthCheckService)
{
_apiHealthCheckService = apiHealthCheckService;
}
[HttpGet]
[ProducesResponseType(200)]
[ProducesResponseType(500)]
public IActionResult Get()
{
try
{
return Ok(_apiHealthCheckService.CheckApiHealthAndBuildEnvironmentView());
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
}
@@ -0,0 +1,82 @@
using LCU.API.Internal.DocumentIngestor.Services;
using LCU.Library.Internal.ApiSecurity.Attributes;
using LCU.Library.Internal.Exceptions;
using Microsoft.AspNetCore.Mvc;
using Serilog;
namespace LCU.API.Internal.DocumentIngestor.Controllers;
[ApiController]
[Route("[controller]")]
public class UploadCompletionReprocessingController : ControllerBase
{
private readonly IUploadCompletionReprocessingService _reprocessingService;
public UploadCompletionReprocessingController(IUploadCompletionReprocessingService reprocessingService)
{
_reprocessingService = reprocessingService;
}
[ApiKey]
[HttpPost("QueueReprocessUploadCompletionByDocumentProcessingInfoId/{documentProcessingInfoId:int}/{userName}")]
[ProducesResponseType(202)]
[ProducesResponseType(400)]
[ProducesResponseType(401)]
[ProducesResponseType(404)]
[ProducesResponseType(500)]
public async Task<IActionResult> QueueReprocessUploadCompletionByDocumentProcessingInfoId(int documentProcessingInfoId, string userName)
{
try
{
if (documentProcessingInfoId <= 0 || string.IsNullOrWhiteSpace(userName))
{
return BadRequest($"DocumentProcessingInfoId and UserName are required.");
}
await _reprocessingService.QueueReprocessUploadCompletionByDocumentProcessingInfoId(documentProcessingInfoId, userName);
return Accepted();
}
catch (ArgumentNullException exception)
{
return StatusCode(StatusCodes.Status404NotFound, exception.Message);
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
[ApiKey]
[HttpPost("QueueReprocessAllNotificationDataFailures/{userName}")]
[ProducesResponseType(202)]
[ProducesResponseType(400)]
[ProducesResponseType(401)]
[ProducesResponseType(500)]
public async Task<IActionResult> QueueReprocessAllNotificationDataFailures(string userName)
{
try
{
if (string.IsNullOrWhiteSpace(userName))
{
return BadRequest($"UserName is required.");
}
await _reprocessingService.QueueReprocessAllNotificationDataFailures(userName);
return Accepted();
}
catch (ServiceException exception)
{
return StatusCode(StatusCodes.Status500InternalServerError, exception.Message);
}
catch (Exception exception)
{
Log.Error(exception, "Unexpected Exception");
return StatusCode(StatusCodes.Status500InternalServerError);
}
}
}
@@ -0,0 +1,95 @@
using LCU.API.Internal.DocumentIngestor.Configurations;
using LCU.API.Internal.DocumentIngestor.Utilities;
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.Accounts;
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.Agreements;
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.MemberAgreements;
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.Mixed;
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.Organizations;
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.Persons;
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.Tax;
namespace LCU.API.Internal.DocumentIngestor.DataAccess;
public class CoreApiWrapperDao : ICoreApiWrapperDao
{
private readonly CoreApiWrapperConfiguration _coreApiWrapperConfiguration;
public CoreApiWrapperDao(CoreApiWrapperConfiguration coreApiWrapperConfiguration)
{
_coreApiWrapperConfiguration = coreApiWrapperConfiguration;
}
public async Task<IEnumerable<PersonTaxIdDataResponse>> GetPersonsTaxIdData(string taxId)
{
var url = _coreApiWrapperConfiguration.GetPersonsTaxIdDataUrl.Replace("{taxId}", taxId);
return await HttpUtilities.GetAsync<List<PersonTaxIdDataResponse>>(url, _coreApiWrapperConfiguration.RetryCount);
}
public async Task<IEnumerable<OrganizationTaxIdDataResponse>> GetOrganizationsTaxIdData(string taxId)
{
var url = _coreApiWrapperConfiguration.GetOrganizationsTaxIdDataUrl.Replace("{taxId}", taxId);
return await HttpUtilities.GetAsync<List<OrganizationTaxIdDataResponse>>(url, _coreApiWrapperConfiguration.RetryCount);
}
public async Task<IEnumerable<AccountOwnership>> GetOwnersByAccountNumber(string accountNumber, string creationDate)
{
var url = _coreApiWrapperConfiguration.GetOwnersByAccountNumberUrl + $"?accountNumber={accountNumber}&creationDate={creationDate}";
return await HttpUtilities.GetAsync<List<AccountOwnership>>(url, _coreApiWrapperConfiguration.RetryCount);
}
public async Task<IEnumerable<AccountOwnership>> GetOwnersByOrganizationName(string organizationName)
{
var url = _coreApiWrapperConfiguration.GetOwnersByOrganizationNameUrl.Replace("{organizationName}", organizationName);
return await HttpUtilities.GetAsync<List<AccountOwnership>>(url, _coreApiWrapperConfiguration.RetryCount);
}
public async Task<IEnumerable<AccountOwnership>> GetOwnersByPersonName(string personName)
{
var url = _coreApiWrapperConfiguration.GetOwnersByPersonNameUrl.Replace("{personName}", personName);
return await HttpUtilities.GetAsync<List<AccountOwnership>>(url, _coreApiWrapperConfiguration.RetryCount);
}
public async Task<IEnumerable<AgreeUserAccount>?> GetAgreeUsersByAccount(string accountNumber)
{
var url = $"{_coreApiWrapperConfiguration.GetAgreeUsersByAccountsUrl}?accountNumbers={accountNumber}";
return await HttpUtilities.GetAsyncNewton<IEnumerable<AgreeUserAccount>?>(url, null, _coreApiWrapperConfiguration.RetryCount);
}
public async Task<IEnumerable<string>?> GetAgreeUsersByPersonNumber(string personNumber)
{
var url = _coreApiWrapperConfiguration.GetAgreeUsersByPersonNumberUrl.Replace("{personNumber}", personNumber);
return await HttpUtilities.GetAsyncNewton<List<string>?>(url, null, _coreApiWrapperConfiguration.RetryCount);
}
public async Task<string?> GetAgreeUserByOrganizationNumber(string organizationNumber)
{
var uri = new Uri(_coreApiWrapperConfiguration.GetAgreeUserByOrganizationNumberUrl.Replace("{organizationNumber}", organizationNumber));
return await HttpUtilities.GetStringResponseAsync(uri, _coreApiWrapperConfiguration.RetryCount);
}
public async Task<Agreement> GetAgreementByUserId(string userId)
{
var url = _coreApiWrapperConfiguration.GetAgreementByUserIdUrl.Replace("{userId}", userId);
return await HttpUtilities.GetAsync<Agreement>(new Uri(url), null, _coreApiWrapperConfiguration.RetryCount);
}
public async Task<AgreementAccount> GetAgreementAccountByAccountId(string accountId)
{
return await HttpUtilities.GetAsync<AgreementAccount>(
_coreApiWrapperConfiguration.GetAgreementAccountByAccountIdUrl.Replace("{accountId}", accountId),
_coreApiWrapperConfiguration.RetryCount);
}
public async Task<IEnumerable<AgreementAccount>?> GetAgreementAccountsByUserId(string userId)
{
return await HttpUtilities.GetAsync<IEnumerable<AgreementAccount>?>(
_coreApiWrapperConfiguration.GetAgreementAccountsByUserIdUrl.Replace("{userId}", userId),
_coreApiWrapperConfiguration.RetryCount);
}
public async Task<PersonOrganization> GetPersonOrOrganizationNumberByMemberId(string memberId)
{
return await HttpUtilities.GetAsync<PersonOrganization>(
new Uri(_coreApiWrapperConfiguration.GetPersonOrOrganizationNumberByMemberIdUrl.Replace("{memberId}", memberId)),
null,
_coreApiWrapperConfiguration.RetryCount);
}
}
@@ -0,0 +1,122 @@
using LCU.API.Internal.DocumentIngestor.Configurations;
using LCU.API.Internal.DocumentIngestor.Utilities;
using LCU.Library.DocumentType.Models.Requests;
using LCU.Library.DocumentType.Models.Responses;
using LCU.Library.DocumentType.Models.Responses.External;
using Microsoft.Extensions.Caching.Memory;
using System.Collections.Specialized;
using System.Web;
namespace LCU.API.Internal.DocumentIngestor.DataAccess;
public class DocumentTypeRetrieverDao : IDocumentTypeRetrieverDao
{
private readonly DocumentTypeRetrieverConfiguration _documentTypeRetrieverConfiguration;
private readonly DocumentCodeDetailCacheConfiguration _documentCodeDetailCacheConfiguration;
private readonly ApiConfiguration _apiConfiguration;
private IMemoryCache _cache;
private const string ClientKeyName = "Client";
private const string ClientKeyValue = "DocumentIngestor";
private const string ApiKeyName = "ApiKey";
private const string UsernameKey = "userName";
private const string PasswordKey = "password";
public DocumentTypeRetrieverDao(DocumentTypeRetrieverConfiguration documentTypeRetrieverConfiguration,
DocumentCodeDetailCacheConfiguration documentCodeDetailCacheConfiguration,
ApiConfiguration apiConfiguration,
IMemoryCache cache)
{
_documentTypeRetrieverConfiguration = documentTypeRetrieverConfiguration;
_documentCodeDetailCacheConfiguration = documentCodeDetailCacheConfiguration;
_apiConfiguration = apiConfiguration;
_cache = cache;
}
public async Task<IEnumerable<DocumentCodeDetailsResponse>> GetDocumentCodeDetails()
{
return await HttpUtilities.GetAsyncNewton<IEnumerable<DocumentCodeDetailsResponse>>(
_documentTypeRetrieverConfiguration.GetDocumentCodeDetailsUrl,
GetDocumentCodeApiKeyHeaders(),
_documentTypeRetrieverConfiguration.RetryCount);
}
public async Task<DocumentCodeDetailsResponse> GetDocumentCodeDetail(string documentCode)
{
return await HttpUtilities.GetAsyncNewton<DocumentCodeDetailsResponse>(
_documentTypeRetrieverConfiguration.GetDocumentCodeDetailsUrl.Replace("{documentCode}", documentCode),
GetDocumentCodeApiKeyHeaders(),
_documentTypeRetrieverConfiguration.RetryCount);
}
public async Task<IEnumerable<DocumentCodeDetailsResponse>> GetDocumentCodeDetailsCache()
{
IEnumerable<DocumentCodeDetailsResponse> documentCodeDetails;
if (!_cache.TryGetValue(_documentCodeDetailCacheConfiguration.CacheName, out documentCodeDetails))
{
documentCodeDetails = await GetDocumentCodeDetails();
var cacheEntryOptions = new MemoryCacheEntryOptions()
.SetAbsoluteExpiration(TimeSpan.FromMinutes(_documentCodeDetailCacheConfiguration.ExpirationMinutes));
_cache.Set(_documentCodeDetailCacheConfiguration.CacheName, documentCodeDetails, cacheEntryOptions);
}
return documentCodeDetails;
}
public async Task<IEnumerable<DocumentMetadataResponse>?> GetListOfMaliciousDocuments(MaliciousDocumentSearchFilter filter)
{
var uri = new Uri($"{_documentTypeRetrieverConfiguration.GetListOfMaliciousDocumentsUrl}{EncodeFilterUri(filter)}");
return await HttpUtilities.GetAsync<IEnumerable<DocumentMetadataResponse>>(uri,
GetDocumentApiKeyHeaders(),
_documentTypeRetrieverConfiguration.RetryCount);
}
public async Task<EnrichedDocumentMetadataResponse?> GetDocumentInformationById(Guid documentId)
{
var uri = new Uri($"{_documentTypeRetrieverConfiguration.GetDocumentInformationByIdUrl.Replace("{documentId}", documentId.ToString())}");
return await HttpUtilities.GetAsync<EnrichedDocumentMetadataResponse>(uri,
GetDocumentCodeApiKeyHeaders(),
_documentTypeRetrieverConfiguration.RetryCount);
}
private string EncodeFilterUri(MaliciousDocumentSearchFilter filter)
{
NameValueCollection nameValueCollection = HttpUtility.ParseQueryString(string.Empty);
if (filter.MaliciousDateStart != null)
{
nameValueCollection.Add("MaliciousDateStart", filter.MaliciousDateStart.ToString());
}
if (filter.MaliciousDateEnd != null)
{
nameValueCollection.Add("MaliciousDateEnd", filter.MaliciousDateEnd.ToString());
}
return $"?{nameValueCollection}";
}
private Dictionary<string, string> GetDocumentCodeApiKeyHeaders()
{
var headers = new Dictionary<string, string>
{
{ ClientKeyName, ClientKeyValue },
{ ApiKeyName, _apiConfiguration.DocumentIngestorApiKey }
};
return headers;
}
private Dictionary<string, string> GetDocumentApiKeyHeaders()
{
var headers = new Dictionary<string, string>
{
{ UsernameKey, _documentTypeRetrieverConfiguration.Username },
{ PasswordKey, _documentTypeRetrieverConfiguration.Password }
};
return headers;
}
}
@@ -0,0 +1,38 @@
using LCU.API.Internal.DocumentIngestor.Configurations;
using LCU.API.Internal.DocumentIngestor.Utilities;
using LCU.Library.DocumentType.Models.Requests.PrimaryOwner;
using LCU.Library.DocumentType.Models.Requests.Account;
using LCU.Library.DocumentType.Models.Requests.Generic;
namespace LCU.API.Internal.DocumentIngestor.DataAccess;
public class DocumentTypeUploaderApiDao : IDocumentTypeUploaderApiDao
{
private readonly DocumentTypeUploaderConfiguration _documentTypeUploaderConfiguration;
public DocumentTypeUploaderApiDao(DocumentTypeUploaderConfiguration documentTypeUploaderConfiguration)
{
_documentTypeUploaderConfiguration = documentTypeUploaderConfiguration;
}
public async Task UploadPrimaryOwnerDocument(PrimaryOwnerDocumentRequest primaryOwnerDocumentRequest)
{
await HttpUtilities.PostAsync(_documentTypeUploaderConfiguration.QueuePrimaryOwnerDocumentUploadUri,
primaryOwnerDocumentRequest,
_documentTypeUploaderConfiguration.RetryCount);
}
public async Task UploadAccountDocument(AccountDocumentRequest accountDocumentRequest)
{
await HttpUtilities.PostAsync(_documentTypeUploaderConfiguration.QueueAccountDocumentUploadUri,
accountDocumentRequest,
_documentTypeUploaderConfiguration.RetryCount);
}
public async Task UploadGenericDocument(GenericDocumentRequest genericDocumentRequest)
{
await HttpUtilities.PostAsync(_documentTypeUploaderConfiguration.QueueGenericDocumentUploadUri,
genericDocumentRequest,
_documentTypeUploaderConfiguration.RetryCount);
}
}
@@ -0,0 +1,118 @@
using LCU.API.Internal.DocumentIngestor.Configurations;
using LCU.API.Internal.DocumentIngestor.Utilities;
using LCU.Library.Internal.FileOperationsModels.Models;
namespace LCU.API.Internal.DocumentIngestor.DataAccess;
public class FileOperationsApiDao : IFileOperationsApiDao
{
private readonly FileOperationsApiConfiguration _fileOperationsApiConfiguration;
public FileOperationsApiDao(FileOperationsApiConfiguration fileOperationsApiConfiguration)
{
_fileOperationsApiConfiguration = fileOperationsApiConfiguration;
}
public async Task<RequestResponse> DirectMoveFile(MoveFileRequest moveFileRequest)
{
return await HttpUtilities.PostAsync<MoveFileRequest, RequestResponse>(_fileOperationsApiConfiguration.DirectMoveFileUri,
moveFileRequest,
_fileOperationsApiConfiguration.RetryCount,
300);
}
public async Task<RequestResponse> DirectWriteFile(WriteFileRequest writeFileRequest)
{
return await HttpUtilities.PostAsync<WriteFileRequest, RequestResponse>(_fileOperationsApiConfiguration.DirectWriteFileUri,
writeFileRequest,
_fileOperationsApiConfiguration.RetryCount);
}
public async Task<RequestResponse> DirectCreateDirectory(CreateDirectoryRequest createDirectoryRequest)
{
return await HttpUtilities.PostAsync<CreateDirectoryRequest, RequestResponse>(_fileOperationsApiConfiguration.DirectCreateDirectoryUri,
createDirectoryRequest,
_fileOperationsApiConfiguration.RetryCount);
}
public async Task<RequestResponse> DirectUnzipFile(UnzipFileRequest unzipFileRequest)
{
return await HttpUtilities.PostAsync<UnzipFileRequest, RequestResponse>(_fileOperationsApiConfiguration.DirectUnzipFileUri,
unzipFileRequest,
_fileOperationsApiConfiguration.RetryCount,
300);
}
public async Task<RequestResponse> DirectZipDirectory(ZipDirectoryRequest zipDirectoryRequest)
{
return await HttpUtilities.PostAsync<ZipDirectoryRequest, RequestResponse>(_fileOperationsApiConfiguration.DirectZipFileUri,
zipDirectoryRequest,
_fileOperationsApiConfiguration.RetryCount,
300);
}
public async Task<RequestResponse> DirectDeleteDirectory(DeleteDirectoryRequest deleteDirectoryRequest)
{
return await HttpUtilities.PostAsync<DeleteDirectoryRequest, RequestResponse>(_fileOperationsApiConfiguration.DirectDeleteDirectoryUri,
deleteDirectoryRequest,
_fileOperationsApiConfiguration.RetryCount,
300);
}
public async Task<RequestResponse> DirectDeleteFile(DeleteFileRequest deleteFileRequest)
{
return await HttpUtilities.PostAsync<DeleteFileRequest, RequestResponse>(_fileOperationsApiConfiguration.DirectDeleteFileUri,
deleteFileRequest,
_fileOperationsApiConfiguration.RetryCount,
300);
}
public async Task<string> GetFileContent(string filePath)
{
var finalFilePath = filePath.Replace("\\", "%5C");
var uri = new Uri($"{_fileOperationsApiConfiguration.GetFileContentUri}/{finalFilePath}");
return await HttpUtilities.GetStringResponseAsync(uri, _fileOperationsApiConfiguration.RetryCount);
}
public async Task<byte[]> GetPdfByteContent(string filePath)
{
var finalFilePath = filePath.Replace("\\", "%5C");
var uri = new Uri($"{_fileOperationsApiConfiguration.GetPdfContentUri}/{finalFilePath}");
return await HttpUtilities.GetByteArrayAsync(uri, _fileOperationsApiConfiguration.RetryCount);
}
public async Task<bool> ValidateFileExists(string filePath)
{
return await HttpUtilities.PostAsync<string, bool>(_fileOperationsApiConfiguration.ValidateFileExistsUri,
filePath,
_fileOperationsApiConfiguration.RetryCount);
}
public async Task<RequestResponse> ValidatePdfPageExists(string filePath, string pageNumber)
{
var finalFilePath = filePath.Replace("\\", "%5C");
return await HttpUtilities.PostAsync<string, RequestResponse>(new Uri($"{_fileOperationsApiConfiguration.ValidatePdfPageExistsUri}/{finalFilePath}/{pageNumber}" ),
"",
_fileOperationsApiConfiguration.RetryCount);
}
public async Task<IEnumerable<string>> BuildDynamicDirectoryList(DynamicDirectoryListRequest request)
{
return await HttpUtilities.PostAsync<DynamicDirectoryListRequest, IEnumerable<string>>(_fileOperationsApiConfiguration.BuildDynamicDirectoryListUri,
request,
_fileOperationsApiConfiguration.RetryCount);
}
public async Task<IEnumerable<string>> BuildDynamicFileList(DynamicFileListRequest request)
{
return await HttpUtilities.PostAsync<DynamicFileListRequest, IEnumerable<string>>(_fileOperationsApiConfiguration.BuildDynamicFileListUri,
request,
_fileOperationsApiConfiguration.RetryCount);
}
public async Task QueueBatchPdfParser(BatchParsePdfRequest batchParsePdfRequest)
{
await HttpUtilities.PostAsync(_fileOperationsApiConfiguration.QueueBatchPdfParserUri,
batchParsePdfRequest,
_fileOperationsApiConfiguration.RetryCount);
}
}
@@ -0,0 +1,26 @@
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.Tax;
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.Accounts;
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.Agreements;
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.MemberAgreements;
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.Persons;
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.Organizations;
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.Mixed;
namespace LCU.API.Internal.DocumentIngestor.DataAccess;
public interface ICoreApiWrapperDao
{
Task<IEnumerable<PersonTaxIdDataResponse>> GetPersonsTaxIdData(string taxId);
Task<IEnumerable<OrganizationTaxIdDataResponse>> GetOrganizationsTaxIdData(string taxId);
Task<IEnumerable<AccountOwnership>> GetOwnersByAccountNumber(string accountNumber, string creationDate);
Task<IEnumerable<AccountOwnership>> GetOwnersByOrganizationName(string organizationName);
Task<IEnumerable<AccountOwnership>> GetOwnersByPersonName(string personName);
Task<IEnumerable<AgreeUserAccount>?> GetAgreeUsersByAccount(string accountNumber);
Task<IEnumerable<string>?> GetAgreeUsersByPersonNumber(string personNumber);
Task<string?> GetAgreeUserByOrganizationNumber(string organizationNumber);
Task<Agreement> GetAgreementByUserId(string userId);
Task<AgreementAccount> GetAgreementAccountByAccountId(string accountId);
Task<IEnumerable<AgreementAccount>?> GetAgreementAccountsByUserId(string userId);
Task<PersonOrganization> GetPersonOrOrganizationNumberByMemberId(string memberId);
}
@@ -0,0 +1,14 @@
using LCU.Library.DocumentType.Models.Requests;
using LCU.Library.DocumentType.Models.Responses;
using LCU.Library.DocumentType.Models.Responses.External;
namespace LCU.API.Internal.DocumentIngestor.DataAccess;
public interface IDocumentTypeRetrieverDao
{
Task<IEnumerable<DocumentCodeDetailsResponse>> GetDocumentCodeDetails();
Task<DocumentCodeDetailsResponse> GetDocumentCodeDetail(string documentCode);
Task<IEnumerable<DocumentCodeDetailsResponse>> GetDocumentCodeDetailsCache();
Task<IEnumerable<DocumentMetadataResponse>?> GetListOfMaliciousDocuments(MaliciousDocumentSearchFilter filter);
Task<EnrichedDocumentMetadataResponse?> GetDocumentInformationById(Guid documentId);
}
@@ -0,0 +1,11 @@
using LCU.Library.DocumentType.Models.Requests.PrimaryOwner;
using LCU.Library.DocumentType.Models.Requests.Account;
using LCU.Library.DocumentType.Models.Requests.Generic;
namespace LCU.API.Internal.DocumentIngestor.DataAccess;
public interface IDocumentTypeUploaderApiDao
{
Task UploadPrimaryOwnerDocument(PrimaryOwnerDocumentRequest primaryOwnerDocumentRequest);
Task UploadAccountDocument(AccountDocumentRequest accountDocumentRequest);
Task UploadGenericDocument(GenericDocumentRequest genericDocumentRequest);
}
@@ -0,0 +1,21 @@
using LCU.Library.Internal.FileOperationsModels.Models;
namespace LCU.API.Internal.DocumentIngestor.DataAccess;
public interface IFileOperationsApiDao
{
Task<RequestResponse> DirectMoveFile(MoveFileRequest moveFileRequest);
Task<RequestResponse> DirectWriteFile(WriteFileRequest writeFileRequest);
Task<RequestResponse> DirectCreateDirectory(CreateDirectoryRequest createDirectoryRequest);
Task<RequestResponse> DirectUnzipFile(UnzipFileRequest unzipFileRequest);
Task<RequestResponse> DirectZipDirectory(ZipDirectoryRequest zipDirectoryRequest);
Task<RequestResponse> DirectDeleteDirectory(DeleteDirectoryRequest deleteDirectoryRequest);
Task<RequestResponse> DirectDeleteFile(DeleteFileRequest deleteFileRequest);
Task<string> GetFileContent(string filePath);
Task<byte[]> GetPdfByteContent(string filePath);
Task<bool> ValidateFileExists(string filePath);
Task<RequestResponse> ValidatePdfPageExists(string filePath, string pageNumber);
Task<IEnumerable<string>> BuildDynamicDirectoryList(DynamicDirectoryListRequest request);
Task<IEnumerable<string>> BuildDynamicFileList(DynamicFileListRequest request);
Task QueueBatchPdfParser(BatchParsePdfRequest batchParsePdfRequest);
}
@@ -0,0 +1,10 @@
using LCU.API.Internal.DocumentIngestor.Models.MemberPreferencesDtos;
namespace LCU.API.Internal.DocumentIngestor.DataAccess;
public interface IMemberPreferencesApiDao
{
Task<MemberOptInAgreementInformation> GetMemberOptInAgreementInfoByUserId(string userId);
Task<MemberOptInInformation> GetMemberOptInSettingsByUserId(string userId);
Task EmailSuccessfulSend(string userId, string emailAddress);
Task EmailFailureSend(string userId, string emailAddress);
}
@@ -0,0 +1,9 @@
using LCU.Library.Internal.NotificationsModels.Models;
namespace LCU.API.Internal.DocumentIngestor.DataAccess
{
public interface INotificationApiDao
{
Task SendEmailAsync(EmailRequest emailRequest);
}
}
@@ -0,0 +1,64 @@
using System.Web;
using LCU.API.Internal.DocumentIngestor.Configurations;
using LCU.API.Internal.DocumentIngestor.Models.MemberPreferencesDtos;
using LCU.API.Internal.DocumentIngestor.Utilities;
using LCU.Library.Internal.DocumentIngestorModels.Constants;
namespace LCU.API.Internal.DocumentIngestor.DataAccess;
public class MemberPreferencesApiDao : IMemberPreferencesApiDao
{
private readonly MemberPreferencesApiConfiguration _memberPreferencesApiConfiguration;
private const string UserName = "UserName";
private const string UserType = "UserType";
public MemberPreferencesApiDao(MemberPreferencesApiConfiguration memberPreferencesApiConfiguration)
{
_memberPreferencesApiConfiguration = memberPreferencesApiConfiguration;
}
public async Task<MemberOptInAgreementInformation> GetMemberOptInAgreementInfoByUserId(string userId)
{
var url = _memberPreferencesApiConfiguration.GetMemberOptInAgreementInfoByUserIdUrl.Replace("{userId}", userId.ToString());
return await HttpUtilities.GetAsync<MemberOptInAgreementInformation>(url, _memberPreferencesApiConfiguration.RetryCount);
}
public async Task<MemberOptInInformation> GetMemberOptInSettingsByUserId(string userId)
{
var url = _memberPreferencesApiConfiguration.GetMemberOptInSettingsByUserIdUrl.Replace("{userId}", userId.ToString());
return await HttpUtilities.GetAsync<MemberOptInInformation>(url, _memberPreferencesApiConfiguration.RetryCount);
}
public Task EmailSuccessfulSend(string userId, string emailAddress) => SendEmailStatusUpdate(_memberPreferencesApiConfiguration.EmailSuccessfulSendUrl, userId, emailAddress);
public Task EmailFailureSend(string userId, string emailAddress) => SendEmailStatusUpdate(_memberPreferencesApiConfiguration.EmailFailedSendUrl, userId, emailAddress);
private async Task SendEmailStatusUpdate(string route, string userId, string? emailAddress)
{
var url = route.Replace("{userId}", userId);
var uri = new UriBuilder(url);
if (emailAddress is not null)
{
var query = HttpUtility.ParseQueryString(uri.Query);
query["email"] = emailAddress;
uri.Query = query.ToString();
}
await HttpUtilities.PostAsync(uri.Uri,
"",
GetMemberPreferencesHeaders(),
_memberPreferencesApiConfiguration.RetryCount);
}
private Dictionary<string, string> GetMemberPreferencesHeaders()
{
var headers = new Dictionary<string, string>
{
{ UserName, Users.System },
{ UserType, Users.System }
};
return headers;
}
}
@@ -0,0 +1,22 @@
using LCU.API.Internal.DocumentIngestor.Configurations;
using LCU.API.Internal.DocumentIngestor.Utilities;
using LCU.Library.Internal.NotificationsModels.Models;
namespace LCU.API.Internal.DocumentIngestor.DataAccess;
public class NotificationApiDao : INotificationApiDao
{
private readonly NotificationApiConfiguration _notificationApiConfiguration;
public NotificationApiDao(NotificationApiConfiguration notificationApiConfiguration)
{
_notificationApiConfiguration = notificationApiConfiguration;
}
public async Task SendEmailAsync(EmailRequest emailRequest)
{
await HttpUtilities.PostAsync(new Uri(_notificationApiConfiguration.EmailUrl),
emailRequest,
_notificationApiConfiguration.RetryCount);
}
}
@@ -0,0 +1,12 @@
using Microsoft.ApplicationInsights.Channel;
using Microsoft.ApplicationInsights.Extensibility;
namespace LCU.API.Internal.DocumentIngestor.Initializers;
public class CloudRoleNameTelemetryInitializer : ITelemetryInitializer
{
public void Initialize(ITelemetry telemetry)
{
telemetry.Context.Cloud.RoleName = "DocumentIngestor";
}
}
@@ -0,0 +1,62 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<LangVersion>latest</LangVersion>
<Configurations>Debug;Release;Test</Configurations>
<Platforms>AnyCPU</Platforms>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<NoWarn>1701;1702;8618; 1591</NoWarn>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<NoWarn>1701;1702;8618; 1591</NoWarn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="CsvHelper" Version="33.0.1" />
<PackageReference Include="LCU.Api.Internal.DispatcherSharedLib" Version="5.7.17" />
<PackageReference Include="LCU.Api.Internal.MaidBotLib" Version="1.0.0" />
<PackageReference Include="LCU.Library.DocumentType" Version="1.12.5" />
<PackageReference Include="LCU.Library.Internal.ApiResponse" Version="3.4.1" />
<PackageReference Include="LCU.Library.Internal.ApiSecurity" Version="1.0.1" />
<PackageReference Include="LCU.Library.Internal.Configuration" Version="1.0.0" />
<PackageReference Include="LCU.Library.Internal.CoreApiWrapperModel" Version="2.27.15" />
<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.1.0" />
<PackageReference Include="LCU.Library.Internal.LCUServiceFactory" Version="3.0.0" />
<PackageReference Include="LCU.Library.Internal.Logging" Version="1.1.0" />
<PackageReference Include="LCU.Library.Internal.NotificationsModels" Version="1.0.3" />
<PackageReference Include="LCU.Library.Internal.RetryUtilities" Version="1.0.0" />
<PackageReference Include="LCU.Library.Internal.Status" Version="1.1.0" />
<PackageReference Include="Microsoft.ApplicationInsights.AspNetCore" Version="2.21.0" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.13" />
<PackageReference Include="Microsoft.Extensions.Http.Polly" Version="6.0.7" />
<PackageReference Include="Microsoft.Identity.Web" Version="1.25.10" />
<PackageReference Include="ncrontab" Version="3.3.1" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="6.0.0" />
<PackageReference Include="System.Data.SqlClient" Version="4.8.6" />
<PackageReference Include="TimeZoneConverter" Version="5.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LCU.API.Internal.DocumentIngestorLib\LCU.API.Internal.DocumentIngestorLib.csproj" />
<ProjectReference Include="..\LCU.Library.Internal.DocumentIngestorModels\LCU.Library.Internal.DocumentIngestorModels.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="Templates\NotificationEmailRowTemplate.html">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="Templates\NotificationEmailTemplate.html">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
@@ -0,0 +1,8 @@
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.Agreements;
namespace LCU.API.Internal.DocumentIngestor.Models.MemberPreferencesDtos;
public class MemberOptInAgreementInformation
{
public Agreement Agreement { get; set; }
public IEnumerable<AgreementAccount> Accounts { get; set; }
}
@@ -0,0 +1,7 @@
namespace LCU.API.Internal.DocumentIngestor.Models.MemberPreferencesDtos;
public class MemberOptInInformation
{
public MemberOptInSettings MemberOptinSettings { get; set; }
public bool HasPendingUpdates { get; set; }
}
@@ -0,0 +1,28 @@
namespace LCU.API.Internal.DocumentIngestor.Models.MemberPreferencesDtos;
public class MemberOptInSettings
{
public const string Paper = "Paper";
public const string Electronic = "Electronic";
public int Id { get; set; }
public string UserId { get; set; }
public string EStatements { get; set; }
public string ENotifications { get; set; }
public string UniversalOptIn { get; set; }
public string LegalVersion { get; set; }
public DateTime? LegalDate { get; set; }
public string UnifiedOptInEmail { get; set; }
public string EStatementsEmail { get; set; }
public string ENotificationsEmail { get; set; }
public bool IsUnifiedPaperEnrolled()
{
return string.Equals(UniversalOptIn, Paper, StringComparison.InvariantCultureIgnoreCase);
}
public bool IsUnifiedElectronicEnrolled()
{
return string.Equals(UniversalOptIn, Electronic, StringComparison.InvariantCultureIgnoreCase);
}
}
@@ -0,0 +1,650 @@
using System.Text.Json.Serialization;
using Microsoft.EntityFrameworkCore;
using Microsoft.OpenApi.Models;
using Newtonsoft.Json;
using Serilog;
using MassTransit;
using LCU.Library.Internal.LcuMassTransit;
using LCU.Library.Internal.LcuMassTransitModels;
using LCU.Library.Internal.Logging;
using LCU.Library.Internal.Logging.Models;
using LCU.Library.Internal.Logging.Middleware;
using LCU.Library.Internal.Configuration;
using LCU.Library.Internal.ApiSecurity;
using LCU.Library.Internal.Status;
using LCU.API.Internal.DocumentIngestor.Configurations;
using LCU.API.Internal.DocumentIngestor.Consumers;
using LCU.API.Internal.DocumentIngestor.DataAccess;
using LCU.API.Internal.DocumentIngestor.Services;
using LCU.API.Internal.DocumentIngestor.Services.IngestionOperationServices;
using LCU.API.Internal.DocumentIngestor.Services.IndexParserServices;
using LCU.API.Internal.DocumentIngestor.Services.DocumentProcessorServices;
using LCU.API.Internal.DocumentIngestor.Services.QueueServices;
using LCU.API.Internal.DocumentIngestor.Services.MicroApiServices;
using LCU.API.Internal.DocumentIngestor.Services.AttributeDeterminingServices;
using LCU.API.Internal.DocumentIngestor.Services.PdfParserServices;
using LCU.API.Internal.DocumentIngestor.Services.MemberNotificationInfoDeterminingServices;
using LCU.API.Internal.DocumentIngestorLib.Repositories;
using LCU.API.Internal.DocumentIngestorLib.Persistence;
using LCU.Api.Internal.DispatcherSharedLib;
using LCU.API.Internal.DocumentIngestor.Initializers;
using LCU.API.Internal.DocumentIngestor.Security;
using LCU.Library.Internal.LCUServiceFactory;
using LCU.Library.Internal.LCUServiceFactory.Configurations;
using Microsoft.ApplicationInsights.DependencyCollector;
using Microsoft.ApplicationInsights.Extensibility;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Identity.Web;
using Microsoft.ApplicationInsights.AspNetCore.Extensions;
string MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
var builder = BuildBuilder(args);
BuildServicesAndConfigurations(builder);
BuildAppAndRun(builder);
WebApplicationBuilder BuildBuilder(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
builder.Configuration.AddJsonFile("/app/config/environment-appsettings/appsettings.json", optional: true, reloadOnChange: true);
builder.Configuration.AddJsonFile("/app/config/workload-appsettings/appsettings.json", optional: true, reloadOnChange: true);
builder.Configuration.AddJsonFile("/vault/secrets/document-ingestor-azure-ad-client-secret.json", optional: true, reloadOnChange: true);
builder.Configuration.AddJsonFile("/vault/secrets/document-ingestor-application-insights-instrumentation-key.json", optional: true, reloadOnChange: true);
builder.Configuration.AddJsonFile("/vault/secrets/document-ingestor-document-manager.json", optional: true, reloadOnChange: true);
builder.Configuration.AddJsonFile("/vault/secrets/document-ingestor-queue-password.json", optional: true, reloadOnChange: true);
builder.Configuration.AddJsonFile("/vault/secrets/document-ingestor-queue-user-name.json", optional: true, reloadOnChange: true);
builder.Configuration.AddJsonFile("/vault/secrets/document-ingestor-database-connection.json", optional: true, reloadOnChange: true);
builder.Configuration.AddJsonFile("/vault/secrets/document-ingestor-environment-from-vault.json", optional: true, reloadOnChange: true);
builder.Configuration.AddJsonFile("/vault/secrets/document-ingestor-document-ingestor-api-key.json", optional: true, reloadOnChange: true);
builder.Configuration.AddJsonFile("/vault/secrets/document-ingestor-seq-api-key.json", optional: true, reloadOnChange: true);
builder.Configuration.AddJsonFile("/vault/secrets/document-ingestor-mobile-banking-api-key.json", optional: true, reloadOnChange: true);
builder.Host.UseSerilog();
return builder;
}
void BuildServicesAndConfigurations(WebApplicationBuilder builder)
{
var services = builder.Services;
var configuration = builder.Configuration;
var apiConfiguration = configuration.Bind<ApiConfiguration>(services, "Primary");
configuration.Bind<FileOperationsApiConfiguration>(services);
configuration.Bind<CoreApiWrapperConfiguration>(services);
configuration.Bind<DocumentTypeUploaderConfiguration>(services);
configuration.Bind<NotificationApiConfiguration>(services);
configuration.Bind<MemberPreferencesApiConfiguration>(services);
configuration.Bind<DispatcherJobCreationConfiguration>(services);
configuration.Bind<DocumentTypeRetrieverConfiguration>(services);
configuration.Bind<DocumentCodeDetailCacheConfiguration>(services);
configuration.Bind<DigitalBankingConfiguration>(services);
var security = configuration.Bind<SecurityConfiguration>(services, "Security");
var dbConfiguration = configuration.Bind<SqlConnectionConfiguration>(services);
var servicesFactoryConfiguration = configuration.Bind<ServicesFactoryConfiguration>(services);
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
.AddMicrosoftIdentityWebApi(configuration.GetSection("AzureAd"));
services.AddAuthorization(options =>
{
options.AddPolicy("user_token", policy =>
{
policy.AuthenticationSchemes.Add(JwtBearerDefaults.AuthenticationScheme);
policy.RequireAuthenticatedUser();
});
options.DefaultPolicy = options.GetPolicy("user_token")!;
options.AddPolicy(SetDocumentNotificationStatusPolicy.Name, policyBuilder => SetDocumentNotificationStatusPolicy.PolicyFactory(policyBuilder, security));
});
services.AddSingleton<IAuthorizationHandler, GroupMembershipRequirementHandler>();
var insightsServiceOptions = new ApplicationInsightsServiceOptions() { ConnectionString = configuration["ApplicationInsights:InstrumentationKey"] };
services.AddApplicationInsightsTelemetry(insightsServiceOptions);
services.AddSingleton<ITelemetryInitializer, CloudRoleNameTelemetryInitializer>();
services.ConfigureTelemetryModule<DependencyTrackingTelemetryModule>((module,o)=>{
module.IncludeDiagnosticSourceActivities.Add("MassTransit");
});
services.AddMemoryCache();
services.AddDbContext<AppDbContext>(options =>
{
options.UseSqlServer
(
dbConfiguration.ConnectionString,
sql => sql.EnableRetryOnFailure(dbConfiguration.MaxRetryCount, dbConfiguration.MaxRetryDelay, null)
);
});
var loggerConfiguration = new LoggingConfiguration(apiConfiguration.AppName,
apiConfiguration.SeqApiKey,
apiConfiguration.SeqUrl);
var lcuLogging = new LcuLogging(loggerConfiguration);
lcuLogging.UseLcuLogging();
services.AddCors(options =>
{
options.AddPolicy(MyAllowSpecificOrigins,
builder =>
{
builder.WithOrigins(
apiConfiguration.CorsAllowedOrigins
).AllowAnyHeader().AllowAnyMethod();
});
});
var connectionConfiguration = MassTransitConfigurationSetUp.AddConnectionConfiguration(ref services, configuration);
//debugging
Console.WriteLine(JsonConvert.SerializeObject(connectionConfiguration));
var receiveEndpointConfigurations = new ReceiveEndpointConfigurations()
{
BatchIngestionReceiveEndpoint = MassTransitConfigurationSetUp.GetReceiveEndpointConfiguration(configuration,
"BatchIngestionReceiveEndpoint"),
DocumentIngestorReceiveEndpoint = MassTransitConfigurationSetUp.GetReceiveEndpointConfiguration(configuration,
"DocumentIngestorReceiveEndpoint"),
DocumentIngestorProcessingReceiveEndpoint = MassTransitConfigurationSetUp.GetReceiveEndpointConfiguration(configuration,
"DocumentIngestorProcessingReceiveEndpoint"),
DocumentIngestorCompletionReceiveEndpoint = MassTransitConfigurationSetUp.GetReceiveEndpointConfiguration(configuration,
"DocumentIngestorCompletionReceiveEndpoint"),
PdfPartitionerEndpoint = MassTransitConfigurationSetUp.GetReceiveEndpointConfiguration(configuration, "PdfPartitionerEndpoint"),
PdfPartitionerCompletionEndpoint = MassTransitConfigurationSetUp.GetReceiveEndpointConfiguration(configuration,
"PdfPartitionerCompletionEndpoint"),
UploadCompletionEndpoint = MassTransitConfigurationSetUp.GetReceiveEndpointConfiguration(configuration,
"UploadCompletionEndpoint"),
MemberDocumentNotifierEndpoint = MassTransitConfigurationSetUp.GetReceiveEndpointConfiguration(configuration,
"MemberDocumentNotifierEndpoint"),
MemberNotificationCompletionEndpoint = MassTransitConfigurationSetUp.GetReceiveEndpointConfiguration(configuration,
"MemberNotificationCompletionEndpoint"),
IngestionFolderCleanUpReceiveEndpoint = MassTransitConfigurationSetUp.GetReceiveEndpointConfiguration(configuration,
"IngestionFolderCleanUpReceiveEndpoint"),
GatherMemberNotificationInfoReceiveEndpoint = MassTransitConfigurationSetUp.GetReceiveEndpointConfiguration(configuration,
"GatherMemberNotificationInfoReceiveEndpoint"),
BatchUpdateMemberNotificationDataEndpoint = MassTransitConfigurationSetUp.GetReceiveEndpointConfiguration(configuration,
"BatchUpdateMemberNotificationDataEndpoint"),
ProcessStatusTypeEmailReceiveEndpoint = MassTransitConfigurationSetUp.GetReceiveEndpointConfiguration(configuration, "ProcessStatusTypeEmailReceiveEndpoint")
};
services.AddSingleton(receiveEndpointConfigurations);
//debugging
Console.WriteLine(JsonConvert.SerializeObject(receiveEndpointConfigurations));
services.AddLCUStatusServicesWithApiHealthCheck(configuration);
AddMassTransitServices(ref services, connectionConfiguration, receiveEndpointConfigurations, apiConfiguration);
AddDocumentIngestorServices(services);
AddDocumentIngestorDaos(services);
AddDocumentIngestorLib(ref services);
services.AddHttpClient();
services.AddDispatcherServices(configuration);
services.AddLCUServiceFactoryAndValidateServiceRegistration<IIndexParserService>(servicesFactoryConfiguration);
services.AddLCUServiceFactoryAndValidateServiceRegistration<IPdfIndexParserService>(servicesFactoryConfiguration);
services.AddLCUServiceFactoryAndValidateServiceRegistration<IPdfParserService>(servicesFactoryConfiguration);
services.AddLCUServiceFactoryAndValidateServiceRegistration<IDocumentProcessingService>(servicesFactoryConfiguration);
services.AddControllers().AddJsonOptions(options => options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()));
services.AddEndpointsApiExplorer();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = $"{apiConfiguration.AppName}", Version = "v1" });
var authority = $"https://login.microsoftonline.com/{configuration.GetSection("AzureAd")["TenantId"]}";
c.AddSecurityDefinition
(
nameof(SecuritySchemeType.OpenIdConnect),
new OpenApiSecurityScheme
{
Type = SecuritySchemeType.OAuth2,
Flows = new OpenApiOAuthFlows
{
AuthorizationCode = new OpenApiOAuthFlow
{
AuthorizationUrl = new Uri($"{authority}/oauth2/v2.0/authorize"),
TokenUrl = new Uri($"{authority}/oauth2/v2.0/token")
}
}
}
);
c.AddSecurityRequirement
(
new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = nameof(SecuritySchemeType.OpenIdConnect)
}
},
Array.Empty<string>()
}
}
);
c.AddSecurityDefinition("ApiKey", new OpenApiSecurityScheme
{
In = ParameterLocation.Header,
Name = "ApiKey"
});
c.AddSecurityDefinition("ApiClient", new OpenApiSecurityScheme
{
In = ParameterLocation.Header,
Name = "Client"
});
c.AddSecurityRequirement
(
new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "ApiKey"
}
},
Array.Empty<string>()
}
}
);
c.AddSecurityRequirement
(
new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "ApiClient"
}
},
Array.Empty<string>()
}
}
);
});
services.AddApiKeySecurity(configuration);
}
void AddMassTransitServices(ref IServiceCollection services,
ConnectionConfiguration connectionConfiguration,
ReceiveEndpointConfigurations receiveEndpointConfigurations,
ApiConfiguration apiConfiguration)
{
services.AddMassTransit(x =>
{
x.AddConsumer<BatchIngestionConsumer>();
x.AddConsumer<IngestorIndexConsumer>();
x.AddConsumer<IngestorProcessingConsumer>();
x.AddConsumer<IngestorCompletionConsumer>();
x.AddConsumer<IngestionFolderCleanUpConsumer>();
x.AddConsumer<PdfPartitionerConsumer>();
x.AddConsumer<PdfPartitionerCompletionConsumer>();
x.AddConsumer<UploadCompletionConsumer>();
x.AddConsumer<MemberDocumentNotifierConsumer>();
x.AddConsumer<MemberNotificationCompletionConsumer>();
x.AddConsumer<GatherMemberNotificationInfoConsumer>();
x.AddConsumer<BatchUpdateMemberNotificationDataConsumer>();
x.AddConsumer<ProcessStatusTypeEmailConsumer>();
x.UsingRabbitMq((context, cfg) =>
{
cfg.Host(connectionConfiguration.HostUrl, "/", host =>
{
host.Username(connectionConfiguration.UserName);
host.Password(connectionConfiguration.Password);
});
cfg.UseTimeout(t => t.Timeout = TimeSpan.FromSeconds(420));
if (apiConfiguration.FeatureFlags.RunBatchIngestionConsumer)
{
cfg.ReceiveEndpoint(receiveEndpointConfigurations.BatchIngestionReceiveEndpoint.ReceiveEndpoint, e =>
{
e.ConfigureConsumer<BatchIngestionConsumer>(context);
e.SetQuorumQueue();
e.PrefetchCount = receiveEndpointConfigurations.BatchIngestionReceiveEndpoint.PrefetchLimit;
e.UseTimeout(t => t.Timeout = TimeSpan.FromSeconds(420));
});
}
if (apiConfiguration.FeatureFlags.RunIngestorIndexConsumer)
{
cfg.ReceiveEndpoint(receiveEndpointConfigurations.DocumentIngestorReceiveEndpoint.ReceiveEndpoint, e =>
{
e.ConfigureConsumer<IngestorIndexConsumer>(context);
e.SetQuorumQueue();
e.PrefetchCount = receiveEndpointConfigurations.DocumentIngestorReceiveEndpoint.PrefetchLimit;
e.UseTimeout(t => t.Timeout = TimeSpan.FromSeconds(420));
});
}
if (apiConfiguration.FeatureFlags.RunIngestorProcessingConsumer)
{
cfg.ReceiveEndpoint(receiveEndpointConfigurations.DocumentIngestorProcessingReceiveEndpoint.ReceiveEndpoint, e =>
{
e.ConfigureConsumer<IngestorProcessingConsumer>(context);
e.SetQuorumQueue();
e.PrefetchCount = receiveEndpointConfigurations.DocumentIngestorProcessingReceiveEndpoint.PrefetchLimit;
e.UseTimeout(t => t.Timeout = TimeSpan.FromSeconds(420));
});
}
if (apiConfiguration.FeatureFlags.RunIngestorCompletionConsumer)
{
cfg.ReceiveEndpoint(receiveEndpointConfigurations.DocumentIngestorCompletionReceiveEndpoint.ReceiveEndpoint, e =>
{
e.ConfigureConsumer<IngestorCompletionConsumer>(context);
e.SetQuorumQueue();
e.PrefetchCount = receiveEndpointConfigurations.DocumentIngestorCompletionReceiveEndpoint.PrefetchLimit;
e.UseTimeout(t => t.Timeout = TimeSpan.FromSeconds(420));
});
}
if (apiConfiguration.FeatureFlags.RunIngestionFolderCleanUpConsumer)
{
cfg.ReceiveEndpoint(receiveEndpointConfigurations.IngestionFolderCleanUpReceiveEndpoint.ReceiveEndpoint, e =>
{
e.ConfigureConsumer<IngestionFolderCleanUpConsumer>(context);
e.SetQuorumQueue();
e.PrefetchCount = receiveEndpointConfigurations.IngestionFolderCleanUpReceiveEndpoint.PrefetchLimit;
e.UseTimeout(t => t.Timeout = TimeSpan.FromSeconds(420));
});
}
if (apiConfiguration.FeatureFlags.RunPdfPartitionerConsumer)
{
cfg.ReceiveEndpoint(receiveEndpointConfigurations.PdfPartitionerEndpoint.ReceiveEndpoint, e =>
{
e.ConfigureConsumer<PdfPartitionerConsumer>(context);
e.SetQuorumQueue();
e.PrefetchCount = receiveEndpointConfigurations.PdfPartitionerEndpoint.PrefetchLimit;
e.UseTimeout(t => t.Timeout = TimeSpan.FromSeconds(420));
});
}
if (apiConfiguration.FeatureFlags.RunPdfPartitionerCompletionConsumer)
{
cfg.ReceiveEndpoint(receiveEndpointConfigurations.PdfPartitionerCompletionEndpoint.ReceiveEndpoint, e =>
{
e.ConfigureConsumer<PdfPartitionerCompletionConsumer>(context);
e.SetQuorumQueue();
e.PrefetchCount = receiveEndpointConfigurations.PdfPartitionerCompletionEndpoint.PrefetchLimit;
e.UseTimeout(t => t.Timeout = TimeSpan.FromSeconds(420));
});
}
if (apiConfiguration.FeatureFlags.RunUploadCompletionConsumer)
{
cfg.ReceiveEndpoint(receiveEndpointConfigurations.UploadCompletionEndpoint.ReceiveEndpoint, e =>
{
e.ConfigureConsumer<UploadCompletionConsumer>(context);
e.SetQuorumQueue();
e.PrefetchCount = receiveEndpointConfigurations.UploadCompletionEndpoint.PrefetchLimit;
e.UseTimeout(t => t.Timeout = TimeSpan.FromSeconds(420));
});
}
if (apiConfiguration.FeatureFlags.RunMemberDocumentNotifierConsumer)
{
cfg.ReceiveEndpoint(receiveEndpointConfigurations.MemberDocumentNotifierEndpoint.ReceiveEndpoint, e =>
{
e.ConfigureConsumer<MemberDocumentNotifierConsumer>(context);
e.SetQuorumQueue();
e.PrefetchCount = receiveEndpointConfigurations.MemberDocumentNotifierEndpoint.PrefetchLimit;
e.UseTimeout(t => t.Timeout = TimeSpan.FromSeconds(420));
});
}
if (apiConfiguration.FeatureFlags.RunMemberNotificationCompletionConsumer)
{
cfg.ReceiveEndpoint(receiveEndpointConfigurations.MemberNotificationCompletionEndpoint.ReceiveEndpoint, e =>
{
e.ConfigureConsumer<MemberNotificationCompletionConsumer>(context);
e.SetQuorumQueue();
e.PrefetchCount = receiveEndpointConfigurations.MemberNotificationCompletionEndpoint.PrefetchLimit;
e.UseTimeout(t => t.Timeout = TimeSpan.FromSeconds(420));
});
}
if (apiConfiguration.FeatureFlags.RunGatherMemberNotificationInfoConsumer)
{
cfg.ReceiveEndpoint(receiveEndpointConfigurations.GatherMemberNotificationInfoReceiveEndpoint.ReceiveEndpoint, e =>
{
e.ConfigureConsumer<GatherMemberNotificationInfoConsumer>(context);
e.SetQuorumQueue();
e.PrefetchCount = receiveEndpointConfigurations.GatherMemberNotificationInfoReceiveEndpoint.PrefetchLimit;
e.UseTimeout(t => t.Timeout = TimeSpan.FromSeconds(420));
});
}
if (apiConfiguration.FeatureFlags.RunBatchUpdateMemberNotificationDataConsumer)
{
cfg.ReceiveEndpoint(receiveEndpointConfigurations.BatchUpdateMemberNotificationDataEndpoint.ReceiveEndpoint, e =>
{
e.ConfigureConsumer<BatchUpdateMemberNotificationDataConsumer>(context);
e.SetQuorumQueue();
e.PrefetchCount = receiveEndpointConfigurations.BatchUpdateMemberNotificationDataEndpoint.PrefetchLimit;
e.UseTimeout(t => t.Timeout = TimeSpan.FromSeconds(420));
});
}
if (apiConfiguration.FeatureFlags.RunProcessStatusTypeSummaryConsumer)
{
cfg.ReceiveEndpoint(receiveEndpointConfigurations.ProcessStatusTypeEmailReceiveEndpoint.ReceiveEndpoint, e =>
{
e.ConfigureConsumer<ProcessStatusTypeEmailConsumer>(context);
e.SetQuorumQueue();
e.PrefetchCount = receiveEndpointConfigurations.ProcessStatusTypeEmailReceiveEndpoint.PrefetchLimit;
e.UseTimeout(t => t.Timeout = TimeSpan.FromSeconds(420));
});
}
});
});
services.AddMassTransitHostedService();
}
void AddDocumentIngestorServices(IServiceCollection services)
{
services.AddScoped<IIngestorRunInfoService, IngestorRunInfoService>();
services.AddScoped<IDocumentProcessingInfoService, DocumentProcessingInfoService>();
services.AddScoped<IOwnerOverrideInfoService, OwnerOverrideInfoService>();
services.AddScoped<IProcessingLogService, ProcessingLogService>();
services.AddScoped<IDocumentTypeArchiveDeleteInfoService, DocumentTypeArchiveDeleteInfoService>();
services.AddScoped<IProcessStatusTypeEmailService, ProcessStatusTypeEmailService>();
services.AddScoped<IDocumentReprocessingService, DocumentReprocessingService>();
services.AddScoped<IUploadCompletionReprocessingService, UploadCompletionReprocessingService>();
services.AddScoped<IPdfPartitionerRunInfoService, PdfPartitionerRunInfoService>();
services.AddScoped<IPdfPartitionerLogService, PdfPartitionerLogService>();
services.AddScoped<IMemberNotificationInfoService, MemberNotificationInfoService>();
services.AddScoped<IMemberDocumentNotifierService, MemberDocumentNotifierService>();
services.AddScoped<IMemberNotificationCompletionService, MemberNotificationCompletionService>();
services.AddScoped<IOsgPreprocessorService, OsgPreprocessorService>();
services.AddScoped<IOsgPreprocessorInfoService, OsgPreprocessorInfoService>();
services.AddTransient<IResponseQueue, ResponseQueue>();
AddIngestionOperationServices(services);
AddQueueServices(services);
AddIngestorIndexServices(services);
AddIngestorPdfIndexServices(services);
AddIngestorPdfParserServices(services);
AddIngestorProcessingServices(services);
AddMemberNotificationInfoDeterminingServices(services);
AddMicroApiServices(services);
AddValueDeterminingServices(services);
}
void AddIngestionOperationServices(IServiceCollection services)
{
services.AddScoped<IBatchIngestionService, BatchIngestionService>();
services.AddScoped<IIndexService, IndexService>();
services.AddScoped<IDocumentProcessorService, DocumentProcessorService>();
services.AddScoped<ICompletionService, CompletionService>();
services.AddScoped<IIngestionFolderCleanUpService, IngestionFolderCleanUpService>();
services.AddScoped<IPdfPartitionerService, PdfPartitionerService>();
services.AddScoped<IPdfPartitionerCompletionService, PdfPartitionerCompletionService>();
services.AddScoped<IUploadCompletionService, UploadCompletionService>();
services.AddScoped<IGatherMemberNotificationInfoService, GatherMemberNotificationInfoService>();
services.AddScoped<IBatchUpdateMemberNotificationDataService, BatchUpdateMemberNotificationDataService>();
}
void AddQueueServices(IServiceCollection services)
{
services.AddScoped<IQueueBatchIngestionService, QueueBatchIngestionService>();
services.AddScoped<IQueueDocumentIngestorService, QueueDocumentIngestorService>();
services.AddScoped<IQueueDocumentProcessingService, QueueDocumentProcessingService>();
services.AddScoped<IQueueCompletionService, QueueCompletionService>();
services.AddScoped<IQueueIngestionFolderCleanUpService, QueueIngestionFolderCleanUpService>();
services.AddScoped<IQueuePdfPartitionerService, QueuePdfPartitionerService>();
services.AddScoped<IQueuePdfPartitionerCompletionService, QueuePdfPartitionerCompletionService>();
services.AddScoped<IQueueMemberDocumentNotifierService, QueueMemberDocumentNotifierService>();
services.AddScoped<IQueueMemberNotificationCompletionService, QueueMemberNotificationCompletionService>();
services.AddScoped<IQueueGatherMemberNotificationInfoService, QueueGatherMemberNotificationInfoService>();
services.AddScoped<IQueueBatchUpdateMemberNotificationDataService, QueueBatchUpdateMemberNotificationDataService>();
services.AddScoped<IQueueProcessStatusTypeEmailService, QueueProcessStatusTypeEmailService>();
}
void AddIngestorIndexServices(IServiceCollection services)
{
services.AddScoped<IIndexParserService, FosTaxStatementIndexService>();
services.AddScoped<IIndexParserService, FosDnaDocumentIndexService>();
services.AddScoped<IIndexParserService, FosLoanStatementIndexService>();
services.AddScoped<IIndexParserService, OsgDnaNoticesIndexService>();
services.AddScoped<IIndexParserService, OsgHistoricalDocumentIndexService>();
services.AddScoped<IIndexParserService, XdiDnaNoticeDocumentIndexService>();
services.AddScoped<IIndexParserService, XdiActionNoticeDocumentIndexService>();
services.AddScoped<IIndexParserService, OsgWeilandStatementIndexService>();
services.AddScoped<IIndexParserService, OsgTaxStatementIndexService>();
services.AddScoped<IIndexParserService, OsgDnaNoticeSplitIndexService>();
services.AddScoped<IIndexParserService, OsgTemenosNoticeDocumentIndexService>();
services.AddScoped<IIndexParserService, OsgVehicleTaxStatementIndexService>();
}
void AddIngestorPdfIndexServices(IServiceCollection services)
{
services.AddScoped<IPdfIndexParserService, FosLoanStatementIndexService>();
services.AddScoped<IPdfIndexParserService, OsgDnaNoticesIndexService>();
services.AddScoped<IPdfIndexParserService, OsgHistoricalDocumentIndexService>();
}
void AddIngestorPdfParserServices(IServiceCollection services)
{
services.AddScoped<IPdfParserService, FosLoanStatementPdfService>();
services.AddScoped<IPdfParserService, OsgDnaNoticesPdfService>();
services.AddScoped<IPdfParserService, OsgHistoricalDocumentPdfService>();
}
void AddIngestorProcessingServices(IServiceCollection services)
{
services.AddScoped<IDocumentProcessingService, FosTaxStatementProcessingService>();
services.AddScoped<IDocumentProcessingService, FosDnaDocumentProcessingService>();
services.AddScoped<IDocumentProcessingService, FosLoanStatementProcessingService>();
services.AddScoped<IDocumentProcessingService, OsgDnaNoticesProcessingService>();
services.AddScoped<IDocumentProcessingService, OsgHistoricalDocumentProcessingService>();
services.AddScoped<IDocumentProcessingService, XdiDnaNoticeDocumentProcessingService>();
services.AddScoped<IDocumentProcessingService, XdiActionNoticesProcessingService>();
services.AddScoped<IDocumentProcessingService, OsgWeilandStatementProcessingService>();
services.AddScoped<IDocumentProcessingService, OsgTaxStatementProcessingService>();
services.AddScoped<IDocumentProcessingService, OsgDnaNoticeSplitProcessingService>();
services.AddScoped<IDocumentProcessingService, OsgTemenosNoticeProcessingService>();
services.AddScoped<IDocumentProcessingService, OsgVehicleTaxStatementProcessingService>();
}
void AddMemberNotificationInfoDeterminingServices(IServiceCollection services)
{
services.AddScoped<IMemberNotificationInfoDeterminingService, MemberNotificationInfoDeterminingService>();
services.AddScoped<IPrimaryNotificationInfoDeterminingService, PrimaryNotificationInfoDeterminingService>();
services.AddScoped<IAccountNotificationInfoDeterminingService, AccountNotificationInfoDeterminingService>();
}
void AddMicroApiServices(IServiceCollection services)
{
services.AddScoped<IDocumentTypeUploaderApiService, DocumentTypeUploaderApiService>();
services.AddScoped<IFileOperationsApiService, FileOperationsApiService>();
services.AddScoped<INotificationApiService, NotificationApiService>();
services.AddScoped<ICoreApiWrapperService, CoreApiWrapperService>();
services.AddScoped<IDocumentTypeRetrieverService, DocumentTypeRetrieverService>();
services.AddScoped<IMemberPreferencesApiService, MemberPreferencesApiService>();
}
void AddValueDeterminingServices(IServiceCollection services)
{
services.AddScoped<IPrimaryOwnerDeterminingService, PrimaryOwnerDeterminingService>();
services.AddScoped<IAccountOwnerDeterminingService, AccountOwnerDeterminingService>();
}
void AddDocumentIngestorDaos(IServiceCollection services)
{
services.AddScoped<IDocumentTypeUploaderApiDao, DocumentTypeUploaderApiDao>();
services.AddScoped<ICoreApiWrapperDao, CoreApiWrapperDao>();
services.AddScoped<IFileOperationsApiDao, FileOperationsApiDao>();
services.AddScoped<INotificationApiDao, NotificationApiDao>();
services.AddScoped<IDocumentTypeRetrieverDao, DocumentTypeRetrieverDao>();
services.AddScoped<IMemberPreferencesApiDao, MemberPreferencesApiDao>();
}
void AddDocumentIngestorLib(ref IServiceCollection services)
{
services.AddScoped<IUnitOfWork, UnitOfWork>();
services.AddScoped<IIngestorRunInfoRepository, IngestorRunInfoRepository>();
services.AddScoped<IDocumentProcessingInfoRepository, DocumentProcessingInfoRepository>();
services.AddScoped<IOwnerOverrideInfoRepository, OwnerOverrideInfoRepository>();
services.AddScoped<IProcessingLogRepository, ProcessingLogRepository>();
services.AddScoped<IDocumentTypeArchiveDeleteInfoRepository, DocumentTypeArchiveDeleteInfoRepository>();
services.AddScoped<IPdfPartitionerRunInfoRepository, PdfPartitionerRunInfoRepository>();
services.AddScoped<IPdfPartitionerLogRepository, PdfPartitionerLogRepository>();
services.AddScoped<IMemberNotificationInfoRepository, MemberNotificationInfoRepository>();
services.AddScoped<IOsgPreprocessorInfoRepository, OsgPreprocessorInfoRepository>();
}
void BuildAppAndRun(WebApplicationBuilder builder)
{
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseSwagger(c=>
{
c.PreSerializeFilters.Add((swaggerDoc, request) =>
{
const string prefixHeader = "X-Forwarded-Prefix";
if (!request.Headers.ContainsKey(prefixHeader)) return;
var serverUrl = request.Headers[prefixHeader];
swaggerDoc.Servers = new List<OpenApiServer>()
{
new() { Description = serverUrl, Url = serverUrl }
};
});
});
app.UseSwaggerUI(c =>
{
c.RoutePrefix = "swagger";
c.SwaggerEndpoint("v1/swagger.json", "LCU.API.Internal.DocumentIngestor v1");
c.OAuthClientId(app.Configuration.GetSection("AzureAd")["ClientId"]);
c.OAuthUsePkce();
c.OAuthScopes(app.Configuration.GetSection("Swagger")["OAuthScope"]);
});
app.UseMiddleware<RequestResponseLoggingMiddleware>();
app.UseSerilogRequestLogging(options =>
{
options.EnrichDiagnosticContext = RequestResponseLoggingMiddleware.RequestDataParser.EnrichFromRequest;
});
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseCors(MyAllowSpecificOrigins);
app.UseHttpsRedirection();
app.MapControllers();
app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
app.Run();
}
@@ -0,0 +1,31 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:30999",
"sslPort": 44346
}
},
"profiles": {
"LCU.API.Internal.DocumentIngestor": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "https://localhost:7139;http://localhost:5139",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
@@ -0,0 +1,13 @@
using Microsoft.AspNetCore.Authorization;
namespace LCU.API.Internal.DocumentIngestor.Security;
public class GroupMembershipRequirement : IAuthorizationRequirement
{
public IReadOnlyCollection<string> Groups { get; }
public GroupMembershipRequirement(params string[] groups)
{
Groups = groups;
}
}
@@ -0,0 +1,20 @@
using Microsoft.AspNetCore.Authorization;
namespace LCU.API.Internal.DocumentIngestor.Security;
public class GroupMembershipRequirementHandler : AuthorizationHandler<GroupMembershipRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, GroupMembershipRequirement requirement)
{
var groups = context.User.Claims.Where(c => c.Type == "groups")
.Concat(context.User.Claims.Where(c => c.Type == "roles"))
.Select(c => c.Value);
if (groups.Any(requirement.Groups.Contains))
{
context.Succeed(requirement);
}
return Task.CompletedTask;
}
}
@@ -0,0 +1,11 @@
using Microsoft.AspNetCore.Authorization;
namespace LCU.API.Internal.DocumentIngestor.Security;
public static class ITRolePolicy
{
public static AuthorizationPolicy PolicyFactory(AuthorizationPolicyBuilder builder, SecurityConfiguration configuration)
=> builder.RequireAuthenticatedUser()
.AddRequirements(new GroupMembershipRequirement(configuration.ITRole.Split(",")))
.Build();
}
@@ -0,0 +1,6 @@
namespace LCU.API.Internal.DocumentIngestor.Security;
public class SecurityConfiguration
{
public string ITRole { get; set; }
}
@@ -0,0 +1,11 @@
using Microsoft.AspNetCore.Authorization;
namespace LCU.API.Internal.DocumentIngestor.Security;
public static class SetDocumentNotificationStatusPolicy
{
public const string Name = nameof(SetDocumentNotificationStatusPolicy);
public static AuthorizationPolicy PolicyFactory(AuthorizationPolicyBuilder builder, SecurityConfiguration configuration)
=> ITRolePolicy.PolicyFactory(builder, configuration);
}
@@ -0,0 +1,189 @@
using LCU.API.Internal.DocumentIngestor.Services.MicroApiServices;
using LCU.API.Internal.DocumentIngestor.Utilities;
using LCU.Library.DocumentType.Enums;
using LCU.Library.DocumentType.Extensions;
using LCU.Library.DocumentType.Models.Requests.Attributes;
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.Accounts;
using LCU.Library.Internal.DocumentIngestorModels.Entities;
using LCU.Library.Internal.DocumentIngestorModels.Enums;
using LCU.Library.Internal.DocumentIngestorModels.Models;
using LCU.Library.Internal.Exceptions;
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.Mixed;
namespace LCU.API.Internal.DocumentIngestor.Services.AttributeDeterminingServices;
public class AccountOwnerDeterminingService : BaseOwnerDeterminingService, IAccountOwnerDeterminingService
{
private readonly ICoreApiWrapperService _coreApiWrapperService;
public AccountOwnerDeterminingService(ICoreApiWrapperService coreApiWrapperService)
{
_coreApiWrapperService = coreApiWrapperService;
}
public async Task<ErrorCaptureResult<AccountAttribute>> DetermineAccountOwnerAttribute(string entityName,
string accountNumber,
DateTime creationDate,
OwnerOverrideInfo ownerOverrideInfo)
{
var accountOwners = await _coreApiWrapperService.GetOwnersByAccountNumber(accountNumber, creationDate.ToShortDateString());
var accountOwnerAttribute = BuildAccountAttribute(accountNumber, accountOwners, ownerOverrideInfo);
if (accountOwnerAttribute.PersonNumbers?.Count == 0 &&
accountOwnerAttribute.OrganizationNumbers?.Count == 0)
{
var message =
$"A PersonNumber or OrganizationNumber could not be determined for an Account Owner of AccountNumber: {accountNumber} and EntityName: {entityName}. " +
"The DNA call provided no results back.";
return ErrorCaptureResult<AccountAttribute>.CreateErrorPayload(message, accountOwnerAttribute);
}
if (ownerOverrideInfo != null)
{
return ErrorCaptureResult<AccountAttribute>.CreateSuccessPayload(accountOwnerAttribute);
}
return CheckPrimaryOwner(entityName, accountOwnerAttribute, accountOwners);
}
public async Task<ErrorCaptureResult<AccountAttribute>> DetermineAccountOwnerAttributeByMemberNumberOrUserId(string memberNumberOrUserId,
string accountNumber,
string docType,
DateTime creationDate,
OwnerOverrideInfo ownerOverrideInfo)
{
var accountOwners = await _coreApiWrapperService.GetOwnersByAccountNumber(accountNumber, creationDate.ToShortDateString());
var accountOwnerAttribute = BuildAccountAttribute(accountNumber, accountOwners, ownerOverrideInfo);
if (accountOwnerAttribute.PersonNumbers?.Count == 0 &&
accountOwnerAttribute.OrganizationNumbers?.Count == 0)
{
var message =
$"A PersonNumber or OrganizationNumber could not be determined for an Account Owner of AccountNumber: {accountNumber} and MemberNumberOrUserId: {memberNumberOrUserId}. " +
"The DNA call provided no results back.";
return ErrorCaptureResult<AccountAttribute>.CreateErrorPayload(message, accountOwnerAttribute);
}
if (ownerOverrideInfo != null)
{
return ErrorCaptureResult<AccountAttribute>.CreateSuccessPayload(accountOwnerAttribute);
}
long personNumber = 0;
long orgNumber = 0;
if (
EnumExtensions.GetValueFromName<AccountDocumentTypes>(docType) != AccountDocumentTypes.MtgNtOneHundredTen && EnumExtensions.GetValueFromName<AccountDocumentTypes>(docType) != AccountDocumentTypes.OpsNtOneHundredTwentyNine && EnumExtensions.GetValueFromName<AccountDocumentTypes>(docType) != AccountDocumentTypes.DmdNtOneHundredThirtyFour && EnumExtensions.GetValueFromName<AccountDocumentTypes>(docType) != AccountDocumentTypes.NegativeBalanceLetter ||
memberNumberOrUserId.ToUpper().StartsWith("M") &&
(EnumExtensions.GetValueFromName<AccountDocumentTypes>(docType) == AccountDocumentTypes.MtgNtOneHundredTen || EnumExtensions.GetValueFromName<AccountDocumentTypes>(docType) == AccountDocumentTypes.OpsNtOneHundredTwentyNine || EnumExtensions.GetValueFromName<AccountDocumentTypes>(docType) == AccountDocumentTypes.DmdNtOneHundredThirtyFour || EnumExtensions.GetValueFromName<AccountDocumentTypes>(docType) == AccountDocumentTypes.NegativeBalanceLetter)
)
{
try
{
PersonOrganization personOrganization = await _coreApiWrapperService.GetPersonOrOrganizationNumberByMemberId(memberNumberOrUserId.ToUpper().TrimStart('M'));
if(personOrganization.PersonNumber != null)
{
personNumber = long.Parse(personOrganization.PersonNumber);
}
if(personOrganization.OrganizationNumber != null)
{
orgNumber = long.Parse(personOrganization.OrganizationNumber);
}
}
catch (ServiceException ex)
{
return ErrorCaptureResult<AccountAttribute>.CreateErrorPayload(ex.Message, accountOwnerAttribute);
}
}
else
{
try
{
var agreementByMemberNumberOrUserId = await _coreApiWrapperService.GetAgreementByUserId(memberNumberOrUserId);
personNumber = agreementByMemberNumberOrUserId.PersonNumber;
orgNumber = agreementByMemberNumberOrUserId.ByOrgNbr;
}
catch (Exception ex)
{
return ErrorCaptureResult<AccountAttribute>.CreateErrorPayload(ex.Message, accountOwnerAttribute);
}
}
try
{
var agreementAccount = await _coreApiWrapperService.GetAgreementAccountByAccountId(accountNumber);
if (personNumber != agreementAccount.TaxReportForPersonNumber && orgNumber != agreementAccount.TaxReportForOrgNumber)
{
var message =
$"Person numbers ({personNumber}/{agreementAccount.TaxReportForPersonNumber}) and Organization numbers ({orgNumber}/{agreementAccount.TaxReportForOrgNumber}) did not match from GetAgreementAccountByAccountId for Account Number: {accountNumber}";
return ErrorCaptureResult<AccountAttribute>.CreateErrorPayload(message, accountOwnerAttribute);
}
return ErrorCaptureResult<AccountAttribute>.CreateSuccessPayload(accountOwnerAttribute);
}
catch (Exception ex)
{
return ErrorCaptureResult<AccountAttribute>.CreateErrorPayload(ex.Message, accountOwnerAttribute);
}
}
private AccountAttribute BuildAccountAttribute(string accountNumber, IEnumerable<AccountOwnership> accountOwnerships, OwnerOverrideInfo? ownerOverrideInfo)
{
var personNumbers = new List<string>();
var organizationNumbers = new List<string>();
if (ownerOverrideInfo != null)
{
switch (ownerOverrideInfo.EntityType)
{
case EntityTypes.Person:
personNumbers.Add(ownerOverrideInfo.EntityId);
break;
case EntityTypes.Organization:
organizationNumbers.Add(ownerOverrideInfo.EntityId);
break;
}
}
personNumbers.AddRange(accountOwnerships.Where(person => person.PersonNumber > 0)
.Select(p => p.PersonNumber.ToString()));
organizationNumbers.AddRange(accountOwnerships.Where(org => org.ByOrgNbr > 0)
.Select(o => o.ByOrgNbr.ToString()));
return new AccountAttribute
{
AccountNumber = accountNumber,
PersonNumbers = personNumbers.Distinct().ToList(),
OrganizationNumbers = organizationNumbers.Distinct().ToList()
};
}
private static ErrorCaptureResult<AccountAttribute> CheckPrimaryOwner(string entityName, AccountAttribute accountAttribute, IEnumerable<AccountOwnership> accountOwnerships)
{
var primaryOwner = accountOwnerships.FirstOrDefault(x => x.IsPrimaryOwner);
if (primaryOwner == null)
{
var message = $"A PersonNumber or OrganizationNumber could not be determined for an Account Owner of AccountNumber: {accountAttribute.AccountNumber} and EntityName: {entityName}. " +
$"The DNA call provided no primary owner back, but responded with {accountOwnerships.ToDetailString()}";
return ErrorCaptureResult<AccountAttribute>.CreateErrorPayload(message, accountAttribute);
}
var doesReturnNameMatch = primaryOwner.PersonNumber > 0
? DoesPersonNameMatchExpectedEntityName(primaryOwner, entityName)
: DoesNameMatchExpectedEntityName(primaryOwner.OrganizationName, entityName);
if (!doesReturnNameMatch)
{
var message = $"A PersonNumber or OrganizationNumber could not be determined for an Account Owner of AccountNumber: {accountAttribute.AccountNumber} and EntityName: {entityName}. " +
$"The DNA call provided a primary owner of: {primaryOwner.ToDetailString()}, which did not match the EntityName";
return ErrorCaptureResult<AccountAttribute>.CreateErrorPayload(message, accountAttribute);
}
return ErrorCaptureResult<AccountAttribute>.CreateSuccessPayload(accountAttribute);
}
}
@@ -0,0 +1,42 @@
using System.Text.RegularExpressions;
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.Accounts;
namespace LCU.API.Internal.DocumentIngestor.Services.AttributeDeterminingServices;
public abstract class BaseOwnerDeterminingService
{
protected static bool DoesPersonNameMatchExpectedEntityName(AccountOwnership primaryOwner, string entityName)
{
var trimmedFirstName = primaryOwner.FirstName?.Trim();
var trimmedMiddleName = primaryOwner.MiddleName?.Trim();
var trimmedMiddleInitial = primaryOwner.MiddleInitial?.Trim();
var trimmedLastName = primaryOwner.LastName?.Trim();
var trimmedSuffix = primaryOwner.Suffix?.Trim();
var fullNameMiddleInitial = $"{trimmedFirstName} {trimmedMiddleInitial} {trimmedLastName} {trimmedSuffix}";
var fullNameMiddleName = $"{trimmedFirstName} {trimmedMiddleName} {trimmedLastName} {trimmedSuffix}";
var fullNameMiddleInitialNoSuffix = $"{trimmedFirstName} {trimmedMiddleInitial} {trimmedLastName}";
var fullNameMiddleNameNoSuffix = $"{trimmedFirstName} {trimmedMiddleName} {trimmedLastName}";
var firstNameLastName = $"{trimmedFirstName} {trimmedLastName}";
return DoesNameMatchExpectedEntityName(entityName, fullNameMiddleInitial) ||
DoesNameMatchExpectedEntityName(entityName, fullNameMiddleName) ||
DoesNameMatchExpectedEntityName(entityName, fullNameMiddleInitialNoSuffix) ||
DoesNameMatchExpectedEntityName(entityName, fullNameMiddleNameNoSuffix) ||
DoesNameMatchExpectedEntityName(entityName, firstNameLastName);
}
protected static bool DoesNameMatchExpectedEntityName(string name, string expectedName)
{
var trimmedOrganizationName = RemoveSpecialCharactersAndSpacing(name);
return RemoveSpecialCharactersAndSpacing(expectedName).Equals(trimmedOrganizationName, StringComparison.InvariantCultureIgnoreCase);
}
protected static string RemoveSpecialCharactersAndSpacing(string name)
{
var nonSpecialString = string.IsNullOrWhiteSpace(name)
? ""
: Regex.Replace(name.Trim(), @"[^0-9a-zA-Z\-\&\s*]+", "");
var nonSpecialStringSpacing = nonSpecialString.Trim().Replace(" ", " ");
return nonSpecialStringSpacing.Length > 39 ? nonSpecialStringSpacing[..40].Trim() : nonSpecialStringSpacing;
}
}
@@ -0,0 +1,18 @@
using LCU.Library.DocumentType.Models.Requests.Attributes;
using LCU.Library.Internal.DocumentIngestorModels.Entities;
using LCU.Library.Internal.DocumentIngestorModels.Models;
namespace LCU.API.Internal.DocumentIngestor.Services.AttributeDeterminingServices;
public interface IAccountOwnerDeterminingService
{
Task<ErrorCaptureResult<AccountAttribute>> DetermineAccountOwnerAttribute(string entityName,
string accountNumber,
DateTime creationDate,
OwnerOverrideInfo overrideRequest);
Task<ErrorCaptureResult<AccountAttribute>> DetermineAccountOwnerAttributeByMemberNumberOrUserId(string id,
string accountNumber,
string docType,
DateTime creationDate,
OwnerOverrideInfo ownerOverrideInfo);
}
@@ -0,0 +1,28 @@
using LCU.Library.DocumentType.Models.Requests.Attributes;
using LCU.Library.Internal.DocumentIngestorModels.Entities;
using LCU.Library.Internal.DocumentIngestorModels.Models;
namespace LCU.API.Internal.DocumentIngestor.Services.AttributeDeterminingServices;
public interface IPrimaryOwnerDeterminingService
{
Task<ErrorCaptureResult<PrimaryOwnerAttribute>> DeterminePrimaryOwnerAttribute(string entityName,
string accountNumber,
string taxId,
OwnerOverrideInfo overrideRequest);
Task<ErrorCaptureResult<PrimaryOwnerAttribute>> DeterminePrimaryOwnerAttribute(string entityName,
string accountNumber,
DateTime creationDate,
OwnerOverrideInfo overrideRequest);
Task<ErrorCaptureResult<PrimaryOwnerAttribute>> DeterminePrimaryOwnerAttributeByMemberNumberOrUserId(string id,
string accountNumber,
string docType,
DateTime creationDate,
OwnerOverrideInfo overrideRequest);
Task<ErrorCaptureResult<PrimaryOwnerAttribute>> DeterminePrimaryOwnerAttributeByMemberNumberOrUserId(string memberNumberOrUserId,
string entityName,
OwnerOverrideInfo overrideRequest);
}
@@ -0,0 +1,418 @@
using LCU.API.Internal.DocumentIngestor.Services.MicroApiServices;
using LCU.API.Internal.DocumentIngestor.Utilities;
using LCU.Library.DocumentType.Enums;
using LCU.Library.DocumentType.Extensions;
using LCU.Library.DocumentType.Models.Requests.Attributes;
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.Agreements;
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.Mixed;
using LCU.Library.Internal.CoreApiWrapperModel.CoreModels.Tax;
using LCU.Library.Internal.DocumentIngestorModels.Entities;
using LCU.Library.Internal.DocumentIngestorModels.Enums;
using LCU.Library.Internal.DocumentIngestorModels.Models;
using LCU.Library.Internal.Exceptions;
namespace LCU.API.Internal.DocumentIngestor.Services.AttributeDeterminingServices;
public class PrimaryOwnerDeterminingService : BaseOwnerDeterminingService, IPrimaryOwnerDeterminingService
{
private readonly ICoreApiWrapperService _coreApiWrapperService;
public PrimaryOwnerDeterminingService(ICoreApiWrapperService coreApiWrapperService)
{
_coreApiWrapperService = coreApiWrapperService;
}
public async Task<ErrorCaptureResult<PrimaryOwnerAttribute>> DeterminePrimaryOwnerAttribute(string entityName,
string accountNumber,
DateTime creationDate,
OwnerOverrideInfo overrideRequest)
{
if (overrideRequest != null)
{
return await OverridePrimaryOwnerAttribute(accountNumber, overrideRequest);
}
var primaryOwnerAttribute = new PrimaryOwnerAttribute
{
AccountNumber = accountNumber
};
var accountOwnerships = await _coreApiWrapperService.GetOwnersByAccountNumber(accountNumber, creationDate.ToShortDateString());
if (!accountOwnerships.Any())
{
var message = $"A PersonNumber or OrganizationNumber could not be determined for a Primary Owner of AccountNumber: {accountNumber} and EntityName: {entityName}. " +
"The DNA call provided no results back.";
return ErrorCaptureResult<PrimaryOwnerAttribute>.CreateErrorPayload(message, primaryOwnerAttribute);
}
var primaryOwners = accountOwnerships.Where(account => account.IsPrimaryOwner).ToList();
if (primaryOwners.Count != 1)
{
var message = $"A PersonNumber or OrganizationNumber could not be determined for an Account Owner of AccountNumber: {accountNumber} and EntityName: {entityName}. " +
$"The DNA call provided no single primary owner back, but responded with {accountOwnerships.ToDetailString()}";
return ErrorCaptureResult<PrimaryOwnerAttribute>.CreateErrorPayload(message, primaryOwnerAttribute);
}
var primaryOwner = primaryOwners.First();
var doesReturnNameMatch = primaryOwner.PersonNumber > 0
? DoesPersonNameMatchExpectedEntityName(primaryOwner, entityName)
: DoesNameMatchExpectedEntityName(primaryOwner.OrganizationName, entityName);
if (!doesReturnNameMatch)
{
var message = $"A PersonNumber or OrganizationNumber could not be determined for an Account Owner of AccountNumber: {accountNumber} and EntityName: {entityName}. " +
$"The DNA call provided a primary owner of: {primaryOwner.ToDetailString()}, which did not match the EntityName";
return ErrorCaptureResult<PrimaryOwnerAttribute>.CreateErrorPayload(message, primaryOwnerAttribute);
}
if (primaryOwner.PersonNumber > 0)
{
primaryOwnerAttribute.PersonNumber = primaryOwner.PersonNumber.ToString();
}
else
{
primaryOwnerAttribute.OrganizationNumber = primaryOwner.ByOrgNbr.ToString();
}
return ErrorCaptureResult<PrimaryOwnerAttribute>.CreateSuccessPayload(primaryOwnerAttribute);
}
public async Task<ErrorCaptureResult<PrimaryOwnerAttribute>> DeterminePrimaryOwnerAttribute(string entityName,
string accountNumber,
string taxId,
OwnerOverrideInfo overrideRequest)
{
if (overrideRequest != null)
{
return await OverridePrimaryOwnerAttribute(accountNumber, overrideRequest);
}
var primaryOwnerAttribute = new PrimaryOwnerAttribute
{
AccountNumber = accountNumber
};
var personsTaxIdData = await _coreApiWrapperService.GetPersonsTaxIdData(taxId);
var personTaxIdDataResponses = personsTaxIdData.ToList();
if (DetermineIfPrimaryOwnerIsPerson(entityName, personTaxIdDataResponses, primaryOwnerAttribute, out var errorCaptureResult))
{
return errorCaptureResult;
}
var organizationTaxIdData = await _coreApiWrapperService.GetOrganizationsTaxIdData(taxId);
var organizationTaxIdDataResponses = organizationTaxIdData.ToList();
if (DetermineIfPrimaryOwnerIsOrganization(entityName, organizationTaxIdDataResponses, primaryOwnerAttribute, out var successPayload))
{
return successPayload;
}
if (!organizationTaxIdDataResponses.Any() && !personTaxIdDataResponses.Any())
{
var message = $"A PersonNumber or OrganizationNumber could not be determined for an Account Owner of AccountNumber: {accountNumber}, Tin: {taxId} and EntityName: {entityName}. " +
"The DNA call provided no results back.";
return ErrorCaptureResult<PrimaryOwnerAttribute>.CreateErrorPayload(message, primaryOwnerAttribute);
}
var errorMessage = $"A PersonNumber or OrganizationNumber could not be determined for an Account Owner of AccountNumber: {accountNumber}, Tin: {taxId} and EntityName: {entityName}. " +
"The DNA call provided no primary owner back, but responded with " +
string.Join
(
"; ",
personTaxIdDataResponses.ToDetailString(),
organizationTaxIdDataResponses.ToDetailString()
);
return ErrorCaptureResult<PrimaryOwnerAttribute>.CreateErrorPayload(errorMessage, primaryOwnerAttribute);
}
public async Task<ErrorCaptureResult<PrimaryOwnerAttribute>> DeterminePrimaryOwnerAttributeByMemberNumberOrUserId(string memberNumberOrUserId,
string accountNumber,
string docType,
DateTime creationDate,
OwnerOverrideInfo overrideRequest)
{
if (overrideRequest != null)
{
return await OverridePrimaryOwnerAttribute(accountNumber, overrideRequest);
}
var primaryOwnerAttribute = new PrimaryOwnerAttribute()
{
AccountNumber = accountNumber
};
Agreement? agreementByMemberNumberOrUserId;
long personNumber = 0;
long orgNumber = 0;
if (
memberNumberOrUserId.ToUpper().StartsWith("M") ||
EnumExtensions.GetValueFromName<PrimaryOwnerDocumentTypes>(docType) == PrimaryOwnerDocumentTypes.MmStmxt
)
{
try
{
PersonOrganization personOrganization = await _coreApiWrapperService.GetPersonOrOrganizationNumberByMemberId(memberNumberOrUserId.ToUpper().TrimStart('M'));
if (personOrganization.PersonNumber != null)
{
personNumber = long.Parse(personOrganization.PersonNumber);
}
else if (personOrganization.OrganizationNumber != null)
{
orgNumber = long.Parse(personOrganization.OrganizationNumber);
}
else
{
return ErrorCaptureResult<PrimaryOwnerAttribute>.CreateErrorPayload($"Error finding PersonOrganization by MemberId: {memberNumberOrUserId}", primaryOwnerAttribute);
}
}
catch (ServiceException ex)
{
return ErrorCaptureResult<PrimaryOwnerAttribute>.CreateErrorPayload(ex.Message, primaryOwnerAttribute);
}
}
else
{
try
{
agreementByMemberNumberOrUserId = await _coreApiWrapperService.GetAgreementByUserId(memberNumberOrUserId);
if (agreementByMemberNumberOrUserId == null)
{
var message =
$"An agreement could not be found from GetAgreementByUserId for User ID: {memberNumberOrUserId}";
return ErrorCaptureResult<PrimaryOwnerAttribute>.CreateErrorPayload(message, primaryOwnerAttribute);
}
personNumber = agreementByMemberNumberOrUserId.PersonNumber;
orgNumber = agreementByMemberNumberOrUserId.ByOrgNbr;
} catch (ServiceException ex)
{
return ErrorCaptureResult<PrimaryOwnerAttribute>.CreateErrorPayload(ex.Message, primaryOwnerAttribute);
}
}
if (EnumExtensions.GetValueFromName<PrimaryOwnerDocumentTypes>(docType) == PrimaryOwnerDocumentTypes.MmStmxt)
{
try
{
var agreementAccount = await _coreApiWrapperService.GetAgreementAccountByAccountId(accountNumber);
if (agreementAccount == null)
{
var message =
$"An agreement account could not be found from GetAgreementAccountByAccountId for Account Number: {accountNumber}";
return ErrorCaptureResult<PrimaryOwnerAttribute>.CreateErrorPayload(message, primaryOwnerAttribute);
}
if (personNumber != agreementAccount.TaxReportForPersonNumber && orgNumber != agreementAccount.TaxReportForOrgNumber)
{
var message =
$"Person numbers ({personNumber}/{agreementAccount.TaxReportForPersonNumber}) and Organization numbers ({orgNumber}/{agreementAccount.TaxReportForOrgNumber}) did not match from GetAgreementAccountByAccountId for Account Number: {accountNumber}";
return ErrorCaptureResult<PrimaryOwnerAttribute>.CreateErrorPayload(message, primaryOwnerAttribute);
}
}
catch (ServiceException ex)
{
return ErrorCaptureResult<PrimaryOwnerAttribute>.CreateErrorPayload(ex.Message, primaryOwnerAttribute);
}
}
if (orgNumber == 0)
{
primaryOwnerAttribute.PersonNumber = personNumber.ToString();
}
else
{
primaryOwnerAttribute.OrganizationNumber = orgNumber.ToString();
}
return ErrorCaptureResult<PrimaryOwnerAttribute>.CreateSuccessPayload(primaryOwnerAttribute);
}
public async Task<ErrorCaptureResult<PrimaryOwnerAttribute>> DeterminePrimaryOwnerAttributeByMemberNumberOrUserId(string memberNumberOrUserId,
string entityName,
OwnerOverrideInfo overrideRequest)
{
var primaryOwnerAttribute = new PrimaryOwnerAttribute();
if (overrideRequest != null)
{
return await OverridePrimaryOwnerAttribute(null, overrideRequest);
}
Agreement? agreementByMemberNumberOrUserId;
var returnedName = string.Empty;
long personNumber = 0;
long orgNumber = 0;
if (memberNumberOrUserId.ToUpper().StartsWith("M") || memberNumberOrUserId.ToUpper().StartsWith("C"))
{
try
{
PersonOrganization personOrganization = await _coreApiWrapperService.GetPersonOrOrganizationNumberByMemberId(memberNumberOrUserId.ToUpper().TrimStart('M').TrimStart('C'));
if (personOrganization.PersonNumber != null)
{
personNumber = long.Parse(personOrganization.PersonNumber);
returnedName = personOrganization.EntityName;
}
else if (personOrganization.OrganizationNumber != null)
{
orgNumber = long.Parse(personOrganization.OrganizationNumber);
returnedName = personOrganization.EntityName;
}
else
{
return ErrorCaptureResult<PrimaryOwnerAttribute>.CreateErrorPayload($"Error finding PersonOrganization by MemberId: {memberNumberOrUserId}", primaryOwnerAttribute);
}
}
catch (ServiceException ex)
{
return ErrorCaptureResult<PrimaryOwnerAttribute>.CreateErrorPayload(ex.Message, primaryOwnerAttribute);
}
}
else
{
try
{
agreementByMemberNumberOrUserId = await _coreApiWrapperService.GetAgreementByUserId(memberNumberOrUserId);
if (agreementByMemberNumberOrUserId == null)
{
// Checking to make sure UserId is not improperly mapped memberNumber
PersonOrganization personOrganization = await _coreApiWrapperService.GetPersonOrOrganizationNumberByMemberId(memberNumberOrUserId.ToUpper().TrimStart('M').TrimStart('C'));
if (personOrganization.PersonNumber != null)
{
personNumber = long.Parse(personOrganization.PersonNumber);
returnedName = personOrganization.EntityName;
}
else if (personOrganization.OrganizationNumber != null)
{
orgNumber = long.Parse(personOrganization.OrganizationNumber);
returnedName = personOrganization.EntityName;
}
else
{
var message =
$"An agreement could not be found from GetAgreementByUserId for User ID: {memberNumberOrUserId}";
return ErrorCaptureResult<PrimaryOwnerAttribute>.CreateErrorPayload(message, primaryOwnerAttribute);
}
}
else
{
personNumber = agreementByMemberNumberOrUserId.PersonNumber;
orgNumber = agreementByMemberNumberOrUserId.ByOrgNbr;
if (orgNumber == 0)
{
returnedName = $"{agreementByMemberNumberOrUserId.FirstName} {agreementByMemberNumberOrUserId.MiddleInitial} {agreementByMemberNumberOrUserId.LastName} {agreementByMemberNumberOrUserId.Suffix}";
}
else
{
returnedName = agreementByMemberNumberOrUserId.OrganizationName;
}
}
} catch (ServiceException ex)
{
return ErrorCaptureResult<PrimaryOwnerAttribute>.CreateErrorPayload(ex.Message, primaryOwnerAttribute);
}
}
if (!DoesNameMatchExpectedEntityName(returnedName, entityName))
{
var message =
$"The entityName ({entityName}) did not match from GetAgreementAccountByAccountId for returnedName: {returnedName}";
return ErrorCaptureResult<PrimaryOwnerAttribute>.CreateErrorPayload(message, primaryOwnerAttribute);
}
if (orgNumber == 0)
{
primaryOwnerAttribute.PersonNumber = personNumber.ToString();
}
else
{
primaryOwnerAttribute.OrganizationNumber = orgNumber.ToString();
}
return ErrorCaptureResult<PrimaryOwnerAttribute>.CreateSuccessPayload(primaryOwnerAttribute);
}
private async Task<ErrorCaptureResult<PrimaryOwnerAttribute>> OverridePrimaryOwnerAttribute(string accountNumber, OwnerOverrideInfo request)
{
var primaryOwnerAttribute = new PrimaryOwnerAttribute()
{
AccountNumber = accountNumber,
PersonNumber = request.EntityType == EntityTypes.Person ? request.EntityId : null,
OrganizationNumber = request.EntityType == EntityTypes.Organization ? request.EntityId : null,
};
return ErrorCaptureResult<PrimaryOwnerAttribute>.CreateSuccessPayload(primaryOwnerAttribute);
}
private static bool DetermineIfPrimaryOwnerIsPerson(string entityName,
IReadOnlyCollection<PersonTaxIdDataResponse> personTaxIdDataResponses,
PrimaryOwnerAttribute primaryOwnerAttribute,
out ErrorCaptureResult<PrimaryOwnerAttribute>? errorCaptureResult)
{
errorCaptureResult = null;
if (!personTaxIdDataResponses.Any())
{
return false;
}
var personNumber = personTaxIdDataResponses
.Where(person => DoesNameMatchExpectedEntityName(person.NameLastFirstMiddleSuffix, entityName))
.Select(p => p.PersonNumber).FirstOrDefault();
var personNumberString = personNumber <= 0 ? null : personNumber.ToString();
if (string.IsNullOrEmpty(personNumberString))
{
return false;
}
primaryOwnerAttribute.PersonNumber = personNumberString;
errorCaptureResult = ErrorCaptureResult<PrimaryOwnerAttribute>.CreateSuccessPayload(primaryOwnerAttribute);
return true;
}
private static bool DetermineIfPrimaryOwnerIsOrganization(string entityName,
IReadOnlyCollection<OrganizationTaxIdDataResponse> organizationTaxIdDataResponses,
PrimaryOwnerAttribute primaryOwnerAttribute,
out ErrorCaptureResult<PrimaryOwnerAttribute>? successPayload)
{
successPayload = null;
if (!organizationTaxIdDataResponses.Any())
{
return false;
}
var organizationNumber = organizationTaxIdDataResponses
.Where(org => DoesNameMatchExpectedEntityName(org.Name, entityName))
.Select(p => p.OrganizationNumber).FirstOrDefault();
var organizationNumberString = organizationNumber != 0 ? organizationNumber.ToString() : null;
if (string.IsNullOrEmpty(organizationNumberString))
{
return false;
}
primaryOwnerAttribute.OrganizationNumber = organizationNumberString;
successPayload = ErrorCaptureResult<PrimaryOwnerAttribute>.CreateSuccessPayload(primaryOwnerAttribute);
return true;
}
}
@@ -0,0 +1,638 @@
using System.Data.SqlClient;
using Serilog;
using LCU.Library.Internal.DocumentIngestorModels.Entities;
using LCU.Library.Internal.Exceptions;
using LCU.API.Internal.DocumentIngestorLib.Repositories;
using LCU.Library.Internal.DocumentIngestorModels.Enums;
using LCU.Library.Internal.DocumentIngestorModels.Models;
using LCU.Library.Internal.DocumentIngestorModels.Models.Pagination;
using LCU.Api.Internal.MaidBotLib.Models;
using LCU.Library.Internal.DocumentIngestorModels.Constants;
namespace LCU.API.Internal.DocumentIngestor.Services;
public class DocumentProcessingInfoService : IDocumentProcessingInfoService
{
private readonly IUnitOfWork _unitOfWork;
private readonly IDocumentProcessingInfoRepository _documentProcessingInfoRepository;
private readonly IProcessingLogService _processingLogService;
private readonly Dictionary<ProcessStatusTypes, List<ProcessStatusTypes>> _statusChangeRejectionList =
new ()
{
[ProcessStatusTypes.Processing] = new()
{
ProcessStatusTypes.Reprocessing,
ProcessStatusTypes.UploadCompletionReprocessing
},
[ProcessStatusTypes.Completed] = new()
{
ProcessStatusTypes.Processing,
ProcessStatusTypes.Completed,
ProcessStatusTypes.ArchiveFailure,
ProcessStatusTypes.CriticalFailure,
ProcessStatusTypes.DataMappingFailure,
ProcessStatusTypes.Reprocessing,
ProcessStatusTypes.NotificationDataFailure,
ProcessStatusTypes.UploadCompletionReprocessing
},
[ProcessStatusTypes.ArchiveFailure] = new()
{
ProcessStatusTypes.UploadCompletionReprocessing
},
[ProcessStatusTypes.CriticalFailure] = new()
{
ProcessStatusTypes.UploadCompletionReprocessing
},
[ProcessStatusTypes.DataMappingFailure] = new()
{
ProcessStatusTypes.Processing,
ProcessStatusTypes.Completed,
ProcessStatusTypes.ArchiveFailure,
ProcessStatusTypes.CriticalFailure,
ProcessStatusTypes.DataMappingFailure,
ProcessStatusTypes.Reprocessing,
ProcessStatusTypes.NotificationDataFailure,
ProcessStatusTypes.UploadCompletionReprocessing
},
[ProcessStatusTypes.Reprocessing] = new()
{
ProcessStatusTypes.Processing,
ProcessStatusTypes.UploadCompletionReprocessing
},
[ProcessStatusTypes.NotificationDataFailure] = new()
{
ProcessStatusTypes.Processing,
ProcessStatusTypes.ArchiveFailure,
ProcessStatusTypes.CriticalFailure,
ProcessStatusTypes.DataMappingFailure,
ProcessStatusTypes.Reprocessing,
ProcessStatusTypes.UploadCompletionReprocessing
},
[ProcessStatusTypes.UploadCompletionReprocessing] = new()
{
ProcessStatusTypes.Processing,
ProcessStatusTypes.ArchiveFailure,
ProcessStatusTypes.CriticalFailure,
ProcessStatusTypes.DataMappingFailure,
ProcessStatusTypes.Reprocessing
}
};
public DocumentProcessingInfoService(IUnitOfWork unitOfWork,
IDocumentProcessingInfoRepository documentProcessingInfoRepository,
IProcessingLogService processingLogService)
{
_unitOfWork = unitOfWork;
_documentProcessingInfoRepository = documentProcessingInfoRepository;
_processingLogService = processingLogService;
}
public async Task<IEnumerable<DocumentProcessingInfo>> GetAsync()
{
try
{
var documentProcessingInfos = await _documentProcessingInfoRepository.FindAsync();
return documentProcessingInfos;
}
catch (Exception exception)
{
Log.Error(exception, $"Failure retrieving DocumentProcessingInfos.");
throw new ServiceException($"Failure retrieving DocumentProcessingInfos.");
}
}
public async Task<DocumentProcessingInfo> GetByIdAsync(int id)
{
try
{
var documentProcessingInfo = await _documentProcessingInfoRepository.FindByIdAsync(id);
return documentProcessingInfo;
}
catch (Exception exception)
{
Log.Error(exception, $"Failure retrieving DocumentProcessingInfo with DocumentProcessingInfoId {id}.");
throw new ServiceException($"Failure retrieving DocumentProcessingInfo with DocumentProcessingInfoId {id}.");
}
}
public async Task<IEnumerable<DocumentProcessingInfo>> GetListByIdAsync(List<int> ids)
{
try
{
var documentProcessingInfo = await _documentProcessingInfoRepository.FindListByIdAsync(ids);
return documentProcessingInfo;
}
catch (Exception exception)
{
var message = $"Failure retrieving list of DocumentProcessingInfos with DocumentProcessingInfoIds: {String.Join(", ", ids.ToArray())}.";
Log.Error(exception, message);
throw new ServiceException(message);
}
}
public async Task<IEnumerable<DocumentProcessingInfo>> GetByIngestorRunInfoIdAsync(Guid ingestorRunInfoId)
{
try
{
var documentProcessingInfos = await _documentProcessingInfoRepository.FindByIngestorRunInfoIdAsync(ingestorRunInfoId);
return documentProcessingInfos;
}
catch (Exception exception)
{
Log.Error(exception, $"Failure retrieving DocumentProcessingInfos with IngestorRunInfoId {ingestorRunInfoId}.");
throw new ServiceException($"Failure retrieving DocumentProcessingInfos with IngestorRunInfoId {ingestorRunInfoId}.");
}
}
public async Task<IEnumerable<DocumentProcessingInfo>> GetByProcessStatusTypeAsync(ProcessStatusTypes statusType, bool? isUnknown = null)
{
try
{
return await _documentProcessingInfoRepository.FindByProcessStatusTypeAsync(statusType, isUnknown);
}
catch (Exception exception)
{
var message = $"Failure retrieving DocumentProcessingInfos with Process Status Type {statusType}. " +
"IsUnknown: " + (isUnknown is null ? "null" : isUnknown.ToString());
Log.Error(exception, message);
throw new ServiceException(message);
}
}
public async Task<IEnumerable<DocumentProcessingInfo>> GetByProcessStatusTypeListAsync(List<ProcessStatusTypes> statusTypes, bool? isUnknown = null)
{
try
{
return await _documentProcessingInfoRepository.FindByProcessStatusTypeListAsync(statusTypes, isUnknown);
}
catch (Exception exception)
{
var message = $"Failure retrieving DocumentProcessingInfos with Process Status Type {(statusTypes is null ? "null" : string.Join(",", statusTypes))}. " +
"IsUnknown: " + (isUnknown is null ? "null" : isUnknown.ToString());
Log.Error(exception, message);
throw new ServiceException(message);
}
}
public async Task<IEnumerable<DocumentProcessingInfo>> GetCompletedFirstPassByIngestorRunInfoIdAsync(Guid ingestorRunInfoId)
{
try
{
return await _documentProcessingInfoRepository.FindCompletedFirstPassByIngestorRunInfoIdAsync(ingestorRunInfoId);
}
catch (Exception exception)
{
var message =
"Failure retrieving CompletedFirstPassByIngestorRunInfoId DocumentProcessingInfos. " +
$"IngestorRunInfoId: {ingestorRunInfoId}";
Log.Error(exception, message);
throw new ServiceException(message);
}
}
public async Task<DocumentProcessingInfo> SaveAsync(DocumentProcessingInfo documentProcessingInfo)
{
try
{
var result = await _documentProcessingInfoRepository.AddAsync(documentProcessingInfo);
await _unitOfWork.CompleteAsync();
return result;
}
catch (Exception exception)
{
Log.Error(exception, $"Failure saving DocumentProcessingInfo.");
throw new ServiceException($"Failure saving DocumentProcessingInfo.");
}
}
public async Task SaveRangeAsync(DocumentProcessingInfo[] documentProcessingInfos)
{
try
{
await _documentProcessingInfoRepository.AddRangeAsync(documentProcessingInfos);
await _unitOfWork.CompleteAsync();
}
catch (Exception exception)
{
Log.Error(exception, "Failure saving range DocumentProcessingInfo.");
throw new ServiceException("Failure saving range DocumentProcessingInfo.");
}
}
public async Task<DocumentProcessingInfo?> UpdateStatusAndAddLog(int documentProcessingInfoId,
ProcessStatusTypes statusType,
string logMessage,
string userName,
bool? entityIsUnknown = null)
{
return await UpdateStatusAndAddLog(documentProcessingInfoId, statusType, new List<string>(new string[] { logMessage }), userName, entityIsUnknown);
}
public async Task<DocumentProcessingInfo?> UpdateStatusAndAddLog(int documentProcessingInfoId,
ProcessStatusTypes statusType,
List<string> logMessages,
string userName,
bool? entityIsUnknown = null)
{
try
{
var documentProcessingInfo = await GetByIdAsync(documentProcessingInfoId);
return await UpdateStatusAndAddLog(documentProcessingInfo, statusType, logMessages, userName, entityIsUnknown);
}
catch (Exception exception)
{
Log.Error(exception, $"Failure Updating Status and Adding Processing Log. DocumentProcessingInfoId: {documentProcessingInfoId}");
throw new ServiceException($"Failure Updating Status and Adding Processing Log. DocumentProcessingInfoId: {documentProcessingInfoId}");
}
}
public async Task<DocumentProcessingInfo?> UpdateStatusAndAddLog(DocumentProcessingInfo documentProcessingInfo,
ProcessStatusTypes statusType,
string logMessage,
string userName,
bool? entityIsUnknown = null)
{
return await UpdateStatusAndAddLog(documentProcessingInfo, statusType, new List<string>(new string[] { logMessage }), userName, entityIsUnknown);
}
public async Task<DocumentProcessingInfo?> UpdateStatusAndAddLog(DocumentProcessingInfo documentProcessingInfo,
ProcessStatusTypes statusType,
List<string> logMessages,
string userName,
bool? entityIsUnknown = null)
{
try
{
ArgumentNullException.ThrowIfNull(documentProcessingInfo);
documentProcessingInfo.StatusType = statusType;
if (entityIsUnknown is not null)
{
documentProcessingInfo.EntityUnknown = entityIsUnknown ?? documentProcessingInfo.EntityUnknown;
}
var updated = await Update(documentProcessingInfo);
if (updated == null)
{
return null;
}
foreach (var log in logMessages)
{
if (string.IsNullOrWhiteSpace(log)) continue;
var processingLog = new ProcessingLog(updated.DocumentProcessingInfoId, DateTime.Now, log, userName);
await _processingLogService.SaveAsync(processingLog);
}
return updated;
}
catch (Exception exception)
{
Log.Error(exception, $"Failure Updating Status and Adding Processing Log. DocumentProcessingInfoId: {documentProcessingInfo.DocumentProcessingInfoId}");
throw new ServiceException($"Failure Updating Status and Adding Processing Log. DocumentProcessingInfoId: {documentProcessingInfo.DocumentProcessingInfoId}");
}
}
public async Task<DocumentProcessingInfo?> UpdateProcessCountAndStatusAndAddLog(int documentProcessingInfoId,
ProcessStatusTypes statusType,
string logMessage,
string userName,
bool? entityIsUnknown = null)
{
return await UpdateProcessCountAndStatusAndAddLog(documentProcessingInfoId, statusType, new List<string>(new string[] { logMessage }), userName, entityIsUnknown);
}
public async Task<DocumentProcessingInfo?> UpdateProcessCountAndStatusAndAddLog(int documentProcessingInfoId,
ProcessStatusTypes statusType,
List<string> logMessages,
string userName,
bool? entityIsUnknown = null)
{
try
{
var documentProcessingInfo = await GetByIdAsync(documentProcessingInfoId);
return await UpdateProcessCountAndStatusAndAddLog(documentProcessingInfo, statusType, logMessages, userName, entityIsUnknown);
}
catch (Exception exception)
{
Log.Error(exception, $"Failure Updating Process Count, Status, and Adding Processing Log. DocumentProcessingInfoId: {documentProcessingInfoId}");
throw new ServiceException($"Failure Updating Process Count, Status, and Adding Processing Log. DocumentProcessingInfoId: {documentProcessingInfoId}");
}
}
public async Task<List<CompletionProcessingData>> UpdateProcessCountAndStatusAndAddLog(List<CompletionRequest> requests)
{
var processingLogs = new List<ProcessingLog>();
var documentProcessingInfos = await GetListByIdAsync(requests.Select(r => r.ProcessingRequest.DocumentProcessingInfoId).ToList());
var completionProcessingDatas = PairCompletionRequestAndDocumentProcessingInfo(requests, documentProcessingInfos);
foreach (var data in completionProcessingDatas)
{
data.DocumentProcessingInfo.ProcessCount++;
data.DocumentProcessingInfo.StatusType = data.CompletionRequest.ProcessResult.ProcessStatusType;
data.DocumentProcessingInfo.EntityUnknown = data.CompletionRequest.ProcessResult.EntityIsUnknown ?? data.DocumentProcessingInfo.EntityUnknown;
if(data.CompletionRequest.ProcessResult.MessageStack != null || data.CompletionRequest.ProcessResult.MessageStack.Count > 0)
{
foreach (var message in data.CompletionRequest.ProcessResult.MessageStack)
{
if (string.IsNullOrWhiteSpace(message)) continue;
processingLogs.Add(new ProcessingLog(data.CompletionRequest.ProcessingRequest.DocumentProcessingInfoId, DateTime.Now, message, Users.System));
}
}
}
await UpdateRangeAsync(completionProcessingDatas.Select(d => d.DocumentProcessingInfo).ToList());
if (processingLogs.Count() >= 1)
{
await _processingLogService.SaveRangeAsync(processingLogs);
}
return completionProcessingDatas;
}
public async Task<DocumentProcessingInfo?> UpdateProcessCountAndStatusAndAddLog(DocumentProcessingInfo documentProcessingInfo,
ProcessStatusTypes statusType,
string logMessage,
string userName,
bool? entityIsUnknown = null)
{
return await UpdateProcessCountAndStatusAndAddLog(documentProcessingInfo, statusType, new List<string>(new string[] { logMessage }), userName, entityIsUnknown);
}
public async Task<DocumentProcessingInfo?> UpdateProcessCountAndStatusAndAddLog(DocumentProcessingInfo documentProcessingInfo,
ProcessStatusTypes statusType,
List<string> logMessages,
string userName,
bool? entityIsUnknown = null)
{
try
{
ArgumentNullException.ThrowIfNull(documentProcessingInfo);
documentProcessingInfo.ProcessCount++;
return await UpdateStatusAndAddLog(documentProcessingInfo, statusType, logMessages, userName, entityIsUnknown);
}
catch (Exception exception)
{
Log.Error(exception, $"Failure Updating Process Count, Status, and Adding Processing Log. DocumentProcessingInfoId: {documentProcessingInfo.DocumentProcessingInfoId}");
throw new ServiceException($"Failure Updating Process Count, Status, and Adding Processing Log. DocumentProcessingInfoId: {documentProcessingInfo.DocumentProcessingInfoId}");
}
}
public List<CompletionProcessingData> PairCompletionRequestAndDocumentProcessingInfo(List<CompletionRequest> requests, IEnumerable<DocumentProcessingInfo> documentProcessingInfos)
{
var completionProcessingDatas = new List<CompletionProcessingData>();
foreach (var request in requests)
{
var documentProcessingInfo = documentProcessingInfos.Where(d => d.DocumentProcessingInfoId == request.ProcessingRequest.DocumentProcessingInfoId).FirstOrDefault();
if (documentProcessingInfo is null)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Error(new Exception(), $"Failure during PairCompletionRequestAndDocumentProcessingInfo. " +
$"The DocumentProcessingInfo was not found for DocumentProcessingInfoId: {request.ProcessingRequest.DocumentProcessingInfoId}");
continue;
}
completionProcessingDatas.Add(new CompletionProcessingData() { CompletionRequest = request, DocumentProcessingInfo = documentProcessingInfo });
}
return completionProcessingDatas;
}
public async Task<DocumentProcessingInfo?> Update(DocumentProcessingInfo documentProcessingInfo)
{
try
{
var existing = await GetByIdAsync(documentProcessingInfo.DocumentProcessingInfoId);
if (existing == null)
{
return existing;
}
existing.CreatedDate = documentProcessingInfo.CreatedDate;
existing.DocumentValuePayload = documentProcessingInfo.DocumentValuePayload;
existing.StatusType = documentProcessingInfo.StatusType;
existing.EntityUnknown = documentProcessingInfo.EntityUnknown;
_documentProcessingInfoRepository.Update(existing);
_unitOfWork.Complete();
return existing;
}
catch (SqlException sqlException)
{
Log.Error(sqlException, $"SQL Failure updating DocumentProcessingInfo. " +
$"DocumentProcessingInfoId: {documentProcessingInfo.DocumentProcessingInfoId}");
throw new ServiceException($"SQL Failure updating DocumentProcessingInfo. " +
$"DocumentProcessingInfoId: {documentProcessingInfo.DocumentProcessingInfoId}");
}
catch (Exception exception)
{
Log.Error(exception, $"Failure updating DocumentProcessingInfo. " +
$"DocumentProcessingInfoId: {documentProcessingInfo.DocumentProcessingInfoId}");
throw new ServiceException($"Failure updating DocumentProcessingInfo. " +
$"DocumentProcessingInfoId: {documentProcessingInfo.DocumentProcessingInfoId}");
}
}
public async Task<IEnumerable<DocumentProcessingInfo>> UpdateRangeAsync(IEnumerable<DocumentProcessingInfo> documentProcessingInfos)
{
try
{
var infos = documentProcessingInfos.ToList();
_documentProcessingInfoRepository.UpdateRange(infos);
await _unitOfWork.CompleteAsync();
return infos;
}
catch (SqlException sqlException)
{
var message = "SQL Failure updating list of DocumentProcessingInfos.";
Log.Error(sqlException, message);
throw new ServiceException(message);
}
catch (Exception exception)
{
var message = "Failure updating list of DocumentProcessingInfos.";
Log.Error(exception, message);
throw new ServiceException(message);
}
}
public async Task Delete(int id)
{
try
{
var documentProcessingInfo = await GetByIdAsync(id);
ArgumentNullException.ThrowIfNull(documentProcessingInfo);
_documentProcessingInfoRepository.Remove(documentProcessingInfo);
_unitOfWork.Complete();
}
catch (SqlException sqlException)
{
Log.Error(sqlException, $"SQL failure removing DocumentProcessingInfo. DocumentProcessingInfoId: {id}");
throw new ServiceException($"SQL failure removing DocumentProcessingInfo. DocumentProcessingInfoId: {id}");
}
catch (Exception exception)
{
Log.Error(exception, $"Failure removing DocumentProcessingInfo. DocumentProcessingInfoId: {id}");
throw new ServiceException($"Failure removing DocumentProcessingInfo. DocumentProcessingInfoId: {id}");
}
}
public async Task<PagedResult<DocumentProcessingInfo>> GetFilteredDocumentProcessingInfo(Filter filter)
{
try
{
return await _documentProcessingInfoRepository.FilteredListAsync(filter);
}
catch (Exception exception)
{
Log.Error(exception, "Failure retrieving filtered documentProcessingInfo.");
throw new ServiceException("Failure retrieving filtered documentProcessingInfo.");
}
}
public async Task<int> CountCompletedByIngestorRunInfoIdAsync(Guid ingestorRunInfoId)
{
try
{
return await _documentProcessingInfoRepository.CountCompletedByIngestorRunInfoIdAsync(ingestorRunInfoId);
}
catch (Exception exception)
{
Log.Error(exception, "Failure counting CompletedByIngestorRunInfoId DocumentProcessingInfos for run info {IngestorRunInfoId}", ingestorRunInfoId);
throw new ServiceException($"Failure counting CompletedByIngestorRunInfoId DocumentProcessingInfos for run info {ingestorRunInfoId}");
}
}
public async Task<int> CountCompletedFirstPassByIngestorRunInfoIdAsync(Guid ingestorRunInfoId)
{
try
{
return await _documentProcessingInfoRepository.CountCompletedFirstPassByIngestorRunInfoIdAsync(ingestorRunInfoId);
}
catch (Exception exception)
{
Log.Error(exception, "Failure counting CompletedFirstPassByIngestorRunInfoId DocumentProcessingInfos for run info {IngestorRunInfoId}", ingestorRunInfoId);
throw new ServiceException($"Failure counting CompletedFirstPassByIngestorRunInfoId DocumentProcessingInfos for run info {ingestorRunInfoId}");
}
}
public async Task<IEnumerable<DocumentProcessingInfo>?> SetDocumentsToEntityUnknown(EntityUnknownRequest request)
{
try
{
var documentProcessingInfos = await GetListByIdAsync(request.DocumentProcessingInfoIds);
if (!documentProcessingInfos.Any())
{
throw new ServiceException("No DocumentProcessingInfo(s) were found");
}
foreach (var documentProcessingInfo in documentProcessingInfos)
{
var logMessage = "Record's EntityUnknown set to True. DocumentProcessingInfoId:" +
$" {documentProcessingInfo.DocumentProcessingInfoId} by {request.UserName} on {DateTime.Now}";
var processingLog = new ProcessingLog(documentProcessingInfo.DocumentProcessingInfoId, DateTime.Now, logMessage, request.UserName);
processingLog = await _processingLogService.SaveAsync(processingLog);
if (processingLog == null)
{
throw new ServiceException("ProcessingLog could not be saved for DocumentProcessingInfoId: " +
documentProcessingInfo.DocumentProcessingInfoId);
}
documentProcessingInfo.EntityUnknown = true;
await Update(documentProcessingInfo);
}
return documentProcessingInfos;
}
catch (ArgumentNullException exception)
{
var message = "Failure during SetDocumentsToUnknown for " +
$"DocumentProcessingInfoIds: ({string.Join(", ", request.DocumentProcessingInfoIds.ToArray())}). " +
$"ExceptionMessage: {exception.Message}";
Log.Error(exception, message);
throw new ServiceException(message);
}
catch (Exception exception)
{
var message = "Failure during SetDocumentsToUnknown for " +
$"DocumentProcessingInfoIds: ({string.Join(", ", request.DocumentProcessingInfoIds.ToArray())}).";
Log.Error(exception, message);
throw new ServiceException(message);
}
}
public async Task<DocumentProcessingInfo?> UpdateDocumentProcessingInfoStatus(DocumentProcessingInfoStatusRequest request)
{
try
{
var documentProcessingInfo = await GetByIdAsync(request.DocumentProcessingInfoId);
if (documentProcessingInfo == null)
{
throw new ServiceException("DocumentProcessingInfo was not found.");
}
if (documentProcessingInfo.StatusType == request.ProcessStatus)
{
throw new ServiceException("DocumentProcessingInfo had the same status as the request and cannot be changed. " +
$"Status: {documentProcessingInfo.StatusType}");
}
var statusChangeNotAllowed = _statusChangeRejectionList[documentProcessingInfo.StatusType].Contains(request.ProcessStatus);
if (statusChangeNotAllowed)
{
throw new ServiceException($"DocumentProcessingInfo had a status of '{Enum.GetName(documentProcessingInfo.StatusType)}' " +
$"and cannot be changed to the requested status of '{Enum.GetName(request.ProcessStatus)}'.");
}
var logMessage = $"Record's ProcessStatus changed from {documentProcessingInfo.StatusType} to {request.ProcessStatus}." +
$" DocumentProcessingInfoId: {documentProcessingInfo.DocumentProcessingInfoId} by {request.Username} on {DateTime.Now}." +
$" Reason: {request.ReasonMessage}";
return await UpdateStatusAndAddLog(documentProcessingInfo, request.ProcessStatus, new List<string> { logMessage }, request.Username);
}
catch (ArgumentNullException exception)
{
var message = "Failure during UpdateDocumentProcessingInfoStatus for " +
$"DocumentProcessingInfoId: ({request.DocumentProcessingInfoId}). " +
$"ExceptionMessage: {exception.Message}";
Log.Error(exception, message);
throw new ServiceException(message);
}
catch (Exception exception)
{
var message = "Failure during UpdateDocumentProcessingInfoStatus for " +
$"DocumentProcessingInfoId: ({request.DocumentProcessingInfoId}).";
Log.Error(exception, message);
throw new ServiceException(message);
}
}
public async Task<IDictionary<Guid, DocumentProcessingInfo?>> GetByDocumentIdsAsync(Guid[] ids)
{
try
{
var infos = (await _documentProcessingInfoRepository.FindByDocumentIdsAsync(ids))
.Where(i => i.DocumentId != null)
.ToDictionary(i => i.DocumentId.Value);
foreach (var missingId in ids.Where(i => !infos.ContainsKey(i)))
{
infos[missingId] = null;
}
return infos;
}
catch (Exception exception)
{
var message = "Failure retrieving DocumentProcessingInfos by DocumentIds.";
Log.Error(exception, message);
throw new ServiceException(message);
}
}
}
@@ -0,0 +1,11 @@
using LCU.Library.Internal.LCUServiceFactory.Configurations;
using LCU.Library.Internal.LCUServiceFactory.Services;
namespace LCU.API.Internal.DocumentIngestor.Services.DocumentProcessorServices;
public abstract class DocumentProcessingService : LcuAbstractService
{
protected DocumentProcessingService(ServicesFactoryConfiguration servicesFactoryConfiguration)
: base(servicesFactoryConfiguration.GetServiceFactoryRegistrationByInterface<IDocumentProcessingService>())
{ }
}
@@ -0,0 +1,257 @@
using System.Globalization;
using LCU.API.Internal.DocumentIngestor.Services.AttributeDeterminingServices;
using LCU.API.Internal.DocumentIngestor.Services.MicroApiServices;
using LCU.Library.DocumentType.Enums;
using LCU.Library.DocumentType.Extensions;
using LCU.Library.DocumentType.Models.Requests.Account;
using LCU.Library.DocumentType.Models.Requests.Attributes;
using LCU.Library.DocumentType.Models.Requests.PrimaryOwner;
using LCU.Library.Internal.DocumentIngestorModels.Entities;
using LCU.Library.Internal.DocumentIngestorModels.Enums;
using LCU.Library.Internal.DocumentIngestorModels.Models;
using LCU.Library.Internal.DocumentIngestorModels.Models.IndexFileDocuments;
using LCU.Library.Internal.DocumentIngestorModels.Validations;
using LCU.Library.Internal.LCUServiceFactory.Configurations;
using Newtonsoft.Json;
using Serilog;
namespace LCU.API.Internal.DocumentIngestor.Services.DocumentProcessorServices
{
public class FosDnaDocumentProcessingService : DocumentProcessingService, IDocumentProcessingService
{
private const DataSourceTypes DataSource = DataSourceTypes.DNA;
private const SourceTypes Source = SourceTypes.FOS;
private readonly IPrimaryOwnerDeterminingService _primaryOwnerDeterminingService;
private readonly IAccountOwnerDeterminingService _accountOwnerDeterminingService;
private readonly IFileOperationsApiService _fileOperationsApiService;
private readonly IDocumentTypeUploaderApiService _documentTypeUploaderApiService;
public FosDnaDocumentProcessingService(IPrimaryOwnerDeterminingService primaryOwnerDeterminingService,
IAccountOwnerDeterminingService accountDeterminingService,
IFileOperationsApiService fileOperationsApiService,
IDocumentTypeUploaderApiService documentTypeUploaderApiService,
ServicesFactoryConfiguration servicesFactoryConfiguration)
: base(servicesFactoryConfiguration)
{
_documentTypeUploaderApiService = documentTypeUploaderApiService;
_fileOperationsApiService = fileOperationsApiService;
_primaryOwnerDeterminingService = primaryOwnerDeterminingService;
_accountOwnerDeterminingService = accountDeterminingService;
}
public async Task<ProcessResult> ProcessRequest(ProcessingRequest request)
{
var processResult = new ProcessResult();
try
{
Log.Debug("Starting FosDnaDocument ProcessRequest.");
ArgumentNullException.ThrowIfNull(request);
var documentValues = JsonConvert.DeserializeObject<FosDnaDocument>(request.DocumentValuePayload);
ArgumentNullException.ThrowIfNull(documentValues);
processResult = ValidateRecord(processResult, documentValues, request.OwnerOverrideInfo);
if (!processResult.Success)
{
return processResult;
}
if (!DateTime.TryParseExact(documentValues.CreationDate, "MMddyyyy", CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, out var creationDate))
{
var message = $"A Creation Date of '{documentValues.CreationDate}' could not be properly formatted " +
$"for an Account Owner of AccountNumber: {documentValues?.AccountNumber} and EntityName: {documentValues?.EntityName}";
processResult = ProcessResult.ProcessDataMappingFailure(processResult, message);
return processResult;
}
if (EnumExtensions.IsDocumentTypeOf<PrimaryOwnerDocumentTypes>(documentValues.DocType))
{
processResult = await HandlePrimaryOwner(request, processResult, documentValues, creationDate);
}
else if (EnumExtensions.IsDocumentTypeOf<AccountDocumentTypes>(documentValues.DocType))
{
processResult = await HandleAccountOwner(request, processResult, documentValues, creationDate);
}
else
{
var message = $"Document Type of {documentValues.DocType} could not be found." +
$"for an Account Owner of AccountNumber: {documentValues?.AccountNumber} and EntityName: {documentValues?.EntityName}";
Log.Error(message);
processResult = ProcessResult.ProcessCriticalFailure(processResult, message);
return processResult;
}
Log.Debug("Ending FosDna ProcessRequest.");
}
catch (Exception exception)
{
var message = "An Exception occured while FosDnaDocument ProcessRequest. " +
$"Exception Message: {exception.Message} ";
Log.Error(exception, message);
processResult = ProcessResult.ProcessCriticalFailure(processResult, message);
}
return processResult;
}
public ProcessResult ValidateRecord(ProcessResult processResult,
FosDnaDocument documentValues,
OwnerOverrideInfo? ownerOverrideInfo)
{
// Keep at top to set EntityUnknown for PsInfoChangeNotice documents with invalid Account Numbers
// Business would like override to skip AccountNumber validation for PsInfoChangeNotice
if (!SkipAccountNumberValidationForPsInfoChangeNotice(documentValues.DocType, ownerOverrideInfo))
{
processResult = MetaDataValidation.ValidateAccountNumber(processResult, documentValues.AccountNumber);
processResult = SetToEntityUnknown(processResult, documentValues.DocType, ownerOverrideInfo);
}
processResult = MetaDataValidation.ValidateFileName(processResult, documentValues.DocName);
processResult = MetaDataValidation.ValidateFullName(processResult, documentValues.EntityName);
return processResult;
}
public async Task<ProcessResult> HandlePrimaryOwner(ProcessingRequest request,
ProcessResult processResult,
FosDnaDocument documentValues,
DateTime creationDate)
{
var primaryOwnerAttribute = await _primaryOwnerDeterminingService.DeterminePrimaryOwnerAttribute(documentValues.EntityName,
documentValues.AccountNumber,
creationDate,
request.OwnerOverrideInfo);
if (!primaryOwnerAttribute.Success)
{
processResult = ProcessResult.ProcessDataMappingFailure(processResult,
primaryOwnerAttribute.Message);
return processResult;
}
var primaryOwnerRequest = await BuildPrimaryOwnerUploadRequest(request, documentValues, creationDate, primaryOwnerAttribute.Payload);
await _documentTypeUploaderApiService.UploadPrimaryOwnerDocument(primaryOwnerRequest, request, processResult);
return processResult;
}
public async Task<ProcessResult> HandleAccountOwner(ProcessingRequest request,
ProcessResult processResult,
FosDnaDocument documentValues,
DateTime creationDate)
{
var accountOwnerAttribute = await _accountOwnerDeterminingService.DetermineAccountOwnerAttribute(documentValues.EntityName,
documentValues.AccountNumber,
creationDate,
request.OwnerOverrideInfo);
if (!accountOwnerAttribute.Success)
{
processResult = ProcessResult.ProcessDataMappingFailure(processResult,
accountOwnerAttribute.Message);
return processResult;
}
var accountOwnerRequest = await BuildAccountUploadRequest(request, documentValues, creationDate, accountOwnerAttribute.Payload);
await _documentTypeUploaderApiService.UploadAccountDocument(accountOwnerRequest, request, processResult);
return processResult;
}
public async Task<PrimaryOwnerDocumentRequest> BuildPrimaryOwnerUploadRequest(ProcessingRequest request,
FosDnaDocument documentValues,
DateTime creationDate,
PrimaryOwnerAttribute primaryOwnerAttribute)
{
var contentBytes = await _fileOperationsApiService.GetContentBytes(request.IngestorRequest.RootPath,
request.DocumentFileName);
var type = documentValues.DocType.GetValueFromName<PrimaryOwnerDocumentTypes>();
ArgumentNullException.ThrowIfNull(type);
var primaryOwnerDocumentRequest = new PrimaryOwnerDocumentRequest
{
Content = contentBytes,
PrimaryOwnerAttribute = primaryOwnerAttribute,
PrimaryOwnerDocumentMetadata = new PrimaryOwnerDocumentMetadata
{
Source = Source,
DataSource = DataSource,
Name = documentValues.DocName,
Type = type,
CreatedDate = creationDate,
TraceId = request.IngestorRunInfoId
}
};
return primaryOwnerDocumentRequest;
}
public async Task<AccountDocumentRequest> BuildAccountUploadRequest(ProcessingRequest request,
FosDnaDocument documentValues,
DateTime creationDate,
AccountAttribute accountAttribute)
{
var contentBytes = await _fileOperationsApiService.GetContentBytes(request.IngestorRequest.RootPath,
request.DocumentFileName);
var type = documentValues.DocType.GetValueFromName<AccountDocumentTypes>();
ArgumentNullException.ThrowIfNull(type);
var accountOwnerDocumentRequest = new AccountDocumentRequest
{
Content = contentBytes,
AccountAttribute = accountAttribute,
AccountDocumentMetadata = new AccountDocumentMetadata
{
Source = Source,
DataSource = DataSource,
Name = documentValues.DocName,
Type = type,
CreatedDate = creationDate,
TraceId = request.IngestorRunInfoId
}
};
return accountOwnerDocumentRequest;
}
private ProcessResult SetToEntityUnknown(ProcessResult processResult,
string documentType,
OwnerOverrideInfo? ownerOverrideInfo)
{
if (string.IsNullOrWhiteSpace(documentType)
|| processResult.Success
|| processResult.ProcessStatusType != ProcessStatusTypes.DataMappingFailure
|| ownerOverrideInfo is not null)
{
return processResult;
}
if (EnumExtensions.IsDocumentTypeOf<PrimaryOwnerDocumentTypes>(documentType))
{
switch (documentType.GetValueFromName<PrimaryOwnerDocumentTypes>())
{
case PrimaryOwnerDocumentTypes.PsInfoChangeNotice:
processResult.EntityIsUnknown = true;
break;
}
}
return processResult;
}
private bool SkipAccountNumberValidationForPsInfoChangeNotice(string docType, OwnerOverrideInfo? ownerOverrideInfo)
{
if (!EnumExtensions.IsDocumentTypeOf<PrimaryOwnerDocumentTypes>(docType))
{
return false;
}
if (ownerOverrideInfo is null
|| docType.GetValueFromName<PrimaryOwnerDocumentTypes>() != PrimaryOwnerDocumentTypes.PsInfoChangeNotice)
{
return false;
}
return true;
}
}
}
@@ -0,0 +1,128 @@
using System.Globalization;
using LCU.API.Internal.DocumentIngestor.Services.AttributeDeterminingServices;
using LCU.API.Internal.DocumentIngestor.Services.MicroApiServices;
using LCU.Library.DocumentType.Enums;
using LCU.Library.DocumentType.Extensions;
using LCU.Library.DocumentType.Models.Requests.Account;
using LCU.Library.DocumentType.Models.Requests.Attributes;
using LCU.Library.Internal.DocumentIngestorModels.Models;
using LCU.Library.Internal.DocumentIngestorModels.Models.IndexFileDocuments;
using LCU.Library.Internal.DocumentIngestorModels.Validations;
using LCU.Library.Internal.LCUServiceFactory.Configurations;
using Newtonsoft.Json;
using Serilog;
namespace LCU.API.Internal.DocumentIngestor.Services.DocumentProcessorServices
{
public class FosLoanStatementProcessingService : DocumentProcessingService, IDocumentProcessingService
{
private const DataSourceTypes DataSource = DataSourceTypes.DNA;
private const SourceTypes Source = SourceTypes.FOS;
private const string DateFormat = "yyyyMMdd";
private readonly IAccountOwnerDeterminingService _accountOwnerDeterminingService;
private readonly IFileOperationsApiService _fileOperationsApiService;
private readonly IDocumentTypeUploaderApiService _documentTypeUploaderApiService;
public FosLoanStatementProcessingService(IAccountOwnerDeterminingService accountDeterminingService,
IFileOperationsApiService fileOperationsApiService,
IDocumentTypeUploaderApiService documentTypeUploaderApiService,
ServicesFactoryConfiguration servicesFactoryConfiguration)
: base(servicesFactoryConfiguration)
{
_documentTypeUploaderApiService = documentTypeUploaderApiService;
_fileOperationsApiService = fileOperationsApiService;
_accountOwnerDeterminingService = accountDeterminingService;
}
public async Task<ProcessResult> ProcessRequest(ProcessingRequest request)
{
var processResult = new ProcessResult();
try
{
Log.Debug("Starting FosLoanStatement ProcessRequest.");
ArgumentNullException.ThrowIfNull(request);
var documentValues = JsonConvert.DeserializeObject<FosLoanStatement>(request.DocumentValuePayload);
ArgumentNullException.ThrowIfNull(documentValues);
processResult = ValidateRecord(processResult, documentValues);
if (!processResult.Success)
{
return processResult;
}
if (!DateTime.TryParseExact(documentValues.CreationDate, DateFormat, CultureInfo.InvariantCulture,
DateTimeStyles.AssumeLocal, out var creationDate))
{
var message =
$"A Creation Date of {documentValues.CreationDate} could not be properly formatted from format: {DateFormat}";
return ProcessResult.ProcessDataMappingFailure(processResult, message);
}
var accountOwnerAttribute = await _accountOwnerDeterminingService.DetermineAccountOwnerAttribute(
documentValues.EntityName,
documentValues.AccountNumber,
creationDate,
request.OwnerOverrideInfo);
if (!accountOwnerAttribute.Success)
{
return ProcessResult.ProcessDataMappingFailure(processResult,
accountOwnerAttribute.Message);
}
var accountOwnerRequest = await BuildAccountUploadRequest(request, documentValues, creationDate, accountOwnerAttribute.Payload);
await _documentTypeUploaderApiService.UploadAccountDocument(accountOwnerRequest, request, processResult);
Log.Debug("Ending FosLoanStatement ProcessRequest.");
}
catch (Exception exception)
{
var message = $"An Exception occured while FosLoanStatement ProcessRequest. " +
$"Exception Message: {exception.Message} ";
Log.Error(exception, message);
processResult = ProcessResult.ProcessCriticalFailure(processResult, message);
}
return processResult;
}
public ProcessResult ValidateRecord(ProcessResult processResult, FosLoanStatement documentValues)
{
processResult = MetaDataValidation.ValidateAccountNumber(processResult, documentValues.AccountNumber);
processResult = MetaDataValidation.ValidateFileName(processResult, documentValues.DocName);
processResult = MetaDataValidation.ValidateFullName(processResult, documentValues.EntityName);
processResult = MetaDataValidation.ValidateDocumentType<AccountDocumentTypes>(processResult, documentValues.DocType);
return processResult;
}
public async Task<AccountDocumentRequest> BuildAccountUploadRequest(ProcessingRequest request,
FosLoanStatement documentValues,
DateTime creationDate,
AccountAttribute accountAttribute)
{
var contentBytes = await _fileOperationsApiService.GetContentBytes(request.IngestorRequest.RootPath,
request.DocumentFileName);
var type = documentValues.DocType.GetValueFromName<AccountDocumentTypes>();
ArgumentNullException.ThrowIfNull(type);
var accountOwnerDocumentRequest = new AccountDocumentRequest
{
Content = contentBytes,
AccountAttribute = accountAttribute,
AccountDocumentMetadata = new AccountDocumentMetadata
{
Source = Source,
DataSource = DataSource,
Name = request.DocumentFileName,
Type = type,
CreatedDate = creationDate,
TraceId = request.IngestorRunInfoId
}
};
return accountOwnerDocumentRequest;
}
}
}
@@ -0,0 +1,161 @@
using Newtonsoft.Json;
using Serilog;
using LCU.Library.DocumentType.Enums;
using LCU.Library.DocumentType.Extensions;
using LCU.Library.DocumentType.Models.Requests.Attributes;
using LCU.Library.DocumentType.Models.Requests.PrimaryOwner;
using LCU.Library.DocumentType.Models.Requests.Generic;
using LCU.Library.Internal.DocumentIngestorModels.Models;
using LCU.Library.Internal.DocumentIngestorModels.Models.IndexFileDocuments;
using LCU.Library.Internal.DocumentIngestorModels.Validations;
using LCU.API.Internal.DocumentIngestor.Services.AttributeDeterminingServices;
using LCU.API.Internal.DocumentIngestor.Services.MicroApiServices;
using LCU.Library.Internal.LCUServiceFactory.Configurations;
namespace LCU.API.Internal.DocumentIngestor.Services.DocumentProcessorServices;
public class FosTaxStatementProcessingService : DocumentProcessingService, IDocumentProcessingService
{
private readonly IPrimaryOwnerDeterminingService _primaryOwnerDeterminingService;
private readonly IFileOperationsApiService _fileOperationsApiService;
private readonly IDocumentTypeUploaderApiService _documentTypeUploaderApiService;
private const DataSourceTypes DataSource = DataSourceTypes.DNA;
private const SourceTypes Source = SourceTypes.FOS;
public FosTaxStatementProcessingService(IPrimaryOwnerDeterminingService userIdDeterminingService,
IFileOperationsApiService fileOperationsApiService,
IDocumentTypeUploaderApiService documentTypeUploaderApiService,
ServicesFactoryConfiguration servicesFactoryConfiguration)
: base(servicesFactoryConfiguration)
{
_documentTypeUploaderApiService = documentTypeUploaderApiService;
_fileOperationsApiService = fileOperationsApiService;
_primaryOwnerDeterminingService = userIdDeterminingService;
}
public async Task<ProcessResult> ProcessRequest(ProcessingRequest request)
{
var processResult = new ProcessResult();
try
{
Log.Debug("Starting FosTaxStatement ProcessRequest.");
ArgumentNullException.ThrowIfNull(request);
var documentValues = JsonConvert.DeserializeObject<FosTaxStatementDocument>(request.DocumentValuePayload);
ArgumentNullException.ThrowIfNull(documentValues);
processResult = ValidateRecord(processResult, documentValues);
if (!processResult.Success)
{
return processResult;
}
if (EnumExtensions.IsDocumentTypeOf<PrimaryOwnerDocumentTypes>(documentValues.FileName))
{
var primaryOwnerAttribute = await _primaryOwnerDeterminingService.DeterminePrimaryOwnerAttribute(
documentValues.FullName,
documentValues.AccountNumber,
documentValues.PrimaryTIN,
request.OwnerOverrideInfo);
if (!primaryOwnerAttribute.Success)
{
processResult = ProcessResult.ProcessDataMappingFailure(processResult,
primaryOwnerAttribute.Message);
return processResult;
}
var uploadRequest = await BuildUploadRequest(request, documentValues, primaryOwnerAttribute.Payload);
await _documentTypeUploaderApiService.UploadPrimaryOwnerDocument(uploadRequest, request, processResult);
}
else if (EnumExtensions.IsDocumentTypeOf<GenericDocumentTypes>(documentValues.FileName))
{
var genericAttribute = new GenericDocumentAttribute
{
EntityName = documentValues.FullName
};
var uploadRequest = await BuildGenericUploadRequest(request, documentValues, genericAttribute);
await _documentTypeUploaderApiService.UploadGenericDocument(uploadRequest, request, processResult);
}
else
{
var message = $"Document Type of {documentValues.FileName} could not be found.";
Log.Error(message);
processResult = ProcessResult.ProcessCriticalFailure(processResult, message);
return processResult;
}
}
catch (Exception exception)
{
var message = "An Exception occured while FosTaxStatement ProcessRequest. " +
$"Exception Message: {exception.Message} ";
Log.Error(exception, message);
processResult = ProcessResult.ProcessCriticalFailure(processResult, message);
}
Log.Debug("Ending FosTaxStatement ProcessRequest.");
return processResult;
}
public ProcessResult ValidateRecord(ProcessResult processResult, FosTaxStatementDocument documentValues)
{
processResult = MetaDataValidation.ValidateAccountNumber(processResult, documentValues.AccountNumber);
processResult = MetaDataValidation.ValidateFileName(processResult, documentValues.FileName);
processResult = MetaDataValidation.ValidateFullName(processResult, documentValues.FullName);
processResult = MetaDataValidation.ValidatePdf(processResult, documentValues.PDF);
processResult = MetaDataValidation.ValidateTin(processResult, documentValues.PrimaryTIN);
return processResult;
}
public async Task<PrimaryOwnerDocumentRequest> BuildUploadRequest(ProcessingRequest request,
FosTaxStatementDocument documentValues,
PrimaryOwnerAttribute primaryOwnerAttribute)
{
var contentBytes = await _fileOperationsApiService.GetContentBytes(request.IngestorRequest.RootPath,
request.DocumentFileName);
var type = documentValues.FileName.GetValueFromName<PrimaryOwnerDocumentTypes>();
var primaryOwnerDocumentRequest = new PrimaryOwnerDocumentRequest
{
Content = contentBytes,
PrimaryOwnerAttribute = primaryOwnerAttribute,
PrimaryOwnerDocumentMetadata = new PrimaryOwnerDocumentMetadata
{
Source = Source,
DataSource = DataSource,
Name = documentValues.PDF,
Type = type,
CreatedDate = DateTime.Now.Date,
TraceId = request.IngestorRunInfoId
}
};
return primaryOwnerDocumentRequest;
}
public async Task<GenericDocumentRequest> BuildGenericUploadRequest(ProcessingRequest request,
FosTaxStatementDocument documentValues,
GenericDocumentAttribute genericDocumentAttribute)
{
var contentBytes = await _fileOperationsApiService.GetContentBytes(request.IngestorRequest.RootPath,
request.DocumentFileName);
var type = documentValues.FileName.GetValueFromName<GenericDocumentTypes>();
var genericDocumentRequest = new GenericDocumentRequest
{
Content = contentBytes,
GenericDocumentAttribute = genericDocumentAttribute,
GenericDocumentMetadata = new GenericDocumentMetadata
{
Source = Source,
DataSource = DataSource,
Name = documentValues.PDF,
Type = type,
CreatedDate = DateTime.Now.Date,
TraceId = request.IngestorRunInfoId
}
};
return genericDocumentRequest;
}
}
@@ -0,0 +1,9 @@
using LCU.Library.Internal.DocumentIngestorModels.Models;
using LCU.Library.Internal.LCUServiceFactory.Services;
namespace LCU.API.Internal.DocumentIngestor.Services.DocumentProcessorServices;
public interface IDocumentProcessingService : ILcuService
{
Task<ProcessResult> ProcessRequest(ProcessingRequest request);
}
@@ -0,0 +1,126 @@
using Newtonsoft.Json;
using Serilog;
using LCU.Library.DocumentType.Enums;
using LCU.Library.DocumentType.Extensions;
using LCU.Library.DocumentType.Models.Requests.Attributes;
using LCU.Library.Internal.DocumentIngestorModels.Models;
using LCU.Library.Internal.DocumentIngestorModels.Models.IndexFileDocuments;
using LCU.Library.Internal.DocumentIngestorModels.Validations;
using LCU.API.Internal.DocumentIngestor.Services.AttributeDeterminingServices;
using LCU.API.Internal.DocumentIngestor.Services.MicroApiServices;
using System.Globalization;
using LCU.Library.DocumentType.Models.Requests.Account;
using LCU.Library.Internal.LCUServiceFactory.Configurations;
namespace LCU.API.Internal.DocumentIngestor.Services.DocumentProcessorServices;
public class OsgDnaNoticeSplitProcessingService : DocumentProcessingService, IDocumentProcessingService
{
private readonly IAccountOwnerDeterminingService _accountOwnerDeterminingService;
private readonly IFileOperationsApiService _fileOperationsApiService;
private readonly IDocumentTypeUploaderApiService _documentTypeUploaderApiService;
private const DataSourceTypes DataSource = DataSourceTypes.DNA;
private const SourceTypes Source = SourceTypes.OSG;
private const string DateFormat = "MMddyyyy";
public OsgDnaNoticeSplitProcessingService(IFileOperationsApiService fileOperationsApiService,
IDocumentTypeUploaderApiService documentTypeUploaderApiService,
IAccountOwnerDeterminingService accountOwnerDeterminingService,
ServicesFactoryConfiguration servicesFactoryConfiguration)
: base(servicesFactoryConfiguration)
{
_documentTypeUploaderApiService = documentTypeUploaderApiService;
_fileOperationsApiService = fileOperationsApiService;
_accountOwnerDeterminingService = accountOwnerDeterminingService;
}
public async Task<ProcessResult> ProcessRequest(ProcessingRequest request)
{
var processResult = new ProcessResult();
try
{
Log.Debug("Starting OsgDnaNoticeSplit ProcessRequest.");
ArgumentNullException.ThrowIfNull(request);
var documentValues = JsonConvert.DeserializeObject<OsgDnaNoticeSplit>(request.DocumentValuePayload);
ArgumentNullException.ThrowIfNull(documentValues);
processResult = ValidateRecord(processResult, documentValues);
if (!processResult.Success)
{
return processResult;
}
if (!DateTime.TryParseExact(documentValues.CreationDate, DateFormat, CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, out var creationDate))
{
var message = $"A Creation Date of '{documentValues.CreationDate}' could not be properly formatted " +
$"for an Account Owner of EntityName: {documentValues?.RecipientName} and EntityId: {documentValues?.AccountNumber}";
processResult = ProcessResult.ProcessDataMappingFailure(processResult, message);
return processResult;
}
var accountOwnerAttribute = await _accountOwnerDeterminingService.DetermineAccountOwnerAttributeByMemberNumberOrUserId(documentValues.UserId,
documentValues.AccountNumber,
documentValues.NoticeId,
creationDate,
request.OwnerOverrideInfo);
if (!accountOwnerAttribute.Success)
{
processResult = ProcessResult.ProcessDataMappingFailure(processResult,
accountOwnerAttribute.Message);
return processResult;
}
var accountOwnerRequest = await BuildUploadRequest(request, documentValues, creationDate, accountOwnerAttribute.Payload);
await _documentTypeUploaderApiService.UploadAccountDocument(accountOwnerRequest, request, processResult);
}
catch (Exception exception)
{
var message = "An Exception occured while OsgTaxStatement ProcessRequest. " +
$"Exception Message: {exception.Message} ";
Log.Error(exception, message);
processResult = ProcessResult.ProcessCriticalFailure(processResult, message);
}
Log.Debug("Ending OsgTaxStatement ProcessRequest.");
return processResult;
}
public ProcessResult ValidateRecord(ProcessResult processResult, OsgDnaNoticeSplit documentValues)
{
processResult = MetaDataValidation.ValidateAccountNumber(processResult, documentValues.AccountNumber);
processResult = MetaDataValidation.ValidateFileName(processResult, documentValues.NoticeName);
processResult = MetaDataValidation.ValidateFullName(processResult, documentValues.RecipientName);
processResult = MetaDataValidation.ValidatePdf(processResult, documentValues.PdfName);
return processResult;
}
public async Task<AccountDocumentRequest> BuildUploadRequest(ProcessingRequest request,
OsgDnaNoticeSplit documentValues,
DateTime creationDate,
AccountAttribute accountAttribute)
{
var contentBytes = await _fileOperationsApiService.GetContentBytes(request.IngestorRequest.RootPath,
request.DocumentFileName);
var type = documentValues.NoticeId.GetValueFromName<AccountDocumentTypes>();
ArgumentNullException.ThrowIfNull(type);
var accountOwnerDocumentRequest = new AccountDocumentRequest
{
Content = contentBytes,
AccountAttribute = accountAttribute,
AccountDocumentMetadata = new AccountDocumentMetadata
{
Source = Source,
DataSource = DataSource,
Name = documentValues.NoticeName,
Type = type,
CreatedDate = creationDate,
TraceId = request.IngestorRunInfoId
}
};
return accountOwnerDocumentRequest;
}
}
@@ -0,0 +1,187 @@
using LCU.API.Internal.DocumentIngestor.Services.AttributeDeterminingServices;
using LCU.API.Internal.DocumentIngestor.Services.MicroApiServices;
using LCU.Library.DocumentType.Enums;
using LCU.Library.DocumentType.Extensions;
using LCU.Library.DocumentType.Models.Requests.Account;
using LCU.Library.DocumentType.Models.Requests.Attributes;
using LCU.Library.DocumentType.Models.Requests.PrimaryOwner;
using LCU.Library.Internal.DocumentIngestorModels.Models;
using LCU.Library.Internal.DocumentIngestorModels.Models.IndexFileDocuments;
using LCU.Library.Internal.DocumentIngestorModels.Validations;
using Newtonsoft.Json;
using Serilog;
using System.Globalization;
using LCU.Library.Internal.LCUServiceFactory.Configurations;
namespace LCU.API.Internal.DocumentIngestor.Services.DocumentProcessorServices
{
public class OsgDnaNoticesProcessingService : DocumentProcessingService, IDocumentProcessingService
{
private const DataSourceTypes DataSource = DataSourceTypes.DNA;
private const SourceTypes Source = SourceTypes.OSG;
private readonly IPrimaryOwnerDeterminingService _primaryOwnerDeterminingService;
private readonly IFileOperationsApiService _fileOperationsApiService;
private readonly IDocumentTypeUploaderApiService _documentTypeUploaderApiService;
private readonly IAccountOwnerDeterminingService _accountOwnerDeterminingService;
private const string DateFormat = "yyyyMMdd";
public OsgDnaNoticesProcessingService(IPrimaryOwnerDeterminingService userIdDeterminingService,
IFileOperationsApiService fileOperationsApiService,
IDocumentTypeUploaderApiService documentTypeUploaderApiService,
IAccountOwnerDeterminingService accountDeterminingService,
ServicesFactoryConfiguration servicesFactoryConfiguration)
: base(servicesFactoryConfiguration)
{
_documentTypeUploaderApiService = documentTypeUploaderApiService;
_fileOperationsApiService = fileOperationsApiService;
_primaryOwnerDeterminingService = userIdDeterminingService;
_accountOwnerDeterminingService = accountDeterminingService;
}
public async Task<ProcessResult> ProcessRequest(ProcessingRequest request)
{
var processResult = new ProcessResult();
try
{
Log.Debug("Starting OsgDnaNoticesDocument ProcessRequest.");
ArgumentNullException.ThrowIfNull(request);
var documentValues = JsonConvert.DeserializeObject<OsgDnaNoticesDocument>(request.DocumentValuePayload);
ArgumentNullException.ThrowIfNull(documentValues);
processResult = ValidateRecord(processResult, documentValues);
if (!processResult.Success)
{
return processResult;
}
if (!DateTime.TryParseExact(documentValues.CreationDate, DateFormat, CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, out var creationDate))
{
var message = $"A Creation Date of '{documentValues.CreationDate}' could not be properly formatted " +
$"for an Account Owner of AccountNumber: {documentValues?.AccountNumber} and EntityId: {documentValues?.MemberNumberOrUserId}";
processResult = ProcessResult.ProcessDataMappingFailure(processResult, message);
return processResult;
}
if (EnumExtensions.IsDocumentTypeOf<PrimaryOwnerDocumentTypes>(documentValues.DocType))
{
var primaryOwnerAttribute = await _primaryOwnerDeterminingService.DeterminePrimaryOwnerAttributeByMemberNumberOrUserId(documentValues.MemberNumberOrUserId,
documentValues.AccountNumber,
documentValues.DocType,
creationDate,
request.OwnerOverrideInfo);
if (!primaryOwnerAttribute.Success)
{
processResult = ProcessResult.ProcessDataMappingFailure(processResult,
primaryOwnerAttribute.Message);
return processResult;
}
var primaryOwnerRequest = await BuildPrimaryOwnerUploadRequest(request, documentValues, creationDate, primaryOwnerAttribute.Payload);
await _documentTypeUploaderApiService.UploadPrimaryOwnerDocument(primaryOwnerRequest, request, processResult);
}
else if (EnumExtensions.IsDocumentTypeOf<AccountDocumentTypes>(documentValues.DocType))
{
var accountOwnerAttribute = await _accountOwnerDeterminingService.DetermineAccountOwnerAttributeByMemberNumberOrUserId(documentValues.MemberNumberOrUserId,
documentValues.AccountNumber,
documentValues.DocType,
creationDate,
request.OwnerOverrideInfo);
if (!accountOwnerAttribute.Success)
{
processResult = ProcessResult.ProcessDataMappingFailure(processResult,
accountOwnerAttribute.Message);
return processResult;
}
var accountOwnerRequest = await BuildAccountUploadRequest(request, documentValues, creationDate, accountOwnerAttribute.Payload);
await _documentTypeUploaderApiService.UploadAccountDocument(accountOwnerRequest, request, processResult);
}
else
{
var message = $"Document Type of {documentValues.DocType} could not be found." +
$"for an Account Owner of AccountNumber: {documentValues?.AccountNumber} and EntityName: {documentValues?.MemberNumberOrUserId}";
Log.Error(message);
processResult = ProcessResult.ProcessCriticalFailure(processResult, message);
return processResult;
}
Log.Debug("Ending OsgDnaNotices ProcessRequest.");
}
catch (Exception exception)
{
var message = "An Exception occured while OsgDnaNoticesDocument ProcessRequest. " +
$"Exception Message: {exception.Message} ";
Log.Error(exception, message);
processResult = ProcessResult.ProcessCriticalFailure(processResult, message);
}
return processResult;
}
public async Task<AccountDocumentRequest> BuildAccountUploadRequest(ProcessingRequest request,
OsgDnaNoticesDocument documentValues,
DateTime creationDate,
AccountAttribute accountAttribute)
{
var contentBytes = await _fileOperationsApiService.GetContentBytes(request.IngestorRequest.RootPath,
request.DocumentFileName);
var type = documentValues.DocType.GetValueFromName<AccountDocumentTypes>();
ArgumentNullException.ThrowIfNull(type);
var accountOwnerDocumentRequest = new AccountDocumentRequest
{
Content = contentBytes,
AccountAttribute = accountAttribute,
AccountDocumentMetadata = new AccountDocumentMetadata
{
Source = Source,
DataSource = DataSource,
Name = request.DocumentFileName,
Type = type,
CreatedDate = creationDate,
TraceId = request.IngestorRunInfoId
}
};
return accountOwnerDocumentRequest;
}
public async Task<PrimaryOwnerDocumentRequest> BuildPrimaryOwnerUploadRequest(ProcessingRequest request,
OsgDnaNoticesDocument documentValues,
DateTime creationDate,
PrimaryOwnerAttribute primaryOwnerAttribute)
{
var contentBytes = await _fileOperationsApiService.GetContentBytes(request.IngestorRequest.RootPath,
request.DocumentFileName);
var type = documentValues.DocType.GetValueFromName<PrimaryOwnerDocumentTypes>();
ArgumentNullException.ThrowIfNull(type);
var primaryOwnerDocumentRequest = new PrimaryOwnerDocumentRequest
{
Content = contentBytes,
PrimaryOwnerAttribute = primaryOwnerAttribute,
PrimaryOwnerDocumentMetadata = new PrimaryOwnerDocumentMetadata
{
Source = Source,
DataSource = DataSource,
Name = request.DocumentFileName,
Type = type,
CreatedDate = creationDate,
TraceId = request.IngestorRunInfoId
}
};
return primaryOwnerDocumentRequest;
}
private static ProcessResult ValidateRecord(ProcessResult processResult, OsgDnaNoticesDocument documentValues)
{
processResult = MetaDataValidation.ValidateAccountNumber(processResult, documentValues.AccountNumber);
processResult = MetaDataValidation.ValidateDate(processResult, documentValues.CreationDate, DateFormat);
return processResult;
}
}
}
@@ -0,0 +1,134 @@
using LCU.API.Internal.DocumentIngestor.Services.AttributeDeterminingServices;
using LCU.API.Internal.DocumentIngestor.Services.MicroApiServices;
using LCU.Library.DocumentType.Enums;
using LCU.Library.DocumentType.Extensions;
using LCU.Library.DocumentType.Models.Requests.Attributes;
using LCU.Library.DocumentType.Models.Requests.PrimaryOwner;
using LCU.Library.Internal.DocumentIngestorModels.Models;
using LCU.Library.Internal.DocumentIngestorModels.Models.IndexFileDocuments;
using LCU.Library.Internal.DocumentIngestorModels.Validations;
using Newtonsoft.Json;
using Serilog;
using System.Globalization;
using LCU.Library.Internal.LCUServiceFactory.Configurations;
namespace LCU.API.Internal.DocumentIngestor.Services.DocumentProcessorServices
{
public class OsgHistoricalDocumentProcessingService : DocumentProcessingService, IDocumentProcessingService
{
private const DataSourceTypes DataSource = DataSourceTypes.DNA;
private const SourceTypes Source = SourceTypes.OSG;
private readonly IPrimaryOwnerDeterminingService _primaryOwnerDeterminingService;
private readonly IFileOperationsApiService _fileOperationsApiService;
private readonly IDocumentTypeUploaderApiService _documentTypeUploaderApiService;
private const string DateFormat = "yyyyMMdd";
public OsgHistoricalDocumentProcessingService(IPrimaryOwnerDeterminingService userIdDeterminingService,
IFileOperationsApiService fileOperationsApiService,
IDocumentTypeUploaderApiService documentTypeUploaderApiService,
ServicesFactoryConfiguration servicesFactoryConfiguration)
: base(servicesFactoryConfiguration)
{
_documentTypeUploaderApiService = documentTypeUploaderApiService;
_fileOperationsApiService = fileOperationsApiService;
_primaryOwnerDeterminingService = userIdDeterminingService;
}
public async Task<ProcessResult> ProcessRequest(ProcessingRequest request)
{
var processResult = new ProcessResult();
try
{
Log.Debug("Starting OsgHistoricalDocument ProcessRequest.");
ArgumentNullException.ThrowIfNull(request);
var documentValues = JsonConvert.DeserializeObject<OsgHistoricalDocument>(request.DocumentValuePayload);
ArgumentNullException.ThrowIfNull(documentValues);
processResult = ValidateRecord(processResult, documentValues);
if (!processResult.Success)
{
return processResult;
}
if (!DateTime.TryParseExact(documentValues.CreationDate, DateFormat, CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, out var creationDate))
{
var message = $"A Creation Date of '{documentValues.CreationDate}' could not be properly formatted " +
$"for an Account Owner of EntityName: {documentValues?.EntityName} and EntityId: {documentValues?.MemberNumberOrUserId}";
processResult = ProcessResult.ProcessDataMappingFailure(processResult, message);
return processResult;
}
if (EnumExtensions.IsDocumentTypeOf<PrimaryOwnerDocumentTypes>(documentValues.DocType))
{
var primaryOwnerAttribute = await _primaryOwnerDeterminingService.DeterminePrimaryOwnerAttributeByMemberNumberOrUserId(documentValues.MemberNumberOrUserId,
documentValues.EntityName,
request.OwnerOverrideInfo);
if (!primaryOwnerAttribute.Success)
{
processResult = ProcessResult.ProcessDataMappingFailure(processResult, primaryOwnerAttribute.Message);
return processResult;
}
var primaryOwnerRequest = await BuildPrimaryOwnerUploadRequest(request, documentValues, creationDate, primaryOwnerAttribute.Payload);
await _documentTypeUploaderApiService.UploadPrimaryOwnerDocument(primaryOwnerRequest, request, processResult);
}
else
{
var message = $"Document Type of {documentValues.DocType} could not be found." +
$"for an Account Owner of EntityName: {documentValues?.EntityName} and EntityId: {documentValues?.MemberNumberOrUserId}";
Log.Error(message);
processResult = ProcessResult.ProcessCriticalFailure(processResult, message);
return processResult;
}
Log.Debug("Ending OsgHistoricalDocument ProcessRequest.");
}
catch (Exception exception)
{
var message = "An Exception occured while OsgHistoricalDocument ProcessRequest. " +
$"Exception Message: {exception.Message} ";
Log.Error(exception, message);
processResult = ProcessResult.ProcessCriticalFailure(processResult, message);
}
return processResult;
}
private async Task<PrimaryOwnerDocumentRequest> BuildPrimaryOwnerUploadRequest(ProcessingRequest request,
OsgHistoricalDocument documentValues,
DateTime creationDate,
PrimaryOwnerAttribute primaryOwnerAttribute)
{
var contentBytes = await _fileOperationsApiService.GetContentBytes(request.IngestorRequest.RootPath,
request.DocumentFileName);
var type = documentValues.DocType.GetValueFromName<PrimaryOwnerDocumentTypes>();
ArgumentNullException.ThrowIfNull(type);
var primaryOwnerDocumentRequest = new PrimaryOwnerDocumentRequest
{
Content = contentBytes,
PrimaryOwnerAttribute = primaryOwnerAttribute,
PrimaryOwnerDocumentMetadata = new PrimaryOwnerDocumentMetadata
{
Source = Source,
DataSource = DataSource,
Name = request.DocumentFileName,
Type = type,
CreatedDate = creationDate,
TraceId = request.IngestorRunInfoId
}
};
return primaryOwnerDocumentRequest;
}
private static ProcessResult ValidateRecord(ProcessResult processResult, OsgHistoricalDocument documentValues)
{
processResult = MetaDataValidation.ValidateFullName(processResult, documentValues.EntityName);
processResult = MetaDataValidation.ValidateDate(processResult, documentValues.CreationDate, DateFormat);
return processResult;
}
}
}
@@ -0,0 +1,173 @@
using Newtonsoft.Json;
using Serilog;
using LCU.Library.DocumentType.Enums;
using LCU.Library.DocumentType.Extensions;
using LCU.Library.DocumentType.Models.Requests.Attributes;
using LCU.Library.DocumentType.Models.Requests.PrimaryOwner;
using LCU.Library.DocumentType.Models.Requests.Generic;
using LCU.Library.Internal.DocumentIngestorModels.Models;
using LCU.Library.Internal.DocumentIngestorModels.Models.IndexFileDocuments;
using LCU.Library.Internal.DocumentIngestorModels.Validations;
using LCU.API.Internal.DocumentIngestor.Services.AttributeDeterminingServices;
using LCU.API.Internal.DocumentIngestor.Services.MicroApiServices;
using Microsoft.VisualBasic;
using System.Globalization;
using LCU.Library.Internal.LCUServiceFactory.Configurations;
namespace LCU.API.Internal.DocumentIngestor.Services.DocumentProcessorServices;
public class OsgTaxStatementProcessingService : DocumentProcessingService, IDocumentProcessingService
{
private readonly IPrimaryOwnerDeterminingService _primaryOwnerDeterminingService;
private readonly IFileOperationsApiService _fileOperationsApiService;
private readonly IDocumentTypeUploaderApiService _documentTypeUploaderApiService;
private const DataSourceTypes DataSource = DataSourceTypes.DNA;
private const SourceTypes Source = SourceTypes.OSG;
private const string DateFormat = "MMddyyyy";
public OsgTaxStatementProcessingService(IPrimaryOwnerDeterminingService userIdDeterminingService,
IFileOperationsApiService fileOperationsApiService,
IDocumentTypeUploaderApiService documentTypeUploaderApiService,
ServicesFactoryConfiguration servicesFactoryConfiguration)
: base(servicesFactoryConfiguration)
{
_documentTypeUploaderApiService = documentTypeUploaderApiService;
_fileOperationsApiService = fileOperationsApiService;
_primaryOwnerDeterminingService = userIdDeterminingService;
}
public async Task<ProcessResult> ProcessRequest(ProcessingRequest request)
{
var processResult = new ProcessResult();
try
{
Log.Debug("Starting OsgTaxStatement ProcessRequest.");
ArgumentNullException.ThrowIfNull(request);
var documentValues = JsonConvert.DeserializeObject<OsgTaxStatement>(request.DocumentValuePayload);
ArgumentNullException.ThrowIfNull(documentValues);
processResult = ValidateRecord(processResult, documentValues);
if (!processResult.Success)
{
return processResult;
}
if (!DateTime.TryParseExact(documentValues.CreationDate, DateFormat, CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, out var creationDate))
{
var message = $"A Creation Date of '{documentValues.CreationDate}' could not be properly formatted " +
$"for an Account Owner of EntityName: {documentValues?.RecipientName} and EntityId: {documentValues?.AccountNumber}";
processResult = ProcessResult.ProcessDataMappingFailure(processResult, message);
return processResult;
}
if (EnumExtensions.IsDocumentTypeOf<PrimaryOwnerDocumentTypes>(documentValues.NoticeName))
{
var primaryOwnerAttribute = await _primaryOwnerDeterminingService.DeterminePrimaryOwnerAttribute(
documentValues.RecipientName,
documentValues.AccountNumber,
documentValues.SSN,
request.OwnerOverrideInfo);
if (!primaryOwnerAttribute.Success)
{
processResult = ProcessResult.ProcessDataMappingFailure(processResult,
primaryOwnerAttribute.Message);
return processResult;
}
var uploadRequest = await BuildUploadRequest(request, documentValues, primaryOwnerAttribute.Payload, creationDate);
await _documentTypeUploaderApiService.UploadPrimaryOwnerDocument(uploadRequest, request, processResult);
}
else if (EnumExtensions.IsDocumentTypeOf<GenericDocumentTypes>(documentValues.NoticeName))
{
var genericAttribute = new GenericDocumentAttribute
{
EntityName = documentValues.RecipientName
};
var uploadRequest = await BuildGenericUploadRequest(request, documentValues, genericAttribute);
await _documentTypeUploaderApiService.UploadGenericDocument(uploadRequest, request, processResult);
}
else
{
var message = $"Document Type of {documentValues.NoticeName} could not be found.";
Log.Error(message);
processResult = ProcessResult.ProcessCriticalFailure(processResult, message);
return processResult;
}
}
catch (Exception exception)
{
var message = "An Exception occured while OsgTaxStatement ProcessRequest. " +
$"Exception Message: {exception.Message} ";
Log.Error(exception, message);
processResult = ProcessResult.ProcessCriticalFailure(processResult, message);
}
Log.Debug("Ending OsgTaxStatement ProcessRequest.");
return processResult;
}
public ProcessResult ValidateRecord(ProcessResult processResult, OsgTaxStatement documentValues)
{
processResult = MetaDataValidation.ValidateAccountNumber(processResult, documentValues.AccountNumber);
processResult = MetaDataValidation.ValidateFileName(processResult, documentValues.NoticeName);
processResult = MetaDataValidation.ValidateFullName(processResult, documentValues.RecipientName);
processResult = MetaDataValidation.ValidatePdf(processResult, documentValues.PdfName);
processResult = MetaDataValidation.ValidateTin(processResult, documentValues.SSN);
return processResult;
}
public async Task<PrimaryOwnerDocumentRequest> BuildUploadRequest(ProcessingRequest request,
OsgTaxStatement documentValues,
PrimaryOwnerAttribute primaryOwnerAttribute,
DateTime creationDate)
{
var contentBytes = await _fileOperationsApiService.GetContentBytes(request.IngestorRequest.RootPath,
request.DocumentFileName);
var type = documentValues.NoticeName.GetValueFromName<PrimaryOwnerDocumentTypes>();
var primaryOwnerDocumentRequest = new PrimaryOwnerDocumentRequest
{
Content = contentBytes,
PrimaryOwnerAttribute = primaryOwnerAttribute,
PrimaryOwnerDocumentMetadata = new PrimaryOwnerDocumentMetadata
{
Source = Source,
DataSource = DataSource,
Name = documentValues.PdfName,
Type = type,
CreatedDate = creationDate,
TraceId = request.IngestorRunInfoId
}
};
return primaryOwnerDocumentRequest;
}
public async Task<GenericDocumentRequest> BuildGenericUploadRequest(ProcessingRequest request,
OsgTaxStatement documentValues,
GenericDocumentAttribute genericDocumentAttribute)
{
var contentBytes = await _fileOperationsApiService.GetContentBytes(request.IngestorRequest.RootPath,
request.DocumentFileName);
var type = documentValues.NoticeName.GetValueFromName<GenericDocumentTypes>();
var genericDocumentRequest = new GenericDocumentRequest
{
Content = contentBytes,
GenericDocumentAttribute = genericDocumentAttribute,
GenericDocumentMetadata = new GenericDocumentMetadata
{
Source = Source,
DataSource = DataSource,
Name = documentValues.PdfName,
Type = type,
CreatedDate = DateTime.Now.Date,
TraceId = request.IngestorRunInfoId
}
};
return genericDocumentRequest;
}
}
@@ -0,0 +1,131 @@
using System.Globalization;
using Newtonsoft.Json;
using Serilog;
using LCU.Library.DocumentType.Enums;
using LCU.Library.DocumentType.Extensions;
using LCU.Library.DocumentType.Models.Requests.Account;
using LCU.Library.DocumentType.Models.Requests.Attributes;
using LCU.Library.Internal.DocumentIngestorModels.Models;
using LCU.Library.Internal.DocumentIngestorModels.Models.IndexFileDocuments;
using LCU.Library.Internal.DocumentIngestorModels.Validations;
using LCU.API.Internal.DocumentIngestor.Services.AttributeDeterminingServices;
using LCU.API.Internal.DocumentIngestor.Services.MicroApiServices;
using LCU.Library.Internal.LCUServiceFactory.Configurations;
namespace LCU.API.Internal.DocumentIngestor.Services.DocumentProcessorServices;
public class OsgTemenosNoticeProcessingService : DocumentProcessingService, IDocumentProcessingService
{
private readonly IAccountOwnerDeterminingService _accountOwnerDeterminingService;
private readonly IFileOperationsApiService _fileOperationsApiService;
private readonly IDocumentTypeUploaderApiService _documentTypeUploaderApiService;
private const DataSourceTypes DataSource = DataSourceTypes.DNA;
private const SourceTypes Source = SourceTypes.XDI;
private const string DateFormat = "MMddyyyy";
public OsgTemenosNoticeProcessingService(IAccountOwnerDeterminingService accountOwnerDeterminingService,
IFileOperationsApiService fileOperationsApiService,
IDocumentTypeUploaderApiService documentTypeUploaderApiService,
ServicesFactoryConfiguration servicesFactoryConfiguration)
: base(servicesFactoryConfiguration)
{
_documentTypeUploaderApiService = documentTypeUploaderApiService;
_fileOperationsApiService = fileOperationsApiService;
_accountOwnerDeterminingService = accountOwnerDeterminingService;
}
public async Task<ProcessResult> ProcessRequest(ProcessingRequest request)
{
var processResult = new ProcessResult();
try
{
Log.Debug("Starting OsgTemenosNotice ProcessRequest.");
ArgumentNullException.ThrowIfNull(request);
var documentValues = JsonConvert.DeserializeObject<OsgTemenosNoticesDocument>(request.DocumentValuePayload);
ArgumentNullException.ThrowIfNull(documentValues);
processResult = ValidateRecord(processResult, documentValues);
if (!processResult.Success)
{
return processResult;
}
if (!DateTime.TryParseExact(documentValues.CreationDate,
DateFormat,
CultureInfo.InvariantCulture,
DateTimeStyles.AssumeLocal,
out var creationDate))
{
var message = $"A Creation Date of {documentValues.CreationDate} could not " +
$"be properly formatted from format: {DateFormat}";
return ProcessResult.ProcessDataMappingFailure(processResult,
message);
}
var accountOwnerAttribute = await _accountOwnerDeterminingService.DetermineAccountOwnerAttribute(documentValues.EntityName,
documentValues.AccountNumber,
creationDate,
request.OwnerOverrideInfo);
if (!accountOwnerAttribute.Success)
{
return ProcessResult.ProcessDataMappingFailure(processResult,
accountOwnerAttribute.Message);
}
var accountOwnerRequest = await BuildUploadRequest(request,
documentValues,
creationDate,
accountOwnerAttribute.Payload);
await _documentTypeUploaderApiService.UploadAccountDocument(accountOwnerRequest, request, processResult);
Log.Debug("Ending OsgTemenosNoticesDocument ProcessRequest.");
}
catch (Exception exception)
{
var message =
$"An Exception occured while OsgTemenosNoticesDocument ProcessRequest. Exception Message: {exception.Message}";
Log.Error(exception, message);
processResult = ProcessResult.ProcessCriticalFailure(processResult, message);
}
return processResult;
}
private static ProcessResult ValidateRecord(ProcessResult processResult, OsgTemenosNoticesDocument documentValues)
{
processResult = MetaDataValidation.ValidateAccountNumber(processResult, documentValues.AccountNumber);
processResult = MetaDataValidation.ValidatePdf(processResult, documentValues.PDF);
processResult = MetaDataValidation.ValidateFullName(processResult, documentValues.EntityName);
processResult = MetaDataValidation.ValidateDate(processResult, documentValues.CreationDate, DateFormat);
processResult = MetaDataValidation.ValidateDocumentType<AccountDocumentTypes>(processResult, documentValues.DocumentType);
return processResult;
}
private async Task<AccountDocumentRequest> BuildUploadRequest(ProcessingRequest request,
OsgTemenosNoticesDocument documentValues,
DateTime creationDate,
AccountAttribute accountAttribute)
{
var contentBytes = await _fileOperationsApiService.GetContentBytes(request.IngestorRequest.RootPath, request.DocumentFileName);
var type = documentValues.DocumentType.GetValueFromName<AccountDocumentTypes>();
ArgumentNullException.ThrowIfNull(type);
return new AccountDocumentRequest
{
Content = contentBytes,
AccountAttribute = accountAttribute,
AccountDocumentMetadata = new AccountDocumentMetadata
{
Source = Source,
DataSource = DataSource,
Name = documentValues.PDF,
Type = type,
CreatedDate = creationDate,
TraceId = request.IngestorRunInfoId
}
};
}
}
@@ -0,0 +1,126 @@
using Newtonsoft.Json;
using Serilog;
using LCU.Library.DocumentType.Enums;
using LCU.Library.DocumentType.Extensions;
using LCU.Library.DocumentType.Models.Requests.Attributes;
using LCU.Library.DocumentType.Models.Requests.PrimaryOwner;
using LCU.Library.DocumentType.Models.Requests.Generic;
using LCU.Library.Internal.DocumentIngestorModels.Models;
using LCU.Library.Internal.DocumentIngestorModels.Models.IndexFileDocuments;
using LCU.Library.Internal.DocumentIngestorModels.Validations;
using LCU.API.Internal.DocumentIngestor.Services.AttributeDeterminingServices;
using LCU.API.Internal.DocumentIngestor.Services.MicroApiServices;
using Microsoft.VisualBasic;
using System.Globalization;
using LCU.Library.Internal.LCUServiceFactory.Configurations;
namespace LCU.API.Internal.DocumentIngestor.Services.DocumentProcessorServices;
public class OsgVehicleTaxStatementProcessingService : DocumentProcessingService, IDocumentProcessingService
{
private readonly IPrimaryOwnerDeterminingService _primaryOwnerDeterminingService;
private readonly IFileOperationsApiService _fileOperationsApiService;
private readonly IDocumentTypeUploaderApiService _documentTypeUploaderApiService;
private const DataSourceTypes DataSource = DataSourceTypes.DNA;
private const SourceTypes Source = SourceTypes.OSG;
private const string DateFormat = "MMddyyyy";
public OsgVehicleTaxStatementProcessingService(IPrimaryOwnerDeterminingService userIdDeterminingService,
IFileOperationsApiService fileOperationsApiService,
IDocumentTypeUploaderApiService documentTypeUploaderApiService,
ServicesFactoryConfiguration servicesFactoryConfiguration)
: base(servicesFactoryConfiguration)
{
_documentTypeUploaderApiService = documentTypeUploaderApiService;
_fileOperationsApiService = fileOperationsApiService;
_primaryOwnerDeterminingService = userIdDeterminingService;
}
public async Task<ProcessResult> ProcessRequest(ProcessingRequest request)
{
var processResult = new ProcessResult();
try
{
Log.Debug("Starting OsgVehicleTaxStatement ProcessRequest.");
ArgumentNullException.ThrowIfNull(request);
var documentValues = JsonConvert.DeserializeObject<OsgTaxStatement>(request.DocumentValuePayload);
ArgumentNullException.ThrowIfNull(documentValues);
processResult = ValidateRecord(processResult, documentValues);
if (!processResult.Success)
{
return processResult;
}
if (!DateTime.TryParseExact(documentValues.CreationDate, DateFormat, CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, out var creationDate))
{
var message = $"A Creation Date of '{documentValues.CreationDate}' could not be properly formatted " +
$"for an Account Owner of EntityName: {documentValues?.RecipientName} and EntityId: {documentValues?.AccountNumber}";
processResult = ProcessResult.ProcessDataMappingFailure(processResult, message);
return processResult;
}
var primaryOwnerAttribute = await _primaryOwnerDeterminingService.DeterminePrimaryOwnerAttribute(
documentValues.RecipientName,
documentValues.AccountNumber,
creationDate,
request.OwnerOverrideInfo);
if (!primaryOwnerAttribute.Success)
{
processResult = ProcessResult.ProcessDataMappingFailure(processResult,
primaryOwnerAttribute.Message);
return processResult;
}
var uploadRequest = await BuildUploadRequest(request, documentValues, primaryOwnerAttribute.Payload, creationDate);
await _documentTypeUploaderApiService.UploadPrimaryOwnerDocument(uploadRequest, request, processResult);
}
catch (Exception exception)
{
var message = "An Exception occured while OsgVehicleTaxStatement ProcessRequest. " +
$"Exception Message: {exception.Message} ";
Log.Error(exception, message);
processResult = ProcessResult.ProcessCriticalFailure(processResult, message);
}
Log.Debug("Ending OsgVehicleTaxStatement ProcessRequest.");
return processResult;
}
public ProcessResult ValidateRecord(ProcessResult processResult, OsgTaxStatement documentValues)
{
processResult = MetaDataValidation.ValidateAccountNumber(processResult, documentValues.AccountNumber);
processResult = MetaDataValidation.ValidateFileName(processResult, documentValues.NoticeName);
processResult = MetaDataValidation.ValidateFullName(processResult, documentValues.RecipientName);
processResult = MetaDataValidation.ValidatePdf(processResult, documentValues.PdfName);
return processResult;
}
public async Task<PrimaryOwnerDocumentRequest> BuildUploadRequest(ProcessingRequest request,
OsgTaxStatement documentValues,
PrimaryOwnerAttribute primaryOwnerAttribute,
DateTime creationDate)
{
var contentBytes = await _fileOperationsApiService.GetContentBytes(request.IngestorRequest.RootPath,
request.DocumentFileName);
var type = documentValues.NoticeId.GetValueFromName<PrimaryOwnerDocumentTypes>();
var primaryOwnerDocumentRequest = new PrimaryOwnerDocumentRequest
{
Content = contentBytes,
PrimaryOwnerAttribute = primaryOwnerAttribute,
PrimaryOwnerDocumentMetadata = new PrimaryOwnerDocumentMetadata
{
Source = Source,
DataSource = DataSource,
Name = documentValues.PdfName,
Type = type,
CreatedDate = creationDate,
TraceId = request.IngestorRunInfoId
}
};
return primaryOwnerDocumentRequest;
}
}
@@ -0,0 +1,137 @@
using LCU.API.Internal.DocumentIngestor.Services.AttributeDeterminingServices;
using LCU.API.Internal.DocumentIngestor.Services.MicroApiServices;
using LCU.Library.DocumentType.Enums;
using LCU.Library.DocumentType.Extensions;
using LCU.Library.DocumentType.Models.Requests.Attributes;
using LCU.Library.DocumentType.Models.Requests.Account;
using LCU.Library.Internal.DocumentIngestorModels.Models;
using LCU.Library.Internal.DocumentIngestorModels.Models.IndexFileDocuments;
using LCU.Library.Internal.DocumentIngestorModels.Validations;
using Newtonsoft.Json;
using Serilog;
using System.Globalization;
using LCU.Library.Internal.LCUServiceFactory.Configurations;
namespace LCU.API.Internal.DocumentIngestor.Services.DocumentProcessorServices
{
public class OsgWeilandStatementProcessingService : DocumentProcessingService, IDocumentProcessingService
{
private const DataSourceTypes DataSource = DataSourceTypes.WEILAND;
private const SourceTypes Source = SourceTypes.OSG;
private readonly IAccountOwnerDeterminingService _accountOwnerDeterminingService;
private readonly IFileOperationsApiService _fileOperationsApiService;
private readonly IDocumentTypeUploaderApiService _documentTypeUploaderApiService;
private const string DateFormat = "yyyyMMdd";
public OsgWeilandStatementProcessingService(IAccountOwnerDeterminingService accountOwnerDeterminingService,
IFileOperationsApiService fileOperationsApiService,
IDocumentTypeUploaderApiService documentTypeUploaderApiService,
ServicesFactoryConfiguration servicesFactoryConfiguration)
: base(servicesFactoryConfiguration)
{
_documentTypeUploaderApiService = documentTypeUploaderApiService;
_fileOperationsApiService = fileOperationsApiService;
_accountOwnerDeterminingService = accountOwnerDeterminingService;
}
public async Task<ProcessResult> ProcessRequest(ProcessingRequest request)
{
var processResult = new ProcessResult();
try
{
Log.Debug("Starting OsgWeilandDocument ProcessRequest.");
ArgumentNullException.ThrowIfNull(request);
var documentValues = JsonConvert.DeserializeObject<OsgWeilandStatement>(request.DocumentValuePayload);
ArgumentNullException.ThrowIfNull(documentValues);
processResult = ValidateRecord(processResult, documentValues);
if (!processResult.Success)
{
return processResult;
}
if (!DateTime.TryParseExact(documentValues.Date, DateFormat, CultureInfo.InvariantCulture, DateTimeStyles.AssumeLocal, out var creationDate))
{
var message = $"A Creation Date of '{documentValues.Date}' could not be properly formatted " +
$"for an Account Owner of EntityName: {documentValues?.AccountTitle} and EntityId: {documentValues?.AccountNumber}";
processResult = ProcessResult.ProcessDataMappingFailure(processResult, message);
return processResult;
}
if (EnumExtensions.IsDocumentTypeOf<AccountDocumentTypes>(documentValues.DocCode))
{
var accountOwnerAttribute = await _accountOwnerDeterminingService.DetermineAccountOwnerAttribute(documentValues.AccountTitle,
documentValues.AccountNumber,
creationDate,
request.OwnerOverrideInfo);
if (!accountOwnerAttribute.Success)
{
processResult = ProcessResult.ProcessDataMappingFailure(processResult, accountOwnerAttribute.Message);
return processResult;
}
var accountOwnerRequest = await BuildUploadRequest(request,
documentValues,
creationDate,
accountOwnerAttribute.Payload);
await _documentTypeUploaderApiService.UploadAccountDocument(accountOwnerRequest, request, processResult);
}
else
{
var message = $"Document Type of {documentValues.DocCode} could not be found." +
$"for an Account Owner of EntityName: {documentValues?.AccountTitle} and EntityId: {documentValues?.AccountNumber}";
Log.Error(message);
processResult = ProcessResult.ProcessCriticalFailure(processResult, message);
return processResult;
}
Log.Debug("Ending OsgWeilandStatement ProcessRequest.");
}
catch (Exception exception)
{
var message = "An Exception occured while OsgWeilandStatement ProcessRequest. " +
$"Exception Message: {exception.Message} ";
Log.Error(exception, message);
processResult = ProcessResult.ProcessCriticalFailure(processResult, message);
}
return processResult;
}
private async Task<AccountDocumentRequest> BuildUploadRequest(ProcessingRequest request,
OsgWeilandStatement documentValues,
DateTime creationDate,
AccountAttribute accountAttribute)
{
var contentBytes = await _fileOperationsApiService.GetContentBytes(request.IngestorRequest.RootPath, request.DocumentFileName);
var type = documentValues.DocCode.GetValueFromName<AccountDocumentTypes>();
ArgumentNullException.ThrowIfNull(type);
return new AccountDocumentRequest
{
Content = contentBytes,
AccountAttribute = accountAttribute,
AccountDocumentMetadata = new AccountDocumentMetadata
{
Source = Source,
DataSource = DataSource,
Name = documentValues.PdfName,
Type = type,
CreatedDate = creationDate,
TraceId = request.IngestorRunInfoId
}
};
}
private static ProcessResult ValidateRecord(ProcessResult processResult, OsgWeilandStatement documentValues)
{
processResult = MetaDataValidation.ValidateAccountNumber(processResult, documentValues.AccountNumber);
processResult = MetaDataValidation.ValidatePdf(processResult, documentValues.PdfName);
processResult = MetaDataValidation.ValidateDate(processResult, documentValues.Date, DateFormat);
processResult = MetaDataValidation.ValidateDocumentType<AccountDocumentTypes>(processResult, documentValues.DocCode);
return processResult;
}
}
}
@@ -0,0 +1,105 @@
using LCU.API.Internal.DocumentIngestor.Services.MicroApiServices;
using LCU.Library.DocumentType.Enums;
using LCU.Library.DocumentType.Extensions;
using LCU.Library.DocumentType.Models.Requests.Generic;
using LCU.Library.DocumentType.Models.Requests.Attributes;
using LCU.Library.Internal.DocumentIngestorModels.Models;
using LCU.Library.Internal.DocumentIngestorModels.Models.IndexFileDocuments;
using LCU.Library.Internal.DocumentIngestorModels.Validations;
using LCU.Library.Internal.LCUServiceFactory.Configurations;
using Newtonsoft.Json;
using Serilog;
namespace LCU.API.Internal.DocumentIngestor.Services.DocumentProcessorServices;
public class XdiActionNoticesProcessingService : DocumentProcessingService, IDocumentProcessingService
{
private const DataSourceTypes DataSource = DataSourceTypes.ACTION;
private const SourceTypes Source = SourceTypes.XDI;
private const string DateFormat = "mm/dd/yyyy";
private readonly IFileOperationsApiService _fileOperationsApiService;
private readonly IDocumentTypeUploaderApiService _documentTypeUploaderApiService;
public XdiActionNoticesProcessingService(IFileOperationsApiService fileOperationsApiService,
IDocumentTypeUploaderApiService documentTypeUploaderApiService,
ServicesFactoryConfiguration servicesFactoryConfiguration)
: base(servicesFactoryConfiguration)
{
_documentTypeUploaderApiService = documentTypeUploaderApiService;
_fileOperationsApiService = fileOperationsApiService;
}
public async Task<ProcessResult> ProcessRequest(ProcessingRequest request)
{
var processResult = new ProcessResult();
try
{
Log.Debug("Starting XdiActionNotice ProcessRequest.");
ArgumentNullException.ThrowIfNull(request);
var documentValues = JsonConvert.DeserializeObject<XdiActionNoticesDocument>(request.DocumentValuePayload);
ArgumentNullException.ThrowIfNull(documentValues);
processResult = ValidateRecord(processResult, documentValues);
if (!processResult.Success)
{
return processResult;
}
var genericAttribute = new GenericDocumentAttribute
{
EntityName = documentValues.EntityName
};
var uploadRequest = await BuildUploadRequest(request, documentValues, genericAttribute);
await _documentTypeUploaderApiService.UploadGenericDocument(uploadRequest, request, processResult);
Log.Debug("Ending XdiActionNoticeDocument ProcessRequest.");
}
catch (Exception exception)
{
var message =
$"An Exception occured while XdiActionNoticeDocument ProcessRequest. Exception Message: {exception.Message}";
Log.Error(exception, message);
processResult = ProcessResult.ProcessCriticalFailure(processResult, message);
}
return processResult;
}
private static ProcessResult ValidateRecord(ProcessResult processResult, XdiActionNoticesDocument documentValues)
{
processResult = MetaDataValidation.ValidateFullName(processResult, documentValues.EntityName);
processResult = MetaDataValidation.ValidateDate(processResult, documentValues.CreationDate, DateFormat);
processResult = MetaDataValidation.ValidateDocumentType<GenericDocumentTypes>(processResult, documentValues.DocumentType);
return processResult;
}
public async Task<GenericDocumentRequest> BuildUploadRequest(ProcessingRequest request,
XdiActionNoticesDocument documentValues,
GenericDocumentAttribute genericDocumentAttribute)
{
var contentBytes = await _fileOperationsApiService.GetContentBytes(request.IngestorRequest.RootPath,
request.DocumentFileName);
var type = documentValues.DocumentType.GetValueFromName<GenericDocumentTypes>();
var genericDocumentRequest = new GenericDocumentRequest
{
Content = contentBytes,
GenericDocumentAttribute = genericDocumentAttribute,
GenericDocumentMetadata = new GenericDocumentMetadata
{
Source = Source,
DataSource = DataSource,
Name = documentValues.DocumentName,
Type = type,
CreatedDate = DateTime.Parse(documentValues.CreationDate),
TraceId = request.IngestorRunInfoId
}
};
return genericDocumentRequest;
}
}
@@ -0,0 +1,131 @@
using System.Globalization;
using Newtonsoft.Json;
using Serilog;
using LCU.Library.DocumentType.Enums;
using LCU.Library.DocumentType.Extensions;
using LCU.Library.DocumentType.Models.Requests.Account;
using LCU.Library.DocumentType.Models.Requests.Attributes;
using LCU.Library.Internal.DocumentIngestorModels.Models;
using LCU.Library.Internal.DocumentIngestorModels.Models.IndexFileDocuments;
using LCU.Library.Internal.DocumentIngestorModels.Validations;
using LCU.API.Internal.DocumentIngestor.Services.AttributeDeterminingServices;
using LCU.API.Internal.DocumentIngestor.Services.MicroApiServices;
using LCU.Library.Internal.LCUServiceFactory.Configurations;
namespace LCU.API.Internal.DocumentIngestor.Services.DocumentProcessorServices;
public class XdiDnaNoticeDocumentProcessingService : DocumentProcessingService, IDocumentProcessingService
{
private readonly IAccountOwnerDeterminingService _accountOwnerDeterminingService;
private readonly IFileOperationsApiService _fileOperationsApiService;
private readonly IDocumentTypeUploaderApiService _documentTypeUploaderApiService;
private const DataSourceTypes DataSource = DataSourceTypes.DNA;
private const SourceTypes Source = SourceTypes.XDI;
private const string DateFormat = "MM/dd/yyyy";
public XdiDnaNoticeDocumentProcessingService(IAccountOwnerDeterminingService accountOwnerDeterminingService,
IFileOperationsApiService fileOperationsApiService,
IDocumentTypeUploaderApiService documentTypeUploaderApiService,
ServicesFactoryConfiguration servicesFactoryConfiguration)
: base(servicesFactoryConfiguration)
{
_documentTypeUploaderApiService = documentTypeUploaderApiService;
_fileOperationsApiService = fileOperationsApiService;
_accountOwnerDeterminingService = accountOwnerDeterminingService;
}
public async Task<ProcessResult> ProcessRequest(ProcessingRequest request)
{
var processResult = new ProcessResult();
try
{
Log.Debug("Starting XdiDnaNoticeDocument ProcessRequest.");
ArgumentNullException.ThrowIfNull(request);
var documentValues = JsonConvert.DeserializeObject<XdiDnaNoticesDocument>(request.DocumentValuePayload);
ArgumentNullException.ThrowIfNull(documentValues);
processResult = ValidateRecord(processResult, documentValues);
if (!processResult.Success)
{
return processResult;
}
if (!DateTime.TryParseExact(documentValues.CreationDate,
DateFormat,
CultureInfo.InvariantCulture,
DateTimeStyles.AssumeLocal,
out var creationDate))
{
var message = $"A Creation Date of {documentValues.CreationDate} could not " +
$"be properly formatted from format: {DateFormat}";
return ProcessResult.ProcessDataMappingFailure(processResult,
message);
}
var accountOwnerAttribute = await _accountOwnerDeterminingService.DetermineAccountOwnerAttribute(documentValues.EntityName,
documentValues.AccountNumber,
creationDate,
request.OwnerOverrideInfo);
if (!accountOwnerAttribute.Success)
{
return ProcessResult.ProcessDataMappingFailure(processResult,
accountOwnerAttribute.Message);
}
var accountOwnerRequest = await BuildUploadRequest(request,
documentValues,
creationDate,
accountOwnerAttribute.Payload);
await _documentTypeUploaderApiService.UploadAccountDocument(accountOwnerRequest, request, processResult);
Log.Debug("Ending XdiDnaNoticeDocument ProcessRequest.");
}
catch (Exception exception)
{
var message =
$"An Exception occured while XdiDnaNoticeDocument ProcessRequest. Exception Message: {exception.Message}";
Log.Error(exception, message);
processResult = ProcessResult.ProcessCriticalFailure(processResult, message);
}
return processResult;
}
private static ProcessResult ValidateRecord(ProcessResult processResult, XdiDnaNoticesDocument documentValues)
{
processResult = MetaDataValidation.ValidateAccountNumber(processResult, documentValues.AccountNumber);
processResult = MetaDataValidation.ValidatePdf(processResult, documentValues.PDF);
processResult = MetaDataValidation.ValidateFullName(processResult, documentValues.EntityName);
processResult = MetaDataValidation.ValidateDate(processResult, documentValues.CreationDate, DateFormat);
processResult = MetaDataValidation.ValidateDocumentType<AccountDocumentTypes>(processResult, documentValues.DocumentType);
return processResult;
}
private async Task<AccountDocumentRequest> BuildUploadRequest(ProcessingRequest request,
XdiDnaNoticesDocument documentValues,
DateTime creationDate,
AccountAttribute accountAttribute)
{
var contentBytes = await _fileOperationsApiService.GetContentBytes(request.IngestorRequest.RootPath, request.DocumentFileName);
var type = documentValues.DocumentType.GetValueFromName<AccountDocumentTypes>();
ArgumentNullException.ThrowIfNull(type);
return new AccountDocumentRequest
{
Content = contentBytes,
AccountAttribute = accountAttribute,
AccountDocumentMetadata = new AccountDocumentMetadata
{
Source = Source,
DataSource = DataSource,
Name = documentValues.PDF,
Type = type,
CreatedDate = creationDate,
TraceId = request.IngestorRunInfoId
}
};
}
}
@@ -0,0 +1,132 @@
using LCU.Library.Internal.DocumentIngestorModels.Entities;
using LCU.Library.Internal.DocumentIngestorModels.Enums;
using LCU.Library.Internal.DocumentIngestorModels.Models;
using LCU.Library.Internal.Exceptions;
using LCU.API.Internal.DocumentIngestor.Configurations;
using LCU.API.Internal.DocumentIngestor.Services.QueueServices;
using Newtonsoft.Json;
using Serilog;
namespace LCU.API.Internal.DocumentIngestor.Services;
public class DocumentReprocessingService : IDocumentReprocessingService
{
private readonly IIngestorRunInfoService _ingestorRunInfoService;
private readonly IDocumentProcessingInfoService _documentProcessingInfoService;
private readonly IOwnerOverrideInfoService _ownerOverrideInfoService;
private readonly IQueueDocumentProcessingService _queueDocumentProcessing;
private readonly ApiConfiguration _apiConfiguration;
public DocumentReprocessingService(IIngestorRunInfoService ingestorRunInfoService,
IDocumentProcessingInfoService documentProcessingInfoService,
IOwnerOverrideInfoService ownerOverrideInfoService,
IQueueDocumentProcessingService queueDocumentProcessing,
ApiConfiguration apiConfiguration)
{
_ingestorRunInfoService = ingestorRunInfoService;
_documentProcessingInfoService = documentProcessingInfoService;
_ownerOverrideInfoService = ownerOverrideInfoService;
_queueDocumentProcessing = queueDocumentProcessing;
_apiConfiguration = apiConfiguration;
}
public async Task QueueReprocessDocumentByDocumentProcessingInfoId(int documentProcessingInfoId, string userName)
{
try
{
var ownerOverrideInfos = await _ownerOverrideInfoService.GetByDocumentProcessingInfoIdAsync(documentProcessingInfoId);
var logMessage = $"Reprocess run of DocumentProcessingInfoId: {documentProcessingInfoId} by {userName} on {DateTime.Now}";
await QueueProcessingRequest(documentProcessingInfoId, ownerOverrideInfos?.FirstOrDefault(), logMessage, userName);
}
catch (ArgumentNullException exception)
{
Log.Error(exception, $"Failure to reprocess, DocumentProcessingInfo could not be found. " +
$"DocumentProcessingInfoId: {documentProcessingInfoId}");
throw;
}
catch (Exception exception)
{
Log.Error(exception, $"Failure reprocessing DocumentProcessingInfo. DocumentProcessingInfoId: {documentProcessingInfoId}");
throw new ServiceException($"Failure reprocessing DocumentProcessingInfo. DocumentProcessingInfoId: {documentProcessingInfoId}");
}
}
public async Task QueueOverrideDocumentByDocumentProcessingInfoId(OwnerOverrideInfo ownerOverrideInfo)
{
try
{
ownerOverrideInfo = await _ownerOverrideInfoService.SaveAsync(ownerOverrideInfo);
var logMessage = $"Override triggered by {ownerOverrideInfo.UserName} at {DateTime.Now} with values: {JsonConvert.SerializeObject(ownerOverrideInfo)}";
await QueueProcessingRequest(ownerOverrideInfo.DocumentProcessingInfoId, ownerOverrideInfo, logMessage, ownerOverrideInfo.UserName);
}
catch (ArgumentNullException exception)
{
Log.Error(exception, $"Failure to override, DocumentProcessingInfo could not be found. " +
$"DocumentProcessingInfoId: {ownerOverrideInfo.DocumentProcessingInfoId}");
throw;
}
catch (Exception exception)
{
Log.Error(exception, $"Failure overriding DocumentProcessingInfo. " +
$"DocumentProcessingInfoId: {ownerOverrideInfo.DocumentProcessingInfoId} | " +
$"EntityType: {Enum.GetName(typeof(EntityTypes), ownerOverrideInfo.EntityType)} | " +
$"EntityId: {ownerOverrideInfo.EntityId}");
throw new ServiceException($"Failure overriding DocumentProcessingInfo. DocumentProcessingInfoId: {ownerOverrideInfo.DocumentProcessingInfoId}");
}
}
public async Task QueueReprocessAllCriticalFailures(string userName)
{
try
{
var result = await _documentProcessingInfoService.GetByProcessStatusTypeAsync(ProcessStatusTypes.CriticalFailure);
var documentProcessingInfos = result.Take(_apiConfiguration.CriticalFailureReprocessLimit);
foreach (var documentProcessingInfo in documentProcessingInfos)
{
await QueueReprocessDocumentByDocumentProcessingInfoId(documentProcessingInfo.DocumentProcessingInfoId, userName);
}
}
catch (ArgumentNullException exception)
{
var message = "Failure during reprocess of DocumentProcessingInfos of ProcessStatusType: CriticalFailure."
+ $" ExceptionMessage: {exception.Message}";
Log.Error(exception, message);
throw new ServiceException(message);
}
catch (Exception exception)
{
Log.Error(exception, "Failure to reprocess all DocumentProcessingInfos with ProcessStatusType: CriticalFailure.");
throw new ServiceException("Failure to reprocess all DocumentProcessingInfos with ProcessStatusType: CriticalFailure.");
}
}
private async Task QueueProcessingRequest(int documentProcessingInfoId, OwnerOverrideInfo? ownerOverrideInfo, string logMessage, string userName)
{
var documentProcessingInfo = await _documentProcessingInfoService.GetByIdAsync(documentProcessingInfoId);
ArgumentNullException.ThrowIfNull(documentProcessingInfo);
var ingestorRunInfo = await _ingestorRunInfoService.GetByIdAsync(documentProcessingInfo.IngestorRunInfoId);
ArgumentNullException.ThrowIfNull(ingestorRunInfo);
var processingRequest = new ProcessingRequest()
{
DocumentProcessingInfoId = documentProcessingInfoId,
IngestorRunInfoId = documentProcessingInfo.IngestorRunInfoId,
DocumentFileName = documentProcessingInfo.DocumentFileName,
DocumentValuePayload = documentProcessingInfo.DocumentValuePayload,
IngestorRequest = new IngestorRequest()
{
IngestorType = ingestorRunInfo.IngestorType,
RootPath = ingestorRunInfo.IndexFilePath,
IndexFileName = ingestorRunInfo.IndexFileName
},
OwnerOverrideInfo = ownerOverrideInfo
};
await _documentProcessingInfoService.UpdateStatusAndAddLog(documentProcessingInfoId, ProcessStatusTypes.Reprocessing, logMessage, userName);
await _queueDocumentProcessing.QueueDocumentProcessingRequest(processingRequest);
}
}
@@ -0,0 +1,134 @@
using System.Data.SqlClient;
using Serilog;
using LCU.Library.Internal.DocumentIngestorModels.Entities;
using LCU.Library.Internal.Exceptions;
using LCU.API.Internal.DocumentIngestorLib.Repositories;
namespace LCU.API.Internal.DocumentIngestor.Services;
public class DocumentTypeArchiveDeleteInfoService : IDocumentTypeArchiveDeleteInfoService
{
private readonly IDocumentTypeArchiveDeleteInfoRepository _documentTypeArchiveDeleteInfoRepository;
private readonly IUnitOfWork _unitOfWork;
public DocumentTypeArchiveDeleteInfoService(IUnitOfWork unitOfWork,
IDocumentTypeArchiveDeleteInfoRepository documentTypeArchiveDeleteInfoRepository)
{
_documentTypeArchiveDeleteInfoRepository = documentTypeArchiveDeleteInfoRepository;
_unitOfWork = unitOfWork;
}
public async Task<IEnumerable<DocumentTypeArchiveDeleteInfo>> GetAsync()
{
try
{
var documentProcessingInfos = await _documentTypeArchiveDeleteInfoRepository.FindAsync();
return documentProcessingInfos;
}
catch (Exception exception)
{
Log.Error(exception, $"Failure retrieving DocumentTypeArchiveDeleteInfos.");
throw new ServiceException($"Failure retrieving DocumentTypeArchiveDeleteInfos.");
}
}
public async Task<DocumentTypeArchiveDeleteInfo> GetByDocumentTypeNameAsync<TEnum>(TEnum documentType) where TEnum : Enum
{
try
{
var typesName = Enum.GetName(typeof(TEnum), documentType);
ArgumentNullException.ThrowIfNull(typesName);
var processingLogs = await _documentTypeArchiveDeleteInfoRepository.FindByDocumentTypeNameAsync(typesName);
return processingLogs;
}
catch (Exception exception)
{
Log.Error(exception, $"Failure retrieving DocumentTypeArchiveDeleteInfo with DocumentType {documentType}.");
throw new ServiceException($"Failure retrieving DocumentTypeArchiveDeleteInfo with DocumentType {documentType}.");
}
}
public async Task<DocumentTypeArchiveDeleteInfo> GetByDocumentTypeNameAsync(string documentTypeName)
{
try
{
var processingLogs = await _documentTypeArchiveDeleteInfoRepository.FindByDocumentTypeNameAsync(documentTypeName);
return processingLogs;
}
catch (Exception exception)
{
Log.Error(exception, $"Failure retrieving DocumentTypeArchiveDeleteInfo with DocumentTypeName {documentTypeName}.");
throw new ServiceException($"Failure retrieving DocumentTypeArchiveDeleteInfo with DocumentType {documentTypeName}.");
}
}
public async Task<DocumentTypeArchiveDeleteInfo> SaveAsync(DocumentTypeArchiveDeleteInfo documentTypeArchiveDeleteInfo)
{
try
{
var result = await _documentTypeArchiveDeleteInfoRepository.AddAsync(documentTypeArchiveDeleteInfo);
await _unitOfWork.CompleteAsync();
return result;
}
catch (Exception exception)
{
Log.Error(exception, $"Failure saving DocumentTypeArchiveDeleteInfo.");
throw new ServiceException($"Failure saving DocumentTypeArchiveDeleteInfo. Exception Message: {exception.Message}");
}
}
public async Task<DocumentTypeArchiveDeleteInfo?> Update(DocumentTypeArchiveDeleteInfo documentTypeArchiveDeleteInfo)
{
try
{
var existing = await GetByDocumentTypeNameAsync(documentTypeArchiveDeleteInfo.DocumentTypeName);
if(existing == null)
{
return existing;
}
existing.ArchiveDays = documentTypeArchiveDeleteInfo.ArchiveDays;
existing.ArchiveMonths = documentTypeArchiveDeleteInfo.ArchiveMonths;
existing.DeleteDays = documentTypeArchiveDeleteInfo.DeleteDays;
_documentTypeArchiveDeleteInfoRepository.Update(existing);
_unitOfWork.Complete();
return existing;
}
catch (SqlException sqlException)
{
Log.Error(sqlException, $"SQL Failure updating DocumentTypeArchiveDeleteInfo. " +
$"DocumentTypeName: {documentTypeArchiveDeleteInfo.DocumentTypeName}");
throw new ServiceException($"SQL Failure updating DocumentTypeArchiveDeleteInfo. " +
$"DocumentTypeName: {documentTypeArchiveDeleteInfo.DocumentTypeName}");
}
catch (Exception exception)
{
Log.Error(exception, $"Failure updating DocumentTypeArchiveDeleteInfo. " +
$"DocumentTypeName: {documentTypeArchiveDeleteInfo.DocumentTypeName}");
throw new ServiceException($"Failure updating DocumentTypeArchiveDeleteInfo. " +
$"DocumentTypeName: {documentTypeArchiveDeleteInfo.DocumentTypeName}");
}
}
public async Task Delete(string documentTypeName)
{
try
{
var documentTypeArchiveDeleteInfo = await GetByDocumentTypeNameAsync(documentTypeName);
ArgumentNullException.ThrowIfNull(documentTypeArchiveDeleteInfo);
_documentTypeArchiveDeleteInfoRepository.Remove(documentTypeArchiveDeleteInfo);
_unitOfWork.Complete();
}
catch (SqlException sqlException)
{
Log.Error(sqlException, $"SQL failure removing DocumentTypeArchiveDeleteInfo. DocumentTypeName: {documentTypeName}");
throw new ServiceException($"SQL failure removing DocumentTypeArchiveDeleteInfo. DocumentTypeName: {documentTypeName}");
}
catch (Exception exception)
{
Log.Error(exception, $"Failure removing DocumentTypeArchiveDeleteInfo. DocumentTypeName: {documentTypeName}");
throw new ServiceException($"Failure removing DocumentTypeArchiveDeleteInfo. DocumentTypeName: {documentTypeName}");
}
}
}
@@ -0,0 +1,69 @@
using LCU.Library.Internal.DocumentIngestorModels.Entities;
using LCU.Library.Internal.DocumentIngestorModels.Enums;
using LCU.Library.Internal.DocumentIngestorModels.Models;
using LCU.Library.Internal.DocumentIngestorModels.Models.Pagination;
namespace LCU.API.Internal.DocumentIngestor.Services;
public interface IDocumentProcessingInfoService
{
Task<IEnumerable<DocumentProcessingInfo>> GetAsync();
Task<DocumentProcessingInfo> GetByIdAsync(int id);
Task<IEnumerable<DocumentProcessingInfo>> GetListByIdAsync(List<int> ids);
Task<IEnumerable<DocumentProcessingInfo>> GetByIngestorRunInfoIdAsync(Guid ingestorRunInfoId);
Task<IEnumerable<DocumentProcessingInfo>> GetByProcessStatusTypeAsync(ProcessStatusTypes statusType, bool? isUnknown = null);
Task<IEnumerable<DocumentProcessingInfo>> GetByProcessStatusTypeListAsync(List<ProcessStatusTypes> statusTypes, bool? isUnknown = null);
Task<IEnumerable<DocumentProcessingInfo>> GetCompletedFirstPassByIngestorRunInfoIdAsync(Guid ingestorRunInfoId);
Task<DocumentProcessingInfo> SaveAsync(DocumentProcessingInfo documentProcessingInfo);
Task SaveRangeAsync(DocumentProcessingInfo[] documentProcessingInfos);
Task<DocumentProcessingInfo?> UpdateStatusAndAddLog(int documentProcessingInfoId,
ProcessStatusTypes statusType,
string logMessage,
string userName,
bool? entityIsUnknown = null);
Task<DocumentProcessingInfo?> UpdateStatusAndAddLog(int documentProcessingInfoId,
ProcessStatusTypes statusType,
List<string> logMessages,
string userName,
bool? entityIsUnknown = null);
Task<DocumentProcessingInfo?> UpdateStatusAndAddLog(DocumentProcessingInfo documentProcessingInfo,
ProcessStatusTypes statusType,
string logMessage,
string userName,
bool? entityIsUnknown = null);
Task<DocumentProcessingInfo?> UpdateStatusAndAddLog(DocumentProcessingInfo documentProcessingInfo,
ProcessStatusTypes statusType,
List<string> logMessages,
string userName,
bool? entityIsUnknown = null);
Task<List<CompletionProcessingData>> UpdateProcessCountAndStatusAndAddLog(List<CompletionRequest> requests);
Task<DocumentProcessingInfo?> UpdateProcessCountAndStatusAndAddLog(int documentProcessingInfoId,
ProcessStatusTypes statusType,
string logMessage,
string userName,
bool? entityIsUnknown = null);
Task<DocumentProcessingInfo?> UpdateProcessCountAndStatusAndAddLog(int documentProcessingInfoId,
ProcessStatusTypes statusType,
List<string> logMessages,
string userName,
bool? entityIsUnknown = null);
Task<DocumentProcessingInfo?> UpdateProcessCountAndStatusAndAddLog(DocumentProcessingInfo documentProcessingInfo,
ProcessStatusTypes statusType,
string logMessage,
string userName,
bool? entityIsUnknown = null);
Task<DocumentProcessingInfo?> UpdateProcessCountAndStatusAndAddLog(DocumentProcessingInfo documentProcessingInfo,
ProcessStatusTypes statusType,
List<string> logMessages,
string userName,
bool? entityIsUnknown = null);
Task<DocumentProcessingInfo?> Update(DocumentProcessingInfo documentProcessingInfo);
Task<IEnumerable<DocumentProcessingInfo>> UpdateRangeAsync(IEnumerable<DocumentProcessingInfo> documentProcessingInfos);
Task Delete(int id);
Task<PagedResult<DocumentProcessingInfo>> GetFilteredDocumentProcessingInfo(Filter filter);
Task<int> CountCompletedFirstPassByIngestorRunInfoIdAsync(Guid ingestorRunInfoId);
Task<int> CountCompletedByIngestorRunInfoIdAsync(Guid ingestorRunInfoId);
Task<IEnumerable<DocumentProcessingInfo>?> SetDocumentsToEntityUnknown(EntityUnknownRequest request);
Task<DocumentProcessingInfo?> UpdateDocumentProcessingInfoStatus(DocumentProcessingInfoStatusRequest request);
Task<IDictionary<Guid, DocumentProcessingInfo?>> GetByDocumentIdsAsync(Guid[] ids);
}
@@ -0,0 +1,10 @@
using LCU.Library.Internal.DocumentIngestorModels.Entities;
namespace LCU.API.Internal.DocumentIngestor.Services;
public interface IDocumentReprocessingService
{
Task QueueReprocessDocumentByDocumentProcessingInfoId(int documentProcessingInfoId, string userName);
Task QueueOverrideDocumentByDocumentProcessingInfoId(OwnerOverrideInfo ownerOverrideRequest);
Task QueueReprocessAllCriticalFailures(string userName);
}
@@ -0,0 +1,12 @@
using LCU.Library.Internal.DocumentIngestorModels.Entities;
namespace LCU.API.Internal.DocumentIngestor.Services;
public interface IDocumentTypeArchiveDeleteInfoService
{
Task<IEnumerable<DocumentTypeArchiveDeleteInfo>> GetAsync();
Task<DocumentTypeArchiveDeleteInfo> GetByDocumentTypeNameAsync<TEnum>(TEnum documentType) where TEnum : Enum;
Task<DocumentTypeArchiveDeleteInfo> GetByDocumentTypeNameAsync(string documentType);
Task<DocumentTypeArchiveDeleteInfo> SaveAsync(DocumentTypeArchiveDeleteInfo documentTypeArchiveDeleteInfo);
Task<DocumentTypeArchiveDeleteInfo?> Update(DocumentTypeArchiveDeleteInfo documentTypeArchiveDeleteInfo);
Task Delete(string documentTypeName);
}
@@ -0,0 +1,12 @@
using LCU.Library.Internal.DocumentIngestorModels.Entities;
namespace LCU.API.Internal.DocumentIngestor.Services;
public interface IIngestorRunInfoService
{
Task<IngestorRunInfo?> GetByIdAsync(Guid id);
Task<IEnumerable<IngestorRunInfo>> GetListByIdAsync(List<Guid> ingestorRunInfoIds);
Task<IngestorRunInfo> SaveAsync(IngestorRunInfo ingestorRunInfo);
Task<IngestorRunInfo> Update(IngestorRunInfo ingestorRunInfo);
Task Delete(Guid ingestorRunInfoId);
IEnumerable<IngestorRunInfo> FindByIngestionEndDateNotArchived(DateTime ingestionEndDate);
}
@@ -0,0 +1,22 @@
using LCU.Library.Internal.DocumentIngestorModels.Entities;
using LCU.Library.Internal.DocumentIngestorModels.Enums;
using LCU.Library.Internal.DocumentIngestorModels.Models;
namespace LCU.API.Internal.DocumentIngestor.Services;
public interface IMemberNotificationInfoService
{
Task<IEnumerable<MemberNotificationInfo>> GetAsync();
Task<MemberNotificationInfo> GetByIdAsync(int id);
Task<IEnumerable<MemberNotificationInfo>> GetListByIdAsync(List<int> ids);
Task<IEnumerable<MemberNotificationInfo>> GetByDocumentProcessingInfoIdAsync(int documentProcessingInfoId);
Task<IEnumerable<MemberNotificationInfo>> GetByNotificationStatusAsync(NotificationStatusTypes status);
Task<IEnumerable<MemberNotificationInfo>> GetSendableMemberNotificationInfosAsync(DateTime minimumUploadDate, int maxAttempts);
Task<MemberNotificationInfo> SaveAsync(MemberNotificationInfo memberNotificationInfo);
Task SaveListAsync(List<MemberNotificationInfo> memberNotificationInfos);
Task<MemberNotificationInfo?> Update(MemberNotificationInfo memberNotificationInfo);
Task<IEnumerable<MemberNotificationInfo?>> UpdateRange(IEnumerable<MemberNotificationInfo> memberNotificationInfos);
Task Delete(int id);
Task<bool> SetDocumentNotificationStatus(int memberNotificationInfoId, NotificationStatusTypes notificationStatus, string userName, string reason);
Task<bool> BulkSetDocumentNotificationStatus(BulkNotificationStatusRequest request, string userName);
}
@@ -0,0 +1,17 @@
using LCU.Library.Internal.DocumentIngestorModels.Entities;
namespace LCU.API.Internal.DocumentIngestor.Services;
public interface IOsgPreprocessorInfoService
{
Task<IEnumerable<OsgPreprocessorInfo>> GetAsync();
Task<OsgPreprocessorInfo> GetByIdAsync(int id);
Task<IEnumerable<OsgPreprocessorInfo>> GetListByIdAsync(List<int> ids);
Task<IEnumerable<OsgPreprocessorInfo>> GetByDocumentTypeAsync(string documentType);
Task<IEnumerable<OsgPreprocessorInfo>> GetByMemberNumberAsync(string memberNumber);
Task<OsgPreprocessorInfo> SaveAsync(OsgPreprocessorInfo osgPreprocessorInfo);
Task SaveListAsync(List<OsgPreprocessorInfo> osgPreprocessorInfos);
Task<OsgPreprocessorInfo?> Update(OsgPreprocessorInfo osgPreprocessorInfo);
Task<IEnumerable<OsgPreprocessorInfo?>> UpdateRange(IEnumerable<OsgPreprocessorInfo> osgPreprocessorInfos);
Task Delete(int id);
}
@@ -0,0 +1,12 @@
using LCU.Library.Internal.DocumentIngestorModels.Entities;
namespace LCU.API.Internal.DocumentIngestor.Services;
public interface IOwnerOverrideInfoService
{
Task<IEnumerable<OwnerOverrideInfo>?> GetAsync();
Task<OwnerOverrideInfo?> GetByIdAsync(int id);
Task<IEnumerable<OwnerOverrideInfo>?> GetByDocumentProcessingInfoIdAsync(int documentProcessingInfoId);
Task<OwnerOverrideInfo> SaveAsync(OwnerOverrideInfo ownerOverrideInfo);
Task Delete(int id);
}

Some files were not shown because too many files have changed in this diff Show More