Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
{ "name": "camel.main.contextReloadEnabled", "required": false, "description": "Used for enabling context reloading. If enabled then Camel allow external systems such as security vaults (AWS secrets manager, etc.) to trigger refreshing Camel by updating property placeholders and reload all existing routes to take changes into effect.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": false, "secret": false },
{ "name": "camel.main.description", "required": false, "description": "Sets the description (intended for humans) of the Camel application.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "string", "javaType": "java.lang.String", "secret": false },
{ "name": "camel.main.devConsoleEnabled", "required": false, "description": "Whether to enable developer console (requires camel-console on classpath). The developer console is only for assisting during development. This is NOT for production usage.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": false, "secret": false, "security": "insecure:dev" },
{ "name": "camel.main.dumpRoutes", "required": false, "description": "If dumping is enabled then Camel will during startup dump all loaded routes (incl rests and route templates) represented as XML\/YAML DSL into the log. This is intended for trouble shooting or to assist during development. Sensitive information that may be configured in the route endpoints could potentially be included in the dump output and is therefore not recommended being used for production usage. This requires to have camel-xml-io\/camel-yaml-io on the classpath to be able to dump the routes as XML\/YAML. You can also use JSon which dumps the route structure in JSon. The JSon does not represent Camel DSL but it useful for tooling to understand the structure of the routes and how EIPs are nested together. You can also use png to save route diagrams as PNG image files either all combined in a single file (default camel-route-diagrams.png) or to a given folder, where routes are grouped by source file name(s) and saved as corresponding .png files.\\ This requires to have camel-diagram on the classpath to be able to render PNG diagrams.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "enum", "javaType": "java.lang.String", "secret": false, "enum": [ "xml", "yaml", "json", "png" ] },
{ "name": "camel.main.dumpRoutes", "required": false, "description": "If dumping is enabled then Camel will during startup dump all loaded routes (incl rests and route templates) represented as XML\/YAML DSL into the log. This is intended for trouble shooting or to assist during development. Sensitive information that may be configured in the route endpoints could potentially be included in the dump output and is therefore not recommended being used for production usage. This requires to have camel-xml-io\/camel-yaml-io on the classpath to be able to dump the routes as XML\/YAML. You can also use JSon which dumps the route structure in JSon. The JSon does not represent Camel DSL but it useful for tooling to understand the structure of the routes and how EIPs are nested together. You can also use png to save route diagrams as PNG image files either all combined in a single file (default camel-route-diagrams.png) or to a given folder, where routes are grouped by source file name(s) and saved as corresponding .png files. This requires to have camel-diagram on the classpath to be able to render PNG diagrams.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "enum", "javaType": "java.lang.String", "secret": false, "enum": [ "xml", "yaml", "json", "png" ] },
{ "name": "camel.main.dumpRoutesGeneratedIds", "required": false, "description": "Whether to include auto generated IDs in the dumped output. Default is false.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": false, "secret": false },
{ "name": "camel.main.dumpRoutesInclude", "required": false, "description": "Controls what to include in output for route dumping. Possible values: all, routes, rests, routeConfigurations, routeTemplates, beans, dataFormats. Multiple values can be separated by comma. Default is routes.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "string", "javaType": "java.lang.String", "defaultValue": "routes", "secret": false },
{ "name": "camel.main.dumpRoutesLog", "required": false, "description": "Whether to log route dumps to Logger", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": true, "secret": false },
Expand Down
26 changes: 2 additions & 24 deletions components/camel-diagram/src/main/docs/diagram.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,11 @@
*Since Camel {since}*

The Diagram module provides route diagram rendering capabilities for Apache Camel routes.
It can generate visual route diagrams as PNG images or text-based tree representations
from route structure data.
It can generate visual route diagrams as PNG images representations from route structure data.

== Features

* Render route diagrams as PNG images with colored nodes and scope boxes
* Generate text-based tree diagrams for terminal output
* Support for all Camel EIPs: choice, doTry/doCatch, filter, split, loop, multicast, and more
* Scope boxes visually group branching and scoping EIPs
* Multiple color themes: dark, light, transparent, or custom
Expand Down Expand Up @@ -70,16 +68,6 @@ BufferedImage image = renderer.renderDiagram(List.of(lr), lr.maxY + RouteDiagram
ImageIO.write(image, "PNG", new File("diagram.png"));
----

=== Text diagram

For terminal or log output, generate a text-based tree:

[source,java]
----
List<String> lines = renderer.printTextDiagram(routes);
lines.forEach(System.out::println);
----

=== With Camel JBang

The diagram rendering is used by the `camel cmd route-diagram` command in Camel JBang:
Expand All @@ -96,11 +84,10 @@ The following built-in themes are available:
* `dark` - dark background (default)
* `light` - light background
* `transparent` - transparent background
* `text` - to use tree diagram instead of visual diagram

Custom colors can be specified using the format:

[source,text]
[source,properties]
----
bg=#1e1e1e:from=#2e7d32:to=#1565c0:eip=#8957e5:choice=#d29922
----
Expand All @@ -113,12 +100,3 @@ To use dark theme
----
camel cmd route-diagram MyRoute.java --theme=dark
----

To print textual tree diagram instead of visual

[source,bash]
----
camel cmd route-diagram MyRoute.java --theme=tree
----

TIP: You can also show diagrams for an existing running integration by executing `camel cmd diagram`.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import java.util.Map;
import java.util.StringJoiner;

import org.apache.camel.console.DevConsoleRegistry;
import org.apache.camel.spi.RouteDiagramDumper;
import org.apache.camel.spi.annotations.DevConsole;
import org.apache.camel.support.PluginHelper;
Expand All @@ -36,7 +35,7 @@ public class DiagramDevConsole extends AbstractDevConsole {
public static final String FILTER = "filter";

/**
* Theme to use: dark, light, or text
* Theme to use: dark or light
*/
public static final String THEME = "theme";

Expand All @@ -60,6 +59,11 @@ public class DiagramDevConsole extends AbstractDevConsole {
*/
public static final String METRIC = "metric";

/**
* Whether to auto-refresh page every 5 seconds
*/
public static final String AUTO_REFRESH = "autoRefresh";

public DiagramDevConsole() {
super("camel", "route-diagram", "Route Diagram", "Visual route diagrams");
}
Expand All @@ -76,24 +80,24 @@ protected String doCallText(Map<String, Object> options) {
.parseInt(options.getOrDefault(NODE_WIDTH, "" + RouteDiagramLayoutEngine.DEFAULT_BOX_WIDTH).toString());
String nodeLabel = (String) options.getOrDefault(NODE_LABEL, RouteDiagramDumper.NodeLabelMode.CODE.name());
boolean metric = "true".equalsIgnoreCase((String) options.getOrDefault(METRIC, "true"));
boolean refresh = "true".equalsIgnoreCase((String) options.getOrDefault(AUTO_REFRESH, "true"));

// special for text
if ("text".equalsIgnoreCase(theme)) {
sj.add(renderTextTheme(filter));
} else {
try {
RouteDiagramDumper dumper = PluginHelper.getRouteDiagramDumper(getCamelContext());
BufferedImage image = dumper.dumpRoutesAsImage(filter, RouteDiagramDumper.Theme.valueOf(theme.toUpperCase()),
metric, RouteDiagramDumper.NodeLabelMode.valueOf(nodeLabel.toUpperCase()), nodeWidth, fontSize);
String base64 = dumper.imageToBase64(image);
// For HTML embedding:
String html = String.format(
"<html>\n<body>\n<img src=\"data:image/png;base64,%s\" alt=\"Route Diagram\">\n</body>\n</html>",
base64);
sj.add(html);
} catch (Exception e) {
// ignore
try {
RouteDiagramDumper dumper = PluginHelper.getRouteDiagramDumper(getCamelContext());
BufferedImage image = dumper.dumpRoutesAsImage(filter, RouteDiagramDumper.Theme.valueOf(theme.toUpperCase()),
metric, RouteDiagramDumper.NodeLabelMode.valueOf(nodeLabel.toUpperCase()), nodeWidth, fontSize);
String base64 = dumper.imageToBase64(image);
// For HTML embedding:
String html = String.format(
" <body>\n <img src=\"data:image/png;base64,%s\" alt=\"Route Diagram\">\n </body>\n",
base64);
if (refresh) {
html = "<head><meta http-equiv=\"refresh\" content=\"5\"></head>\n" + html;
}
html = "<html>\n" + html + "</html>\n";
sj.add(html);
} catch (Exception e) {
// ignore
}

return sj.toString();
Expand Down Expand Up @@ -124,18 +128,4 @@ protected Map<String, Object> doCallJson(Map<String, Object> options) {
return root;
}

private String renderTextTheme(String filter) {
final StringJoiner sj = new StringJoiner("\n");

org.apache.camel.console.DevConsole dc
= getCamelContext().getCamelContextExtension().getContextPlugin(DevConsoleRegistry.class)
.resolveById("route-structure");
JsonObject root = (JsonObject) dc.call(MediaType.JSON, Map.of("filter", filter));
var routes = RouteDiagramHelper.parseRoutes(root);
RouteDiagramRenderer renderer = new RouteDiagramRenderer();
var lines = renderer.printTextDiagram(routes);
lines.forEach(sj::add);
sj.add("");
return sj.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -451,11 +451,17 @@ private Color getNodeColor(String type, DiagramColors colors) {
};
}

public List<String> printTextDiagram(List<RouteInfo> routes) {
/**
* Used for testing
*/
List<String> printTextDiagram(List<RouteInfo> routes) {
return printTextDiagram(routes, RouteDiagramLayoutEngine.NodeLabelMode.CODE);
}

public List<String> printTextDiagram(List<RouteInfo> routes, RouteDiagramLayoutEngine.NodeLabelMode mode) {
/**
* Used for testing
*/
List<String> printTextDiagram(List<RouteInfo> routes, RouteDiagramLayoutEngine.NodeLabelMode mode) {
List<String> lines = new ArrayList<>();
for (RouteInfo route : routes) {
lines.add("");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
package org.apache.camel.diagram;

import java.util.Base64;
import java.util.Map;

import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.console.DevConsole;
Expand Down Expand Up @@ -74,16 +73,6 @@ void testTextOutputDefault() {
assertThat(text).contains("data:image/png;base64,");
}

@Test
void testTextOutputTextTheme() {
DevConsole console = resolveConsole();
String text = (String) console.call(DevConsole.MediaType.TEXT, Map.of(DiagramDevConsole.THEME, "text"));
assertThat(text).contains("Route: myRoute");
assertThat(text).contains("Route: otherRoute");
assertThat(text).contains("[from]");
assertThat(text).contains("[choice]");
}

@Test
void testJsonOutput() {
System.setProperty("java.awt.headless", "true");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
{ "name": "camel.main.contextReloadEnabled", "required": false, "description": "Used for enabling context reloading. If enabled then Camel allow external systems such as security vaults (AWS secrets manager, etc.) to trigger refreshing Camel by updating property placeholders and reload all existing routes to take changes into effect.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": false, "secret": false },
{ "name": "camel.main.description", "required": false, "description": "Sets the description (intended for humans) of the Camel application.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "string", "javaType": "java.lang.String", "secret": false },
{ "name": "camel.main.devConsoleEnabled", "required": false, "description": "Whether to enable developer console (requires camel-console on classpath). The developer console is only for assisting during development. This is NOT for production usage.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": false, "secret": false, "security": "insecure:dev" },
{ "name": "camel.main.dumpRoutes", "required": false, "description": "If dumping is enabled then Camel will during startup dump all loaded routes (incl rests and route templates) represented as XML\/YAML DSL into the log. This is intended for trouble shooting or to assist during development. Sensitive information that may be configured in the route endpoints could potentially be included in the dump output and is therefore not recommended being used for production usage. This requires to have camel-xml-io\/camel-yaml-io on the classpath to be able to dump the routes as XML\/YAML. You can also use JSon which dumps the route structure in JSon. The JSon does not represent Camel DSL but it useful for tooling to understand the structure of the routes and how EIPs are nested together. You can also use png to save route diagrams as PNG image files either all combined in a single file (default camel-route-diagrams.png) or to a given folder, where routes are grouped by source file name(s) and saved as corresponding .png files.\\ This requires to have camel-diagram on the classpath to be able to render PNG diagrams.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "enum", "javaType": "java.lang.String", "secret": false, "enum": [ "xml", "yaml", "json", "png" ] },
{ "name": "camel.main.dumpRoutes", "required": false, "description": "If dumping is enabled then Camel will during startup dump all loaded routes (incl rests and route templates) represented as XML\/YAML DSL into the log. This is intended for trouble shooting or to assist during development. Sensitive information that may be configured in the route endpoints could potentially be included in the dump output and is therefore not recommended being used for production usage. This requires to have camel-xml-io\/camel-yaml-io on the classpath to be able to dump the routes as XML\/YAML. You can also use JSon which dumps the route structure in JSon. The JSon does not represent Camel DSL but it useful for tooling to understand the structure of the routes and how EIPs are nested together. You can also use png to save route diagrams as PNG image files either all combined in a single file (default camel-route-diagrams.png) or to a given folder, where routes are grouped by source file name(s) and saved as corresponding .png files. This requires to have camel-diagram on the classpath to be able to render PNG diagrams.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "enum", "javaType": "java.lang.String", "secret": false, "enum": [ "xml", "yaml", "json", "png" ] },
{ "name": "camel.main.dumpRoutesGeneratedIds", "required": false, "description": "Whether to include auto generated IDs in the dumped output. Default is false.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": false, "secret": false },
{ "name": "camel.main.dumpRoutesInclude", "required": false, "description": "Controls what to include in output for route dumping. Possible values: all, routes, rests, routeConfigurations, routeTemplates, beans, dataFormats. Multiple values can be separated by comma. Default is routes.", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "string", "javaType": "java.lang.String", "defaultValue": "routes", "secret": false },
{ "name": "camel.main.dumpRoutesLog", "required": false, "description": "Whether to log route dumps to Logger", "sourceType": "org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": true, "secret": false },
Expand Down
Loading
Loading