feat(templateUpdater): Применена логика SetUpdateTaskStatusIfAllow. Удален старый проект GeneratorTemplates

This commit is contained in:
Mikhail Trubnikov
2026-03-13 12:10:06 +10:00
parent eb6bbe02b3
commit 74d7affd8e
18 changed files with 14 additions and 773 deletions

View File

@@ -28,10 +28,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PARR.EsppTemplateSync", "PA
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "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 EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PARR.GeneratorTemplates", "PARR.GeneratorTemplates\PARR.GeneratorTemplates.csproj", "{79EC7AD8-9A16-4806-881A-E5632C48C461}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PARR.GeneratorTemplatesWorker", "PARR.GeneratorTemplatesWorker\PARR.GeneratorTemplatesWorker.csproj", "{BE11D005-D3FE-4F29-93A2-7379E729C78D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PARR.EsppOrderLoader", "PARR.EsppOrderLoader\PARR.EsppOrderLoader.csproj", "{F83395F9-CE33-40A5-BA1A-4A1233E9AA67}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PARR.EsppOrderLoader", "PARR.EsppOrderLoader\PARR.EsppOrderLoader.csproj", "{F83395F9-CE33-40A5-BA1A-4A1233E9AA67}"
EndProject EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PARR.EsppOrderLoaderWorker", "PARR.EsppOrderLoaderWorker\PARR.EsppOrderLoaderWorker.csproj", "{868ED9E0-42AD-4540-90BE-31A57A21CD93}" Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PARR.EsppOrderLoaderWorker", "PARR.EsppOrderLoaderWorker\PARR.EsppOrderLoaderWorker.csproj", "{868ED9E0-42AD-4540-90BE-31A57A21CD93}"
@@ -136,14 +132,6 @@ Global
{B02E5B16-59BD-4F02-9CC4-6873409DBD84}.Debug|Any CPU.Build.0 = Debug|Any CPU {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.ActiveCfg = Release|Any CPU
{B02E5B16-59BD-4F02-9CC4-6873409DBD84}.Release|Any CPU.Build.0 = 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
{F83395F9-CE33-40A5-BA1A-4A1233E9AA67}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {F83395F9-CE33-40A5-BA1A-4A1233E9AA67}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F83395F9-CE33-40A5-BA1A-4A1233E9AA67}.Debug|Any CPU.Build.0 = Debug|Any CPU {F83395F9-CE33-40A5-BA1A-4A1233E9AA67}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F83395F9-CE33-40A5-BA1A-4A1233E9AA67}.Release|Any CPU.ActiveCfg = Release|Any CPU {F83395F9-CE33-40A5-BA1A-4A1233E9AA67}.Release|Any CPU.ActiveCfg = Release|Any CPU

View File

@@ -1,102 +0,0 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using PARR.BLL.Contracts;
using PARR.BLL.Domain.Mq;
using PARR.BLL.Services.Interfaces;
using PARR.DAL.Models;
using PARR.GeneratorTemplates.Services;
using PARR.GeneratorTemplates.Settings;
using System.Threading.Tasks;
namespace PARR.GeneratorTemplates
{
internal class GeneratorTemplate : IGeneratorTemplate
{
private readonly MqSettings mqSettings;
private readonly IMqService mqService;
private readonly ILogger<GeneratorTemplate> logger;
private readonly ITransformService transformService;
private readonly IValidatorService validatorService;
private readonly IServiceProvider serviceProvider;
public GeneratorTemplate(
MqSettings mqSettings,
IMqService mqService,
ILogger<GeneratorTemplate> logger,
ITransformService transformService,
IValidatorService validatorService,
IServiceProvider serviceProvider
)
{
this.mqSettings = mqSettings;
this.mqService = mqService;
this.logger = logger;
this.transformService = transformService;
this.validatorService = validatorService;
this.serviceProvider = serviceProvider;
}
public async Task StartAsync()
{
#region test
// string msg = "{\"WorkId\":\"91219bec-e5f7-4a1a-b4c9-c135035d2498\",\"ApplicationId\":\"13044a1f-fa0c-476f-b501-2b8d06bac9f8\",\"Action\":\"create\",\"Ek\":\"ВРТ*ДВС\",\"StatusEk\":0}";
// string msg = "{\"WorkId\":\"91219bec-e5f7-4a1a-b4c9-c135035d2498\",\"ApplicationId\":\"13044a1f-fa0c-476f-b501-2b8d06bac9f8\",\"Action\":\"deactivate\",\"Ek\":\"ВРТ*ДВС\",\"StatusEk\":0}";
// await GenerateTemplates(msg);
#endregion
var isConnected = await mqService.InitConsumerAsync(mqSettings, GenerateTemplates);
if (!isConnected)
throw new Exception("Ошибка при подключении к RabbitMq");
}
public async Task StopAsync()
{
await mqService.DisposeAsync();
}
private async Task GenerateTemplates(string msg)
{
logger.LogInformation($"Получили запрос: {msg}");
var query = transformService.GetModelFromJson<GeneratorTemplateMq>(msg);
if (query == null)
return;
if (!await validatorService.IsValidApplicationAndWorksAsync(query.ApplicationId, query.WorkId))
{
logger.LogError($"Не валидны параметры {nameof(query.ApplicationId)}: {query.ApplicationId}, " +
$"{nameof(query.WorkId)}: {query.WorkId}," +
$" нет таких значений или они не связаны в таблице ${nameof(ApplicationsInWork)}");
return;
}
Enum.TryParse(typeof(GenerateTemplateActionsEnum), query.Action, true, out var action);
using (var scope = serviceProvider.CreateScope())
{
var templateManager = scope.ServiceProvider.GetService<ITemplateManager>();
if (templateManager == null)
throw new Exception($"Не найден сервис: {nameof(ITemplateManager)}");
switch (action)
{
case GenerateTemplateActionsEnum.create:
await templateManager.CreateTemplates(query);
break;
case GenerateTemplateActionsEnum.deactivate:
await templateManager.DeactivateTemplates(query);
break;
default:
logger.LogError($"Во входящем запросе, поле {nameof(query.Action)} не содержит допустимых значений");
return;
}
}
}
}
}

