using LCU.Api.Internal.Dispatcher.Configurations; using LCU.Library.Internal.DispatcherModels.Models.Requests; using System.Collections.Generic; using System.IO; namespace LCU.Api.Internal.Dispatcher.Services.DispatcherOperationServices { public class SendErroredJobAlertService : ISendErroredJobAlertService { private readonly ApiConfiguration _apiConfiguration; private readonly INotificationService _notificationService; public SendErroredJobAlertService(ApiConfiguration apiConfiguration, INotificationService notificationService) { _apiConfiguration = apiConfiguration; _notificationService = notificationService; } public Task HandleSendingErroredJobAlerts(List batchedErroredJobAlertRequestList) { var erroredJobAlertRequests = CombineFromBatch(batchedErroredJobAlertRequestList); return SendErroredJobsReport(erroredJobAlertRequests); } public async Task SendErroredJobsReport(List erroredJobAlertRequests) { var groupedJobsByRecipients = GroupJobsByRecipients(erroredJobAlertRequests); var result = true; foreach (var recipientGroup in groupedJobsByRecipients) { var successful = await HandleBatchErroredJobs(recipientGroup.Value, recipientGroup.Key); if (!successful) { result = false; } } if (!result) { throw new ServiceException($"Failure to Send Errored Jobs Report. Result: {result}"); } } public List CombineFromBatch(List batchedErroredJobAlertRequestList) { var erroredJobAlertRequests = new List(); foreach (var batch in batchedErroredJobAlertRequestList) { erroredJobAlertRequests.AddRange(batch.ErroredJobAlertRequests); } return erroredJobAlertRequests; } public Dictionary> GroupJobsByRecipients(List erroredJobAlertRequests) { var groupedRecipients = new Dictionary>(); foreach (var erroredJobAlertRequest in erroredJobAlertRequests) { AddRecipients(erroredJobAlertRequest, groupedRecipients); } return groupedRecipients; } public void AddRecipients(ErroredJobAlertRequest erroredJbAlertRequest, Dictionary> groupedRecipients) { if (erroredJbAlertRequest.CurrentJob.JobErrorRecipients == null || erroredJbAlertRequest.CurrentJob.JobErrorRecipients.Count == 0) { AddRecipient(_apiConfiguration.DefaultErrorRecipient, erroredJbAlertRequest, groupedRecipients); return; } foreach (var jobErrorRecipient in erroredJbAlertRequest.CurrentJob.JobErrorRecipients) { AddRecipient(jobErrorRecipient.Recipient, erroredJbAlertRequest, groupedRecipients); } } public void AddRecipient(string defaultErrorRecipient, ErroredJobAlertRequest erroredJobAlertRequest, Dictionary> groupedRecipients) { var recipientLower = defaultErrorRecipient.ToLower(); if (!groupedRecipients.ContainsKey(recipientLower)) { groupedRecipients.Add(recipientLower, new List()); } groupedRecipients[recipientLower].Add(erroredJobAlertRequest); } public async Task HandleBatchErroredJobs(List erroredJobAlertRequests, string recipient) { string rowsOfErrors = ""; foreach (ErroredJobAlertRequest erroredJobAlertRequest in erroredJobAlertRequests) { var jobErrorDetail = SetUpJobErrorDetails(erroredJobAlertRequest); if (jobErrorDetail != null) { rowsOfErrors += CreateErrorRow(jobErrorDetail); } } var emailTemplate = CreateBatchErroredJobsEmail(rowsOfErrors); var successfullySent = await _notificationService.SendEmailAsync(recipient, _apiConfiguration.BatchErroredJobsSubject, emailTemplate); return successfullySent; } public JobErrorDetail SetUpJobErrorDetails(ErroredJobAlertRequest erroredJobAlertRequest) { var jobErrorDetail = new JobErrorDetail() { JobName = erroredJobAlertRequest?.CurrentJob?.Name, WorkItemName = erroredJobAlertRequest?.CurrentWorkItem?.Name, JobStatus = erroredJobAlertRequest?.CurrentJob?.JobStatus.ToString(), StartTime = erroredJobAlertRequest?.CurrentWorkItem?.CurrentWorkItemExecution?.StartedTimestamp.ToString() }; return jobErrorDetail; } public string CreateErrorRow(JobErrorDetail jobErrorDetails) { using var errorRowReader = new StreamReader(_apiConfiguration.ErrorRowTemplate); string errorRowOutput = errorRowReader.ReadToEnd(); foreach (var property in jobErrorDetails.GetType().GetProperties()) { string value = property.GetValue(jobErrorDetails) == null ? string.Empty : property.GetValue(jobErrorDetails).ToString(); errorRowOutput = errorRowOutput.Replace($"{{{property.Name}}}", value); } return errorRowOutput; } public string CreateBatchErroredJobsEmail(string errorRows) { using var batchErroredJobsReader = new StreamReader(_apiConfiguration.BatchErroredJobsTemplate); string batchErroredJobsOutput = batchErroredJobsReader.ReadToEnd(); return batchErroredJobsOutput.Replace("{TableRows}", errorRows); } } }