Files
parr_api/PARR.API/Controllers/V1/JobController.cs

317 lines
14 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 AutoMapper;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using PARR.API.Contracts.V1;
using PARR.API.Contracts.V1.Requests.Queries;
using PARR.API.Contracts.V1.Responses;
using PARR.API.Contracts.V1.Responses.Base;
using PARR.API.Controllers.V1.Base;
using PARR.API.Extensions;
using PARR.API.MappingProfiles;
using PARR.API.Services.Interfaces;
using PARR.DAL.Contracts;
using PARR.DAL.DomainModels;
using PARR.DAL.Models;
using PARR.DAL.Services.Interfaces;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;
using static PARR.API.Contracts.V1.ApiRoutes;
namespace PARR.API.Controllers.V1
{
public class JobController : BaseApiController
{
private readonly IMapper mapper;
private readonly IJobService jobService;
//private readonly ISchedulerService schedulerService;
private readonly IClientService clientService;
private readonly IHostService hostService;
private readonly IJobJournalService jobJournalService;
public JobController(
IMapper mapper,
IJobService jobService,
IClientService clientService,
IHostService hostService,
IJobJournalService jobJournalService
)
{
this.mapper = mapper;
this.jobService = jobService;
//this.schedulerService = schedulerService;
this.clientService = clientService;
this.hostService = hostService;
this.jobJournalService = jobJournalService;
}
/// <summary>
/// Список всех jobов постранично в соотвествии с фильтрами
/// </summary>
/// <param name="paginationQuery"></param>
/// <returns></returns>
[HttpGet(ApiRoutes.Jobs.GetAll)]
public async Task<IActionResult> GetAll([FromQuery] PaginationQuery paginationQuery, [FromQuery] JobGetAllQuery filter)
{
var paginationFilter = mapper.Map<PaginationFilter>(paginationQuery);
IQueryable<Job> query = jobService.Get().Include(t => t.JobMode).OrderBy(s => s.StartAt);
if (filter.IsEnabled.HasValue)
query = query.Where(t => t.IsEnabled == filter.IsEnabled);
if (filter.StartDatePlanned.HasValue)
query = query.Where(t => t.StartAt.DateTime.Date <= filter.StartDatePlanned.Value.DateTime.Date); ;
var jobs = await jobService.GetPage(query, paginationFilter).ToListAsync();
if (!jobs.Any())
return NoContent();
var jobResponse = mapper.Map<List<JobGetAllResponse>>(jobs);
var paginationResponse = new PagedResponse<JobGetAllResponse>(jobResponse, true).GetPaginatedProps(paginationFilter, query);
return Ok(paginationResponse);
}
[HttpGet(ApiRoutes.Jobs.GetByIp)]
public async Task<IActionResult> GetByClientIP([FromQuery] JobGetByIpQuery requestQuery)
{
var ip = requestQuery.Ip ?? clientService.GetClientIp()?.ToString();
if (string.IsNullOrEmpty(ip))
return BadRequest(new Response(false, new List<ErrorModel> { new ErrorModel { Message = "Client IP address is null." } }));
var date = requestQuery.Date ?? DateTimeOffset.Now;
// С одним IP может быть несколько информационных систем, соответственного а таблице храниться несколько записей хостов с одинаковым IP
var hosts = await hostService.Get().Where(h => h.IP == ip).ToListAsync();
var hostJobsDict = new Dictionary<DAL.Models.Host, List<Job>>();
foreach (var host in hosts)
{
var jobsHost = await jobService.Get()
.Include(a => a.Application).ThenInclude(ah => ah.ApplicationsInHosts)/*.ThenInclude(h => h.Host)*/
.Include(jm => jm.JobMode)
.AsSplitQuery()
.Where(j => j.Application != null && j.Application.ApplicationsInHosts.Any(ah => ah.HostId == host.Id) && j.IsEnabled)
.ToListAsync();
if (jobsHost.Any())
{
hostJobsDict.Add(host, jobsHost);
}
}
var jobsList = new List<Job>();
var response = new Dictionary<string, string>();
foreach (var hostAndJobs in hostJobsDict)
{
hostAndJobs.Value.ForEach(async item =>
{
if (!jobsList.Contains(item))
{
jobsList.Add(item);
var plannedJobs = await GetListJobsAsync(item, hostAndJobs.Key, date);
//todo:!!! эти списки склеивать в один, отсортировать по дате и перегнать в дикт
//var baseTime = new DateTimeOffset(date.Year, date.Year, 01, 0, 0, 0, new TimeSpan(0));
////если более суток то идём в JobJournal и получаем дату последнегно запуска. Если нет то приравниваем к StartAt
//var freq = item.Frequency;
//if (true)
//{
//}
//var curTimeCreation = baseTime;
//while(curTimeCreation <= curTimeCreation.EndOfDay())
//{
// curTimeCreation=curTimeCreation.DateTime.AddMinutes(freq);
//}
//kaskjdhaskjkjasklhd
}
});
}
// var jobListForResponse = new
//var dic = new Dictionary<string, string>();
//dic.Add("sss1", "222");
//dic.Add("sss2", "333");
return Ok();
}
private async Task<List<Job>> GetListJobsAsync(Job job, DAL.Models.Host host, DateTimeOffset queryDate)
{
var jobs = new List<Job>();
// freaq > суток или нет?
//-----------
// меньше суток
//фрек=10 мин
// старт эт = 17:00 и != сегодня
//цикл 17:00 -10мин пока не начнется вчерашний день
//цикл 17:00 +10мин пока не начентся завтрашний день
// елси страт эт == сегодня
//цикл 17:00 +10мин пока не начентся завтрашний день
//-----------
// ------freaq больше суток--------
// журнал берем последнее событие (че там со статусами? не надо пока), к нему пребавляем фрек, и смотрим == сегодня или нет, если сегодня то добавляем
// --------------
var allDayMinutes = 1440;
if (job.Frequency >= allDayMinutes)
{
//больше или = суток
var lastJournalItem = await jobJournalService.GetLastAsync(job.Id, host.Id, queryDate);
if (lastJournalItem == null)
{
// если в истории нет записей, то запускаем сегодня в стартЭт
// берем квери дэйт и ем задаем время из Джобс СтартЭт
var startDateTimeNext = new DateTimeOffset(queryDate.Year, queryDate.Month, queryDate.Day, job.StartAt.Hour, job.StartAt.Minute, job.StartAt.Second, new TimeSpan(0));
//todo:
var jobToAdded = new Job { StartAt = startDateTimeNext };
jobs.Add(jobToAdded);
}
else
{
var startDateNext = lastJournalItem.DateOper.DateTime.AddMinutes(job.Frequency);
if (startDateNext.Date == queryDate.DateTime.Date)
{
// если берем прошлую последнюю операцию из журнала, и к ней прибавить фрекунси, то время следующего старта сдвинется на время выполнения прошлого задания
// чтобы это избежать, берем квери дэйт и ем задаем время из Джобс СтартЭт
var startDateTimeNext = new DateTimeOffset(queryDate.Year, queryDate.Month, queryDate.Day, job.StartAt.Hour, job.StartAt.Minute, job.StartAt.Second, new TimeSpan(0));
//todo:
var jobToAdded = new Job { StartAt = startDateTimeNext };
jobs.Add(jobToAdded);
}
}
}
else
{
//меньше суток
var startAtMinutes = (job.StartAt - job.StartAt.StartOfDay()).TotalMinutes;
// если дата старта != queryDate
if (job.StartAt.DateTime.Date != queryDate.DateTime.Date)
{
// отнимаем пока не наступили прошлые стуки
var min = startAtMinutes;
while (min > 0)
{
//TODO
var jobToAdded = new Job { StartAt = queryDate.StartOfDay().AddMinutes(min) };
jobs.Add(jobToAdded);
min = min - job.Frequency;
}
// прибавляем пока не наступят след сутки
while (min <= allDayMinutes)
{
//TODO
var jobToAdded = new Job { StartAt = queryDate.StartOfDay().AddMinutes(min) };
jobs.Add(jobToAdded);
min = min + job.Frequency;
}
}
else
{
// = queryDate
// прибавляем пока не наступят след сутки
var min = startAtMinutes;
while (min <= allDayMinutes)
{
//TODO
var jobToAdded = new Job { StartAt = queryDate.StartOfDay().AddMinutes(min) };
jobs.Add(jobToAdded);
min = min + job.Frequency;
}
}
}
return jobs;
}
//[HttpGet(ApiRoutes.Jobs.GetByIp)]
//public async Task<IActionResult> GetByClientIP([FromQuery] JobGetByIpQuery requestQuery)
//{
// var ip = requestQuery.Ip ?? clientService.GetClientIp()?.ToString();
// if (string.IsNullOrEmpty(ip))
// return BadRequest(new Response(false, new List<ErrorModel> { new ErrorModel { Message = "Client IP address is null." } }));
// var date = requestQuery.Date ?? DateTimeOffset.Now;
// // С одним IP может быть несколько информационных систем, соответственного а таблице храниться несколько записей хостов с одинаковым IP
// var hosts = await hostService.Get().Where(h => h.IP == ip).ToListAsync();
// var hostJobsDict = new Dictionary<DAL.Models.Host, List<Job>>();
// foreach (var host in hosts)
// {
// var jobsHostQuery = jobService.Get()
// .Include(a => a.Application).ThenInclude(ah => ah.ApplicationsInHosts)/*.ThenInclude(h => h.Host)*/
// .Include(jm => jm.JobMode)
// .AsSplitQuery()
// .Where(j => j.Application != null && j.Application.ApplicationsInHosts.Any(ah => ah.HostId == host.Id));
// if (requestQuery.IsPlanned == true)
// {
// // ототбражем только включенные
// jobsHostQuery = jobsHostQuery.Where(t => t.IsEnabled == true);
// }
// var jobsHost = await jobsHostQuery.ToListAsync();
// if (requestQuery.IsPlanned == true)
// {
// // смотрим в истории, если задание уже было запущено, то его не отображаем
// foreach (var jobItem in jobsHost)
// {
// var journalItem = await jobJournalService.GetLastAsync(jobItem.Id, host.Id, date);
// if (JobStatusEnum.started) { }
// }
// }
// if (jobsHost.Any())
// {
// //Проверяем Job вк
// hostJobsDict.Add(host, jobsHost);
// }
// }
// //hostJobsDict.Values.Distinct();
// var jobsJoined = new List<Job>();
// foreach (var job in hostJobsDict.Values)
// {
// job.ForEach(item =>
// {
// jobsJoined.Add(item);
// });
// }
// if (!jobsJoined.Any())
// return NoContent();
// var jobResponse = mapper.Map<List<JobGetAllResponse>>(jobsJoined.Distinct());
// return Ok(new Response<List<JobGetAllResponse>>(jobResponse, true, new List<ErrorModel>(), $"{ip},{date}"));
//}
}
}