Skip to content

Commit 617d3c6

Browse files
committed
Merge branch 'stable' into stable-to-release-1.2
2 parents 5d5da4d + 33e7c57 commit 617d3c6

22 files changed

+473
-204
lines changed

backend/infrahub/core/diff/enricher/cardinality_one.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from infrahub.core.constants import NULL_VALUE, DiffAction, RelationshipCardinality
44
from infrahub.core.constants.database import DatabaseEdgeType
55
from infrahub.database import InfrahubDatabase
6+
from infrahub.log import get_logger
67

78
from ..model.path import (
89
CalculatedDiffs,
@@ -16,6 +17,8 @@
1617
if TYPE_CHECKING:
1718
from infrahub.core.schema import MainSchemaTypes
1819

20+
log = get_logger()
21+
1922

2023
class DiffCardinalityOneEnricher(DiffEnricherInterface):
2124
"""Clean up diffs for cardinality=one relationships to make them cleaner and more intuitive
@@ -34,13 +37,15 @@ def __init__(self, db: InfrahubDatabase):
3437

3538
async def enrich(self, enriched_diff_root: EnrichedDiffRoot, calculated_diffs: CalculatedDiffs) -> None: # noqa: ARG002
3639
self._node_schema_map = {}
40+
log.info("Beginning cardinality-one diff enrichment...")
3741
for diff_node in enriched_diff_root.nodes:
3842
for relationship_group in diff_node.relationships:
3943
if (
4044
relationship_group.cardinality is RelationshipCardinality.ONE
4145
and len(relationship_group.relationships) > 0
4246
):
4347
self.consolidate_cardinality_one_diff_elements(diff_relationship=relationship_group)
48+
log.info("Cardinality-one diff enrichment complete.")
4449

4550
def _determine_action(self, previous_value: Any, new_value: Any) -> DiffAction:
4651
if previous_value == new_value:

backend/infrahub/core/diff/enricher/hierarchy.py

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,24 @@
77
from infrahub.core.query.relationship import RelationshipGetPeerQuery, RelationshipPeerData
88
from infrahub.core.schema import ProfileSchema, TemplateSchema
99
from infrahub.database import InfrahubDatabase
10+
from infrahub.log import get_logger
1011

1112
from ..model.path import (
1213
CalculatedDiffs,
1314
EnrichedDiffRoot,
1415
)
16+
from ..parent_node_adder import DiffParentNodeAdder, ParentNodeAddRequest
1517
from .interface import DiffEnricherInterface
1618

19+
log = get_logger()
20+
1721

1822
class DiffHierarchyEnricher(DiffEnricherInterface):
1923
"""Add hierarchy and parent/component nodes to diff even if the higher-level nodes are unchanged"""
2024

21-
def __init__(self, db: InfrahubDatabase):
25+
def __init__(self, db: InfrahubDatabase, parent_adder: DiffParentNodeAdder):
2226
self.db = db
27+
self.parent_adder = parent_adder
2328

2429
async def enrich(
2530
self,
@@ -30,6 +35,8 @@ async def enrich(
3035
# - A node has a relationship of kind parent
3136
# - A node is part of a hierarchy
3237

38+
log.info("Beginning hierarchical diff enrichment...")
39+
self.parent_adder.initialize(enriched_diff_root=enriched_diff_root)
3340
node_rel_parent_map: dict[str, list[str]] = defaultdict(list)
3441
node_hierarchy_map: dict[str, list[str]] = defaultdict(list)
3542

@@ -55,6 +62,7 @@ async def enrich(
5562

5663
await self._enrich_nodes_with_parent(enriched_diff_root=enriched_diff_root, node_map=node_rel_parent_map)
5764
await self._enrich_hierarchical_nodes(enriched_diff_root=enriched_diff_root, node_map=node_hierarchy_map)
65+
log.info("Hierarchical diff enrichment complete.")
5866

5967
async def _enrich_hierarchical_nodes(
6068
self,
@@ -65,6 +73,7 @@ async def _enrich_hierarchical_nodes(
6573

6674
# Retrieve the ID of all ancestors
6775
for kind, node_ids in node_map.items():
76+
log.info(f"Beginning hierarchy enrichment for {kind} node, num_nodes={len(node_ids)}...")
6877
hierarchy_schema = self.db.schema.get(
6978
name=kind, branch=enriched_diff_root.diff_branch_name, duplicate=False
7079
)
@@ -89,7 +98,7 @@ async def _enrich_hierarchical_nodes(
8998

9099
current_node = node
91100
for ancestor in ancestors:
92-
parent = enriched_diff_root.add_parent(
101+
parent_request = ParentNodeAddRequest(
93102
node_id=current_node.uuid,
94103
parent_id=str(ancestor.uuid),
95104
parent_kind=ancestor.kind,
@@ -99,6 +108,7 @@ async def _enrich_hierarchical_nodes(
99108
parent_rel_cardinality=parent_rel.cardinality,
100109
parent_rel_label=parent_rel.label or "",
101110
)
111+
parent = self.parent_adder.add_parent(parent_request=parent_request)
102112

103113
current_node = parent
104114

@@ -116,6 +126,7 @@ async def _enrich_nodes_with_parent(
116126

117127
# Query the UUID of the parent
118128
for kind, ids in node_map.items():
129+
log.info(f"Beginning parent enrichment for {kind} node, num_nodes={len(ids)}...")
119130
schema_node = self.db.schema.get(name=kind, branch=enriched_diff_root.diff_branch_name, duplicate=False)
120131

121132
parent_rel = [rel for rel in schema_node.relationships if rel.kind == RelationshipKind.PARENT][0]
@@ -140,15 +151,16 @@ async def _enrich_nodes_with_parent(
140151
# Check if the parent are already present
141152
# If parent is already in the list of node we need to add a relationship
142153
# If parent is not in the list of node, we need to add it
154+
diff_node_map = enriched_diff_root.get_node_map(node_uuids=set(parent_peers.keys()))
143155
for node_id, peer_parent in parent_peers.items():
144156
# TODO check if we can optimize this part to avoid querying this multiple times
145-
node = enriched_diff_root.get_node(node_uuid=node_id)
157+
node = diff_node_map[node_id]
146158
schema_node = self.db.schema.get(
147159
name=node.kind, branch=enriched_diff_root.diff_branch_name, duplicate=False
148160
)
149161
parent_rel = [rel for rel in schema_node.relationships if rel.kind == RelationshipKind.PARENT][0]
150162

151-
enriched_diff_root.add_parent(
163+
parent_request = ParentNodeAddRequest(
152164
node_id=node.uuid,
153165
parent_id=str(peer_parent.peer_id),
154166
parent_kind=peer_parent.peer_kind,
@@ -158,6 +170,7 @@ async def _enrich_nodes_with_parent(
158170
parent_rel_cardinality=parent_rel.cardinality,
159171
parent_rel_label=parent_rel.label or "",
160172
)
173+
self.parent_adder.add_parent(parent_request=parent_request)
161174

162175
if node_parent_with_parent_map:
163176
await self._enrich_nodes_with_parent(

backend/infrahub/core/diff/enricher/labels.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from infrahub.core.constants.database import DatabaseEdgeType
77
from infrahub.core.query.node import NodeGetKindQuery
88
from infrahub.database import InfrahubDatabase
9+
from infrahub.log import get_logger
910

1011
from ..model.path import (
1112
CalculatedDiffs,
@@ -17,6 +18,8 @@
1718
from ..payload_builder import get_display_labels
1819
from .interface import DiffEnricherInterface
1920

21+
log = get_logger()
22+
2023
PROPERTY_TYPES_WITH_LABELS = {DatabaseEdgeType.IS_RELATED, DatabaseEdgeType.HAS_OWNER, DatabaseEdgeType.HAS_SOURCE}
2124

2225

@@ -194,6 +197,7 @@ async def enrich(
194197
calculated_diffs: CalculatedDiffs | None = None, # noqa: ARG002
195198
conflicts_only: bool = False,
196199
) -> None:
200+
log.info("Beginning display labels diff enrichment...")
197201
self._base_branch_name = enriched_diff_root.base_branch_name
198202
self._diff_branch_name = enriched_diff_root.diff_branch_name
199203
self._conflicts_only = conflicts_only
@@ -214,3 +218,4 @@ async def enrich(
214218
...
215219

216220
self._update_relationship_labels(enriched_diff=enriched_diff_root)
221+
log.info("Display labels diff enrichment complete.")

backend/infrahub/core/diff/enricher/path_identifier.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
from infrahub.core.constants import PathType
22
from infrahub.core.path import DataPath
33
from infrahub.database import InfrahubDatabase
4+
from infrahub.log import get_logger
45

56
from ..model.path import CalculatedDiffs, EnrichedDiffRoot
67
from .interface import DiffEnricherInterface
78

9+
log = get_logger()
10+
811

912
class DiffPathIdentifierEnricher(DiffEnricherInterface):
1013
"""Add path identifiers to every element in the diff"""
@@ -62,3 +65,4 @@ async def enrich(self, enriched_diff_root: EnrichedDiffRoot, calculated_diffs: C
6265
relationship_property_path = relationship_element_path.model_copy()
6366
relationship_property_path.property_name = relationship_property.property_type.value
6467
relationship_property.path_identifier = relationship_property_path.get_path(with_peer=False)
68+
log.info("Path identifier diff enrichment complete.")

backend/infrahub/core/diff/model/path.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,13 @@ def has_node(self, node_uuid: str) -> bool:
486486
except ValueError:
487487
return False
488488

489+
def get_node_map(self, node_uuids: set[str] | None = None) -> dict[str, EnrichedDiffNode]:
490+
node_map = {}
491+
for node in self.nodes:
492+
if node_uuids is None or node.uuid in node_uuids:
493+
node_map[node.uuid] = node
494+
return node_map
495+
489496
def get_all_conflicts(self) -> dict[str, EnrichedDiffConflict]:
490497
all_conflicts: dict[str, EnrichedDiffConflict] = {}
491498
for node in self.nodes:
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
from dataclasses import dataclass, field
2+
3+
from infrahub.core.constants import DiffAction, RelationshipCardinality
4+
5+
from .model.path import EnrichedDiffNode, EnrichedDiffRelationship, EnrichedDiffRoot
6+
7+
8+
@dataclass
9+
class ParentNodeAddRequest:
10+
node_id: str
11+
parent_id: str
12+
parent_kind: str
13+
parent_label: str
14+
parent_rel_name: str
15+
parent_rel_identifier: str
16+
parent_rel_cardinality: RelationshipCardinality
17+
parent_rel_label: str = field(default="")
18+
19+
20+
class DiffParentNodeAdder:
21+
def __init__(self) -> None:
22+
self._diff_root: EnrichedDiffRoot | None = None
23+
self._node_map: dict[str, EnrichedDiffNode] = {}
24+
25+
def initialize(self, enriched_diff_root: EnrichedDiffRoot) -> None:
26+
self._diff_root = enriched_diff_root
27+
self._node_map = enriched_diff_root.get_node_map()
28+
29+
def get_root(self) -> EnrichedDiffRoot:
30+
if not self._diff_root:
31+
raise RuntimeError("Must call initialize before using")
32+
return self._diff_root
33+
34+
def get_node(self, node_uuid: str) -> EnrichedDiffNode:
35+
return self._node_map[node_uuid]
36+
37+
def has_node(self, node_uuid: str) -> bool:
38+
return node_uuid in self._node_map
39+
40+
def add_node(self, node: EnrichedDiffNode) -> None:
41+
if node.uuid in self._node_map:
42+
return
43+
self._node_map[node.uuid] = node
44+
self.get_root().nodes.add(node)
45+
46+
def add_parent(self, parent_request: ParentNodeAddRequest) -> EnrichedDiffNode:
47+
if not self._diff_root:
48+
raise RuntimeError("Must call initialize before using")
49+
node = self.get_node(node_uuid=parent_request.node_id)
50+
if not self.has_node(node_uuid=parent_request.parent_id):
51+
parent = EnrichedDiffNode(
52+
uuid=parent_request.parent_id,
53+
kind=parent_request.parent_kind,
54+
label=parent_request.parent_label,
55+
action=DiffAction.UNCHANGED,
56+
changed_at=None,
57+
)
58+
self.add_node(parent)
59+
else:
60+
parent = self.get_node(node_uuid=parent_request.parent_id)
61+
62+
try:
63+
rel = node.get_relationship(name=parent_request.parent_rel_name)
64+
rel.nodes.add(parent)
65+
except ValueError:
66+
node.relationships.add(
67+
EnrichedDiffRelationship(
68+
name=parent_request.parent_rel_name,
69+
identifier=parent_request.parent_rel_identifier,
70+
label=parent_request.parent_rel_label,
71+
cardinality=parent_request.parent_rel_cardinality,
72+
changed_at=None,
73+
action=DiffAction.UNCHANGED,
74+
nodes={parent},
75+
)
76+
)
77+
78+
return parent

backend/infrahub/core/diff/payload_builder.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
from typing import TYPE_CHECKING
44

5+
from infrahub import config
56
from infrahub.core.manager import NodeManager
67
from infrahub.core.registry import registry
78
from infrahub.exceptions import SchemaNotFoundError
@@ -26,8 +27,18 @@ async def get_display_labels_per_kind(
2627
if skip_missing_schema:
2728
return {}
2829
raise
29-
nodes = await NodeManager.get_many(ids=ids, fields=fields, db=db, branch=branch)
30-
return {node_id: await node.render_display_label(db=db) for node_id, node in nodes.items()}
30+
display_label_map: dict[str, str] = {}
31+
offset = 0
32+
limit = config.SETTINGS.database.query_size_limit
33+
while True:
34+
limited_ids = ids[offset : offset + limit]
35+
if not limited_ids:
36+
break
37+
node_map = await NodeManager.get_many(ids=limited_ids, fields=fields, db=db, branch=branch)
38+
for node_id, node in node_map.items():
39+
display_label_map[node_id] = await node.render_display_label(db=db)
40+
offset += limit
41+
return display_label_map
3142

3243

3344
async def get_display_labels(nodes: dict[str, dict[str, list[str]]], db: InfrahubDatabase) -> dict[str, dict[str, str]]:

0 commit comments

Comments
 (0)