Синхронизация данных АИХ ИТ с ПАРР

This commit is contained in:
Mikhail Kuznetsov
2023-08-14 15:24:57 +10:00
parent e16eecaeba
commit 260a20e9bf
26 changed files with 475 additions and 329 deletions

View File

@@ -1,4 +1,5 @@
using AutoMapper;
using PARR.DAL.Models;
using PARR.DAL.Models.AIHIT;
using PARR.DAL.Models.V1;
using System.Xml;
@@ -18,7 +19,11 @@ namespace PARR.AIHIT.MappingProfiles
.ForMember(d => d.WorkGroup, o => o.MapFrom(s => (s.Attributes!["РАБОЧАЯ_ГР_ОТВ_ЗАК"] != null) ? s.Attributes!["РАБОЧАЯ_ГР_ОТВ_ЗАК"]!.Value.Trim() : ""))
.ForMember(d => d.Responsible, o => o.MapFrom(s => s.Attributes!["ОТВЕТСТВЕННЫЙ_ЗАК"]!.Value.Trim()));
CreateMap<Models.EK, RawDataEK>();
CreateMap<RawDataEK, Host>()
.ForMember(d => d.HostName, o => o.MapFrom(s => s.EKFindCode))//TODO Определить имя хоста по
.ForMember(d => d.IP, o => o.MapFrom(s => s.IP))
.ForMember(d => d.Status, o => o.MapFrom(s => s.Status))
.ForMember(d => d.WorkGroup, o => o.MapFrom(s => s.WorkGroup));
//CreateMap<PARR.DAL.Models.Host, PARR.DAL.Models.Host>()
// .ForMember(d => d.HostName, o => o.MapFrom(s => s.HostName))
// .ForMember(d => d.IP, o => o.MapFrom(s => s.IP))

View File

