Skip to content

Commit 072590e

Browse files
authored
CAMEL-23385: camel-diagram - Add watch option (#23121)
* CAMEL-23385: camel-diagram - Add watch option * CAMEL-23385: camel-diagram - Auto refresh and remove text tree dump (used internally for testing)
1 parent 7f943d3 commit 072590e

12 files changed

Lines changed: 125 additions & 123 deletions

File tree

catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
{ "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 },
5656
{ "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 },
5757
{ "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" },
58-
{ "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" ] },
58+
{ "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" ] },
5959
{ "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 },
6060
{ "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 },
6161
{ "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 },

components/camel-diagram/src/main/docs/diagram.adoc

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,11 @@
1010
*Since Camel {since}*
1111

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

1615
== Features
1716

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

73-
=== Text diagram
74-
75-
For terminal or log output, generate a text-based tree:
76-
77-
[source,java]
78-
----
79-
List<String> lines = renderer.printTextDiagram(routes);
80-
lines.forEach(System.out::println);
81-
----
82-
8371
=== With Camel JBang
8472

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

10188
Custom colors can be specified using the format:
10289

103-
[source,text]
90+
[source,properties]
10491
----
10592
bg=#1e1e1e:from=#2e7d32:to=#1565c0:eip=#8957e5:choice=#d29922
10693
----
@@ -113,12 +100,3 @@ To use dark theme
113100
----
114101
camel cmd route-diagram MyRoute.java --theme=dark
115102
----
116-
117-
To print textual tree diagram instead of visual
118-
119-
[source,bash]
120-
----
121-
camel cmd route-diagram MyRoute.java --theme=tree
122-
----
123-
124-
TIP: You can also show diagrams for an existing running integration by executing `camel cmd diagram`.

components/camel-diagram/src/main/java/org/apache/camel/diagram/DiagramDevConsole.java

Lines changed: 22 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import java.util.Map;
2121
import java.util.StringJoiner;
2222

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

3837
/**
39-
* Theme to use: dark, light, or text
38+
* Theme to use: dark or light
4039
*/
4140
public static final String THEME = "theme";
4241

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

62+
/**
63+
* Whether to auto-refresh page every 5 seconds
64+
*/
65+
public static final String AUTO_REFRESH = "autoRefresh";
66+
6367
public DiagramDevConsole() {
6468
super("camel", "route-diagram", "Route Diagram", "Visual route diagrams");
6569
}
@@ -76,24 +80,24 @@ protected String doCallText(Map<String, Object> options) {
7680
.parseInt(options.getOrDefault(NODE_WIDTH, "" + RouteDiagramLayoutEngine.DEFAULT_BOX_WIDTH).toString());
7781
String nodeLabel = (String) options.getOrDefault(NODE_LABEL, RouteDiagramDumper.NodeLabelMode.CODE.name());
7882
boolean metric = "true".equalsIgnoreCase((String) options.getOrDefault(METRIC, "true"));
83+
boolean refresh = "true".equalsIgnoreCase((String) options.getOrDefault(AUTO_REFRESH, "true"));
7984

80-
// special for text
81-
if ("text".equalsIgnoreCase(theme)) {
82-
sj.add(renderTextTheme(filter));
83-
} else {
84-
try {
85-
RouteDiagramDumper dumper = PluginHelper.getRouteDiagramDumper(getCamelContext());
86-
BufferedImage image = dumper.dumpRoutesAsImage(filter, RouteDiagramDumper.Theme.valueOf(theme.toUpperCase()),
87-
metric, RouteDiagramDumper.NodeLabelMode.valueOf(nodeLabel.toUpperCase()), nodeWidth, fontSize);
88-
String base64 = dumper.imageToBase64(image);
89-
// For HTML embedding:
90-
String html = String.format(
91-
"<html>\n<body>\n<img src=\"data:image/png;base64,%s\" alt=\"Route Diagram\">\n</body>\n</html>",
92-
base64);
93-
sj.add(html);
94-
} catch (Exception e) {
95-
// ignore
85+
try {
86+
RouteDiagramDumper dumper = PluginHelper.getRouteDiagramDumper(getCamelContext());
87+
BufferedImage image = dumper.dumpRoutesAsImage(filter, RouteDiagramDumper.Theme.valueOf(theme.toUpperCase()),
88+
metric, RouteDiagramDumper.NodeLabelMode.valueOf(nodeLabel.toUpperCase()), nodeWidth, fontSize);
89+
String base64 = dumper.imageToBase64(image);
90+
// For HTML embedding:
91+
String html = String.format(
92+
" <body>\n <img src=\"data:image/png;base64,%s\" alt=\"Route Diagram\">\n </body>\n",
93+
base64);
94+
if (refresh) {
95+
html = "<head><meta http-equiv=\"refresh\" content=\"5\"></head>\n" + html;
9696
}
97+
html = "<html>\n" + html + "</html>\n";
98+
sj.add(html);
99+
} catch (Exception e) {
100+
// ignore
97101
}
98102

99103
return sj.toString();
@@ -124,18 +128,4 @@ protected Map<String, Object> doCallJson(Map<String, Object> options) {
124128
return root;
125129
}
126130

127-
private String renderTextTheme(String filter) {
128-
final StringJoiner sj = new StringJoiner("\n");
129-
130-
org.apache.camel.console.DevConsole dc
131-
= getCamelContext().getCamelContextExtension().getContextPlugin(DevConsoleRegistry.class)
132-
.resolveById("route-structure");
133-
JsonObject root = (JsonObject) dc.call(MediaType.JSON, Map.of("filter", filter));
134-
var routes = RouteDiagramHelper.parseRoutes(root);
135-
RouteDiagramRenderer renderer = new RouteDiagramRenderer();
136-
var lines = renderer.printTextDiagram(routes);
137-
lines.forEach(sj::add);
138-
sj.add("");
139-
return sj.toString();
140-
}
141131
}

components/camel-diagram/src/main/java/org/apache/camel/diagram/RouteDiagramRenderer.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -451,11 +451,17 @@ private Color getNodeColor(String type, DiagramColors colors) {
451451
};
452452
}
453453

454-
public List<String> printTextDiagram(List<RouteInfo> routes) {
454+
/**
455+
* Used for testing
456+
*/
457+
List<String> printTextDiagram(List<RouteInfo> routes) {
455458
return printTextDiagram(routes, RouteDiagramLayoutEngine.NodeLabelMode.CODE);
456459
}
457460

458-
public List<String> printTextDiagram(List<RouteInfo> routes, RouteDiagramLayoutEngine.NodeLabelMode mode) {
461+
/**
462+
* Used for testing
463+
*/
464+
List<String> printTextDiagram(List<RouteInfo> routes, RouteDiagramLayoutEngine.NodeLabelMode mode) {
459465
List<String> lines = new ArrayList<>();
460466
for (RouteInfo route : routes) {
461467
lines.add("");

components/camel-diagram/src/test/java/org/apache/camel/diagram/DiagramDevConsoleTest.java

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
package org.apache.camel.diagram;
1818

1919
import java.util.Base64;
20-
import java.util.Map;
2120

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

77-
@Test
78-
void testTextOutputTextTheme() {
79-
DevConsole console = resolveConsole();
80-
String text = (String) console.call(DevConsole.MediaType.TEXT, Map.of(DiagramDevConsole.THEME, "text"));
81-
assertThat(text).contains("Route: myRoute");
82-
assertThat(text).contains("Route: otherRoute");
83-
assertThat(text).contains("[from]");
84-
assertThat(text).contains("[choice]");
85-
}
86-
8776
@Test
8877
void testJsonOutput() {
8978
System.setProperty("java.awt.headless", "true");

core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
{ "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 },
5656
{ "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 },
5757
{ "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" },
58-
{ "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" ] },
58+
{ "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" ] },
5959
{ "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 },
6060
{ "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 },
6161
{ "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 },

0 commit comments

Comments
 (0)