Skip to content

Commit

Permalink
Add HasRootProblem behavior for service
Browse files Browse the repository at this point in the history
  • Loading branch information
raviks789 committed Sep 26, 2024
1 parent a1bbc36 commit b41bdb3
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 2 deletions.
4 changes: 3 additions & 1 deletion application/controllers/ServiceController.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ public function init()
$name = $this->params->getRequired('name');
$hostName = $this->params->getRequired('host.name');

$query = Service::on($this->getDb())->with([
$query = Service::on($this->getDb())
->withColumns(['has_root_problem'])
->with([
'state',
'icon_image',
'host',
Expand Down
106 changes: 106 additions & 0 deletions library/Icingadb/Model/Behavior/HasRootProblem.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<?php

/* Icinga DB Web | (c) 2024 Icinga GmbH | GPLv2 */

namespace Icinga\Module\Icingadb\Model\Behavior;

use Icinga\Module\Icingadb\Model\DependencyEdge;
use ipl\Orm\AliasedExpression;
use ipl\Orm\ColumnDefinition;
use ipl\Orm\Query;
use ipl\Sql\Expression;
use ipl\Sql\Filter\Exists;
use ipl\Sql\Filter\NotExists;
use ipl\Stdlib\Filter;
use ipl\Orm\Contract\RewriteColumnBehavior;
use ipl\Orm\Contract\QueryAwareBehavior;

class HasRootProblem implements RewriteColumnBehavior, QueryAwareBehavior
{
/** @var Query */
protected $query;

public function setQuery(Query $query)
{
$this->query = $query;

return $this;
}

public function rewriteColumn($column, ?string $relation = null)
{
if ($this->isSelectableColumn($column)) {
$subQuery = $this->createBehaviorSubquery($relation);

$column = $relation !== null ? str_replace('.', '_', $relation) . "_$column" : $column;

$alias = $this->query->getDb()->quoteIdentifier([$column]);

list($select, $values) = $this->query->getDb()
->getQueryBuilder()
->assembleSelect($subQuery->assembleSelect());

return new AliasedExpression($alias, "($select)", null, ...$values);
}
}

public function isSelectableColumn(string $name): bool
{
return $name === 'has_root_problem';
}

public function rewriteColumnDefinition(ColumnDefinition $def, string $relation): void
{
$name = $def->getName();

if ($this->isSelectableColumn($name)) {
$def->setLabel(t('Has Root Problem'));
}
}

/**
* Create the sub-query used by the behavior
*
* @param ?string $relation
*
* @return Query
*/
protected function createBehaviorSubquery(?string $relation = null): Query
{
$path = 'from.dependency_node';
$subQueryRelation = $relation !== null ? $relation . $path : $path;
$subQuery = $this->query->createSubQuery(new DependencyEdge(), $subQueryRelation)
->limit(1)
->columns([new Expression('1')]);

$subQuery->getSelectBase()->join(
['root_dependency' => 'dependency'],
[$subQuery->getResolver()->getAlias($subQuery->getModel()) . '.dependency_id = root_dependency.id']
)->join(
['root_dependency_state' => 'dependency_state'],
['root_dependency.id = root_dependency_state.dependency_id']
)->where(new Expression("root_dependency_state.failed = 'y'"));

return $subQuery;
}

public function rewriteCondition(Filter\Condition $condition, $relation = null)
{
$column = substr($condition->getColumn(), strlen($relation));

if ($this->isSelectableColumn($column)) {
$subQuery = $this->createBehaviorSubquery($relation);
if ($condition->getValue()) {
if ($condition instanceof Filter\Unequal) {
return new NotExists($subQuery->assembleSelect());
} else {
return new Exists($subQuery->assembleSelect());
}
} elseif ($condition instanceof Filter\Unequal) {
return new Exists($subQuery->assembleSelect());
} else {
return new NotExists($subQuery->assembleSelect());
}
}
}
}
3 changes: 3 additions & 0 deletions library/Icingadb/Model/Service.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

use Icinga\Module\Icingadb\Common\Auth;
use Icinga\Module\Icingadb\Model\Behavior\BoolCast;
use Icinga\Module\Icingadb\Model\Behavior\HasRootProblem;
use Icinga\Module\Icingadb\Model\Behavior\ReRoute;
use ipl\Orm\Behavior\Binary;
use ipl\Orm\Behaviors;
Expand Down Expand Up @@ -191,6 +192,8 @@ public function createBehaviors(Behaviors $behaviors)
'zone_id',
'command_endpoint_id'
]));

$behaviors->add(new HasRootProblem());
}

public function createDefaults(Defaults $defaults)
Expand Down
6 changes: 5 additions & 1 deletion library/Icingadb/Widget/Detail/ObjectDetail.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use Icinga\Module\Icingadb\Common\Macros;
use Icinga\Module\Icingadb\Compat\CompatHost;
use Icinga\Module\Icingadb\Model\CustomvarFlat;
use Icinga\Module\Icingadb\Model\Service;
use Icinga\Module\Icingadb\Model\UnreachableParent;
use Icinga\Module\Icingadb\Web\Navigation\Action;
use Icinga\Module\Icingadb\Widget\ItemList\DependencyNodeList;
Expand Down Expand Up @@ -606,7 +607,10 @@ protected function fetchCustomVars()

protected function createRootProblems(): ?array
{
if ($this->object->state->is_reachable) {
if (
$this->object->state->is_reachable
|| ($this->object instanceof Service && ! $this->object->has_root_problem)
) {
return null;
}

Expand Down

0 comments on commit b41bdb3

Please sign in to comment.