NodeAction: Allow method appliesTo to throw an exception

Also implements it's usage in all available actions.
This commit is contained in:
Johannes Meyer 2019-01-14 14:57:16 +01:00
parent 877f86a746
commit eef8adb9be
7 changed files with 87 additions and 25 deletions

View file

@ -0,0 +1,9 @@
<?php
namespace Icinga\Module\Businessprocess\Exception;
use Icinga\Exception\IcingaException;
class ModificationError extends IcingaException
{
}

View file

@ -3,6 +3,7 @@
namespace Icinga\Module\Businessprocess\Modification;
use Icinga\Module\Businessprocess\BpConfig;
use Icinga\Module\Businessprocess\Exception\ModificationError;
use Icinga\Module\Businessprocess\Node;
use Icinga\Exception\ProgrammingError;
@ -48,10 +49,13 @@ abstract class NodeAction
abstract public function applyTo(BpConfig $config);
/**
* Every NodeAction must be able to tell whether it could be applied to a BusinessProcess
* Every NodeAction must be able to tell whether it can be applied to a BusinessProcess
*
* @param BpConfig $config
* @return bool
* @param BpConfig $config
*
* @throws ModificationError
*
* @return bool
*/
abstract public function appliesTo(BpConfig $config);
@ -81,6 +85,21 @@ abstract class NodeAction
return $this->getActionName() === $actionName;
}
/**
* Throw a ModificationError
*
* @param string $msg
* @param mixed ...
*
* @throws ModificationError
*/
protected function error($msg)
{
$error = ModificationError::create(func_get_args());
/** @var ModificationError $error */
throw $error;
}
/**
* Create an instance of a given actionName for a specific Node
*

View file

@ -17,11 +17,11 @@ class NodeAddChildrenAction extends NodeAction
{
$name = $this->getNodeName();
if (! $config->hasNode($name)) {
return false;
if (! $config->hasBpNode($name)) {
$this->error('Process "%s" not found', $name);
}
return $config->getNode($name) instanceof BpNode;
return true;
}
/**

View file

@ -72,7 +72,17 @@ class NodeCreateAction extends NodeAction
*/
public function appliesTo(BpConfig $config)
{
return ! $config->hasNode($this->getNodeName());
$name = $this->getNodeName();
if ($config->hasNode($name)) {
$this->error('A node with name "%s" already exists', $name);
}
$parent = $this->getParentName();
if ($parent !== null && !$config->hasBpNode($parent)) {
$this->error('Parent process "%s" missing', $parent);
}
return true;
}
/**

View file

@ -47,15 +47,21 @@ class NodeModifyAction extends NodeAction
$name = $this->getNodeName();
if (! $config->hasNode($name)) {
return false;
$this->error('Node "%s" not found', $name);
}
$node = $config->getNode($name);
foreach ($this->properties as $key => $val) {
$func = 'get' . ucfirst($key);
if ($this->formerProperties[$key] !== $node->$func()) {
return false;
$currentVal = $node->{'get' . ucfirst($key)}();
if ($this->formerProperties[$key] !== $currentVal) {
$this->error(
'Property %s of node "%s" changed its value from "%s" to "%s"',
$key,
$name,
$this->formerProperties[$key],
$currentVal
);
}
}

View file

@ -72,46 +72,55 @@ class NodeMoveAction extends NodeAction
public function appliesTo(BpConfig $config)
{
if (! $config->getMetadata()->isManuallyOrdered()) {
return false;
$this->error('Process configuration is not manually ordered yet');
}
$name = $this->getNodeName();
if ($this->parent !== null) {
if (! $config->hasBpNode($this->parent)) {
return false;
$this->error('Parent process "%s" missing', $this->parent);
}
$parent = $config->getBpNode($this->parent);
if (! $parent->hasChild($name)) {
return false;
$this->error('Node "%s" not found in process "%s"', $name, $this->parent);
}
$nodes = $parent->getChildNames();
if (! isset($nodes[$this->from]) || $nodes[$this->from] !== $name) {
return false;
$this->error('Node "%s" not found at position %d', $name, $this->from);
}
} else {
if (! $config->hasNode($name)) {
return false;
$this->error('Toplevel process "%s" not found', $name);
}
if ($config->getBpNode($name)->getDisplay() !== $this->getFrom()) {
return false;
if ($config->getBpNode($name)->getDisplay() !== $this->from) {
$this->error('Toplevel process "%s" not found at position %d', $name, $this->from);
}
}
if ($this->parent !== $this->newParent) {
if ($this->newParent !== null) {
if (! $config->hasBpNode($this->newParent)) {
return false;
$this->error('New parent process "%s" missing', $this->newParent);
}
$childrenCount = $config->getBpNode($this->newParent)->countChildren();
if ($this->to > 0 && $childrenCount < $this->to) {
$this->error(
'New parent process "%s" has not enough children. Target position %d out of range',
$this->newParent,
$this->to
);
}
} else {
$childrenCount = $config->countChildren();
}
if ($this->getTo() > 0 && $childrenCount < $this->getTo()) {
return false;
if ($this->to > 0 && $childrenCount < $this->to) {
$this->error(
'Process configuration has not enough toplevel processes. Target position %d out of range',
$this->to
);
}
}
}

View file

@ -40,12 +40,21 @@ class NodeRemoveAction extends NodeAction
*/
public function appliesTo(BpConfig $config)
{
$name = $this->getNodeName();
$parent = $this->getParentName();
if ($parent === null) {
return $config->hasNode($this->getNodeName());
if (!$config->hasNode($name)) {
$this->error('Toplevel process "%s" not found', $name);
}
} else {
return $config->hasNode($this->getNodeName()) && $config->hasNode($this->getParentName());
if (! $config->hasNode($parent)) {
$this->error('Parent process "%s" missing', $parent);
} elseif (! $config->getBpNode($parent)->hasChild($name)) {
$this->error('Node "%s" not found in process "%s"', $name, $parent);
}
}
return true;
}
/**