Skip to content

Commit

Permalink
Merge pull request fossology#2870 from andreas-menzl/andreas-menzl/fe…
Browse files Browse the repository at this point in the history
…at/job-api-sort-and-status-filter

feat(api): Added sort and status filter options to jobs endpoint

Reviewed-by: kaushlendra-pratap.singh@siemens.com
Tested-by: kaushlendra-pratap.singh@siemens.com
  • Loading branch information
shaheemazmalmmd authored Dec 6, 2024
2 parents f63e714 + baa4db0 commit 6046391
Show file tree
Hide file tree
Showing 5 changed files with 203 additions and 256 deletions.
190 changes: 54 additions & 136 deletions src/www/ui/api/Controllers/JobController.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@

namespace Fossology\UI\Api\Controllers;

use Fossology\Lib\Dao\ShowJobsDao;
use Fossology\Lib\Db\DbManager;
use Fossology\UI\Api\Exceptions\HttpBadRequestException;
use Fossology\UI\Api\Exceptions\HttpErrorException;
Expand Down Expand Up @@ -70,27 +69,22 @@ public function getAllJobs($request, $response, $args)
{
$apiVersion = ApiVersion::getVersion($request);
$this->throwNotAdminException();
$id = null;
$limit = 0;
$page = 1;
if ($apiVersion == ApiVersion::V2) {
$query = $request->getQueryParams();
$limit = $query['limit'] ?? 0;
$page = $query['page'] ?? 1;
} else {
$limit = $request->hasHeader('limit') ? $request->getHeaderLine('limit') : 0;
$page = $request->hasHeader('page') ? $request->getHeaderLine('page') : 1;
}
if (empty($page)) {
$page = 1;
}
if ((! is_numeric($limit) || $limit < 0) ||
(! is_numeric($page) || $page < 1)) {
throw new HttpBadRequestException(
"Limit and page cannot be smaller than 1 and has to be numeric!");

$queryParams = $request->getQueryParams();
$query = $apiVersion == ApiVersion::V2 ? $queryParams : array_map(function($header) {
return implode(",", $header);
}, $request->getHeaders());

$limit = isset($query['limit']) ? intval($query['limit']) : 0;
$page = isset($query['page']) ? intval($query['page']) : 1;
$sort = $queryParams['sort'] ?? "ASC";
$status = $queryParams['status'] ?? null;

if ($limit < 0 || $page < 1) {
throw new HttpBadRequestException("Limit and page cannot be smaller than 1 and has to be numeric!");
}

return $this->getAllResults($id, $request, $response, $limit, $page, $apiVersion);
return $this->getAllResults(null, $status, $request, $response, $sort, $limit, $page, $apiVersion);
}

/**
Expand All @@ -105,47 +99,40 @@ public function getAllJobs($request, $response, $args)
public function getJobs($request, $response, $args)
{
$apiVersion = ApiVersion::getVersion($request);
$query = $request->getQueryParams();
$userId = $this->restHelper->getUserId();
$limit = 0;
$page = 1;
if ($apiVersion == ApiVersion::V2) {
$limit = $query['limit'] ?? 0;
$page = $query['page'] ?? 1;
} else {
$limit = $request->hasHeader('limit') ? $request->getHeaderLine('limit') : 0;
$page = $request->hasHeader('page') ? $request->getHeaderLine('page') : 1;
}
if (empty($page)) {
$page = 1;
}
if ((! is_numeric($limit) || $limit < 0) ||
(! is_numeric($page) || $page < 1)) {
throw new HttpBadRequestException(
"Limit and page cannot be smaller than 1 and has to be numeric!");

$queryParams = $request->getQueryParams();
$query = $apiVersion == ApiVersion::V2 ? $queryParams : array_map(function($header) {
return implode(",", $header);
}, $request->getHeaders());

$limit = isset($query['limit']) ? intval($query['limit']) : 0;
$page = isset($query['page']) ? intval($query['page']) : 1;
$sort = $queryParams['sort'] ?? "ASC";
$status = $queryParams['status'] ?? null;

if ($limit < 0 || $page < 1) {
throw new HttpBadRequestException("Limit and page cannot be smaller than 1 and has to be numeric!");
}

$id = null;
if (isset($args['id'])) {
$id = intval($args['id']);
if (! $this->dbHelper->doesIdExist("job", "job_pk", $id)) {
throw new HttpNotFoundException("Job id " . $id . " doesn't exist");
}
$id = isset($args['id']) ? intval($args['id']) : null;
if ($id !== null && !$this->dbHelper->doesIdExist("job", "job_pk", $id)) {
throw new HttpNotFoundException("Job id " . $id . " doesn't exist");
}

if ($id !== null) {
/* If the ID is passed, don't check for upload */
return $this->getAllResults($id, $request, $response, $limit, $page, $apiVersion);
return $this->getAllResults($id, $status, $request, $response, $sort, $limit, $page, $apiVersion);
}

