From d50cb20c9502d902311945583cd83cb94d3bd624 Mon Sep 17 00:00:00 2001 From: Mikhail Trubnikov Date: Wed, 20 Sep 2023 16:51:29 +1000 Subject: [PATCH 1/8] =?UTF-8?q?=D0=BF=D1=80=D0=BE=D0=B5=D0=BA=D1=82=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- PARR.API/Settings/MqSettings.cs | 12 +++------ PARR.BLL/Contracts/Interfaces/IMqSettings.cs | 13 ++++++++++ .../PARR.GeneratorTemplates.csproj | 9 +++++++ .../PARR.GeneratorTemplatesWorker.csproj | 13 ++++++++++ PARR.GeneratorTemplatesWorker/Program.cs | 17 ++++++++++++ .../Properties/launchSettings.json | 11 ++++++++ PARR.GeneratorTemplatesWorker/Worker.cs | 21 +++++++++++++++ .../appsettings.Development.json | 8 ++++++ .../appsettings.json | 26 +++++++++++++++++++ PARR.Worker/PARR.Worker/Program.cs | 3 --- 10 files changed, 121 insertions(+), 12 deletions(-) create mode 100644 PARR.BLL/Contracts/Interfaces/IMqSettings.cs create mode 100644 PARR.GeneratorTemplates/PARR.GeneratorTemplates.csproj create mode 100644 PARR.GeneratorTemplatesWorker/PARR.GeneratorTemplatesWorker.csproj create mode 100644 PARR.GeneratorTemplatesWorker/Program.cs create mode 100644 PARR.GeneratorTemplatesWorker/Properties/launchSettings.json create mode 100644 PARR.GeneratorTemplatesWorker/Worker.cs create mode 100644 PARR.GeneratorTemplatesWorker/appsettings.Development.json create mode 100644 PARR.GeneratorTemplatesWorker/appsettings.json diff --git a/PARR.API/Settings/MqSettings.cs b/PARR.API/Settings/MqSettings.cs index db4d8e7e..4efd1fff 100644 --- a/PARR.API/Settings/MqSettings.cs +++ b/PARR.API/Settings/MqSettings.cs @@ -1,4 +1,6 @@ -namespace PARR.API.Settings +using PARR.BLL.Contracts.Interfaces; + +namespace PARR.API.Settings { public class MqSettings { @@ -12,12 +14,4 @@ public string User { get; set; } = string.Empty; public string Password { get; set; } = string.Empty; } - - public interface IMqSettings - { - string HostName { get; set; } - string QueueName { get; set; } - string User { get; set; } - string Password { get; set; } - } } diff --git a/PARR.BLL/Contracts/Interfaces/IMqSettings.cs b/PARR.BLL/Contracts/Interfaces/IMqSettings.cs new file mode 100644 index 00000000..ef0536c9 --- /dev/null +++ b/PARR.BLL/Contracts/Interfaces/IMqSettings.cs @@ -0,0 +1,13 @@ +namespace PARR.BLL.Contracts.Interfaces +{ + /// + /// Поля настроек MQ, используется для appsettings.json + /// + public interface IMqSettings + { + string HostName { get; set; } + string QueueName { get; set; } + string User { get; set; } + string Password { get; set; } + } +} diff --git a/PARR.GeneratorTemplates/PARR.GeneratorTemplates.csproj b/PARR.GeneratorTemplates/PARR.GeneratorTemplates.csproj new file mode 100644 index 00000000..cfadb03d --- /dev/null +++ b/PARR.GeneratorTemplates/PARR.GeneratorTemplates.csproj @@ -0,0 +1,9 @@ + + + + net7.0 + enable + enable + + + diff --git a/PARR.GeneratorTemplatesWorker/PARR.GeneratorTemplatesWorker.csproj b/PARR.GeneratorTemplatesWorker/PARR.GeneratorTemplatesWorker.csproj new file mode 100644 index 00000000..245b1a44 --- /dev/null +++ b/PARR.GeneratorTemplatesWorker/PARR.GeneratorTemplatesWorker.csproj @@ -0,0 +1,13 @@ + + + + net7.0 + enable + enable + dotnet-PARR.GeneratorTemplatesWorker-deb14157-f207-44e0-8d4b-963c6066a75e + + + + + + diff --git a/PARR.GeneratorTemplatesWorker/Program.cs b/PARR.GeneratorTemplatesWorker/Program.cs new file mode 100644 index 00000000..a3ea5e29 --- /dev/null +++ b/PARR.GeneratorTemplatesWorker/Program.cs @@ -0,0 +1,17 @@ +using PARR.GeneratorTemplatesWorker; +using Serilog; + +IHost host = Host.CreateDefaultBuilder(args) + .ConfigureServices(services => + { + services.AddHostedService(); + }) + .UseSerilog((hostContext, services, config) => + { + config + .WriteTo.Console() + .ReadFrom.Configuration(hostContext.Configuration); + }) + .Build(); + +host.Run(); diff --git a/PARR.GeneratorTemplatesWorker/Properties/launchSettings.json b/PARR.GeneratorTemplatesWorker/Properties/launchSettings.json new file mode 100644 index 00000000..06416c77 --- /dev/null +++ b/PARR.GeneratorTemplatesWorker/Properties/launchSettings.json @@ -0,0 +1,11 @@ +{ + "profiles": { + "PARR.GeneratorTemplatesWorker": { + "commandName": "Project", + "dotnetRunMessages": true, + "environmentVariables": { + "DOTNET_ENVIRONMENT": "Development" + } + } + } +} diff --git a/PARR.GeneratorTemplatesWorker/Worker.cs b/PARR.GeneratorTemplatesWorker/Worker.cs new file mode 100644 index 00000000..9baaa069 --- /dev/null +++ b/PARR.GeneratorTemplatesWorker/Worker.cs @@ -0,0 +1,21 @@ +namespace PARR.GeneratorTemplatesWorker +{ + public class Worker : BackgroundService + { + private readonly ILogger _logger; + + public Worker(ILogger logger) + { + _logger = logger; + } + + protected override async Task ExecuteAsync(CancellationToken stoppingToken) + { + while (!stoppingToken.IsCancellationRequested) + { + _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now); + await Task.Delay(1000, stoppingToken); + } + } + } +} \ No newline at end of file diff --git a/PARR.GeneratorTemplatesWorker/appsettings.Development.json b/PARR.GeneratorTemplatesWorker/appsettings.Development.json new file mode 100644 index 00000000..b2dcdb67 --- /dev/null +++ b/PARR.GeneratorTemplatesWorker/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.Hosting.Lifetime": "Information" + } + } +} diff --git a/PARR.GeneratorTemplatesWorker/appsettings.json b/PARR.GeneratorTemplatesWorker/appsettings.json new file mode 100644 index 00000000..d250dadc --- /dev/null +++ b/PARR.GeneratorTemplatesWorker/appsettings.json @@ -0,0 +1,26 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "Serilog": { + "MinimumLevel": { + "Default": "Debug", + "Override": { + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Debug" + } + }, + "WriteTo": [ + { + "Name": "File", + "Args": { + "path": "log/log-.txt", + "rollingInterval": "Day" + } + } + ] + } +} diff --git a/PARR.Worker/PARR.Worker/Program.cs b/PARR.Worker/PARR.Worker/Program.cs index 7432b953..bdaf9c9b 100644 --- a/PARR.Worker/PARR.Worker/Program.cs +++ b/PARR.Worker/PARR.Worker/Program.cs @@ -1,7 +1,4 @@ -using Microsoft.EntityFrameworkCore; using PARR.AIHIT; -using PARR.DAL; -using PARR.Mail; using PARR.Worker; using PARR.Worker.Settings; using Serilog; From 096a990669d0c8fa741dbd2a1a69580bdc215912 Mon Sep 17 00:00:00 2001 From: Mikhail Trubnikov Date: Thu, 21 Sep 2023 09:37:36 +1000 Subject: [PATCH 2/8] Bll MqService --- PARR.API.sln | 14 ++++- .../V1/GeneratorTemplateController.cs | 19 ++++--- PARR.API/Installers/ApiServicesInstaller.cs | 1 - .../Interfaces/IMqGeneratorTemplateService.cs | 7 --- PARR.BLL/Domain/Mq/MqSendResult.cs | 18 ++++++ PARR.BLL/PARR.BLL.csproj | 1 + PARR.BLL/ParrBllInstaller.cs | 1 + .../Services/Implementations/MqService.cs | 55 ++++++++++++------- PARR.BLL/Services/Interfaces/IMqService.cs | 10 ++++ .../GeneratorTemplateInstaller.cs | 16 ++++++ .../PARR.GeneratorTemplatesWorker.csproj | 5 ++ 11 files changed, 109 insertions(+), 38 deletions(-) delete mode 100644 PARR.API/Services/Interfaces/IMqGeneratorTemplateService.cs create mode 100644 PARR.BLL/Domain/Mq/MqSendResult.cs rename PARR.API/Services/Implementations/MqGeneratorTemplateService.cs => PARR.BLL/Services/Implementations/MqService.cs (52%) create mode 100644 PARR.BLL/Services/Interfaces/IMqService.cs create mode 100644 PARR.GeneratorTemplates/GeneratorTemplateInstaller.cs diff --git a/PARR.API.sln b/PARR.API.sln index d731ecfe..ce7ca48a 100644 --- a/PARR.API.sln +++ b/PARR.API.sln @@ -28,7 +28,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PARR.EsppTemplateSyncWorker EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PARR.EsppTemplateSync", "PARR.EsppTemplateSync\PARR.EsppTemplateSync.csproj", "{39FD9AAD-0792-46B2-A935-42486A993C32}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PARR.MockData", "PARR.MockData\PARR.MockData.csproj", "{B02E5B16-59BD-4F02-9CC4-6873409DBD84}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PARR.MockData", "PARR.MockData\PARR.MockData.csproj", "{B02E5B16-59BD-4F02-9CC4-6873409DBD84}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PARR.GeneratorTemplates", "PARR.GeneratorTemplates\PARR.GeneratorTemplates.csproj", "{79EC7AD8-9A16-4806-881A-E5632C48C461}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PARR.GeneratorTemplatesWorker", "PARR.GeneratorTemplatesWorker\PARR.GeneratorTemplatesWorker.csproj", "{BE11D005-D3FE-4F29-93A2-7379E729C78D}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -74,6 +78,14 @@ Global {B02E5B16-59BD-4F02-9CC4-6873409DBD84}.Debug|Any CPU.Build.0 = Debug|Any CPU {B02E5B16-59BD-4F02-9CC4-6873409DBD84}.Release|Any CPU.ActiveCfg = Release|Any CPU {B02E5B16-59BD-4F02-9CC4-6873409DBD84}.Release|Any CPU.Build.0 = Release|Any CPU + {79EC7AD8-9A16-4806-881A-E5632C48C461}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {79EC7AD8-9A16-4806-881A-E5632C48C461}.Debug|Any CPU.Build.0 = Debug|Any CPU + {79EC7AD8-9A16-4806-881A-E5632C48C461}.Release|Any CPU.ActiveCfg = Release|Any CPU + {79EC7AD8-9A16-4806-881A-E5632C48C461}.Release|Any CPU.Build.0 = Release|Any CPU + {BE11D005-D3FE-4F29-93A2-7379E729C78D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BE11D005-D3FE-4F29-93A2-7379E729C78D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BE11D005-D3FE-4F29-93A2-7379E729C78D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BE11D005-D3FE-4F29-93A2-7379E729C78D}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/PARR.API/Controllers/V1/GeneratorTemplateController.cs b/PARR.API/Controllers/V1/GeneratorTemplateController.cs index 8deb8b11..a3438f85 100644 --- a/PARR.API/Controllers/V1/GeneratorTemplateController.cs +++ b/PARR.API/Controllers/V1/GeneratorTemplateController.cs @@ -5,7 +5,9 @@ using PARR.API.Contracts.V1.Requests; using PARR.API.Contracts.V1.Responses.Base; using PARR.API.Controllers.V1.Base; using PARR.API.Services.Interfaces; +using PARR.API.Settings; using PARR.BLL.Domain.Mq; +using PARR.BLL.Services.Interfaces; using System.Text.Json; namespace PARR.API.Controllers.V1 @@ -13,18 +15,21 @@ namespace PARR.API.Controllers.V1 public class GeneratorTemplateController : BaseApiController { private readonly IValidator validator; - private readonly IMqGeneratorTemplateService mqGeneratorTemplateService; + private readonly IMqService mqService; private readonly IUriService uriService; + private readonly MqSettings mqSettings; public GeneratorTemplateController( IValidator validator, - IMqGeneratorTemplateService mqGeneratorTemplateService, - IUriService uriService + IMqService mqService, + IUriService uriService, + MqSettings mqSettings ) { this.validator = validator; - this.mqGeneratorTemplateService = mqGeneratorTemplateService; + this.mqService = mqService; this.uriService = uriService; + this.mqSettings = mqSettings; } /// @@ -38,8 +43,6 @@ namespace PARR.API.Controllers.V1 if (!resultValidate.IsValid) return BadRequest(new Response(resultValidate.Errors)); - // Todo: проверить есть ли в бд такие ворк и апп - var obj = new GeneratorTemplateMq { Action = request.Action, @@ -50,9 +53,9 @@ namespace PARR.API.Controllers.V1 var msg = JsonSerializer.Serialize(obj); - var result = mqGeneratorTemplateService.SendMsg(msg); + var result = mqService.Send(mqSettings.GenerateTemplates, new[] { msg }); - if (!result) + if (!result.IsSuccess) return BadRequest(new Response(false, new List { new ErrorModel { Message = $"Ошибка при отправке данных." } })); var createdUri = uriService.GetAllUri(ApiRoutes.Template.GetAll); diff --git a/PARR.API/Installers/ApiServicesInstaller.cs b/PARR.API/Installers/ApiServicesInstaller.cs index a097cd3a..4ff3bc14 100644 --- a/PARR.API/Installers/ApiServicesInstaller.cs +++ b/PARR.API/Installers/ApiServicesInstaller.cs @@ -20,7 +20,6 @@ namespace PARR.API.Installers }); services.AddTransient(); - services.AddTransient(); diff --git a/PARR.API/Services/Interfaces/IMqGeneratorTemplateService.cs b/PARR.API/Services/Interfaces/IMqGeneratorTemplateService.cs deleted file mode 100644 index 51d3361c..00000000 --- a/PARR.API/Services/Interfaces/IMqGeneratorTemplateService.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace PARR.API.Services.Interfaces -{ - public interface IMqGeneratorTemplateService - { - bool SendMsg(string msg); - } -} diff --git a/PARR.BLL/Domain/Mq/MqSendResult.cs b/PARR.BLL/Domain/Mq/MqSendResult.cs new file mode 100644 index 00000000..b719b484 --- /dev/null +++ b/PARR.BLL/Domain/Mq/MqSendResult.cs @@ -0,0 +1,18 @@ +namespace PARR.BLL.Domain.Mq +{ + /// + /// Результат отправки очереди в MQ + /// + public class MqSendResult + { + /// + /// Результат отправки + /// + public bool IsSuccess { get; set; } + + /// + /// Неотправленные сообщения + /// + public string[]? NotSendMessages { get; set; } + } +} diff --git a/PARR.BLL/PARR.BLL.csproj b/PARR.BLL/PARR.BLL.csproj index 1c2edf9c..fa036eaa 100644 --- a/PARR.BLL/PARR.BLL.csproj +++ b/PARR.BLL/PARR.BLL.csproj @@ -11,6 +11,7 @@ + diff --git a/PARR.BLL/ParrBllInstaller.cs b/PARR.BLL/ParrBllInstaller.cs index 782a45e0..0c34489d 100644 --- a/PARR.BLL/ParrBllInstaller.cs +++ b/PARR.BLL/ParrBllInstaller.cs @@ -16,6 +16,7 @@ namespace PARR.BLL services.AddTransient(); + services.AddTransient(); } } } diff --git a/PARR.API/Services/Implementations/MqGeneratorTemplateService.cs b/PARR.BLL/Services/Implementations/MqService.cs similarity index 52% rename from PARR.API/Services/Implementations/MqGeneratorTemplateService.cs rename to PARR.BLL/Services/Implementations/MqService.cs index 245efa0d..6d74876d 100644 --- a/PARR.API/Services/Implementations/MqGeneratorTemplateService.cs +++ b/PARR.BLL/Services/Implementations/MqService.cs @@ -1,30 +1,34 @@ -using PARR.API.Services.Interfaces; -using PARR.API.Settings; +using Microsoft.Extensions.Logging; +using PARR.BLL.Contracts.Interfaces; +using PARR.BLL.Domain.Mq; +using PARR.BLL.Services.Interfaces; using RabbitMQ.Client; using System.Text; -namespace PARR.API.Services.Implementations +namespace PARR.BLL.Services.Implementations { - public class MqGeneratorTemplateService : IMqGeneratorTemplateService + internal class MqService : IMqService { - private readonly MqSettings mqSettings; - private readonly ILogger logger; + private readonly ILogger logger; - public MqGeneratorTemplateService(MqSettings mqSettings, ILogger logger) + public MqService(ILogger logger) { - this.mqSettings = mqSettings; this.logger = logger; } - public bool SendMsg(string msg) + public MqSendResult Send(IMqSettings mqSettings, string[] msgList) { var factory = new ConnectionFactory { - HostName = mqSettings.GenerateTemplates.HostName, - UserName = mqSettings.GenerateTemplates.User, - Password = mqSettings.GenerateTemplates.Password + HostName = mqSettings.HostName, + UserName = mqSettings.User, + Password = mqSettings.Password }; + // индекс текущей отправки в очередь из массива msgList + // нужен для формирования списка неотправленных сообщений + var sendIdx = 0; + try { using (var connection = factory.CreateConnection()) @@ -41,33 +45,42 @@ namespace PARR.API.Services.Implementations //В целом эти параметры можно посмотреть в админке RabbitMQ channel.QueueDeclare( - queue: mqSettings.GenerateTemplates.QueueName, + queue: mqSettings.QueueName, durable: true, exclusive: false, autoDelete: false, arguments: args ); - var body = Encoding.UTF8.GetBytes(msg); - var props = channel.CreateBasicProperties(); //храним на диске props.DeliveryMode = 2; //время жизни, мс //props.Expiration = "60000"; - channel.BasicPublish(exchange: "", routingKey: mqSettings.GenerateTemplates.QueueName, basicProperties: props, body: body); + foreach (var msg in msgList) + { + var body = Encoding.UTF8.GetBytes(msg); + channel.BasicPublish(exchange: "", routingKey: mqSettings.QueueName, basicProperties: props, body: body); + + sendIdx++; + logger.LogDebug($"Отправлено сообщение в очередь: {mqSettings.QueueName}, {msg}"); + } } - logger.LogDebug($"Отправлено сообщение в очередь: {mqSettings.GenerateTemplates.QueueName}, {msg}"); - - return true; + return new MqSendResult { IsSuccess = true }; } catch (Exception ex) { - logger.LogError(ex, $"Ошибка при отправке сообщения в очередь {mqSettings.GenerateTemplates.QueueName}, {msg}"); + var notSendMsg = new List(); - return false; + // формируем список неотправленных элементов + for (int i = sendIdx; i < msgList.Length; i++) + notSendMsg.Add(msgList[i]); + + logger.LogError(ex, $"Ошибка при отправке сообщения в очередь {mqSettings.QueueName}, {string.Join(',', notSendMsg)}"); + + return new MqSendResult { IsSuccess = false, NotSendMessages = notSendMsg.ToArray() }; } } } diff --git a/PARR.BLL/Services/Interfaces/IMqService.cs b/PARR.BLL/Services/Interfaces/IMqService.cs new file mode 100644 index 00000000..ab825e3e --- /dev/null +++ b/PARR.BLL/Services/Interfaces/IMqService.cs @@ -0,0 +1,10 @@ +using PARR.BLL.Contracts.Interfaces; +using PARR.BLL.Domain.Mq; + +namespace PARR.BLL.Services.Interfaces +{ + public interface IMqService + { + MqSendResult Send(IMqSettings mqSettings, string[] msgList); + } +} diff --git a/PARR.GeneratorTemplates/GeneratorTemplateInstaller.cs b/PARR.GeneratorTemplates/GeneratorTemplateInstaller.cs new file mode 100644 index 00000000..4007a483 --- /dev/null +++ b/PARR.GeneratorTemplates/GeneratorTemplateInstaller.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace PARR.GeneratorTemplates +{ + public static class GeneratorTemplateInstaller + { + //public static void InstallGeneratorTemplateServices(this IServiceCollection services, IConfiguration configuration) + //{ + + //} + } +} diff --git a/PARR.GeneratorTemplatesWorker/PARR.GeneratorTemplatesWorker.csproj b/PARR.GeneratorTemplatesWorker/PARR.GeneratorTemplatesWorker.csproj index 245b1a44..3385ae46 100644 --- a/PARR.GeneratorTemplatesWorker/PARR.GeneratorTemplatesWorker.csproj +++ b/PARR.GeneratorTemplatesWorker/PARR.GeneratorTemplatesWorker.csproj @@ -8,6 +8,11 @@ + + + + + From c7acfd153dbccf94030c6d8b0e6c12f3f0a62505 Mon Sep 17 00:00:00 2001 From: Mikhail Trubnikov Date: Thu, 21 Sep 2023 15:21:33 +1000 Subject: [PATCH 3/8] Mq Consumer --- .../Services/Implementations/MqService.cs | 59 +++++++++++++++++++ PARR.BLL/Services/Interfaces/IMqService.cs | 5 ++ PARR.GeneratorTemplates/GeneratorTemplate.cs | 39 ++++++++++++ .../GeneratorTemplateInstaller.cs | 41 ++++++++++--- PARR.GeneratorTemplates/IGeneratorTemplate.cs | 8 +++ .../PARR.GeneratorTemplates.csproj | 5 ++ .../Settings/MqSettings.cs | 12 ++++ .../PARR.GeneratorTemplatesWorker.csproj | 4 ++ PARR.GeneratorTemplatesWorker/Program.cs | 19 +++++- PARR.GeneratorTemplatesWorker/Worker.cs | 25 ++++++-- .../appsettings.Development.json | 3 + .../appsettings.json | 6 ++ 12 files changed, 211 insertions(+), 15 deletions(-) create mode 100644 PARR.GeneratorTemplates/GeneratorTemplate.cs create mode 100644 PARR.GeneratorTemplates/IGeneratorTemplate.cs create mode 100644 PARR.GeneratorTemplates/Settings/MqSettings.cs diff --git a/PARR.BLL/Services/Implementations/MqService.cs b/PARR.BLL/Services/Implementations/MqService.cs index 6d74876d..ff0882f3 100644 --- a/PARR.BLL/Services/Implementations/MqService.cs +++ b/PARR.BLL/Services/Implementations/MqService.cs @@ -3,6 +3,7 @@ using PARR.BLL.Contracts.Interfaces; using PARR.BLL.Domain.Mq; using PARR.BLL.Services.Interfaces; using RabbitMQ.Client; +using RabbitMQ.Client.Events; using System.Text; namespace PARR.BLL.Services.Implementations @@ -11,6 +12,8 @@ namespace PARR.BLL.Services.Implementations { private readonly ILogger logger; + public event ReceivedHandler? Received; + public MqService(ILogger logger) { this.logger = logger; @@ -83,5 +86,61 @@ namespace PARR.BLL.Services.Implementations return new MqSendResult { IsSuccess = false, NotSendMessages = notSendMsg.ToArray() }; } } + + + //TODO: rename ListenQueue + public void InitConsumer(IMqSettings mqSettings) + { + logger.LogInformation($"Устанавливаю соединение с RabbitMQ: {mqSettings.HostName}, {mqSettings.QueueName}"); + + var facory = new ConnectionFactory + { + HostName = mqSettings.HostName, + UserName = mqSettings.User, + Password = mqSettings.Password, + AutomaticRecoveryEnabled = true, + DispatchConsumersAsync = true + }; + + try + { + var connection = facory.CreateConnection(); + var channel = connection.CreateModel(); + + var args = new Dictionary { { "x-queue-mode", "lazy" } }; + + channel.QueueDeclare( + queue: mqSettings.QueueName, + durable: true, + exclusive: false, + autoDelete: false, + arguments: args + ); + + logger.LogInformation($"Соединение с RabbitMQ установлено: {mqSettings.HostName}, {mqSettings.QueueName}"); + + + var consumer = new AsyncEventingBasicConsumer(channel); + consumer.Received += async (ch, ea) => + { + var content = Encoding.UTF8.GetString(ea.Body.ToArray()); + logger.LogDebug($"Получено сообщение: {content}"); + + //https://metanit.com/sharp/tutorial/3.14.php + Received?.Invoke(content); + + channel.BasicAck(ea.DeliveryTag, false); + await Task.Yield(); + }; + + channel.BasicConsume(mqSettings.QueueName, false, consumer); + + } + catch (Exception ex) + { + logger.LogError(ex, $"Ошибка при получении сообщений из очереди: {mqSettings.HostName}, {mqSettings.QueueName}"); + } + } + } } diff --git a/PARR.BLL/Services/Interfaces/IMqService.cs b/PARR.BLL/Services/Interfaces/IMqService.cs index ab825e3e..6f7cc5ba 100644 --- a/PARR.BLL/Services/Interfaces/IMqService.cs +++ b/PARR.BLL/Services/Interfaces/IMqService.cs @@ -3,8 +3,13 @@ using PARR.BLL.Domain.Mq; namespace PARR.BLL.Services.Interfaces { + public delegate void ReceivedHandler(string msg); + public interface IMqService { + event ReceivedHandler? Received; + + void InitConsumer(IMqSettings mqSettings); MqSendResult Send(IMqSettings mqSettings, string[] msgList); } } diff --git a/PARR.GeneratorTemplates/GeneratorTemplate.cs b/PARR.GeneratorTemplates/GeneratorTemplate.cs new file mode 100644 index 00000000..147eef2f --- /dev/null +++ b/PARR.GeneratorTemplates/GeneratorTemplate.cs @@ -0,0 +1,39 @@ +using Microsoft.Extensions.Logging; +using PARR.BLL.Services.Interfaces; +using PARR.GeneratorTemplates.Settings; + +namespace PARR.GeneratorTemplates +{ + internal class GeneratorTemplate : IGeneratorTemplate + { + private readonly MqSettings mqSettings; + private readonly IMqService mqService; + private readonly ILogger logger; + + public GeneratorTemplate( + MqSettings mqSettings, + IMqService mqService, + ILogger logger + ) + { + this.mqSettings = mqSettings; + this.mqService = mqService; + this.logger = logger; + } + + public void Start() + { + mqService.InitConsumer(mqSettings); + + mqService.Received += (msg) => + { + logger.LogInformation($"Привет откуда надо!!! ${msg}"); + }; + } + + public void Stop() + { + + } + } +} diff --git a/PARR.GeneratorTemplates/GeneratorTemplateInstaller.cs b/PARR.GeneratorTemplates/GeneratorTemplateInstaller.cs index 4007a483..4b8d1acf 100644 --- a/PARR.GeneratorTemplates/GeneratorTemplateInstaller.cs +++ b/PARR.GeneratorTemplates/GeneratorTemplateInstaller.cs @@ -1,16 +1,41 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using PARR.BLL; +using PARR.DAL; +using PARR.GeneratorTemplates.Settings; namespace PARR.GeneratorTemplates { public static class GeneratorTemplateInstaller { - //public static void InstallGeneratorTemplateServices(this IServiceCollection services, IConfiguration configuration) - //{ + //1 + public static void InstallGeneratorTemplateServices(this IServiceCollection services, IConfiguration configuration) + { + services.InstallDalServices(configuration); + services.InstallBllServices(configuration); + + var mqSettings = new MqSettings(); + configuration.GetSection(nameof(MqSettings)).Bind(mqSettings); + services.AddSingleton(mqSettings); + + //add other services + services.AddTransient(); + } + + //2 + public static IConfigurationBuilder AddGeneratorTemplateConfigurations(this IConfigurationBuilder builder, IServiceCollection services) + { + builder.AddDalConfigurations(services); + + return builder; + } + + //3 + public static void AddGeneratorTemplateSettings(this IServiceCollection services, IConfiguration configuration) + { + services.AddDallSettings(configuration); + } + - //} } } diff --git a/PARR.GeneratorTemplates/IGeneratorTemplate.cs b/PARR.GeneratorTemplates/IGeneratorTemplate.cs new file mode 100644 index 00000000..89c2f408 --- /dev/null +++ b/PARR.GeneratorTemplates/IGeneratorTemplate.cs @@ -0,0 +1,8 @@ +namespace PARR.GeneratorTemplates +{ + public interface IGeneratorTemplate + { + void Start(); + void Stop(); + } +} diff --git a/PARR.GeneratorTemplates/PARR.GeneratorTemplates.csproj b/PARR.GeneratorTemplates/PARR.GeneratorTemplates.csproj index cfadb03d..21190861 100644 --- a/PARR.GeneratorTemplates/PARR.GeneratorTemplates.csproj +++ b/PARR.GeneratorTemplates/PARR.GeneratorTemplates.csproj @@ -6,4 +6,9 @@ enable + + + + + diff --git a/PARR.GeneratorTemplates/Settings/MqSettings.cs b/PARR.GeneratorTemplates/Settings/MqSettings.cs new file mode 100644 index 00000000..97d78349 --- /dev/null +++ b/PARR.GeneratorTemplates/Settings/MqSettings.cs @@ -0,0 +1,12 @@ +using PARR.BLL.Contracts.Interfaces; + +namespace PARR.GeneratorTemplates.Settings +{ + internal class MqSettings : IMqSettings + { + public string HostName { get; set; } = string.Empty; + public string QueueName { get; set; } = string.Empty; + public string User { get; set; } = string.Empty; + public string Password { get; set; } = string.Empty; + } +} diff --git a/PARR.GeneratorTemplatesWorker/PARR.GeneratorTemplatesWorker.csproj b/PARR.GeneratorTemplatesWorker/PARR.GeneratorTemplatesWorker.csproj index 3385ae46..bb916995 100644 --- a/PARR.GeneratorTemplatesWorker/PARR.GeneratorTemplatesWorker.csproj +++ b/PARR.GeneratorTemplatesWorker/PARR.GeneratorTemplatesWorker.csproj @@ -15,4 +15,8 @@ + + + + diff --git a/PARR.GeneratorTemplatesWorker/Program.cs b/PARR.GeneratorTemplatesWorker/Program.cs index a3ea5e29..b9739fda 100644 --- a/PARR.GeneratorTemplatesWorker/Program.cs +++ b/PARR.GeneratorTemplatesWorker/Program.cs @@ -1,9 +1,26 @@ +using PARR.GeneratorTemplates; using PARR.GeneratorTemplatesWorker; using Serilog; + IHost host = Host.CreateDefaultBuilder(args) - .ConfigureServices(services => + .ConfigureServices((hostContext, services) => { + services.InstallGeneratorTemplateServices(hostContext.Configuration); + //hostContext.Configuration.AddGeneratorTemplateConfigurations(services); + //services.AddGeneratorTemplateSettings(hostContext.Configuration); + + //services.AddHostedService(); + }) + //.ConfigureAppConfiguration((hostContext, configBuilder) => + //{ + //TODO: !!! !!! !!! не смог прикрутить AddGeneratorTemplateConfigurations, не могу прокинуть туда сервисы + // configBuilder.AddGeneratorTemplateConfigurations(hostContext.Services); + //}) + .ConfigureServices((hostContext, services) => + { + //services.AddGeneratorTemplateSettings(hostContext.Configuration); + services.AddHostedService(); }) .UseSerilog((hostContext, services, config) => diff --git a/PARR.GeneratorTemplatesWorker/Worker.cs b/PARR.GeneratorTemplatesWorker/Worker.cs index 9baaa069..7f1ec28a 100644 --- a/PARR.GeneratorTemplatesWorker/Worker.cs +++ b/PARR.GeneratorTemplatesWorker/Worker.cs @@ -1,21 +1,34 @@ +using PARR.GeneratorTemplates; + namespace PARR.GeneratorTemplatesWorker { public class Worker : BackgroundService { private readonly ILogger _logger; + private readonly IGeneratorTemplate generatorTemplate; - public Worker(ILogger logger) + public Worker(ILogger logger, IGeneratorTemplate generatorTemplate) { _logger = logger; + this.generatorTemplate = generatorTemplate; } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { - while (!stoppingToken.IsCancellationRequested) - { - _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now); - await Task.Delay(1000, stoppingToken); - } + // todo: обернуть в таск? + generatorTemplate.Start(); + //while (!stoppingToken.IsCancellationRequested) + //{ + // _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now); + // await Task.Delay(1000, stoppingToken); + //} + } + + public override Task StopAsync(CancellationToken cancellationToken) + { + generatorTemplate.Stop(); + + return base.StopAsync(cancellationToken); } } } \ No newline at end of file diff --git a/PARR.GeneratorTemplatesWorker/appsettings.Development.json b/PARR.GeneratorTemplatesWorker/appsettings.Development.json index b2dcdb67..992d2719 100644 --- a/PARR.GeneratorTemplatesWorker/appsettings.Development.json +++ b/PARR.GeneratorTemplatesWorker/appsettings.Development.json @@ -4,5 +4,8 @@ "Default": "Information", "Microsoft.Hosting.Lifetime": "Information" } + }, + "MqSettings": { + "HostName": "10.99.253.216" } } diff --git a/PARR.GeneratorTemplatesWorker/appsettings.json b/PARR.GeneratorTemplatesWorker/appsettings.json index d250dadc..a28563b8 100644 --- a/PARR.GeneratorTemplatesWorker/appsettings.json +++ b/PARR.GeneratorTemplatesWorker/appsettings.json @@ -22,5 +22,11 @@ } } ] + }, + "MqSettings": { + "HostName": "parr-rabbitmq", + "QueueName": "parr-generate-templates", + "User": "generate_templates_worker", + "Password": "Dhgdf%d&609sssa" } } From 9ff7421d5ffa507e017cebdce78c26bb04967c42 Mon Sep 17 00:00:00 2001 From: Mikhail Trubnikov Date: Thu, 21 Sep 2023 15:37:38 +1000 Subject: [PATCH 4/8] fix mq --- PARR.BLL/Services/Implementations/MqService.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/PARR.BLL/Services/Implementations/MqService.cs b/PARR.BLL/Services/Implementations/MqService.cs index ff0882f3..081f142e 100644 --- a/PARR.BLL/Services/Implementations/MqService.cs +++ b/PARR.BLL/Services/Implementations/MqService.cs @@ -67,7 +67,7 @@ namespace PARR.BLL.Services.Implementations channel.BasicPublish(exchange: "", routingKey: mqSettings.QueueName, basicProperties: props, body: body); sendIdx++; - logger.LogDebug($"Отправлено сообщение в очередь: {mqSettings.QueueName}, {msg}"); + logger.LogDebug($"Отправлено сообщение в очередь: {mqSettings.HostName} {mqSettings.QueueName}, {msg}"); } } @@ -81,7 +81,7 @@ namespace PARR.BLL.Services.Implementations for (int i = sendIdx; i < msgList.Length; i++) notSendMsg.Add(msgList[i]); - logger.LogError(ex, $"Ошибка при отправке сообщения в очередь {mqSettings.QueueName}, {string.Join(',', notSendMsg)}"); + logger.LogError(ex, $"Ошибка при отправке сообщения в очередь {mqSettings.HostName} {mqSettings.QueueName}, {string.Join(',', notSendMsg)}"); return new MqSendResult { IsSuccess = false, NotSendMessages = notSendMsg.ToArray() }; } @@ -104,8 +104,8 @@ namespace PARR.BLL.Services.Implementations try { - var connection = facory.CreateConnection(); - var channel = connection.CreateModel(); + using var connection = facory.CreateConnection(); + using var channel = connection.CreateModel(); var args = new Dictionary { { "x-queue-mode", "lazy" } }; From 232426ce5e3677367f3dde152196008a828a1c03 Mon Sep 17 00:00:00 2001 From: Mikhail Trubnikov Date: Thu, 21 Sep 2023 15:44:01 +1000 Subject: [PATCH 5/8] api mq fix --- PARR.API/appsettings.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PARR.API/appsettings.json b/PARR.API/appsettings.json index 513c496c..5176f9cc 100644 --- a/PARR.API/appsettings.json +++ b/PARR.API/appsettings.json @@ -39,7 +39,7 @@ }, "MqSettings": { "GenerateTemplates": { - "HostName": "parr-rabbitmq", + "HostName": "parr-espp_parr-rabbitmq", "QueueName": "parr-generate-templates", "User": "generate_templates_api", "Password": "DHhjgdsf*&%95" From 109ac9d70b8e6df4751e60fd29479d726964fd19 Mon Sep 17 00:00:00 2001 From: Mikhail Trubnikov Date: Thu, 21 Sep 2023 15:53:37 +1000 Subject: [PATCH 6/8] mq --- PARR.API/appsettings.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PARR.API/appsettings.json b/PARR.API/appsettings.json index 5176f9cc..f15eb375 100644 --- a/PARR.API/appsettings.json +++ b/PARR.API/appsettings.json @@ -39,7 +39,7 @@ }, "MqSettings": { "GenerateTemplates": { - "HostName": "parr-espp_parr-rabbitmq", + "HostName": "10.99.253.216", "QueueName": "parr-generate-templates", "User": "generate_templates_api", "Password": "DHhjgdsf*&%95" From cff93be36adad681a01a0d6d04a3228566e1a107 Mon Sep 17 00:00:00 2001 From: Mikhail Trubnikov Date: Thu, 21 Sep 2023 16:38:38 +1000 Subject: [PATCH 7/8] mq dispose --- .../Services/Implementations/MqService.cs | 19 ++++++++++++++++--- PARR.BLL/Services/Interfaces/IMqService.cs | 2 +- PARR.GeneratorTemplates/GeneratorTemplate.cs | 9 ++++++--- .../appsettings.json | 2 +- 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/PARR.BLL/Services/Implementations/MqService.cs b/PARR.BLL/Services/Implementations/MqService.cs index 081f142e..12720100 100644 --- a/PARR.BLL/Services/Implementations/MqService.cs +++ b/PARR.BLL/Services/Implementations/MqService.cs @@ -12,6 +12,9 @@ namespace PARR.BLL.Services.Implementations { private readonly ILogger logger; + private IConnection? connection; + private IModel? channel; + public event ReceivedHandler? Received; public MqService(ILogger logger) @@ -88,7 +91,6 @@ namespace PARR.BLL.Services.Implementations } - //TODO: rename ListenQueue public void InitConsumer(IMqSettings mqSettings) { logger.LogInformation($"Устанавливаю соединение с RabbitMQ: {mqSettings.HostName}, {mqSettings.QueueName}"); @@ -104,8 +106,11 @@ namespace PARR.BLL.Services.Implementations try { - using var connection = facory.CreateConnection(); - using var channel = connection.CreateModel(); + //using var connection = facory.CreateConnection(); + //using var channel = connection.CreateModel(); + + connection = facory.CreateConnection(); + channel = connection.CreateModel(); var args = new Dictionary { { "x-queue-mode", "lazy" } }; @@ -142,5 +147,13 @@ namespace PARR.BLL.Services.Implementations } } + public void Dispose() + { + channel?.Close(); + connection?.Close(); + + channel?.Dispose(); + connection?.Dispose(); + } } } diff --git a/PARR.BLL/Services/Interfaces/IMqService.cs b/PARR.BLL/Services/Interfaces/IMqService.cs index 6f7cc5ba..3db517c6 100644 --- a/PARR.BLL/Services/Interfaces/IMqService.cs +++ b/PARR.BLL/Services/Interfaces/IMqService.cs @@ -5,7 +5,7 @@ namespace PARR.BLL.Services.Interfaces { public delegate void ReceivedHandler(string msg); - public interface IMqService + public interface IMqService : IDisposable { event ReceivedHandler? Received; diff --git a/PARR.GeneratorTemplates/GeneratorTemplate.cs b/PARR.GeneratorTemplates/GeneratorTemplate.cs index 147eef2f..c767e305 100644 --- a/PARR.GeneratorTemplates/GeneratorTemplate.cs +++ b/PARR.GeneratorTemplates/GeneratorTemplate.cs @@ -23,17 +23,20 @@ namespace PARR.GeneratorTemplates public void Start() { - mqService.InitConsumer(mqSettings); - mqService.Received += (msg) => { logger.LogInformation($"Привет откуда надо!!! ${msg}"); + //todo: идем дальеш! }; + + mqService.InitConsumer(mqSettings); + + } public void Stop() { - + mqService.Dispose(); } } } diff --git a/PARR.GeneratorTemplatesWorker/appsettings.json b/PARR.GeneratorTemplatesWorker/appsettings.json index a28563b8..c4246afa 100644 --- a/PARR.GeneratorTemplatesWorker/appsettings.json +++ b/PARR.GeneratorTemplatesWorker/appsettings.json @@ -24,7 +24,7 @@ ] }, "MqSettings": { - "HostName": "parr-rabbitmq", + "HostName": "10.99.253.216", "QueueName": "parr-generate-templates", "User": "generate_templates_worker", "Password": "Dhgdf%d&609sssa" From c33302acbfe42be4febba98bb0c56bf602a8fddd Mon Sep 17 00:00:00 2001 From: Mikhail Trubnikov Date: Fri, 22 Sep 2023 08:14:39 +1000 Subject: [PATCH 8/8] todo --- PARR.GeneratorTemplates/GeneratorTemplate.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/PARR.GeneratorTemplates/GeneratorTemplate.cs b/PARR.GeneratorTemplates/GeneratorTemplate.cs index c767e305..00b33020 100644 --- a/PARR.GeneratorTemplates/GeneratorTemplate.cs +++ b/PARR.GeneratorTemplates/GeneratorTemplate.cs @@ -27,6 +27,17 @@ namespace PARR.GeneratorTemplates { logger.LogInformation($"Привет откуда надо!!! ${msg}"); //todo: идем дальеш! + + // создать отдельный метод + // преобразовать json в модель + // попробовать поиск по регулярке + + // проверить как ту дела с асинком + // логгер работает в разных потоках все таки или нет? + + // поиск в существующих шаблонах, есть ли такие и есть ли у них эти работы + // поиск в хостах эк которых еще нет в шаблонах и у них такие работы + // генерим список и вставляем в шаблоны }; mqService.InitConsumer(mqSettings);