This commit is contained in:
Zeeshaun
2026-03-13 09:11:35 -05:00
parent f004c8205a
commit c2d6bda458
197 changed files with 14970 additions and 0 deletions
@@ -0,0 +1,7 @@
namespace LCU.API.Internal.DocumentLib.Configurations;
public class BlobStorageConfiguration
{
public string ConnectionString { get; set; }
public string ContainerName { get; set; }
}
@@ -0,0 +1,11 @@
namespace LCU.API.Internal.DocumentLib.Configurations;
public class DatabaseConfiguration
{
public string ConnectionString { get; set; }
public string DatabaseName { get; set; }
public string DocumentContainerName { get; set; }
public string AuditContainerName { get; set; }
}
@@ -0,0 +1,17 @@
using System.ComponentModel.DataAnnotations.Schema;
namespace LCU.API.Internal.DocumentLib.Configurations;
public class NotificationApiConfiguration
{
public string Url { get; set; }
public string Email { get; set; }
[NotMapped]
public string EmailUrl
{
get
{
return Url + Email;
}
}
}
@@ -0,0 +1,55 @@
using System;
using LCU.Library.Internal.DocumentModels.Requests;
using MongoDB.Bson.Serialization.Attributes;
namespace LCU.API.Internal.DocumentLib.Containers;
[BsonKnownTypes(typeof(DocumentFieldAudit), typeof(DocumentActionAudit))]
public abstract class DocumentAudit
{
protected DocumentAudit(Guid documentId, string source, DateTime date, string userId)
{
DocumentId = documentId;
Source = source;
Date = date;
UserId = userId;
}
public Guid DocumentId { get; set; }
public string Source { get; set; }
[BsonDateTimeOptions(Kind = DateTimeKind.Utc)]
public DateTime Date { get; set; }
public string UserId { get; set; }
}
[BsonIgnoreExtraElements]
public class DocumentFieldAudit : DocumentAudit
{
public DocumentFieldAudit(Guid documentId, string source, DateTime date, string userId, string field, object previousValue, object currentValue)
: base(documentId, source, date, userId)
{
Field = field;
PreviousValue = previousValue;
CurrentValue = currentValue;
}
public string Field { get; set; }
public object PreviousValue { get; set; }
public object CurrentValue { get; set; }
}
[BsonIgnoreExtraElements]
public class DocumentActionAudit : DocumentAudit
{
public DocumentActionAudit(Guid documentId, string source, DateTime date, string userId, DocumentAction action, string description)
: base(documentId, source, date, userId)
{
Action = action;
ActionDescription = description;
}
public DocumentAction Action { get; set; }
public string ActionDescription { get; set; }
}
@@ -0,0 +1,40 @@
using System;
using MongoDB.Bson;
using MongoDB.Bson.IO;
using MongoDB.Bson.Serialization.Conventions;
namespace LCU.API.Internal.DocumentLib.Containers;
public class DocumentAuditDiscriminatorConvention : IDiscriminatorConvention
{
public static string Discriminator = StandardDiscriminatorConvention.Scalar.ElementName;
public string ElementName => Discriminator;
public Type GetActualType(IBsonReader bsonReader, Type nominalType)
{
var bookmark = bsonReader.GetBookmark();
try
{
bsonReader.ReadStartDocument();
if (!bsonReader.FindElement(ElementName)) return typeof(DocumentFieldAudit);
return bsonReader.ReadString() switch
{
nameof(DocumentFieldAudit) => typeof(DocumentFieldAudit),
nameof(DocumentActionAudit) => typeof(DocumentActionAudit),
_ => throw new NotSupportedException()
};
}
finally
{
bsonReader.ReturnToBookmark(bookmark);
}
}
public BsonValue GetDiscriminator(Type nominalType, Type actualType)
{
return actualType.Name;
}
}
@@ -0,0 +1,54 @@
using System;
using System.Collections.Generic;
using System.Numerics;
using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Attributes;
using MongoDB.Bson.Serialization.Serializers;
namespace LCU.API.Internal.DocumentLib.Containers;
[BsonIgnoreExtraElements]
public class DocumentInformation
{
public Guid DocumentId { get; set; }
public Guid? DocumentBlobId { get; set; }
public Guid? TraceId { get; set; }
public string Name { get; set; }
public string Type { get; set; }
public string Source { get; set; }
public string DataSource { get; set; }
[BsonSerializer(typeof(BigIntSerializer))]
public BigInteger FileSize { get; set; }
public bool? ScanStatus { get; set; }
[BsonDateTimeOptions(Kind = DateTimeKind.Utc)]
public DateTime UploadDate { get; set; }
[BsonDateTimeOptions(Kind = DateTimeKind.Utc)]
public DateTime? LastModifiedDate { get; set; }
[BsonDateTimeOptions(Kind = DateTimeKind.Utc)]
public DateTime CreatedDate { get; set; }
public string[] PersonNumbers { get; set; }
public string[] OrganizationNumbers { get; set; }
public string AccountNumber { get; set; }
public Dictionary<string, string> Attributes { get; set; }
}
public class BigIntSerializer : SerializerBase<BigInteger>
{
public override BigInteger Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
{
var val = context.Reader.ReadString();
return BigInteger.Parse(val);
}
public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, BigInteger value)
{
context.Writer.WriteString(value.ToString());
}
}
@@ -0,0 +1,44 @@
using System;
using System.IO;
using System.Threading.Tasks;
using Azure;
using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models;
namespace LCU.API.Internal.DocumentLib.DataAccess;
public class BlobApiDao : IBlobApiDao
{
private readonly BlobContainerClient _client;
public BlobApiDao(IBlobStorageClient storageClient)
{
_client = storageClient.GetClient();
}
public async Task<Guid> SaveDocumentToBlob(byte[] fileData)
{
var blobDocumentId = Guid.NewGuid();
using var stream = new MemoryStream(fileData, false);
await _client.GetBlobClient(blobDocumentId.ToString()).UploadAsync(stream);
return blobDocumentId;
}
public async Task UpdateDocumentInBlob(Guid blobDocumentId, byte[] fileData)
{
using var stream = new MemoryStream(fileData, false);
await _client.GetBlobClient(blobDocumentId.ToString()).UploadAsync(stream, true);
}
public async Task<Response> RemoveDocumentFromBlob(Guid blobDocumentId)
{
return await _client.GetBlobClient(blobDocumentId.ToString())
.DeleteAsync(DeleteSnapshotsOption.IncludeSnapshots);
}
public async Task<Response<BlobDownloadStreamingResult>> GetDocumentFromBlob(Guid blobDocumentId)
{
return await _client.GetBlobClient(blobDocumentId.ToString()).DownloadStreamingAsync();
}
}
@@ -0,0 +1,20 @@
using Azure.Storage.Blobs;
using LCU.API.Internal.DocumentLib.Configurations;
namespace LCU.API.Internal.DocumentLib.DataAccess;
public class BlobStorageClient : IBlobStorageClient
{
private readonly BlobContainerClient _containerClient;
public BlobStorageClient(BlobStorageConfiguration config)
{
var serviceClient = new BlobServiceClient(config.ConnectionString);
_containerClient = serviceClient.GetBlobContainerClient(config.ContainerName);
}
public BlobContainerClient GetClient()
{
return _containerClient;
}
}
@@ -0,0 +1,14 @@
using System;
using System.Threading.Tasks;
using Azure;
using Azure.Storage.Blobs.Models;
namespace LCU.API.Internal.DocumentLib.DataAccess;
public interface IBlobApiDao
{
Task<Guid> SaveDocumentToBlob(byte[] fileData);
Task UpdateDocumentInBlob(Guid blobDocumentId, byte[] fileData);
Task<Response> RemoveDocumentFromBlob(Guid blobDocumentId);
Task<Response<BlobDownloadStreamingResult>> GetDocumentFromBlob(Guid blobDocumentId);
}
@@ -0,0 +1,8 @@
using Azure.Storage.Blobs;
namespace LCU.API.Internal.DocumentLib.DataAccess;
public interface IBlobStorageClient
{
BlobContainerClient GetClient();
}
@@ -0,0 +1,10 @@
using LCU.API.Internal.NotificationsApiLib.Models;
using System.Threading.Tasks;
namespace LCU.API.Internal.DocumentLib.DataAccess
{
public interface INotificationApiDao
{
Task SendEmailAsync(EmailRequest emailRequest);
}
}
@@ -0,0 +1,23 @@
using LCU.API.Internal.DocumentLib.Configurations;
using LCU.API.Internal.DocumentLib.Utilities;
using LCU.API.Internal.NotificationsApiLib.Models;
using System.Threading.Tasks;
using System;
namespace LCU.API.Internal.DocumentLib.DataAccess
{
public class NotificationApiDao : INotificationApiDao
{
private readonly NotificationApiConfiguration _notificationApiConfiguration;
public NotificationApiDao(NotificationApiConfiguration notificationApiConfiguration)
{
_notificationApiConfiguration = notificationApiConfiguration;
}
public async Task SendEmailAsync(EmailRequest emailRequest)
{
await HttpUtilities.PostAsync<EmailRequest>(new Uri(_notificationApiConfiguration.EmailUrl),
emailRequest);
}
}
}
@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>latest</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Azure.Storage.Blobs" Version="12.13.0" />
<PackageReference Include="LCU.API.Internal.NotificationsApiLib" Version="2.1.0" />
<PackageReference Include="LCU.Library.Internal.Exceptions" Version="1.0.0" />
<PackageReference Include="Microsoft.Azure.Cosmos" Version="3.30.1" />
<PackageReference Include="MongoDB.Driver" Version="2.20.0" />
<PackageReference Include="Serilog" Version="2.11.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LCU.Library.Internal.DocumentModels\LCU.Library.Internal.DocumentModels.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,19 @@
using LCU.API.Internal.DocumentLib.Configurations;
using MongoDB.Driver;
namespace LCU.API.Internal.DocumentLib.Repositories;
public class DataClient : IDataClient
{
private readonly MongoClient _client;
public DataClient(DatabaseConfiguration config)
{
_client = new MongoClient(config.ConnectionString);
}
public MongoClient GetClient()
{
return _client;
}
}
@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using LCU.API.Internal.DocumentLib.Containers;
using LCU.API.Internal.DocumentLib.Utilities;
using MongoDB.Driver;
namespace LCU.API.Internal.DocumentLib.Repositories;
public class DocumentAuditRepository : IDocumentAuditRepository
{
private readonly IMongoCollection<DocumentAudit> _documentAudits;
public DocumentAuditRepository(IMongoCollectionFactory collectionFactory)
{
_documentAudits = collectionFactory.GetCollection<DocumentAudit>();
}
public async Task<List<DocumentAudit>> GetDocumentAudits(params Guid[] documentIds)
{
return await (await _documentAudits.FindAsync(doc => documentIds.Contains(doc.DocumentId))).ToListAsync();
}
public async Task<IEnumerable<DocumentAudit>> SaveDocumentAudits(params DocumentAudit[] documentAudit)
{
await _documentAudits.InsertManyAsync(documentAudit);
return documentAudit;
}
}
@@ -0,0 +1,269 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using LCU.API.Internal.DocumentLib.Containers;
using LCU.API.Internal.DocumentLib.Utilities;
using LCU.Library.Internal.DocumentIngestorModels.Models.Pagination;
using LCU.Library.Internal.DocumentModels.Requests.Search;
using Microsoft.Azure.Cosmos.Linq;
using MongoDB.Bson;
using MongoDB.Driver;
namespace LCU.API.Internal.DocumentLib.Repositories;
public class DocumentInformationRepository : IDocumentInformationRepository
{
private readonly IMongoCollection<DocumentInformation> _documents;
public DocumentInformationRepository(IMongoCollectionFactory collectionFactory)
{
_documents = collectionFactory.GetCollection<DocumentInformation>();
}
public async Task<DocumentInformation> GetDocumentInformation(Guid documentId)
{
return await _documents.Find(doc => doc.DocumentId == documentId)
.SingleOrDefaultAsync();
}
public async Task<List<DocumentInformation>> SearchDocumentInformation(DocumentInformationFilter filter, int? skip = null, int? take = null, List<SortableField>? sortDefinition = null)
{
var pipelineFilter = FilterFactory(filter);
var sorter = Sorter<DocumentInformation>.GetSorter(sortDefinition);
if (sorter != null) pipelineFilter = pipelineFilter.Sort(sorter);
if (skip.HasValue) pipelineFilter = pipelineFilter.Skip(skip.Value);
if (take.HasValue) pipelineFilter = pipelineFilter.Limit(take.Value);
var documentsInformation = await _documents.AggregateAsync(pipelineFilter);
return await documentsInformation.ToListAsync();
}
public async Task<long> CountDocuments(DocumentInformationFilter filter)
{
return (await _documents.AggregateAsync(FilterFactory(filter).Count())).Single().Count;
}
public async Task<DocumentInformation> GetDocumentInformationByBlobId(Guid documentBlobId)
{
return await _documents
.Find(doc => doc.DocumentBlobId == documentBlobId)
.SingleOrDefaultAsync();
}
public async Task<DocumentInformation> SaveDocumentInformation(DocumentInformation document)
{
await _documents.InsertOneAsync(document);
return document;
}
public async Task<DocumentInformation> UpdateDocumentInformation(Guid documentId, DocumentInformation newDocument)
{
await _documents.FindOneAndReplaceAsync(doc => doc.DocumentId == documentId, newDocument);
return newDocument;
}
public async Task<DocumentInformation> RemoveDocumentInformation(Guid documentId)
{
return await _documents.FindOneAndDeleteAsync(document => document.DocumentId == documentId);
}
public async Task<List<Guid>> GetDocumentsForCleanup(GetDocumentCleanupRequest request)
{
IList<FilterDefinition<DocumentInformation>> filterConcat = new List<FilterDefinition<DocumentInformation>>();
foreach(var documentCodeDetail in request.DocumentCodeDetailInfos)
{
var adjustedDate = DateTime.Now.AddMonths(documentCodeDetail.InternalRetentionMonths * -1);
var typeFilter = Builders<DocumentInformation>.Filter.Eq(x => x.Type, documentCodeDetail.DocumentCode);
var dateFilter = Builders<DocumentInformation>.Filter.Lt(x => x.CreatedDate, adjustedDate);
var groupFilter = Builders<DocumentInformation>.Filter.And(typeFilter, dateFilter);
filterConcat.Add(groupFilter);
}
var filter = Builders<DocumentInformation>.Filter;
var oneConcat = filter.Empty;
oneConcat &= filter.Or(filterConcat);
var nullFilter = Builders<DocumentInformation>.Filter.Ne(x => x.DocumentBlobId, null);
oneConcat &= filter.And(nullFilter);
var pipelineFilter = new EmptyPipelineDefinition<DocumentInformation>()
.Match(oneConcat)
.Limit(request.Limit);
var documentsInformation = await _documents.AggregateAsync(pipelineFilter);
return (await documentsInformation.ToListAsync()).Select(document => document.DocumentId).ToList();
}
private PipelineDefinition<DocumentInformation, DocumentInformation> FilterFactory(DocumentInformationFilter filter)
{
var builder = Builders<DocumentInformation>.Filter;
IList<FilterDefinition<DocumentInformation>> stageOneFiltersAnd = new List<FilterDefinition<DocumentInformation>>();
IList<FilterDefinition<DocumentInformation>> stageOneFiltersOr = new List<FilterDefinition<DocumentInformation>>();
IList<FilterDefinition<DocumentInformation>> stageTwoFiltersAnd = new List<FilterDefinition<DocumentInformation>>();
IList<FilterDefinition<DocumentInformation>> stageTwoFiltersOr = new List<FilterDefinition<DocumentInformation>>();
if (!string.IsNullOrWhiteSpace(filter.Name))
{
stageOneFiltersAnd.Add(builder.Eq("Name", filter.Name));
}
if (!string.IsNullOrWhiteSpace(filter.Type))
{
stageOneFiltersAnd.Add(builder.Eq("Type", filter.Type));
}
if (filter.TypeContainsAny != null && filter.TypeContainsAny.Any())
{
stageOneFiltersAnd.Add(builder.In("Type", filter.TypeContainsAny));
}
if (filter.ScanStatus != null)
{
stageOneFiltersAnd.Add(builder.Eq("ScanStatus", filter.ScanStatus));
}
if (!string.IsNullOrWhiteSpace(filter.Source))
{
stageOneFiltersAnd.Add(builder.Eq("Source", filter.Source));
}
if (!string.IsNullOrWhiteSpace(filter.DataSource))
{
stageOneFiltersAnd.Add(builder.Eq("DataSource", filter.DataSource));
}
if (filter.TraceId != null)
{
stageOneFiltersAnd.Add(builder.Eq("TraceId", filter.TraceId));
}
if (!string.IsNullOrWhiteSpace(filter.PersonNumbersEquals))
{
stageOneFiltersAnd.Add(builder.Eq("PersonNumbers", filter.PersonNumbersEquals));
}
if (filter.PersonNumbersContains != null && filter.PersonNumbersContains.Any())
{
stageOneFiltersAnd.Add(builder.All("PersonNumbers", filter.PersonNumbersContains));
}
if (filter.PersonNumbersContainsAny != null && filter.PersonNumbersContainsAny.Any())
{
stageOneFiltersAnd.Add(builder.In("PersonNumbers", filter.PersonNumbersContainsAny));
}
if (filter.OrganizationNumbersEquals != null && filter.OrganizationNumbersEquals.Any())
{
stageOneFiltersAnd.Add(builder.Eq("OrganizationNumbers", filter.OrganizationNumbersEquals));
}
if (filter.OrganizationNumbersContains != null && filter.OrganizationNumbersContains.Any())
{
stageOneFiltersAnd.Add(builder.All("OrganizationNumbers", filter.OrganizationNumbersContains));
}
if (filter.OrganizationNumbersContainsAny != null && filter.OrganizationNumbersContainsAny.Any())
{
stageOneFiltersAnd.Add(builder.In("OrganizationNumbers", filter.OrganizationNumbersContainsAny));
}
if (filter.AccountNumberEquals != null && filter.AccountNumberEquals.Any())
{
stageOneFiltersAnd.Add(builder.Eq("AccountNumber", filter.AccountNumberEquals));
}
if (filter.AccountNumberContainsAny != null && filter.AccountNumberContainsAny.Any())
{
stageOneFiltersAnd.Add(builder.In("AccountNumber", filter.AccountNumberContainsAny));
}
if (filter.AttributesEquals != null && filter.AttributesEquals.Any())
{
foreach (var keyValuePair in filter.AttributesEquals)
{
stageOneFiltersAnd.Add(builder.Eq($"Attributes.{keyValuePair.Key.Trim()}", keyValuePair.Value.Trim()));
}
}
if (filter.AttributesContains is not null)
{
foreach (var keyValuePair in filter.AttributesContains)
{
var queryExpr =
new BsonRegularExpression(
new Regex($"\\b({keyValuePair.Value.Trim()})\\b", RegexOptions.IgnoreCase));
stageTwoFiltersAnd.Add(builder.Regex($"Attributes.{keyValuePair.Key.Trim()}", queryExpr));
}
}
if (filter.AttributesContainsAny is not null)
{
foreach (var keyValuePair in filter.AttributesContainsAny)
{
foreach (var value in keyValuePair.Value.Split(','))
{
var queryExpr = new BsonRegularExpression(new Regex($"^{value.Trim()}$", RegexOptions.IgnoreCase));
stageTwoFiltersOr.Add(builder.Regex($"Attributes.{keyValuePair.Key.Trim()}", queryExpr));
}
}
}
if (filter.CreatedDateMinimum != null)
{
stageOneFiltersAnd.Add(builder.Gte("CreatedDate", filter.CreatedDateMinimum));
}
if (filter.CreatedDateMaximum != null)
{
stageOneFiltersAnd.Add(builder.Lte("CreatedDate", filter.CreatedDateMaximum));
}
if (filter.UploadDateMinimum != null)
{
stageOneFiltersAnd.Add(builder.Gte("UploadDate", filter.UploadDateMinimum));
}
if (filter.UploadDateMaximum != null)
{
stageOneFiltersAnd.Add(builder.Lte("UploadDate", filter.UploadDateMaximum));
}
if (filter.LastModifiedMinimum != null)
{
stageOneFiltersAnd.Add(builder.Gte("LastModifiedDate", filter.LastModifiedMinimum));
}
if (filter.LastModifiedDateMaximum != null)
{
stageOneFiltersAnd.Add(builder.Lte("LastModifiedDate", filter.LastModifiedDateMaximum));
}
var stageOneFilterConcat = builder.Empty;
if (stageOneFiltersAnd.Any())
{
stageOneFilterConcat &= builder.And(stageOneFiltersAnd);
}
if (stageOneFiltersOr.Any())
{
stageOneFilterConcat &= builder.Or(stageOneFiltersOr);
}
var stageTwoFilterConcat = builder.Empty;
if (stageTwoFiltersAnd.Any())
{
stageOneFilterConcat &= builder.And(stageTwoFiltersAnd);
}
if (stageTwoFiltersOr.Any())
{
stageTwoFilterConcat &= builder.Or(stageTwoFiltersOr);
}
return new EmptyPipelineDefinition<DocumentInformation>()
.Match(stageOneFilterConcat)
.Match(stageTwoFilterConcat);
}
}
@@ -0,0 +1,8 @@
using MongoDB.Driver;
namespace LCU.API.Internal.DocumentLib.Repositories;
public interface IDataClient
{
MongoClient GetClient();
}
@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using LCU.API.Internal.DocumentLib.Containers;
namespace LCU.API.Internal.DocumentLib.Repositories;
public interface IDocumentAuditRepository
{
Task<List<DocumentAudit>> GetDocumentAudits(params Guid[] documentIds);
Task<IEnumerable<DocumentAudit>> SaveDocumentAudits(params DocumentAudit[] documentAudit);
}
@@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using LCU.API.Internal.DocumentLib.Containers;
using LCU.Library.Internal.DocumentIngestorModels.Models.Pagination;
using LCU.Library.Internal.DocumentModels.Requests.Search;
namespace LCU.API.Internal.DocumentLib.Repositories;
public interface IDocumentInformationRepository
{
Task<DocumentInformation> GetDocumentInformation(Guid documentId);
Task<DocumentInformation> GetDocumentInformationByBlobId(Guid documentBlobId);
Task<List<DocumentInformation>> SearchDocumentInformation(DocumentInformationFilter filter, int? skip = null, int? take = null, List<SortableField>? sortDefinition = null);
Task<DocumentInformation> SaveDocumentInformation(DocumentInformation document);
Task<DocumentInformation> UpdateDocumentInformation(Guid documentId, DocumentInformation newDocument);
Task<DocumentInformation> RemoveDocumentInformation(Guid documentId);
Task<long> CountDocuments(DocumentInformationFilter filter);
Task<List<Guid>> GetDocumentsForCleanup(GetDocumentCleanupRequest request);
}
@@ -0,0 +1,105 @@
using LCU.Library.Internal.Exceptions;
using Newtonsoft.Json;
using Serilog;
using System;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using JsonSerializer = System.Text.Json.JsonSerializer;
namespace LCU.API.Internal.DocumentLib.Utilities;
public class HttpUtilities
{
public static HttpClient CreateClient(Uri uri)
{
var handler = new HttpClientHandler
{
SslProtocols = System.Security.Authentication.SslProtocols.Tls12 |
System.Security.Authentication.SslProtocols.Tls11 |
System.Security.Authentication.SslProtocols.Tls,
ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true
};
var httpClient = new HttpClient(handler)
{
Timeout = TimeSpan.FromSeconds(60),
BaseAddress = uri
};
return httpClient;
}
public static async Task PostAsync<TRequest>(Uri uri, TRequest request)
{
try
{
var client = CreateClient(uri);
var jsonBody = JsonSerializer.Serialize(request);
var content = new StringContent(jsonBody, Encoding.UTF8, "application/json");
var response = await client.PostAsync(uri, content);
if (!response.IsSuccessStatusCode)
{
throw new ServiceException($"StatusCode:{response.StatusCode}, " +
$"Content: {response.Content.ReadAsStringAsync().Result}");
}
}
catch (Exception exception)
{
Log.Error(exception, "Failure during PostAsync.");
throw new ServiceException($"Failure during Document Upload. Exception Message: {exception.Message}");
}
}
public static async Task<TResponse> PostAsync<TRequest, TResponse>(Uri uri, TRequest request)
{
try
{
var client = CreateClient(uri);
var jsonBody = JsonSerializer.Serialize(request);
var content = new StringContent(jsonBody, Encoding.UTF8, "application/json");
var response = await client.PostAsync(uri, content);
if (!response.IsSuccessStatusCode)
{
throw new ServiceException($"StatusCode:{response.StatusCode}, " +
$"Content: {response.Content.ReadAsStringAsync().Result}");
}
var stringResponse = await response.Content.ReadAsStringAsync();
return JsonSerializer.Deserialize<TResponse>(stringResponse, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
}
catch (Exception exception)
{
Log.Error(exception, "Failure during PostAsync.");
throw new ServiceException($"Failure during PostAsync. Exception Message: {exception.Message}");
}
}
public static async Task<TResponse> GetAsync<TResponse>(string url)
{
try
{
var uri = new Uri(url);
var client = CreateClient(uri);
var response = await client.GetAsync(uri);
if (!response.IsSuccessStatusCode)
{
throw new ServiceException($"StatusCode:{response.StatusCode}, " +
$"Content: {response.Content.ReadAsStringAsync().Result}");
}
var stringResponse = await response.Content.ReadAsStringAsync();
return JsonSerializer.Deserialize<TResponse>(stringResponse, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
}
catch (Exception exception)
{
Log.Error(exception, "Failure during GetAsync.");
throw new ServiceException($"Failure during GetAsync. Exception Message: {exception.Message}");
}
}
}
@@ -0,0 +1,8 @@
using MongoDB.Driver;
namespace LCU.API.Internal.DocumentLib.Utilities;
public interface IMongoCollectionFactory
{
IMongoCollection<T> GetCollection<T>();
}
@@ -0,0 +1,37 @@
using System;
using LCU.API.Internal.DocumentLib.Configurations;
using LCU.API.Internal.DocumentLib.Containers;
using LCU.API.Internal.DocumentLib.Repositories;
using MongoDB.Driver;
namespace LCU.API.Internal.DocumentLib.Utilities;
public class MongoCollectionFactory : IMongoCollectionFactory
{
private readonly IDataClient _mongoDataClient;
private readonly DatabaseConfiguration _config;
public MongoCollectionFactory(IDataClient mongoDataClient, DatabaseConfiguration config)
{
_mongoDataClient = mongoDataClient;
_config = config;
}
public IMongoCollection<T> GetCollection<T>()
{
return _mongoDataClient
.GetClient()
.GetDatabase(_config.DatabaseName)
.GetCollection<T>(CollectionNameFor<T>());
}
private string CollectionNameFor<T>()
{
return typeof(T) switch
{
var t when t == typeof(DocumentInformation) => _config.DocumentContainerName,
var t when t == typeof(DocumentAudit) => _config.AuditContainerName,
_ => throw new NotImplementedException()
};
}
}