Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request: add support for Structurizr #510

Closed
shah opened this issue Nov 29, 2020 · 24 comments
Closed

Feature request: add support for Structurizr #510

shah opened this issue Nov 29, 2020 · 24 comments
Labels
🍩 enhancement New feature or request ☕ java Related to Java code

Comments

@shah
Copy link

shah commented Nov 29, 2020

Structurizr.com would be a great addition to Kroki.

@shah
Copy link
Author

shah commented Nov 30, 2020

Great idea about C4-PlantUML @Mogztter -- Structurizr is interesting because it has multiple output formats and has a special architecture-oriented DSL but perhaps it's not OSS.

@simonbrowndotje
Copy link

Correct, the structurizr.com renderer is not open source, but the Structurizr DSL and Structurizr CLI are open source. The DSL allows you to create a software architecture model, while the CLI provides an export to a number of open source tools, including PlantUML, Mermaid, and WebSequenceDiagrams. These exporters are open source too (and provided by the Structurizr Java extensions project).

@ggrossetie
Copy link
Member

Thanks for your reply Simon!
So in theory, Kroki could accept Structurizr DSL (text), parse it using StructurizrDslParser.parse, convert it to C4 PlantUML using AbstractPlantUMLWriter.write and then use PlantUML to convert it to an image 🎉
Did I get it right?

I think we will start with one output format.

@simonbrowndotje In your opinion, which provider between Mermaid, PlantUML and GraphViz produces the best output? It's probably a trick question since you are trying to provide the best possible output for each one of them but still... 🤔

I've never had the opportunity to tell you but Structurizr is amazing, keep up the good work 👌

@ggrossetie ggrossetie added ☕ java Related to Java code 🍩 enhancement New feature or request labels Nov 30, 2020
@simonbrowndotje
Copy link

simonbrowndotje commented Nov 30, 2020

Thank you! 🙂

Yes, that's correct, and the StructurizrPlantUMLWriter is probably the best output of PlantUML and Mermaid (the Graphviz libary is only used for automatic layout, it doesn't produce full diagrams).

Edited: there's a test/demo page at https://structurizr.com/dsl with different output formats

@ggrossetie
Copy link
Member

Awesome, I will do that 👍

Also if you think of other integrations between Kroki and Structurizr, feel free to ping me.

@shah
Copy link
Author

shah commented Jun 30, 2021

@Mogztter I was curious if you were able to connect the two excellent Kroki and Structurizr projects. Thanks for checking!

@ggrossetie
Copy link
Member

No haven't time yet, I was looking at integrating other diagram librairies (such as https://github.com/mingrammer/diagrams).

Will try to take some time to work on it next week.

@simonbrowndotje
Copy link

Just FYI ... when using the StructurizrDslParser, you can use the restricted property to disallow the keywords that read from the local file system (e.g. !docs, !adrs, icon, etc) if needed.

@ggrossetie
Copy link
Member

@simonbrowndotje That will be extremely useful, thanks for the head-ups. Is it possible to disable extends and !include completely (even if the target is an HTTPS URL)?

To avoid abuse on the public instance, I disable all I/O operations. Then, users can allow/whitelist operations on their local installation.

@simonbrowndotje
Copy link

simonbrowndotje commented Jul 3, 2021

Not at the moment, but I could certainly add that ... theme support should also be disabled for the same reason.

Just out of interest, how would the integration work? A DSL file can define a number of views ... which view would Kroki render?

Edit: I'm guessing just a request parameter specifying the view key?

@shah
Copy link
Author

shah commented Jul 3, 2021

Yes @simonbrowndotje that would be great -- using a request parameter to specify the view (something like ?view=X) would be handy. Thanks for considering this @Mogztter - between Kroki and Structurizr we'll have a great opportunity to give architects tools that would actually improve communications by integrating diagrams everywhere a URL can embedded.

@simonbrowndotje I love your videos and lectures on the topic of communicating design and directing developer intent through architecture diagrams. Keep it up!

@ggrossetie
Copy link
Member

Not at the moment, but I could certainly add that ... theme support should also be disabled for the same reason.

👍🏻
In the meantime, I guess I can "sanitize" the input by removing !input ... and extends directives.

Just out of interest, how would the integration work? A DSL file can define a number of views ... which view would Kroki render?
Edit: I'm guessing just a request parameter specifying the view key?

For now, the API does not support any kind of request parameters so I guess we will use the default/first view.

@shah
Copy link
Author

shah commented Jul 3, 2021

