Files
parr_api/PARR.EsppScheduleSync/ScheduleSyncher.cs

372 lines
17 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using PARR.BLL.Helpers;
using PARR.BLL.Services.Interfaces;
using PARR.DAL.Contracts;
using PARR.DAL.Models;
using PARR.DAL.Services.Interfaces;
using PARR.EsppScheduleSync.Domain;
using PARR.EsppScheduleSync.Settings;
using PARR.EsppSync;
using System.Linq;
namespace PARR.EsppScheduleSync
{
internal class ScheduleSyncher : IScheduleSyncher
{
private readonly ILogger<ScheduleSyncher> logger;
private readonly GlobalSettings globalSettings;
private readonly IMqService mqService;
private readonly ISyncService<EsppObjectSchedule> syncService;
private readonly SettingsFromDb settingsFromDb;
private readonly IServiceProvider serviceProvider;
public ScheduleSyncher(
ILogger<ScheduleSyncher> logger,
GlobalSettings globalSettings,
IMqService mqService,
ISyncService<EsppObjectSchedule> syncService,
SettingsFromDb settingsFromDb,
IServiceProvider serviceProvider
)
{
this.logger = logger;
this.globalSettings = globalSettings;
this.mqService = mqService;
this.syncService = syncService;
this.settingsFromDb = settingsFromDb;
this.serviceProvider = serviceProvider;
if (globalSettings.MqSettings == null)
{
logger.LogError("Нет секции настроек хранилища. MqSettings, EsppTemplates");
throw new Exception("Нет секции настроек хранилища. MqSettings, EsppTemplates");
}
}
public void Start()
{
var isConnected = mqService.InitConsumer(globalSettings!.MqSettings!, SyncScheduleAsync);
if (!isConnected)
throw new Exception("Ошибка при подключении к RabbitMq");
logger.LogInformation($"Запущена проверка очереди {globalSettings.MqSettings!.QueueName}.");
}
public void Stop()
{
mqService.Dispose();
logger.LogInformation($"=== === === Соединение с очередью {globalSettings.MqSettings!.QueueName} закрыто === === ===");
}
private async Task SyncScheduleAsync(string str)
{
await syncService.SyncEsppObjectAsync(str, ParseStrToEsppObject, ConvertDbObjToEsppObj);
}
/// <summary>
/// Преобразование модели БД в модель для сравнения
/// </summary>
/// <param name="template"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
private EsppObjectSchedule ConvertDbObjToEsppObj(Template template)
{
var esppObjectFromDb = new EsppObjectSchedule
{
TemplateName = template.Name,
Code = template.ScheduleEsppId ?? "",
ScheduleName = template.Name,
IsActive = template.IsActiveSchedule,
ResponseArea = template.Host!.ResponseArea!.Name,
WorkGroup = template.Host!.WorkGroup!,
//Мы решили, что для всех расписаний "Нет исключений", если что-то поменяется, тут нужно переделать
TypeV60calendar = settingsFromDb.ScheduleExclude == "Нет исключений" ? "NONE" : "",
Scheduled = EsppScheduleHelpers.GetNextRun(template.ApplicationsInWork!.NextRun),
Timezone = settingsFromDb.ScheduleTimezone,
//Мы решили, что для всех расписаний "Отсутствует дата завершения", если что-то поменяется, тут нужно переделать
TerminationType = settingsFromDb.ScheduleRepeatRange == "Отсутствует дата завершения" ? "forever" : "",
CompleteAfter = "",
V60calendar = ""
};
FillScheduleFromDb(template, ref esppObjectFromDb);
return ClearOptionalFields(esppObjectFromDb);
}
/// <summary>
/// Заполнить расписание из БД
/// </summary>
/// <returns></returns>
private void FillScheduleFromDb(Template template, ref EsppObjectSchedule esppObject)
{
using (var scope = serviceProvider.CreateScope())
{
var esppSchTypeConfigService = scope.ServiceProvider.GetService<IEsppSchTypeConfigService>();
if (esppSchTypeConfigService == null)
throw new Exception($"Не найден сервис: {nameof(IEsppSchTypeConfigService)}");
var esppSchedule = esppSchTypeConfigService.GetEsppScheduleDto(template.ApplicationInWorkId);
if (esppSchedule == null)
{
logger.LogError($"Не смог получить расписание из БД для шаблона templateId: {template.Id}, {template.Name}");
return;
}
var typeSchedule = GetTypeScheduleByString(esppSchedule.TypeSchedule.Name);
if (!typeSchedule.HasValue)
return;
//тип повторения
esppObject.TypeSchedule = typeSchedule.Value;
//в зависимости от типа, присваиваем значения
switch (esppObject.TypeSchedule)
{
case EsppSchTypeScheduleEnum.Regularly:
esppObject.Interval = esppSchedule.Values.First(t => t.Order == 0).Value.EsppExportValue;
break;
case EsppSchTypeScheduleEnum.Weekly:
esppObject.Dayofweek = esppSchedule.Values.First(t => t.Order == 0).Value.EsppExportValue;
break;
case EsppSchTypeScheduleEnum.Monthly:
esppObject.Dayofmonth = esppSchedule.Values.First(t => t.Order == 0).Value.EsppExportValue;
break;
case EsppSchTypeScheduleEnum.Monthly2:
esppObject.Md1 = esppSchedule.Values.First(t => t.Order == 0).Value.EsppExportValue;
esppObject.Md2 = esppSchedule.Values.First(t => t.Order == 1).Value.EsppExportValue;
break;
case EsppSchTypeScheduleEnum.Annually:
esppObject.Annualm = esppSchedule.Values.First(t => t.Order == 0).Value.EsppExportValue;
esppObject.Annualday = esppSchedule.Values.First(t => t.Order == 1).Value.EsppExportValue;
break;
case EsppSchTypeScheduleEnum.Annually2:
esppObject.An1 = esppSchedule.Values.First(t => t.Order == 0).Value.EsppExportValue;
esppObject.An2 = esppSchedule.Values.First(t => t.Order == 1).Value.EsppExportValue;
esppObject.An3 = esppSchedule.Values.First(t => t.Order == 2).Value.EsppExportValue;
break;
}
}
}
/// <summary>
/// Парсинг из строки в модель для сравнения
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
/// <exception cref="NotImplementedException"></exception>
private EsppObjectSchedule? ParseStrToEsppObject(string str)
{
var splittedContent = str.Split(globalSettings.ParsingSeparator);
if (splittedContent.Length != 23)
{
logger.LogError($"Входная строка после сплита не содержит 23 объекта (факт: {splittedContent.Length}).");
return null;
}
var templateName = splittedContent[6];
var scheduleName = splittedContent[2];
if (!IsValidName(templateName) || !IsValidName(scheduleName))
return null;
bool.TryParse(splittedContent[1].Trim(), out var isActive);
var typeSchedule = GetTypeScheduleByString(splittedContent[7]);
if (!typeSchedule.HasValue)
return null;
var esppObject = new EsppObjectSchedule
{
TemplateName = templateName,
Code = splittedContent[0],
ScheduleName = scheduleName,
IsActive = isActive,
ResponseArea = splittedContent[5],
WorkGroup = splittedContent[3],
TypeSchedule = typeSchedule.Value,
Interval = splittedContent[8],
Dayofweek = splittedContent[15],
Dayofmonth = splittedContent[14],
Md1 = splittedContent[16],
Md2 = splittedContent[17],
Annualm = splittedContent[13],
Annualday = splittedContent[12],
An1 = splittedContent[9],
An2 = splittedContent[10],
An3 = splittedContent[11],
TypeV60calendar = splittedContent[21],
Scheduled = splittedContent[4],
Timezone = splittedContent[18],
TerminationType = splittedContent[19],
CompleteAfter = splittedContent[20],
V60calendar = splittedContent[22]
};
return ClearOptionalFields(esppObject);
}
/// <summary>
/// Преобразовать из строки в Тип Повторения
/// </summary>
/// <param name="typeSchedule"></param>
/// <returns></returns>
private EsppSchTypeScheduleEnum? GetTypeScheduleByString(string typeSchedule)
{
typeSchedule = typeSchedule.ToLower();
//Regularly, Регулярно (значение в ЕСПП и в БД не совпадают, в бд Regularly, в ЕСПП simple)
if (typeSchedule == "simple" || typeSchedule == EsppSchTypeScheduleEnum.Regularly.ToString().ToLower())
return EsppSchTypeScheduleEnum.Regularly;
if (typeSchedule == EsppSchTypeScheduleEnum.Weekly.ToString().ToLower())
return EsppSchTypeScheduleEnum.Weekly;
if (typeSchedule == EsppSchTypeScheduleEnum.Monthly.ToString().ToLower())
return EsppSchTypeScheduleEnum.Monthly;
if (typeSchedule == EsppSchTypeScheduleEnum.Monthly2.ToString().ToLower())
return EsppSchTypeScheduleEnum.Monthly2;
if (typeSchedule == EsppSchTypeScheduleEnum.Annually.ToString().ToLower())
return EsppSchTypeScheduleEnum.Annually;
if (typeSchedule == EsppSchTypeScheduleEnum.Annually2.ToString().ToLower())
return EsppSchTypeScheduleEnum.Annually2;
logger.LogError($"Не смог преобразовать Тип повторения из ЕСПП в EsppSchTypeScheduleEnum. Получено значение {typeSchedule}");
return null;
}
/// <summary>
/// Проверка имени шаблона и расписание на соответствие префиксу из настроек
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
private bool IsValidName(string name)
{
var currentCulture = Thread.CurrentThread.CurrentCulture;
//if (!string.IsNullOrEmpty(settingsFromDb.TemplatePrefixName) && name.StartsWith(settingsFromDb.TemplatePrefixName, true, currentCulture))
// return true;
if (!string.IsNullOrEmpty(settingsFromDb.TemplatePrefixWithoutVariable) && name.Contains(settingsFromDb.TemplatePrefixWithoutVariable)) // , StringComparison.CurrentCultureIgnoreCase
return true;
logger.LogWarning($"Имя шаблона или расписания не соответствует обязательному префиксу({settingsFromDb.TemplatePrefixWithoutVariable}). {name} игнорирован");
return false;
}
/// <summary>
/// Очистка полей которые не нуждаются в синхронизации
/// </summary>
/// <param name="esppObject"></param>
/// <returns></returns>
private EsppObjectSchedule ClearOptionalFields(EsppObjectSchedule esppObject)
{
esppObject.Code = string.Empty;
esppObject.ScheduleName = string.Empty;
esppObject.ResponseArea = string.Empty;
esppObject.WorkGroup = string.Empty;
esppObject.CompleteAfter = string.Empty;
esppObject.V60calendar = string.Empty;
// В ЕСПП, при изменении "Повторять задачу", остаются предыдущие значения, их не нужно синхронизировать (касается только данных полученных из ЕСПП, в БД все ок)
// т.е. если стояло Ежедненвно:понедельник, а изменили например на Еженедельно..., то в ежедневно значения останутся, но будут отрабатывать значения из Еженедельно.
// Т е значения из Ежедненвно проверять не нужно, вот их и будем очищать
switch (esppObject.TypeSchedule)
{
case EsppSchTypeScheduleEnum.Regularly:
//esppObject.Interval = string.Empty;
esppObject.Dayofweek = string.Empty;
esppObject.Dayofmonth = string.Empty;
esppObject.Md1 = string.Empty;
esppObject.Md2 = string.Empty;
esppObject.Annualm = string.Empty;
esppObject.Annualday = string.Empty;
esppObject.An1 = string.Empty;
esppObject.An2 = string.Empty;
esppObject.An3 = string.Empty;
break;
case EsppSchTypeScheduleEnum.Weekly:
esppObject.Interval = string.Empty;
//esppObject.Dayofweek = string.Empty;
esppObject.Dayofmonth = string.Empty;
esppObject.Md1 = string.Empty;
esppObject.Md2 = string.Empty;
esppObject.Annualm = string.Empty;
esppObject.Annualday = string.Empty;
esppObject.An1 = string.Empty;
esppObject.An2 = string.Empty;
esppObject.An3 = string.Empty;
break;
case EsppSchTypeScheduleEnum.Monthly:
esppObject.Interval = string.Empty;
esppObject.Dayofweek = string.Empty;
//esppObject.Dayofmonth = string.Empty;
esppObject.Md1 = string.Empty;
esppObject.Md2 = string.Empty;
esppObject.Annualm = string.Empty;
esppObject.Annualday = string.Empty;
esppObject.An1 = string.Empty;
esppObject.An2 = string.Empty;
esppObject.An3 = string.Empty;
break;
case EsppSchTypeScheduleEnum.Monthly2:
esppObject.Interval = string.Empty;
esppObject.Dayofweek = string.Empty;
esppObject.Dayofmonth = string.Empty;
//esppObject.Md1 = string.Empty;
//esppObject.Md2 = string.Empty;
esppObject.Annualm = string.Empty;
esppObject.Annualday = string.Empty;
esppObject.An1 = string.Empty;
esppObject.An2 = string.Empty;
esppObject.An3 = string.Empty;
break;
case EsppSchTypeScheduleEnum.Annually:
esppObject.Interval = string.Empty;
esppObject.Dayofweek = string.Empty;
esppObject.Dayofmonth = string.Empty;
esppObject.Md1 = string.Empty;
esppObject.Md2 = string.Empty;
//esppObject.Annualm = string.Empty;
//esppObject.Annualday = string.Empty;
esppObject.An1 = string.Empty;
esppObject.An2 = string.Empty;
esppObject.An3 = string.Empty;
break;
case EsppSchTypeScheduleEnum.Annually2:
esppObject.Interval = string.Empty;
esppObject.Dayofweek = string.Empty;
esppObject.Dayofmonth = string.Empty;
esppObject.Md1 = string.Empty;
esppObject.Md2 = string.Empty;
esppObject.Annualm = string.Empty;
esppObject.Annualday = string.Empty;
//esppObject.An1 = string.Empty;
//esppObject.An2 = string.Empty;
//esppObject.An3 = string.Empty;
break;
}
return esppObject;
}
}
}