using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using PARR.BLL.Domain.Mq; using PARR.BLL.Helpers; using PARR.Constants; using PARR.DAL.Contracts; using PARR.DAL.Models; using PARR.DAL.Services.Interfaces; using PARR.TemplateDistributor; namespace PARR.GeneratorTemplates.Services { internal class TemplateManager : ITemplateManager { private readonly ITemplateService templateService; private readonly IHostService hostService; private readonly ILogger logger; private readonly SettingsFromDb settingsFromDb; private readonly IRobotConfigurationService robotConfigurationService; private readonly IApplicationsInWorkService applicationsInWorkService; private readonly ITemplateDistributor templateDistributor; public TemplateManager( ITemplateService templateService, IHostService hostService, ILogger logger, SettingsFromDb settingsFromDb, IRobotConfigurationService robotConfigurationService, IApplicationsInWorkService applicationsInWorkService, ITemplateDistributor templateDistributor ) { this.templateService = templateService; this.hostService = hostService; this.logger = logger; this.settingsFromDb = settingsFromDb; this.robotConfigurationService = robotConfigurationService; this.applicationsInWorkService = applicationsInWorkService; this.templateDistributor = templateDistributor; } public async Task CreateTemplates(GeneratorTemplateMq query) { //TODO Migratin to Job ////В таблице AppInWork находим РР, и смотрим ее рабочие группы. Затем по ним будем фильтровать хосты //var appInWorkWg = await applicationsInWorkService.Get() // .Include(t => t.WorkGroups) // .FirstAsync(t => t.ApplicationId == query.ApplicationId && t.WorkId == query.WorkId); //if (!appInWorkWg.WorkGroups.Any()) //{ // logger.LogWarning($"Не генерирую шаблоны. Нет рабочих групп у ApplicationInWork с id: {appInWorkWg.Id}"); // return; //} //var workGroups = appInWorkWg.WorkGroups.ToList(); ////Согласно параметрам, находит все ЭК в таблице Hosts. ////Далее проверяет есть ли такие шаблоны в таблице Templates, если нет, то создает, активирует и ставит статус Creating. ////Если такие шаблоны уже есть, ничего с ними не делает. //string ekPattern = SqlHelpers.RegexToLike(query.Ek); //// список хостов для создания шаблонов //var queryHosts = hostService.Get() // //.Include(t => t.WorkGroupItem) // .Include(t => t.ApplicationsInHosts) // .ThenInclude(t => t.Application).ThenInclude(t => t!.ApplicationsInWorks).ThenInclude(w => w.Work) // .Include(t => t.Templates) // .ThenInclude(w => w.ApplicationsInWork) // .Include(t => t.ResponseArea) // .Where(t => // t.ApplicationsInHosts.Any(h => // h.ApplicationId == query.ApplicationId // && h.Application!.ApplicationsInWorks.Any(w => w.WorkId == query.WorkId) // ) // && EF.Functions.Like(t.Ek.ToLower(), ekPattern) // // смотрим что нет такого шаблона // && t.Templates.Any(templ => templ.ApplicationsInWork!.WorkId == query.WorkId && templ.ApplicationsInWork.ApplicationId == query.ApplicationId) == false // // смотрим что у этих хостов есть нужные группы // //&& workGroups.Any(x => x.WorkGroupId == t.WorkGroupId) // ); //// статус ЭК //if (query.StatusEk > 0) // queryHosts = queryHosts.Where(t => t.EkStatusCode == query.StatusEk); //var hosts = await queryHosts // .AsSplitQuery() // .ToListAsync(); //// Исключаем хосты у которых нет нужных групп //hosts = hosts.Where(t => workGroups.Any(x => x.WorkGroupId == t.WorkGroupId)).ToList(); //if (!hosts.Any()) //{ // logger.LogInformation($"Не найдено ЭК попадающих под условие: ${JsonSerializer.Serialize(query)}"); // return; //} //// хосты группируем по РГ, чтоб потом распределить/рассчитать NextRun //var groupingHostByWg = hosts.GroupBy(t => t.WorkGroupId); //foreach (var group in groupingHostByWg) //{ // var groupingHosts = group.ToList(); // var templates = CreateQueryTemplates(groupingHosts, query); // //проверяем, что нет шаблонов с такими именами, исключаем их // templates = await ExcludeExistTemplatesAsync(templates); // if (!templates.Any()) // continue; // //заполняем NextRun // templates = await templateDistributor.DistributeTemplateAsync(templates, appInWorkWg.Id, (Guid)group.Key!); // // сохраняем // foreach (var template in templates) // { // if (!await templateService.CreateAsync(template) || !await templateService.CommitAsync(query.HistoryInitiator)) // { // logger.LogError($"Ошибка при создании шаблона: Name: {template.Name}, ApplicationInWorkId: {template.ApplicationInWorkId}, HostId: {template.HostId}"); // } // else // { // logger.LogInformation($"Создан шаблон: Name: {template.Name}, ApplicationInWorkId: {template.ApplicationInWorkId}, " + // $"HostId: {template.HostId}"); // } // } //} #region создавали шаблоны до того, как стали группировать по РГ ////Создаем шаблоны //foreach (var host in hosts) //{ // var appInWork = host.ApplicationsInHosts.FirstOrDefault(t => t.ApplicationId == query.ApplicationId)?.Application?.ApplicationsInWorks.FirstOrDefault(a => a.WorkId == query.WorkId); // if (appInWork == null) // { // // такого не может быть, так как выполнился запрос при получении списка хостов, но мало ли // logger.LogError($"Ошибка при создании шаблона. В таблице ApplicationsInWorks не найден Id согласно запроса WorkId: {query.WorkId}, ApplicationId: {query.ApplicationId}"); // return; // } // var template = new Template // { // Id = Guid.NewGuid(), // //Name = TemplateHelpers.GenerateTemplateName("ЗО" ,settingsFromDb.TemplatePrefixName, host.Ek, appInWork.Work!.Name), // //Генерить имя с полным именем работы и подстановкой ЭК // //Name = TemplateHelpers.GenerateTemplateNameWithResponseArea(host.ResponseArea!.Name, settingsFromDb.TemplatePrefixName, host.Ek, appInWork.Work!.Name.ApplyShortcode(Constants.Shortcode.ShortcodeEnum.EK, host.Ek)), // //Вместо полного имени работы, подставляется сокращенный суффикс или полное имя с ЭК если суффикса нет // Name = TemplateHelpers.GenerateTemplateNameWithResponseArea( // host.ResponseArea!.Name, // settingsFromDb.TemplatePrefixName, // host.Ek, // appInWork.Work!.TemplateSuffix ?? appInWork.Work!.Name.ApplyShortcode(Constants.Shortcode.ShortcodeEnum.EK, host.Ek) // ), // IsActiveTemplate = query.IsActiveTemplate ?? false, // IsActiveSchedule = query.IsActiveSchedule ?? false, // ApplicationInWorkId = appInWork.Id, // HostId = host.Id, // //TODO: // //NextRun = ???, // LastRun = null // }; // if (!await templateService.CreateAsync(template) || !await templateService.CommitAsync()) // { // logger.LogError($"Ошибка при создании шаблона: Name: {template.Name}, ApplicationInWorkId: {template.ApplicationInWorkId}, HostId: {template.HostId}"); // } // else // { // logger.LogInformation($"Создан шаблон: Name: {template.Name}, ApplicationInWorkId: {template.ApplicationInWorkId}, " + // $"HostId: {template.HostId}"); // } //} #endregion } /// /// Исключаем существующие шаблоны из запроса на создание /// /// /// private async Task> ExcludeExistTemplatesAsync(List