@@ -6,9 +6,12 @@ using MimeKit;
using PARR.AIHIT.Settings;
using PARR.DAL.Contracts;
using PARR.DAL.Extensions;
using PARR.DAL.Models;
using PARR.DAL.Models.AIHIT;
using PARR.DAL.Models.V1;
using PARR.DAL.Services.Interfaces;
using PARR.DAL.Services.Interfaces.AIHIT;
using PARR.DAL.Services.Interfaces.V1;
using PARR.Mail.Services;
using System.Text;
using System.Xml;
@@ -20,6 +23,10 @@ namespace PARR.AIHIT
private readonly ILogger<Syncher> logger;
private readonly IMailService mailService;
private readonly SyncherSettings syncherSettings;
private readonly V1_IHostService V1_hostService;
private readonly V1_IApplicationTypeService V1_appTypeService;
private readonly V1_IApplicationInHostService V1_appInHostService;
private readonly V1_IApplicationService V1_appService;
private readonly IHostService hostService;
private readonly IMapper mapper;
private readonly IApplicationService appService;
@@ -28,12 +35,16 @@ namespace PARR.AIHIT
private readonly IRawDataEKService rawDataEKService;
private readonly ISettingService settingService;
public List<V1_ApplicationType> AppTypes { get; private set; } = new List<V1_ApplicationType>();
public List<ApplicationType> AppTypes { get; private set; } = new List<ApplicationType>();
public Syncher(
ILogger<Syncher> logger,
IMailService mailService,
SyncherSettings syncherSettings,
V1_IHostService V1_hostService,
V1_IApplicationService V1_appService,
V1_IApplicationTypeService V1_appTypeService,
V1_IApplicationInHostService V1_appInHostService,
IHostService hostService,
IMapper mapper,
IApplicationService appService,
@@ -53,6 +64,10 @@ namespace PARR.AIHIT
this.logger = logger;
this.mailService = mailService;
this.syncherSettings = syncherSettings;
this.V1_hostService = V1_hostService;
this.V1_appService = V1_appService;
this.V1_appTypeService = V1_appTypeService;
this.V1_appInHostService = V1_appInHostService;
}
private async Task GetAppTypesAsync()
@@ -103,15 +118,15 @@ namespace PARR.AIHIT
if (!linkEK.StartsWith("ВРТ")) continue;
// var foundHost = await hostService.GetHostAsync(ip, linkEK, regionalEK);
var foundHost = await hostService.GetHostWithAppsAsync(ip, linkEK, regionalEK);
var foundHost = await V1_hostService.GetHostWithAppsAsync(ip, linkEK, regionalEK);
var mappedHost = mapper.Map<V1_Host>(vm);
var hostApplications = await GetAndFillApplicationsAsync(vm);
var hostApplications = await V1_GetAndFillApplicationsAsync(vm);
if (foundHost == null)
{
// создаем
if (!await hostService.CreateAsync(mappedHost) || !await hostService.CommitAsync())
if (!await V1_hostService.CreateAsync(mappedHost) || !await V1_hostService.CommitAsync())
{
logger.LogError($"Не удалось создать узел {mappedHost.IP} {mappedHost.RegionalEK}");
continue;
@@ -121,7 +136,7 @@ namespace PARR.AIHIT
// Синхронизация Applications
await SyncApplicationAndHostAsync(foundHost, hostApplications);
await V1_SyncApplicationAndHostAsync(foundHost, hostApplications);
}
else
{
@@ -170,14 +185,14 @@ namespace PARR.AIHIT
if (isChanged)
{
foundHost.DateModified = DateTimeOffset.UtcNow;
if (!await hostService.CommitAsync())
if (!await V1_hostService.CommitAsync())
logger.LogError($"Не удалось обновить узел {mappedHost.IP} {mappedHost.RegionalEK}");
else
logger.LogInformation($"----- Обновлён Host: {mappedHost.Id}, {mappedHost.LinkEK} -----");
}
// Синхронизация Applications
await SyncApplicationAndHostAsync(foundHost, hostApplications, true);
await V1_SyncApplicationAndHostAsync(foundHost, hostApplications, true);
}
}
}
@@ -194,7 +209,7 @@ namespace PARR.AIHIT
public async Task InvokeFromDatabase()
{
await GetAppTypesAsync();
/*
//Получаем зоны ответственности из БД
var respAreas = settingService.Get().Where(ra => ra.Group == AIHTITSettings.RespAreaGroupName).ToList();
@@ -294,11 +309,63 @@ namespace PARR.AIHIT
var statusList = settingService.Get().Where(s => s.Group == AIHTITSettings.StatusGroupName).Select(s => s.Value.Trim()).ToList();
if (statusList == null || statusList.Count == 0) return;
var eks = rawDataEKService.Get().Where(e => e.IsActive == "t" && (e.Status != null && statusList.Contains(e.Status.Trim()))).ToList();
var eks = rawDataEKService.Get().Where(e => e.IsActive == "t"
&& (e.Status != null && statusList.Contains(e.Status.Trim()))
).ToList();
foreach (var ek in eks)
{
if (ek.IP == null) continue;
var foundHost = await hostService.GetHostWithAppsAsync(ek.IP);
var mappedHost = mapper.Map<Host>(ek);
var hostApplications = await GetAndFillApplicationsAsync(ek);
if (foundHost == null)
{
// создаем
if (!await hostService.CreateAsync(mappedHost) || !await hostService.CommitAsync())
{
logger.LogError($"Не удалось создать узел {mappedHost.IP}");
continue;
}
else
logger.LogInformation($"----- Создан Host: {mappedHost.Id} -----");
// Синхронизация Applications
await SyncApplicationAndHostAsync(foundHost, hostApplications);
}
else
{
// обновляем
var isChanged = false;
if (!foundHost.Status!.Equals(mappedHost.Status))
{
foundHost.Status = mappedHost.Status;
isChanged = true;
}
else if (!foundHost.WorkGroup!.Equals(mappedHost.WorkGroup))
{
foundHost.WorkGroup = mappedHost.WorkGroup;
isChanged = true;
}
if (isChanged)
{
foundHost.DateModified = DateTimeOffset.UtcNow;
if (!await hostService.CommitAsync())
logger.LogError($"Не удалось обновить узел {mappedHost.IP}");
else
logger.LogInformation($"----- Обновлён Host: {mappedHost.Id} -----");
}
// Синхронизация Applications
await SyncApplicationAndHostAsync(foundHost, hostApplications, true);
}
}
}
private async Task SyncApplicationAndHostAsync(V1_Host? host, List<V1_Application> hostApplications, bool isUpdateDateModified = false)
private async Task V1_SyncApplicationAndHostAsync(V1_Host? host, List<V1_Application> hostApplications, bool isUpdateDateModified = false)
{
var isUpdated = false;
if (host == null)
@@ -316,7 +383,7 @@ namespace PARR.AIHIT
logger.LogInformation($"Host: {host.Id}, {host.LinkEK} добавление нового приложения Application {changedHostApp.Name}");
var newAppHost = new V1_ApplicationInHost { Id = Guid.NewGuid(), ApplicationId = changedHostApp.Id, HostId = host.Id };
if (!await appInHostService.CreateAsync(newAppHost))
if (!await V1_appInHostService.CreateAsync(newAppHost))
logger.LogError($"Не удалось создать ApplicationInHost {changedHostApp.Name}, host: {host.Id}, {host.LinkEK}");
isUpdated = true;
@@ -330,11 +397,11 @@ namespace PARR.AIHIT
if (appToRemove == null)
{
//todo remove appToRemove
var obj = await appInHostService.Get().FirstOrDefaultAsync(t => t.ApplicationId == app.Id && t.HostId == host.Id);
var obj = await V1_appInHostService.Get().FirstOrDefaultAsync(t => t.ApplicationId == app.Id && t.HostId == host.Id);
if (obj != null)
{
logger.LogInformation($"Host: {host.Id}, {host.LinkEK} удаление неактуального приложения Application {app.Application?.Name}");
appInHostService.Delete(obj);
V1_appInHostService.Delete(obj);
isUpdated = true;
}
@@ -351,7 +418,7 @@ namespace PARR.AIHIT
}
private async Task<List<V1_Application>> GetAndFillApplicationsAsync(XmlNode vm)
private async Task<List<V1_Application>> V1_GetAndFillApplicationsAsync(XmlNode vm)
{
logger.LogInformation($"--- Начало парсинга данных о программном обеспечении(СП, БД, ОС) из Xml документа от АИХ ИТ ---");
var applications = new List<V1_Application>();
@@ -362,21 +429,21 @@ namespace PARR.AIHIT
var appList = GetAppFromXML(vm?.Attributes?["СП"]?.Value);
foreach (var app in appList)
{
var created = await CreateAppIfNotExistAsync(app, ApplicationTypesEnum.APP);
var created = await V1_CreateAppIfNotExistAsync(app, ApplicationTypesEnum.APP);
if (created != null)
applications.Add(created);
}
var dbList = GetAppFromXML(vm?.Attributes?["СУБД"]?.Value);
foreach (var db in dbList)
{
var created = await CreateAppIfNotExistAsync(db, ApplicationTypesEnum.DB);
var created = await V1_CreateAppIfNotExistAsync(db, ApplicationTypesEnum.DB);
if (created != null)
applications.Add(created);
}
var osList = GetAppFromXML(vm?.Attributes?["ОС"]?.Value);
foreach (var os in appList)
{
var created = await CreateAppIfNotExistAsync(os, ApplicationTypesEnum.OS);
var created = await V1_CreateAppIfNotExistAsync(os, ApplicationTypesEnum.OS);
if (created != null)
applications.Add(created);
}
@@ -386,6 +453,99 @@ namespace PARR.AIHIT
return applications;
}
private async Task SyncApplicationAndHostAsync(Host? host, List<Application> hostApplications, bool isUpdateDateModified = false)
{
var isUpdated = false;
if (host == null)
return;
logger.LogInformation($"--- Host: {host.Id}, начало синхронизации приложений ({hostApplications.Count()}) ---");
foreach (var changedHostApp in hostApplications)
{
var exist = host.ApplicationsInHosts.FirstOrDefault(a => a.ApplicationId == changedHostApp.Id);
if (exist == null)
{
//add
logger.LogInformation($"Host: {host.Id}, добавление нового приложения Application {changedHostApp.Name}");
var newAppHost = new ApplicationInHost { Id = Guid.NewGuid(), ApplicationId = changedHostApp.Id, HostId = host.Id };
if (!await appInHostService.CreateAsync(newAppHost))
logger.LogError($"Не удалось создать ApplicationInHost {changedHostApp.Name}, host: {host.Id}");
isUpdated = true;
}
}
foreach (var app in host.ApplicationsInHosts)
{
var appToRemove = hostApplications.FirstOrDefault(a => a.Id == app.Id);
if (appToRemove == null)
{
//todo remove appToRemove
var obj = await appInHostService.Get().FirstOrDefaultAsync(t => t.ApplicationId == app.Id && t.HostId == host.Id);
if (obj != null)
{
logger.LogInformation($"Host: {host.Id}, удаление неактуального приложения Application {app.Application?.Name}");
appInHostService.Delete(obj);
isUpdated = true;
}
}
}
if (isUpdated && isUpdateDateModified)
host.DateModified = DateTimeOffset.UtcNow;
if (!await appInHostService.CommitAsync())
logger.LogError($"Не удалось обновить ApplicationInHost для Host: {host.Id}");
logger.LogInformation($"=== Host: {host.Id} конец синхронизации приложений ===");
}
private async Task<List<Application>> GetAndFillApplicationsAsync(RawDataEK vm)
{
logger.LogInformation($"--- Начало парсинга данных о программном обеспечении(СП, БД, ОС) из АИХ ИТ ---");
var applications = new List<Application>();
if (vm.APPType != null)
{
var appList = vm.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 (vm.DBType != null)
{
var appList = vm.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 (vm.ClientOS != null)
{
var appList = vm.ClientOS.Split(new char[] { ',', ';' }).Distinct().ToList();
foreach (var app in appList)
{
var created = await CreateAppIfNotExistAsync(app, ApplicationTypesEnum.OS);
if (created != null)
applications.Add(created);
}
}
logger.LogInformation($"=== Конец парсинга данных о программном обеспечении(СП, БД, ОС) из АИХ ИТ ===");
return applications;
}
private List<string> GetAppFromXML(string? appField)
{
if (string.IsNullOrEmpty(appField))
@@ -419,7 +579,38 @@ namespace PARR.AIHIT
return osList;
}
private async Task<V1_Application?> CreateAppIfNotExistAsync(string appName, ApplicationTypesEnum type)//Application application)
private async Task<V1_Application?> V1_CreateAppIfNotExistAsync(string appName, ApplicationTypesEnum type)//Application application)
{
if (string.IsNullOrEmpty(appName) || string.IsNullOrWhiteSpace(appName)) return null;
var existApp = await V1_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 V1_Application
{
Id = Guid.NewGuid(),
Name = appName.Trim(),
ApplicationTypeId = appType.Id
};
if (!await V1_appService.CreateAsync(app) || !await V1_appService.CommitAsync())
logger.LogError($"Не удалось создать запись в таблице Application: {appName}, {app.ToJson()}");
else
logger.LogInformation($"Создана запись а таблице Application: {appName}, {app.ToJson()}");
return await V1_appService.GetAsync(app.Id);
}
private async Task<Application?> CreateAppIfNotExistAsync(string appName, ApplicationTypesEnum type)//Application application)
{
if (string.IsNullOrEmpty(appName) || string.IsNullOrWhiteSpace(appName)) return null;
@@ -435,7 +626,7 @@ namespace PARR.AIHIT
return null;
}
var app = new DAL.Models.V1.V1_Application
var app = new Application
{
Id = Guid.NewGuid(),
Name = appName.Trim(),
@@ -450,7 +641,7 @@ namespace PARR.AIHIT
return await appService.GetAsync(app.Id);
}
private V1_ApplicationType? GetAppTypeByName(ApplicationTypesEnum type)
private ApplicationType? GetAppTypeByName(ApplicationTypesEnum type)
{
var existType = AppTypes.FirstOrDefault(t => t.Name == type.ToString());
if (existType == null)