avisi-cloud / structurizr-site-generatr

Static site generator for architecture models created with Structurizr DSL
https://avisi-cloud.github.io/structurizr-site-generatr/
Apache License 2.0
224 stars 34 forks source link

Feature Request: Support for `image` views or option to ignore such views #625

Open hgross opened 20 hours ago

hgross commented 20 hours ago

Structurizr supports to integrate with PlantUML (or other plugins like Mermaid) by defining an image-view (see structurizr docs).

Do you have any plans to support or add an option to ignore those image-views? At this moment, the generate-site command will fail when such a view is defined:


views {
    properties {
        "plantuml.url" "http://localhost:8888"
        "plantuml.format" "svg" // or "png"
    }

    image scope "plantuml-my-state-machine" {
        plantuml "model/state-machine.puml"
        title "[State] Some State Machine"
    }

    ...
}
Exception in thread "main" java.lang.IllegalStateException: java.lang.IllegalStateException: View [State] Some State Machine has a non-exportable type
        at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(Unknown Source)
        at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Unknown Source)
        at java.base/java.lang.reflect.Constructor.newInstance(Unknown Source)
        at java.base/java.util.concurrent.ForkJoinTask.getThrowableException(Unknown Source)
        at java.base/java.util.concurrent.ForkJoinTask.reportException(Unknown Source)
        at java.base/java.util.concurrent.ForkJoinTask.invoke(Unknown Source)
        at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateParallel(Unknown Source)
        at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateParallel(Unknown Source)
        at java.base/java.util.stream.AbstractPipeline.evaluate(Unknown Source)
        at java.base/java.util.stream.ReferencePipeline.forEach(Unknown Source)
        at java.base/java.util.stream.ReferencePipeline$Head.forEach(Unknown Source)
        at nl.avisi.structurizr.site.generatr.site.SiteGeneratorKt.generateHtmlFiles(SiteGenerator.kt:202)
        at nl.avisi.structurizr.site.generatr.site.SiteGeneratorKt.generateSite(SiteGenerator.kt:87)
        at nl.avisi.structurizr.site.generatr.site.SiteGeneratorKt.generateSite$default(SiteGenerator.kt:67)
        at nl.avisi.structurizr.site.generatr.GenerateSiteCommand.generateSiteForModel(GenerateSiteCommand.kt:131)
        at nl.avisi.structurizr.site.generatr.GenerateSiteCommand.execute(GenerateSiteCommand.kt:73)
        at kotlinx.cli.ArgParser.parse(ArgParser.kt:657)
        at kotlinx.cli.ArgParser.parse(ArgParser.kt:530)
        at nl.avisi.structurizr.site.generatr.AppKt.main(App.kt:13)
Caused by: java.lang.IllegalStateException: View [State] Some State Machine has a non-exportable type
        at nl.avisi.structurizr.site.generatr.site.PlantUmlExporterWithElementLinks.export(PlantUmlExporter.kt:49)
        at nl.avisi.structurizr.site.generatr.site.DiagramGeneratorKt.generatePlantUMLDiagramWithElementLinks(DiagramGenerator.kt:86)
        at nl.avisi.structurizr.site.generatr.site.DiagramGeneratorKt.generateDiagramWithElementLinks(DiagramGenerator.kt:43)
        at nl.avisi.structurizr.site.generatr.site.SiteGeneratorKt.generateSite$lambda$8(SiteGenerator.kt:79)
        at nl.avisi.structurizr.site.generatr.site.model.DiagramViewModel$Companion.forView(DiagramViewModel.kt:26)
        at nl.avisi.structurizr.site.generatr.site.model.ToHtmlKt.transformEmbeddedDiagramElements(ToHtml.kt:171)
        at nl.avisi.structurizr.site.generatr.site.model.ToHtmlKt.markdownToHtml(ToHtml.kt:56)
        at nl.avisi.structurizr.site.generatr.site.model.ToHtmlKt.toHtml(ToHtml.kt:34)
        at nl.avisi.structurizr.site.generatr.site.model.WorkspaceDocumentationSectionPageViewModel.<init>(WorkspaceDocumentationSectionPageViewModel.kt:12)
        at nl.avisi.structurizr.site.generatr.site.SiteGeneratorKt.generateHtmlFiles$lambda$52$lambda$17$lambda$16(SiteGenerator.kt:138)
        at nl.avisi.structurizr.site.generatr.site.SiteGeneratorKt.generateHtmlFiles$lambda$53(SiteGenerator.kt:202)
        at nl.avisi.structurizr.site.generatr.site.SiteGeneratorKt.generateHtmlFiles$lambda$54(SiteGenerator.kt:202)
        at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(Unknown Source)
        at java.base/java.util.AbstractList$RandomAccessSpliterator.forEachRemaining(Unknown Source)
        at java.base/java.util.stream.AbstractPipeline.copyInto(Unknown Source)
        at java.base/java.util.stream.ForEachOps$ForEachTask.compute(Unknown Source)
        at java.base/java.util.concurrent.CountedCompleter.exec(Unknown Source)
        at java.base/java.util.concurrent.ForkJoinTask.doExec(Unknown Source)
        at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(Unknown Source)
        at java.base/java.util.concurrent.ForkJoinPool.scan(Unknown Source)
        at java.base/java.util.concurrent.ForkJoinPool.runWorker(Unknown Source)
        at java.base/java.util.concurrent.ForkJoinWorkerThread.run(Unknown Source)
qtzar commented 18 hours ago

I just tested this and it seems to be working fine. The only difference between what I did and what you have above is that I set the plantUML Generator URL to a real url and not localHost:8888

"plantuml.url" "https://plantuml.com/plantuml"

the localhost:8888 in the documentation is only valid if you have a PlantUML generator running locally on that port.

hgross commented 17 hours ago

I have a working backend PlantUML backend running locally. All my PlantUML diagrams are fine in structurizr-lite's structurizr-ui. I am using docker compose to set up the whole thing - like this:

services:
  structurizr:
    image: structurizr/lite
    ports:
      - "8081:8080"
    volumes:
      - ./structurizr:/usr/local/structurizr
    environment:
      - STRUCTURIZR_WORKSPACE_FILENAME=${STRUCTURIZR_WORKSPACE_FILENAME:-model/workspace.dsl}
      - TZ=Europe/Berlin

  plantuml:
    image: plantuml/plantuml-server:tomcat
    ports:
      - "8080:8080"
    environment:
      - PLANTUML_LIMIT_SIZE=24384
      - JAVA_MIN_HEAP_SIZE=64M
      - JAVA_MAX_HEAP_SIZE=4G
      - TZ=Europe/Berlin

I am also using the docker variant to execute generate-site: docker run -it --rm -v ${workspaceFolder}/structurizr:/var/model ghcr.io/avisi-cloud/structurizr-site-generatr generate-site --workspace-file workspace.dsl

Does generatr require direct access to the PlantUML endpoint to work? This would not be the case with my docker-compose setup, since the docker run call would not have access because localhost would point somewhere else without bridging it into the docker-compose network.

The exception message has a non-exportable type does not reveal much of the details.

qtzar commented 17 hours ago

yes, this seems to be more of a docker config issue.

You are on the correct line of thought to build out a new network bridge to run all these containers in, give the containers names and then in the view property you should be able to reference the PlantUML container by name instead of localhost.