Skip to content

Commit

Permalink
resolves yuzutech#1521 use native image of Ditaa
Browse files Browse the repository at this point in the history
  • Loading branch information
ggrossetie committed May 7, 2023
1 parent 834f6aa commit 7aaf223
Show file tree
Hide file tree
Showing 19 changed files with 253 additions and 196 deletions.
3 changes: 0 additions & 3 deletions .github/workflows/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,6 @@ jobs:
java-version: 11
distribution: temurin

- name: Install Java dependencies
run: make installLocalDependencies

- name: Build Java server
run: make buildServer

Expand Down
3 changes: 0 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ SERVICES_TIMEOUT=15

default:

installLocalDependencies:
./mvnw install:install-file -Dfile=./server/lib/ditaamini-1.0.3.jar -DgroupId=ditaa -DartifactId=ditaa-mini -Dversion=1.0.3 -Dpackaging=jar

buildServer:
./mvnw --no-transfer-progress clean package

Expand Down
15 changes: 4 additions & 11 deletions ci/tasks/update-versions.js
Original file line number Diff line number Diff line change
Expand Up @@ -203,14 +203,10 @@ try {
const { version } = graphvizVersionFound.groups
diagramLibraryVersions.graphviz = version
}
}

const d2GoModContent = await fs.readFile(ospath.join(rootDir, 'server', 'ops', 'docker', 'go.mod'), 'utf8')
for (const line of d2GoModContent.split('\n')) {
const d2VersionFound = line.match(/^require oss.terrastruct.com\/d2 v(?<version>.+)$/)
if (d2VersionFound) {
const { version } = d2VersionFound.groups
diagramLibraryVersions.d2 = version
const ditaaVersionFound = line.match(/^ARG DITAA_VERSION="(?<version>.+)"$/)
if (ditaaVersionFound) {
const { version } = ditaaVersionFound.groups
diagramLibraryVersions.ditaa = version
}
}

Expand All @@ -226,9 +222,6 @@ try {
const { value: structurizrVersion } = await mvnEvaluateExpression('structurizr-dsl.version')
diagramLibraryVersions.structurizr = structurizrVersion

const { value: ditaaVersion } = await mvnEvaluateExpression('ditaa-mini.version')
diagramLibraryVersions.ditaa = ditaaVersion

console.log({
diagramLibraryVersions: Object.fromEntries(Object.entries(diagramLibraryVersions).sort((a, b) => a[0].localeCompare(b[0]))),
count: Object.keys(diagramLibraryVersions).length
Expand Down
2 changes: 1 addition & 1 deletion docs/antora.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ asciidoc:
diagramsnet-version: 16.2.4
ditaa-version: 1.0.3
erd-version: 0.2.1.0
excalidraw-version: 0.14.2
excalidraw-version: 0.15.2
graphviz-version: 8.0.4
mermaid-version: 9.4.3
nomnoml-version: 1.5.3
Expand Down
3 changes: 2 additions & 1 deletion docs/modules/setup/pages/configuration.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -110,13 +110,14 @@ you can override its location manually using an environment variable or a Java s
`KROKI_BYTEFIELD_BIN_PATH`:: Path to the `bytefield-svg` binary (defaults: `/usr/bin/bytefield`)
`KROKI_D2_BIN_PATH`:: Path to `d2` binary (defaults: `/usr/bin/d2`)
`KROKI_DBML_BIN_PATH`:: Path to `dbml` binary (defaults: `/usr/bin/dbml`)
`KROKI_DITAA_BIN_PATH`:: Path to `ditaa` binary (defaults: `/usr/bin/ditaa`)
`KROKI_DOT_BIN_PATH`:: Path to `dot` binary (defaults: `/usr/bin/dot`)
`KROKI_ERD_BIN_PATH`:: Path to `erd` binary (defaults: `/usr/bin/erd`)
`KROKI_NOMNOML_BIN_PATH`:: Path to `nomnoml` binary (defaults: `/usr/bin/nomnoml`)
`KROKI_PIKCHR_BIN_PATH`:: Path to `pikchr` binary (defaults: `/usr/bin/pikchr`)
`KROKI_PLANTUML_BIN_PATH`:: Path to `plantuml` binary (defaults: `/usr/bin/plantuml`)
`KROKI_SVGBOB_BIN_PATH`:: Path to `svgbob` binary (defaults: `/usr/bin/svgbob`)
`KROKI_TIKZ2SVG_PATH`:: Path to `tikz2svg` binary (defaults: `/usr/bin/tikz2svg`)
`KROKI_TIKZ2SVG_BIN_PATH`:: Path to `tikz2svg` binary (defaults: `/usr/bin/tikz2svg`)
`KROKI_UMLET_BIN_PATH`:: Path to `umlet` binary (defaults: `/usr/bin/umlet`)
`KROKI_VEGA_BIN_PATH`:: Path to `vega` binary which supports both Vega and Vega-Lite grammar (defaults: `/usr/bin/bytefield`)
`KROKI_WAVEDROM_BIN_PATH`:: Path to `wavedrom` binary (defaults: `/usr/bin/wavedrom`)
Expand Down
61 changes: 31 additions & 30 deletions server/README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,34 @@ Kroki server acts as a gateway and provides a unified API on-top of diagrams lib

== How to update third-party dependencies

=== ditaamini

Since https://github.com/stathissideris/ditaa is unmaintained, we are using an active fork: https://github.com/pepijnve/ditaa/tree/master
The jar is published as part of AsciidoctorJ Diagram: https://search.maven.org/artifact/org.asciidoctor/asciidoctorj-diagram-ditaamini

To update ditaamini:

. Download the latest version of `org.asciidoctor:asciidoctorj-diagram-ditaamini` from Maven central
. Unzip `asciidoctorj-diagram-ditaamini` jar
. Copy `gems/asciidoctor-diagram-ditaamini-$VERSION/lib/asciidoctor-diagram/ditaa/ditaamini-$VERSION.jar` to `server/lib`
. Update the version in the `installLocalDependencies` task located in the `Makefile` at the root of this repository:
+
[source,diff]
----
installLocalDependencies:
- mvn install:install-file -Dfile=./server/lib/ditaamini-1.0.3.jar -DgroupId=ditaa -DartifactId=ditaa-mini -Dversion=1.0.3 -Dpackaging=jar
+ mvn install:install-file -Dfile=./server/lib/ditaamini-1.0.4.jar -DgroupId=ditaa -DartifactId=ditaa-mini -Dversion=1.0.4 -Dpackaging=jar
----
. Run the `installLocalDependencies` task to make sure that everything is working as expected:
+
$ make installLocalDependencies

. Update the version in `server/pom.xml`:
+
[source,diff]
----
-<ditaa-mini.version>1.0.3</ditaa-mini.version>
+<ditaa-mini.version>1.0.4</ditaa-mini.version>
----
. Build the project
=== Ditaa (mini)

Since https://github.com/stathissideris/ditaa is unmaintained, we are using an active fork: https://github.com/yuzutech/ditaa-mini which is based on an active fork https://github.com/pepijnve/ditaa.

We are producing native binaries with GraalVM: https://github.com/yuzutech/ditaa-mini/releases.

When a new version is available, we need to :

. update the fork
. run the following workflow: https://github.com/yuzutech/ditaa-mini/actions/workflows/native-image-on-demand.yml
. update the argument variable `ARG DITAA_VERSION="x.y.z"` in `server/ops/docker/jdk11-jammy/Dockerfile`

=== PlantUML

We are producing native binaries with GraalVM: https://github.com/ggrossetie/plantuml/releases

When a new version is available, we need to:

. update the fork
. run the following workflow: https://github.com/ggrossetie/plantuml/actions/workflows/native-image-on-demand.yml
. update the argument variable `ARG PLANTUML_VERSION="x.y.z"` in `server/ops/docker/jdk11-jammy/Dockerfile`

=== UMLet

We are producing native binaries with GraalVM: https://github.com/yuzutech/umlet/releases

When a new version is available, we need to:

. update the fork
. run the following workflow: https://github.com/yuzutech/umlet/actions/workflows/release.yml
. update the argument variable `ARG UMLET_VERSION="x.y.z"` in `server/ops/docker/jdk11-jammy/Dockerfile`
Binary file removed server/lib/ditaamini-1.0.3.jar
Binary file not shown.
7 changes: 6 additions & 1 deletion server/ops/docker/jdk11-jammy/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ ARG D2_VERSION="0.4.1"
ARG PLANTUML_VERSION="1.2023.6"
ARG UMLET_VERSION="2023-03-20_UMLet_v15.1"
ARG GRAPHVIZ_VERSION="8.0.4"
ARG DITAA_VERSION="1.0.3"
ARG TARGETARCH

RUN addgroup --gecos 1000 kroki && adduser --disabled-password --ingroup kroki -u 1000 kroki
Expand Down Expand Up @@ -244,6 +245,9 @@ RUN apt-get update && apt-get install --no-install-recommends --yes \
RUN wget "https://github.com/yuzutech/graphviz-builder/releases/download/${GRAPHVIZ_VERSION}/dot-linux-${TARGETARCH}" -O /usr/bin/dot && \
chmod +x /usr/bin/dot

RUN wget "https://github.com/yuzutech/ditaa-mini/releases/download/${DITAA_VERSION}/ditaamini-linux-${TARGETARCH}-${DITAA_VERSION}" -O /usr/bin/ditaa && \
chmod +x /usr/bin/ditaa

RUN wget "https://github.com/terrastruct/d2/releases/download/v${D2_VERSION}/d2-v${D2_VERSION}-linux-${TARGETARCH}.tar.gz" -O - | tar -zxv -C /usr/bin d2-v${D2_VERSION}/bin/d2 && \
mv usr/bin/d2-v${D2_VERSION}/bin/d2 /usr/bin/d2 && \
chmod +x /usr/bin/d2
Expand Down Expand Up @@ -281,7 +285,8 @@ ENV KROKI_PIKCHR_BIN_PATH=/usr/bin/pikchr
ENV KROKI_D2_BIN_PATH=/usr/bin/d2
ENV KROKI_UMLET_BIN_PATH=/usr/bin/umlet
ENV KROKI_PLANTUML_BIN_PATH=/usr/bin/plantuml
ENV KROKI_TIKZ2SVG_PATH=/usr/bin/tikz2svg
ENV KROKI_TIKZ2SVG_BIN_PATH=/usr/bin/tikz2svg
ENV KROKI_DITAA_BIN_PATH=/usr/bin/ditaa
ENV JAVA_OPTS="-Dlogback.configurationFile=/etc/kroki/logback.xml -Dvertx.logger-delegate-factory-class-name=io.vertx.core.logging.SLF4JLogDelegateFactory"

COPY --chown=kroki:kroki target/kroki-server.jar /usr/local/kroki/kroki-server.jar
Expand Down
6 changes: 0 additions & 6 deletions server/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
<junit.jupiter.version>5.9.3</junit.jupiter.version>
<assertj-core.version>3.24.2</assertj-core.version>
<mockito-core.version>4.11.0</mockito-core.version>
<ditaa-mini.version>1.0.3</ditaa-mini.version>
<slf4j-api.version>2.0.7</slf4j-api.version>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
Expand Down Expand Up @@ -78,11 +77,6 @@
<artifactId>logback-json-classic</artifactId>
<version>0.1.5</version>
</dependency>
<dependency>
<groupId>ditaa</groupId>
<artifactId>ditaa-mini</artifactId>
<version>${ditaa-mini.version}</version>
</dependency>
<dependency>
<groupId>guru.nidi.com.kitfox</groupId>
<artifactId>svgSalamander</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion server/src/main/java/io/kroki/server/Server.java
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ static void start(Vertx vertx, JsonObject config, Handler<AsyncResult<HttpServer
DiagramRegistry registry = new DiagramRegistry(router, bodyHandler);
registry.register(new Plantuml(vertx, config), "plantuml");
registry.register(new Plantuml(vertx, config), "c4plantuml");
registry.register(new Ditaa(vertx), "ditaa");
registry.register(new Ditaa(vertx, config), "ditaa");
registry.register(new Blockdiag(vertx, config), "blockdiag", "seqdiag", "actdiag", "nwdiag", "packetdiag", "rackdiag");
registry.register(new Umlet(vertx, config, commander), "umlet");
registry.register(new Graphviz(vertx, config, commander), "graphviz", "dot");
Expand Down
50 changes: 7 additions & 43 deletions server/src/main/java/io/kroki/server/service/Ditaa.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,8 @@
import io.vertx.core.Vertx;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.json.JsonObject;
import org.stathissideris.ditaa.core.CommandLineConverter;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.io.*;
import java.util.Arrays;
import java.util.List;

Expand All @@ -24,9 +19,11 @@ public class Ditaa implements DiagramService {
private static final List<FileFormat> SUPPORTED_FORMATS = Arrays.asList(FileFormat.SVG, FileFormat.PNG);
private final SourceDecoder sourceDecoder;
private final Vertx vertx;
private final DitaaCommand command;

public Ditaa(Vertx vertx) {
public Ditaa(Vertx vertx, JsonObject config) {
this.vertx = vertx;
this.command = new DitaaCommand(config);
this.sourceDecoder = new SourceDecoder() {
@Override
public String decode(String encoded) throws DecodeException {
Expand Down Expand Up @@ -54,44 +51,11 @@ public String getVersion() {
public void convert(String sourceDecoded, String serviceName, FileFormat fileFormat, JsonObject options, Handler<AsyncResult<Buffer>> handler) {
vertx.executeBlocking(future -> {
try {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
convert(fileFormat, options, new ByteArrayInputStream(sourceDecoded.getBytes()), outputStream);
future.complete(outputStream.toByteArray());
} catch (IllegalStateException e) {
byte[] result = this.command.convert(sourceDecoded, fileFormat, options);
future.complete(result);
} catch (IllegalStateException | InterruptedException | IOException e) {
future.fail(e);
}
}, res -> handler.handle(res.map(o -> Buffer.buffer((byte[]) o))));
}

static void convert(FileFormat fileFormat, JsonObject options, InputStream inputStream, OutputStream outputStream) {
List<String> args = new ArrayList<>();
if (fileFormat.equals(FileFormat.SVG)) {
args.add("--svg");
}
String noAntialias = options.getString("no-antialias");
if (noAntialias != null) {
args.add("--no-antialias");
}
String noSeparation = options.getString("no-separation");
if (noSeparation != null) {
args.add("--no-separation");
}
String roundCorners = options.getString("round-corners");
if (roundCorners != null) {
args.add("--round-corners");
}
String scale = options.getString("scale");
if (scale != null) {
args.add("--scale " + scale);
}
String noShadows = options.getString("no-shadows");
if (noShadows != null) {
args.add("--no-shadows");
}
String tabs = options.getString("tabs");
if (tabs != null) {
args.add("--tabs " + tabs);
}
CommandLineConverter.convert(args.toArray(new String[0]), inputStream, outputStream);
}
}
54 changes: 54 additions & 0 deletions server/src/main/java/io/kroki/server/service/DitaaCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package io.kroki.server.service;

import io.kroki.server.action.Commander;
import io.kroki.server.format.FileFormat;
import io.vertx.core.json.JsonObject;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class DitaaCommand {

private final String binPath;
private final Commander commander;

public DitaaCommand(JsonObject config) {
this.binPath = config.getString("KROKI_DITAA_BIN_PATH", "ditaa");
this.commander = new Commander(config);
}

public byte[] convert(String source, FileFormat format, JsonObject options) throws IOException, InterruptedException {
List<String> commands = new ArrayList<>();
commands.add(binPath);
if (format.equals(FileFormat.SVG)) {
commands.add("--svg");
}
String noAntialias = options.getString("no-antialias");
if (noAntialias != null) {
commands.add("--no-antialias");
}
String noSeparation = options.getString("no-separation");
if (noSeparation != null) {
commands.add("--no-separation");
}
String roundCorners = options.getString("round-corners");
if (roundCorners != null) {
commands.add("--round-corners");
}
String scale = options.getString("scale");
if (scale != null) {
commands.add("--scale " + scale);
}
String noShadows = options.getString("no-shadows");
if (noShadows != null) {
commands.add("--no-shadows");
}
String tabs = options.getString("tabs");
if (tabs != null) {
commands.add("--tabs " + tabs);
}
commands.add("-");
return commander.execute(source.getBytes(), commands.toArray(new String[0]));
}
}
14 changes: 7 additions & 7 deletions server/src/main/java/io/kroki/server/service/Plantuml.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
Expand Down Expand Up @@ -76,7 +75,8 @@ public class Plantuml implements DiagramService {
private static final Pattern STDLIB_PATH_RX = Pattern.compile("<([a-zA-Z0-9]+)/[^>]+>");

private final Vertx vertx;
private final PlantumlCommand command;
private final PlantumlCommand plantumlCommand;
private final DitaaCommand ditaaCommand;
private final SafeMode safeMode;
private final Logging logging;
private static final String c4 = read("c4.puml");
Expand Down Expand Up @@ -119,7 +119,8 @@ public String decode(String encoded) throws DecodeException {
return DiagramSource.plantumlDecode(encoded);
}
};
this.command = new PlantumlCommand(config);
this.plantumlCommand = new PlantumlCommand(config);
this.ditaaCommand = new DitaaCommand(config);
this.includeWhitelist = parseIncludeWhitelist(config);
this.logging = new Logging(logger);
// Disable unsafe include for security reasons
Expand Down Expand Up @@ -207,10 +208,9 @@ public void convert(String sourceDecoded, String serviceName, FileFormat fileFor
vertx.executeBlocking(future -> {
try {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
// REMIND: options are unsupported for now.
Ditaa.convert(fileFormat, options, new ByteArrayInputStream(ditaaContext.getSource().getBytes()), outputStream);
ditaaCommand.convert(ditaaContext.getSource(), fileFormat, options);
future.complete(outputStream.toByteArray());
} catch (IllegalStateException e) {
} catch (IllegalStateException | IOException | InterruptedException e) {
future.fail(e);
}
}, res -> handler.handle(res.map(o -> Buffer.buffer((byte[]) o))));
Expand All @@ -224,7 +224,7 @@ public void convert(String sourceDecoded, String serviceName, FileFormat fileFor
// add !theme directive just after the @start directive
sourceWithTheme = START_BLOCK_RX.matcher(primeSource).replaceAll("$1!theme " + theme + "\n");
}
byte[] data = this.command.convert(sourceWithTheme, fileFormat, options);
byte[] data = this.plantumlCommand.convert(sourceWithTheme, fileFormat, options);
future.complete(data);
} catch (Exception e) {
future.fail(e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import io.kroki.server.unit.TimeValue;
import io.vertx.core.json.JsonObject;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Base64;
Expand Down
2 changes: 1 addition & 1 deletion server/src/main/java/io/kroki/server/service/TikZ.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public class TikZ implements DiagramService {

public TikZ(Vertx vertx, JsonObject config, Commander commander) {
this.vertx = vertx;
this.binPath = config.getString("KROKI_TIKZ2SVG_PATH", "tikz2svg");
this.binPath = config.getString("KROKI_TIKZ2SVG_BIN_PATH", "tikz2svg");
this.sourceDecoder = new SourceDecoder() {
@Override
public String decode(String encoded) throws DecodeException {
Expand Down
Loading

0 comments on commit 7aaf223

Please sign in to comment.