Skip to content

Commit b49abb7

Browse files
yt-msMidnighter
authored andcommitted
feat: add SoftwareSystemInstances to DeploymentNodes
1 parent 00eff23 commit b49abb7

File tree

4 files changed

+87
-3
lines changed

4 files changed

+87
-3
lines changed

src/structurizr/model/deployment_node.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
from .container_instance import ContainerInstance, ContainerInstanceIO
2424
from .deployment_element import DeploymentElement, DeploymentElementIO
2525
from .infrastructure_node import InfrastructureNode, InfrastructureNodeIO
26+
from .software_system import SoftwareSystem
2627
from .software_system_instance import SoftwareSystemInstance, SoftwareSystemInstanceIO
2728

2829

@@ -169,6 +170,37 @@ def add_container_instance(
169170
model += instance
170171
return instance
171172

173+
def add_software_system_instance(
174+
self, software_system: SoftwareSystem, *, replicate_relationships: bool
175+
) -> SoftwareSystemInstance:
176+
"""
177+
Create a new instance of the given software system.
178+
179+
Args:
180+
software_system(SoftwareSystem): the SoftwareSystem to add an instance of.
181+
replicate_relationships: True if relationships should be replicated between
182+
the element instances in the same deployment
183+
environment, False otherwise.
184+
"""
185+
instance_id = (
186+
max(
187+
[
188+
s.instance_id
189+
for s in self.software_system_instances
190+
if s.software_system is software_system
191+
],
192+
default=0,
193+
)
194+
+ 1
195+
)
196+
instance = SoftwareSystemInstance(
197+
software_system=software_system, instance_id=instance_id, parent=self
198+
)
199+
self._software_system_instances.add(instance)
200+
model = self.model
201+
model += instance
202+
return instance
203+
172204
def __iadd__(self, node: "DeploymentNode") -> "DeploymentNode":
173205
"""Add a newly constructed chile deployment node to this node."""
174206
if node in self._children:
@@ -217,4 +249,10 @@ def hydrate(
217249
instance = ContainerInstance.hydrate(instance_io, model=model, parent=node)
218250
node._container_instances.add(instance)
219251

252+
for instance_io in deployment_node_io.software_system_instances:
253+
instance = SoftwareSystemInstance.hydrate(
254+
instance_io, model=model, parent=node
255+
)
256+
node._software_system_instances.add(instance)
257+
220258
return node

src/structurizr/model/software_system_instance.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030

3131
if TYPE_CHECKING:
32+
from .deployment_node import DeploymentNode
3233
from .model import Model
3334

3435

@@ -60,6 +61,7 @@ def hydrate(
6061
cls,
6162
system_instance_io: SoftwareSystemInstanceIO,
6263
model: "Model",
64+
parent: "DeploymentNode",
6365
) -> "SoftwareSystemInstance":
6466
"""Hydrate a new SoftwareSystemInstance instance from its IO.
6567
@@ -69,6 +71,7 @@ def hydrate(
6971
instance = cls(
7072
**cls.hydrate_arguments(system_instance_io),
7173
software_system=system,
74+
parent=parent,
7275
)
7376
model += instance
7477
return instance

tests/unit/model/test_deployment_node.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,3 +164,46 @@ def test_deployment_node_serialising_container(model_with_node):
164164
def test_deployment_node_adding_container_replicating_relationships(model_with_node):
165165
"""Test replicating relationships when adding a container instance."""
166166
raise AssertionError() # Not implemented yet
167+
168+
169+
def test_deployment_node_add_software_system(model_with_node):
170+
"""Test adding a software system to a node to create an instance."""
171+
node = model_with_node.empty_node
172+
system = MockElement("element")
173+
174+
instance = node.add_software_system_instance(system, replicate_relationships=False)
175+
176+
assert instance.software_system is system
177+
assert instance.model is model_with_node
178+
assert instance.parent is node
179+
assert instance in node.software_system_instances
180+
assert instance.instance_id == 1
181+
182+
183+
def test_deployment_node_serialising_software_system(model_with_node):
184+
"""Test serialisation and deserialisation includes container instances."""
185+
node = model_with_node.empty_node
186+
system = model_with_node.mock_element
187+
node.add_software_system_instance(system, replicate_relationships=False)
188+
189+
io = DeploymentNodeIO.from_orm(node)
190+
191+
assert len(io.software_system_instances) == 1
192+
assert io.software_system_instances[0].id == "id"
193+
194+
node2 = DeploymentNode.hydrate(io, model_with_node)
195+
196+
assert len(node2.software_system_instances) == 1
197+
instance = node2.software_system_instances[0]
198+
assert instance.instance_id == 1
199+
assert instance.software_system is system
200+
assert instance.model is model_with_node
201+
assert instance.parent is node2
202+
203+
204+
@pytest.mark.xfail(strict=True)
205+
def test_deployment_node_adding_software_system_replicating_relationships(
206+
model_with_node,
207+
):
208+
"""Test replicating relationships when adding a software system instance."""
209+
raise AssertionError() # Not implemented yet

tests/unit/model/test_software_system_instance.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ def test_software_system_instance_hydration_retrieves_software_system_from_id(
9494
software_system_id="19", instance_id=3, environment="Live"
9595
)
9696

97-
instance = SoftwareSystemInstance.hydrate(io, model_with_system)
97+
instance = SoftwareSystemInstance.hydrate(io, model_with_system, parent=None)
9898

9999
assert instance.instance_id == 3
100100
assert instance.environment == "Live"
@@ -108,7 +108,7 @@ def test_software_system_instance_name_is_software_system_name(model_with_system
108108
software_system_id="19", instance_id=3, environment="Live"
109109
)
110110

111-
instance = SoftwareSystemInstance.hydrate(io, model_with_system)
111+
instance = SoftwareSystemInstance.hydrate(io, model_with_system, parent=None)
112112

113113
assert instance.name == "Mock System"
114114

@@ -123,7 +123,7 @@ def test_software_system_instance_hyrdates_http_health_checks(model_with_system)
123123
health_checks=[health_check_io],
124124
)
125125

126-
instance = SoftwareSystemInstance.hydrate(io, model_with_system)
126+
instance = SoftwareSystemInstance.hydrate(io, model_with_system, parent=None)
127127

128128
assert len(instance.health_checks) == 1
129129
assert list(instance.health_checks)[0].name == "name"

0 commit comments

Comments
 (0)