Refactor watchers
[pti/o2.git] / o2ims / service / watcher / base.py
index c3ff3d4..45967de 100644 (file)
@@ -12,7 +12,6 @@
 #  See the License for the specific language governing permissions and\r
 #  limitations under the License.\r
 \r
-from o2ims.domain.resource_type import ResourceTypeEnum\r
 from o2ims.service.client.base_client import BaseClient\r
 from o2ims.domain.stx_object import StxGenericModel\r
 from o2ims.service.unit_of_work import AbstractUnitOfWork\r
@@ -21,142 +20,66 @@ import logging
 logger = logging.getLogger(__name__)\r
 \r
 \r
-class InvalidOcloudState(Exception):\r
-    pass\r
-\r
-\r
 class BaseWatcher(object):\r
-    def __init__(self, client: BaseClient) -> None:\r
+    def __init__(self, client: BaseClient,\r
+                 uow: AbstractUnitOfWork) -> None:\r
         super().__init__()\r
         self._client = client\r
+        self._uow = uow\r
 \r
     def targetname(self) -> str:\r
         return self._targetname()\r
 \r
-    def probe(self):\r
-        self._probe()\r
+    def probe(self, parent: object = None):\r
+        return self._probe(parent)\r
 \r
-    def _probe(self):\r
+    def _probe(self, parent: object = None):\r
         raise NotImplementedError\r
 \r
     def _targetname(self):\r
         raise NotImplementedError\r
 \r
-\r
-class OcloudWatcher(BaseWatcher):\r
-    def __init__(self, ocloud_client: BaseClient,\r
-                 uow: AbstractUnitOfWork) -> None:\r
-        super().__init__(ocloud_client)\r
-        self._uow = uow\r
-\r
-    def _targetname(self):\r
-        return "ocloud"\r
-\r
-    def _probe(self):\r
-        ocloudmodel = self._client.get(None)\r
-        if ocloudmodel:\r
-            self._compare_and_update(ocloudmodel)\r
-\r
-    def _compare_and_update(self, ocloudmodel: StxGenericModel) -> bool:\r
-        with self._uow:\r
-            # localmodel = self._uow.stxobjects.get(str(ocloudmodel.id))\r
-            oclouds = self._uow.stxobjects.list(ResourceTypeEnum.OCLOUD)\r
-            if len(oclouds) > 1:\r
-                raise InvalidOcloudState("More than 1 ocloud is found")\r
-            if len(oclouds) == 0:\r
-                logger.info("add ocloud:" + ocloudmodel.name\r
-                            + " update_at: " + str(ocloudmodel.updatetime)\r
-                            + " id: " + str(ocloudmodel.id)\r
-                            + " hash: " + str(ocloudmodel.hash))\r
-                self._uow.stxobjects.add(ocloudmodel)\r
-            else:\r
-                localmodel = oclouds.pop()\r
-                if localmodel.is_outdated(ocloudmodel):\r
-                    logger.info("update ocloud:" + ocloudmodel.name\r
-                                + " update_at: " + str(ocloudmodel.updatetime)\r
-                                + " id: " + str(ocloudmodel.id)\r
-                                + " hash: " + str(ocloudmodel.hash))\r
-                    localmodel.update_by(ocloudmodel)\r
-                    self._uow.stxobjects.update(localmodel)\r
-            self._uow.commit()\r
-\r
-\r
-class DmsWatcher(BaseWatcher):\r
-    def __init__(self, client: BaseClient,\r
-                 uow: AbstractUnitOfWork) -> None:\r
-        super().__init__(client)\r
-        self._uow = uow\r
-\r
-    def _targetname(self):\r
-        return "dms"\r
-\r
-    def _probe(self):\r
-        ocloudmodel = self._client.get(None)\r
-        if ocloudmodel:\r
-            self._compare_and_update(ocloudmodel)\r
-\r
     def _compare_and_update(self, newmodel: StxGenericModel) -> bool:\r
         with self._uow:\r
             # localmodel = self._uow.stxobjects.get(ocloudmodel.id)\r
             localmodel = self._uow.stxobjects.get(str(newmodel.id))\r
             if not localmodel:\r