if (array_key_exists(self::UPLOAD_PARAM, $query)) {
if (array_key_exists(self::UPLOAD_PARAM, $queryParams)) {
/* If the upload is passed, filter accordingly */
return $this->getFilteredResults(intval($query[self::UPLOAD_PARAM]),
$request, $response, $limit, $page, $apiVersion);
} else {
$id = null;
return $this->getAllUserResults($id, $userId, $request, $response, $limit, $page, $apiVersion);
return $this->getFilteredResults(intval($queryParams[self::UPLOAD_PARAM]),
$status, $request, $response, $sort, $limit, $page, $apiVersion);
}

/* Otherwise return all jobs for the current user */
return $this->getAllUserResults($userId, $status, $request, $response, $sort, $limit, $page, $apiVersion);
}

/**
Expand Down Expand Up @@ -248,60 +235,56 @@ public function deleteJob($request, $response, $args)
/**
* Get all jobs created by the current user.
*
* @param integer|null $id Specific job id or null for all jobs
* @param integer $uid Specific user id
* @param integer $userId Specific user id
* @param string|null $status Status of the jobs to return
* @param Request $request Request object
* @param ResponseHelper $response Response object
* @param string $sort Sorting order for the results
* @param integer $limit Limit of jobs per page
* @param integer $page Page number required
* @param integer $apiVersion API version
* @return ResponseHelper
*/
private function getAllUserResults($id, $uid, $request, $response, $limit, $page, $apiVersion)
private function getAllUserResults($userId, $status, $request, $response, $sort, $limit, $page, $apiVersion)
{
list($jobs, $count) = $this->dbHelper->getUserJobs($id, $uid, $limit, $page);
list($jobs, $count) = $this->dbHelper->getUserJobs($userId, $status, $sort, $limit, $page);
$finalJobs = [];
foreach ($jobs as $job) {
$this->updateEtaAndStatus($job);
$this->updateEta($job);
if ($apiVersion == ApiVersion::V2) {
$this->addJobQueue($job, $request);
}
$finalJobs[] = $job->getArray($apiVersion);
}
if ($id !== null) {
$finalJobs = $finalJobs[0];
} else {
usort($finalJobs, [$this, "sortJobsByDate"]);
}
return $response->withHeader("X-Total-Pages", $count)->withJson($finalJobs, 200);
}

