Adding MaidBotApi

This commit is contained in:
Zeeshaun
2026-03-11 13:21:47 -05:00
parent f3cb730f3b
commit f004c8205a
122 changed files with 4227 additions and 0 deletions
@@ -0,0 +1,46 @@
using System;
using System.Threading.Tasks;
using Serilog;
using LCU.Api.Internal.MaidBotApi.Exceptions;
using LCU.Api.Internal.MaidBotLib.Models;
using LCU.Api.Internal.MaidBotLib.Repositories;
using LCU.Library.Internal.Exceptions;
namespace LCU.Api.Internal.MaidBotApi.Services;
public class DebugEventLogService : IDebugEventLogService
{
private readonly IDebugEventLogRepository _debugEventLogRepository;
private readonly IUnitOfWork _unitOfWork;
public DebugEventLogService(IUnitOfWork unitOfWork,
IDebugEventLogRepository debugEventLogRepository)
{
_unitOfWork = unitOfWork;
_debugEventLogRepository = debugEventLogRepository;
}
public async Task DebugEventLog(EventLog eventLog)
{
if (!string.IsNullOrEmpty(eventLog.DebugData))
{
var debugEventLog = new DebugEventLog(eventLog);
await SaveAsync(debugEventLog);
}
}
public async Task<DebugEventLog> SaveAsync(DebugEventLog debugEventLog)
{
try
{
var result = await _debugEventLogRepository.AddAsync(debugEventLog);
await _unitOfWork.CompleteAsync();
return result;
}
catch (Exception exception)
{
Log.Error(exception, $"Failure saving DebugEventLog.");
throw new ServiceException($"Failure saving DebugEventLog.");
}
}
}
@@ -0,0 +1,87 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Serilog;
using Newtonsoft.Json;
using LCU.Api.Internal.MaidBotLib.Models;
using LCU.Api.Internal.MaidBotLib.Repositories;
using LCU.Library.Internal.Exceptions;
namespace LCU.Api.Internal.MaidBotApi.Services;
public class EventLogService : IEventLogService
{
private readonly IEventLogRepository _eventLogRepository;
private readonly IDebugEventLogService _debugEventLogService;
private readonly ILoggingMatrixService _loggingMatrixService;
private readonly IUnitOfWork _unitOfWork;
public EventLogService(IEventLogRepository eventLogRepository,
IDebugEventLogService debugEventLogService,
ILoggingMatrixService loggingMatrixService,
IUnitOfWork unitOfWork)
{
_eventLogRepository = eventLogRepository;
_debugEventLogService = debugEventLogService;
_loggingMatrixService = loggingMatrixService;
_unitOfWork = unitOfWork;
}
public async Task HandleIncomingEventLog(EventLog eventLog)
{
var loggingMatrixes = await _loggingMatrixService.GetByApplicationLevelAndGroupAsync(eventLog.Application,
eventLog.Level,
eventLog.Group);
if (loggingMatrixes.Any())
{
await SaveAsync(eventLog);
}
await _debugEventLogService.DebugEventLog(eventLog);
}
public async Task<IEnumerable<EventLog>> GetAsync()
{
try
{
return await _eventLogRepository.ListAsync();
}
catch (Exception exception)
{
var message = "Failure retrieving EventLogs.";
Log.Error(exception, message);
throw new ServiceException($"{message} Exception Message: {exception.Message}. ");
}
}
public async Task<EventLog> SaveAsync(EventLog eventLog)
{
try
{
var result = await _eventLogRepository.AddAsync(eventLog);
await _unitOfWork.CompleteAsync();
return result;
}
catch (Exception exception)
{
var message = $"Failure saving EventLog. EventLog: { JsonConvert.SerializeObject(eventLog)}";
Log.Error(exception, message);
throw new ServiceException($"{message} Exception Message: {exception.Message}.");
}
}
public void DeleteMany(List<EventLog> eventLogs)
{
try
{
_eventLogRepository.RemoveRange(eventLogs);
_unitOfWork.Complete();
}
catch (Exception exception)
{
var message = $"Failure to delete EventLogs.";
Log.Error(exception, message);
throw new ServiceException($"{message} Exception Message: {exception.Message}.");
}
}
}
@@ -0,0 +1,9 @@
using System.Threading.Tasks;
using LCU.Api.Internal.MaidBotLib.Models;
namespace LCU.Api.Internal.MaidBotApi.Services;
public interface IDebugEventLogService
{
Task DebugEventLog(EventLog eventLog);
Task<DebugEventLog> SaveAsync(DebugEventLog debugEventLog);
}
@@ -0,0 +1,12 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using LCU.Api.Internal.MaidBotLib.Models;
namespace LCU.Api.Internal.MaidBotApi.Services;
public interface IEventLogService
{
Task HandleIncomingEventLog(EventLog eventLog);
Task<IEnumerable<EventLog>> GetAsync();
Task<EventLog> SaveAsync(EventLog eventLog);
void DeleteMany(List<EventLog> eventLogs);
}
@@ -0,0 +1,7 @@
using System.Threading.Tasks;
namespace LCU.Api.Internal.MaidBotApi.Services;
public interface ILogDistributionService
{
Task HandleLogDistribution();
}
@@ -0,0 +1,17 @@
using LCU.Api.Internal.MaidBotLib.Models;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace LCU.Api.Internal.MaidBotApi.Services
{
public interface ILoggingMatrixService
{
Task<IEnumerable<LoggingMatrix>> GetAsync();
Task<IEnumerable<LoggingMatrix>> GetActiveAsync();
Task<LoggingMatrix> GetByIdAsync(int id);
Task<IEnumerable<LoggingMatrix>> GetByApplicationLevelAndGroupAsync(string application, string level, string group);
Task<IEnumerable<LoggingMatrix>> GetByApplicationAndLevelAsync(string application, string level);
Task<LoggingMatrix> SaveAsync(LoggingMatrix loggingMatrix);
Task<LoggingMatrix> UpdateAsync(LoggingMatrix loggingMatrix);
}
}
@@ -0,0 +1,9 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using LCU.Api.Internal.MaidBotLib.Models;
namespace LCU.Api.Internal.MaidBotApi.Services;
public interface INotificationsApiService
{
Task SendNotificationAsync(LoggingMatrix loggingMatrix, List<EventLog> eventLogs);
}
@@ -0,0 +1,8 @@
using System.Threading.Tasks;
using LCU.Api.Internal.MaidBotLib.Models;
namespace LCU.Api.Internal.MaidBotApi.Services;
public interface IQueueEventLogService
{
Task QueueEventLog(EventLog request);
}
@@ -0,0 +1,59 @@
using Serilog;
using System;
using System.Linq;
using System.Threading.Tasks;
namespace LCU.Api.Internal.MaidBotApi.Services;
public class LogDistributionService : ILogDistributionService
{
private readonly IEventLogService _eventLogService;
private readonly ILoggingMatrixService _loggingMatrixService;
private readonly INotificationsApiService _notificationsApiService;
public LogDistributionService(IEventLogService eventLogService,
ILoggingMatrixService loggingMatrixService,
INotificationsApiService notificationsApiService)
{
_eventLogService = eventLogService;
_loggingMatrixService = loggingMatrixService;
_notificationsApiService = notificationsApiService;
}
public async Task HandleLogDistribution()
{
try
{
var eventLogs = await _eventLogService.GetAsync();
if(eventLogs == null || !eventLogs.Any())
{
return;
}
var loggingMatrixs = await _loggingMatrixService.GetActiveAsync();
if (loggingMatrixs == null || !loggingMatrixs.Any())
{
return;
}
foreach (var loggingMatrix in loggingMatrixs)
{
var matrixEventLogs = eventLogs.Where(eventLog => eventLog.Application == loggingMatrix.Application &&
eventLog.Level == loggingMatrix.Level &&
eventLog.Group == loggingMatrix.Group).ToList();
if (!matrixEventLogs.Any())
{
continue;
}
await _notificationsApiService.SendNotificationAsync(loggingMatrix, matrixEventLogs);
}
_eventLogService.DeleteMany(eventLogs.ToList());
}
catch (Exception exception)
{
Log.Error(exception, "Failure to Handle Log Distribution.");
}
}
}
@@ -0,0 +1,140 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Serilog;
using LCU.Api.Internal.MaidBotLib.Models;
using LCU.Api.Internal.MaidBotLib.Repositories;
using LCU.Library.Internal.Exceptions;
namespace LCU.Api.Internal.MaidBotApi.Services;
public class LoggingMatrixService : ILoggingMatrixService
{
private readonly ILoggingMatrixRepository _loggingMatrixRepository;
private readonly IUnitOfWork _unitOfWork;
public LoggingMatrixService(IUnitOfWork unitOfWork,
ILoggingMatrixRepository loggingMatrixRepository)
{
_unitOfWork = unitOfWork;
_loggingMatrixRepository = loggingMatrixRepository;
}
public async Task<IEnumerable<LoggingMatrix>> GetAsync()
{
try
{
return await _loggingMatrixRepository.ListAsync();
}
catch (Exception exception)
{
var message = "Failure retrieving Logging Matrixes.";
Log.Error(exception, message);
throw new ServiceException($"{message} Exception Message: {exception.Message}. ");
}
}
public async Task<IEnumerable<LoggingMatrix>> GetActiveAsync()
{
try
{
return await _loggingMatrixRepository.ListActiveAsync();
}
catch (Exception exception)
{
var message = "Failure retrieving active Logging Matrixes.";
Log.Error(exception, message);
throw new ServiceException($"{message} Exception Message: {exception.Message}. ");
}
}
public async Task<IEnumerable<LoggingMatrix>> GetByApplicationLevelAndGroupAsync(string application, string level, string group)
{
try
{
return await _loggingMatrixRepository.RetrieveByApplicationLevelAndGroup(application, level, group);
}
catch (Exception exception)
{
var message = $"Failure retrieving Logging Matrixes with application {application} and level {level}.";
Log.Error(exception, message);
throw new ServiceException($"{message} Exception Message: {exception.Message}. ");
}
}
public async Task<IEnumerable<LoggingMatrix>> GetByApplicationAndLevelAsync(string application, string level)
{
try
{
return await _loggingMatrixRepository.RetrieveByApplciationAndLevel(application, level);
}
catch (Exception exception)
{
var message = $"Failure retrieving Logging Matrixes with application {application} and level {level}.";
Log.Error(exception, message);
throw new ServiceException($"{message} Exception Message: {exception.Message}. ");
}
}
public async Task<LoggingMatrix> GetByIdAsync(int id)
{
LoggingMatrix loggingMatrix = null;
try
{
loggingMatrix = await _loggingMatrixRepository.FindByIdAsync(id);
return loggingMatrix;
}
catch (Exception exception)
{
var message = $"Failure retrieving Logging Matrix with id {id}.";
Log.Error(exception, message);
throw new ServiceException($"{message} Exception Message: {exception.Message}.");
}
}
public async Task<LoggingMatrix> SaveAsync(LoggingMatrix loggingMatrix)
{
try
{
var result = await _loggingMatrixRepository.AddAsync(loggingMatrix);
await _unitOfWork.CompleteAsync();
return result;
}
catch (Exception exception)
{
var message = $"Failure saving Logging Matrix. LoggingMatrix: { JsonConvert.SerializeObject(loggingMatrix)}";
Log.Error(exception, message);
throw new ServiceException($"{message} Exception Message: {exception.Message}.");
}
}
public async Task<LoggingMatrix> UpdateAsync(LoggingMatrix loggingMatrix)
{
try
{
var existing = await GetByIdAsync(loggingMatrix.LoggingMatrixId);
if (existing == null)
{
return null;
}
existing.Application = loggingMatrix.Application;
existing.Level = loggingMatrix.Level;
existing.Group = loggingMatrix.Group;
existing.Email = loggingMatrix.Email;
existing.Disabled = loggingMatrix.Disabled;
_loggingMatrixRepository.Update(existing);
await _unitOfWork.CompleteAsync();
return existing;
}
catch (Exception exception)
{
var message = $"Failure updating Logging Matrix. LoggingMatrix: { JsonConvert.SerializeObject(loggingMatrix)}";
Log.Error(exception, message);
throw new ServiceException($"{message} Exception Message: {exception.Message}.");
}
}
}
@@ -0,0 +1,78 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Text;
using System.IO;
using Serilog;
using LCU.Api.Internal.MaidBotApi.DataAccesses;
using LCU.Api.Internal.MaidBotLib.Models;
using LCU.Library.Internal.Exceptions;
using LCU.Shared.Common.NotificationApiLib.Models;
using LCU.Api.Internal.MaidBotApi.Configurations;
namespace LCU.Api.Internal.MaidBotApi.Services;
public class NotificationsApiService : INotificationsApiService
{
private readonly ApiConfiguration _apiConfiguration;
private readonly INotificationsApiDao _notificationsApiDao;
private const string TableRowsTag = "{TableRows}";
private const string ApplicationTag = "{Application}";
private const string LevelTag = "{Level}";
public NotificationsApiService(ApiConfiguration apiConfiguration,
INotificationsApiDao notificationsApiDao)
{
_apiConfiguration = apiConfiguration;
_notificationsApiDao = notificationsApiDao;
}
public async Task SendNotificationAsync(LoggingMatrix loggingMatrix, List<EventLog> eventLogs)
{
try
{
var emailRequest = new EmailRequest
{
Recipient = new List<string> { loggingMatrix.Email },
Subject = $"{loggingMatrix.Application} - {loggingMatrix.Level}",
Body = CreateEmailBody(loggingMatrix, eventLogs)
};
await _notificationsApiDao.SendEmailRequest(emailRequest);
}
catch (Exception exception)
{
var message = $"Failure to Send Maidbot Email.";
Log.Error(exception, message);
throw new ServiceException($"{message} Exception Message: {exception.Message}");
}
}
public string CreateEmailBody(LoggingMatrix loggingMatrix, List<EventLog> eventLogs)
{
var errorRows = new StringBuilder();
foreach(var eventLog in eventLogs)
{
errorRows.Append(CreateEventLogRow(eventLog));
}
var logEmailTemplateReader = new StreamReader(_apiConfiguration.LogEmailTemplate);
string logEmailTemplateOutput = logEmailTemplateReader.ReadToEnd();
logEmailTemplateOutput = logEmailTemplateOutput.Replace(TableRowsTag, errorRows.ToString());
logEmailTemplateOutput = logEmailTemplateOutput.Replace(ApplicationTag, loggingMatrix.Level);
return logEmailTemplateOutput.Replace(LevelTag, loggingMatrix.Application);
}
public string CreateEventLogRow(EventLog eventLog)
{
var errorRowReader = new StreamReader(_apiConfiguration.LogEmailRowTemplate);
string errorRowOutput = errorRowReader.ReadToEnd();
foreach (var property in eventLog.GetType().GetProperties())
{
string value = property.GetValue(eventLog) == null ? string.Empty :
property.GetValue(eventLog).ToString();
errorRowOutput = errorRowOutput.Replace($"{{{property.Name}}}", value);
}
return errorRowOutput;
}
}
@@ -0,0 +1,36 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using MassTransit;
using Serilog;
using LCU.Api.Internal.MaidBotLib.Models;
using LCU.Library.Internal.Exceptions;
using LCU.Library.Internal.LcuMassTransitModels;
namespace LCU.Api.Internal.MaidBotApi.Services;
public class QueueEventLogService : IQueueEventLogService
{
private readonly ISendEndpoint _sendEndpoint;
public QueueEventLogService(IBusControl busControl,
ReceiveEndpointConfiguration receiveEndpointConfiguration)
{
_sendEndpoint = busControl.GetSendEndpoint(receiveEndpointConfiguration.ReceiveEndpointUri).Result;
}
public async Task QueueEventLog(EventLog request)
{
try
{
var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(30));
await _sendEndpoint.Send(request, cancellationTokenSource.Token);
}
catch (Exception exception)
{
Log.ForContext(Enum.GetName(typeof(PropertyEnum), PropertyEnum.Group),
Enum.GetName(typeof(GroupEnum), GroupEnum.ITDevelopment))
.Fatal(exception, "Failed to Queue EventLog Request.");
throw new ServiceException("Failed to Queue EventLog Request.");
}
}
}