From e92880b79a76d0003968c4e82ff88aa1e9721da5 Mon Sep 17 00:00:00 2001 From: Paolo Date: Fri, 6 Mar 2020 14:15:10 +0100 Subject: [PATCH] - Added new private methods _checkPermissions and _convertJobs to controller system/jq/JobsQueueManager - Added new public method updateJobsQueue to controller system/jq/JobsQueueManager - system/jq/JobsQueueManager->getLastJobs now checks permissions - Added new public method updateJobsQueue to JQW_Controller - Less redundant constansts in Library JobsQueueLib - JobsQueueLib constructor now loads models JobsQueueModel, JobTypesModel and JobStatusesModel - Added new public methods getLastJobs, addNewJobsToQueue and updateJobsQueue to JobsQueueLib - Added new private methods _checkNewJobStructure, _checkUpdateJobStructure, _checkJobType, _checkJobStatus, _inArray, _dropNotAllowedPropertiesNewJob and _dropNotAllowedPropertiesUpdateJob to --- .../system/jq/JobsQueueManager.php | 83 +++++- application/core/JQW_Controller.php | 14 + application/libraries/JobsQueueLib.php | 255 ++++++++++++++++-- 3 files changed, 324 insertions(+), 28 deletions(-) diff --git a/application/controllers/system/jq/JobsQueueManager.php b/application/controllers/system/jq/JobsQueueManager.php index 9275fa845..b6e4efe29 100644 --- a/application/controllers/system/jq/JobsQueueManager.php +++ b/application/controllers/system/jq/JobsQueueManager.php @@ -10,6 +10,8 @@ class JobsQueueManager extends Auth_Controller { // Config entry name for White list of permissions... const JOB_TYPE_PERMISSIONS_WHITE_LIST = 'job_type_permissions_white_list'; + // Parameter names + const PARAM_JOBS = 'jobs'; /** * Constructor @@ -19,12 +21,15 @@ class JobsQueueManager extends Auth_Controller parent::__construct( array( 'getLastJobs' => 'admin:r', - 'addNewJobsToQueue' => 'admin:rw' + 'addNewJobsToQueue' => 'admin:rw', + 'updateJobsQueue' => 'admin:rw' ) ); // Loads JobsQueueLib $this->load->library('JobsQueueLib'); + // Loads permission lib + $this->load->library('PermissionLib'); } //------------------------------------------------------------------------------------------------------------------ @@ -35,7 +40,9 @@ class JobsQueueManager extends Auth_Controller */ public function getLastJobs() { - $type = $this->input->get(JobsQueueLib::PARAM_JOB_TYPE); + $type = $this->input->get(JobsQueueLib::PROPERTY_TYPE); + + $this->_checkPermissions($type); $this->outputJson($this->jobsqueuelib->getLastJobs($type)); } @@ -46,21 +53,75 @@ class JobsQueueManager extends Auth_Controller */ public function addNewJobsToQueue() { - $type = $this->input->post(JobsQueueLib::PARAM_JOB_TYPE); - $jobs = $this->input->post(JobsQueueLib::PARAM_JOBS); + $type = $this->input->post(JobsQueueLib::PROPERTY_TYPE); + $jobs = $this->input->post(self::PARAM_JOBS); - // Loads permission lib - $this->load->library('PermissionLib'); + $this->_checkPermissions($type); + // Otherwise convert jobs from json to php and call JobsQueueLib library + $this->outputJson($this->jobsqueuelib->addNewJobsToQueue($type, $this->_convertJobs($jobs))); + } + + /** + * Add new jobs in the jobs queue with the given type + * jobs is an array of job objects + */ + public function updateJobsQueue() + { + $type = $this->input->post(JobsQueueLib::PROPERTY_TYPE); + $jobs = $this->input->post(self::PARAM_JOBS); + + $this->_checkPermissions($type); + + // Otherwise convert jobs from json to php and call JobsQueueLib library + $this->outputJson($this->jobsqueuelib->updateJobsQueue($type, $this->_convertJobs($jobs))); + } + + //------------------------------------------------------------------------------------------------------------------ + // Private methods + + /** + * + */ + private function _checkPermissions($type) + { // Checks if the caller has the permissions to add new jobs with the given type in the queue if (!$this->permissionlib->isEntitled($this->config->item(self::JOB_TYPE_PERMISSIONS_WHITE_LIST), $type)) { // Permissions NOT valid - $this->outputJsonError('You are not allowed to access to this content'); - } - else // Otherwise call JobsQueueLib library - { - $this->outputJson($this->jobsqueuelib->addNewJobsToQueue($type, $jobs)); + $this->terminateWithJsonError('You are not allowed to access to this content'); } } + + /** + * + */ + private function _convertJobs($jobs) + { + if (isEmptyArray($jobs)) return null; // if not a valid array then return null + + $convertedJobsArray = array(); // returned values + + // Loops through all the provided jobs + foreach ($jobs as $job) + { + $tmpObj = json_decode($job); // Try to decode json to php + + // If decode was a success + if ($tmpObj != null) + { + $convertedJobsArray[] = $tmpObj; // then store the decoded object in the result array + } + else // otherwise + { + // Create a new object and store the error message in it + $tmpObj = new stdClass(); + $tmpObj->{JobsQueueLib::PROPERTY_ERROR} = 'A not valid json was provided'; + + $convertedJobsArray[] = $tmpObj; // store this object into the result array + } + } + + return $convertedJobsArray; + } } diff --git a/application/core/JQW_Controller.php b/application/core/JQW_Controller.php index 616eaf4fd..c6d2362e3 100644 --- a/application/core/JQW_Controller.php +++ b/application/core/JQW_Controller.php @@ -60,4 +60,18 @@ abstract class JQW_Controller extends JOB_Controller return $result; } + + /** + * Updates jobs already present in the jobs queue + * jobs is an array of job objects + */ + protected function updateJobsQueue($type, $jobs) + { + $result = $this->jobsqueuelib->updateJobsQueue($type, $jobs); + + // If an error occurred then log it in database + if (isError($result)) $this->logError(getError($result), $type); + + return $result; + } } diff --git a/application/libraries/JobsQueueLib.php b/application/libraries/JobsQueueLib.php index fe73b40c6..ac0e38786 100644 --- a/application/libraries/JobsQueueLib.php +++ b/application/libraries/JobsQueueLib.php @@ -7,23 +7,22 @@ if (!defined('BASEPATH')) exit('No direct script access allowed'); */ class JobsQueueLib { - // Job types - // SAP - const JOB_TYPE_SAP_STAMMDATEN_UPDATE = 'SAPStammdatenUpdate'; - const JOB_TYPE_SAP_PAYMENT = 'SAPPayment'; - // DVUH - const JOB_TYPE_OEH_PAYMENT = 'OEHPayment'; - // Job statuses const STATUS_NEW = 'new'; const STATUS_RUNNING = 'running'; const STATUS_DONE = 'done'; const STATUS_FAILED = 'failed'; - // Parameter names - const PARAM_JOB_TYPE = 'type'; - const PARAM_JOB_STATUS = 'status'; - const PARAM_JOBS = 'jobs'; + // Job object properties + const PROPERTY_JOBID = 'jobid'; + const PROPERTY_CREATIONTIME = 'creationtime'; + const PROPERTY_TYPE = 'type'; + const PROPERTY_STATUS = 'status'; + const PROPERTY_INPUT = 'input'; + const PROPERTY_OUTPUT = 'output'; + const PROPERTY_START_TIME = 'starttime'; + const PROPERTY_END_TIME = 'endtime'; + const PROPERTY_ERROR = 'error'; private $_ci; // CI instance @@ -34,29 +33,251 @@ class JobsQueueLib { // Gets CI instance $this->_ci =& get_instance(); + + // Loads JQM configuration + $this->_ci->config->load('jqm'); + + // Loads all needed models + $this->_ci->load->model('system/JobsQueue_model', 'JobsQueueModel'); + $this->_ci->load->model('system/JobTypes_model', 'JobTypesModel'); + $this->_ci->load->model('system/JobStatuses_model', 'JobStatusesModel'); } //------------------------------------------------------------------------------------------------------------------ // Public methods /** - * + * To get all the most recently added jobs using the given job type */ - public function getJobsByType() + public function getLastJobs($type) { + $this->_ci->JobsQueueModel->resetQuery(); + + $this->_ci->JobsQueueModel->addOrder('creationtime', 'DESC'); + + return $this->_ci->JobsQueueModel->loadWhere(array('status' => self::STATUS_NEW, 'type' => $type)); } /** - * + * Add new jobs in the jobs queue with the given type + * jobs is an array of job objects */ - public function addNewJobsToQueue() + public function addNewJobsToQueue($type, $jobs) { + // Checks parameters + if (isEmptyString($type)) return error('The provided type parameter is not a valid string'); + if (isEmptyArray($jobs)) return error('The provided jobs parameter is not a valid array'); + + // Get all the job types + $dbResult = $this->_ci->JobTypesModel->load(); + if (isError($dbResult)) return $dbResult; + $types = getData($dbResult); + + // If the given type is not present in database + if (!$this->_checkJobType($type, $types)) return error('The provided type parameter is not valid'); + + $results = $jobs; // returned values + $errorOccurred = false; // very optimistic + + // Get all the job statuses + $dbResult = $this->_ci->JobStatusesModel->load(); + if (isError($dbResult)) return $dbResult; + $statuses = getData($dbResult); + + // Loops through all the provided jobs + foreach ($results as $job) + { + // If the structure of the job object is valid AND the type is valid AND the status is valid + if ($this->_checkNewJobStructure($job) && $this->_checkJobStatus($job, $statuses)) + { + $this->_dropNotAllowedPropertiesNewJob($job); // remove the black listed properties from this object + + $job->{self::PROPERTY_TYPE} = $type; // What you asked is what you get! + + // Try to insert the single job into database + $dbResult = $this->_ci->JobsQueueModel->insert($job); + + // If an error occurred during while inserting in database + if (isError($dbResult)) + { + $job->{self::PROPERTY_ERROR} = getError($dbResult); // retrieve the cause and store it in job object + $errorOccurred = true; // set error occurred flag + } + else // otherwise + { + $job->{self::PROPERTY_JOBID} = getData($dbResult); // get the jobid and store it in job object + } + } + else // otherwise + { + $errorOccurred = true; // set error occurred flag + } + } + + // If an error occurred then returns the results in an error object + if ($errorOccurred) return error($results); + + return success($results); // otherwise return results in a success object } /** - * + * Updates jobs already present in the jobs queue + * jobs is an array of job objects */ - public function getJobsByStatus() + public function updateJobsQueue($type, $jobs) { + // Checks parameters + if (isEmptyArray($jobs)) return error('The provided jobs parameter is not a valid array'); + + $results = $jobs; // returned values + $errorOccurred = false; // very optimistic + + // Get all the job statuses + $dbResult = $this->_ci->JobStatusesModel->load(); + if (isError($dbResult)) return $dbResult; + $statuses = getData($dbResult); + + // Loops through all the provided jobs + foreach ($results as $job) + { + // If the structure of the job object is valid + if ($this->_checkUpdateJobStructure($job) && $this->_checkJobStatus($job, $statuses)) + { + $this->_dropNotAllowedPropertiesUpdateJob($job); // remove the black listed properties from this object + + $job->{self::PROPERTY_TYPE} = $type; // What you asked is what you get! + + // Try to update the single job into database + $dbResult = $this->_ci->JobsQueueModel->update($job->{self::PROPERTY_JOBID}, (array)$job); + + // If an error occurred during while updating in database + if (isError($dbResult)) + { + $job->{self::PROPERTY_ERROR} = getError($dbResult); // retrieve the cause and store it in job object + $errorOccurred = true; // set error occurred flag + } + } + else // otherwise + { + $errorOccurred = true; // set error occurred flag + } + } + + // If an error occurred then returns the results in an error object + if ($errorOccurred) return error($results); + + return success($results); // otherwise return results in a success object + } + + //------------------------------------------------------------------------------------------------------------------ + // Private methods + + /** + * Checks the job object structure when needed for insert + */ + private function _checkNewJobStructure(&$job) + { + // If job is a valid object and contains the required properties AND does NOT already contain the property error + if (is_object($job) + && property_exists($job, self::PROPERTY_STATUS) + && !property_exists($job, self::PROPERTY_ERROR)) + { + return true; // it is valid! + } + + // If not object then object it! + if (!is_object($job)) $job = new stdClass(); + + // If an error property was not already previously stored then store an error message in job object + if (!property_exists($job, self::PROPERTY_ERROR)) + { + $job->{self::PROPERTY_ERROR} = 'The structure of the provided job is not valid'; + } + + return false; // better sorry than wrong + } + + /** + * Checks the job object structure when needed for update + */ + private function _checkUpdateJobStructure(&$job) + { + // If job is a valid object + if (is_object($job) && property_exists($job, self::PROPERTY_JOBID)) return true; // it is valid! + + // If not object then object it! + if (!is_object($job)) $job = new stdClass(); + + // If an error property was not already previously stored then store an error message in job object + if (!property_exists($job, self::PROPERTY_ERROR)) + { + $job->{self::PROPERTY_ERROR} = 'The structure of the provided job is not valid'; + } + + return false; // better sorry than wrong + } + + /** + * Checks if the given job contains a valid type + */ + private function _checkJobType($type, $types) + { + return $this->_inArray($type, $types, self::PROPERTY_TYPE); + } + + /** + * Checks if the given job contains a valid status + */ + private function _checkJobStatus(&$job, $statuses) + { + $found = $this->_inArray($job->{self::PROPERTY_STATUS}, $statuses, self::PROPERTY_STATUS); + + // No status was not found and does NOT already contain the property error + if (!$found && !property_exists($job, self::PROPERTY_ERROR)) + { + $job->{self::PROPERTY_ERROR} = 'The provided status of this job is not valid'; // store the error message in the object + } + + return $found; + } + + /** + * Search in an array the given value + * The elements of the given array are objects + * The given value is compared with the property specified by the $propertyName parameter of each object of the given array + */ + private function _inArray($value, $array, $propertyName) + { + $found = false; + + foreach ($array as $element) + { + if ($value == $element->{$propertyName}) + { + $found = true; + break; + } + } + + return $found; + } + + /** + * Drop not allowed properties from the given job + */ + private function _dropNotAllowedPropertiesNewJob(&$job) + { + unset($job->{self::PROPERTY_JOBID}); + unset($job->{self::PROPERTY_CREATIONTIME}); + unset($job->{self::PROPERTY_TYPE}); + } + + /** + * Drop not allowed properties from the given job + */ + private function _dropNotAllowedPropertiesUpdateJob(&$job) + { + unset($job->{self::PROPERTY_CREATIONTIME}); + unset($job->{self::PROPERTY_TYPE}); } }