null, 'job_name' => null, 'job_class' => null, 'disabled' => null, 'run_interval' => null, 'last_attempt_succeeded' => null, 'ts_last_attempt' => null, 'ts_last_error' => null, 'last_error_message' => null, 'timeperiod_id' => null, ]; protected $stateProperties = [ 'last_attempt_succeeded', 'last_error_message', 'ts_last_attempt', 'ts_last_error', ]; protected $settingsTable = 'director_job_setting'; protected $settingsRemoteId = 'job_id'; public function getUniqueIdentifier() { return $this->get('job_name'); } /** * @deprecated please use JobHook::getInstance() * @return JobHook */ public function job() { return $this->getInstance(); } /** * @return JobHook */ public function getInstance() { if ($this->job === null) { $class = $this->get('job_class'); $this->job = new $class(); $this->job->setDb($this->connection); $this->job->setDefinition($this); } return $this->job; } /** * @throws \Icinga\Module\Director\Exception\DuplicateKeyException */ public function run() { $job = $this->getInstance(); $this->set('ts_last_attempt', date('Y-m-d H:i:s')); try { $job->run(); $this->set('last_attempt_succeeded', 'y'); $success = true; } catch (Exception $e) { Logger::error($e->getMessage()); $this->set('ts_last_error', date('Y-m-d H:i:s')); $this->set('last_error_message', $e->getMessage()); $this->set('last_attempt_succeeded', 'n'); $success = false; } if ($this->hasBeenModified()) { $this->store(); } return $success; } /** * @return bool */ public function shouldRun() { return (! $this->hasBeenDisabled()) && $this->isPending(); } /** * @return bool */ public function isOverdue() { if (! $this->shouldRun()) { return false; } if ($this->get('ts_last_attempt') === null) { return true; } return ( strtotime($this->get('ts_last_attempt')) + $this->get('run_interval') * 2 ) < time(); } public function hasBeenDisabled() { return $this->get('disabled') === 'y'; } /** * @return bool */ public function isPending() { if ($this->get('ts_last_attempt') === null) { return $this->isWithinTimeperiod(); } if (strtotime($this->get('ts_last_attempt')) + $this->get('run_interval') < time()) { return $this->isWithinTimeperiod(); } return false; } /** * @return bool */ public function isWithinTimeperiod() { if ($this->hasTimeperiod()) { return $this->timeperiod()->isActive(); } else { return true; } } public function lastAttemptSucceeded() { return $this->get('last_attempt_succeeded') === 'y'; } public function lastAttemptFailed() { return $this->get('last_attempt_succeeded') === 'n'; } public function hasTimeperiod() { return $this->get('timeperiod_id') !== null; } /** * @param $timeperiod * @return $this * @throws \Icinga\Exception\NotFoundError */ public function setTimeperiod($timeperiod) { if (is_string($timeperiod)) { $timeperiod = IcingaTimePeriod::load($timeperiod, $this->connection); } elseif (! $timeperiod instanceof IcingaTimePeriod) { throw new InvalidArgumentException('TimePeriod expected'); } $this->set('timeperiod_id', $timeperiod->get('id')); return $this; } /** * @param string $name * @param int $id * @param Db $connection * @api internal * @return bool */ protected static function existsWithNameAndId($name, $id, Db $connection) { $db = $connection->getDbAdapter(); $dummy = new static(); $idCol = $dummy->autoincKeyName; $keyCol = $dummy->keyName; return (string) $id === (string) $db->fetchOne( $db->select() ->from($dummy->table, $idCol) ->where("$idCol = ?", $id) ->where("$keyCol = ?", $name) ); } /** * @api internal Exporter only * @return IcingaTimePeriod */ public function timeperiod() { try { return IcingaTimePeriod::loadWithAutoIncId($this->get('timeperiod_id'), $this->connection); } catch (NotFoundError $e) { throw new \RuntimeException(sprintf( 'The TimePeriod configured for Job "%s" could not have been found', $this->get('name') )); } } }