View File

@@ -1,44 +0,0 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using PARR.BLL;
using PARR.DAL;
using PARR.GeneratorTemplates.Services;
using PARR.GeneratorTemplates.Settings;
namespace PARR.GeneratorTemplates
{
public static class GeneratorTemplateInstaller
{
//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<IGeneratorTemplate, GeneratorTemplate>();
services.AddTransient<IValidatorService, ValidatorService>();
services.AddTransient<ITemplateManager, TemplateManager>();
}
//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);
}
}
}

View File

@@ -1,8 +0,0 @@
namespace PARR.GeneratorTemplates
{
public interface IGeneratorTemplate
{
Task StartAsync();
Task StopAsync();
}
}

View File

@@ -1,15 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\PARR.BLL\PARR.BLL.csproj" />
<ProjectReference Include="..\PARR.DAL\PARR.DAL.csproj" />
<ProjectReference Include="..\PARR.TemplateDistributor\PARR.TemplateDistributor.csproj" />
</ItemGroup>
</Project>

View File

@@ -1,10 +0,0 @@
using PARR.BLL.Domain.Mq;
namespace PARR.GeneratorTemplates.Services
{
internal interface ITemplateManager
{
Task CreateTemplates(GeneratorTemplateMq query);
Task DeactivateTemplates(GeneratorTemplateMq query);
}
}

View File

@@ -1,7 +0,0 @@
namespace PARR.GeneratorTemplates.Services
{
internal interface IValidatorService
{
Task<bool> IsValidApplicationAndWorksAsync(Guid applicationId, Guid workId);
}
}

View File