/**
* Get all jobs for the current user.
*
* @param integer|null $id Specific job id or null for all jobs
* @param string|null $status Status of the jobs to return
* @param Request $request Request object
* @param ResponseHelper $response Response object
* @param string $sort Sorting order for the results
* @param integer $limit Limit of jobs per page
* @param integer $page Page number required
* @param integer $apiVersion API version
* @return ResponseHelper
*/
private function getAllResults($id, $request, $response, $limit, $page, $apiVersion)
private function getAllResults($id, $status, $request, $response, $sort, $limit, $page, $apiVersion)
{
list($jobs, $count) = $this->dbHelper->getJobs($id, $limit, $page);
list($jobs, $count) = $this->dbHelper->getJobs($id, $status, $sort, $limit, $page, null);
$finalJobs = [];
foreach ($jobs as $job) {
$this->updateEtaAndStatus($job);
$this->updateEta($job);
if ($apiVersion == ApiVersion::V2) {
$this->addJobQueue($job, $request);
}
$finalJobs[] = $job->getArray($apiVersion);
}
if ($id !== null) {
$finalJobs = $finalJobs[0];
} else {
usort($finalJobs, [$this, "sortJobsByDate"]);
}
return $response->withHeader("X-Total-Pages", $count)->withJson($finalJobs, 200);
}
Expand All @@ -310,30 +293,31 @@ private function getAllResults($id, $request, $response, $limit, $page, $apiVers
* Get all jobs for the given upload.
*
* @param integer $uploadId Upload id to be filtered
* @param string|null $status Status of the jobs to return
* @param Request $request Request object
* @param ResponseHelper $response Response object
* @param string $sort Sorting order for the results
* @param integer $limit Limit of jobs per page
* @param integer $page Page number required
* @param integer $apiVersion API version
* @return ResponseHelper
* @throws HttpNotFoundException
*/
private function getFilteredResults($uploadId, $request, $response, $limit, $page, $apiVersion)
private function getFilteredResults($uploadId, $status, $request, $response, $sort, $limit, $page, $apiVersion)
{
if (! $this->dbHelper->doesIdExist("upload", "upload_pk", $uploadId)) {
throw new HttpNotFoundException("Upload id " . $uploadId .
" doesn't exist");
}
list($jobs, $count) = $this->dbHelper->getJobs(null, $limit, $page, $uploadId);
list($jobs, $count) = $this->dbHelper->getJobs(null, $status, $sort, $limit, $page, $uploadId);
$finalJobs = [];
foreach ($jobs as $job) {
$this->updateEtaAndStatus($job);
$this->updateEta($job);
if ($apiVersion == ApiVersion::V2) {
$this->addJobQueue($job, $request);
}
$finalJobs[] = $job->getArray($apiVersion);
}
usort($finalJobs, [$this, "sortJobsByDate"]);
return $response->withHeader("X-Total-Pages", $count)->withJson($finalJobs, 200);
}

Expand All @@ -342,17 +326,10 @@ private function getFilteredResults($uploadId, $request, $response, $limit, $pag
*
* @param[in,out] Job $job The job to be updated
*/
private function updateEtaAndStatus(&$job)
private function updateEta(&$job)
{
$jobDao = $this->restHelper->getJobDao();

$jobqueue = [];
$jobqueue = $jobDao->getChlidJobStatus($job->getId());

$job->setEta($this->getUploadEtaInSeconds($job->getId(),
$job->getUploadId()));

$job->setStatus($this->getJobStatus(array_keys($jobqueue)));
}

/**
Expand All @@ -375,54 +352,6 @@ private function getUploadEtaInSeconds($jobId, $uploadId)
return $eta;
}

/**
* Get the job status based on jobqueue.
*
* @param array $jobqueue The job queue with job id as values
* @return string Job status (Completed, Processing, Queued or Failed)
*/
private function getJobStatus($jobqueue)
{
$showJobDao = $this->restHelper->getShowJobDao();
$jobStatus = 0;
/* Check each job in queue */
foreach ($jobqueue as $jobId) {
$jobInfo = $showJobDao->getDataForASingleJob($jobId);
$endtext = $jobInfo['jq_endtext'];
switch ($endtext) {
case 'Completed':
$jobStatus |= self::JOB_COMPLETED;
break;
case 'Started':
case 'Restarted':
case 'Paused':
$jobStatus |= self::JOB_STARTED;
break;
default:
if (empty($jobInfo['jq_endtime'])) {
$jobStatus |= self::JOB_QUEUED;
} else {
$jobStatus |= self::JOB_FAILED;
}
}
}

$jobStatusString = "";
if ($jobStatus & self::JOB_FAILED) {
/* If at least one job is failed, set status as failed */
$jobStatusString = "Failed";
} else if ($jobStatus & self::JOB_STARTED) {
/* If at least one job is started, set status as processing */
$jobStatusString = "Processing";
} else if ($jobStatus & self::JOB_QUEUED) {
$jobStatusString = "Queued";
} else {
/* If everything completed successfully, set status as completed */
$jobStatusString = "Completed";
}
return $jobStatusString;
}

/**
* Get the history of all the jobs queued based on an upload
*
Expand Down Expand Up @@ -557,17 +486,6 @@ private function compareJobsInfo($JobsInfo1, $JobsInfo2)
return $JobsInfo2["job"]["job_pk"] - $JobsInfo1["job"]["job_pk"];
}

/**
* @brief Sort compare function to order $JobsInfo by jobqueue start time
* @param array $job1 Result from finalJobs
* @param array $job2 Result from finalJobs
* @return int
*/
private function sortJobsByDate($job1, $job2)
{
return strtotime($job2['queueDate']) - strtotime($job1['queueDate']);
}

/**
* @brief Get the summary statistics of all the jobs
* @param Request $request
Expand Down
Loading

0 comments on commit 6046391

Please sign in to comment.