feat(api): Логика смены статусов для заданий робота. RobotTaskController

This commit is contained in:
Mikhail Trubnikov
2023-10-05 16:56:02 +10:00
parent 4679994600
commit af4a0b60b8
26 changed files with 2779 additions and 126 deletions

View File

@@ -0,0 +1,109 @@
using AutoMapper;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using PARR.API.Contracts.V1;
using PARR.API.Contracts.V1.Responses;
using PARR.API.Contracts.V1.Responses.Base;
using PARR.API.Controllers.V1.Base;
using PARR.DAL.Contracts;
using PARR.DAL.Models;
using PARR.DAL.Services.Interfaces;
namespace PARR.API.Controllers.V1
{
public class RobotTaskController : BaseApiController
{
private readonly IMapper mapper;
private readonly SettingsFromDb settingsFromDb;
private readonly IRobotConfigurationService robotConfigurationService;
public RobotTaskController(
IMapper mapper,
SettingsFromDb settingsFromDb,
IRobotConfigurationService robotConfigurationService
)
{
this.mapper = mapper;
this.settingsFromDb = settingsFromDb;
this.robotConfigurationService = robotConfigurationService;
}
/// <summary>
/// Получить задание для робота по коду робота и по статусу задания
/// </summary>
/// <param name="robotCode"></param>
/// <param name="taskStatusCode"></param>
/// <returns></returns>
[HttpGet(ApiRoutes.RobotTask.GetByRobotAndStatusTask)]
public async Task<IActionResult> GetByRobotAndStatusTask([FromRoute] RobotsEnum robotCode, [FromRoute] TaskStatusEnum taskStatusCode)
{
//Ищем все задания с превышенным кол-вом попыток и с просроченным временем и ставим им статус ошибки
await robotConfigurationService.FindUnfulfilledTaskAndSetRobotErrorStatusAsync(settingsFromDb.RobotAttemptsNumber, settingsFromDb.RobotWaitTime);
var query = robotConfigurationService.Get()
.Where(t => t.RobotCode == (int)robotCode && t.TaskStatusCode == (int)taskStatusCode)
.AsSplitQuery();
switch (robotCode)
{
case RobotsEnum.TemplateOrder:
query = query.Include(t => t.Template)
.ThenInclude(t => t!.Host).ThenInclude(t => t!.ResponseArea)
.Include(t => t.Template)
.ThenInclude(t => t!.Host)
.Include(t => t.Template)
.ThenInclude(a => a!.ApplicationsInWork)
.ThenInclude(w => w!.Work)
.ThenInclude(t => t!.Tnk)
.ThenInclude(s => s!.Subprocess)
.ThenInclude(p => p!.Process);
break;
case RobotsEnum.ScheduleOrder:
//todo: include
break;
default:
break;
}
RobotConfiguration? task = null;
//ищем задание в ожидании, если нашли, выбираем ее
task = await query.FirstOrDefaultAsync(t => t.RobotStatusCode == (int)RobotStatusEnum.Wait);
if (task == null)
{
//ищем задания в работе, которые можно перезапустить
//Поиск пои `RobotStatusCode` = 22.
//Далее проверяется `LastStatusUpdated`, что время последнего смены статуса не превышает допустимого(берется из настроек, поле `RobotWaitTime`)
//и что текущая попытка не больше разрешенной(берется из настроек, поле `RobotAttemptsNumber`) - если это так, берется эта запись.
var endDate = DateTimeOffset.UtcNow.Add(-settingsFromDb.RobotWaitTime);
task = await query.FirstOrDefaultAsync(t =>
t.RobotStatusCode == (int)RobotStatusEnum.InProgress
&& t.AttemptsNumber < settingsFromDb.RobotAttemptsNumber
&& t.LastStatusUpdated < endDate
);
}
if (task == null)
return NotFound();
//TODO: сделать маппинг!!!
switch (robotCode)
{
case RobotsEnum.TemplateOrder:
//RobotTaskTemplateResponse
return Ok(new Response<RobotTaskTemplateResponse>(mapper.Map<RobotTaskTemplateResponse>(task), true));
case RobotsEnum.ScheduleOrder:
//RobotTaskScheduleResponse
return Ok(new Response<RobotTaskScheduleResponse>(mapper.Map<RobotTaskScheduleResponse>(task), true));
default:
break;
}
return BadRequest();
}
}
}

