diff --git a/PARR.API.sln b/PARR.API.sln index 1fed32c2..820abfa8 100644 --- a/PARR.API.sln +++ b/PARR.API.sln @@ -60,6 +60,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PARR.EsppScheduleSync", "PA EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PARR.EsppScheduleSyncWorker", "PARR.EsppScheduleSyncWorker\PARR.EsppScheduleSyncWorker.csproj", "{C597A1D7-1BC5-493B-BC29-03EC830FB090}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PARR.NextRun", "PARR.NextRun\PARR.NextRun.csproj", "{92400205-B781-4C6C-BDA3-6D3652C2B62F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PARR.NextRunWorker", "PARR.NextRunWorker\PARR.NextRunWorker.csproj", "{47C6E193-257A-4001-84D7-11B640E3D1A0}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -160,6 +164,14 @@ Global {C597A1D7-1BC5-493B-BC29-03EC830FB090}.Debug|Any CPU.Build.0 = Debug|Any CPU {C597A1D7-1BC5-493B-BC29-03EC830FB090}.Release|Any CPU.ActiveCfg = Release|Any CPU {C597A1D7-1BC5-493B-BC29-03EC830FB090}.Release|Any CPU.Build.0 = Release|Any CPU + {92400205-B781-4C6C-BDA3-6D3652C2B62F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {92400205-B781-4C6C-BDA3-6D3652C2B62F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {92400205-B781-4C6C-BDA3-6D3652C2B62F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {92400205-B781-4C6C-BDA3-6D3652C2B62F}.Release|Any CPU.Build.0 = Release|Any CPU + {47C6E193-257A-4001-84D7-11B640E3D1A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {47C6E193-257A-4001-84D7-11B640E3D1A0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {47C6E193-257A-4001-84D7-11B640E3D1A0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {47C6E193-257A-4001-84D7-11B640E3D1A0}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/PARR.DAL/TransformServices/EsppScheduleTransformService.cs b/PARR.DAL/TransformServices/EsppScheduleTransformService.cs index 1788ec49..55c65d04 100644 --- a/PARR.DAL/TransformServices/EsppScheduleTransformService.cs +++ b/PARR.DAL/TransformServices/EsppScheduleTransformService.cs @@ -46,7 +46,11 @@ namespace PARR.DAL.TransformServices {"Суббота", 6 }, {"Воскресенье", 0 } }; - public EsppScheduleTransformService(IEsppSchTypeConfigService esppSchTypeConfigService, ILogger logger) + + public EsppScheduleTransformService( + IEsppSchTypeConfigService esppSchTypeConfigService, + ILogger logger + ) { this.esppSchTypeConfigService = esppSchTypeConfigService; this.logger = logger; diff --git a/PARR.EsppOrderManagerWorker/Program.cs b/PARR.EsppOrderManagerWorker/Program.cs index cd42bd06..271e8644 100644 --- a/PARR.EsppOrderManagerWorker/Program.cs +++ b/PARR.EsppOrderManagerWorker/Program.cs @@ -1,5 +1,4 @@ using Elastic.CommonSchema.Serilog; -using PARR.EsppApi; using PARR.EsppOrderManager; using PARR.EsppOrderManagerWorker; using Serilog; diff --git a/PARR.NextRun/INextRunManager.cs b/PARR.NextRun/INextRunManager.cs new file mode 100644 index 00000000..987a3141 --- /dev/null +++ b/PARR.NextRun/INextRunManager.cs @@ -0,0 +1,7 @@ +namespace PARR.NextRun +{ + public interface INextRunManager + { + Task StartAsync(); + } +} diff --git a/PARR.NextRun/NextRunInstaller.cs b/PARR.NextRun/NextRunInstaller.cs new file mode 100644 index 00000000..c3d0cfb1 --- /dev/null +++ b/PARR.NextRun/NextRunInstaller.cs @@ -0,0 +1,23 @@ +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using PARR.BLL; +using PARR.DAL; +using PARR.NextRun.Settings; + +namespace PARR.NextRun +{ + public static class NextRunInstaller + { + public static void InstallNextRunServices(this IServiceCollection services, IConfiguration configuration) + { + services.InstallBllServices(configuration); + services.InstallDalServices(configuration); + + var settings = new WorkerSettings(); + configuration.GetSection(nameof(WorkerSettings)).Bind(settings); + services.AddSingleton(settings); + + services.AddTransient(); + } + } +} diff --git a/PARR.NextRun/NextRunManager.cs b/PARR.NextRun/NextRunManager.cs new file mode 100644 index 00000000..16f49d4d --- /dev/null +++ b/PARR.NextRun/NextRunManager.cs @@ -0,0 +1,80 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using PARR.BLL.Services.Interfaces; +using PARR.DAL.Services.Interfaces; +using PARR.DAL.TransformServices; +using PARR.NextRun.Settings; + +namespace PARR.NextRun +{ + internal class NextRunManager : INextRunManager + { + private readonly WorkerSettings workerSettings; + private readonly ILogger logger; + private readonly IIntervalService intervalService; + private readonly IServiceProvider serviceProvider; + + public NextRunManager( + WorkerSettings workerSettings, + ILogger logger, + IIntervalService intervalService, + IServiceProvider serviceProvider + ) + { + this.workerSettings = workerSettings; + this.logger = logger; + this.intervalService = intervalService; + this.serviceProvider = serviceProvider; + } + + public async Task StartAsync() + { + logger.LogInformation("Запуск сервиса рассчета времени следующего создания наряда (nextRun)"); + + await intervalService.IntervalInitAsync(async () => + { + using (var scope = serviceProvider.CreateScope()) + { + var appInWorkService = scope.ServiceProvider.GetService(); + var esppSchService = scope.ServiceProvider.GetService(); + + if (appInWorkService == null || esppSchService == null) + throw new Exception("Не смог получить серивс IApplicationsInWorkService или IEsppScheduleTransformService"); + + await HandlerAsync(appInWorkService, esppSchService); + } + }, workerSettings.RepeatEvery); + } + + + /// + /// Рассчет следующей даты срабатываения + /// + /// + private async Task HandlerAsync(IApplicationsInWorkService applicationsInWorkService, IEsppScheduleTransformService esppScheduleTransformService) + { + var objs = await applicationsInWorkService.Get().Where(t => t.NextRun < DateTimeOffset.UtcNow).ToListAsync(); + + logger.LogDebug($"Объектов для обновления: {objs.Count()} шт."); + + int errorsCount = 0; + + foreach (var obj in objs) + { + var nextRun = await esppScheduleTransformService.GetNextDateAsync(obj.Id, obj.NextRun); + obj.NextRun = nextRun; + + if (await applicationsInWorkService.CommitAsync()) + logger.LogDebug($"Обновлено значение поле NextRun {obj.NextRun} для строки {obj.Id}"); + else + { + logger.LogError($"Ошибка при обновлении значения поля NextRun {obj.NextRun} для строки {obj.Id}"); + errorsCount++; + } + } + + logger.LogInformation($"Завершено обновление полей NextRun. Полей в задании: {objs.Count()}, обновлено: {objs.Count() - errorsCount}, ошибок: {errorsCount}"); + } + } +} diff --git a/PARR.NextRun/PARR.NextRun.csproj b/PARR.NextRun/PARR.NextRun.csproj new file mode 100644 index 00000000..21190861 --- /dev/null +++ b/PARR.NextRun/PARR.NextRun.csproj @@ -0,0 +1,14 @@ + + + + net7.0 + enable + enable + + + + + + + + diff --git a/PARR.NextRun/Settings/WorkerSettings.cs b/PARR.NextRun/Settings/WorkerSettings.cs new file mode 100644 index 00000000..f91e9744 --- /dev/null +++ b/PARR.NextRun/Settings/WorkerSettings.cs @@ -0,0 +1,7 @@ +namespace PARR.NextRun.Settings +{ + internal class WorkerSettings + { + public TimeSpan RepeatEvery { get; set; } + } +} diff --git a/PARR.NextRunWorker/Dockerfile b/PARR.NextRunWorker/Dockerfile new file mode 100644 index 00000000..0cf8a67d --- /dev/null +++ b/PARR.NextRunWorker/Dockerfile @@ -0,0 +1,28 @@ +#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 +ARG BUILD_CONFIGURATION=Release +WORKDIR /src +COPY ["NuGet.config", "."] +COPY ["PARR.NextRunWorker/PARR.NextRunWorker.csproj", "PARR.NextRunWorker/"] +COPY ["PARR.NextRun/PARR.NextRun.csproj", "PARR.NextRun/"] +COPY ["PARR.BLL/PARR.BLL.csproj", "PARR.BLL/"] +COPY ["PARR.DAL/PARR.DAL.csproj", "PARR.DAL/"] +COPY ["PARR.Constants/PARR.Constants.csproj", "PARR.Constants/"] +RUN dotnet restore "./PARR.NextRunWorker/./PARR.NextRunWorker.csproj" +COPY . . +WORKDIR "/src/PARR.NextRunWorker" +RUN dotnet build "./PARR.NextRunWorker.csproj" -c $BUILD_CONFIGURATION -o /app/build + +FROM build AS publish +ARG app_version=0.0.0-default +ARG BUILD_CONFIGURATION=Release +RUN dotnet publish "./PARR.NextRunWorker.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false /p:Version=$app_version + +FROM base AS final +WORKDIR /app +COPY --from=publish /app/publish . +ENTRYPOINT ["dotnet", "PARR.NextRunWorker.dll"] \ No newline at end of file diff --git a/PARR.NextRunWorker/PARR.NextRunWorker.csproj b/PARR.NextRunWorker/PARR.NextRunWorker.csproj new file mode 100644 index 00000000..eca219ba --- /dev/null +++ b/PARR.NextRunWorker/PARR.NextRunWorker.csproj @@ -0,0 +1,24 @@ + + + + net7.0 + enable + enable + dotnet-PARR.NextRunWorker-a622ce44-5924-404c-b214-4dcbdba3aca3 + Linux + + + + + + + + + + + + + + + + diff --git a/PARR.NextRunWorker/Program.cs b/PARR.NextRunWorker/Program.cs new file mode 100644 index 00000000..a61e2e0f --- /dev/null +++ b/PARR.NextRunWorker/Program.cs @@ -0,0 +1,29 @@ +using Elastic.CommonSchema.Serilog; +using PARR.NextRun; +using PARR.NextRunWorker; +using Serilog; + +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.InstallNextRunServices(builder.Configuration); +builder.Services.AddHostedService(); + +var host = builder.Build(); +host.Run(); + diff --git a/PARR.NextRunWorker/Properties/launchSettings.json b/PARR.NextRunWorker/Properties/launchSettings.json new file mode 100644 index 00000000..cba97fae --- /dev/null +++ b/PARR.NextRunWorker/Properties/launchSettings.json @@ -0,0 +1,14 @@ +{ + "profiles": { + "PARR.NextRunWorker": { + "commandName": "Project", + "environmentVariables": { + "DOTNET_ENVIRONMENT": "Development" + }, + "dotnetRunMessages": true + }, + "Docker": { + "commandName": "Docker" + } + } +} \ No newline at end of file diff --git a/PARR.NextRunWorker/Worker.cs b/PARR.NextRunWorker/Worker.cs new file mode 100644 index 00000000..68f879fc --- /dev/null +++ b/PARR.NextRunWorker/Worker.cs @@ -0,0 +1,19 @@ +using PARR.NextRun; + +namespace PARR.NextRunWorker +{ + public class Worker : BackgroundService + { + private readonly INextRunManager nextRunManager; + + public Worker(INextRunManager nextRunManager) + { + this.nextRunManager = nextRunManager; + } + + protected override async Task ExecuteAsync(CancellationToken stoppingToken) + { + await nextRunManager.StartAsync(); + } + } +} diff --git a/PARR.NextRunWorker/appsettings.Development.json b/PARR.NextRunWorker/appsettings.Development.json new file mode 100644 index 00000000..b2dcdb67 --- /dev/null +++ b/PARR.NextRunWorker/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.Hosting.Lifetime": "Information" + } + } +} diff --git a/PARR.NextRunWorker/appsettings.json b/PARR.NextRunWorker/appsettings.json new file mode 100644 index 00000000..19f26b7a --- /dev/null +++ b/PARR.NextRunWorker/appsettings.json @@ -0,0 +1,32 @@ +{ + "ConnectionStrings": { + "DefaultConnection": "Server=10.99.253.184;Database=parr;User Id=app_parr; Password=PosdfkhT&)%sdfligL&%5546;" + }, + "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" + } + } + ] + }, + "WorkerSettings": { + "RepeatEvery": "0:50:00" + } +} diff --git a/PARR.Test/Worker.cs b/PARR.Test/Worker.cs index 23f08d86..441fe981 100644 --- a/PARR.Test/Worker.cs +++ b/PARR.Test/Worker.cs @@ -37,7 +37,7 @@ namespace PARR.Test private async Task TestEsppApi() { //var result = await esppApiService.FindOrdersAsync(new FindOrdersQuery { DescriptionContains = "Полное", GenerateDateStart = new DateTime(2023, 10, 10) , GenerateDateEnd = new DateTime(2023, 10, 24) }); - var recordId = "НАР24-00007352"; + var recordId = "НАР24-00009262"; var result = await esppApiService.FindOrderByRecordIdAsync(recordId); diff --git a/README.md b/README.md index 8635bb4c..cbd86eaf 100644 --- a/README.md +++ b/README.md @@ -28,5 +28,6 @@ - PARR.Master - логика связывания нарядов ЕСПП и Агентов ПАРР, связывание нарядов и шаблонов, добавление нарядов в очередь на закрытие - PARR.MasterWorker - PARR.MockData - загрузка тестовых данных +- PARR.NextRun - рассчет следующей даты генерации наряда/запуска агента +- PARR.NextRunWorker - PARR.Test - тестирование функций ПАРР -