@Mogztter when you have a minute, if you update Kroki to pass the URL as a CGI parameter (environment variable) it means that any tool that wants to use it could do so. For example, when you call any tool, set the following environment variables:

  • KROKI_RENDERER_ID - this could be PlantUML, Structurizer, etc. basically whatever "tool ID" you're using
  • KROKI_CANONICAL_URL - this would be the URL, as passed in by the user

With the above two environment variables set, each tool could add "support" for Kroki just by checking the environment to see if they are being called in "Kroki Context". That way, if @simonbrowndotje wanted to add a feature specific to Kroki he could use the environment variable to do so.

@ggrossetie
Copy link
Member

@shah Please open a new issue if you want to discuss about another changes otherwise the conversation gets sidetracked and it becomes hard to follow.

For now, the API does not support any kind of request parameters so I guess we will use the default/first view.

@simonbrowndotje I just noticed that getViews() (on com.structurizr.view.ViewSet) is using an HashSet<View> and, as far as I known, it does not guarantee the constant order of elements. So, I guess using the "first" element from the HashSet won't be reliable. Is there a way to get the first view declared in the DSL?

ggrossetie added a commit to ggrossetie/kroki that referenced this issue Jul 8, 2021
@simonbrowndotje
Copy link

Is there a way to get the first view declared in the DSL?

There isn't I'm afraid.

@ggrossetie
Copy link
Member

Thanks for your quick response!
Until we have #827, maybe we could use a certainly arbitrary but reliable rule such as:

  • Take the higher level view possible:
    1. System landscape
    2. System context
    3. Container
    4. Component
    5. Dynamic view
    6. Deployment view
  • If there's more than one view, then take the first one in alphabetical order

Not great but at least it's predictable. What do you think?

@shah
Copy link
Author

shah commented Jul 9, 2021

@Mogztter until #827 is available I think it would be fine to have people just use Structurizr with a single view and then use multiple views when #827 is introduced in a release.

@ggrossetie
Copy link
Member

@shah we still need to decide what do you when we receive a Structurizr diagram with multiple views.

@shah
Copy link
Author

shah commented Jul 9, 2021

Thanks for confirming @Mogztter - my opinion, until #827 is implemented, is to take the first view (which might be "random" according to Simon). For anyone that cannot wait for #827 and does not want a random view from a set of views, they can just create a file with a single view. Then, when #827 is done Kroki can support multiple, configurable, views through URL parameters or POST.

ggrossetie added a commit to ggrossetie/kroki that referenced this issue Sep 9, 2021
@ggrossetie
Copy link
Member

@simonbrowndotje I've added the following dependencies:

<dependency>
  <groupId>com.structurizr</groupId>
  <artifactId>structurizr-dsl</artifactId>
  <version>1.14.0</version>
</dependency>
<dependency>
  <groupId>com.structurizr</groupId>
  <artifactId>structurizr-plantuml</artifactId>
  <version>1.6.3</version>
  <exclusions>
    <exclusion>
      <groupId>com.structurizr</groupId>
      <artifactId>structurizr-core</artifactId>
    </exclusion>
  </exclusions>
</dependency>
<dependency>
  <groupId>com.structurizr</groupId>
  <artifactId>structurizr-core</artifactId>
  <version>1.9.7</version>
</dependency>

But it adds ~80Mb of dependencies 😓
For reference, the size of the "fat-jar" before adding Structurizr was 20Mb.

Looking at the dependency tree, it seems that com.structurizr:structurizr-dsl depends on jruby, groovy and kotlin-scripting.

