From 90306b7a63ad3fe4e9902256894c8b27549ab0f5 Mon Sep 17 00:00:00 2001 From: Mikhail Kuznetsov Date: Tue, 6 Feb 2024 16:54:40 +1000 Subject: [PATCH] =?UTF-8?q?fix(aihit-syncer):=20=D0=BE=D0=B3=D1=80=D0=B0?= =?UTF-8?q?=D0=BD=D0=B8=D1=87=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B8=D1=81=D0=BF?= =?UTF-8?q?=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D1=8F=20?= =?UTF-8?q?scope.=20=D0=A1=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD=20=D0=BE=D1=82?= =?UTF-8?q?=D0=B4=D0=B5=D0=BB=D1=8C=D0=BD=D1=8B=D0=B9=20SyncerService?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- PARR.AIHITSyncer/AihitSyncer.cs | 354 +++++--------------- PARR.AIHITSyncer/AihitSyncerInstaller.cs | 2 + PARR.AIHITSyncer/Services/ISyncerService.cs | 7 + PARR.AIHITSyncer/Services/SyncerService.cs | 303 +++++++++++++++++ 4 files changed, 401 insertions(+), 265 deletions(-) create mode 100644 PARR.AIHITSyncer/Services/ISyncerService.cs create mode 100644 PARR.AIHITSyncer/Services/SyncerService.cs diff --git a/PARR.AIHITSyncer/AihitSyncer.cs b/PARR.AIHITSyncer/AihitSyncer.cs index 1e914914..77ee9fcc 100644 --- a/PARR.AIHITSyncer/AihitSyncer.cs +++ b/PARR.AIHITSyncer/AihitSyncer.cs @@ -1,60 +1,50 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; +using PARR.AIHITSyncer.Services; using PARR.AIHITSyncer.Settings; -using PARR.BLL.Domain.Mq; using PARR.BLL.Services.Interfaces; -using PARR.DAL.Contracts; -using PARR.DAL.Extensions; using PARR.DAL.Models; -using PARR.DAL.Services.Interfaces; -using System.Text.RegularExpressions; namespace PARR.AIHITSyncer { internal class AihitSyncer : IAihitSyncer { private readonly ILogger logger; - private readonly WorkerSettings workerSettings; private readonly IMqService mqService; private readonly MqSettings mqSettings; - private readonly ITransformService transformService; private readonly IServiceProvider serviceProvider; - public List AppTypes { get; private set; } = new List(); + public AihitSyncer( ILogger logger, - WorkerSettings workerSettings, IMqService mqService, MqSettings mqSettings, - ITransformService transformService, IServiceProvider serviceProvider ) { this.logger = logger; - this.workerSettings = workerSettings; this.mqService = mqService; this.mqSettings = mqSettings; - this.transformService = transformService; this.serviceProvider = serviceProvider; } - private async Task GetAppTypesAsync() - { - if (AppTypes == null || AppTypes.Count == 0) - using (var scope = serviceProvider.CreateScope()) - { - var appTypesService = scope.ServiceProvider.GetService(); - if (appTypesService == null) - throw new Exception("Не смог получить серивс IApplicationTypeService, scope.ServiceProvider.GetService()"); - AppTypes = await appTypesService.Get().ToListAsync(); - } - - } public void Start() { logger.LogInformation("Запуск сервиса синхронизации данных из АИХИТ и ПАРР."); - var isConnected = mqService.InitConsumer(mqSettings, SyncDataAsync); + //var isConnected = mqService.InitConsumer(mqSettings, SyncDataAsync); + + var isConnected = mqService.InitConsumer(mqSettings, async (string msg) => + { + using (var scope = serviceProvider.CreateScope()) + { + var syncerService = scope.ServiceProvider.GetService(); + if (syncerService == null) + throw new Exception("Не смог получить серивс ISyncerService, scope.ServiceProvider.GetService()"); + + await syncerService.SyncAsync(msg); + //await Task.CompletedTask; + } + }); if (!isConnected) throw new Exception("Ошибка при подключении к RabbitMq"); @@ -64,273 +54,107 @@ namespace PARR.AIHITSyncer mqService.Dispose(); } - private async Task SyncDataAsync(string msg) - { - var objFromQuery = transformService.GetModelFromJson(msg); - if (objFromQuery == null) - return; + //private async Task SyncDataAsync(string msg) + //{ + // //SyncService + // using (var scope = serviceProvider.CreateScope()) + // { + // var service = scope.ServiceProvider.GetService(); + // //if (service == null) + // // throw new Exception("Не смог получить серивс IHostService, scope.ServiceProvider.GetService()"); - using (var scope = serviceProvider.CreateScope()) - { - var hostService = scope.ServiceProvider.GetService(); - if (hostService == null) - throw new Exception("Не смог получить серивс IHostService, scope.ServiceProvider.GetService()"); + // await service.StartAsync(msg); - await SyncHostToScopeAsync(hostService, objFromQuery); + // //await SyncHostToScopeAsync(hostService, objFromQuery); - await GetAppTypesAsync(); - } + // //await GetAppTypesAsync(); + // } - logger.LogDebug($"Закончил работу с сообщением: {msg}"); - //await Task.CompletedTask; - } + //var objFromQuery = transformService.GetModelFromJson(msg); + //if (objFromQuery == null) + // return; - private async Task SyncHostToScopeAsync(IHostService hostService, AihitDataMq objFromQuery) - { - //ищем существующий хост в БД - var host = await hostService.GetHostWithAppsAsync(objFromQuery.IP); - var isNew = false; - //если не нашли - создаём - if (host == null) - { - isNew = true; - host = await CreateHostAsync(hostService, objFromQuery); - } - else - { - logger.LogDebug($"Найден хост в БД: {host!.Ek}({host.IP})"); - //проверям и обновляем поля - await SyncHostFieldsAsync(hostService, host, objFromQuery); - } + //using (var scope = serviceProvider.CreateScope()) + //{ + // var hostService = scope.ServiceProvider.GetService(); + // if (hostService == null) + // throw new Exception("Не смог получить серивс IHostService, scope.ServiceProvider.GetService()"); - //получаем лист ПО из объекта - var appsInObj = await GetAppInObjectAsync(host, objFromQuery); + // await SyncHostToScopeAsync(hostService, objFromQuery); - await SyncApplicationAndHostAsync(host, appsInObj, !isNew); - } + // await GetAppTypesAsync(); + //} - private async Task> GetAppInObjectAsync(Host? host, AihitDataMq objFromQuery) - { - var applications = new List(); + //logger.LogDebug($"Закончил работу с сообщением: {msg}"); + //await Task.CompletedTask; + //} - if (objFromQuery.APPType != null) - { - var appList = objFromQuery.APPType.Split(new char[] { ',', ';' }).Distinct().ToList(); - foreach (var app in appList) - { - var created = await CreateAppIfNotExistAsync(app, ApplicationTypesEnum.APP); - if (created != null) - applications.Add(created); - } - } - if (objFromQuery.DBType != null) - { - var appList = objFromQuery.DBType.Split(new char[] { ',', ';' }).Distinct().ToList(); - foreach (var app in appList) - { - var created = await CreateAppIfNotExistAsync(app, ApplicationTypesEnum.DB); - if (created != null) - applications.Add(created); - } - } - if (objFromQuery.OSType != null) - { - var appList = objFromQuery.OSType.Split(new char[] { ',', ';' }).Distinct().ToList(); - foreach (var app in appList) - { - var created = await CreateAppIfNotExistAsync(app, ApplicationTypesEnum.OS); - if (created != null) - applications.Add(created); - } - } - return applications; - } + //private async Task SyncHostToScopeAsync(IHostService hostService, AihitDataMq objFromQuery) + //{ + // //ищем существующий хост в БД + // var host = await hostService.GetHostWithAppsAsync(objFromQuery.IP); + // var isNew = false; + // //если не нашли - создаём + // if (host == null) + // { + // isNew = true; + // host = await CreateHostAsync(hostService, objFromQuery); + // } + // else + // { + // logger.LogDebug($"Найден хост в БД: {host!.Ek}({host.IP})"); + // //проверям и обновляем поля + // await SyncHostFieldsAsync(hostService, host, objFromQuery); + // } - private async Task SyncHostFieldsAsync(IHostService hostService, Host host, AihitDataMq objFromQuery) - { - var isChanged = false; - if (host.IP != objFromQuery.IP) - { - host.IP = objFromQuery.IP; - isChanged = true; - } - if (host.EkStatusCode != ResolveCode(objFromQuery.Status)) - { - host.EkStatusCode = ResolveCode(objFromQuery.Status); - isChanged = true; - } - if (objFromQuery.WorkGroup != null && (host.WorkGroup == null || !host.WorkGroup!.Equals(objFromQuery.WorkGroup))) - { - host.WorkGroup = objFromQuery.WorkGroup; - isChanged = true; - } - if (host.ResponseAreaCode != ((ResolveCode(objFromQuery.ResponseArea) == 0) ? 99 : ResolveCode(objFromQuery.ResponseArea))) - {//TODO Возможно проще выгружать с помощью INCLUDE зону ответственности и сравнивать string - host.ResponseAreaCode = ((ResolveCode(objFromQuery.ResponseArea) == 0) ? 99 : ResolveCode(objFromQuery.ResponseArea)); - isChanged = true; - } - if (isChanged) - { - host.DateModified = DateTimeOffset.UtcNow; - if (!await hostService.CommitAsync()) - logger.LogError($"Не удалось обновить узел {host.Ek}({host.IP})"); - else - logger.LogInformation($"Обновлён Host: {host.Ek}({host.Id})"); - } - } + // //получаем лист ПО из объекта + // var appsInObj = await GetAppInObjectAsync(host, objFromQuery); - private async Task CreateHostAsync(IHostService hostService, AihitDataMq objFromQuery) - { - var id = Guid.NewGuid(); - var host = new Host - { - Id = id, - Ek = objFromQuery.EK, - IP = objFromQuery.IP, - EkStatusCode = ResolveCode(objFromQuery.Status), - WorkGroup = objFromQuery.WorkGroup, - ResponseAreaCode = ResolveCode(objFromQuery.ResponseArea) - }; - - if (!await hostService.CreateAsync(host) || !await hostService.CommitAsync()) - logger.LogError($"Не удалось создать узел {host.Ek}({host.IP})"); - else - logger.LogInformation($"----- Создан узел: {host.Id} -----"); + // await SyncApplicationInHostAsync(host, appsInObj, !isNew); + //} - return await hostService.GetHostWithAppsAsync(host.IP); - } - /// - /// Возвращает первую цифру из строки, котроая является кодом статуса или зоны ответственности для ЭК - /// - /// - /// - private int ResolveCode(string field) - { - var pattern = "\\d+"; - var regex = new Regex(pattern); - int.TryParse(regex.Match(field).Value, out int result); + //private async Task CreateHostAsync(IHostService hostService, AihitDataMq objFromQuery) + //{ + // var id = Guid.NewGuid(); + // var host = new Host + // { + // Id = id, + // Ek = objFromQuery.EK, + // IP = objFromQuery.IP, + // EkStatusCode = ResolveCode(objFromQuery.Status), + // WorkGroup = objFromQuery.WorkGroup, + // ResponseAreaCode = ResolveCode(objFromQuery.ResponseArea) + // }; - return result; - } - - private async Task CreateAppIfNotExistAsync(string appName, ApplicationTypesEnum type) - { - if (string.IsNullOrEmpty(appName) || string.IsNullOrWhiteSpace(appName)) return null; + // if (!await hostService.CreateAsync(host) || !await hostService.CommitAsync()) + // logger.LogError($"Не удалось создать узел {host.Ek}({host.IP})"); + // else + // logger.LogInformation($"----- Создан узел: {host.Id} -----"); - using (var scope = serviceProvider.CreateScope()) - { - var appService = scope.ServiceProvider.GetService(); - if (appService == null) - throw new Exception("Не смог получить серивс IApplicationService, scope.ServiceProvider.GetService()"); - - var existApp = await appService.GetByNameAsync(appName); - if (existApp != null) - return existApp; - - //Создаем - var appType = GetAppTypeByName(type); - if (appType == null) - { - logger.LogError($"Не удалось создать запись в таблице Applications: {appName}, так как не получил AppType: {type.ToString()}"); - return null; - } - - var app = new Application - { - Id = Guid.NewGuid(), - Name = appName.Trim(), - ApplicationTypeId = appType.Id - }; - - if (!await appService.CreateAsync(app) || !await appService.CommitAsync()) - logger.LogError($"Не удалось создать запись в таблице Application: {appName}, {app.ToJson()}"); - else - logger.LogInformation($"Создана запись а таблице Application: {appName}, {app.ToJson()}"); - - return await appService.GetAsync(app.Id); - } - } - - /// - /// Метод синхронизации - /// - /// Хост - /// Список программного обеспечения - /// Признак обновления поля DateModified - /// - private async Task SyncApplicationAndHostAsync(Host? host, List appsInObject, bool isUpdateDateModified = false) - { - var isUpdated = false; - if (host == null) - return; - - logger.LogDebug($"Host: {host.Ek}({host.IP}), начало синхронизации приложений ({appsInObject.Count()}) "); - using (var scope = serviceProvider.CreateScope()) - { - var appInHostService = scope.ServiceProvider.GetService(); - if (appInHostService == null) - throw new Exception("Не смог получить серивс IApplicationInHostService, scope.ServiceProvider.GetService()"); + // return await hostService.GetHostWithAppsAsync(host.IP); + //} - foreach (var appInObject in appsInObject) - { - var exist = host.ApplicationsInHosts.FirstOrDefault(a => a.ApplicationId == appInObject.Id); - if (exist == null) - { - //add - logger.LogInformation($"Host: {host.Ek}({host.IP}), добавление нового приложения Application {appInObject.Name}"); + //private int ResolveCode(string field) + //{ + // var pattern = "\\d+"; + // var regex = new Regex(pattern); - var newAppHost = new ApplicationInHost { Id = Guid.NewGuid(), ApplicationId = appInObject.Id, HostId = host.Id }; - if (!await appInHostService.CreateAsync(newAppHost)) - logger.LogError($"Не удалось создать ApplicationInHost {appInObject.Name}, host: {host.Ek}({host.IP})"); + // int.TryParse(regex.Match(field).Value, out int result); - isUpdated = true; - } - } + // return result; + //} - foreach (var appInHost in host.ApplicationsInHosts) - { - var appToRemove = appsInObject.FirstOrDefault(a => a.Id == appInHost.ApplicationId); - if (appToRemove == null) - { - //todo remove appToRemove - var obj = await appInHostService.Get().FirstOrDefaultAsync(t => t.ApplicationId == appInHost.ApplicationId && t.HostId == host.Id); - if (obj != null) - { - logger.LogInformation($"Host: {host.Ek}({host.IP}), удаление неактуального приложения Application {appInHost.Application?.Name}"); - appInHostService.Delete(obj); - if (!await appInHostService.CommitAsync()) - logger.LogError($"Не удалось удалить Application {appInHost.Application?.Name} узла {host.Ek}({host.IP})"); - isUpdated = true; - } - } - } - if (isUpdated && isUpdateDateModified) - host.DateModified = DateTimeOffset.UtcNow; - if (!await appInHostService.CommitAsync()) - logger.LogError($"Не удалось обновить ApplicationInHost для Host: {host.Ek}({host.IP})"); - } - logger.LogDebug($"Host: {host.Ek}({host.IP} конец синхронизации приложений"); - - } - private ApplicationType? GetAppTypeByName(ApplicationTypesEnum type) - { - var existType = AppTypes.FirstOrDefault(t => t.Name == type.ToString()); - if (existType == null) - logger.LogError($"Не найден AppType: {type}"); - - return existType; - } } } diff --git a/PARR.AIHITSyncer/AihitSyncerInstaller.cs b/PARR.AIHITSyncer/AihitSyncerInstaller.cs index 55d2fc24..2221981d 100644 --- a/PARR.AIHITSyncer/AihitSyncerInstaller.cs +++ b/PARR.AIHITSyncer/AihitSyncerInstaller.cs @@ -1,5 +1,6 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using PARR.AIHITSyncer.Services; using PARR.AIHITSyncer.Settings; using PARR.BLL; using PARR.DAL; @@ -22,6 +23,7 @@ namespace PARR.AIHITSyncer services.AddSingleton(mqSettings); services.AddTransient(); + services.AddTransient(); } } } diff --git a/PARR.AIHITSyncer/Services/ISyncerService.cs b/PARR.AIHITSyncer/Services/ISyncerService.cs new file mode 100644 index 00000000..af95d7cf --- /dev/null +++ b/PARR.AIHITSyncer/Services/ISyncerService.cs @@ -0,0 +1,7 @@ +namespace PARR.AIHITSyncer.Services +{ + public interface ISyncerService + { + Task SyncAsync(string msq); + } +} diff --git a/PARR.AIHITSyncer/Services/SyncerService.cs b/PARR.AIHITSyncer/Services/SyncerService.cs new file mode 100644 index 00000000..535b9c22 --- /dev/null +++ b/PARR.AIHITSyncer/Services/SyncerService.cs @@ -0,0 +1,303 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; +using PARR.BLL.Domain.Mq; +using PARR.BLL.Services.Interfaces; +using PARR.DAL.Contracts; +using PARR.DAL.Extensions; +using PARR.DAL.Models; +using PARR.DAL.Services.Interfaces; +using System.Text.RegularExpressions; + +namespace PARR.AIHITSyncer.Services +{ + internal class SyncerService : ISyncerService + { + private readonly ILogger logger; + private readonly IHostService hostService; + private readonly IApplicationService appService; + private readonly IApplicationInHostService appInHostService; + private readonly IApplicationTypeService appTypeService; + private readonly ITransformService transformService; + + public List AppTypes { get; private set; } = new List(); + + public SyncerService( + ILogger logger, + IHostService hostService, + IApplicationService appService, + IApplicationInHostService appInHostService, + IApplicationTypeService appTypeService, + ITransformService transformService + ) + { + this.logger = logger; + this.hostService = hostService; + this.appService = appService; + this.appInHostService = appInHostService; + this.appTypeService = appTypeService; + this.transformService = transformService; + } + + + public async Task SyncAsync(string msg) + { + await GetAppTypesAsync(); + + var objFromQuery = transformService.GetModelFromJson(msg); + if (objFromQuery == null) + return; + + await SyncHostAsync(objFromQuery); + } + + + private async Task SyncHostAsync(AihitDataMq objFromQuery) + { + //ищем существующий хост в БД + var host = await hostService.GetHostWithAppsAsync(objFromQuery.IP); + var isNew = false; + //если не нашли - создаём + if (host == null) + { + isNew = true; + host = await CreateHostAsync(objFromQuery); + } + else + { + logger.LogDebug($"Найден хост в БД: {host!.Ek}({host.IP})"); + //проверям и обновляем поля + await SyncHostFieldsAsync(host, objFromQuery); + } + + //получаем лист ПО из объекта + var appsInObj = await GetAppsInObjectAsync(host, objFromQuery); + + await SyncApplicationInHostAsync(host, appsInObj, !isNew); + } + + + private async Task CreateHostAsync(AihitDataMq objFromQuery) + { + var id = Guid.NewGuid(); + var host = new Host + { + Id = id, + Ek = objFromQuery.EK, + IP = objFromQuery.IP, + EkStatusCode = ResolveCode(objFromQuery.Status), + WorkGroup = objFromQuery.WorkGroup, + ResponseAreaCode = ResolveCode(objFromQuery.ResponseArea) + }; + + if (!await hostService.CreateAsync(host) || !await hostService.CommitAsync()) + logger.LogError($"Не удалось создать узел {host.Ek}({host.IP})"); + else + logger.LogInformation($"----- Создан узел: {host.Id} -----"); + + + return await hostService.GetHostWithAppsAsync(host.IP); + } + + + private async Task SyncHostFieldsAsync(Host host, AihitDataMq objFromQuery) + { + var isChanged = false; + if (host.IP != objFromQuery.IP) + { + host.IP = objFromQuery.IP; + isChanged = true; + } + if (host.EkStatusCode != ResolveCode(objFromQuery.Status)) + { + host.EkStatusCode = ResolveCode(objFromQuery.Status); + isChanged = true; + } + if (objFromQuery.WorkGroup != null && (host.WorkGroup == null || !host.WorkGroup!.Equals(objFromQuery.WorkGroup))) + { + host.WorkGroup = objFromQuery.WorkGroup; + isChanged = true; + } + if (host.ResponseAreaCode != ((ResolveCode(objFromQuery.ResponseArea) == 0) ? 99 : ResolveCode(objFromQuery.ResponseArea))) + {//TODO Возможно проще выгружать с помощью INCLUDE зону ответственности и сравнивать string + host.ResponseAreaCode = ((ResolveCode(objFromQuery.ResponseArea) == 0) ? 99 : ResolveCode(objFromQuery.ResponseArea)); + isChanged = true; + } + if (isChanged) + { + host.DateModified = DateTimeOffset.UtcNow; + if (!await hostService.CommitAsync()) + logger.LogError($"Не удалось обновить узел {host.Ek}({host.IP})"); + else + logger.LogInformation($"Обновлён Host: {host.Ek}({host.Id})"); + } + } + + + private async Task> GetAppsInObjectAsync(Host? host, AihitDataMq objFromQuery) + { + var applications = new List(); + + if (objFromQuery.APPType != null) + { + var appList = objFromQuery.APPType.Split(new char[] { ',', ';' }).Distinct().ToList(); + foreach (var app in appList) + { + var created = await CreateAppIfNotExistAsync(app, ApplicationTypesEnum.APP); + if (created != null) + applications.Add(created); + } + } + if (objFromQuery.DBType != null) + { + var appList = objFromQuery.DBType.Split(new char[] { ',', ';' }).Distinct().ToList(); + foreach (var app in appList) + { + var created = await CreateAppIfNotExistAsync(app, ApplicationTypesEnum.DB); + if (created != null) + applications.Add(created); + } + } + if (objFromQuery.OSType != null) + { + var appList = objFromQuery.OSType.Split(new char[] { ',', ';' }).Distinct().ToList(); + foreach (var app in appList) + { + var created = await CreateAppIfNotExistAsync(app, ApplicationTypesEnum.OS); + if (created != null) + applications.Add(created); + } + } + return applications; + } + + + private async Task CreateAppIfNotExistAsync(string appName, ApplicationTypesEnum type) + { + if (string.IsNullOrEmpty(appName) || string.IsNullOrWhiteSpace(appName)) return null; + + + var existApp = await appService.GetByNameAsync(appName); + if (existApp != null) + return existApp; + + //Создаем + var appType = GetAppTypeByName(type); + if (appType == null) + { + logger.LogError($"Не удалось создать запись в таблице Applications: {appName}, так как не получил AppType: {type.ToString()}"); + return null; + } + + var app = new Application + { + Id = Guid.NewGuid(), + Name = appName.Trim(), + ApplicationTypeId = appType.Id + }; + + if (!await appService.CreateAsync(app) || !await appService.CommitAsync()) + logger.LogError($"Не удалось создать запись в таблице Application: {appName}, {app.ToJson()}"); + else + logger.LogInformation($"Создана запись а таблице Application: {appName}, {app.ToJson()}"); + + return await appService.GetAsync(app.Id); + + } + + + /// + /// Метод синхронизации + /// + /// Хост + /// Список программного обеспечения + /// Признак обновления поля DateModified + /// + private async Task SyncApplicationInHostAsync(Host? host, List appsInObject, bool isUpdateDateModified = false) + { + var isUpdated = false; + if (host == null) + return; + + logger.LogDebug($"Host: {host.Ek}({host.IP}), начало синхронизации приложений ({appsInObject.Count()}) "); + + foreach (var appInObject in appsInObject) + { + var exist = host.ApplicationsInHosts.FirstOrDefault(a => a.ApplicationId == appInObject.Id); + + if (exist == null) + { + //add + logger.LogInformation($"Host: {host.Ek}({host.IP}), добавление нового приложения Application {appInObject.Name}"); + + var newAppHost = new ApplicationInHost { Id = Guid.NewGuid(), ApplicationId = appInObject.Id, HostId = host.Id }; + if (!await appInHostService.CreateAsync(newAppHost)) + logger.LogError($"Не удалось создать ApplicationInHost {appInObject.Name}, host: {host.Ek}({host.IP})"); + + isUpdated = true; + } + } + + foreach (var appInHost in host.ApplicationsInHosts) + { + var appToRemove = appsInObject.FirstOrDefault(a => a.Id == appInHost.ApplicationId); + + if (appToRemove == null) + { + //todo remove appToRemove + var obj = await appInHostService.Get().FirstOrDefaultAsync(t => t.ApplicationId == appInHost.ApplicationId && t.HostId == host.Id); + if (obj != null) + { + logger.LogInformation($"Host: {host.Ek}({host.IP}), удаление неактуального приложения Application {appInHost.Application?.Name}"); + appInHostService.Delete(obj); + + if (!await appInHostService.CommitAsync()) + logger.LogError($"Не удалось удалить Application {appInHost.Application?.Name} узла {host.Ek}({host.IP})"); + + isUpdated = true; + } + } + } + + if (isUpdated && isUpdateDateModified) + host.DateModified = DateTimeOffset.UtcNow; + + if (!await appInHostService.CommitAsync()) + logger.LogError($"Не удалось обновить ApplicationInHost для Host: {host.Ek}({host.IP})"); + + logger.LogDebug($"Host: {host.Ek}({host.IP} конец синхронизации приложений"); + + } + + + private ApplicationType? GetAppTypeByName(ApplicationTypesEnum type) + { + var existType = AppTypes.FirstOrDefault(t => t.Name == type.ToString()); + if (existType == null) + logger.LogError($"Не найден AppType: {type}"); + + return existType; + } + + + /// + /// Возвращает первую цифру из строки, котроая является кодом статуса или зоны ответственности для ЭК + /// + /// + /// + private int ResolveCode(string field) + { + var pattern = "\\d+"; + var regex = new Regex(pattern); + + int.TryParse(regex.Match(field).Value, out int result); + + return result; + } + + private async Task GetAppTypesAsync() + { + if (AppTypes == null || AppTypes.Count == 0) + AppTypes = await appTypeService.Get().ToListAsync(); + } + } +}