From cb894dfc25bcdab4fdd583385479f84cc592ac3d Mon Sep 17 00:00:00 2001 From: chris kn Date: Sun, 8 Dec 2024 14:59:20 +0100 Subject: [PATCH] Update Docs and prepare version 13.1 --- README.md | 328 +++-- build.gradle.kts | 2 +- docs/container_example.svg | 2 +- docs/deployment_example.svg | 2 +- docs/dynamic_example_nested.png | Bin 0 -> 109415 bytes docs/dynamic_example_nested.svg | 1237 ----------------- docs/dynamic_example_nested_as_sequence.svg | 2 +- .../internal/export/writer/StyleWriter.kt | 4 +- .../resources/sprites/k8s_stdlib_sprites.json | 496 ++++++- .../view/DeploymentViewTest.kt | 21 +- .../view/DynamicViewTest.kt | 64 +- .../view/style/StyleIntegrationTest.kt | 2 +- .../expected/view/deployment/Deployment.puml | 15 +- .../expected/view/dynamic/DynamicView.puml | 10 +- .../view/dynamic/DynamicWithBoundary.puml | 5 +- .../dynamic/DynamicWithBoundarySequence.puml | 5 +- .../view/dynamic/DynamicWithLayout.puml | 14 +- .../dynamic/DynamicWithLayoutSequence.puml | 10 +- .../DynamicWithNestedParallelFlow.puml | 10 +- ...DynamicWithNestedParallelFlowSequence.puml | 10 +- .../view/dynamic/DynamicWithParallelFlow.puml | 10 +- .../DynamicWithParallelFlowSequence.puml | 10 +- .../view/style/ComponentStyleTest.puml | 2 +- .../expected/view/style/SystemStyleTest.puml | 2 +- 24 files changed, 829 insertions(+), 1434 deletions(-) create mode 100644 docs/dynamic_example_nested.png delete mode 100644 docs/dynamic_example_nested.svg diff --git a/README.md b/README.md index 3c9896c..4b44aba 100644 --- a/README.md +++ b/README.md @@ -5,13 +5,13 @@ Structurizr C4-PlantUML extension aims to bridge the gap between the [structurizr java library](https://github.com/structurizr/java) and [C4-PlantUML](https://github.com/plantuml-stdlib/C4-PlantUML) by extending the structurizr model and providing an extended C4-PlantUML exporter. It is written in Kotlin. ## Table of contents - * [Examples](#example) + * [Diagrams](#example) * [How to use it](#how-to-use-it) * [Related resources](#related-resources) -## Examples +## Diagrams -The following examples diagrams demonstrate the additional features the Structurizr C4-PlantUML extension provides: +The following examples diagrams demonstrate the features the Structurizr C4-PlantUML extension provides: * links, icons and properties for elements and relationships * external containers @@ -20,6 +20,8 @@ The following examples diagrams demonstrate the additional features the Structur * differentiation between synchronous and asynchronous relationships * nested numbered parallel sequences for dynamic diagrams * advanced layout configuration for C4-PlantUML diagrams +* sprite api allowing to use the PlantUML StdLib and custom sprite definitions +* custom styles for model elements and relationships More examples can be found under `src/test/kotlin` @@ -30,110 +32,140 @@ More examples can be found under `src/test/kotlin` The following code creates and writes the example container diagram: ```kotlin -val workspace = Workspace("My Workspace", "") -val model = workspace.model -val properties = C4Properties(values = listOf(listOf("prop 1", "value 1"))) -val softwareSystem = model.softwareSystem( - name = "My Software System", - description = "system description", - link = "https://www.google.de" -) -val backendApplication = softwareSystem.container( - name = "Backend App", - description = "some backend app", - technology = "Kotlin", - tags = listOf("Tag2"), - icon = "docker", - link = "https://www.google.de", - properties = properties -) -val app = softwareSystem.container( - name = "App", - description = "android app", - technology = "Android", - icon = "android", -) -val database = softwareSystem.container( - name = "Database", - description = "some database", - c4Type = C4Type.DATABASE, - technology = "postgres", - icon = "postgresql", - usedBy = listOf(Dependency(backendApplication, "CRUD", "JPA")) -) -val broker = model.softwareSystem( - name = "Broker", - description = "Message Broker", - location = Location.External, - c4Type = C4Type.QUEUE, - icon = "kafka", -) -val topic = broker.container( - "my.topic", - "external topic", - c4Type = C4Type.QUEUE, - icon = "kafka", - usedBy = listOf( - Dependency(backendApplication, "reads topic", "Avro", interactionStyle = InteractionStyle.Asynchronous) + val workspace = Workspace("My Workspace", "") + val model = workspace.model + val properties = C4Properties(values = listOf(listOf("prop 1", "value 1"))) + val softwareSystem = model.softwareSystem( + name = "My Software System", + description = "system description", + link = "https://www.google.de" ) -) -val graphql = model.softwareSystem( - name = "GraphQL", - description = "Federated GraphQL", - location = Location.External, - icon = "graphql" -) -val internalSchema = graphql.container( - name = "Internal Schema", - description = "Schema provided by our app", - location = Location.Internal, - usedBy = listOf( - Dependency(backendApplication, "provides subgraph to"), - Dependency(app, "reuqest data using", "GraphQL", icon = "graphql", link = "https://graphql.org/") + val backendApplication = softwareSystem.container( + name = "Backend App", + description = "some backend app", + technology = "Kotlin", + tags = listOf("Tag2"), + sprite = SpriteLibrary.spriteByName("logos-docker-icon"), + link = "https://www.google.de", + properties = properties ) -) -val externalSchema = graphql.container( - name = "External Schema", - description = "Schema provided by another team", - uses = listOf(Dependency(internalSchema, "extends schema")) -) -val androidUser = model.person( - name = "Android User", - description = "some Android user", - location = Location.External, - icon = "android", - uses = listOf(Dependency(app, "uses app")) -) -val maintainer = model.person( - name = "Maintainer", - description = "some employee", - location = Location.Internal, - link = "https://www.google.de", - uses = listOf( - Dependency(backendApplication, "Admin UI", "REST") - ), - properties = properties -) - -fun createAndWriteContainerView(){ + val app = softwareSystem.container( + name = "App", + description = "android app", + technology = "Android", + sprite = SpriteLibrary.spriteByName("logos-android-icon"), + ) + val database = softwareSystem.container( + name = "Database", + description = "some database", + c4Type = C4Type.DATABASE, + technology = "postgres", + sprite = SpriteLibrary.spriteByName("logos-postgresql-img"), + usedBy = listOf( + Dependency( + destination = backendApplication, + description = "CRUD", + technology = "JPA" + ) + ) + ) + val broker = model.softwareSystem( + name = "Broker", + description = "Message Broker", + location = Location.External, + c4Type = C4Type.QUEUE, + sprite = SpriteLibrary.spriteByName("logos-kafka-icon"), + ) + val topic = broker.container( + "my.topic", + "external topic", + c4Type = C4Type.QUEUE, + sprite = SpriteLibrary.spriteByName("logos-kafka-icon"), + usedBy = listOf( + Dependency( + destination = backendApplication, + description = "reads topic", + technology = "Avro", + interactionStyle = InteractionStyle.Asynchronous + ) + ) + ) + val graphql = model.softwareSystem( + name = "GraphQL", + description = "Federated GraphQL", + location = Location.External, + sprite = SpriteLibrary.spriteByName("logos-graphql") + ) + val internalSchema = graphql.container( + name = "Internal Schema", + description = "Schema provided by our app", + location = Location.Internal, + usedBy = listOf( + Dependency( + destination = backendApplication, + description = "provides subgraph to" + ), + Dependency( + destination = app, + description = "reuqest data using", + technology = "GraphQL", + sprite = SpriteLibrary.spriteByName("logos-graphql"), + link = "https://graphql.org/" + ) + ) + ) + val externalSchema = graphql.container( + name = "External Schema", + description = "Schema provided by another team", + uses = listOf(Dependency(destination = internalSchema, description = "extends schema")) + ) + model.person( + name = "Android User", + description = "some Android user", + location = Location.External, + sprite = SpriteLibrary.spriteByName("logos-android-icon"), + uses = listOf(Dependency(destination = app, description = "uses app")) + ) + model.person( + name = "Maintainer", + description = "some employee", + location = Location.Internal, + link = "https://www.google.de", + uses = listOf( + Dependency( + destination = backendApplication, + description = "Admin UI", + technology = "REST" + ) + ), + properties = properties + ) + + val diagramKey = "ExampleContainerView" val containerView = workspace.views.containerView( - softwareSystem, - "ContainerWithBoundary", - "Example container view", - C4PlantUmlLayout( + system = softwareSystem, + key = diagramKey, + description = "example container view", + layout = C4PlantUmlLayout( legend = Legend.ShowLegend, layout = Layout.TopDown, lineType = LineType.Ortho, nodeSep = 100, rankSep = 130, dependencyConfigurations = listOf( - DependencyConfiguration(filter = { it.destination == database }, direction = Direction.Right), - DependencyConfiguration(filter = { it.destination == topic }, direction = Direction.Up) + DependencyConfiguration( + filter = { it.destination == database }, + direction = Direction.Right + ), + DependencyConfiguration( + filter = { it.destination == topic }, + direction = Direction.Up + ) ) ) ) containerView.addAllContainers() - containerView.externalSoftwareSystemBoundariesVisible = true + containerView.showExternalSoftwareSystemBoundaries = true containerView.add(topic) containerView.add(internalSchema) containerView.add(externalSchema) @@ -147,27 +179,56 @@ fun createAndWriteContainerView(){ As the following example shows, the C4-PlantUML extension provides, in addition to the parallel sequences provided by the Structurizr library, nested numbered parallel sequences for dynamic diagrams. -![Example dynamic diagram](./docs/dynamic_example_nested.svg) +![Example dynamic diagram](./docs/dynamic_example_nested.png) ```kotlin -dynamicView.add(customer, customerFrontend, "Uses") -dynamicView.add(customerFrontend, customerService, "Updates customer information using") -dynamicView.add(customerService, customerDatabase, "Stores data in") -dynamicView.add(customerService, messageBus, "Sends customer update events to") +val dynamicView: DynamicView = workspace.views.dynamicView( + system = customerInformationSystem, + key = diagramKey, + description = "This diagram shows what happens when a customer updates their details", + layout = C4PlantUmlLayout( + dependencyConfigurations = listOf( + DependencyConfiguration( + filter = { it.source == customerFrontend || it.destination == messageBus }, + direction = Right + ), + DependencyConfiguration( + filter = { it.source == customerService && it.destination == customerFrontend }, + direction = Left + ), + DependencyConfiguration( + filter = { it.source == customer }, + direction = Right + ), + DependencyConfiguration( + filter = { it.destination == customer }, + direction = Left + ) + ) + ) +) + +dynamicView.add(source = customer, destination = customerFrontend, description = "Uses") +dynamicView.add(source = customerFrontend, destination = customerService, description = "Updates customer information using") +dynamicView.add(source = customerService, destination = customerDatabase, description = "Stores data in") +dynamicView.add(source = customerService, destination = messageBus, description = "Sends customer update events to") with(dynamicView.startNestedParallelSequence()) { - add(messageBus, reportingService, "Sends customer update events to") + add(source = messageBus, destination = reportingService, description = "Sends customer update events to") with(this.startNestedParallelSequence()) { - add(reportingService, reportingDatabase, "Stores data in") + add(source = reportingService, destination = reportingDatabase, description = "Stores data in") endParallelSequence() } - add(messageBus, auditingService, "Sends customer update events to") + add(source = messageBus, destination = auditingService, description = "Sends customer update events to") with(this.startNestedParallelSequence()) { - add(auditingService, auditStore, "Stores events in") + add(source = auditingService, destination = auditStore, description = "Stores events in") endParallelSequence() } - add(customerService, customerFrontend, "Confirms update to") + add(source = customerService, destination = customerFrontend, description = "Confirms update to") endParallelSequence() } +dynamicView.add(source = customerFrontend, destination = customer, description = "Sends feedback to") + +assertExpectedDiagramWasWrittenForView(workspace, pathToExpectedDiagrams, diagramKey) ``` Dynamic diagrams can also be rendered as sequence diagram by setting the property `DynamicView.renderAsSequenceDiagram` to true. @@ -181,7 +242,7 @@ As the following example demonstrates how to model deployments and create deploy ![Example deployment diagram](./docs/deployment_example.svg) ```kotlin -val mySystem = model.softwareSystem( + val mySystem = model.softwareSystem( "System container", "Example System", Location.Internal @@ -195,22 +256,22 @@ val webApplication: Container = mySystem.container( "Web Application", "Spring Boot web application", technology = "Java and Spring MVC", - icon = "springboot" + sprite = SpriteLibrary.spriteByName("logos-spring"), ) val database: Container = mySystem.container( "Database", "Stores data", technology = "PostgreSql", - icon = "postgresql", + sprite = SpriteLibrary.spriteByName("logos-postgresql"), c4Type = C4Type.DATABASE, properties = C4Properties(values = listOf(listOf("region", "eu-central-1"))), usedBy = listOf(Dependency(webApplication, "stores data in", "JDBC")) ) val failoverDatabase: Container = mySystem.container( - "Failover Database", - database.description, + name = "Failover Database", + description = database.description, technology = database.technology, - icon = database.icon, + sprite = database.sprite, c4Type = database.c4Type, properties = C4Properties(values = listOf(listOf("region", "eu-west-1"))), usedBy = listOf(Dependency(database, "replicates data to")) @@ -218,7 +279,7 @@ val failoverDatabase: Container = mySystem.container( val aws = model.deploymentNode( "AWS", "Production AWS environment", - icon = "aws", + sprite = SpriteLibrary.spriteByName("aws-Groups-AWSCloudAlt"), properties = C4Properties( header = listOf("Property", "Value", "Description"), values = listOf( @@ -229,12 +290,12 @@ val aws = model.deploymentNode( ) aws.deploymentNode( "AWS RDS", - icon = "rds", + sprite = SpriteLibrary.spriteByName("aws-database-AuroraPostgreSQLInstance"), hostsContainers = listOf(failoverDatabase, database) ) val eks = aws.deploymentNode( "EKS cluster", - icon = "awsEKSCloud", + sprite = SpriteLibrary.spriteByName("aws-containers-EKSCloud"), ) val webAppPod = eks.deploymentNode( @@ -242,30 +303,42 @@ val webAppPod = eks.deploymentNode( "Web App POD" ).deploymentNode( "Web App container", - icon = "docker", + sprite = SpriteLibrary.spriteByName("logos-docker-img"), hostsContainers = listOf(webApplication) ) +val jaegerSprite = ( + SpriteLibrary.spriteByName("tupadr3-devicons2-jaegertracing") as PlantUmlSprite + ).copy(color = "lightblue") val jaegerSidecar = webAppPod.infrastructureNode( "Jaeger Sidecar", - "Jaeger sidecar sending Traces" + "Jaeger sidecar sending Traces", + sprite = jaegerSprite ) -model.deploymentNode( +val aws2 = model.deploymentNode( "Another AWS Account", - icon = "aws" -).deploymentNode( - "Jaeger Container", + sprite = SpriteLibrary.spriteByName("aws-groups-AWSCloudAlt") +) +val jaegerContainer = aws2.deploymentNode( + name = "Jaeger Container", + sprite = SpriteLibrary.spriteByName("logos-docker-img"), usedBy = listOf( Dependency( jaegerSidecar, "writes traces to", - interactionStyle = InteractionStyle.Asynchronous, + interactionStyle = Asynchronous, link = "https://www.jaegertracing.io/", + sprite = SpriteLibrary.spriteByName("k8s-KubernetesCronjob"), + properties = C4Properties( + header = listOf("key", "value"), + values = listOf(listOf("ip", "10.234.12.13")) + ) ) ) -).infrastructureNode("Jaeger") +) +jaegerContainer.infrastructureNode("Jaeger", sprite = jaegerSprite) val appleDevice = model.deploymentNode( "Apple Device", - icon = "apple", + sprite = SpriteLibrary.spriteByName("tupadr3-devicons-apple"), hostsSystems = listOf(iosApp) ) @@ -273,7 +346,7 @@ val loadBalancer = eks.infrastructureNode( name = "Load Balancer", description = "Nginx Load Balancer", technology = "nginx", - icon = "nginx", + sprite = SpriteLibrary.spriteByName("logos-nginx"), link = "https://www.google.de", uses = listOf(Dependency(webAppPod, "forwards requests to")), usedBy = listOf(Dependency(appleDevice, "requests data from")), @@ -283,21 +356,22 @@ val loadBalancer = eks.infrastructureNode( ) ) -val deploymentView = views.deploymentView( +val deploymentView = + views.deploymentView( mySystem, - "Deployment", + diagramKey, "A deployment diagram showing the environment.", C4PlantUmlLayout( nodeSep = 50, rankSep = 50, - layout = Layout.LeftToRight, + layout = LeftToRight, dependencyConfigurations = listOf( DependencyConfiguration( filter = { it.source == loadBalancer || it.destination.name == failoverDatabase.name }, - direction = Direction.Left + direction = Right ) ) ) diff --git a/build.gradle.kts b/build.gradle.kts index b6c33a9..a76be0c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -12,7 +12,7 @@ plugins { } group = "io.github.chriskn" -version = "0.12.1" +version = "0.13.1" java.sourceCompatibility = JavaVersion.VERSION_17 repositories { diff --git a/docs/container_example.svg b/docs/container_example.svg index 4e6defa..6c7494d 100644 --- a/docs/container_example.svg +++ b/docs/container_example.svg @@ -1 +1 @@ -My Software System - ContainersMy Software System[System]Broker[System]GraphQL[System]Backend App[Kotlin] some backend appprop 1value 1App[Android] android appDatabase[postgres] some databasemy.topic external topicExternal Schema Schema provided by anotherteamInternal Schema Schema provided by our appAndroid User some Android userMaintainer some employeeprop 1value 1uses appreuqest data using[GraphQL]CRUD[JPA]provides subgraph toreads topic[Avro]extends schemaAdmin UI[REST]Legend  person  container  external_person  external_container  system boundary(dashed)  async relationship(dashed) Example container view \ No newline at end of file +My Software System - ContainersMy Software System - ContainersBroker[system]GraphQL[system]My Software System[system]my.topic external topicExternal Schema Schema provided by anotherteamInternal Schema Schema provided by our appApp[Android] android appBackend App[Kotlin] some backend appprop 1value 1Database[postgres] some databaseAndroid User some Android userMaintainer some employeeprop 1value 1uses appreuqest data using[GraphQL]CRUD[JPA]provides subgraph toreads topic[Avro]extends schemaAdmin UI[REST]Legend  person  container  external person  external container  system boundary  async relationship (dashed) example container view \ No newline at end of file diff --git a/docs/deployment_example.svg b/docs/deployment_example.svg index 6786dd6..e52e9da 100644 --- a/docs/deployment_example.svg +++ b/docs/deployment_example.svg @@ -1 +1 @@ -System container - Deployment - DefaultAWS Production AWS environmentPropertyValueDescriptionProperty1Value1Description1Property2Value2Description2AWS RDSEKS clustermy.web.app Web App PODWeb App containerAnother AWS AccountJaeger ContainerApple DeviceDatabase[PostgreSql] Stores dataregioneu-central-1Failover Database[PostgreSql] Stores dataregioneu-west-1Load Balancer[nginx] Nginx Load BalancerPropertyvalueIP10.234.234.132Jaeger Sidecar Jaeger sidecar sending TracesWeb Application[Java and Spring MVC] Spring Boot web applicationJaegeriOS App iOS Applicationrequests data fromreplicates data towrites traces toforwards requests tostores data in[JDBC]Legend  container  external_system  node  async relationship(dashed) A deployment diagram showing the environment. \ No newline at end of file +System container - Deployment - DefaultSystem container - Deployment - DefaultAWS Production AWS environmentPropertyValueDescriptionProperty1Value1Description1Property2Value2Description2AWS RDSEKS clustermy.web.app Web App PODWeb App containerAnother AWS AccountJaeger ContainerApple DeviceDatabase[PostgreSql] Stores dataregioneu-central-1Failover Database[PostgreSql] Stores dataregioneu-west-1Load Balancer[nginx] Nginx Load BalancerPropertyvalueIP10.234.234.132Jaeger Sidecar Jaeger sidecar sending TracesWeb Application[Java and Spring MVC] Spring Boot web applicationJaegeriOS App iOS Applicationrequests data fromreplicates data towrites traces tokeyvalueip10.234.12.13forwards requests tostores data in[JDBC]Legend  container  external system  node  async relationship (dashed) A deployment diagram showing the environment. \ No newline at end of file diff --git a/docs/dynamic_example_nested.png b/docs/dynamic_example_nested.png new file mode 100644 index 0000000000000000000000000000000000000000..ee5152583145b9ff312a918e2d621ee9331d6af9 GIT binary patch literal 109415 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

IqwT5@?rIZRn9HH$efLNbg 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 z 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 Information System - DynamicCustomer A costumerCustomer FrontendApplication[Angular] Allows customers to managetheir profileCustomer Service[Java and Spring Boot] The point of access forcustomer information.Customer Database[Oracle] Stores customer informationMessage Bus[RabbitMQ] Transport for business events.Reporting Service[Ruby] Creates normalised data forreporting purposes.Reporting Database[MySql] Stores a normalised version ofall business data for ad hocreporting purposesAuditing Service[C#, Net] Provides organisation-wideauditing facilities.Audit Store[Event Store] Stores information aboutevents that have happened1: Uses2: Updates customerinformation using[JSON/HTTPS]5.3: Confirms update to[WebSocket]3: Stores data in[JDBC]4: Sends customer updateevents tofieldvalueEvent Typecreate5.1: Sends customerupdate events to5.1.1: Stores data in5.2: Sends customerupdate events to5.2.1: Stores events inLegend  person  container  async relationship(dashed) This diagram shows what happens when a customer updates their details \ No newline at end of file diff --git a/docs/dynamic_example_nested_as_sequence.svg b/docs/dynamic_example_nested_as_sequence.svg index 0e9fecf..3bf8bae 100644 --- a/docs/dynamic_example_nested_as_sequence.svg +++ b/docs/dynamic_example_nested_as_sequence.svg @@ -1 +1 @@ -Customer Information System - DynamicCustomerCustomer Frontend Application[Angular]Customer Service[Java and Spring Boot]Customer Database[Oracle]Message Bus[RabbitMQ]Reporting Service[Ruby]Reporting Database[MySql]Auditing Service[C#, Net]Audit Store[Event Store]1 Uses2 Updates customerinformation using[JSON/HTTPS]3 Stores data in[JDBC]4 Sends customer updateevents tofieldvalueEvent Typecreate5.1 Sends customerupdate events to 5.1.1Stores data in5.2 Sends customerupdate events to5.2.1 Stores events in5.3 Confirms update to[WebSocket]Legend  person  container  async relationship(last text color, last line color, dashed) This diagram shows what happens when a customer updates their details \ No newline at end of file +Customer Information System - DynamicCustomer Information System - DynamicCustomerCustomer Frontend Application[Angular]Customer Service[Java and Spring Boot]Customer Database[Oracle]Message Bus[RabbitMQ]Reporting Service[Ruby]Reporting Database[MySql]Auditing Service[C#, Net]Audit Store[Event Store]1 Uses2 Updates customerinformation using[JSON/HTTPS]3 Stores data in[JDBC]4 Sends customer updateevents tofieldvalueEvent Typecreate5.1 Sends customerupdate events to5.1.1 Stores data in5.2 Sends customerupdate events to5.2.1 Stores events in5.3 Confirms update to[WebSocket]6 Sends feedback toLegend  person  container  async relationship (dashed) This diagram shows what happens when a customer updates their details \ No newline at end of file diff --git a/src/main/kotlin/com/github/chriskn/structurizrextension/internal/export/writer/StyleWriter.kt b/src/main/kotlin/com/github/chriskn/structurizrextension/internal/export/writer/StyleWriter.kt index 3a749bd..732a944 100644 --- a/src/main/kotlin/com/github/chriskn/structurizrextension/internal/export/writer/StyleWriter.kt +++ b/src/main/kotlin/com/github/chriskn/structurizrextension/internal/export/writer/StyleWriter.kt @@ -197,11 +197,9 @@ internal object StyleWriter { if (scaleString.isBlank()) { """"$url"""" } else { - """"$url,$scaleString"""" + """"$url{$scaleString}"""" } } - - else -> throw IllegalArgumentException("Unknown sprite type ${this::class}") } private fun spriteString( diff --git a/src/main/resources/sprites/k8s_stdlib_sprites.json b/src/main/resources/sprites/k8s_stdlib_sprites.json index 1642648..a0f604f 100644 --- a/src/main/resources/sprites/k8s_stdlib_sprites.json +++ b/src/main/resources/sprites/k8s_stdlib_sprites.json @@ -1 +1,495 @@ -{"name": "Kubernetes plantuml-stdlib Sprites", "source": "https://github.com/plantuml/plantuml-stdlib/tree/master/stdlib/k8s/", "additionalIncludes": [""], "sprites": [{"@type": "PlantUmlSprite", "name": "k8s-C4", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-Common", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-Container", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-Context", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-Simplified", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesApi", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesCcm", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesCm", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesCrb", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesCrd", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesCrole", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesCronjob", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesDeploy", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesDs", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesEp", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesEtcd", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesGroup", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesHpa", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesIng", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesJob", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesKproxy", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesKubelet", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesLimits", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesMaster", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesNetpol", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesNode", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesNs", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesPod", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesPsp", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesPv", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesPvc", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesQuota", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesRb", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesRole", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesRs", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesSa", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesSc", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesSched", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesSecret", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesSts", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesSvc", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesUser", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesVol", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesApi", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesCcm", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesCm", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesCrb", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesCrd", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesCrole", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesCronjob", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesDeploy", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesDs", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesEp", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesEtcd", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesGroup", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesHpa", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesIng", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesJob", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesKproxy", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesKubelet", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesLimits", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesMaster", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesNetpol", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesNode", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesNs", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesPod", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesPsp", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesPv", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesPvc", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesQuota", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesRb", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesRole", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesRs", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesSa", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesSc", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesSched", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesSecret", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesSts", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesSvc", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesUser", "path": "", "color": "#66ABDD"}, {"@type": "PlantUmlSprite", "name": "k8s-KubernetesVol", "path": "", "color": "#66ABDD"}]} \ No newline at end of file +{ + "name": "Kubernetes plantuml-stdlib Sprites", + "source": "https://github.com/plantuml/plantuml-stdlib/tree/master/stdlib/k8s/", + "additionalIncludes": [ + "" + ], + "sprites": [ + { + "@type": "PlantUmlSprite", + "name": "k8s-C4", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-Common", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-Container", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-Context", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-Simplified", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesApi", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesCcm", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesCm", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesCrb", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesCrd", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesCrole", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesCronjob", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesDeploy", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesDs", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesEp", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesEtcd", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesGroup", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesHpa", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesIng", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesJob", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesKproxy", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesKubelet", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesLimits", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesMaster", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesNetpol", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesNode", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesNs", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesPod", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesPsp", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesPv", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesPvc", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesQuota", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesRb", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesRole", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesRs", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesSa", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesSc", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesSched", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesSecret", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesSts", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesSvc", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesUser", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesVol", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesApi", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesCcm", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesCm", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesCrb", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesCrd", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesCrole", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesCronjob", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesDeploy", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesDs", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesEp", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesEtcd", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesGroup", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesHpa", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesIng", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesJob", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesKproxy", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesKubelet", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesLimits", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesMaster", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesNetpol", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesNode", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesNs", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesPod", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesPsp", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesPv", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesPvc", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesQuota", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesRb", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesRole", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesRs", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesSa", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesSc", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesSched", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesSecret", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesSts", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesSvc", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesUser", + "path": "", + "color": "#66ABDD" + }, + { + "@type": "PlantUmlSprite", + "name": "k8s-KubernetesVol", + "path": "", + "color": "#66ABDD" + } + ] +} \ No newline at end of file diff --git a/src/test/kotlin/com/github/chriskn/structurizrextension/view/DeploymentViewTest.kt b/src/test/kotlin/com/github/chriskn/structurizrextension/view/DeploymentViewTest.kt index 0ad688e..7ab645f 100644 --- a/src/test/kotlin/com/github/chriskn/structurizrextension/view/DeploymentViewTest.kt +++ b/src/test/kotlin/com/github/chriskn/structurizrextension/view/DeploymentViewTest.kt @@ -15,6 +15,7 @@ import com.github.chriskn.structurizrextension.api.view.layout.DependencyConfigu import com.github.chriskn.structurizrextension.api.view.layout.Direction.Right import com.github.chriskn.structurizrextension.api.view.layout.Layout.LeftToRight import com.github.chriskn.structurizrextension.api.view.sprite.library.SpriteLibrary +import com.github.chriskn.structurizrextension.api.view.sprite.sprites.PlantUmlSprite import com.github.chriskn.structurizrextension.assertExpectedDiagramWasWrittenForView import com.structurizr.Workspace import com.structurizr.model.Container @@ -97,33 +98,39 @@ class DeploymentViewTest { "Web App POD" ).deploymentNode( "Web App container", - sprite = SpriteLibrary.spriteByName("logos-docker-icon"), + sprite = SpriteLibrary.spriteByName("logos-docker-img"), hostsContainers = listOf(webApplication) ) + val jaegerSprite = ( + SpriteLibrary.spriteByName("tupadr3-devicons2-jaegertracing") as PlantUmlSprite + ).copy(color = "lightblue") val jaegerSidecar = webAppPod.infrastructureNode( "Jaeger Sidecar", "Jaeger sidecar sending Traces", - sprite = SpriteLibrary.spriteByName("tupadr3-devicons2-jaegertracing") + sprite = jaegerSprite ) - model.deploymentNode( + val aws2 = model.deploymentNode( "Another AWS Account", sprite = SpriteLibrary.spriteByName("aws-groups-AWSCloudAlt") - ).deploymentNode( - "Jaeger Container", + ) + val jaegerContainer = aws2.deploymentNode( + name = "Jaeger Container", + sprite = SpriteLibrary.spriteByName("logos-docker-img"), usedBy = listOf( Dependency( jaegerSidecar, "writes traces to", interactionStyle = Asynchronous, - sprite = SpriteLibrary.spriteByName("logos-kafka-icon"), link = "https://www.jaegertracing.io/", + sprite = SpriteLibrary.spriteByName("k8s-KubernetesCronjob"), properties = C4Properties( header = listOf("key", "value"), values = listOf(listOf("ip", "10.234.12.13")) ) ) ) - ).infrastructureNode("Jaeger") + ) + jaegerContainer.infrastructureNode("Jaeger", sprite = jaegerSprite) val appleDevice = model.deploymentNode( "Apple Device", sprite = SpriteLibrary.spriteByName("tupadr3-devicons-apple"), diff --git a/src/test/kotlin/com/github/chriskn/structurizrextension/view/DynamicViewTest.kt b/src/test/kotlin/com/github/chriskn/structurizrextension/view/DynamicViewTest.kt index adcdc52..d823510 100644 --- a/src/test/kotlin/com/github/chriskn/structurizrextension/view/DynamicViewTest.kt +++ b/src/test/kotlin/com/github/chriskn/structurizrextension/view/DynamicViewTest.kt @@ -1,7 +1,8 @@ package com.github.chriskn.structurizrextension.view import com.github.chriskn.structurizrextension.api.model.C4Properties -import com.github.chriskn.structurizrextension.api.model.C4Type +import com.github.chriskn.structurizrextension.api.model.C4Type.DATABASE +import com.github.chriskn.structurizrextension.api.model.C4Type.QUEUE import com.github.chriskn.structurizrextension.api.model.Dependency import com.github.chriskn.structurizrextension.api.model.component import com.github.chriskn.structurizrextension.api.model.container @@ -18,6 +19,7 @@ import com.github.chriskn.structurizrextension.api.view.layout.Direction.Right import com.github.chriskn.structurizrextension.api.view.layout.Mode.Neighbor import com.github.chriskn.structurizrextension.api.view.showExternalBoundaries import com.github.chriskn.structurizrextension.api.view.sprite.library.SpriteLibrary +import com.github.chriskn.structurizrextension.api.view.sprite.sprites.ImageSprite import com.github.chriskn.structurizrextension.assertExpectedDiagramWasWrittenForView import com.structurizr.Workspace import com.structurizr.model.InteractionStyle.Asynchronous @@ -89,9 +91,9 @@ class DynamicViewTest { fun `DynamicWithLayout is written to plant uml as expected`(asSequenceDiagram: Boolean) { val diagramKey = determineDiagramPath("DynamicWithLayout", asSequenceDiagram) val dynamicView: DynamicView = workspace.views.dynamicView( - customerInformationSystem, - diagramKey, - "This diagram shows what happens when a customer updates their details", + system = customerInformationSystem, + key = diagramKey, + description = "This diagram shows what happens when a customer updates their details", layout = C4PlantUmlLayout( dependencyConfigurations = listOf( DependencyConfiguration( @@ -101,12 +103,46 @@ class DynamicViewTest { DependencyConfiguration( filter = { it.source == customerService && it.destination == customerFrontend }, direction = Left + ), + DependencyConfiguration( + filter = { it.source == customer }, + direction = Right + ), + DependencyConfiguration( + filter = { it.destination == customer }, + direction = Left ) ) ) ) - configureWithNestedParallelNumbering(dynamicView) + dynamicView.add(source = customer, destination = customerFrontend, description = "Uses") + dynamicView.add( + source = customerFrontend, + destination = customerService, + description = "Updates customer information using" + ) + dynamicView.add(source = customerService, destination = customerDatabase, description = "Stores data in") + dynamicView.add( + source = customerService, + destination = messageBus, + description = "Sends customer update events to" + ) + with(dynamicView.startNestedParallelSequence()) { + add(source = messageBus, destination = reportingService, description = "Sends customer update events to") + with(this.startNestedParallelSequence()) { + add(source = reportingService, destination = reportingDatabase, description = "Stores data in") + endParallelSequence() + } + add(source = messageBus, destination = auditingService, description = "Sends customer update events to") + with(this.startNestedParallelSequence()) { + add(source = auditingService, destination = auditStore, description = "Stores events in") + endParallelSequence() + } + add(source = customerService, destination = customerFrontend, description = "Confirms update to") + endParallelSequence() + } + dynamicView.add(source = customerFrontend, destination = customer, description = "Sends feedback to") dynamicView.renderAsSequenceDiagram = asSequenceDiagram assertExpectedDiagramWasWrittenForView(workspace, pathToExpectedDiagrams, diagramKey) @@ -282,14 +318,17 @@ class DynamicViewTest { "Customer Database", "Stores customer information", technology = "Oracle", - c4Type = C4Type.DATABASE, + sprite = SpriteLibrary.spriteByName("tupadr3-devicons2-oracle-original"), + c4Type = DATABASE, usedBy = listOf(Dependency(customerService, "", technology = "JDBC", link = "www.google.com")) ) + val rabbitMqSprite = SpriteLibrary.spriteByName("logos-rabbitmq-icon-img") as ImageSprite private val messageBus = customerInformationSystem.container( "Message Bus", "Transport for business events.", technology = "RabbitMQ", - c4Type = C4Type.QUEUE, + c4Type = QUEUE, + sprite = rabbitMqSprite.copy(scale = 0.3), usedBy = listOf( Dependency( customerService, @@ -312,8 +351,9 @@ class DynamicViewTest { "Reporting Database", "Stores a normalised version of all business data for ad hoc reporting purposes", technology = "MySql", - c4Type = C4Type.DATABASE, - usedBy = listOf(Dependency(reportingService, "", sprite = SpriteLibrary.spriteByName("tupadr3-devicons-mysql"))) + c4Type = DATABASE, + sprite = SpriteLibrary.spriteByName("tupadr3-devicons-mysql"), + usedBy = listOf(Dependency(reportingService, "")) ) private val auditingService = customerInformationSystem.container( "Auditing Service", @@ -325,7 +365,7 @@ class DynamicViewTest { "Audit Store", "Stores information about events that have happened", technology = "Event Store", - c4Type = C4Type.DATABASE, + c4Type = DATABASE, usedBy = listOf(Dependency(auditingService, "")) ) private val reportingController = reportingService.component( @@ -337,6 +377,8 @@ class DynamicViewTest { "Reporting Repository", "Reporting repository", technology = "JDBC", - usedBy = listOf(Dependency(reportingController, "")) + usedBy = listOf( + Dependency(reportingController, "", sprite = SpriteLibrary.spriteByName("tupadr3-devicons2-openapi")) + ) ) } diff --git a/src/test/kotlin/com/github/chriskn/structurizrextension/view/style/StyleIntegrationTest.kt b/src/test/kotlin/com/github/chriskn/structurizrextension/view/style/StyleIntegrationTest.kt index 4abf1f2..ee4d067 100644 --- a/src/test/kotlin/com/github/chriskn/structurizrextension/view/style/StyleIntegrationTest.kt +++ b/src/test/kotlin/com/github/chriskn/structurizrextension/view/style/StyleIntegrationTest.kt @@ -135,7 +135,7 @@ class StyleIntegrationTest { technology = "REST", c4Shape = ROUNDED_BOX, sprite = OpenIconicSprite("&compass"), - legendSprite = OpenIconicSprite("&compass"), + legendSprite = OpenIconicSprite("&compass", scale = 1.1, color = "red"), legendText = "this is a legend text" ) private val androidSprite = SpriteLibrary.spriteByName( diff --git a/src/test/resources/expected/view/deployment/Deployment.puml b/src/test/resources/expected/view/deployment/Deployment.puml index 51a4f26..60c5c5f 100644 --- a/src/test/resources/expected/view/deployment/Deployment.puml +++ b/src/test/resources/expected/view/deployment/Deployment.puml @@ -1,11 +1,12 @@ @startuml(id=Deployment) +!define GILBARBARA_PNG_URL https://raw.githubusercontent.com/plantuml-stdlib/gilbarbara-plantuml-sprites/v1.1/pngs !includeurl https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Deployment.puml !includeurl +!includeurl !includeurl !includeurl !includeurl -!includeurl -!includeurl +!includeurl !includeurl !includeurl !includeurl @@ -35,8 +36,8 @@ Node(Default.AWS, "AWS", "", "Production AWS environment", $sprite="AWSCloudAlt, } Node(Default.AWS.EKScluster, "EKS cluster", "", "", $sprite="EKSCloud,color=#ed7100") { Node(Default.AWS.EKScluster.mywebapp, "my.web.app", "", "Web App POD", "") { - Node(Default.AWS.EKScluster.mywebapp.WebAppcontainer, "Web App container", "", "", $sprite="docker-icon") { - Node(Default.AWS.EKScluster.mywebapp.WebAppcontainer.JaegerSidecar, "Jaeger Sidecar", "", "Jaeger sidecar sending Traces", $sprite="jaegertracing") + Node(Default.AWS.EKScluster.mywebapp.WebAppcontainer, "Web App container", "", "", $sprite="img:GILBARBARA_PNG_URL/docker.png") { + Node(Default.AWS.EKScluster.mywebapp.WebAppcontainer.JaegerSidecar, "Jaeger Sidecar", "", "Jaeger sidecar sending Traces", $sprite="jaegertracing,color=#add8e6") Container(Default.AWS.EKScluster.mywebapp.WebAppcontainer.WebApplication_1, "Web Application", "Java and Spring MVC", "Spring Boot web application", $sprite="spring") } } @@ -46,8 +47,8 @@ Node(Default.AWS, "AWS", "", "Production AWS environment", $sprite="AWSCloudAlt, } } Node(Default.AnotherAWSAccount, "Another AWS Account", "", "", $sprite="AWSCloudAlt,color=#232f3e") { - Node(Default.AnotherAWSAccount.JaegerContainer, "Jaeger Container", "", "", "") { - Node(Default.AnotherAWSAccount.JaegerContainer.Jaeger, "Jaeger", "", "", "") + Node(Default.AnotherAWSAccount.JaegerContainer, "Jaeger Container", "", "", $sprite="img:GILBARBARA_PNG_URL/docker.png") { + Node(Default.AnotherAWSAccount.JaegerContainer.Jaeger, "Jaeger", "", "", $sprite="jaegertracing,color=#add8e6") } } Node(Default.AppleDevice, "Apple Device", "", "", $sprite="apple") { @@ -57,7 +58,7 @@ Rel(Default.AppleDevice, Default.AWS.EKScluster.LoadBalancer, "requests data fro Rel_R(Default.AWS.AWSRDS.Database_1, Default.AWS.AWSRDS.FailoverDatabase_1, "replicates data to") SetPropertyHeader("key", "value") AddProperty("ip", "10.234.12.13") -Rel(Default.AWS.EKScluster.mywebapp.WebAppcontainer.JaegerSidecar, Default.AnotherAWSAccount.JaegerContainer, "writes traces to", $sprite="kafka-icon", $link="https://www.jaegertracing.io/", $tags="async relationship") +Rel(Default.AWS.EKScluster.mywebapp.WebAppcontainer.JaegerSidecar, Default.AnotherAWSAccount.JaegerContainer, "writes traces to", $sprite="KubernetesCronjob,color=#66abdd", $link="https://www.jaegertracing.io/", $tags="async relationship") Rel_R(Default.AWS.EKScluster.LoadBalancer, Default.AWS.EKScluster.mywebapp.WebAppcontainer, "forwards requests to") Rel(Default.AWS.EKScluster.mywebapp.WebAppcontainer.WebApplication_1, Default.AWS.AWSRDS.Database_1, "stores data in", "JDBC") diff --git a/src/test/resources/expected/view/dynamic/DynamicView.puml b/src/test/resources/expected/view/dynamic/DynamicView.puml index d12cfd4..e88ed4b 100644 --- a/src/test/resources/expected/view/dynamic/DynamicView.puml +++ b/src/test/resources/expected/view/dynamic/DynamicView.puml @@ -1,6 +1,8 @@ @startuml(id=DynamicView) +!define GILBARBARA_PNG_URL https://raw.githubusercontent.com/plantuml-stdlib/gilbarbara-plantuml-sprites/v1.1/pngs !includeurl https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Dynamic.puml !includeurl +!includeurl title Customer Information System - Dynamic caption desc @@ -13,10 +15,10 @@ AddRelTag("async relationship", $lineStyle=DashedLine(), $legendText=async relat Person(Customer, "Customer", "A costumer", "") Container(CustomerInformationSystem.CustomerFrontendApplication, "Customer Frontend Application", "Angular", "Allows customers to manage their profile", "") Container(CustomerInformationSystem.CustomerService, "Customer Service", "Java and Spring Boot", "The point of access for customer information.", "") -ContainerDb(CustomerInformationSystem.CustomerDatabase, "Customer Database", "Oracle", "Stores customer information", "") -ContainerQueue(CustomerInformationSystem.MessageBus, "Message Bus", "RabbitMQ", "Transport for business events.", "") +ContainerDb(CustomerInformationSystem.CustomerDatabase, "Customer Database", "Oracle", "Stores customer information", $sprite="oracle_original") +ContainerQueue(CustomerInformationSystem.MessageBus, "Message Bus", "RabbitMQ", "Transport for business events.", $sprite="img:GILBARBARA_PNG_URL/rabbitmq-icon.png{scale=0.3}") Container(CustomerInformationSystem.ReportingService, "Reporting Service", "Ruby", "Creates normalised data for reporting purposes.", "") -ContainerDb(CustomerInformationSystem.ReportingDatabase, "Reporting Database", "MySql", "Stores a normalised version of all business data for ad hoc reporting purposes", "") +ContainerDb(CustomerInformationSystem.ReportingDatabase, "Reporting Database", "MySql", "Stores a normalised version of all business data for ad hoc reporting purposes", $sprite="mysql") Container(CustomerInformationSystem.AuditingService, "Auditing Service", "C#, Net", "Provides organisation-wide auditing facilities.", "") ContainerDb(CustomerInformationSystem.AuditStore, "Audit Store", "Event Store", "Stores information about events that have happened", "") RelIndex(1,Customer, CustomerInformationSystem.CustomerFrontendApplication, "Uses") @@ -26,7 +28,7 @@ SetPropertyHeader("field", "value") AddProperty("Event Type", "create") RelIndex(4,CustomerInformationSystem.CustomerService, CustomerInformationSystem.MessageBus, "Sends customer update events to", $tags="async relationship") RelIndex(5.1,CustomerInformationSystem.MessageBus, CustomerInformationSystem.ReportingService, "Sends customer update events to", $tags="async relationship") -RelIndex(5.1.1,CustomerInformationSystem.ReportingService, CustomerInformationSystem.ReportingDatabase, "Stores data in", $sprite="mysql") +RelIndex(5.1.1,CustomerInformationSystem.ReportingService, CustomerInformationSystem.ReportingDatabase, "Stores data in") RelIndex(5.2,CustomerInformationSystem.MessageBus, CustomerInformationSystem.AuditingService, "Sends customer update events to", $tags="async relationship") RelIndex(5.2.1,CustomerInformationSystem.AuditingService, CustomerInformationSystem.AuditStore, "Stores events in") RelIndex(5.3,CustomerInformationSystem.CustomerService, CustomerInformationSystem.CustomerFrontendApplication, "Confirms update to", "WebSocket", $link="www.bing.com", $tags="async relationship") diff --git a/src/test/resources/expected/view/dynamic/DynamicWithBoundary.puml b/src/test/resources/expected/view/dynamic/DynamicWithBoundary.puml index 86a5c89..78084fd 100644 --- a/src/test/resources/expected/view/dynamic/DynamicWithBoundary.puml +++ b/src/test/resources/expected/view/dynamic/DynamicWithBoundary.puml @@ -1,5 +1,6 @@ @startuml(id=DynamicWithBoundary) !includeurl https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Dynamic.puml +!includeurl title Reporting Service - Dynamic caption This diagram shows what happens when a customer updates their details @@ -8,12 +9,12 @@ SHOW_PERSON_OUTLINE() LAYOUT_TOP_DOWN() System_Boundary(CustomerInformationSystem, Customer Information System) { - Container_Boundary("CustomerInformationSystem.ReportingService_boundary", "Reporting Service") { + Container_Boundary("CustomerInformationSystem.ReportingService_boundary", "Reporting Service" ){ Component(CustomerInformationSystem.ReportingService.ReportingController, "Reporting Controller", "REST", "Reporting Controller", "") Component(CustomerInformationSystem.ReportingService.ReportingRepository, "Reporting Repository", "JDBC", "Reporting repository", "") } } -RelIndex(1,CustomerInformationSystem.ReportingService.ReportingController, CustomerInformationSystem.ReportingService.ReportingRepository, "Stores entity") +RelIndex(1,CustomerInformationSystem.ReportingService.ReportingController, CustomerInformationSystem.ReportingService.ReportingRepository, "Stores entity", $sprite="openapi") SHOW_LEGEND(true) diff --git a/src/test/resources/expected/view/dynamic/DynamicWithBoundarySequence.puml b/src/test/resources/expected/view/dynamic/DynamicWithBoundarySequence.puml index e7dddda..593d256 100644 --- a/src/test/resources/expected/view/dynamic/DynamicWithBoundarySequence.puml +++ b/src/test/resources/expected/view/dynamic/DynamicWithBoundarySequence.puml @@ -1,5 +1,6 @@ @startuml(id=DynamicWithBoundarySequence) !includeurl https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Sequence.puml +!includeurl title Reporting Service - Dynamic caption This diagram shows what happens when a customer updates their details @@ -7,12 +8,12 @@ caption This diagram shows what happens when a customer updates their details SHOW_PERSON_OUTLINE() System_Boundary(CustomerInformationSystem, Customer Information System) - Container_Boundary("CustomerInformationSystem.ReportingService_boundary", "Reporting Service") + Container_Boundary("CustomerInformationSystem.ReportingService_boundary", "Reporting Service" ) Component(CustomerInformationSystem.ReportingService.ReportingController, "Reporting Controller", "REST", "Reporting Controller", "") Component(CustomerInformationSystem.ReportingService.ReportingRepository, "Reporting Repository", "JDBC", "Reporting repository", "") Boundary_End() Boundary_End() -Rel(CustomerInformationSystem.ReportingService.ReportingController, CustomerInformationSystem.ReportingService.ReportingRepository, "1 Stores entity" ) +Rel(CustomerInformationSystem.ReportingService.ReportingController, CustomerInformationSystem.ReportingService.ReportingRepository, "1 Stores entity" , $sprite="openapi") SHOW_LEGEND(true) diff --git a/src/test/resources/expected/view/dynamic/DynamicWithLayout.puml b/src/test/resources/expected/view/dynamic/DynamicWithLayout.puml index f1b7f73..cf4b55c 100644 --- a/src/test/resources/expected/view/dynamic/DynamicWithLayout.puml +++ b/src/test/resources/expected/view/dynamic/DynamicWithLayout.puml @@ -1,6 +1,8 @@ @startuml(id=DynamicWithLayout) +!define GILBARBARA_PNG_URL https://raw.githubusercontent.com/plantuml-stdlib/gilbarbara-plantuml-sprites/v1.1/pngs !includeurl https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Dynamic.puml !includeurl +!includeurl title Customer Information System - Dynamic caption This diagram shows what happens when a customer updates their details @@ -13,24 +15,24 @@ AddRelTag("async relationship", $lineStyle=DashedLine(), $legendText=async relat Person(Customer, "Customer", "A costumer", "") Container(CustomerInformationSystem.CustomerFrontendApplication, "Customer Frontend Application", "Angular", "Allows customers to manage their profile", "") Container(CustomerInformationSystem.CustomerService, "Customer Service", "Java and Spring Boot", "The point of access for customer information.", "") -ContainerDb(CustomerInformationSystem.CustomerDatabase, "Customer Database", "Oracle", "Stores customer information", "") -ContainerQueue(CustomerInformationSystem.MessageBus, "Message Bus", "RabbitMQ", "Transport for business events.", "") +ContainerDb(CustomerInformationSystem.CustomerDatabase, "Customer Database", "Oracle", "Stores customer information", $sprite="oracle_original") +ContainerQueue(CustomerInformationSystem.MessageBus, "Message Bus", "RabbitMQ", "Transport for business events.", $sprite="img:GILBARBARA_PNG_URL/rabbitmq-icon.png{scale=0.3}") Container(CustomerInformationSystem.ReportingService, "Reporting Service", "Ruby", "Creates normalised data for reporting purposes.", "") -ContainerDb(CustomerInformationSystem.ReportingDatabase, "Reporting Database", "MySql", "Stores a normalised version of all business data for ad hoc reporting purposes", "") +ContainerDb(CustomerInformationSystem.ReportingDatabase, "Reporting Database", "MySql", "Stores a normalised version of all business data for ad hoc reporting purposes", $sprite="mysql") Container(CustomerInformationSystem.AuditingService, "Auditing Service", "C#, Net", "Provides organisation-wide auditing facilities.", "") ContainerDb(CustomerInformationSystem.AuditStore, "Audit Store", "Event Store", "Stores information about events that have happened", "") -RelIndex(1,Customer, CustomerInformationSystem.CustomerFrontendApplication, "Uses") +RelIndex_R(1,Customer, CustomerInformationSystem.CustomerFrontendApplication, "Uses") RelIndex_R(2,CustomerInformationSystem.CustomerFrontendApplication, CustomerInformationSystem.CustomerService, "Updates customer information using", "JSON/HTTPS") RelIndex(3,CustomerInformationSystem.CustomerService, CustomerInformationSystem.CustomerDatabase, "Stores data in", "JDBC", $link="www.google.com") SetPropertyHeader("field", "value") AddProperty("Event Type", "create") RelIndex_R(4,CustomerInformationSystem.CustomerService, CustomerInformationSystem.MessageBus, "Sends customer update events to", $tags="async relationship") RelIndex(5.1,CustomerInformationSystem.MessageBus, CustomerInformationSystem.ReportingService, "Sends customer update events to", $tags="async relationship") -RelIndex(5.1.1,CustomerInformationSystem.ReportingService, CustomerInformationSystem.ReportingDatabase, "Stores data in", $sprite="mysql") +RelIndex(5.1.1,CustomerInformationSystem.ReportingService, CustomerInformationSystem.ReportingDatabase, "Stores data in") RelIndex(5.2,CustomerInformationSystem.MessageBus, CustomerInformationSystem.AuditingService, "Sends customer update events to", $tags="async relationship") RelIndex(5.2.1,CustomerInformationSystem.AuditingService, CustomerInformationSystem.AuditStore, "Stores events in") RelIndex_L(5.3,CustomerInformationSystem.CustomerService, CustomerInformationSystem.CustomerFrontendApplication, "Confirms update to", "WebSocket", $link="www.bing.com", $tags="async relationship") -RelIndex(6,CustomerInformationSystem.CustomerFrontendApplication, Customer, "Sends feedback to") +RelIndex_L(6,CustomerInformationSystem.CustomerFrontendApplication, Customer, "Sends feedback to") SHOW_LEGEND(true) diff --git a/src/test/resources/expected/view/dynamic/DynamicWithLayoutSequence.puml b/src/test/resources/expected/view/dynamic/DynamicWithLayoutSequence.puml index d1e8903..91d4b9f 100644 --- a/src/test/resources/expected/view/dynamic/DynamicWithLayoutSequence.puml +++ b/src/test/resources/expected/view/dynamic/DynamicWithLayoutSequence.puml @@ -1,6 +1,8 @@ @startuml(id=DynamicWithLayoutSequence) +!define GILBARBARA_PNG_URL https://raw.githubusercontent.com/plantuml-stdlib/gilbarbara-plantuml-sprites/v1.1/pngs !includeurl https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Sequence.puml !includeurl +!includeurl title Customer Information System - Dynamic caption This diagram shows what happens when a customer updates their details @@ -12,10 +14,10 @@ AddRelTag("async relationship", $lineStyle=DashedLine(), $legendText=async relat Person(Customer, "Customer", "A costumer", "") Container(CustomerInformationSystem.CustomerFrontendApplication, "Customer Frontend Application", "Angular", "Allows customers to manage their profile", "") Container(CustomerInformationSystem.CustomerService, "Customer Service", "Java and Spring Boot", "The point of access for customer information.", "") -ContainerDb(CustomerInformationSystem.CustomerDatabase, "Customer Database", "Oracle", "Stores customer information", "") -ContainerQueue(CustomerInformationSystem.MessageBus, "Message Bus", "RabbitMQ", "Transport for business events.", "") +ContainerDb(CustomerInformationSystem.CustomerDatabase, "Customer Database", "Oracle", "Stores customer information", $sprite="oracle_original") +ContainerQueue(CustomerInformationSystem.MessageBus, "Message Bus", "RabbitMQ", "Transport for business events.", $sprite="img:GILBARBARA_PNG_URL/rabbitmq-icon.png{scale=0.3}") Container(CustomerInformationSystem.ReportingService, "Reporting Service", "Ruby", "Creates normalised data for reporting purposes.", "") -ContainerDb(CustomerInformationSystem.ReportingDatabase, "Reporting Database", "MySql", "Stores a normalised version of all business data for ad hoc reporting purposes", "") +ContainerDb(CustomerInformationSystem.ReportingDatabase, "Reporting Database", "MySql", "Stores a normalised version of all business data for ad hoc reporting purposes", $sprite="mysql") Container(CustomerInformationSystem.AuditingService, "Auditing Service", "C#, Net", "Provides organisation-wide auditing facilities.", "") ContainerDb(CustomerInformationSystem.AuditStore, "Audit Store", "Event Store", "Stores information about events that have happened", "") Rel(Customer, CustomerInformationSystem.CustomerFrontendApplication, "1 Uses" ) @@ -25,7 +27,7 @@ SetPropertyHeader("field", "value") AddProperty("Event Type", "create") Rel(CustomerInformationSystem.CustomerService, CustomerInformationSystem.MessageBus, "4 Sends customer update events to" , $tags="async relationship") Rel(CustomerInformationSystem.MessageBus, CustomerInformationSystem.ReportingService, "5.1 Sends customer update events to" , $tags="async relationship") -Rel(CustomerInformationSystem.ReportingService, CustomerInformationSystem.ReportingDatabase, "5.1.1 Stores data in" , $sprite="mysql") +Rel(CustomerInformationSystem.ReportingService, CustomerInformationSystem.ReportingDatabase, "5.1.1 Stores data in" ) Rel(CustomerInformationSystem.MessageBus, CustomerInformationSystem.AuditingService, "5.2 Sends customer update events to" , $tags="async relationship") Rel(CustomerInformationSystem.AuditingService, CustomerInformationSystem.AuditStore, "5.2.1 Stores events in" ) Rel(CustomerInformationSystem.CustomerService, CustomerInformationSystem.CustomerFrontendApplication, "5.3 Confirms update to" , $techn="WebSocket", $tags="async relationship", $link="www.bing.com") diff --git a/src/test/resources/expected/view/dynamic/DynamicWithNestedParallelFlow.puml b/src/test/resources/expected/view/dynamic/DynamicWithNestedParallelFlow.puml index a6dcbe5..5be2d86 100644 --- a/src/test/resources/expected/view/dynamic/DynamicWithNestedParallelFlow.puml +++ b/src/test/resources/expected/view/dynamic/DynamicWithNestedParallelFlow.puml @@ -1,6 +1,8 @@ @startuml(id=DynamicWithNestedParallelFlow) +!define GILBARBARA_PNG_URL https://raw.githubusercontent.com/plantuml-stdlib/gilbarbara-plantuml-sprites/v1.1/pngs !includeurl https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Dynamic.puml !includeurl +!includeurl title Customer Information System - Dynamic caption This diagram shows what happens when a customer updates their details @@ -13,10 +15,10 @@ AddRelTag("async relationship", $lineStyle=DashedLine(), $legendText=async relat Person(Customer, "Customer", "A costumer", "") Container(CustomerInformationSystem.CustomerFrontendApplication, "Customer Frontend Application", "Angular", "Allows customers to manage their profile", "") Container(CustomerInformationSystem.CustomerService, "Customer Service", "Java and Spring Boot", "The point of access for customer information.", "") -ContainerDb(CustomerInformationSystem.CustomerDatabase, "Customer Database", "Oracle", "Stores customer information", "") -ContainerQueue(CustomerInformationSystem.MessageBus, "Message Bus", "RabbitMQ", "Transport for business events.", "") +ContainerDb(CustomerInformationSystem.CustomerDatabase, "Customer Database", "Oracle", "Stores customer information", $sprite="oracle_original") +ContainerQueue(CustomerInformationSystem.MessageBus, "Message Bus", "RabbitMQ", "Transport for business events.", $sprite="img:GILBARBARA_PNG_URL/rabbitmq-icon.png{scale=0.3}") Container(CustomerInformationSystem.ReportingService, "Reporting Service", "Ruby", "Creates normalised data for reporting purposes.", "") -ContainerDb(CustomerInformationSystem.ReportingDatabase, "Reporting Database", "MySql", "Stores a normalised version of all business data for ad hoc reporting purposes", "") +ContainerDb(CustomerInformationSystem.ReportingDatabase, "Reporting Database", "MySql", "Stores a normalised version of all business data for ad hoc reporting purposes", $sprite="mysql") Container(CustomerInformationSystem.AuditingService, "Auditing Service", "C#, Net", "Provides organisation-wide auditing facilities.", "") ContainerDb(CustomerInformationSystem.AuditStore, "Audit Store", "Event Store", "Stores information about events that have happened", "") RelIndex(1,Customer, CustomerInformationSystem.CustomerFrontendApplication, "Uses") @@ -26,7 +28,7 @@ SetPropertyHeader("field", "value") AddProperty("Event Type", "create") RelIndex(4,CustomerInformationSystem.CustomerService, CustomerInformationSystem.MessageBus, "Sends customer update events to", $tags="async relationship") RelIndex(5.1,CustomerInformationSystem.MessageBus, CustomerInformationSystem.ReportingService, "Sends customer update events to", $tags="async relationship") -RelIndex(5.1.1,CustomerInformationSystem.ReportingService, CustomerInformationSystem.ReportingDatabase, "Stores data in", $sprite="mysql") +RelIndex(5.1.1,CustomerInformationSystem.ReportingService, CustomerInformationSystem.ReportingDatabase, "Stores data in") RelIndex(5.2,CustomerInformationSystem.MessageBus, CustomerInformationSystem.AuditingService, "Sends customer update events to", $tags="async relationship") RelIndex(5.2.1,CustomerInformationSystem.AuditingService, CustomerInformationSystem.AuditStore, "Stores events in") RelIndex(5.3,CustomerInformationSystem.CustomerService, CustomerInformationSystem.CustomerFrontendApplication, "Confirms update to", "WebSocket", $link="www.bing.com", $tags="async relationship") diff --git a/src/test/resources/expected/view/dynamic/DynamicWithNestedParallelFlowSequence.puml b/src/test/resources/expected/view/dynamic/DynamicWithNestedParallelFlowSequence.puml index d416f12..551fe65 100644 --- a/src/test/resources/expected/view/dynamic/DynamicWithNestedParallelFlowSequence.puml +++ b/src/test/resources/expected/view/dynamic/DynamicWithNestedParallelFlowSequence.puml @@ -1,6 +1,8 @@ @startuml(id=DynamicWithNestedParallelFlowSequence) +!define GILBARBARA_PNG_URL https://raw.githubusercontent.com/plantuml-stdlib/gilbarbara-plantuml-sprites/v1.1/pngs !includeurl https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Sequence.puml !includeurl +!includeurl title Customer Information System - Dynamic caption This diagram shows what happens when a customer updates their details @@ -12,10 +14,10 @@ AddRelTag("async relationship", $lineStyle=DashedLine(), $legendText=async relat Person(Customer, "Customer", "A costumer", "") Container(CustomerInformationSystem.CustomerFrontendApplication, "Customer Frontend Application", "Angular", "Allows customers to manage their profile", "") Container(CustomerInformationSystem.CustomerService, "Customer Service", "Java and Spring Boot", "The point of access for customer information.", "") -ContainerDb(CustomerInformationSystem.CustomerDatabase, "Customer Database", "Oracle", "Stores customer information", "") -ContainerQueue(CustomerInformationSystem.MessageBus, "Message Bus", "RabbitMQ", "Transport for business events.", "") +ContainerDb(CustomerInformationSystem.CustomerDatabase, "Customer Database", "Oracle", "Stores customer information", $sprite="oracle_original") +ContainerQueue(CustomerInformationSystem.MessageBus, "Message Bus", "RabbitMQ", "Transport for business events.", $sprite="img:GILBARBARA_PNG_URL/rabbitmq-icon.png{scale=0.3}") Container(CustomerInformationSystem.ReportingService, "Reporting Service", "Ruby", "Creates normalised data for reporting purposes.", "") -ContainerDb(CustomerInformationSystem.ReportingDatabase, "Reporting Database", "MySql", "Stores a normalised version of all business data for ad hoc reporting purposes", "") +ContainerDb(CustomerInformationSystem.ReportingDatabase, "Reporting Database", "MySql", "Stores a normalised version of all business data for ad hoc reporting purposes", $sprite="mysql") Container(CustomerInformationSystem.AuditingService, "Auditing Service", "C#, Net", "Provides organisation-wide auditing facilities.", "") ContainerDb(CustomerInformationSystem.AuditStore, "Audit Store", "Event Store", "Stores information about events that have happened", "") Rel(Customer, CustomerInformationSystem.CustomerFrontendApplication, "1 Uses" ) @@ -25,7 +27,7 @@ SetPropertyHeader("field", "value") AddProperty("Event Type", "create") Rel(CustomerInformationSystem.CustomerService, CustomerInformationSystem.MessageBus, "4 Sends customer update events to" , $tags="async relationship") Rel(CustomerInformationSystem.MessageBus, CustomerInformationSystem.ReportingService, "5.1 Sends customer update events to" , $tags="async relationship") -Rel(CustomerInformationSystem.ReportingService, CustomerInformationSystem.ReportingDatabase, "5.1.1 Stores data in" , $sprite="mysql") +Rel(CustomerInformationSystem.ReportingService, CustomerInformationSystem.ReportingDatabase, "5.1.1 Stores data in" ) Rel(CustomerInformationSystem.MessageBus, CustomerInformationSystem.AuditingService, "5.2 Sends customer update events to" , $tags="async relationship") Rel(CustomerInformationSystem.AuditingService, CustomerInformationSystem.AuditStore, "5.2.1 Stores events in" ) Rel(CustomerInformationSystem.CustomerService, CustomerInformationSystem.CustomerFrontendApplication, "5.3 Confirms update to" , $techn="WebSocket", $tags="async relationship", $link="www.bing.com") diff --git a/src/test/resources/expected/view/dynamic/DynamicWithParallelFlow.puml b/src/test/resources/expected/view/dynamic/DynamicWithParallelFlow.puml index aad08c4..28c1153 100644 --- a/src/test/resources/expected/view/dynamic/DynamicWithParallelFlow.puml +++ b/src/test/resources/expected/view/dynamic/DynamicWithParallelFlow.puml @@ -1,6 +1,8 @@ @startuml(id=DynamicWithParallelFlow) +!define GILBARBARA_PNG_URL https://raw.githubusercontent.com/plantuml-stdlib/gilbarbara-plantuml-sprites/v1.1/pngs !includeurl https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Dynamic.puml !includeurl +!includeurl title Customer Information System - Dynamic caption This diagram shows what happens when a customer updates their details @@ -13,11 +15,11 @@ AddRelTag("async relationship", $lineStyle=DashedLine(), $legendText=async relat Person(Customer, "Customer", "A costumer", "") Container(CustomerInformationSystem.CustomerFrontendApplication, "Customer Frontend Application", "Angular", "Allows customers to manage their profile", "") Container(CustomerInformationSystem.CustomerService, "Customer Service", "Java and Spring Boot", "The point of access for customer information.", "") -ContainerDb(CustomerInformationSystem.CustomerDatabase, "Customer Database", "Oracle", "Stores customer information", "") -ContainerQueue(CustomerInformationSystem.MessageBus, "Message Bus", "RabbitMQ", "Transport for business events.", "") +ContainerDb(CustomerInformationSystem.CustomerDatabase, "Customer Database", "Oracle", "Stores customer information", $sprite="oracle_original") +ContainerQueue(CustomerInformationSystem.MessageBus, "Message Bus", "RabbitMQ", "Transport for business events.", $sprite="img:GILBARBARA_PNG_URL/rabbitmq-icon.png{scale=0.3}") Container(CustomerInformationSystem.ReportingService, "Reporting Service", "Ruby", "Creates normalised data for reporting purposes.", "") Container(CustomerInformationSystem.AuditingService, "Auditing Service", "C#, Net", "Provides organisation-wide auditing facilities.", "") -ContainerDb(CustomerInformationSystem.ReportingDatabase, "Reporting Database", "MySql", "Stores a normalised version of all business data for ad hoc reporting purposes", "") +ContainerDb(CustomerInformationSystem.ReportingDatabase, "Reporting Database", "MySql", "Stores a normalised version of all business data for ad hoc reporting purposes", $sprite="mysql") ContainerDb(CustomerInformationSystem.AuditStore, "Audit Store", "Event Store", "Stores information about events that have happened", "") RelIndex(1,Customer, CustomerInformationSystem.CustomerFrontendApplication, "Uses") RelIndex(2,CustomerInformationSystem.CustomerFrontendApplication, CustomerInformationSystem.CustomerService, "Updates customer information using", "JSON/HTTPS") @@ -28,7 +30,7 @@ RelIndex(4,CustomerInformationSystem.CustomerService, CustomerInformationSystem. RelIndex(5,CustomerInformationSystem.MessageBus, CustomerInformationSystem.ReportingService, "Sends customer update events to", $tags="async relationship") RelIndex(5,CustomerInformationSystem.MessageBus, CustomerInformationSystem.AuditingService, "Sends customer update events to", $tags="async relationship") RelIndex(5,CustomerInformationSystem.CustomerService, CustomerInformationSystem.CustomerFrontendApplication, "Confirms update to", "WebSocket", $link="www.bing.com", $tags="async relationship") -RelIndex(6,CustomerInformationSystem.ReportingService, CustomerInformationSystem.ReportingDatabase, "Stores data in", $sprite="mysql") +RelIndex(6,CustomerInformationSystem.ReportingService, CustomerInformationSystem.ReportingDatabase, "Stores data in") RelIndex(6,CustomerInformationSystem.AuditingService, CustomerInformationSystem.AuditStore, "Stores events in") SHOW_LEGEND(true) diff --git a/src/test/resources/expected/view/dynamic/DynamicWithParallelFlowSequence.puml b/src/test/resources/expected/view/dynamic/DynamicWithParallelFlowSequence.puml index 4f21576..78f4b74 100644 --- a/src/test/resources/expected/view/dynamic/DynamicWithParallelFlowSequence.puml +++ b/src/test/resources/expected/view/dynamic/DynamicWithParallelFlowSequence.puml @@ -1,6 +1,8 @@ @startuml(id=DynamicWithParallelFlowSequence) +!define GILBARBARA_PNG_URL https://raw.githubusercontent.com/plantuml-stdlib/gilbarbara-plantuml-sprites/v1.1/pngs !includeurl https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Sequence.puml !includeurl +!includeurl title Customer Information System - Dynamic caption This diagram shows what happens when a customer updates their details @@ -12,11 +14,11 @@ AddRelTag("async relationship", $lineStyle=DashedLine(), $legendText=async relat Person(Customer, "Customer", "A costumer", "") Container(CustomerInformationSystem.CustomerFrontendApplication, "Customer Frontend Application", "Angular", "Allows customers to manage their profile", "") Container(CustomerInformationSystem.CustomerService, "Customer Service", "Java and Spring Boot", "The point of access for customer information.", "") -ContainerDb(CustomerInformationSystem.CustomerDatabase, "Customer Database", "Oracle", "Stores customer information", "") -ContainerQueue(CustomerInformationSystem.MessageBus, "Message Bus", "RabbitMQ", "Transport for business events.", "") +ContainerDb(CustomerInformationSystem.CustomerDatabase, "Customer Database", "Oracle", "Stores customer information", $sprite="oracle_original") +ContainerQueue(CustomerInformationSystem.MessageBus, "Message Bus", "RabbitMQ", "Transport for business events.", $sprite="img:GILBARBARA_PNG_URL/rabbitmq-icon.png{scale=0.3}") Container(CustomerInformationSystem.ReportingService, "Reporting Service", "Ruby", "Creates normalised data for reporting purposes.", "") Container(CustomerInformationSystem.AuditingService, "Auditing Service", "C#, Net", "Provides organisation-wide auditing facilities.", "") -ContainerDb(CustomerInformationSystem.ReportingDatabase, "Reporting Database", "MySql", "Stores a normalised version of all business data for ad hoc reporting purposes", "") +ContainerDb(CustomerInformationSystem.ReportingDatabase, "Reporting Database", "MySql", "Stores a normalised version of all business data for ad hoc reporting purposes", $sprite="mysql") ContainerDb(CustomerInformationSystem.AuditStore, "Audit Store", "Event Store", "Stores information about events that have happened", "") Rel(Customer, CustomerInformationSystem.CustomerFrontendApplication, "1 Uses" ) Rel(CustomerInformationSystem.CustomerFrontendApplication, CustomerInformationSystem.CustomerService, "2 Updates customer information using" , $techn="JSON/HTTPS") @@ -27,7 +29,7 @@ Rel(CustomerInformationSystem.CustomerService, CustomerInformationSystem.Message Rel(CustomerInformationSystem.MessageBus, CustomerInformationSystem.ReportingService, "5 Sends customer update events to" , $tags="async relationship") Rel(CustomerInformationSystem.MessageBus, CustomerInformationSystem.AuditingService, "5 Sends customer update events to" , $tags="async relationship") Rel(CustomerInformationSystem.CustomerService, CustomerInformationSystem.CustomerFrontendApplication, "5 Confirms update to" , $techn="WebSocket", $tags="async relationship", $link="www.bing.com") -Rel(CustomerInformationSystem.ReportingService, CustomerInformationSystem.ReportingDatabase, "6 Stores data in" , $sprite="mysql") +Rel(CustomerInformationSystem.ReportingService, CustomerInformationSystem.ReportingDatabase, "6 Stores data in" ) Rel(CustomerInformationSystem.AuditingService, CustomerInformationSystem.AuditStore, "6 Stores events in" ) SHOW_LEGEND(true) diff --git a/src/test/resources/expected/view/style/ComponentStyleTest.puml b/src/test/resources/expected/view/style/ComponentStyleTest.puml index 045a505..134fcc0 100644 --- a/src/test/resources/expected/view/style/ComponentStyleTest.puml +++ b/src/test/resources/expected/view/style/ComponentStyleTest.puml @@ -10,7 +10,7 @@ SHOW_PERSON_OUTLINE() LAYOUT_TOP_DOWN() AddRelTag("Dependency Style", $sprite="cell_phone_android_stand_alone", $lineColor=#008000, $textColor=#aa9999, $techn=Android, $lineStyle=DottedLine(), $lineThickness=2, $legendSprite="cell_phone_android_stand_alone,scale=0.3,color=#008000", $legendText=Android user uses) -AddElementTag("Component Style", $sprite="&compass", $bgColor=#ffffff, $fontColor=#ff0000, $borderColor=#800080, $borderStyle=BoldLine(), $borderThickness=5, $shadowing=false, $shape=RoundedBoxShape(), $techn=REST, $legendSprite="&compass", $legendText=this is a legend text) +AddElementTag("Component Style", $sprite="&compass", $bgColor=#ffffff, $fontColor=#ff0000, $borderColor=#800080, $borderStyle=BoldLine(), $borderThickness=5, $shadowing=false, $shape=RoundedBoxShape(), $techn=REST, $legendSprite="&compass,scale=1.1,color=#ff0000", $legendText=this is a legend text) AddBoundaryTag("Boundary Style", $bgColor=#00ffff, $fontColor=#008000, $borderColor=#ff0000, $borderStyle=DottedLine(), $borderThickness=4, $shadowing=false, $legendText=this is a system) AddPersonTag("Person Style", $sprite="apple,scale=0.5,color=#008000", $bgColor=#00ff00, $fontColor=#0000ff, $borderColor=#ff0000, $borderStyle=DashedLine(), $borderThickness=4, $shadowing=false, $shape=EightSidedShape(), $legendText=this is a apple) diff --git a/src/test/resources/expected/view/style/SystemStyleTest.puml b/src/test/resources/expected/view/style/SystemStyleTest.puml index 66cfa3e..9b5e5e0 100644 --- a/src/test/resources/expected/view/style/SystemStyleTest.puml +++ b/src/test/resources/expected/view/style/SystemStyleTest.puml @@ -10,7 +10,7 @@ SHOW_PERSON_OUTLINE() LAYOUT_TOP_DOWN() AddRelTag("Dependency Style", $sprite="cell_phone_android_stand_alone", $lineColor=#008000, $textColor=#aa9999, $techn=Android, $lineStyle=DottedLine(), $lineThickness=2, $legendSprite="cell_phone_android_stand_alone,scale=0.3,color=#008000", $legendText=Android user uses) -AddElementTag("System Style", $sprite="img:https://plantuml.com/logo3.png,scale=0.4", $bgColor=#000000, $fontColor=#ffff00, $borderColor=#008000, $borderStyle=DashedLine(), $borderThickness=4, $shadowing=true, $shape=EightSidedShape(), $techn=Kafka, $legendSprite="&compass,scale=3.0", $legendText=this is a legend) +AddElementTag("System Style", $sprite="img:https://plantuml.com/logo3.png{scale=0.4}", $bgColor=#000000, $fontColor=#ffff00, $borderColor=#008000, $borderStyle=DashedLine(), $borderThickness=4, $shadowing=true, $shape=EightSidedShape(), $techn=Kafka, $legendSprite="&compass,scale=3.0", $legendText=this is a legend) AddPersonTag("Person Style", $sprite="apple,scale=0.5,color=#008000", $bgColor=#00ff00, $fontColor=#0000ff, $borderColor=#ff0000, $borderStyle=DashedLine(), $borderThickness=4, $shadowing=false, $shape=EightSidedShape(), $legendText=this is a apple) System(MySoftwareSystem, "My Software System", "system", "", $tags="System Style+Boundary Style")