Fix INF-352 Add aggregate resource types
[pti/o2.git] / o2common / service / watcher / base.py
1 # Copyright (C) 2021 Wind River Systems, Inc.
2 #
3 #  Licensed under the Apache License, Version 2.0 (the "License");
4 #  you may not use this file except in compliance with the License.
5 #  You may obtain a copy of the License at
6 #
7 #      http://www.apache.org/licenses/LICENSE-2.0
8 #
9 #  Unless required by applicable law or agreed to in writing, software
10 #  distributed under the License is distributed on an "AS IS" BASIS,
11 #  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 #  See the License for the specific language governing permissions and
13 #  limitations under the License.
14
15 import traceback
16 # from logging import exception
17 # from cgtsclient import exc
18
19 from o2common.service.client.base_client import BaseClient
20 from o2common.domain import commands
21 from o2common.service.messagebus import MessageBus
22 from o2common.helper import o2logging
23 logger = o2logging.get_logger(__name__)
24
25
26 class BaseWatcher(object):
27     def __init__(self, client: BaseClient,
28                  bus: MessageBus) -> None:
29         super().__init__()
30         self._client = client
31         self._bus = bus
32         self._tags = None
33         # self._uow = bus.uow
34
35     def targetname(self) -> str:
36         return self._targetname()
37
38     def probe(self, parent: commands.Command = None, tags: object = None):
39         try:
40             cmds = self._probe(
41                 parent.data if parent else None, tags)
42             for cmd in cmds:
43                 self._bus.handle(cmd)
44
45             # return self._probe(parent)
46             return cmds
47         except Exception as ex:
48             logger.warning("Failed to probe %s watcher due to: %s - %s" %
49                            (self._targetname(), type(ex), str(ex)))
50             logger.debug(traceback.format_exc())
51             return []
52
53     def _probe(self, parent: object = None, tags: object = None) \
54             -> commands.Command:
55         raise NotImplementedError
56
57     def _targetname(self):
58         raise NotImplementedError
59
60     # def _compare_and_update(self, newmodel: StxGenericModel) -> bool:
61     #     with self._uow:
62     #         # localmodel = self._uow.stxobjects.get(ocloudmodel.id)
63     #         localmodel = self._uow.stxobjects.get(str(newmodel.id))
64     #         if not localmodel:
65     #             logger.info("add entry:" + newmodel.name)
66     #             self._uow.stxobjects.add(newmodel)
67     #         elif localmodel.is_outdated(newmodel):
68     #             logger.info("update entry:" + newmodel.name)
69     #             localmodel.update_by(newmodel)
70     #             self._uow.stxobjects.update(localmodel)
71     #         self._uow.commit()
72
73
74 # node to organize watchers in tree hierachy
75 class WatcherTree(object):
76     def __init__(self, watcher: BaseWatcher) -> None:
77         super().__init__()
78         self.watcher = watcher
79         self.children = {}
80         self.tags = None
81
82     def addchild(self, watcher: BaseWatcher) -> object:
83         child = WatcherTree(watcher)
84         self.children[watcher.targetname()] = child
85         return child
86
87     def removechild(self, targetname: str) -> object:
88         return self.children.pop(targetname)
89
90     # probe all resources by parent, depth = 0 for indefinite recursive
91     def probe(self, parentresource=None, depth: int = 0, tags: object = None):
92         logger.debug("probe resources with watcher: "
93                      + self.watcher.targetname())
94         childdepth = depth - 1 if depth > 0 else 0
95         resources = self.watcher.probe(parentresource, tags)
96         logger.debug("probe returns " + str(len(resources)) + " resources")
97         if self.watcher._tags is not None:
98             tags = self.watcher._tags
99
100         if depth == 1:
101             # stop recursive
102             return
103
104         for res in resources:
105             for targetname in self.children.keys():
106                 self.children[targetname].probe(res, childdepth, tags)