diff --git a/PARR.API/Contracts/V1/ApiRoutes.cs b/PARR.API/Contracts/V1/ApiRoutes.cs index 3ca29558..fea903f7 100644 --- a/PARR.API/Contracts/V1/ApiRoutes.cs +++ b/PARR.API/Contracts/V1/ApiRoutes.cs @@ -215,6 +215,7 @@ public static class StatRabbitMq { public const string GetQueueStats = BaseStat + "/rabbitmq-queues/"; + public const string GetConnectionStats = BaseStat + "/rabbitmq-connections/"; } #endregion diff --git a/PARR.API/Contracts/V1/Responses/Statistics/StatRabbitMqQueueResponse.cs b/PARR.API/Contracts/V1/Responses/Statistics/StatRabbitMqQueueResponse.cs deleted file mode 100644 index 275d8a95..00000000 --- a/PARR.API/Contracts/V1/Responses/Statistics/StatRabbitMqQueueResponse.cs +++ /dev/null @@ -1,13 +0,0 @@ -using PARR.DAL.Services.Interfaces; - -namespace PARR.API.Contracts.V1.Responses.Statistics -{ - public class StatRabbitMqQueueResponse - { - public required string Name { get; set; } - - public int Consumers { get; set; } - - public int MessagesTotal { get; set; } - } -} diff --git a/PARR.API/Controllers/V1/Statistics/StatRabbitMqController.cs b/PARR.API/Controllers/V1/Statistics/StatRabbitMqController.cs index a8f9637a..3077baec 100644 --- a/PARR.API/Controllers/V1/Statistics/StatRabbitMqController.cs +++ b/PARR.API/Controllers/V1/Statistics/StatRabbitMqController.cs @@ -2,7 +2,6 @@ using Microsoft.AspNetCore.Mvc; using PARR.API.Contracts.V1; using PARR.API.Contracts.V1.Responses.Base; -using PARR.API.Contracts.V1.Responses.Statistics; using PARR.API.Controllers.V1.Base; using PARR.API.Settings; using PARR.BLL.Services.Interfaces; @@ -19,12 +18,14 @@ namespace PARR.API.Controllers.V1.Statistics private readonly IMqService mqService; private readonly MqSettings mqSettings; private readonly ILogger logger; + private readonly IMqAdminService mqAdminService; - public StatRabbitMqController(IMqService mqService, MqSettings mqSettings, ILogger logger) + public StatRabbitMqController(IMqService mqService, MqSettings mqSettings, ILogger logger, IMqAdminService mqAdminService) { this.mqService = mqService; this.mqSettings = mqSettings; this.logger = logger; + this.mqAdminService = mqAdminService; } /// @@ -32,25 +33,48 @@ namespace PARR.API.Controllers.V1.Statistics /// /// [HttpGet(ApiRoutes.StatRabbitMq.GetQueueStats)] - public IActionResult GetQueueStats() + public async Task GetQueueStats() { - var response = new List(); + var result = await mqAdminService.GetQueuesAsync(mqSettings.Statistics.StatMqAuth); - // список очередей - foreach (var queue in mqSettings.Statistics.QueueList) - { - var result = mqService.GetQueueCount(mqSettings.Statistics.StatMqAuth, queue); + if (!result.IsSuccess) + return BadRequest(new Response(false, new List { new ErrorModel { Message = $"Ошибка при получении статистики из RabbitMQ." } })); - if (!result.IsSuccess) - { - logger.LogError(result.Exception, $"Ошибка при запросе статистики из RabbitMQ для очереди: ${queue}"); - return BadRequest(new Response(false, new List { new ErrorModel { Message = $"" } })); - } + return Ok(new Response(result.Response, true)); - response.Add(new StatRabbitMqQueueResponse { Name = queue, Consumers = result.ConsumerCount, MessagesTotal = result.Count }); - } + //var response = new List(); - return Ok(new Response>(response.OrderBy(t => t.Name).ToList(), true)); + //// список очередей + //foreach (var queue in mqSettings.Statistics.QueueList) + //{ + // var result = mqService.GetQueueCount(mqSettings.Statistics.StatMqAuth, queue); + + // if (!result.IsSuccess) + // { + // logger.LogError(result.Exception, $"Ошибка при запросе статистики из RabbitMQ для очереди: ${queue}"); + // return BadRequest(new Response(false, new List { new ErrorModel { Message = $"" } })); + // } + + // response.Add(new StatRabbitMqQueueResponse { Name = queue, Consumers = result.ConsumerCount, MessagesTotal = result.Count }); + //} + + //return Ok(new Response>(response.OrderBy(t => t.Name).ToList(), true)); + } + + + /// + /// Статистика соединений в RabbitMQ + /// + /// + [HttpGet(ApiRoutes.StatRabbitMq.GetConnectionStats)] + public async Task GetConnectionStats() + { + var result = await mqAdminService.GetConnectionsAsync(mqSettings.Statistics.StatMqAuth); + + if (!result.IsSuccess) + return BadRequest(new Response(false, new List { new ErrorModel { Message = $"Ошибка при получении статистики из RabbitMQ." } })); + + return Ok(new Response(result.Response, true)); } } } diff --git a/PARR.API/Settings/MqSettings.cs b/PARR.API/Settings/MqSettings.cs index c89cdc93..7cee6dae 100644 --- a/PARR.API/Settings/MqSettings.cs +++ b/PARR.API/Settings/MqSettings.cs @@ -18,7 +18,6 @@ namespace PARR.API.Settings public class MqStatistics { - public List QueueList { get; set; } = new List(); public StatMqAuth StatMqAuth { get; set; } = new StatMqAuth(); } diff --git a/PARR.API/appsettings.json b/PARR.API/appsettings.json index 86134484..89b3f95a 100644 --- a/PARR.API/appsettings.json +++ b/PARR.API/appsettings.json @@ -50,8 +50,7 @@ "HostName": "parr-rabbitmq", "User": "rabbit_stats", "Password": "KJHdgfjHFsdy^&$!ff331" - }, - "QueueList": [ "parr-aihit-data", "parr-espp-schedulers", "parr-espp-templates", "parr-generate-templates", "parr-orders" ] + } } }, "UserCacheSettings": { diff --git a/PARR.BLL/Domain/Mq/MqApiResult.cs b/PARR.BLL/Domain/Mq/MqApiResult.cs new file mode 100644 index 00000000..8ad233e3 --- /dev/null +++ b/PARR.BLL/Domain/Mq/MqApiResult.cs @@ -0,0 +1,14 @@ +namespace PARR.BLL.Domain.Mq +{ + /// + /// Ответ от API RabbitMQ + /// + public class MqApiResult + { + public bool IsSuccess { get; set; } + + public object? Response { get; set; } + + public Exception? Exception { get; set; } + } +} diff --git a/PARR.BLL/Domain/Mq/MqQueueCountResult.cs b/PARR.BLL/Domain/Mq/MqQueueCountResult.cs deleted file mode 100644 index b725f76c..00000000 --- a/PARR.BLL/Domain/Mq/MqQueueCountResult.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace PARR.BLL.Domain.Mq -{ - /// - /// Результат запроса кол-ва сообщений в очереди RabbitMq - /// - public class MqQueueCountResult - { - public bool IsSuccess { get;set; } - - public int Count { get; set; } - - public int ConsumerCount { get; set; } - - public Exception? Exception { get; set; } - } -} diff --git a/PARR.BLL/PARR.BLL.csproj b/PARR.BLL/PARR.BLL.csproj index fa036eaa..68fba7c3 100644 --- a/PARR.BLL/PARR.BLL.csproj +++ b/PARR.BLL/PARR.BLL.csproj @@ -10,6 +10,7 @@ + diff --git a/PARR.BLL/ParrBllInstaller.cs b/PARR.BLL/ParrBllInstaller.cs index e37f21e9..0796fbdb 100644 --- a/PARR.BLL/ParrBllInstaller.cs +++ b/PARR.BLL/ParrBllInstaller.cs @@ -18,6 +18,7 @@ namespace PARR.BLL services.AddTransient(); services.AddTransient(); + services.AddHttpClient(); services.AddTransient(); services.AddTransient(); } diff --git a/PARR.BLL/Services/Implementations/MqAdminService.cs b/PARR.BLL/Services/Implementations/MqAdminService.cs new file mode 100644 index 00000000..02ef557e --- /dev/null +++ b/PARR.BLL/Services/Implementations/MqAdminService.cs @@ -0,0 +1,78 @@ +using Microsoft.Extensions.Logging; +using PARR.BLL.Contracts.Interfaces; +using PARR.BLL.Domain.Mq; +using PARR.BLL.Services.Interfaces; +using System.Net; +using System.Net.Http.Headers; +using System.Text; +using System.Text.Json; + +namespace PARR.BLL.Services.Implementations +{ + internal class MqAdminService : IMqAdminService + { + private readonly HttpClient httpClient; + private readonly ILogger logger; + + public MqAdminService(HttpClient httpClient, ILogger logger) + { + this.httpClient = httpClient; + this.logger = logger; + } + + + public async Task GetConnectionsAsync(IMqSettings mqSettings) + { + var url = $"http://{mqSettings.HostName}:15672/api/connections"; + + return await SendRequestAsync(mqSettings, url); + } + + + public async Task GetQueuesAsync(IMqSettings mqSettings) + { + var url = $"http://{mqSettings.HostName}:15672/api/queues"; + + return await SendRequestAsync(mqSettings, url); + } + + + private async Task SendRequestAsync(IMqSettings mqSettings, string url) + { + SetAuthorizationHeaders(mqSettings); + + try + { + var result = await httpClient.GetAsync(url); + + if (result.StatusCode == HttpStatusCode.OK) + { + var content = await result.Content.ReadAsStringAsync(); + var json = JsonSerializer.Deserialize(content); + + return new MqApiResult { IsSuccess = true, Response = json }; + } + else + { + logger.LogError($"Ошибка при запросе к RabbitMq, url: {url}, StatusCode: {result.StatusCode}"); + + return new MqApiResult { IsSuccess = false }; + } + } + catch (Exception ex) + { + logger.LogError(ex, $"Ошибка при запросе к RabbitMQ, url: {url}"); + return new MqApiResult { IsSuccess = false, Exception = ex }; + } + } + + + private void SetAuthorizationHeaders(IMqSettings mqSettings) + { + httpClient.DefaultRequestHeaders.Clear(); + httpClient.DefaultRequestHeaders.Authorization = + new AuthenticationHeaderValue("Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes($"{mqSettings.User}:{mqSettings.Password}"))); + + } + } +} diff --git a/PARR.BLL/Services/Implementations/MqService.cs b/PARR.BLL/Services/Implementations/MqService.cs index 62f2b3b5..5dd994ee 100644 --- a/PARR.BLL/Services/Implementations/MqService.cs +++ b/PARR.BLL/Services/Implementations/MqService.cs @@ -155,34 +155,6 @@ namespace PARR.BLL.Services.Implementations } } - public MqQueueCountResult GetQueueCount(IMqSettings mqSettings, string queueName) - { - var factory = new ConnectionFactory - { - HostName = mqSettings.HostName, - UserName = mqSettings.User, - Password = mqSettings.Password, - }; - - try - { - using (var connection = factory.CreateConnection()) - using (var channel = connection.CreateModel()) - { - var messageCount = channel.MessageCount(queueName); - var consumerCount = channel.ConsumerCount(queueName); - - return new MqQueueCountResult { Count = (int)messageCount, ConsumerCount = (int)consumerCount, IsSuccess = true }; - } - } - catch (Exception ex) - { - logger.LogError(ex, $"Ошибка при запросе кол-ва сообщений в очереди {queueName}"); - - return new MqQueueCountResult { Count = 0, IsSuccess = false, Exception = ex }; - } - } - public void Dispose() { channel?.Close(); diff --git a/PARR.BLL/Services/Interfaces/IMqAdminService.cs b/PARR.BLL/Services/Interfaces/IMqAdminService.cs new file mode 100644 index 00000000..50407230 --- /dev/null +++ b/PARR.BLL/Services/Interfaces/IMqAdminService.cs @@ -0,0 +1,22 @@ +using PARR.BLL.Contracts.Interfaces; +using PARR.BLL.Domain.Mq; + +namespace PARR.BLL.Services.Interfaces +{ + public interface IMqAdminService + { + /// + /// Получить статистику соединений из RabbitMQ + /// + /// + /// + Task GetConnectionsAsync(IMqSettings mqSettings); + + /// + /// Получить статистику по очередям из RabbitMQ + /// + /// + /// + Task GetQueuesAsync(IMqSettings mqSettings); + } +} diff --git a/PARR.BLL/Services/Interfaces/IMqService.cs b/PARR.BLL/Services/Interfaces/IMqService.cs index c54bf4a8..d96bfb32 100644 --- a/PARR.BLL/Services/Interfaces/IMqService.cs +++ b/PARR.BLL/Services/Interfaces/IMqService.cs @@ -7,7 +7,6 @@ namespace PARR.BLL.Services.Interfaces public interface IMqService : IDisposable { - MqQueueCountResult GetQueueCount(IMqSettings mqSettings, string queueName); bool InitConsumer(IMqSettings mqSettings, MqMessageHandlerDelegate messageHandler); MqSendResult Send(IMqSettings mqSettings, string[] msgList); }