2023-06-20 12:29:58 +10:00
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 ;
2023-06-20 16:54:38 +10:00
using PARR.API.MappingProfiles ;
2023-06-20 12:29:58 +10:00
using PARR.API.Services.Interfaces ;
2023-06-20 16:54:38 +10:00
using PARR.DAL.Contracts ;
2023-06-20 12:29:58 +10:00
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 ;
2023-06-20 16:54:38 +10:00
private readonly IJobJournalService jobJournalService ;
2023-06-20 12:29:58 +10:00
public JobController (
IMapper mapper ,
IJobService jobService ,
IClientService clientService ,
2023-06-20 16:54:38 +10:00
IHostService hostService ,
IJobJournalService jobJournalService
2023-06-20 12:29:58 +10:00
)
{
this . mapper = mapper ;
this . jobService = jobService ;
//this.schedulerService = schedulerService;
this . clientService = clientService ;
this . hostService = hostService ;
2023-06-20 16:54:38 +10:00
this . jobJournalService = jobJournalService ;
2023-06-20 12:29:58 +10:00
}
/// <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)*/
2023-06-20 16:54:38 +10:00
. Include ( jm = > jm . JobMode )
2023-06-20 12:29:58 +10:00
. AsSplitQuery ( )
2023-06-20 16:54:38 +10:00
. Where ( j = > j . Application ! = null & & j . Application . ApplicationsInHosts . Any ( ah = > ah . HostId = = host . Id ) & & j . IsEnabled )
2023-06-20 12:29:58 +10:00
. ToListAsync ( ) ;
2023-06-20 16:54:38 +10:00
2023-06-20 12:29:58 +10:00
if ( jobsHost . Any ( ) )
2023-06-20 16:54:38 +10:00
{
2023-06-20 12:29:58 +10:00
hostJobsDict . Add ( host , jobsHost ) ;
2023-06-20 16:54:38 +10:00
}
2023-06-20 12:29:58 +10:00
}
2023-06-20 16:54:38 +10:00
var jobsList = new List < Job > ( ) ;
var response = new Dictionary < string , string > ( ) ;
foreach ( var hostAndJobs in hostJobsDict )
2023-06-20 12:29:58 +10:00
{
2023-06-20 16:54:38 +10:00
hostAndJobs . Value . ForEach ( async item = >
2023-06-20 12:29:58 +10:00
{
2023-06-20 16:54:38 +10:00
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
}
2023-06-20 12:29:58 +10:00
} ) ;
}
2023-06-20 16:54:38 +10:00
// var jobListForResponse = new
2023-06-20 12:29:58 +10:00
2023-06-20 16:54:38 +10:00
//var dic = new Dictionary<string, string>();
//dic.Add("sss1", "222");
//dic.Add("sss2", "333");
return Ok ( ) ;
2023-06-20 12:29:58 +10:00
}
2023-06-20 16:54:38 +10:00
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}"));
//}
2023-06-20 12:29:58 +10:00
}
}