@@ -1,326 +0,0 @@
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<TemplateManager> logger;
private readonly SettingsFromDb settingsFromDb;
private readonly IRobotConfigurationService robotConfigurationService;
private readonly IApplicationsInWorkService applicationsInWorkService;
private readonly ITemplateDistributor templateDistributor;
public TemplateManager(
ITemplateService templateService,
IHostService hostService,
ILogger<TemplateManager> 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
}
/// <summary>
/// Исключаем существующие шаблоны из запроса на создание
/// </summary>
/// <param name="templates"></param>
/// <returns></returns>
private async Task<List<Template>> ExcludeExistTemplatesAsync(List<Template> templates)
{
// то ли костыль, то ли нет. Иногда попадают отфильтрованные шаблоны для создания, но они уже есть в БД. На всякий проверяем есть они или нет, и если есть, исключаем их из запроса.
// ищмем по имени такие шаблоны в БД и исключаем их
var existTemplates = await templateService.Get().Where(t => templates.Select(x => x.Name).Any(x => x == t.Name)).ToListAsync();
if (existTemplates.Any())
{
existTemplates.ForEach(item => logger.LogWarning($"Исключаем из запроса на создание шаблон, так как он уже есть в БД: {item.Name}"));
templates = templates.Where(t => !existTemplates.Any(x => x.Name == t.Name)).ToList();
}
return templates;
}
private List<Template> CreateQueryTemplates(List<Host> hosts, GeneratorTemplateMq query)
{
var templates = new List<Template>();
//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;
// return templates;
// }
// 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
// ),
// IsActiveTemplate = query.IsActiveTemplate ?? false,
// IsActiveSchedule = query.IsActiveSchedule ?? false,
// JobId = appInWork.Id,//TODO Migratin to Job
// UnitId = host.Id,//TODO Migratin to Job
// // NextRun не задаем значение, его рассчитаем позже
// //NextRun = ???,
// LastRun = null
// };
// templates.Add(template);
//}
return templates;
}
public async Task DeactivateTemplates(GeneratorTemplateMq query)
{
//TODO: !!! тут не учитываются поля query.IsActiveTemplate, query.IsActiveSchedule, просто все деактивируется. !!!
//В таблице 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();
//Ищет все активные шаблоны согласно параметрам в таблице Templates, и деактивирует их. Меняем на статус Updating
// делаем sql формат для like из запроса.
string ekPattern = SqlHelpers.RegexToLike(query.Ek);
var queryTemplates = templateService.Get()
.Include(t => t.Unit)//TODO Migratin to Job
.Include(t => t.Job)//TODO Migratin to Job
.Include(t => t.RobotConfigurations)
.Where(t =>
(t.IsActiveTemplate == true || t.IsActiveSchedule == true)
//&& t.ApplicationsInWork!.ApplicationId == query.ApplicationId//TODO Migratin to Job
//&& t.ApplicationsInWork!.WorkId == query.WorkId//TODO Migratin to Job
&& EF.Functions.Like(t.Unit!.Name.ToLower(), ekPattern)
);
// статус ЭК
if (query.StatusEk > 0)
queryTemplates = queryTemplates;//.Where(t => t.Unit!.BaseFields.Status == query.StatusEk);//TODO Migratin to Job
var existTemplates = await queryTemplates
.AsSplitQuery()
.ToListAsync();
// Исключаем хосты у которых нет нужных групп
existTemplates = existTemplates.Where(t => workGroups.Any(x => x.WorkGroup.Name == t.Unit.BaseFields.WorkGroup)).ToList();
if (!existTemplates.Any())
{
logger.LogInformation("Нет шаблонов для деактивации");
return;
}
existTemplates.ForEach(item =>
{
item.DateModified = DateTimeOffset.UtcNow;
if (item.IsActiveTemplate)
{
item.IsActiveTemplate = false;
//необходимо обновить шаблон
var config = robotConfigurationService.GetFromTemplateByRobotCode(RobotsEnum.TemplateOrder, item);
robotConfigurationService.ChangeTaskStatus(TaskStatusEnum.Updating, config);
}
if (item.IsActiveSchedule)
{
item.IsActiveSchedule = false;
//необходимо обновить расписание
var config = robotConfigurationService.GetFromTemplateByRobotCode(RobotsEnum.ScheduleOrder, item);
robotConfigurationService.ChangeTaskStatus(TaskStatusEnum.Updating, config);
}
});
if (await templateService.CommitAsync(query.HistoryInitiator))
existTemplates.ForEach(item => logger.LogInformation($"Деактивирован шаблон: {item.Name}"));
else
existTemplates.ForEach(item => logger.LogError($"Ошибка при дактивации шаблона: {item.Name}"));
}
}
}

View File

@@ -1,34 +0,0 @@
using Microsoft.Extensions.DependencyInjection;
using PARR.DAL.Services.Interfaces;
namespace PARR.GeneratorTemplates.Services
{
internal class ValidatorService : IValidatorService
{
private readonly IServiceProvider serviceProvider;
public ValidatorService(IServiceProvider serviceProvider)
{
this.serviceProvider = serviceProvider;
}
/// <summary>
/// Проверка, валидны ли поля и связана ли Работа с Приложением
/// </summary>
/// <param name="applicationId"></param>
/// <param name="workId"></param>
/// <returns></returns>
public async Task<bool> IsValidApplicationAndWorksAsync(Guid applicationId, Guid workId)
{
using (var scope = serviceProvider.CreateScope())
{
var service = scope.ServiceProvider.GetService<IApplicationsInWorkService>();
if (service == null)
throw new Exception($"Не найден сервис: {nameof(IApplicationsInWorkService)}");
return await service.GetAsync(applicationId, workId) != null;
}
}
}
}

View File

@@ -1,13 +0,0 @@
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;
public ushort? PrefetchCount { get; set; } = 0;
}
}

View File

