Skip to content

Commit

Permalink
resolves yuzutech#827 pass options to the underlying service
Browse files Browse the repository at this point in the history
  • Loading branch information
ggrossetie committed Aug 2, 2021
1 parent d32c0b2 commit 055a88f
Show file tree
Hide file tree
Showing 26 changed files with 165 additions and 71 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public String getVersion() {
}

@Override
public void convert(String sourceDecoded, String serviceName, FileFormat fileFormat, Handler<AsyncResult<Buffer>> handler) {
public void convert(String sourceDecoded, String serviceName, FileFormat fileFormat, JsonObject options, Handler<AsyncResult<Buffer>> handler) {
String requestURI = "/" + serviceName + "/" + fileFormat.getName();
Handler<AsyncResult<HttpResponse<Buffer>>> responseHandler = Delegator.createHandler(host, port, requestURI, handler);
Delegator.delegate(client, host, port, requestURI, sourceDecoded, responseHandler);
Expand Down
2 changes: 1 addition & 1 deletion server/src/main/java/io/kroki/server/service/Bpmn.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public String getVersion() {
}

@Override
public void convert(String sourceDecoded, String serviceName, FileFormat fileFormat, Handler<AsyncResult<Buffer>> handler) {
public void convert(String sourceDecoded, String serviceName, FileFormat fileFormat, JsonObject options, Handler<AsyncResult<Buffer>> handler) {
String requestURI = "/" + serviceName + "/" + fileFormat.getName();
Handler<AsyncResult<HttpResponse<Buffer>>> responseHandler = Delegator.createHandler(host, port, requestURI, handler);
Delegator.delegate(client, host, port, requestURI, sourceDecoded, responseHandler);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public String getVersion() {
}

@Override
public void convert(String sourceDecoded, String serviceName, FileFormat fileFormat, Handler<AsyncResult<Buffer>> handler) {
public void convert(String sourceDecoded, String serviceName, FileFormat fileFormat, JsonObject options, Handler<AsyncResult<Buffer>> handler) {
vertx.executeBlocking(future -> {
try {
byte[] result = bytefield(sourceDecoded.getBytes());
Expand Down
33 changes: 29 additions & 4 deletions server/src/main/java/io/kroki/server/service/DiagramHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import io.kroki.server.response.Caching;
import io.kroki.server.response.DiagramResponse;
import io.vertx.core.Handler;
import io.vertx.core.MultiMap;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.http.HttpServerResponse;
import io.vertx.core.json.JsonObject;
Expand All @@ -21,7 +22,9 @@
import org.slf4j.LoggerFactory;

import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class DiagramHandler {
Expand Down Expand Up @@ -62,7 +65,10 @@ public Handler<RoutingContext> createGet(String serviceName) {
String sourceEncoded = request.getParam("source_encoded");
try {
String sourceDecoded = service.getSourceDecoder().decode(sourceEncoded);
convert(routingContext, sourceDecoded, serviceName, fileFormat);
MultiMap headers = request.headers();
MultiMap params = request.params();
JsonObject options = getOptions(new JsonObject(), headers, params);
convert(routingContext, sourceDecoded, serviceName, fileFormat, options);
} catch (DecodeException e) {
routingContext.fail(new BadRequestException(e.getMessage(), e));
}
Expand Down Expand Up @@ -97,7 +103,8 @@ public Handler<RoutingContext> createPost(String serviceName) {
}
fileFormat = getOutputFileFormatFromTextRequest(serviceName, routingContext);
}
convert(routingContext, diagramSource, serviceName, fileFormat);
JsonObject options = new JsonObject();
convert(routingContext, diagramSource, serviceName, fileFormat, options);
} catch (UnsupportedFormatException | UnsupportedMimeTypeException | UndefinedOutputFormatException e) {
routingContext.fail(e);
}
Expand Down Expand Up @@ -144,6 +151,24 @@ private FileFormat getOutputFileFormatFromAcceptHeaders(String serviceName, Rout
throw new UnsupportedMimeTypeException(mimeTypes, serviceName, supportedFormats);
}

private JsonObject getOptions(JsonObject diagramOptions, MultiMap headers, MultiMap params) {
Map<String, Object> options = new HashMap<>();
for (Map.Entry<String, String> paramEntry : params.entries()) {
options.put(paramEntry.getKey().toLowerCase(), paramEntry.getValue());
}
for (Map.Entry<String, String> headerEntry : headers.entries()) {
if (headerEntry.getKey().toLowerCase().startsWith("kroki-diagram-options-")) {
String key = headerEntry.getKey().toLowerCase().replace("kroki-diagram-options-", "");
options.put(key, headerEntry.getValue());
}
}
for (String diagramOptionName : diagramOptions.fieldNames()) {
Object value = diagramOptions.getValue(diagramOptionName);
options.put(diagramOptionName.toLowerCase(), value);
}
return new JsonObject(options);
}

// delegate

public FileFormat validate(String serviceName, String outputFormat) {
Expand All @@ -155,9 +180,9 @@ public FileFormat validate(String serviceName, String outputFormat) {
return fileFormat;
}

public void convert(RoutingContext routingContext, String sourceDecoded, String serviceName, FileFormat fileFormat) {
public void convert(RoutingContext routingContext, String sourceDecoded, String serviceName, FileFormat fileFormat, JsonObject options) {
long start = System.currentTimeMillis();
service.convert(sourceDecoded, serviceName, fileFormat, res -> {
service.convert(sourceDecoded, serviceName, fileFormat, options, res -> {
logging.convert(routingContext, start, serviceName, fileFormat);
if (res.failed()) {
routingContext.fail(res.cause());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ public Handler<RoutingContext> create() {
}
try {
FileFormat fileFormat = diagramHandler.validate(diagramType, outputFormat);
diagramHandler.convert(routingContext, diagramSource, diagramType, fileFormat);
JsonObject options = new JsonObject();
diagramHandler.convert(routingContext, diagramSource, diagramType, fileFormat, options);
} catch (UnsupportedFormatException e) {
routingContext.fail(e);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import io.vertx.core.AsyncResult;
import io.vertx.core.Handler;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.json.JsonObject;

import java.util.List;

Expand All @@ -16,5 +17,5 @@ public interface DiagramService {

String getVersion();

void convert(String sourceDecoded, String serviceName, FileFormat fileFormat, Handler<AsyncResult<Buffer>> handler);
void convert(String sourceDecoded, String serviceName, FileFormat fileFormat, JsonObject options, Handler<AsyncResult<Buffer>> handler);
}
3 changes: 2 additions & 1 deletion server/src/main/java/io/kroki/server/service/Ditaa.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import io.vertx.core.Handler;
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;
Expand Down Expand Up @@ -50,7 +51,7 @@ public String getVersion() {
}

@Override
public void convert(String sourceDecoded, String serviceName, FileFormat fileFormat, Handler<AsyncResult<Buffer>> handler) {
public void convert(String sourceDecoded, String serviceName, FileFormat fileFormat, JsonObject options, Handler<AsyncResult<Buffer>> handler) {
vertx.executeBlocking(future -> {
try {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
Expand Down
2 changes: 1 addition & 1 deletion server/src/main/java/io/kroki/server/service/Erd.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public String getVersion() {
}

@Override
public void convert(String sourceDecoded, String serviceName, FileFormat fileFormat, Handler<AsyncResult<Buffer>> handler) {
public void convert(String sourceDecoded, String serviceName, FileFormat fileFormat, JsonObject options, Handler<AsyncResult<Buffer>> handler) {
vertx.executeBlocking(future -> {
try {
byte[] result = erd(sourceDecoded.getBytes(), fileFormat.getName());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public String getVersion() {
}

@Override
public void convert(String sourceDecoded, String serviceName, FileFormat fileFormat, Handler<AsyncResult<Buffer>> handler) {
public void convert(String sourceDecoded, String serviceName, FileFormat fileFormat, JsonObject options, Handler<AsyncResult<Buffer>> handler) {
String requestURI = "/" + serviceName + "/" + fileFormat.getName();
Handler<AsyncResult<HttpResponse<Buffer>>> responseHandler = Delegator.createHandler(host, port, requestURI, handler);
Delegator.delegate(client, host, port, requestURI, sourceDecoded, responseHandler);
Expand Down
38 changes: 30 additions & 8 deletions server/src/main/java/io/kroki/server/service/Graphviz.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,14 @@
import io.kroki.server.decode.SourceDecoder;
import io.kroki.server.error.DecodeException;
import io.kroki.server.format.FileFormat;
import io.kroki.server.response.Caching;
import io.kroki.server.response.DiagramResponse;
import io.vertx.core.AsyncResult;
import io.vertx.core.Handler;
import io.vertx.core.Vertx;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.json.JsonObject;

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

Expand All @@ -24,7 +23,6 @@ public class Graphviz implements DiagramService {
private final Vertx vertx;
private final String binPath;
private final SourceDecoder sourceDecoder;
private final DiagramResponse diagramResponse;
private final Commander commander;

public Graphviz(Vertx vertx, JsonObject config, Commander commander) {
Expand All @@ -36,7 +34,6 @@ public String decode(String encoded) throws DecodeException {
return DiagramSource.decode(encoded);
}
};
this.diagramResponse = new DiagramResponse(new Caching("2.40.1"));
this.commander = commander;
}

Expand All @@ -56,23 +53,48 @@ public String getVersion() {
}

@Override
public void convert(String sourceDecoded, String serviceName, FileFormat fileFormat, Handler<AsyncResult<Buffer>> handler) {
public void convert(String sourceDecoded, String serviceName, FileFormat fileFormat, JsonObject options, Handler<AsyncResult<Buffer>> handler) {
vertx.executeBlocking(future -> {
try {
byte[] result = dot(sourceDecoded.getBytes(), fileFormat.getName());
byte[] result = dot(sourceDecoded.getBytes(), fileFormat.getName(), options);
future.complete(result);
} catch (IOException | InterruptedException | IllegalStateException e) {
future.fail(e);
}
}, res -> handler.handle(res.map(o -> Buffer.buffer((byte[]) o))));
}

private byte[] dot(byte[] source, String format) throws IOException, InterruptedException, IllegalStateException {
private byte[] dot(byte[] source, String format, JsonObject options) throws IOException, InterruptedException, IllegalStateException {
List<String> commands = new ArrayList<>();
commands.add(binPath);
// Supported format:
// canon cmap cmapx cmapx_np dot dot_json eps fig gd gd2 gif gv imap imap_np ismap
// jpe jpeg jpg json json0 mp pdf pic plain plain-ext
// png pov ps ps2
// svg svgz tk vml vmlz vrml wbmp x11 xdot xdot1.2 xdot1.4 xdot_json xlib
return commander.execute(source, binPath, "-T" + format);
commands.add("-T" + format);
String scale = options.getString("scale");
if (scale != null) {
commands.add("-s" + scale);
}
String layout = options.getString("layout");
if (layout != null) {
commands.add("-K" + layout);
}
for (String fieldName : options.fieldNames()) {
if (fieldName.startsWith("node-attribute-")) {
String name = fieldName.replace("node-attribute-", "");
commands.add("-N" + name + "=" + options.getString(fieldName));
}
if (fieldName.startsWith("graph-attribute-")) {
String name = fieldName.replace("graph-attribute-", "");
commands.add("-G" + name + "=" + options.getString(fieldName));
}
if (fieldName.startsWith("edge-attribute-")) {
String name = fieldName.replace("edge-attribute-", "");
commands.add("-E" + name + "=" + options.getString(fieldName));
}
}
return commander.execute(source, commands.toArray(new String[0]));
}
}
2 changes: 1 addition & 1 deletion server/src/main/java/io/kroki/server/service/Mermaid.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public String getVersion() {
}

@Override
public void convert(String sourceDecoded, String serviceName, FileFormat fileFormat, Handler<AsyncResult<Buffer>> handler) {
public void convert(String sourceDecoded, String serviceName, FileFormat fileFormat, JsonObject options, Handler<AsyncResult<Buffer>> handler) {
String requestURI = "/" + serviceName + "/" + fileFormat.getName();
Handler<AsyncResult<HttpResponse<Buffer>>> responseHandler = Delegator.createHandler(host, port, requestURI, handler);
Delegator.delegate(client, host, port, requestURI, sourceDecoded, responseHandler);
Expand Down
2 changes: 1 addition & 1 deletion server/src/main/java/io/kroki/server/service/Nomnoml.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public String getVersion() {
}

@Override
public void convert(String sourceDecoded, String serviceName, FileFormat fileFormat, Handler<AsyncResult<Buffer>> handler) {
public void convert(String sourceDecoded, String serviceName, FileFormat fileFormat, JsonObject options, Handler<AsyncResult<Buffer>> handler) {
vertx.executeBlocking(future -> {
try {
byte[] result = nomnoml(sourceDecoded.getBytes());
Expand Down
2 changes: 1 addition & 1 deletion server/src/main/java/io/kroki/server/service/Pikchr.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public String getVersion() {
}

@Override
public void convert(String sourceDecoded, String serviceName, FileFormat fileFormat, Handler<AsyncResult<Buffer>> handler) {
public void convert(String sourceDecoded, String serviceName, FileFormat fileFormat, JsonObject options, Handler<AsyncResult<Buffer>> handler) {
vertx.executeBlocking(future -> {
try {
byte[] result = pikchr(sourceDecoded.getBytes());
Expand Down
2 changes: 1 addition & 1 deletion server/src/main/java/io/kroki/server/service/Plantuml.java
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ public String getVersion() {
}

@Override
public void convert(String sourceDecoded, String serviceName, FileFormat fileFormat, Handler<AsyncResult<Buffer>> handler) {
public void convert(String sourceDecoded, String serviceName, FileFormat fileFormat, JsonObject options, Handler<AsyncResult<Buffer>> handler) {
String source;
try {
source = sanitize(sourceDecoded, this.safeMode, this.includeWhitelist);
Expand Down
2 changes: 1 addition & 1 deletion server/src/main/java/io/kroki/server/service/Svgbob.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public String getVersion() {
}

@Override
public void convert(String sourceDecoded, String serviceName, FileFormat fileFormat, Handler<AsyncResult<Buffer>> handler) {
public void convert(String sourceDecoded, String serviceName, FileFormat fileFormat, JsonObject options, Handler<AsyncResult<Buffer>> handler) {
vertx.executeBlocking(future -> {
try {
byte[] result = svgbob(sourceDecoded.getBytes());
Expand Down
3 changes: 2 additions & 1 deletion server/src/main/java/io/kroki/server/service/Umlet.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import io.vertx.core.Handler;
import io.vertx.core.Vertx;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.json.JsonObject;

import java.io.IOException;
import java.util.Arrays;
Expand Down Expand Up @@ -47,7 +48,7 @@ public String getVersion() {
}

@Override
public void convert(String sourceDecoded, String serviceName, FileFormat fileFormat, Handler<AsyncResult<Buffer>> handler) {
public void convert(String sourceDecoded, String serviceName, FileFormat fileFormat, JsonObject options, Handler<AsyncResult<Buffer>> handler) {
vertx.executeBlocking(future -> {
try {
byte[] result = UmletConverter.convert(sourceDecoded, fileFormat.getName());
Expand Down
12 changes: 2 additions & 10 deletions server/src/main/java/io/kroki/server/service/Vega.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public String getVersion() {
}

@Override
public void convert(String sourceDecoded, String serviceName, FileFormat fileFormat, Handler<AsyncResult<Buffer>> handler) {
public void convert(String sourceDecoded, String serviceName, FileFormat fileFormat, JsonObject options, Handler<AsyncResult<Buffer>> handler) {
vertx.executeBlocking(future -> {
try {
byte[] result = vega(sourceDecoded.getBytes(), fileFormat.getName());
Expand All @@ -72,15 +72,7 @@ public void convert(String sourceDecoded, String serviceName, FileFormat fileFor
}

private byte[] vega(byte[] source, String format) throws IOException, InterruptedException, IllegalStateException {
final String vegaSafeMode;
switch (safeMode) {
case UNSAFE:
vegaSafeMode = "unsafe";
break;
default:
vegaSafeMode = "secure";
break;
}
String vegaSafeMode = safeMode == SafeMode.UNSAFE ? "unsafe" : "secure";
return commander.execute(source, binPath,
"--output-format=" + format,
"--safe-mode=" + vegaSafeMode,
Expand Down
2 changes: 1 addition & 1 deletion server/src/main/java/io/kroki/server/service/Wavedrom.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public String getVersion() {
}

@Override
public void convert(String sourceDecoded, String serviceName, FileFormat fileFormat, Handler<AsyncResult<Buffer>> handler) {
public void convert(String sourceDecoded, String serviceName, FileFormat fileFormat, JsonObject options, Handler<AsyncResult<Buffer>> handler) {
vertx.executeBlocking(future -> {
try {
byte[] result = vega(sourceDecoded.getBytes());
Expand Down
8 changes: 4 additions & 4 deletions server/src/test/java/io/kroki/server/ServerConfigTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,28 @@ class ServerConfigTest {

@Test
void throw_exception_when_non_ipv6_listen_address_contains_more_than_one_colon() {
assertThatThrownBy(() -> Server.getListenAddress(new JsonObject().put("KROKI_LISTEN", "localhost:1234:5678")))
assertThatThrownBy(() -> Server.getListenAddress(new JsonObject().put("KROKI_LISTEN", "localhost:1234:5678")))
.isInstanceOf(IllegalArgumentException.class)
.hasMessageStartingWith("KROKI_LISTEN is not a valid listen address 'localhost:1234:5678', format must be: 'host:5678', ':5678', '1.2.3.4:5678', '[2041:0:140f::875b:131b]:5678' or '[2041:0:140f::875b:131b]'");
}

@Test
void throw_exception_when_listen_address_contains_host_as_port() {
assertThatThrownBy(() -> Server.getListenAddress(new JsonObject().put("KROKI_LISTEN", ":localhost")))
assertThatThrownBy(() -> Server.getListenAddress(new JsonObject().put("KROKI_LISTEN", ":localhost")))
.isInstanceOf(NumberFormatException.class)
.hasMessageStartingWith("For input string: \"localhost\"");
}

@Test
void throw_exception_when_listen_address_contains_ipv4_as_port() {
assertThatThrownBy(() -> Server.getListenAddress(new JsonObject().put("KROKI_LISTEN", ":192.168.0.1")))
assertThatThrownBy(() -> Server.getListenAddress(new JsonObject().put("KROKI_LISTEN", ":192.168.0.1")))
.isInstanceOf(NumberFormatException.class)
.hasMessageStartingWith("For input string: \"192.168.0.1\"");
}

@Test
void throw_exception_when_listen_address_contains_an_empty_port() {
assertThatThrownBy(() -> Server.getListenAddress(new JsonObject().put("KROKI_LISTEN", "localhost:")))
assertThatThrownBy(() -> Server.getListenAddress(new JsonObject().put("KROKI_LISTEN", "localhost:")))
.isInstanceOf(IllegalArgumentException.class)
.hasMessageStartingWith("For input string: \"\"");
}
Expand Down
Loading

0 comments on commit 055a88f

Please sign in to comment.