using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using PARR.BLL.Domain.Mq; using PARR.BLL.Services.Interfaces; using PARR.Constants; using PARR.TemplateMatcher.Services.Interfaces; using PARR.TemplateMatcher.Settings; namespace PARR.TemplateMatcher { internal class MqTemplateMatcher : IMqTemplateMatcher { private readonly ILogger logger; private readonly MqSettings mqSettings; private readonly IMqService mqService; private readonly ITransformService transformService; private readonly IServiceProvider serviceProvider; public MqTemplateMatcher( ILogger logger, MqSettings mqSettings, IMqService mqService, ITransformService transformService, IServiceProvider serviceProvider ) { this.logger = logger; this.mqSettings = mqSettings; this.mqService = mqService; this.transformService = transformService; this.serviceProvider = serviceProvider; } public async Task StartAsync() { var isConnected = await mqService.InitConsumerAsync(mqSettings.TemplateMatcher, HandleMessageAsync); if (!isConnected) throw new Exception("Ошибка при подключении к RabbitMq"); } private async Task HandleMessageAsync(string msg) { logger.LogInformation($"Получили запрос: {msg}"); var query = transformService.GetModelFromJson(msg); if (query == null) { logger.LogWarning("Не удалось десериализовать сообщение в TemplateMatcherMq: {Message}", msg); return; } await using (var scope = serviceProvider.CreateAsyncScope()) { var templateMatcherService = GetServiceInScope(scope); switch (query.EntityType) { case SyncTaskEntityTypeEnum.Job: var validatorService = GetServiceInScope(scope); if (!await validatorService.IsValidAsync(query.Id)) { logger.LogWarning("Сущность {EntityType} с Id {Id} не прошла валидацию", query.EntityType, query.Id); return; } switch (query.Action) { case TemplateMatcherActionEnum.Sync: // Создать недостающие шаблоны, привязать к нужному Job, включить/выключить по фильтрам await templateMatcherService.SyncTemplatesForJob(query.Id, query.Initiator); break; case TemplateMatcherActionEnum.Update: // Обновить существующие шаблоны: имя, привязка к Job, вкл/выкл по фильтрам await templateMatcherService.UpdateTemplatesForJob(query.Id, query.Initiator); break; default: logger.LogWarning("Неизвестное действие для {EntityType}: {Action}", query.EntityType, query.Action); break; } break; case SyncTaskEntityTypeEnum.JobGroup: logger.LogWarning("Обработка EntityType JobGroup не реализована. Id: {Id}, Action: {Action}", query.Id, query.Action); break; case SyncTaskEntityTypeEnum.Template: logger.LogWarning("Обработка EntityType Template не реализована. Id: {Id}, Action: {Action}", query.Id, query.Action); break; default: logger.LogWarning("Неизвестный тип сущности: {EntityType}", query.EntityType); break; } } } public async Task StopAsync() { await mqService.DisposeAsync(); } private Service GetServiceInScope(IServiceScope scope) { var service = scope.ServiceProvider.GetService(); if (service == null) throw new Exception($"Не найден сервис: {nameof(Service)}"); return service; } } }