@@ -1,28 +0,0 @@
#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM 10.99.253.167:8090/dotnet/runtime:7.0 AS base
WORKDIR /app
FROM 10.99.253.167:8090/dotnet/sdk:7.0 AS build
WORKDIR /src
COPY ["NuGet.config", "."]
COPY ["PARR.GeneratorTemplatesWorker/PARR.GeneratorTemplatesWorker.csproj", "PARR.GeneratorTemplatesWorker/"]
COPY ["PARR.GeneratorTemplates/PARR.GeneratorTemplates.csproj", "PARR.GeneratorTemplates/"]
COPY ["PARR.TemplateDistributor/PARR.TemplateDistributor.csproj", "PARR.TemplateDistributor/"]
COPY ["PARR.BLL/PARR.BLL.csproj", "PARR.BLL/"]
COPY ["PARR.DAL/PARR.DAL.csproj", "PARR.DAL/"]
COPY ["PARR.Constants/PARR.Constants.csproj", "PARR.Constants/"]
COPY ["PARR.Common/PARR.Common.csproj", "PARR.Common/"]
RUN dotnet restore "PARR.GeneratorTemplatesWorker/PARR.GeneratorTemplatesWorker.csproj"
COPY . .
WORKDIR "/src/PARR.GeneratorTemplatesWorker"
RUN dotnet build "PARR.GeneratorTemplatesWorker.csproj" -c Release -o /app/build
FROM build AS publish
ARG app_version=0.0.0-default
RUN dotnet publish "PARR.GeneratorTemplatesWorker.csproj" -c Release -o /app/publish /p:UseAppHost=false /p:Version=$app_version
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "PARR.GeneratorTemplatesWorker.dll"]

View File

@@ -1,24 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk.Worker">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>dotnet-PARR.GeneratorTemplatesWorker-deb14157-f207-44e0-8d4b-963c6066a75e</UserSecretsId>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Elastic.CommonSchema.Serilog" Version="8.6.1" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1" />
<PackageReference Include="Serilog.Extensions.Hosting" Version="7.0.0" />
<PackageReference Include="Serilog.Settings.Configuration" Version="7.0.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="4.1.0" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\PARR.GeneratorTemplates\PARR.GeneratorTemplates.csproj" />
</ItemGroup>
</Project>

View File

@@ -1,33 +0,0 @@
using Elastic.CommonSchema.Serilog;
using PARR.GeneratorTemplates;
using PARR.GeneratorTemplatesWorker;
using Serilog;
using PARR.TemplateDistributor;
var builder = Host.CreateApplicationBuilder();
builder.Services.AddLogging(config =>
{
config.ClearProviders();
var logger = new LoggerConfiguration();
if (builder.Environment.IsProduction())
logger.WriteTo.Console(new EcsTextFormatter());
else
logger.WriteTo.Console();
logger.ReadFrom.Configuration(builder.Configuration);
config.AddSerilog(logger.CreateLogger());
});
builder.Services.InstallGeneratorTemplateServices(builder.Configuration);
builder.Configuration.AddGeneratorTemplateConfigurations(builder.Services);
builder.Services.AddGeneratorTemplateSettings(builder.Configuration);
builder.Services.InstallTemplateDistributorSerivces(builder.Configuration);
builder.Services.AddHostedService<Worker>();
var host = builder.Build();
host.Run();

View File

@@ -1,14 +0,0 @@
{
"profiles": {
"PARR.GeneratorTemplatesWorker": {
"commandName": "Project",
"environmentVariables": {
"DOTNET_ENVIRONMENT": "Development"
},
"dotnetRunMessages": true
},
"Docker": {
"commandName": "Docker"
}
}
}

View File

@@ -1,28 +0,0 @@
using PARR.GeneratorTemplates;
namespace PARR.GeneratorTemplatesWorker
{
public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;
private readonly IGeneratorTemplate generatorTemplate;
public Worker(ILogger<Worker> logger, IGeneratorTemplate generatorTemplate)
{
_logger = logger;
this.generatorTemplate = generatorTemplate;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
await generatorTemplate.StartAsync();
await Task.Delay(Timeout.Infinite, stoppingToken);
}
public override async Task StopAsync(CancellationToken cancellationToken)
{
await generatorTemplate.StopAsync();
await base.StopAsync(cancellationToken);
}
}
}

View File

