|
4 | 4 | from ..keeper_dag import DAG, EdgeType |
5 | 5 | from ..keeper_dag.exceptions import DAGVertexException |
6 | 6 | from ..keeper_dag.crypto import urlsafe_str_to_bytes |
7 | | -from ..keeper_dag.types import PamGraphId, PamEndpoints |
| 7 | +from ..keeper_dag.types import PamGraphId |
| 8 | +from discovery_common.types import DiscoveryObject |
8 | 9 | import os |
9 | 10 | import importlib |
10 | 11 | import time |
11 | | -from typing import Any, Optional, TYPE_CHECKING |
| 12 | +from typing import Any, Optional, Dict, List, TYPE_CHECKING |
12 | 13 |
|
13 | 14 | if TYPE_CHECKING: |
14 | 15 | from ..keeper_dag.vertex import DAGVertex |
@@ -59,6 +60,8 @@ def __init__(self, record: Any, logger: Optional[Any] = None, history_level: int |
59 | 60 |
|
60 | 61 | self.conn = get_connection(logger=logger, **kwargs) |
61 | 62 |
|
| 63 | + self._cache: Optional[Dict] = None |
| 64 | + |
62 | 65 | @property |
63 | 66 | def dag(self) -> DAG: |
64 | 67 | if self._dag is None: |
@@ -123,6 +126,12 @@ def close(self): |
123 | 126 | Clean up resources held by this Infrastructure instance. |
124 | 127 | Releases the DAG instance and connection to prevent memory leaks. |
125 | 128 | """ |
| 129 | + if self._cache: |
| 130 | + for v in self._cache.values(): |
| 131 | + v["vertex"] = None |
| 132 | + v["content"] = None |
| 133 | + self._cache.clear() |
| 134 | + |
126 | 135 | if self._dag is not None: |
127 | 136 | self._dag = None |
128 | 137 | self.conn = None |
@@ -150,6 +159,86 @@ def save(self, delta_graph: Optional[bool] = None): |
150 | 159 | self._dag.save(delta_graph=delta_graph) |
151 | 160 | self.logger.debug(f"infrastructure took {time.time()-ts} secs to save") |
152 | 161 |
|
| 162 | + def cache_objects(self): |
| 163 | + |
| 164 | + self.logger.debug(f"building id to infrastructure cache") |
| 165 | + |
| 166 | + self._cache = {} |
| 167 | + |
| 168 | + def _cache(v: DAGVertex, parent_content: Optional[DiscoveryObject] = None): |
| 169 | + c = DiscoveryObject.get_discovery_object(v) |
| 170 | + key = c.object_type_value.lower() + c.id.lower() |
| 171 | + self._cache[key] = { |
| 172 | + "key": key, |
| 173 | + "uid": v.uid, |
| 174 | + "parent_uid": parent_content.uid if parent_content else None, |
| 175 | + "vertex": v, |
| 176 | + "content": c, |
| 177 | + "was_found": False, |
| 178 | + "could_login": True, |
| 179 | + "is_new": False, |
| 180 | + "md5": c.md5 |
| 181 | + } |
| 182 | + |
| 183 | + for next_v in v.has_vertices(): |
| 184 | + _cache(next_v, c) |
| 185 | + |
| 186 | + if self.has_discovery_data: |
| 187 | + ts = time.time() |
| 188 | + _cache(self.get_configuration, None) |
| 189 | + self.logger.info(f" infrastructure cache build time: {time.time()-ts} seconds") |
| 190 | + else: |
| 191 | + self.logger.info(f" no infrastructure data to cache") |
| 192 | + |
| 193 | + def get_cache_info(self, object_type_value: str, object_id: str) -> Dict: |
| 194 | + return self._cache.get(object_type_value.lower() + object_id.lower()) |
| 195 | + |
| 196 | + def get_cache_info_by_key(self, key: str) -> Dict: |
| 197 | + return self._cache.get(key.lower()) |
| 198 | + |
| 199 | + def get_missing_cache_list(self, uid: Optional[str] = None) -> List[str]: |
| 200 | + not_found_list = [] |
| 201 | + for k, v in self._cache.items(): |
| 202 | + if not v["is_new"] and not v["was_found"]: |
| 203 | + if uid is None or uid == v["uid"] or uid == v["parent_uid"]: |
| 204 | + not_found_list.append(k) |
| 205 | + return not_found_list |
| 206 | + |
| 207 | + def add_info_to_cache(self, vertex: DAGVertex, content: DiscoveryObject, parent_vertex: Optional[DAGVertex] = None): |
| 208 | + if self._cache is None: |
| 209 | + self._cache = {} |
| 210 | + |
| 211 | + key = content.object_type_value.lower() + content.id.lower() |
| 212 | + self._cache[key] = { |
| 213 | + "key": key, |
| 214 | + "uid": vertex.uid, |
| 215 | + "parent_uid": parent_vertex.uid if parent_vertex else None, |
| 216 | + "vertex": vertex, |
| 217 | + "content": content, |
| 218 | + "was_found": True, |
| 219 | + "could_login": True, |
| 220 | + "is_new": True, |
| 221 | + "md5": content.md5 |
| 222 | + } |
| 223 | + |
| 224 | + def update_cache_info(self, info: Dict): |
| 225 | + key = info["key"] |
| 226 | + self._cache[key] = info |
| 227 | + |
| 228 | + def find_content(self, query: Dict, ignore_case: bool = False) -> Optional[DAGVertex]: |
| 229 | + """ |
| 230 | + Find the vertex that matches the query. |
| 231 | +
|
| 232 | + Will only find one. |
| 233 | + If it does not match, return None |
| 234 | + If matches on more, return None |
| 235 | + """ |
| 236 | + |
| 237 | + vertices = self.dag.search_content(query=query, ignore_case=ignore_case) |
| 238 | + if len(vertices) != 1: |
| 239 | + return None |
| 240 | + return vertices[0] |
| 241 | + |
153 | 242 | def to_dot(self, graph_format: str = "svg", show_hex_uid: bool = False, |
154 | 243 | show_version: bool = True, show_only_active_vertices: bool = False, |
155 | 244 | show_only_active_edges: bool = False, sync_point: int = None, graph_type: str = "dot"): |
|
0 commit comments