From 5a0acb1af3137f81f58fc95b54e9baadb2d6e905 Mon Sep 17 00:00:00 2001 From: Renato Dinhani Date: Tue, 6 Aug 2024 11:25:04 -0300 Subject: [PATCH] feat: architecture diagram using structurizr --- .../rendered-stratus-components-graphviz.svg | 146 ++++++++++++++++++ .../rendered-stratus-components-mermaid.svg | 1 + .../rendered-stratus-components-plantuml.svg | 1 + static/diagrams/stratus-components.main.kts | 80 ++++++++-- static/diagrams/stratus-components.md | 12 -- 5 files changed, 219 insertions(+), 21 deletions(-) create mode 100644 static/diagrams/rendered-stratus-components-graphviz.svg create mode 100644 static/diagrams/rendered-stratus-components-mermaid.svg create mode 100644 static/diagrams/rendered-stratus-components-plantuml.svg delete mode 100644 static/diagrams/stratus-components.md diff --git a/static/diagrams/rendered-stratus-components-graphviz.svg b/static/diagrams/rendered-stratus-components-graphviz.svg new file mode 100644 index 000000000..823e29d7f --- /dev/null +++ b/static/diagrams/rendered-stratus-components-graphviz.svg @@ -0,0 +1,146 @@ + + + + + + +%3 + +Stratus - Internals - Components + +cluster_2 + +Internals +[Container] + + + +10 + +Storage: Temporary +[Component: In-Memory] + + + +3 + +Importer Online +[Component] + + + +6 + +Core: Executor +[Component] + + + +3->6 + + +execute + + + +4 + +RPC: Server +[Component] + + + +5 + +RPC: Subscriptions +[Component] + + + +4->5 + + +manage + + + +4->6 + + +execute + + + +8 + +Storage +[Component] + + + +4->8 + + +read + + + +7 + +Core: Miner +[Component] + + + +5->7 + + +subscribe + + + +6->7 + + +writes + + + +6->8 + + +read + + + +7->8 + + +write + + + +8->10 + + +read/write + + + +9 + +Storage: Permanent +[Component: RocksDB] + + + +8->9 + + +read/write + + + diff --git a/static/diagrams/rendered-stratus-components-mermaid.svg b/static/diagrams/rendered-stratus-components-mermaid.svg new file mode 100644 index 000000000..95838075f --- /dev/null +++ b/static/diagrams/rendered-stratus-components-mermaid.svg @@ -0,0 +1 @@ +
Stratus - Internals - Components
Internals
execute
manage
read
execute
subscribe
read
writes
write
read/write
read/write
Importer Online
[Component]
RPC: Server
[Component]
RPC: Subscriptions
[Component]
Core: Executor
[Component]
Core: Miner
[Component]
Storage
[Component]
Storage: Permanent
[Component: RocksDB]
Storage: Temporary
[Component: In-Memory]
\ No newline at end of file diff --git a/static/diagrams/rendered-stratus-components-plantuml.svg b/static/diagrams/rendered-stratus-components-plantuml.svg new file mode 100644 index 000000000..4bfc66fb6 --- /dev/null +++ b/static/diagrams/rendered-stratus-components-plantuml.svg @@ -0,0 +1 @@ +Stratus - Internals - ComponentsInternals[Container]Storage: Temporary[In-Memory]Importer OnlineRPC: ServerRPC: SubscriptionsCore: ExecutorCore: MinerStorageStorage: Permanent[RocksDB]executemanagereadexecutesubscribereadwriteswriteread/writeread/writeLegend  component  container boundary(dashed)  \ No newline at end of file diff --git a/static/diagrams/stratus-components.main.kts b/static/diagrams/stratus-components.main.kts index 6f1266f79..69902a6d5 100644 --- a/static/diagrams/stratus-components.main.kts +++ b/static/diagrams/stratus-components.main.kts @@ -1,4 +1,11 @@ -// kotlin stratus-components.main.kts +// Dependencies: +// * Kotlin and JVM for running this script. +// * mermaid-cli for Mermaid diagrams. +// * Graphviz for DOT diagrams. +// * PlantUML for PlantUML diagrams. +// +// Usage: +// kotlin stratus-components.main.kts | bash // ----------------------------------------------------------------------------- // Imports @@ -8,7 +15,9 @@ import com.structurizr.* import com.structurizr.export.* +import com.structurizr.export.dot.* import com.structurizr.export.mermaid.* +import com.structurizr.export.plantuml.* import com.structurizr.model.* import com.structurizr.view.* import java.io.File @@ -18,23 +27,76 @@ import java.io.File // ----------------------------------------------------------------------------- val workspace = Workspace("Stratus", null) val views = workspace.views +val styles = views.configuration.styles val model = workspace.model -val stratus = model.addSoftwareSystem("Stratus") // ----------------------------------------------------------------------------- // Components // ----------------------------------------------------------------------------- -val core = stratus.addContainer("Core") -val storage = stratus.addContainer("Storage") +val stratus = model.addSoftwareSystem("Stratus") +val stratusInternals = stratus.addContainer("Internals") + +val importer = stratusInternals.addComponent("Importer Online") +val rpcServer = stratusInternals.addComponent("RPC: Server") +val rpcSubs = stratusInternals.addComponent("RPC: Subscriptions") +val executor = stratusInternals.addComponent("Core: Executor") +val miner = stratusInternals.addComponent("Core: Miner") +val storage = stratusInternals.addComponent("Storage") +val storagePerm = stratusInternals.addComponent("Storage: Permanent").also { it.technology = "RocksDB"; } +val storageTemp = stratusInternals.addComponent("Storage: Temporary").also { it.technology = "In-Memory"} + +// ----------------------------------------------------------------------------- +// Relationships +// ----------------------------------------------------------------------------- +importer.uses(executor, "execute") + +rpcServer.uses(rpcSubs, "manage") +rpcServer.uses(storage, "read") +rpcServer.uses(executor, "execute") + +rpcSubs.uses(miner, "subscribe") + +executor.uses(storage, "read") +executor.uses(miner, "writes") + +miner.uses(storage, "write") + +storage.uses(storageTemp, "read/write") +storage.uses(storagePerm, "read/write") // ----------------------------------------------------------------------------- // Views // ----------------------------------------------------------------------------- -val stratusView = views.createSystemContextView(stratus, "Internal components", "") -stratusView.addAllElements() +val componentsView = views.createComponentView(stratusInternals, "", "") +componentsView.addAllElements() // ----------------------------------------------------------------------------- -// Exporter +// Exporters // ----------------------------------------------------------------------------- -val diagram = MermaidDiagramExporter().export(stratusView) -File("stratus-components.md").writeText("```mermaid\n${diagram.definition}\n```") +fun export(exporter: AbstractDiagramExporter, view: ComponentView): File { + if (exporter is MermaidDiagramExporter) { + view.enableAutomaticLayout(AutomaticLayout.RankDirection.LeftRight) // mermaid is bugged + } else { + view.enableAutomaticLayout(AutomaticLayout.RankDirection.TopBottom) + } + val diagram = exporter.export(componentsView) + return createTempFile(prefix = "stratus-", suffix = ".diagram").also { it .writeText(diagram.definition) } +} + +val mermaidFile = export(MermaidDiagramExporter(), componentsView) +val dotFile = export(DOTExporter(), componentsView) +val plantUmlFile = export(C4PlantUMLExporter(), componentsView) + +val renderCommands = listOf( + "echo Rendering Mermaid", + "mmdc -i $mermaidFile -o ./rendered-stratus-components-mermaid.svg", + "echo Rendering Graphviz", + "dot -Tsvg $dotFile -o ./rendered-stratus-components-graphviz.svg", + "echo Rendering PlantUML", + "java -jar /usr/local/bin/plantuml.jar -failfast -tsvg -o $(pwd)/plantuml $plantUmlFile", + "mv ./plantuml/*.svg ./rendered-stratus-components-plantuml.svg", + "rm -rf plantuml" + +) +println(renderCommands.joinToString("\n")) + diff --git a/static/diagrams/stratus-components.md b/static/diagrams/stratus-components.md deleted file mode 100644 index 489ededcc..000000000 --- a/static/diagrams/stratus-components.md +++ /dev/null @@ -1,12 +0,0 @@ -```mermaid -graph TB - linkStyle default fill:#ffffff - - subgraph diagram ["Stratus - System Context"] - style diagram fill:#ffffff,stroke:#ffffff - - 1["
Stratus
[Software System]
"] - style 1 fill:#dddddd,stroke:#9a9a9a,color:#000000 - - end -``` \ No newline at end of file