using BMA.EHR.Application.Repositories; using BMA.EHR.Domain.Models.Insignias; using BMA.EHR.Domain.Shared; using Microsoft.AspNetCore.Http; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using RabbitMQ.Client; using RabbitMQ.Client.Events; using System.Text; namespace BMA.EHR.Infrastructure.MessageQueue { public class RabbitMQConsumer : BackgroundService { #region " Fields " private readonly IHttpContextAccessor _httpContextAccessor; private const string INSIGNIA_QUEUE = "bma_insignia_request"; private readonly IServiceScopeFactory _serviceScopeFactory; private readonly IConfiguration _configuration; private IConnection _connection; private IModel _channel; #endregion #region " Constructor and Destructor " public RabbitMQConsumer(IHttpContextAccessor httpContextAccessor, IServiceScopeFactory serviceScopeFactory, IConfiguration configuration) { _serviceScopeFactory = serviceScopeFactory; _configuration = configuration; _httpContextAccessor = httpContextAccessor; var host = _configuration["RabbitMQ:URL"]; var userName = _configuration["RabbitMQ:UserName"]; var password = _configuration["RabbitMQ:Password"]; var factory = new ConnectionFactory() { HostName = host, UserName = userName, Password = password }; _connection = factory.CreateConnection(); _channel = _connection.CreateModel(); _channel.QueueDeclare(queue: INSIGNIA_QUEUE, durable: false, exclusive: false, autoDelete: false, arguments: null); } public override void Dispose() { _channel.Close(); _connection.Close(); base.Dispose(); } #endregion #region " Properties " private string? AccessToken => _httpContextAccessor?.HttpContext?.Request.Headers["Authorization"]; #endregion #region " Methods " #region " Private " private async Task CalculateInsigniaAsync(Guid periodId) { using (var scope = _serviceScopeFactory.CreateScope()) { var userRepo = scope.ServiceProvider.GetRequiredService(); var insigniaRepo = scope.ServiceProvider.GetRequiredService(); var selectPeriod = await insigniaRepo.GetByIdAsync(periodId); if (selectPeriod == null) { throw new Exception(GlobalMessages.InsigniaPeriodNotFound); } var organizations = await userRepo.GetActiveRootAsync(AccessToken, selectPeriod.RevisionId); foreach (var organization in organizations) { if (organization == null) continue; var result = await insigniaRepo.GetInsigniaRequest(periodId, organization.Id); if (result != null) { Guid period = result.PeriodId; string requestStatus = result.RequestStatus; var candidate = await insigniaRepo.GetInsigniaCandidateBKK(periodId, organization.Id); // ตรวจสอบว่ารายการอยู่ใน table insignia_request_new if (requestStatus == null) { // บันทึกรายชื่อ await insigniaRepo.InsertCandidate(period, organization.Id, organization.OrgRootName, candidate); } } } } } #endregion #region " Overrides " protected override Task ExecuteAsync(CancellationToken stoppingToken) { Console.WriteLine("ExecuteAsync started."); // Log ตรวจสอบ var consumer = new EventingBasicConsumer(_channel); consumer.Received += (model, ea) => { var body = ea.Body.ToArray(); var message = Encoding.UTF8.GetString(body); var periodId = Guid.Parse(message); Console.WriteLine(" [x] Received {0}", message); //process insignia request while receive message var res = CalculateInsigniaAsync(periodId); Console.WriteLine(" [x] Success Calculate Period {0}", periodId); }; _channel.BasicConsume(queue: INSIGNIA_QUEUE, autoAck: true, consumer: consumer); return Task.CompletedTask; } #endregion #endregion } }