Files
2026-03-24 15:26:03 -05:00

258 lines
9.6 KiB
C#

using LCU.Api.Internal.Dispatcher.Configurations;
using LCU.Api.Internal.DispatcherLib.Repositories;
using LCU.Api.Internal.DispatcherSharedLib.BuilderServices;
using LCU.Library.Internal.ApiResponse.Models;
using LCU.Library.Internal.LcuMassTransitModels;
using Microsoft.Data.SqlClient;
using Newtonsoft.Json;
using System.Collections.Generic;
namespace LCU.Api.Internal.Dispatcher.Services;
public class WorkItemService : IWorkItemService
{
private readonly IUnitOfWork _unitOfWork;
private readonly IWorkItemRepository _workItemRepository;
private readonly IWorkItemExecutionService _workItemExecutionService;
private readonly IActionBuilderService _actionBuilderService;
private readonly ConnectionConfiguration _connectionConfiguration;
private readonly ReceiveEndpointConfiguration _completionReceiveEndpoint;
private readonly ApiConfiguration _apiConfiguration;
public WorkItemService(IUnitOfWork unitOfWork,
IWorkItemRepository workItemRepository,
IWorkItemExecutionService workItemExecutionService,
IActionBuilderService actionBuilderService,
ConnectionConfiguration connectionConfiguration,
ReceiveEndpointConfigurations queueReceiveEndpointsConfigurations,
ApiConfiguration apiConfiguration)
{
_unitOfWork = unitOfWork;
_workItemRepository = workItemRepository;
_workItemExecutionService = workItemExecutionService;
_actionBuilderService = actionBuilderService;
_connectionConfiguration = connectionConfiguration;
_completionReceiveEndpoint = queueReceiveEndpointsConfigurations.CompletionReceiveEndpoint;
_apiConfiguration = apiConfiguration;
}
public async Task<WorkItem> GetByIdAsync(int id)
{
WorkItem workItem = null;
try
{
workItem = await _workItemRepository.FindByIdAsync(id);
ArgumentNullException.ThrowIfNull(workItem);
}
catch (Exception exception)
{
Log.Error(exception, $"Failure retrieving dispatcher workitem with id {id}.");
throw new ServiceException($"Failure retrieving dispatcher workitem with id {id}.");
}
return workItem;
}
public async Task<IEnumerable<WorkItem>> GetByJobIdAsync(int jobId)
{
IEnumerable<WorkItem> workItems = null;
try
{
workItems = await _workItemRepository.FindByJobIdAsync(jobId);
ArgumentNullException.ThrowIfNull(workItems);
}
catch (Exception exception)
{
Log.Error(exception, $"Failure retrieving dispatcher workitems with JobId {jobId}.");
throw new ServiceException($"Failure retrieving dispatcher workitems with JobId {jobId}.");
}
return workItems;
}
public async Task<IEnumerable<WorkItem>> GetByJobIdWithExecutionsAsync(int jobId)
{
IEnumerable<WorkItem> workItems = null;
try
{
workItems = await _workItemRepository.FindByJobIdWithExecutionsAsync(jobId,
_apiConfiguration.NumberOfWorkItemExecutions,
_apiConfiguration.NumberOfExecutionMessages);
ArgumentNullException.ThrowIfNull(workItems);
}
catch (Exception exception)
{
Log.Error(exception, $"Failure retrieving dispatcher workitems and executions with JobId {jobId}.");
throw new ServiceException($"Failure retrieving dispatcher workitems and executions with JobId {jobId}.");
}
return workItems;
}
public async Task<WorkItem> GetFirstOrDefaultWorkItemByJobId(int jobId)
{
WorkItem workItem = null;
try
{
workItem = await _workItemRepository.GetFirstOrDefaultWorkItemByJobId(jobId);
}
catch (Exception exception)
{
Log.Error(exception, $"Failure retrieving first or default workItem with JobId: {jobId}.");
throw new ServiceException($"Failure retrieving first or default workItem with JobId: {jobId}.");
}
return workItem;
}
public async Task<WorkItem> GetNextWorkItemByJobId(int jobId, int currentWorkItemOrder)
{
WorkItem workItem = null;
try
{
workItem = await _workItemRepository.GetNextWorkItemByJobId(jobId, currentWorkItemOrder);
}
catch (Exception exception)
{
Log.Error(exception, $"Failure retrieving next workItem with JobId: {jobId}.");
throw new ServiceException($"Failure retrieving next workItem with JobId: {jobId}.");
}
return workItem;
}
public async Task<ICollection<WorkItem>> PopulateActionFieldsAndUpdateList(ICollection<WorkItem> workItems)
{
try
{
var updatedWorkItems = new List<WorkItem>();
foreach (var workItem in workItems)
{
var newWorkItem = workItem;
newWorkItem = PopulateActionFields(newWorkItem);
newWorkItem = await UpdateAsync(newWorkItem);
updatedWorkItems.Add(newWorkItem);
}
return updatedWorkItems;
}
catch (Exception exception)
{
Log.Error(exception, $"Failure populating action fields and updating dispatcher workitems.");
}
return null;
}
public async Task<WorkItem> ResetCanceledJobCounter(WorkItem workItem)
{
var trackedWorkItem = await _workItemRepository.GetTrackedWorkItem(workItem.WorkItemId);
trackedWorkItem.CanceledJobCounter = 0;
await _unitOfWork.CompleteAsync();
return await _workItemRepository.FindByIdAsync(trackedWorkItem.WorkItemId);
}
public async Task<WorkItem> IncreaseCanceledJobCounter(WorkItem workItem)
{
var trackedWorkItem = await _workItemRepository.GetTrackedWorkItem(workItem.WorkItemId);
trackedWorkItem.CanceledJobCounter++;
await _unitOfWork.CompleteAsync();
return await _workItemRepository.FindByIdAsync(trackedWorkItem.WorkItemId);
}
public async Task<WorkItem> UpdateAsync(WorkItem workItem)
{
try
{
_workItemRepository.Update(workItem);
await _unitOfWork.CompleteAsync();
return workItem;
}
catch (SqlException sqlException)
{
Log.Error(sqlException, $"SQL Failure updating dispatcher workitem with id {workItem.WorkItemId}");
throw new ServiceException($"SQL Failure updating dispatcher workitem with id {workItem.WorkItemId}");
}
catch (Exception exception)
{
Log.Error(exception, $"Failure updating dispatcher workitem with id {workItem.WorkItemId}");
throw new ServiceException($"Failure updating dispatcher workitem with id {workItem.WorkItemId}");
}
}
public void SaveList(ICollection<WorkItem> workItems)
{
try
{
_workItemRepository.AddList(workItems);
_unitOfWork.Complete();
}
catch (Exception exception)
{
Log.Error(exception, $"Failure saving list of workitems.");
throw new ServiceException($"Failure saving list of workitems.");
}
}
public async Task DeleteList(ICollection<WorkItem> workItems)
{
try
{
foreach (var workItem in workItems)
{
var workItemExecutions = await _workItemExecutionService.GetAllByWorkItemId(workItem.WorkItemId);
workItem.WorkItemExecutions = workItemExecutions.ToList();
}
_workItemRepository.RemoveList(workItems);
await _unitOfWork.CompleteAsync();
}
catch (SqlException sqlException)
{
Log.Error(sqlException, $"SQL Failure removing dispatcher workitems");
throw new ServiceException($"SQL Failure removing dispatcher workitems");
}
catch (Exception exception)
{
Log.Error(exception, $"Failure removing dispatcher workitems");
throw new ServiceException($"Failure removing dispatcher workitems");
}
}
public WorkItem PopulateActionFields(WorkItem workItem)
{
var actionBuilder = _actionBuilderService.BuildAction(workItem.ActionType);
var responseItem = CreateResponseItem(workItem.WorkItemId);
workItem = actionBuilder.AddUrlAndHttpMethod(workItem);
workItem = actionBuilder.AddWorkItemReturnResponse(workItem, responseItem);
return workItem;
}
private ResponseItem CreateResponseItem(int workItemId)
{
var dispatcherReturnResponse = new DispatcherReturnResponse
{
WorkItemId = workItemId
};
var serializeDispatcherReturnResponse = JsonConvert.SerializeObject(dispatcherReturnResponse);
var newReturnItem = new ResponseItem
{
ResponsePayload = serializeDispatcherReturnResponse,
ReturnQueueConnectionConfig = new QueueConnectionConfig()
{
Url = _connectionConfiguration.HostUrl,
Username = _connectionConfiguration.UserName,
Password = _connectionConfiguration.Password
},
ReturnQueueConsumerConfig = new QueueConsumerConfig()
{
ExchangeName = _completionReceiveEndpoint.ReceiveEndpoint
}
};
return newReturnItem;
}
}