-                logger.info("add dms:" + newmodel.name)\r
+                logger.info("add entry:" + newmodel.name)\r
                 self._uow.stxobjects.add(newmodel)\r
             elif localmodel.is_outdated(newmodel):\r
-                logger.info("update dms:" + newmodel.name)\r
+                logger.info("update entry:" + newmodel.name)\r
                 localmodel.update_by(newmodel)\r
-                self._uow.stxobjects.update(newmodel)\r
+                self._uow.stxobjects.update(localmodel)\r
             self._uow.commit()\r
 \r
 \r
-class ResourcePoolWatcher(BaseWatcher):\r
-    def __init__(self, client: BaseClient,\r
-                 uow: AbstractUnitOfWork) -> None:\r
+# node to organize watchers in tree hierachy\r
+class WatcherTree(object):\r
+    def __init__(self, watcher: BaseWatcher) -> None:\r
         super().__init__()\r
-        self._uow = uow\r
-\r
-    def _targetname(self):\r
-        return "resourcepool"\r
-\r
-    def _probe(self):\r
-        ocloudmodel = self._client.get(None)\r
-        if ocloudmodel:\r
-            logger.info("detect ocloudmodel:" + ocloudmodel.name)\r
-            self._compare_and_update(ocloudmodel)\r
-\r
-    def _compare_and_update(self, newmodel: StxGenericModel) -> bool:\r
-        with self._uow:\r
-            # localmodel = self._uow.stxobjects.get(ocloudmodel.id)\r
-            localmodel = self._uow.stxobjects.get(str(newmodel.id))\r
-            if not localmodel:\r
-                self._uow.stxobjects.add(newmodel)\r
-            elif localmodel.is_outdated(newmodel):\r
-                localmodel.update_by(newmodel)\r
-                self._uow.stxobjects.update(newmodel)\r
-            self._uow.commit()\r
-\r
-\r
-class ResourceWatcher(BaseWatcher):\r
-    def __init__(self, client: BaseClient,\r
-                 uow: AbstractUnitOfWork) -> None:\r
-        super().__init__()\r
-        self._uow = uow\r
-\r
-    def _targetname(self):\r
-        return "resource"\r
-\r
-    def _probe(self):\r
-        ocloudmodel = self._client.get(None)\r
-        if ocloudmodel:\r
-            self._compare_and_update(ocloudmodel)\r
-\r
-    def _compare_and_update(self, newmodel: StxGenericModel) -> bool:\r
-        with self._uow:\r
-            # localmodel = self._repo.get(ocloudmodel.id)\r
-            localmodel = self._uow.stxobjects.get(str(newmodel.id))\r
-            if not localmodel:\r
-                self._uow.stxobjects.add(newmodel)\r
-            elif localmodel.is_outdated(newmodel):\r
-                localmodel.update_by(newmodel)\r
-                self._uow.stxobjects.update(newmodel)\r
-            self._uow.commit()\r
+        self.watcher = watcher\r
+        self.children = {}\r
+\r
+    def addchild(self, watcher: BaseWatcher) -> object:\r
+        child = WatcherTree(watcher)\r
+        self.children[watcher.targetname()] = child\r
+        return child\r
+\r
+    def removechild(self, targetname: str) -> object:\r
+        return self.children.pop(targetname)\r
+\r
+    # probe all resources by parent, depth = 0 for indefinite recursive\r
+    def probe(self, parentresource=None, depth: int = 0):\r
+        logger.debug("probe resources with watcher: "\r
+                     + self.watcher.targetname())\r
+        childdepth = depth - 1 if depth > 0 else 0\r
+        resources = self.watcher.probe(parentresource)\r
+        logger.debug("probe returns " + str(len(resources)) + "resources")\r
+\r
+        if depth == 1:\r
+            # stop recursive\r
+            return\r
+\r
+        for res in resources:\r
+            for node in self.children:\r
+                node.probe(res, childdepth)\r