summaryrefslogtreecommitdiffstats
path: root/library/Businessprocess/State/IcingaDbState.php
diff options
context:
space:
mode:
Diffstat (limited to 'library/Businessprocess/State/IcingaDbState.php')
-rw-r--r--library/Businessprocess/State/IcingaDbState.php145
1 files changed, 145 insertions, 0 deletions
diff --git a/library/Businessprocess/State/IcingaDbState.php b/library/Businessprocess/State/IcingaDbState.php
new file mode 100644
index 0000000..f33d4a4
--- /dev/null
+++ b/library/Businessprocess/State/IcingaDbState.php
@@ -0,0 +1,145 @@
+<?php
+
+namespace Icinga\Module\Businessprocess\State;
+
+use Exception;
+use Icinga\Application\Benchmark;
+use Icinga\Module\Businessprocess\BpConfig;
+use Icinga\Module\Businessprocess\IcingaDbObject;
+use Icinga\Module\Businessprocess\ServiceNode;
+use Icinga\Module\Icingadb\Model\Host;
+use Icinga\Module\Icingadb\Model\Service;
+use ipl\Sql\Connection as IcingaDbConnection;
+use ipl\Stdlib\Filter;
+
+class IcingaDbState
+{
+ /** @var BpConfig */
+ protected $config;
+
+ /** @var IcingaDbConnection */
+ protected $backend;
+
+ public function __construct(BpConfig $config)
+ {
+ $this->config = $config;
+ $this->backend = IcingaDbObject::fetchDb();
+ }
+
+ public static function apply(BpConfig $config)
+ {
+ $self = new static($config);
+ $self->retrieveStatesFromBackend();
+
+ return $config;
+ }
+
+ public function retrieveStatesFromBackend()
+ {
+ $config = $this->config;
+
+ try {
+ $this->reallyRetrieveStatesFromBackend();
+ } catch (Exception $e) {
+ $config->addError(
+ $config->translate('Could not retrieve process state: %s'),
+ $e->getMessage()
+ );
+ }
+ }
+
+ public function reallyRetrieveStatesFromBackend()
+ {
+ $config = $this->config;
+
+ Benchmark::measure(sprintf(
+ 'Retrieving states for business process %s using Icinga DB backend',
+ $config->getName()
+ ));
+
+ $hosts = $config->listInvolvedHostNames();
+ if (empty($hosts)) {
+ return $this;
+ }
+
+ $queryHost = Host::on($this->backend)->with('state');
+ IcingaDbObject::applyIcingaDbRestrictions($queryHost);
+
+ $queryHost->filter(Filter::equal('host.name', $hosts));
+
+ $hostObject = $queryHost->getModel()->getTableName();
+
+ Benchmark::measure('Retrieved states for ' . $queryHost->count() . ' hosts in ' . $config->getName());
+
+ $queryService = Service::on($this->backend)->with([
+ 'state',
+ 'host',
+ 'host.state'
+ ]);
+
+ $queryService->filter(Filter::equal('host.name', $hosts));
+
+ IcingaDbObject::applyIcingaDbRestrictions($queryService);
+
+ Benchmark::measure('Retrieved states for ' . $queryService->count() . ' services in ' . $config->getName());
+
+ $configs = $config->listInvolvedConfigs();
+
+ $serviceObject = $queryService->getModel()->getTableName();
+
+ foreach ($configs as $cfg) {
+ foreach ($queryService as $row) {
+ $this->handleDbRow($row, $cfg, $serviceObject);
+ }
+ foreach ($queryHost as $row) {
+ $this->handleDbRow($row, $cfg, $hostObject);
+ }
+ }
+
+ Benchmark::measure('Got states for business process ' . $config->getName());
+
+ return $this;
+ }
+
+ protected function handleDbRow($row, BpConfig $config, $objectName)
+ {
+ if ($objectName === 'service') {
+ $key = $row->host->name . ';' . $row->name;
+ } else {
+ $key = $row->name . ';Hoststatus';
+ }
+
+ // We fetch more states than we need, so skip unknown ones
+ if (! $config->hasNode($key)) {
+ return;
+ }
+
+ $node = $config->getNode($key);
+
+ if ($this->config->usesHardStates()) {
+ if ($row->state->hard_state !== null) {
+ $node->setState($row->state->hard_state)->setMissing(false);
+ }
+ } else {
+ if ($row->state->soft_state !== null) {
+ $node->setState($row->state->soft_state)->setMissing(false);
+ }
+ }
+
+ if ($row->state->last_state_change !== null) {
+ $node->setLastStateChange($row->state->last_state_change/1000);
+ }
+ if ($row->state->in_downtime) {
+ $node->setDowntime(true);
+ }
+ if ($row->state->is_acknowledged) {
+ $node->setAck(true);
+ }
+
+ $node->setAlias($row->display_name);
+
+ if ($node instanceof ServiceNode) {
+ $node->setHostAlias($row->host->display_name);
+ }
+ }
+}