This commit is contained in:
Zeeshaun
2026-05-04 10:09:55 -05:00
parent a57846d9d1
commit 7b25f249e3
30 changed files with 99 additions and 283 deletions
@@ -21,14 +21,6 @@ public class DnaAuditProcessConsumer : IConsumer<DnaAuditProcessRequest>
await scope.ServiceProvider.GetRequiredService<IDNADataAuditProcessService>().HandleDnaAuditProcessRequest(context.Message);
Log.Debug("Ending DnaAuditProcessConsumer.");
}
catch (ServiceException serviceException)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Error(serviceException, $"DnaAuditProcess Failure. " +
$"The request is placed on DnaAuditProcess_error.");
throw;
}
catch (Exception exception)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
@@ -17,15 +17,6 @@ public class XdiBatchProcessConsumer : IConsumer<XdiBatchProcessRequest>
using var scope = _scopeFactory.CreateScope();
await Task.Run(async () => await scope.ServiceProvider.GetRequiredService<IXdiBatchProcessService>().HandleXdiBatchProcess(context.Message));
}
catch (ServiceException ex)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Error($"XdiBatchProcessConsumer Failure. " +
$"The response is placed on LCU.MemberPreferencesApi.XdiBatchProcess_error. " +
$"Error Message: {ex.Message}");
throw;
}
catch (Exception exception)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
@@ -1,8 +1,10 @@
using LCU.API.Internal.MemberPreferencesApi.Services.QueueServices;
using Microsoft.AspNetCore.Mvc;
using Microsoft.FeatureManagement.Mvc;
namespace LCU.API.Internal.MemberPreferencesApi.Controllers;
[FeatureGate(FeatureGates.EnableControllers)]
[ApiController]
[Route("api/[controller]")]
public class QueueXdiBatchProcessController : ControllerBase
@@ -13,7 +13,6 @@
<PackageReference Include="LCU.Api.Internal.MaidBotLib" Version="1.0.2" />
<PackageReference Include="LCU.Library.Internal.Exceptions" Version="2.0.0" />
<PackageReference Include="LCU.Library.Internal.FileOperationsModels" Version="4.1.5" />
<PackageReference Include="LCU.Library.Internal.LcuClassPatterns.Crud" Version="1.0.2" />
<PackageReference Include="LCU.Library.Internal.LcuHttpClient" Version="1.21.0" />
<PackageReference Include="LCU.Library.Internal.LcuMassTransit" Version="1.0.0" />
<PackageReference Include="LCU.Library.Internal.LcuMassTransitModels" Version="1.1.0" />
@@ -68,7 +68,7 @@ public class XdiBatch
}
if (currentSettings.UniversalOptIn == DeliveryPreference.Microfiche &&
currentSettings.ENotifications == DeliveryPreference.Electronic)
currentSettings.ENotifications == DeliveryPreference.Electronic)
{
_updateMemberToPrint.AddRow(item.UserId, currentSettings.UnifiedOptInEmail);
return true;
@@ -245,7 +245,6 @@ void AddMemberPreferencesLib(ref IServiceCollection services)
services.AddScoped<IMemberPreferenceRepository, MemberPreferenceRepository>();
services.AddScoped<IMemberPreferences, MemberPreferenceRepository>();
services.AddScoped<IXdiBatchItemsRepository, XdiBatchItemsRepository>();
services.AddScoped<IXdiBatchProcessInfoRepository, XdiBatchProcessInfoRepository>();
services.AddScoped<IDnaAuditProcessRepository, DnaAuditProcessRepository>();
}
@@ -50,7 +50,6 @@ public class DNADataAuditProcessService : IDNADataAuditProcessService
Log.Error(ex.Message);
// Return successful as True so Dispatcher job never stops running.
await QueueReturnResponse.QueueResponse(request, true, new List<string>() { ex.Message });
throw new ServiceException($"Failed to handled Consumed DnaAuditProcessRequest. ExceptionMessage: {ex.Message}");
}
}
@@ -18,7 +18,7 @@ namespace LCU.API.Internal.MemberPreferencesApi.MicroApiServices
{
var result = await _fileOperationsApiDao.AppendFileAsync(request);
Log.Information($"XDI File Sent, Response: {result.ReturnResponse}");
Log.Information($"XDI File Saved. Response: {result.ReturnResponse}");
return result;
}
catch (Exception ex)
@@ -1,5 +1,6 @@
using LCU.API.Internal.MemberPreferencesApi.Models;
using LCU.Library.Internal.MemberPreferencesApiModels.Entities;
using LCU.Library.Internal.MemberPreferencesApiModels.Responses;
namespace LCU.API.Internal.MemberPreferencesApi.Services.XdiServices;
@@ -7,9 +8,9 @@ public interface IXdiBatchService
{
Task AddXdiBatchItem(XdiBatchItem newItem);
Task SaveRangeAsync(List<XdiBatchItem> xdiBatchItemList);
Task CreateXdiBatchFiles(XdiBatchRequest request);
Task<RequestResponse> CreateXdiBatchFiles(XdiBatchRequest request);
Task<XdiBatchRequest> BuildXdiBatchRequest(XdiBatchRequest request);
Task<List<XdiBatchFileExport>> BuildXdiFiles(XdiBatchFile batchFile, string filePath, XdiBatchProcessInfo xdiBatchProcessInfo);
Task<List<XdiBatchFileExport>> BuildXdiFiles(XdiBatchFile batchFile, string filePath);
Task<bool> MarkPendingSuccessful(List<XdiBatchFileExport> batchFileExportList);
Task<bool> DoesMemberHavePendingXdiChange(string memberId);
}
@@ -36,8 +36,8 @@ public class XdiBatchProcessService : IXdiBatchProcessService
XdiAppendFileRootBasePath = xdiBatchProcessRequest.XdiAppendFileRootBasePath
};
await _xdiBatchService.CreateXdiBatchFiles(request);
await QueueReturnResponse.QueueResponse(xdiBatchProcessRequest, true, new List<string> { $"Requested {xdiBatchItems.Count()} Xdi Batch Items to Process."});
var result = await _xdiBatchService.CreateXdiBatchFiles(request);
await QueueReturnResponse.QueueResponse(xdiBatchProcessRequest, result.IsSuccessful, result.MessageStack);
}
}
catch (Exception ex)
@@ -45,7 +45,6 @@ public class XdiBatchProcessService : IXdiBatchProcessService
var errorMessage = $"Failed to HandleXdiBatchProcess. Exception Message: {ex.Message}";
Log.Error(errorMessage);
await QueueReturnResponse.QueueResponse(xdiBatchProcessRequest, false, new List<string>() {errorMessage});
throw new ServiceException(errorMessage);
}
}
}
@@ -1,17 +1,15 @@
using LCU.API.Internal.MemberPreferencesApi.MicroApiServices;
using LCU.API.Internal.MemberPreferencesApi.Models;
using LCU.API.Internal.MemberPreferencesApiLib.Repositories;
using LCU.Library.Internal.FileOperationsModels.Models;
using LCU.Library.Internal.LcuClassPatterns.Crud.Services;
using LCU.Library.Internal.MemberPreferencesApiModels.Entities;
using LCU.Library.Internal.MemberPreferencesApiModels.Enums;
using System.Data.SqlClient;
using LCU.Library.Internal.MemberPreferencesApiModels.Responses;
using FileOperationsModels = LCU.Library.Internal.FileOperationsModels.Models;
namespace LCU.API.Internal.MemberPreferencesApi.Services.XdiServices
{
public class XdiBatchService : CrudService<XdiBatchProcessInfo>, IXdiBatchService
public class XdiBatchService : IXdiBatchService
{
private readonly IXdiBatchProcessInfoRepository _xdiBatchProcessInfoRepository;
private readonly IXdiBatchItemsRepository _xdiBatchItemsRepository;
private readonly IUnifiedOptInRepository _unifiedOptInRepository;
private readonly IMemberPreferenceRepository _memberPreferenceRepository;
@@ -21,44 +19,37 @@ namespace LCU.API.Internal.MemberPreferencesApi.Services.XdiServices
public XdiBatchService(IXdiBatchItemsRepository xdiBatchItemsRepository,
IUnitOfWork unitOfWork, IUnifiedOptInRepository unifiedOptInRepository,
IMemberPreferenceRepository memberPreferencesRepository, IFileOperationsApiService fileOperationsApiService,
IXdiBatchProcessInfoRepository xdiBatchProcessInfoRepository) : base(xdiBatchProcessInfoRepository)
IMemberPreferenceRepository memberPreferencesRepository, IFileOperationsApiService fileOperationsApiService)
{
_xdiBatchItemsRepository = xdiBatchItemsRepository;
_unitOfWork = unitOfWork;
_memberPreferenceRepository = memberPreferencesRepository;
_unifiedOptInRepository = unifiedOptInRepository;
_fileOperationsApiService = fileOperationsApiService;
_xdiBatchProcessInfoRepository = xdiBatchProcessInfoRepository;
}
public async Task CreateXdiBatchFiles(XdiBatchRequest request)
public async Task<RequestResponse> CreateXdiBatchFiles(XdiBatchRequest request)
{
var batchProcessInfo = new XdiBatchProcessInfo();
var batchUserIds = string.Join(",", request.XdiBatchItems.Select(c => c.UserId).ToList());
var requestResponse = new RequestResponse();
try
{
var batchProcessInProgress = _xdiBatchProcessInfoRepository.FindBatchProcessInfoByStatus(XdiBatchProcessStatus.InProgress).Result;
if (batchProcessInProgress.Count() == 0)
{
request = await BuildXdiBatchRequest(request);
batchProcessInfo = await CreateNewBatchProcessInfo(request.XdiBatchItems.Count());
await CreateXdiExportFileRequest(request, batchProcessInfo);
await UpdateBatchAsync(batchProcessInfo, XdiBatchProcessStatus.Completed, $"Completed XDI Batch Process for UserIds: {batchUserIds}");
}
request = await BuildXdiBatchRequest(request);
requestResponse = await CreateXdiExportFileRequest(request);
}
catch (Exception ex)
{
Log.Error(ex, $"Failed to Create XDI Batch Files.");
await UpdateBatchAsync(batchProcessInfo, XdiBatchProcessStatus.Failed, $"Failed XDI Batch Process for UserIds: {batchUserIds}");
throw new ServiceException($"Failed to Create XDI Batch Files. Exception Message: {ex.Message}");
var batchUserIds = string.Join(",", request.XdiBatchItems.Select(c => c.UserId).ToList());
var errorMessage = $"Failed to Create XDI Batch Files for UserId(s): {batchUserIds} Error: { ex.Message}";
Log.Error(errorMessage);
requestResponse.MessageStack.Add(errorMessage);
requestResponse.IsSuccessful = false;
}
return requestResponse;
}
public async Task<XdiBatchRequest> BuildXdiBatchRequest(XdiBatchRequest request)
{
foreach (var item in request.XdiBatchItems)
foreach (var item in request.XdiBatchItems)
{
var currentSettings = await _unifiedOptInRepository.GetMemberOptInSettings(item.UserId);
if (currentSettings != null)
@@ -81,45 +72,62 @@ namespace LCU.API.Internal.MemberPreferencesApi.Services.XdiServices
Log.Error($"No XdiBatchRow or XDI File was processed based on current member UserId: {item.UserId} Opt In Settings, marking complete.");
_xdiBatchItemsRepository.Delete(item);
}
};
};
}
;
}
;
await _unitOfWork.CompleteAsync(XdiBatchProcessOperatorName, DateTime.UtcNow, UserType.System);
return request;
}
public async Task CreateXdiExportFileRequest(XdiBatchRequest request, XdiBatchProcessInfo xdiBatchProcessInfo)
public async Task<RequestResponse> CreateXdiExportFileRequest(XdiBatchRequest request)
{
var requestResponse = new RequestResponse();
try
{
IReadOnlyCollection<XdiBatchFile> batchFiles = request.XdiBatch.GetNonEmptyFiles();
Log.Information($"XdiBatchService produced {batchFiles.Count} files");
var batchFilesMessage = ($"XdiBatchService produced {batchFiles.Count} file(s)");
Log.Information(batchFilesMessage);
foreach (var xdiBatchFile in batchFiles)
{
var xdiBatchFileExport = await BuildXdiFiles(xdiBatchFile, request.XdiAppendFileRootBasePath, xdiBatchProcessInfo);
await MarkPendingSuccessful(xdiBatchFileExport);
var xdiBatchFileExport = await BuildXdiFiles(xdiBatchFile, request.XdiAppendFileRootBasePath);
if (xdiBatchFileExport != null)
{
await MarkPendingSuccessful(xdiBatchFileExport);
}
}
}
requestResponse.IsSuccessful = true;
requestResponse.MessageStack.Add(batchFilesMessage);
}
catch (Exception ex)
{
Log.Error(ex, $"Failed to Create the XDI File to export.");
var errorMessage = $"Failed to Create the XDI File to export. {ex.Message}";
Log.Error(errorMessage);
requestResponse.MessageStack.Add(errorMessage);
requestResponse.IsSuccessful = false;
}
return requestResponse;
}
public async Task<List<XdiBatchFileExport>> BuildXdiFiles(XdiBatchFile batchFile, string filePath, XdiBatchProcessInfo xdiBatchProcessInfo)
public async Task<List<XdiBatchFileExport>> BuildXdiFiles(XdiBatchFile batchFile, string filePath)
{
AppendFileRequest request = BuildFileOperationsRequest(batchFile, filePath);
FileOperationsModels.AppendFileRequest request = BuildFileOperationsRequest(batchFile, filePath);
var xdiBatchFileExport = await CreateDirectoryXdiFiles(batchFile);
var result = await _fileOperationsApiService.AppendFile(request);
if (!result.IsSuccessful)
{
throw new Exception($"Failed to Append File: {batchFile.GetFileName}");
}
return xdiBatchFileExport;
}
private AppendFileRequest BuildFileOperationsRequest(XdiBatchFile xdiBatchFile, string filePath)
private FileOperationsModels.AppendFileRequest BuildFileOperationsRequest(XdiBatchFile xdiBatchFile, string filePath)
{
var request = new AppendFileRequest()
var request = new FileOperationsModels.AppendFileRequest()
{
DestinationPath = filePath,
Extension = ".txt",
@@ -256,45 +264,5 @@ namespace LCU.API.Internal.MemberPreferencesApi.Services.XdiServices
}
}
}
public async Task<XdiBatchProcessInfo> CreateNewBatchProcessInfo(int batchTotal)
{
var xdiBatchProcessInfo = new XdiBatchProcessInfo();
xdiBatchProcessInfo.StartTimeStamp = DateTime.Now;
xdiBatchProcessInfo.XdiBatchProcessStatus = XdiBatchProcessStatus.InProgress;
xdiBatchProcessInfo.BatchTotal = batchTotal;
return await _xdiBatchProcessInfoRepository.AddAsync(xdiBatchProcessInfo);
}
public async Task<XdiBatchProcessInfo> UpdateBatchAsync(XdiBatchProcessInfo xdiBatchProcessInfo, XdiBatchProcessStatus xdiBatchStatus, string apiResponse)
{
try
{
var existing = await _xdiBatchProcessInfoRepository.FindByIdAsync(xdiBatchProcessInfo.XdiBatchProcessInfoId);
if (existing == null)
{
throw new ServiceException($"XdiBatchProcessInfo with XdiBatchProcessInfoId {xdiBatchProcessInfo.XdiBatchProcessInfoId} not found");
}
existing.XdiBatchProcessStatus = xdiBatchStatus;
existing.ApiResponse = apiResponse;
existing.EndTimeStamp = DateTime.Now;
await _xdiBatchProcessInfoRepository.UpdateAsync(existing);
await _unitOfWork.CompleteAsync();
return existing;
}
catch (SqlException sqlEx)
{
var message = $"Failure updating XdiBatchProcessInfo with XdiBatchProcessInfoId {xdiBatchProcessInfo.XdiBatchProcessInfoId}";
Log.Error(sqlEx, message);
throw new ServiceException(message);
}
catch (Exception ex)
{
var message = $"Failure updating XdiBatchProcessInfo with XdiBatchProcessInfoId {xdiBatchProcessInfo.XdiBatchProcessInfoId}";
Log.Error(ex, message);
throw new ServiceException(message);
}
}
}
}
@@ -42,7 +42,7 @@
"AppendFile": "DirectFileOperations/AppendFile"
},
"CoreApiWrapperConfiguration": {
"CoreApiBaseUrl": "https://qa-core-api-wrapper-api.apps.azure.lcu-internal.com/api/core/",
"CoreApiBaseUrl": "https://localhost:44355/api/core/",
"CoreApiGetAgreementByUserId": "Agree/AgreementByUserId/{userId}",
"CoreApiGetAgreementByAgreementId": "Agree/AgreementByAgreementId/{agreementId}",
"CoreApiGetAgreementsByAccountId": "Agree/AgreementsByAccountId/{accountId}",