1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
<?php
namespace Icinga\Module\Businessprocess\Controllers;
use Icinga\Application\Modules\Module;
use Icinga\Module\Businessprocess\ProvidedHook\Icingadb\IcingadbSupport;
use Icinga\Module\Businessprocess\Renderer\Breadcrumb;
use Icinga\Module\Businessprocess\Renderer\TileRenderer;
use Icinga\Module\Businessprocess\Simulation;
use Icinga\Module\Businessprocess\State\IcingaDbState;
use Icinga\Module\Businessprocess\State\MonitoringState;
use Icinga\Module\Businessprocess\Web\Controller;
use Icinga\Module\Businessprocess\Web\Url;
class NodeController extends Controller
{
public function impactAction()
{
$this->setAutorefreshInterval(10);
$content = $this->content();
$this->controls()->add(
$this->singleTab($this->translate('Node Impact'))
);
$name = $this->params->get('name');
$this->addTitle($this->translate('Business Impact (%s)'), $name);
$simulation = Simulation::fromSession($this->session());
foreach ($this->storage()->listProcessNames() as $configName) {
$config = $this->storage()->loadProcess($configName);
$parents = [];
if ($config->hasNode($name)) {
foreach ($config->getNode($name)->getPaths() as $path) {
array_pop($path); // Remove the monitored node
$immediateParentName = array_pop($path); // The directly affected process
$parents[] = [$config->getNode($immediateParentName), $path];
}
}
$askedConfigs = [];
foreach ($config->getImportedNodes() as $importedNode) {
$importedConfig = $importedNode->getBpConfig();
if (isset($askedConfigs[$importedConfig->getName()])) {
continue;
} else {
$askedConfigs[$importedConfig->getName()] = true;
}
if ($importedConfig->hasNode($name)) {
$node = $importedConfig->getNode($name);
$nativePaths = $node->getPaths($config);
do {
$path = array_pop($nativePaths);
$importedNodePos = array_search($importedNode->getIdentifier(), $path, true);
if ($importedNodePos !== false) {
array_pop($path); // Remove the monitored node
$immediateParentName = array_pop($path); // The directly affected process
$importedPath = array_slice($path, $importedNodePos + 1);
// We may get multiple native paths. Though, only the right hand of the path
// is what we're interested in. The left part is not what is getting imported.
$antiDuplicator = join('|', $importedPath) . '|' . $immediateParentName;
if (isset($parents[$antiDuplicator])) {
continue;
}
foreach ($importedNode->getPaths($config) as $targetPath) {
if ($targetPath[count($targetPath) - 1] === $immediateParentName) {
array_pop($targetPath);
$parent = $importedNode;
} else {
$parent = $importedConfig->getNode($immediateParentName);
}
$parents[$antiDuplicator] = [$parent, array_merge($targetPath, $importedPath)];
}
}
} while (! empty($nativePaths));
}
}
if (empty($parents)) {
continue;
}
if (Module::exists('icingadb') &&
(! $config->getBackendName() && IcingadbSupport::useIcingaDbAsBackend())
) {
IcingaDbState::apply($config);
} else {
MonitoringState::apply($config);
}
$config->applySimulation($simulation);
foreach ($parents as $parentAndPath) {
$renderer = (new TileRenderer($config, array_shift($parentAndPath)))
->setUrl(Url::fromPath('businessprocess/process/show', ['config' => $configName]))
->setPath(array_shift($parentAndPath));
$bc = Breadcrumb::create($renderer);
$bc->getAttributes()->set('data-base-target', '_next');
$content->add($bc);
}
}
if ($content->isEmpty()) {
$content->add($this->translate('No impact detected. Is this node part of a business process?'));
}
}
}
|