using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using MSAdminUsuarios.Context; using MSAdminUsuarios.Controllers; using MSAdminUsuarios.Models; using Newtonsoft.Json; using RabbitMQ.Client; using RabbitMQ.Client.Events; using System.Reflection; using System.Text; namespace MSAdminUsuarios.Utils { public static class RabbitMQService { private static string[] _queues = Array.Empty(); private static string _exchange = "MSAdminUsuarios"; public static IModel GetRabbitMQChannel(IServiceProvider serviceProvider, string projectName) { //var loggerFactory = LoggerFactory.Create(builder => builder.AddConsole().AddEventLog()); //var logger = loggerFactory.CreateLogger("Rabbit1"); var connection = serviceProvider.GetService(); if (connection == null) throw new Exception("Connection is null."); var channel = connection.CreateModel(); //Declare exchange if it doesnt already exist var exchangeName = projectName; _exchange = exchangeName; channel.ExchangeDeclare( exchange: exchangeName, type: ExchangeType.Topic, durable: true, autoDelete: false, arguments: null ); _queues = new string[] { $"{exchangeName}.PerfilesPorUsuario", $"{exchangeName}.Usuarios" }; foreach (var queue in _queues) { channel.QueueDeclare( queue: queue, durable: true, exclusive: false, autoDelete: false, arguments: null ); channel.QueueBind( queue: queue, exchange: exchangeName, routingKey: $"{queue}.*" ); } return channel; } public static void ListenForIntegrationEvents(string projectName, WebApplicationBuilder builder) { RabbitMQConfig mqConfig = builder.Configuration.GetSection("RabbitMQConfig").Get(); var loggerFactory = LoggerFactory.Create(builder => builder.AddConsole().AddEventLog()); //var logger = loggerFactory.CreateLogger("Rabbit2"); //logger.LogInformation("Inicia Rabbitmq con"); ConnectionFactory factory = new() { HostName = mqConfig.HostName, UserName = mqConfig.UserName, Password = mqConfig.Password, }; IConnection connection = factory.CreateConnection(); IModel channel = connection.CreateModel(); EventingBasicConsumer consumer = new(channel); consumer.Received += RabbitMQService.ConsumeRabbitMQEvent; List queues = new() { $"{projectName}.PerfilesPorUsuario", $"{projectName}.Usuarios", }; foreach (var queue in queues) { channel.BasicConsume( queue: queue, autoAck: false, consumer: consumer ); } } public static async void ConsumeRabbitMQEvent(object? sender, BasicDeliverEventArgs ea) { var body = ea.Body.ToArray(); var message = Encoding.UTF8.GetString(body); var route = ea.RoutingKey; if (message == null || message.Length == 0) { throw new Exception("Datos no recibidos"); } if (route == null || route.Length == 0) { throw new Exception("RouteKey no recibida"); } var controller = route.Split("."); var consumer = (EventingBasicConsumer)sender!; var model = consumer.Model; var loggerFactory = LoggerFactory.Create(builder => builder.AddConsole().AddEventLog()); var logger = loggerFactory.CreateLogger("RMQ.MsAdminUsuarios"); ModelContext context = new(); if (controller[1] == "PerfilesPorUsuario") { try { var data = JsonConvert.DeserializeObject(message); var PPUCtrl = new PerfilesPorUsuarioController(context); var result = await PPUCtrl.GuardarPerfilesPorUsuario(data!); if (result is OkResult) { model.BasicAck(ea.DeliveryTag, false); } else throw new Exception(); } catch (Exception ex) { // Temporalmente solo logeamos el error en lugar de rechazar logger.LogCritical(ExMessage(ex)); //model.BasicReject(ea.DeliveryTag, true); model.BasicAck(ea.DeliveryTag, false); } return; } if (controller[1] == "Usuarios") { try { var data = JsonConvert.DeserializeObject(message); var UsuariosCtrl = new UsuariosController(context); IActionResult result = await UsuariosCtrl.GuardarUsuarios(data!); if (result is OkResult) { model.BasicAck(ea.DeliveryTag, false); } else throw new Exception(((ConflictObjectResult)result).Value?.ToString() ?? "No registra log"); } catch (Exception ex) { // Temporalmente solo logeamos el error en lugar de rechazar logger.LogCritical(ExMessage(ex)); //model.BasicReject(ea.DeliveryTag, true); model.BasicAck(ea.DeliveryTag, false); } return; } } private static string ExMessage(Exception ex) { var sb = new StringBuilder(); sb.Append(ex.Message) .Append(ex.InnerException); return sb.ToString(); } } }