View File

@@ -95,29 +95,31 @@ namespace PARR.API.Controllers.V1
if (request.IdSeries == null)
request.IdSeries = Guid.NewGuid();
var historyItem = new RobotTemplateHistory
{
Id = Guid.NewGuid(),
HistoryLevel = request.HistoryLevel,
RobotMessage = request.RobotMessage,
EsppMessage = request.EsppMessage,
TemplateId = request.TemplateId,
TemplateStatusCode = template.StatusCode,
IdSeries = request.IdSeries.Value
};
//var historyItem = new RobotTemplateHistory
//{
// Id = Guid.NewGuid(),
// HistoryLevel = request.HistoryLevel,
// RobotMessage = request.RobotMessage,
// EsppMessage = request.EsppMessage,
// TemplateId = request.TemplateId,
// TemplateStatusCode = template.StatusCode,
// IdSeries = request.IdSeries.Value
//};
if (!await historyService.CreateAsync(historyItem) || !await historyService.CommitAsync())
return BadRequest(new Response(false, new List<ErrorModel> { new ErrorModel { Message = $"Ошибка при добавлении записи в историю" } }));
//if (!await historyService.CreateAsync(historyItem) || !await historyService.CommitAsync())
// return BadRequest(new Response(false, new List<ErrorModel> { new ErrorModel { Message = $"Ошибка при добавлении записи в историю" } }));
var createdObj = await historyService.Get()
.Include(t => t.Template)
.Include(t => t.RobotHistoryLevel)
.FirstOrDefaultAsync(t => t.Id == historyItem.Id);
//var createdObj = await historyService.Get()
// .Include(t => t.Template)
// .Include(t => t.RobotHistoryLevel)
// .FirstOrDefaultAsync(t => t.Id == historyItem.Id);
var response = mapper.Map<RobotTemplateHistoryResponse>(createdObj);
var createdUri = uriService.GetAllUri(ApiRoutes.RobotTemplateHistory.GetAll) + $"?{nameof(RobotTemplateHistoryQuery.IdSeries)}={createdObj!.IdSeries}";
//var response = mapper.Map<RobotTemplateHistoryResponse>(createdObj);
//var createdUri = uriService.GetAllUri(ApiRoutes.RobotTemplateHistory.GetAll) + $"?{nameof(RobotTemplateHistoryQuery.IdSeries)}={createdObj!.IdSeries}";
return Created(createdUri, new Response<RobotTemplateHistoryResponse>(response, true));
//return Created(createdUri, new Response<RobotTemplateHistoryResponse>(response, true));
return Ok("Доделать");
}
}

View File

@@ -51,14 +51,14 @@ namespace PARR.API.Controllers.V1
{
switch (filter.StatusCode.Value)
{
case (int)StatusTemplateEnum.Ok:
query = query.Where(t => t.StatusCode == (int)StatusTemplateEnum.Ok);
case (int)TaskStatusEnum.Ok:
query = query.Where(t => t.StatusCode == (int)TaskStatusEnum.Ok);
break;
case (int)StatusTemplateEnum.Creating:
query = query.Where(t => t.StatusCode == (int)StatusTemplateEnum.Creating);
case (int)TaskStatusEnum.Creating:
query = query.Where(t => t.StatusCode == (int)TaskStatusEnum.Creating);
break;
case (int)StatusTemplateEnum.Updating:
query = query.Where(t => t.StatusCode == (int)StatusTemplateEnum.Updating);
case (int)TaskStatusEnum.Updating:
query = query.Where(t => t.StatusCode == (int)TaskStatusEnum.Updating);
break;
default:
break;
@@ -170,7 +170,7 @@ namespace PARR.API.Controllers.V1
if (template == null)
return BadRequest(new Response(false, new List<ErrorModel> { new ErrorModel { Message = $"Не найден шаблон с id: {id}" } }));
template.StatusCode = (int)StatusTemplateEnum.Ok;
template.StatusCode = (int)TaskStatusEnum.Ok;
if (!await templateService.CommitAsync())
return BadRequest(new Response(false, new List<ErrorModel> { new ErrorModel { Message = $"Ошибка при изменении статуса у шаблона с id: {id}" } }));