+- com.structurizr:structurizr-dsl:jar:1.14.0:compile
|  +- com.structurizr:structurizr-client:jar:1.9.7:runtime
|  |  +- com.fasterxml.jackson.core:jackson-databind:jar:2.10.5.1:runtime
|  |  +- org.apache.httpcomponents.client5:httpclient5:jar:5.0:runtime
|  |  |  +- org.apache.httpcomponents.core5:httpcore5:jar:5.0:runtime
|  |  |  +- org.apache.httpcomponents.core5:httpcore5-h2:jar:5.0:runtime
|  |  |  \- commons-codec:commons-codec:jar:1.13:runtime
|  |  \- javax.xml.bind:jaxb-api:jar:2.3.0:runtime
|  +- com.structurizr:structurizr-adr-tools:jar:1.3.8:runtime
|  +- org.codehaus.groovy:groovy-jsr223:jar:3.0.8:runtime
|  |  \- org.codehaus.groovy:groovy:jar:3.0.8:runtime
|  +- org.jetbrains.kotlin:kotlin-scripting-jsr223:jar:1.5.30:runtime
|  |  +- org.jetbrains.kotlin:kotlin-script-runtime:jar:1.5.30:runtime
|  |  +- org.jetbrains.kotlin:kotlin-stdlib:jar:1.5.30:runtime
|  |  |  +- org.jetbrains:annotations:jar:13.0:runtime
|  |  |  \- org.jetbrains.kotlin:kotlin-stdlib-common:jar:1.5.30:runtime
|  |  +- org.jetbrains.kotlin:kotlin-scripting-common:jar:1.5.30:runtime
|  |  |  \- org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:jar:1.5.0:runtime
|  |  |     \- org.jetbrains.kotlin:kotlin-stdlib-jdk8:jar:1.5.0:runtime
|  |  |        \- org.jetbrains.kotlin:kotlin-stdlib-jdk7:jar:1.5.0:runtime
|  |  +- org.jetbrains.kotlin:kotlin-scripting-jvm:jar:1.5.30:runtime
|  |  +- org.jetbrains.kotlin:kotlin-scripting-jvm-host:jar:1.5.30:runtime
|  |  +- org.jetbrains.kotlin:kotlin-compiler-embeddable:jar:1.5.30:runtime
|  |  |  +- org.jetbrains.kotlin:kotlin-reflect:jar:1.5.30:runtime
|  |  |  +- org.jetbrains.kotlin:kotlin-daemon-embeddable:jar:1.5.30:runtime
|  |  |  \- org.jetbrains.intellij.deps:trove4j:jar:1.0.20181211:runtime
|  |  \- org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:jar:1.5.30:runtime
|  |     \- org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:jar:1.5.30:runtime
|  |        \- org.jetbrains.kotlinx:kotlinx-coroutines-core:jar:1.5.0:runtime
|  \- org.jruby:jruby-core:jar:9.2.19.0:runtime
|     +- com.github.jnr:jnr-netdb:jar:1.2.0:runtime
|     +- com.github.jnr:jnr-enxio:jar:0.32.6:runtime
|     +- com.github.jnr:jnr-unixsocket:jar:0.38.8:runtime
|     +- com.github.jnr:jnr-posix:jar:3.1.7:runtime
|     +- com.github.jnr:jnr-constants:jar:0.10.2:runtime
|     +- com.github.jnr:jffi:jar:1.3.3:runtime
|     +- com.github.jnr:jffi:jar:native:1.3.3:runtime
|     +- org.jruby.joni:joni:jar:2.1.31:runtime
|     +- org.jruby.jcodings:jcodings:jar:1.0.46:runtime
|     +- org.jruby:dirgra:jar:0.3:runtime
|     +- com.headius:invokebinder:jar:1.11:runtime
|     +- com.headius:options:jar:1.4:runtime
|     +- com.jcraft:jzlib:jar:1.1.3:runtime
|     +- com.martiansoftware:nailgun-server:jar:0.9.1:runtime
|     +- joda-time:joda-time:jar:2.10.5:runtime
|     +- com.headius:backport9:jar:1.8:runtime
|     \- javax.annotation:javax.annotation-api:jar:1.3.1:runtime

I'm only using the following imports:

import com.structurizr.dsl.StructurizrDslParser;
import com.structurizr.dsl.StructurizrDslParserException;
import com.structurizr.io.plantuml.StructurizrPlantUMLWriter;
import com.structurizr.view.View;

Is it possible to disable the "script" feature in order to remove the jruby, groovy and kotlin-scripting dependencies?

Thanks!

@ggrossetie
Copy link
Member

If I remove jruby, groovy and kotlin-scripting dependencies, the size is 23Mb which is fine.

It seems that structurirz-dsl is using the javax.script.ScriptEngineManager API and, as a result, does not have direct import of JRuby, Kotlin or Groovy:

https://github.com/structurizr/dsl/blob/ba879c1e9804dff6196e25e3175ee907f5f841e3/src/main/java/com/structurizr/dsl/ScriptDslContext.java#L10-L28

The code will also throw an exception with a descriptive message if the script engine is not found.
So I think we should be fine if we exclude the scripting dependencies. Of course, the !script feature won't work but it keeps the size of the Kroki server reasonnable.

@simonbrowndotje
Copy link

v1.15.0 of the DSL library removes those dependencies. 👍

Just FYI though, structurizr-plantuml is deprecated in favour of structurizr-export (this unified version is much more full-featured, and all export formats now work in the same way).

@ggrossetie
Copy link
Member

Wow, thanks Simon!
I've created #929 as a follow-up issue and opened a pull request to do what you've suggested 👍🏻

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🍩 enhancement New feature or request ☕ java Related to Java code
Projects
None yet
Development

No branches or pull requests

3 participants