WIP: TemplateResolver: Fix updating imports without clearing the cache

Not yet working, IcingaObjectImports load stuff from TemplateResolver, which loops with this code.

refs #13033
This commit is contained in:
Markus Frosch 2016-11-03 09:01:56 +01:00
parent ee0def7d2b
commit bfcb452595
4 changed files with 115 additions and 5 deletions

View File

@ -8,6 +8,7 @@ use Icinga\Data\Filter\FilterChain;
use Icinga\Data\Filter\FilterExpression;
use Icinga\Exception\ProgrammingError;
use Icinga\Module\Director\CustomVariable\CustomVariables;
use Icinga\Module\Director\Data\Db\DbConnection;
use Icinga\Module\Director\IcingaConfig\AssignRenderer;
use Icinga\Module\Director\Data\Db\DbObject;
use Icinga\Module\Director\Db\Cache\PrefetchCache;
@ -1028,6 +1029,14 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
$this->resolveCache[$what] = $vals;
}
protected function onStore()
{
parent::onStore();
if ($this->supportsImports()) {
$this->templateResolver()->refreshObject($this);
}
}
public function invalidateResolveCache()
{
$this->resolveCache = array();
@ -2161,6 +2170,12 @@ abstract class IcingaObject extends DbObject implements IcingaConfigRenderer
return $class::load($id, $db);
}
protected function onLoadFromDb()
{
parent::onLoadFromDb();
$this->templateResolver()->refreshObject($this);
}
/**
* @param $type
* @param $id

View File

@ -168,7 +168,9 @@ class IcingaObjectImports implements Iterator, Countable, IcingaConfigRenderer
protected function refreshIndex()
{
$this->idx = array_keys($this->imports);
$this->object->templateResolver()->refreshObject($this->object);
if ($this->object->hasBeenLoadedFromDb()) {
$this->object->templateResolver()->refreshObject($this->object);
}
return $this;
}

View File

@ -2,7 +2,9 @@
namespace Icinga\Module\Director\Objects;
use Icinga\Exception\IcingaException;
use Icinga\Exception\NotFoundError;
use Icinga\Exception\ProgrammingError;
use Icinga\Module\Director\Db;
use Icinga\Module\Director\Exception\NestingError;
@ -44,6 +46,9 @@ class IcingaTemplateResolver
$this->type = $object->getShortTableName();
$this->table = $object->getTableName();
$this->connection = $object->getConnection();
if ($this->connection === null) {
throw new ProgrammingError('Connection is null for object %s "%s"!', $this->type, $this->object->getId());
}
$this->db = $this->connection->getDbAdapter();
return $this;
@ -376,11 +381,55 @@ class IcingaTemplateResolver
public function refreshObject(IcingaObject $object)
{
$parentNames = $object->imports;
self::$nameIdx[$object->object_name] = $parentNames;
if ($object->hasBeenLoadedFromDb()) {
self::$idIdx[$object->getId()] = $this->getIdsForNames($parentNames);
$this->clearCache();
$this->requireTemplates();
if (substr($object->getObjectName(), 0, 6) !== 'import')
return;
//return;
$name = $object->object_name;
$id = $object->id;
echo "before\n";
var_dump(self::$nameIdx[$this->type]);
var_dump(self::$idIdx[$this->type]);
if ($id === null) {
throw new IcingaException('Can not update index for unstored object: %s', $name);
}
self::$nameToId[$this->type][$name] = $id;
self::$idToName[$this->type][$id] = $name;
var_dump($id);
#unset(self::$nameIdx[$this->type][$name]);
#unset(self::$idIdx[$this->type][$id]);
var_dump($object->imports);
foreach ($object->imports as $import) {
if (array_key_exists($import, self::$nameToId[$this->type])) {
$importId = self::$nameToId[$this->type][$import];
self::$nameIdx[$this->type][$name][$import] = $importId;
self::$idIdx[$this->type][$id][$importId] = $import;
}
else {
throw new IcingaException(
'Import "%s" is unknown for object %s "%s"',
$import, $this->type, $name
);
}
}
echo "after\n";
var_dump(self::$nameIdx[$this->type]);
var_dump(self::$idIdx[$this->type]);
#self::$nameIdx[$this->type][$name] = $parentNames;
#self::$idIdx[$this->type][$id] = $this->getIdsForNames($parentNames);
return $this;
}
}

View File

@ -4,6 +4,7 @@ namespace Tests\Icinga\Module\Director\Objects;
use Icinga\Module\Director\Data\PropertiesFilter\ArrayCustomVariablesFilter;
use Icinga\Module\Director\Data\PropertiesFilter\CustomVariablesFilter;
use Icinga\Module\Director\Exception\NestingError;
use Icinga\Module\Director\IcingaConfig\IcingaConfig;
use Icinga\Module\Director\Objects\DirectorDatafield;
use Icinga\Module\Director\Objects\IcingaHost;
@ -607,6 +608,49 @@ class IcingaHostTest extends BaseTestCase
);
}
public function testLoopingImports()
{
if ($this->skipForMissingDb()) {
return;
}
$db = $this->getDb();
$host1 = IcingaHost::create(array(
'object_name' => 'import_loop1',
'object_type' => 'template',
'vars.import1' => 'yes',
));
$host1->store($db);
$host2 = IcingaHost::create(array(
'object_name' => 'import_loop2',
'object_type' => 'template',
'vars.import2' => '123',
));
$host2->setImports('import_loop1');
$host2->store($db);
$host1->setImports('import_loop2');
$host1->store($db);
unset($host1);
try {
$host1 = IcingaHost::load('import_loop1', $db);
$host2 = IcingaHost::load('import_loop2', $db);
var_dump($host1->templateResolver()->listResolvedParentIds());
var_dump($host1->imports);
var_dump($host2->imports);
throw new IcingaException('This should have triggered a NestingError exception!');
} catch (NestingError $e) {
throw new IcingaException('Nesting Error catched');
}
# TODO
}
protected function getDummyRelatedProperties()
{