@@ -1,32 +0,0 @@
{
"ConnectionStrings": {
"RedisConnection": "10.99.253.216:6379,password=ParrP@ssPtk202MMdevDvs"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"Serilog": {
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"WriteTo": [
{
"Name": "File",
"Args": {
"path": "log/log-.txt",
"rollingInterval": "Day"
}
}
]
},
"MqSettings": {
"HostName": "10.99.253.216"
}
}

View File

@@ -1,31 +0,0 @@
{
"ConnectionStrings": {
"DefaultConnection": "Server=10.99.253.184;Database=parr;User Id=app_parr; Password=PosdfkhT&)%sdfligL&%5546;",
"RedisConnection": "parr-redis:6379,password=ParrP@ssPtk202MMdevDvs"
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.EntityFrameworkCore": "Error",
"Microsoft.EntityFrameworkCore.Database.Command": "Warning",
"Microsoft.AspNetCore": "Warning"
}
},
"Serilog": {
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning",
"Microsoft.EntityFrameworkCore": "Error",
"Microsoft.EntityFrameworkCore.Database.Command": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
}
},
"MqSettings": {
"HostName": "parr-rabbitmq",
"QueueName": "parr-generate-templates",
"User": "generate_templates_worker",
"Password": "Dhgdf%d&609sssa"
}
}

View File

@@ -157,7 +157,8 @@ namespace PARR.TemplateUpdater.Services
{ {
// ставим задачу на обновление шаблона // ставим задачу на обновление шаблона
var config = robotConfigurationService.GetFromTemplateByRobotCode(RobotsEnum.TemplateOrder, template); var config = robotConfigurationService.GetFromTemplateByRobotCode(RobotsEnum.TemplateOrder, template);
robotConfigurationService.ChangeTaskStatus(TaskStatusEnum.Updating, config); //robotConfigurationService.ChangeTaskStatus(TaskStatusEnum.Updating, config);
robotConfigurationService.SetUpdateTaskStatusIfAllow(config);
logger.LogDebug("Для шаблона {TemplateId} устанавливаю статус {Status}", template.Id, RobotStatusEnum.Wait.ToString()); logger.LogDebug("Для шаблона {TemplateId} устанавливаю статус {Status}", template.Id, RobotStatusEnum.Wait.ToString());
} }
@@ -166,7 +167,8 @@ namespace PARR.TemplateUpdater.Services
{ {
// ставим задачу на обновление расписания // ставим задачу на обновление расписания
var config = robotConfigurationService.GetFromTemplateByRobotCode(RobotsEnum.ScheduleOrder, template); var config = robotConfigurationService.GetFromTemplateByRobotCode(RobotsEnum.ScheduleOrder, template);
robotConfigurationService.ChangeTaskStatus(TaskStatusEnum.Updating, config); //robotConfigurationService.ChangeTaskStatus(TaskStatusEnum.Updating, config);
robotConfigurationService.SetUpdateTaskStatusIfAllow(config);
logger.LogDebug("Для расписания {TemplateId} устанавливаю статус {Status}", template.Id, RobotStatusEnum.Wait.ToString()); logger.LogDebug("Для расписания {TemplateId} устанавливаю статус {Status}", template.Id, RobotStatusEnum.Wait.ToString());
} }
@@ -199,11 +201,11 @@ namespace PARR.TemplateUpdater.Services
return false; return false;
} }
if (template.ScheduleEsppId == null) //if (template.ScheduleEsppId == null)
{ //{
logger.LogError("Сообщение не валидно. Номер расписания не может быть null, робот не сможет обновить шаблон: {TemplateName}", template.Name); // logger.LogError("Сообщение не валидно. Номер расписания не может быть null, робот не сможет обновить шаблон: {TemplateName}", template.Name);
return false; // return false;
} //}
var config = robotConfigurationService.GetFromTemplateByRobotCode(RobotsEnum.TemplateOrder, template); var config = robotConfigurationService.GetFromTemplateByRobotCode(RobotsEnum.TemplateOrder, template);
if (config == null) if (config == null)
@@ -212,11 +214,11 @@ namespace PARR.TemplateUpdater.Services
return false; return false;
} }
if (config.TaskStatusCode != (int)TaskStatusEnum.Ok) //if (config.TaskStatusCode != (int)TaskStatusEnum.Ok)
{ //{
logger.LogError("Сообщение не валидно. Не закончено создание или предыдущее обновление - нельзя начинать новое изменение шаблона: {TemplateName}", template.Name); // logger.LogError("Сообщение не валидно. Не закончено создание или предыдущее обновление - нельзя начинать новое изменение шаблона: {TemplateName}", template.Name);
return false; // return false;
} //}
if (string.IsNullOrEmpty(query.Name?.Trim())) if (string.IsNullOrEmpty(query.Name?.Trim()))
{ {