[icinga-checkins] icinga.org: icingaweb2-module-director/fiddle/template-resolver-13033: WIP : TemplateResolver: Fix updating imports without clearing the cache

git at icinga.org git at icinga.org
Thu Nov 3 09:02:03 CET 2016


Module: icingaweb2-module-director
Branch: fiddle/template-resolver-13033
Commit: bfcb452595a1197808578b3e3bcc5f9947ac4abd
URL:    https://git.icinga.org/?p=icingaweb2-module-director.git;a=commit;h=bfcb452595a1197808578b3e3bcc5f9947ac4abd

Author: Markus Frosch <markus.frosch at icinga.com>
Date:   Thu Nov  3 09:01:56 2016 +0100

WIP: TemplateResolver: Fix updating imports without clearing the cache

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

refs #13033

---

 library/Director/Objects/IcingaObject.php          |   15 ++++++
 library/Director/Objects/IcingaObjectImports.php   |    4 +-
 .../Director/Objects/IcingaTemplateResolver.php    |   57 ++++++++++++++++++--
 .../library/Director/Objects/IcingaHostTest.php    |   44 +++++++++++++++
 4 files changed, 115 insertions(+), 5 deletions(-)

diff --git a/library/Director/Objects/IcingaObject.php b/library/Director/Objects/IcingaObject.php
index 6410ca4..af0f6e1 100644
--- a/library/Director/Objects/IcingaObject.php
+++ b/library/Director/Objects/IcingaObject.php
@@ -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
diff --git a/library/Director/Objects/IcingaObjectImports.php b/library/Director/Objects/IcingaObjectImports.php
index ffc440e..ebfeb1e 100644
--- a/library/Director/Objects/IcingaObjectImports.php
+++ b/library/Director/Objects/IcingaObjectImports.php
@@ -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;
     }
 
diff --git a/library/Director/Objects/IcingaTemplateResolver.php b/library/Director/Objects/IcingaTemplateResolver.php
index 31a913e..e1dbb8c 100644
--- a/library/Director/Objects/IcingaTemplateResolver.php
+++ b/library/Director/Objects/IcingaTemplateResolver.php
@@ -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;
     }
 }
diff --git a/test/php/library/Director/Objects/IcingaHostTest.php b/test/php/library/Director/Objects/IcingaHostTest.php
index 1b3175b..edca12d 100644
--- a/test/php/library/Director/Objects/IcingaHostTest.php
+++ b/test/php/library/Director/Objects/IcingaHostTest.php
@@ -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()
     {



More information about the icinga-checkins mailing list