feat(aihitMainSyncer): Написана логика создания новых Unit и Field.
This commit is contained in:
55
PARR.AIHITMainSyncer/AihitMainSyncer.cs
Normal file
55
PARR.AIHITMainSyncer/AihitMainSyncer.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using PARR.AIHITMainSyncer.Services;
|
||||
using PARR.AIHITMainSyncer.Settings;
|
||||
using PARR.BLL.Services.Interfaces;
|
||||
|
||||
namespace PARR.AIHITMainSyncer
|
||||
{
|
||||
internal class AihitMainSyncer : IAihitMainSyncer
|
||||
{
|
||||
private readonly ILogger<AihitMainSyncer> logger;
|
||||
private readonly IMqService mqService;
|
||||
private readonly MqSettings mqSettings;
|
||||
private readonly IServiceProvider serviceProvider;
|
||||
|
||||
public AihitMainSyncer(
|
||||
ILogger<AihitMainSyncer> logger,
|
||||
IMqService mqService,
|
||||
MqSettings mqSettings,
|
||||
IServiceProvider serviceProvider
|
||||
)
|
||||
{
|
||||
this.logger = logger;
|
||||
this.mqService = mqService;
|
||||
this.mqSettings = mqSettings;
|
||||
this.serviceProvider = serviceProvider;
|
||||
}
|
||||
public void Start()
|
||||
{
|
||||
logger.LogInformation("Запуск сервиса синхронизации данных из АИХИТ и ПАРР.");
|
||||
|
||||
var isConnected = mqService.InitConsumer(mqSettings, async (string msg) =>
|
||||
{
|
||||
using (var scope = serviceProvider.CreateScope())
|
||||
{
|
||||
var syncerService = scope.ServiceProvider.GetService<ISyncerService>();
|
||||
if (syncerService == null)
|
||||
throw new Exception("Не смог получить серивс ISyncerService, scope.ServiceProvider.GetService<ISyncerService>()");
|
||||
|
||||
await syncerService.SyncAsync(msg);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
if (!isConnected)
|
||||
throw new Exception("Ошибка при подключении к RabbitMq");
|
||||
}
|
||||
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
mqService.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
43
PARR.AIHITMainSyncer/AihitMainSyncerInstaller.cs
Normal file
43
PARR.AIHITMainSyncer/AihitMainSyncerInstaller.cs
Normal file
@@ -0,0 +1,43 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using PARR.AIHITMainSyncer.Services;
|
||||
using PARR.AIHITMainSyncer.Settings;
|
||||
using PARR.BLL;
|
||||
using PARR.DAL;
|
||||
|
||||
namespace PARR.AIHITMainSyncer
|
||||
{
|
||||
public static class AihitMainSyncerInstaller
|
||||
{
|
||||
public static void InstallAihitMainSyncerServices(this IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
services.InstallBllServices(configuration);
|
||||
services.InstallDalServices(configuration);
|
||||
|
||||
var settings = new WorkerSettings();
|
||||
configuration.GetSection(nameof(WorkerSettings)).Bind(settings);
|
||||
services.AddSingleton(settings);
|
||||
|
||||
var mqSettings = new MqSettings();
|
||||
configuration.GetSection(nameof(MqSettings)).Bind(mqSettings);
|
||||
services.AddSingleton(mqSettings);
|
||||
|
||||
services.AddTransient<IAihitMainSyncer, AihitMainSyncer>();
|
||||
services.AddTransient<ISyncerService, SyncerService>();
|
||||
}
|
||||
|
||||
|
||||
public static IConfigurationBuilder AddAihitMainSyncerConfigurations(this IConfigurationBuilder builder, IServiceCollection services)
|
||||
{
|
||||
builder.AddDalConfigurations(services);
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
|
||||
public static void AddAihitMainSyncerSettings(this IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
services.AddDallSettings(configuration);
|
||||
}
|
||||
}
|
||||
}
|
||||
10
PARR.AIHITMainSyncer/IAihitMainSyncer.cs
Normal file
10
PARR.AIHITMainSyncer/IAihitMainSyncer.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
namespace PARR.AIHITMainSyncer
|
||||
{
|
||||
public interface IAihitMainSyncer
|
||||
{
|
||||
void Start();
|
||||
|
||||
|
||||
void Stop();
|
||||
}
|
||||
}
|
||||
14
PARR.AIHITMainSyncer/PARR.AIHITMainSyncer.csproj
Normal file
14
PARR.AIHITMainSyncer/PARR.AIHITMainSyncer.csproj
Normal file
@@ -0,0 +1,14 @@
|
||||
<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" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
7
PARR.AIHITMainSyncer/Services/ISyncerService.cs
Normal file
7
PARR.AIHITMainSyncer/Services/ISyncerService.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace PARR.AIHITMainSyncer.Services
|
||||
{
|
||||
public interface ISyncerService
|
||||
{
|
||||
Task SyncAsync(string msg);
|
||||
}
|
||||
}
|
||||
136
PARR.AIHITMainSyncer/Services/SyncerService.cs
Normal file
136
PARR.AIHITMainSyncer/Services/SyncerService.cs
Normal file
@@ -0,0 +1,136 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using PARR.BLL.Domain.Mq;
|
||||
using PARR.BLL.Services.Interfaces;
|
||||
using PARR.DAL.Extensions;
|
||||
using PARR.DAL.Models.Unit;
|
||||
using PARR.DAL.Services.Interfaces.Unit;
|
||||
|
||||
namespace PARR.AIHITMainSyncer.Services
|
||||
{
|
||||
internal class SyncerService : ISyncerService
|
||||
{
|
||||
private readonly ILogger<SyncerService> logger;
|
||||
private readonly ITransformService transformService;
|
||||
private readonly IUnitService unitService;
|
||||
private readonly IUnitFieldService unitFieldService;
|
||||
|
||||
public SyncerService(
|
||||
ILogger<SyncerService> logger,
|
||||
ITransformService transformService,
|
||||
IUnitService unitService,
|
||||
IUnitFieldService unitFieldService
|
||||
)
|
||||
{
|
||||
this.logger = logger;
|
||||
this.transformService = transformService;
|
||||
this.unitService = unitService;
|
||||
this.unitFieldService = unitFieldService;
|
||||
}
|
||||
|
||||
|
||||
public async Task SyncAsync(string msg)
|
||||
{
|
||||
logger.LogInformation("Запуск синхронизации данных из очереди сообщений в ПАРР.");
|
||||
var objFromQuery = transformService.GetModelFromJson<AihitMainDataMq>(msg);
|
||||
if (objFromQuery == null)
|
||||
return;
|
||||
|
||||
await SyncUnitAsync(objFromQuery);
|
||||
}
|
||||
|
||||
|
||||
private async Task SyncUnitAsync(AihitMainDataMq objFromQuery)
|
||||
{
|
||||
var fields = await GetFieldsInObjectAsync(objFromQuery);
|
||||
|
||||
var unit = await unitService.GetUnitWithFieldsAsync(objFromQuery.Name);
|
||||
|
||||
if (unit == null)
|
||||
unit = await CreateUnitAsync(objFromQuery);
|
||||
else
|
||||
logger.LogDebug($"Найден Unit в БД: {unit.Name})");
|
||||
|
||||
await SyncFieldInUnitAsync(unit!, fields);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
private async Task SyncFieldInUnitAsync(Unit unit, List<Guid> fieldsId)
|
||||
{
|
||||
var isChanged = false;
|
||||
|
||||
//Смотрим какие поля нам прислали, есть новые?
|
||||
var newFields = fieldsId.Except(unit.UnitFields.Select(uf => uf.FieldId)).ToList();
|
||||
|
||||
//добавляем если есть
|
||||
if (newFields.Any())
|
||||
{
|
||||
if (!isChanged)
|
||||
isChanged = true;
|
||||
newFields.ForEach(uf =>
|
||||
{
|
||||
unit.UnitFields.Add(
|
||||
new UnitInField { UnitId = unit.Id, FieldId = uf, DateCreated = DateTimeOffset.UtcNow }
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
//TODO: Удаление неактуальных
|
||||
|
||||
if (isChanged && !await unitFieldService.CommitAsync())
|
||||
logger.LogError($"Не удалось изменить набор Fields в Unit {unit.Name}");
|
||||
else
|
||||
logger.LogInformation($"----- Набор Fields в Unit изменён: {unit.Name} -----");
|
||||
}
|
||||
|
||||
private async Task<List<Guid>> GetFieldsInObjectAsync(AihitMainDataMq objFromQuery)
|
||||
{
|
||||
var fields = new List<Guid>();
|
||||
|
||||
foreach (var item in objFromQuery.Properties)
|
||||
{
|
||||
var field = await CreateUnitFieldIfNotExistAsync(item.Key);
|
||||
fields.Add(field!.Id);
|
||||
}
|
||||
|
||||
return fields;
|
||||
}
|
||||
|
||||
|
||||
private async Task<Unit?> CreateUnitAsync(AihitMainDataMq objFromQuery)
|
||||
{
|
||||
var unit = new Unit { Name = objFromQuery.Name.Trim() };
|
||||
|
||||
if (!await unitService.CreateAsync(unit) || !await unitService.CommitAsync())
|
||||
logger.LogError($"Не удалось создать Unit {unit.Name}");
|
||||
else
|
||||
logger.LogInformation($"----- Создан Unit: {unit.Name} -----");
|
||||
|
||||
return await unitService.GetUnitWithFieldsAsync(unit.Name);
|
||||
}
|
||||
|
||||
|
||||
private async Task<UnitField?> CreateUnitFieldIfNotExistAsync(string name)
|
||||
{
|
||||
var existUnitField = await unitFieldService.GetByAihitNameAsync(name);
|
||||
|
||||
if (existUnitField != null)
|
||||
return existUnitField;
|
||||
|
||||
var field = new UnitField
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
AihitName = name.Trim(),
|
||||
EsppName = null
|
||||
};
|
||||
|
||||
if (!await unitFieldService.CreateAsync(field) || !await unitFieldService.CommitAsync())
|
||||
logger.LogError($"Не удалось создать запись в таблице Fields: {name}, {field.ToJson()}");
|
||||
else
|
||||
logger.LogInformation($"Создана запись а таблице Fields: {name}, {field.ToJson()}");
|
||||
|
||||
return await unitFieldService.GetAsync(field.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
15
PARR.AIHITMainSyncer/Settings/MqSettings.cs
Normal file
15
PARR.AIHITMainSyncer/Settings/MqSettings.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using PARR.BLL.Contracts.Interfaces;
|
||||
|
||||
namespace PARR.AIHITMainSyncer.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;
|
||||
}
|
||||
}
|
||||
7
PARR.AIHITMainSyncer/Settings/WorkerSettings.cs
Normal file
7
PARR.AIHITMainSyncer/Settings/WorkerSettings.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace PARR.AIHITMainSyncer.Settings
|
||||
{
|
||||
internal class WorkerSettings
|
||||
{
|
||||
public TimeSpan RepeatEvery { get; set; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user