This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch brow in repository https://gitbox.apache.org/repos/asf/camel.git
commit 437e1fcd38453df075046d3f10f03e779230f74f Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Mon Sep 9 10:54:54 2024 +0200 CAMEL-21183: BrowseEndpoint should have limit/filter to optimize returned data from component implementations --- .../camel/impl/console/BrowseDevConsole.java | 16 +++++-- .../camel/cli/connector/LocalCliConnector.java | 16 ++++--- .../core/commands/action/CamelBrowseAction.java | 41 +++++++++++----- .../core/commands/action/MessageTableHelper.java | 55 ++++++++++++---------- 4 files changed, 83 insertions(+), 45 deletions(-) diff --git a/core/camel-console/src/main/java/org/apache/camel/impl/console/BrowseDevConsole.java b/core/camel-console/src/main/java/org/apache/camel/impl/console/BrowseDevConsole.java index eca24510fe6..7d1507e4ea0 100644 --- a/core/camel-console/src/main/java/org/apache/camel/impl/console/BrowseDevConsole.java +++ b/core/camel-console/src/main/java/org/apache/camel/impl/console/BrowseDevConsole.java @@ -60,6 +60,11 @@ public class BrowseDevConsole extends AbstractDevConsole { */ public static final String INCLUDE_BODY = "includeBody"; + /** + * Maximum size of the message body to include in the dump + */ + public static final String BODY_MAX_CHARS = "bodyMaxChars"; + @Metadata(defaultValue = "32768", description = "Maximum size of the message body to include in the dump") private int bodyMaxChars = 32 * 1024; @@ -93,6 +98,7 @@ public class BrowseDevConsole extends AbstractDevConsole { final int max = lim == null ? limit : Integer.parseInt(lim); boolean dump = "true".equals(options.getOrDefault(DUMP, "true")); boolean includeBody = "true".equals(options.getOrDefault(INCLUDE_BODY, "true")); + int maxChars = Integer.parseInt((String) options.getOrDefault(BODY_MAX_CHARS, "" + bodyMaxChars)); Collection<Endpoint> endpoints = new TreeSet<>(Comparator.comparing(Endpoint::getEndpointUri)); endpoints.addAll(getCamelContext().getEndpoints()); @@ -102,12 +108,12 @@ public class BrowseDevConsole extends AbstractDevConsole { List<Exchange> list = be.getExchanges(max, null); if (list != null) { sb.append("\n"); - sb.append(String.format("Browse: %s (size: %d)%n", endpoint.getEndpointUri(), max)); + sb.append(String.format("Browse: %s (size: %d limit: %d)%n", endpoint.getEndpointUri(), list.size(), max)); if (dump) { for (Exchange e : list) { String json = MessageHelper.dumpAsJSon(e.getMessage(), false, false, includeBody, 2, true, true, true, - bodyMaxChars, true); + maxChars, true); sb.append(json); sb.append("\n"); } @@ -130,6 +136,7 @@ public class BrowseDevConsole extends AbstractDevConsole { final int max = lim == null ? limit : Integer.parseInt(lim); boolean dump = "true".equals(options.getOrDefault(DUMP, "true")); boolean includeBody = "true".equals(options.getOrDefault(INCLUDE_BODY, "true")); + int maxChars = Integer.parseInt((String) options.getOrDefault(BODY_MAX_CHARS, "" + bodyMaxChars)); Collection<Endpoint> endpoints = new TreeSet<>(Comparator.comparing(Endpoint::getEndpointUri)); endpoints.addAll(getCamelContext().getEndpoints()); @@ -140,13 +147,14 @@ public class BrowseDevConsole extends AbstractDevConsole { if (list != null) { JsonObject jo = new JsonObject(); jo.put("endpointUri", endpoint.getEndpointUri()); - jo.put("size", max); + jo.put("queueSize", list.size()); + jo.put("limit", max); arr.add(jo); if (dump) { JsonArray arr2 = new JsonArray(); for (Exchange e : list) { arr2.add(MessageHelper.dumpAsJSonObject(e.getMessage(), false, false, includeBody, true, true, true, - bodyMaxChars)); + maxChars)); } if (!arr2.isEmpty()) { jo.put("messages", arr2); diff --git a/dsl/camel-cli-connector/src/main/java/org/apache/camel/cli/connector/LocalCliConnector.java b/dsl/camel-cli-connector/src/main/java/org/apache/camel/cli/connector/LocalCliConnector.java index c1767158c37..f9663d8f71b 100644 --- a/dsl/camel-cli-connector/src/main/java/org/apache/camel/cli/connector/LocalCliConnector.java +++ b/dsl/camel-cli-connector/src/main/java/org/apache/camel/cli/connector/LocalCliConnector.java @@ -777,13 +777,17 @@ public class LocalCliConnector extends ServiceSupport implements CliConnector, C DevConsole dc = camelContext.getCamelContextExtension().getContextPlugin(DevConsoleRegistry.class) .resolveById("browse"); if (dc != null) { - String filter = root.getString("filter"); - String limit = root.getString("limit"); - String dump = root.getString("dump"); - String includeBody = root.getString("includeBody"); + Map<String, Object> map = new HashMap<>(); + map.put("filter", root.getString("filter")); + map.put("limit", root.getString("limit")); + map.put("dump", root.getString("dump")); + map.put("includeBody", root.getString("includeBody")); + String bodyMaxChars = root.getString("bodyMaxChars"); + if (bodyMaxChars != null) { + map.put("bodyMaxChars", bodyMaxChars); + } JsonObject json - = (JsonObject) dc.call(DevConsole.MediaType.JSON, - Map.of("filter", filter, "limit", limit, "dump", dump, "includeBody", includeBody)); + = (JsonObject) dc.call(DevConsole.MediaType.JSON, map); LOG.trace("Updating output file: {}", outputFile); IOHelper.writeText(json.toJson(), outputFile); } else { diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelBrowseAction.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelBrowseAction.java index 10052052584..56ebf965d17 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelBrowseAction.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/CamelBrowseAction.java @@ -87,6 +87,14 @@ public class CamelBrowseAction extends ActionBaseCommand { description = "Show message body in browsed messages") boolean showBody = true; + @CommandLine.Option(names = { "--only-body" }, defaultValue = "false", + description = "Show only message body in browsed messages") + boolean onlyBody; + + @CommandLine.Option(names = { "--body-max-chars" }, + description = "Maximum size of the message body to include in the dump") + int bodyMaxChars; + @CommandLine.Option(names = { "--logging-color" }, defaultValue = "true", description = "Use colored logging") boolean loggingColor = true; @@ -123,6 +131,9 @@ public class CamelBrowseAction extends ActionBaseCommand { root.put("limit", limit); root.put("dump", dump); root.put("includeBody", showBody); + if (bodyMaxChars > 0) { + root.put("bodyMaxChars", bodyMaxChars); + } File f = getActionFile(Long.toString(pid)); try { @@ -153,7 +164,8 @@ public class CamelBrowseAction extends ActionBaseCommand { for (int i = 0; arr != null && i < arr.size(); i++) { JsonObject o = (JsonObject) arr.get(i); row.uri = o.getString("endpointUri"); - row.size = o.getLong("size"); + row.queueSize = o.getInteger("queueSize"); + row.limit = o.getInteger("limit"); if (dump) { row.messages = o.getCollection("messages"); } @@ -167,7 +179,7 @@ public class CamelBrowseAction extends ActionBaseCommand { rows.sort(this::sortRow); if (dump) { - dumpMessages(rows); + dumpMessages(rows, onlyBody); } else { tableStatus(rows); } @@ -178,7 +190,7 @@ public class CamelBrowseAction extends ActionBaseCommand { return 0; } - protected void dumpMessages(List<Row> rows) { + protected void dumpMessages(List<Row> rows, boolean onlyBody) { MessageTableHelper tableHelper = new MessageTableHelper(); tableHelper.setPretty(pretty); tableHelper.setLoggingColor(loggingColor); @@ -188,14 +200,19 @@ public class CamelBrowseAction extends ActionBaseCommand { if (row.messages != null) { for (int i = 0; i < row.messages.size(); i++) { JsonObject jo = row.messages.get(i); - String exchangeId = jo.getString("exchangeId"); JsonObject message = jo.getMap("message"); - if (!showHeaders && message != null) { + if (onlyBody) { + exchangeId = null; message.remove("headers"); - } - if (!showBody && message != null) { - message.remove("body"); + message.remove("messageType"); + } else { + if (!showHeaders && message != null) { + message.remove("headers"); + } + if (!showBody && message != null) { + message.remove("body"); + } } JsonObject ep = new JsonObject(); ep.put("endpoint", row.uri); @@ -219,7 +236,8 @@ public class CamelBrowseAction extends ActionBaseCommand { .maxWidth(40, OverflowBehaviour.ELLIPSIS_RIGHT) .with(r -> r.name), new Column().header("AGE").headerAlign(HorizontalAlign.CENTER).with(r -> r.ago), - new Column().header("TOTAL").with(r -> "" + r.size), + new Column().header("SIZE").with(r -> "" + r.queueSize), + new Column().header("LIMIT").with(r -> "" + r.limit), new Column().header("ENDPOINT").visible(!wideUri).dataAlign(HorizontalAlign.LEFT) .maxWidth(90, OverflowBehaviour.ELLIPSIS_RIGHT) .with(this::getEndpointUri), @@ -239,7 +257,7 @@ public class CamelBrowseAction extends ActionBaseCommand { case "uri": return o1.uri.compareToIgnoreCase(o2.uri) * negate; case "size": - return Long.compare(o1.size, o2.size) * negate; + return Long.compare(o1.queueSize, o2.queueSize) * negate; default: return 0; } @@ -262,7 +280,8 @@ public class CamelBrowseAction extends ActionBaseCommand { String ago; long uptime; String uri; - long size; + int queueSize; + int limit; List<JsonObject> messages; Row copy() { diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/MessageTableHelper.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/MessageTableHelper.java index 69cce88dc95..ab19131715d 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/MessageTableHelper.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/action/MessageTableHelper.java @@ -174,23 +174,27 @@ public class MessageTableHelper { rows.add(new TableRow("Property", jo.getString("type"), jo.getString("key"), jo.get("value"))); } } - tab2 = AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, Arrays.asList( - new Column().dataAlign(HorizontalAlign.LEFT) - .minWidth(showExchangeProperties || showExchangeVariables ? 12 : 10).with(TableRow::kindAsString), - new Column().dataAlign(HorizontalAlign.LEFT) - .minWidth(25).maxWidth(50, OverflowBehaviour.CLIP_LEFT).with(TableRow::typeAsString), - new Column().dataAlign(HorizontalAlign.RIGHT) - .minWidth(25).maxWidth(40, OverflowBehaviour.NEWLINE).with(TableRow::keyAsString), - new Column().dataAlign(HorizontalAlign.LEFT) - .maxWidth(80, OverflowBehaviour.NEWLINE).with(TableRow::valueAsString))); + if (!rows.isEmpty()) { + tab2 = AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, Arrays.asList( + new Column().dataAlign(HorizontalAlign.LEFT) + .minWidth(showExchangeProperties || showExchangeVariables ? 12 : 10).with(TableRow::kindAsString), + new Column().dataAlign(HorizontalAlign.LEFT) + .minWidth(25).maxWidth(50, OverflowBehaviour.CLIP_LEFT).with(TableRow::typeAsString), + new Column().dataAlign(HorizontalAlign.RIGHT) + .minWidth(25).maxWidth(40, OverflowBehaviour.NEWLINE).with(TableRow::keyAsString), + new Column().dataAlign(HorizontalAlign.LEFT) + .maxWidth(80, OverflowBehaviour.NEWLINE).with(TableRow::valueAsString))); + } rows.clear(); // message type before headers - TableRow msgRow = new TableRow("Message", root.getString("messageType"), null, null); - tab3 = AsciiTable.getTable(AsciiTable.NO_BORDERS, List.of(msgRow), Arrays.asList( - new Column().dataAlign(HorizontalAlign.LEFT) - .minWidth(showExchangeProperties || showExchangeVariables ? 12 : 10).with(TableRow::kindAsString), - new Column().dataAlign(HorizontalAlign.LEFT).with(TableRow::typeAsString))); + if (root.getString("messageType") != null) { + TableRow msgRow = new TableRow("Message", root.getString("messageType"), null, null); + tab3 = AsciiTable.getTable(AsciiTable.NO_BORDERS, List.of(msgRow), Arrays.asList( + new Column().dataAlign(HorizontalAlign.LEFT) + .minWidth(showExchangeProperties || showExchangeVariables ? 12 : 10).with(TableRow::kindAsString), + new Column().dataAlign(HorizontalAlign.LEFT).with(TableRow::typeAsString))); + } arr = root.getCollection("headers"); if (arr != null) { for (Object o : arr) { @@ -198,16 +202,19 @@ public class MessageTableHelper { rows.add(new TableRow("Header", jo.getString("type"), jo.getString("key"), jo.get("value"))); } } - // headers - tab4 = AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, Arrays.asList( - new Column().dataAlign(HorizontalAlign.LEFT) - .minWidth(showExchangeProperties || showExchangeVariables ? 12 : 10).with(TableRow::kindAsString), - new Column().dataAlign(HorizontalAlign.LEFT) - .minWidth(25).maxWidth(50, OverflowBehaviour.CLIP_LEFT).with(TableRow::typeAsString), - new Column().dataAlign(HorizontalAlign.RIGHT) - .minWidth(25).maxWidth(40, OverflowBehaviour.NEWLINE).with(TableRow::keyAsString), - new Column().dataAlign(HorizontalAlign.LEFT) - .maxWidth(80, OverflowBehaviour.NEWLINE).with(TableRow::valueAsString))); + if (!rows.isEmpty()) { + // headers + tab4 = AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, Arrays.asList( + new Column().dataAlign(HorizontalAlign.LEFT) + .minWidth(showExchangeProperties || showExchangeVariables ? 12 : 10).with(TableRow::kindAsString), + new Column().dataAlign(HorizontalAlign.LEFT) + .minWidth(25).maxWidth(50, OverflowBehaviour.CLIP_LEFT).with(TableRow::typeAsString), + new Column().dataAlign(HorizontalAlign.RIGHT) + .minWidth(25).maxWidth(40, OverflowBehaviour.NEWLINE).with(TableRow::keyAsString), + new Column().dataAlign(HorizontalAlign.LEFT) + .maxWidth(80, OverflowBehaviour.NEWLINE).with(TableRow::valueAsString))); + } + rows.clear(); // body and type JsonObject jo = root.getMap("body");