using API.Schema; using API.Schema.Jobs; using Asp.Versioning; using Microsoft.AspNetCore.Mvc; using static Microsoft.AspNetCore.Http.StatusCodes; namespace API.Controllers; [ApiVersion(2)] [ApiController] [Produces("application/json")] [Route("v{version:apiVersion}/[controller]")] public class JobController(PgsqlContext context) : Controller { /// /// Returns Jobs with requested Job-IDs /// /// Array of Job-IDs /// Array of Jobs [HttpPost("WithIDs")] [ProducesResponseType(Status200OK)] public IActionResult GetJobs([FromBody] string[] ids) { Job[] ret = context.Jobs.Where(job => ids.Contains(job.JobId)).ToArray(); return Ok(ret); } /// /// Get all due Jobs (NextExecution > CurrentTime) /// /// Array of Jobs [HttpGet("Due")] [ProducesResponseType(Status200OK)] public IActionResult GetDueJobs() { DateTime now = DateTime.Now.ToUniversalTime(); Job[] dueJobs = context.Jobs.Where(job => job.NextExecution < now && job.state < JobState.Running).ToArray(); return Ok(dueJobs); } /// /// Get all Jobs in requested State /// /// Requested Job-State /// Array of Jobs [HttpGet("State/{state}")] [ProducesResponseType(Status200OK)] public IActionResult GetJobsInState(JobState state) { Job[] jobsInState = context.Jobs.Where(job => job.state == state).ToArray(); return Ok(jobsInState); } /// /// Returns all Jobs of requested Type /// /// Requested Job-Type /// Array of Jobs [HttpPost("Type/{type}")] [ProducesResponseType(Status200OK)] public IActionResult GetJobsOfType(JobType type) { Job[] jobsOfType = context.Jobs.Where(job => job.JobType == type).ToArray(); return Ok(jobsOfType); } /// /// Return Job with ID /// /// Job-ID /// Job [HttpGet("{id}")] [ProducesResponseType(Status200OK)] [ProducesResponseType(Status404NotFound)] public IActionResult GetJob(string id) { Job? ret = context.Jobs.Find(id); return (ret is not null) switch { true => Ok(ret), false => NotFound() }; } /// /// Updates the State of a Job /// /// Job-ID /// New State /// Nothing [HttpPatch("{id}/Status")] [ProducesResponseType(Status200OK)] [ProducesResponseType(Status404NotFound)] [ProducesResponseType(Status500InternalServerError)] public IActionResult UpdateJobStatus(string id, [FromBody]JobState state) { try { Job? ret = context.Jobs.Find(id); switch (ret is not null) { case true: ret.state = state; context.Update(ret); context.SaveChanges(); return Ok(); case false: return NotFound(); } } catch (Exception e) { return StatusCode(500, e.Message); } } /// /// Create a new Job /// /// Job /// Nothing [HttpPut] [ProducesResponseType(Status201Created)] [ProducesResponseType(Status500InternalServerError)] public IActionResult CreateJob([FromBody]Job job) { try { context.Jobs.Add(job); context.SaveChanges(); return Created(); } catch (Exception e) { return StatusCode(500, e.Message); } } /// /// Delete Job with ID /// /// Job-ID /// Nothing [HttpDelete("{id}")] [ProducesResponseType(Status200OK)] [ProducesResponseType(Status404NotFound)] [ProducesResponseType(Status500InternalServerError)] public IActionResult DeleteJob(string id) { try { Job? ret = context.Jobs.Find(id); switch (ret is not null) { case true: context.Remove(ret); context.SaveChanges(); return Ok(); case false: return NotFound(); } } catch (Exception e) { return StatusCode(500, e.Message); } } /// /// Starts the Job with the requested ID /// /// Job-ID /// Nothing [HttpPost("{id}/Start")] [ProducesResponseType(Status202Accepted)] [ProducesResponseType(Status404NotFound)] [ProducesResponseType(Status500InternalServerError)] public IActionResult StartJob(string id) { Job? ret = context.Jobs.Find(id); if (ret is null) return NotFound(); ret.NextExecution = DateTime.UnixEpoch; try { context.Update(ret); context.SaveChanges(); return Accepted(); } catch (Exception e) { return StatusCode(500, e.Message); } } [HttpPost("{id}/Stop")] public IActionResult StopJob(string id) { return NotFound(new ProblemResponse("Not implemented")); //TODO } }