FOSSology  3.2.0rc1
Open Source License Compliance by Open Source Software
JobController.php
Go to the documentation of this file.
1 <?php
2 /***************************************************************
3  Copyright (C) 2018 Siemens AG
4  Author: Gaurav Mishra <mishra.gaurav@siemens.com>
5 
6  This program is free software; you can redistribute it and/or
7  modify it under the terms of the GNU General Public License
8  version 2 as published by the Free Software Foundation.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License along
16  with this program; if not, write to the Free Software Foundation, Inc.,
17  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  ***************************************************************/
25 
35 
41 {
45  const UPLOAD_PARAM = "upload";
49  const JOB_COMPLETED = 0x1 << 1;
53  const JOB_STARTED = 0x1 << 2;
57  const JOB_QUEUED = 0x1 << 3;
61  const JOB_FAILED = 0x1 << 4;
70  public function getJobs($request, $response, $args)
71  {
72  $query = $request->getQueryParams();
73 
74  $limit = 0;
75  $page = 1;
76  if ($request->hasHeader('limit')) {
77  $limit = $request->getHeaderLine('limit');
78  $page = $request->getHeaderLine('page');
79  if (empty($page)) {
80  $page = 1;
81  }
82  if ((isset($limit) && (! is_numeric($limit) || $limit < 0)) ||
83  (! is_numeric($page) || $page < 1)) {
84  $returnVal = new Info(400,
85  "Limit and page cannot be smaller than 1 and has to be numeric!",
86  InfoType::ERROR);
87  return $response->withJson($returnVal->getArray(), $returnVal->getCode());
88  }
89  }
90 
91  $id = null;
92  if (isset($args['id'])) {
93  $id = intval($args['id']);
94  if (! $this->dbHelper->doesIdExist("job", "job_pk", $id)) {
95  $returnVal = new Info(404, "Job id " . $id . " doesn't exist",
96  InfoType::ERROR);
97  return $response->withJson($returnVal->getArray(), $returnVal->getCode());
98  }
99  }
100 
101  if ($id !== null) {
102  /* If the ID is passed, don't check for upload */
103  return $this->getAllResults($id, $response, $limit, $page);
104  }
105 
106  if (array_key_exists(self::UPLOAD_PARAM, $query)) {
107  /* If the upload is passed, filter accordingly */
108  return $this->getFilteredResults(intval($query[self::UPLOAD_PARAM]),
109  $response, $limit, $page);
110  } else {
111  return $this->getAllResults($id, $response, $limit, $page);
112  }
113  }
114 
123  public function createJob($request, $response, $args)
124  {
125  $folder = $request->getHeaderLine("folderId");
126  $upload = $request->getHeaderLine("uploadId");
127  if (is_numeric($folder) && is_numeric($upload) && $folder > 0 && $upload > 0) {
128  $scanOptionsJSON = $request->getParsedBody();
129  if (empty($scanOptionsJSON)) {
130  $error = new Info(403, "No agents selected!", InfoType::ERROR);
131  return $response->withJson($error->getArray(), $error->getCode());
132  }
133  $parametersSent = false;
134  $analysis = new Analysis();
135  if (array_key_exists("analysis", $scanOptionsJSON) && ! empty($scanOptionsJSON["analysis"])) {
136  $analysis->setUsingArray($scanOptionsJSON["analysis"]);
137  $parametersSent = true;
138  }
139  $decider = new Decider();
140  if (array_key_exists("decider", $scanOptionsJSON) && ! empty($scanOptionsJSON["decider"])) {
141  $decider->setUsingArray($scanOptionsJSON["decider"]);
142  $parametersSent = true;
143  }
144  $reuser = new Reuser(0, 0, false, false);
145  try {
146  if (array_key_exists("reuse", $scanOptionsJSON) && ! empty($scanOptionsJSON["reuse"])) {
147  $reuser->setUsingArray($scanOptionsJSON["reuse"]);
148  $parametersSent = true;
149  }
150  } catch (\UnexpectedValueException $e) {
151  $error = new Info($e->getCode(), $e->getMessage(), InfoType::ERROR);
152  return $response->withJson($error->getArray(), $error->getCode());
153  }
154 
155  if (! $parametersSent) {
156  $error = new Info(403, "No parameters selected for agents!",
157  InfoType::ERROR);
158  return $response->withJson($error->getArray(), $error->getCode());
159  }
160 
161  $scanOptions = new ScanOptions($analysis, $reuser, $decider);
162  $info = $scanOptions->scheduleAgents($folder, $upload);
163  return $response->withJson($info->getArray(), $info->getCode());
164  } else {
165  $error = new Info(400, "Folder id and upload id should be integers!", InfoType::ERROR);
166  return $response->withJson($error->getArray(), $error->getCode());
167  }
168  }
169 
179  private function getAllResults($id, $response, $limit, $page)
180  {
181  list($jobs, $count) = $this->dbHelper->getJobs($id, $limit, $page);
182  $finalJobs = [];
183  foreach ($jobs as $job) {
184  $this->updateEtaAndStatus($job);
185  $finalJobs[] = $job->getArray();
186  }
187  if ($id !== null) {
188  $finalJobs = $finalJobs[0];
189  }
190  return $response->withHeader("X-Total-Pages", $count)->withJson($finalJobs, 200);
191  }
192 
202  private function getFilteredResults($uploadId, $response, $limit, $page)
203  {
204  if (! $this->dbHelper->doesIdExist("upload", "upload_pk", $uploadId)) {
205  $returnVal = new Info(404, "Upload id " . $uploadId . " doesn't exist",
206  InfoType::ERROR);
207  return $response->withJson($returnVal->getArray(), $returnVal->getCode());
208  }
209  list($jobs, $count) = $this->dbHelper->getJobs(null, $limit, $page, $uploadId);
210  $finalJobs = [];
211  foreach ($jobs as $job) {
212  $this->updateEtaAndStatus($job);
213  $finalJobs[] = $job->getArray();
214  }
215  return $response->withHeader("X-Total-Pages", $count)->withJson($finalJobs, 200);
216  }
217 
223  private function updateEtaAndStatus(&$job)
224  {
225  $jobDao = $this->restHelper->getJobDao();
226 
227  $eta = 0;
228  $status = "";
229  $jobqueue = [];
230 
231  /* Check if the job has no upload like Maintenance job */
232  if (empty($job->getUploadId())) {
233  $sql = "SELECT jq_pk, jq_end_bits from jobqueue WHERE jq_job_fk = $1;";
234  $statement = __METHOD__ . ".getJqpk";
235  $rows = $this->dbHelper->getDbManager()->getRows($sql, [$job->getId()],
236  $statement);
237  if (count($rows) > 0) {
238  $jobqueue[$rows[0]['jq_pk']] = $rows[0]['jq_end_bits'];
239  }
240  } else {
241  $jobqueue = $jobDao->getAllJobStatus($job->getUploadId(),
242  $job->getUserId(), $job->getGroupId());
243  }
244 
245  $job->setEta($this->getUploadEtaInSeconds($job->getId(),
246  $job->getUploadId()));
247 
248  $job->setStatus($this->getJobStatus(array_keys($jobqueue)));
249  }
250 
258  private function getUploadEtaInSeconds($jobId, $uploadId)
259  {
260  $showJobDao = $this->restHelper->getShowJobDao();
261  $eta = $showJobDao->getEstimatedTime($jobId, '', 0, $uploadId);
262  $eta = explode(":", $eta);
263  if (count($eta) > 1) {
264  $eta = ($eta[0] * 3600) + ($eta[1] * 60) + ($eta[2]);
265  } else {
266  $eta = 0;
267  }
268  return $eta;
269  }
270 
277  private function getJobStatus($jobqueue)
278  {
279  $showJobDao = $this->restHelper->getShowJobDao();
280  $jobStatus = 0;
281  /* Check each job in queue */
282  foreach ($jobqueue as $jobId) {
283  $jobInfo = $showJobDao->getDataForASingleJob($jobId);
284  $endtext = $jobInfo['jq_endtext'];
285  switch ($endtext) {
286  case 'Completed':
287  $jobStatus |= self::JOB_COMPLETED;
288  break;
289  case 'Started':
290  case 'Restarted':
291  case 'Paused':
292  $jobStatus |= self::JOB_STARTED;
293  break;
294  default:
295  if (empty($jobInfo['jq_endtime'])) {
296  $jobStatus |= self::JOB_QUEUED;
297  } else {
298  $jobStatus |= self::JOB_FAILED;
299  }
300  }
301  }
302 
303  $jobStatusString = "";
304  if ($jobStatus & self::JOB_STARTED) {
305  /* If at least one job is started, set status as processing */
306  $jobStatusString = "Processing";
307  } else if ($jobStatus & self::JOB_QUEUED) {
308  $jobStatusString = "Queued";
309  } else if ($jobStatus & self::JOB_FAILED) {
310  /* If at least one job is failed, set status as failed */
311  $jobStatusString = "Failed";
312  } else {
313  /* If everything completed successfully, set status as completed */
314  $jobStatusString = "Completed";
315  }
316  return $jobStatusString;
317  }
318 }
Base controller for REST calls.
Model to hold add settings for new scan.
Definition: ScanOptions.php:38
Model to hold info required by Reuser agent.
Definition: Reuser.php:28
createJob($request, $response, $args)
getJobs($request, $response, $args)
getFilteredResults($uploadId, $response, $limit, $page)
Model to hold analysis settings.
Definition: Analysis.php:30
Info model to contain general error and return values.
Definition: Info.php:29
getAllResults($id, $response, $limit, $page)