Skip to content

Commit 4fe8f5f

Browse files
yt-msMidnighter
authored andcommitted
feat(DeploymentView): add serialisation/deserialisation support
1 parent fa58671 commit 4fe8f5f

File tree

3 files changed

+73
-8
lines changed

3 files changed

+73
-8
lines changed

src/structurizr/view/deployment_view.py

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
Used to show the mapping of container instances to deployment nodes.
1717
"""
1818

19-
from typing import Iterable, Optional, Union
19+
from typing import Iterable, List, Optional, Union
2020

2121
from ..mixin.model_ref_mixin import ModelRefMixin
2222
from ..model.container_instance import ContainerInstance
@@ -26,17 +26,25 @@
2626
from ..model.relationship import Relationship
2727
from ..model.software_system_instance import SoftwareSystemInstance
2828
from ..model.static_structure_element import StaticStructureElement
29-
from .animation import Animation
30-
from .view import View
29+
from .animation import Animation, AnimationIO
30+
from .view import View, ViewIO
3131

3232

3333
__all__ = ("DeploymentView", "DeploymentViewIO")
3434

3535

36-
class DeploymentViewIO:
37-
"""Represent a deployment view."""
36+
class DeploymentViewIO(ViewIO):
37+
"""
38+
Represent a deployment view.
39+
40+
Attributes:
41+
environment: the name of the environment that this deployment view is for
42+
(e.g. "Development", "Live", etc.)
43+
animations: the set of animation steps (optional)
44+
"""
3845

39-
pass
46+
environment: Optional[str] = None
47+
animations: List[AnimationIO] = []
4048

4149

4250
class DeploymentView(ModelRefMixin, View):
@@ -236,3 +244,12 @@ def _find_deployment_node(self, element: Element) -> DeploymentNode:
236244
def animations(self) -> Iterable[Animation]:
237245
"""Return the animations for this view."""
238246
return list(self._animations)
247+
248+
@classmethod
249+
def hydrate(cls, deployment_view_io: DeploymentViewIO) -> "DeploymentView":
250+
"""Hydrate a new DeploymentView instance from its IO."""
251+
return cls(
252+
environment=deployment_view_io.environment,
253+
animations=map(Animation.hydrate, deployment_view_io.animations),
254+
**cls.hydrate_arguments(deployment_view_io),
255+
)

src/structurizr/view/view_set.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
from .component_view import ComponentView, ComponentViewIO
2727
from .configuration import Configuration, ConfigurationIO
2828
from .container_view import ContainerView, ContainerViewIO
29-
from .deployment_view import DeploymentView
29+
from .deployment_view import DeploymentView, DeploymentViewIO
3030
from .system_context_view import SystemContextView, SystemContextViewIO
3131
from .system_landscape_view import SystemLandscapeView, SystemLandscapeViewIO
3232
from .view import View
@@ -55,6 +55,9 @@ class ViewSetIO(BaseModel):
5555
configuration: ConfigurationIO
5656
container_views: List[ContainerViewIO] = Field(default=(), alias="containerViews")
5757
component_views: List[ComponentViewIO] = Field(default=(), alias="componentViews")
58+
deployment_views: List[DeploymentViewIO] = Field(
59+
default=(), alias="deploymentViews"
60+
)
5861

5962
# TODO:
6063
# dynamic_views: List[DynamicView] = Field(set(), alias="dynamicViews")
@@ -129,6 +132,12 @@ def hydrate(cls, views: ViewSetIO, model: "Model") -> "ViewSet":
129132
cls._hydrate_view(view, model=model)
130133
component_views.append(view)
131134

135+
deployment_views = []
136+
for view_io in views.deployment_views:
137+
view = DeploymentView.hydrate(view_io)
138+
cls._hydrate_view(view, model=model)
139+
deployment_views.append(view)
140+
132141
return cls(
133142
model=model,
134143
# TODO:
@@ -137,6 +146,7 @@ def hydrate(cls, views: ViewSetIO, model: "Model") -> "ViewSet":
137146
system_context_views=system_context_views,
138147
container_views=container_views,
139148
component_views=component_views,
149+
deployment_views=deployment_views,
140150
configuration=Configuration.hydrate(views.configuration),
141151
)
142152

tests/unit/view/test_deployment_view.py

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
from structurizr import Workspace
1919
from structurizr.model import SoftwareSystem
20-
from structurizr.view.deployment_view import DeploymentView
20+
from structurizr.view.deployment_view import DeploymentView, DeploymentViewIO
2121

2222

2323
@pytest.fixture(scope="function")
@@ -427,3 +427,41 @@ def test_deployment_view_removing_parent_deployment_node(empty_workspace: Worksp
427427

428428
deployment_view.remove(parent_deployment_node)
429429
assert len(deployment_view.element_views) == 0
430+
431+
432+
def test_deployment_view_hydration(empty_workspace: Workspace):
433+
"""Test round-tripping via the DeploymentViewIO instance."""
434+
model = empty_workspace.model
435+
views = empty_workspace.views
436+
437+
software_system = model.add_software_system("Software System")
438+
web_application = software_system.add_container("Web Application")
439+
database = software_system.add_container("Database")
440+
web_application.uses(database, "Reads from and writes to", "JDBC/HTTPS")
441+
442+
developer_laptop = model.add_deployment_node("Developer Laptop")
443+
apache_tomcat = developer_laptop.add_deployment_node("Apache Tomcat")
444+
oracle = developer_laptop.add_deployment_node("Oracle")
445+
web_application_instance = apache_tomcat.add_container(web_application)
446+
database_instance = oracle.add_container(database)
447+
448+
deployment_view = views.create_deployment_view(
449+
software_system=software_system,
450+
key="deployment",
451+
description="Description",
452+
environment="Live",
453+
)
454+
deployment_view += developer_laptop
455+
assert len(deployment_view.element_views) == 5
456+
457+
deployment_view.add_animation(web_application_instance)
458+
deployment_view.add_animation(database_instance)
459+
460+
io = DeploymentViewIO.from_orm(deployment_view)
461+
assert io.environment == "Live"
462+
assert len(io.animations) == 2
463+
464+
new_deployment_view = DeploymentView.hydrate(io)
465+
assert len(new_deployment_view.element_views) == 5
466+
assert new_deployment_view.environment == deployment_view.environment
467+
assert len(new_deployment_view.animations) == len(deployment_view.animations)

0 commit comments

Comments
 (0)