From 400db385a3f8bdd6a130d1670857e5ee25e36b20 Mon Sep 17 00:00:00 2001 From: Claus Ibsen Date: Sun, 11 Feb 2024 12:16:08 +0100 Subject: [PATCH] Var trace (#13088) CAMEL-20408: camel-core - Tracer should include exchange variables --- .../camel-main-configuration-metadata.json | 1 + .../camel/component/stub/StubConsole.java | 2 +- .../org/apache/camel/spi/BacklogDebugger.java | 10 ++ .../org/apache/camel/spi/BacklogTracer.java | 10 ++ .../camel/impl/debugger/BacklogTracer.java | 11 ++ .../impl/debugger/DefaultBacklogDebugger.java | 15 ++- .../impl/engine/CamelInternalProcessor.java | 14 ++- ...ggerConfigurationPropertiesConfigurer.java | 6 + .../camel-main-configuration-metadata.json | 1 + core/camel-main/src/main/docs/main.adoc | 3 +- .../apache/camel/main/BaseMainSupport.java | 1 + .../main/DebuggerConfigurationProperties.java | 21 ++++ .../mbean/ManagedBacklogDebuggerMBean.java | 6 + .../mbean/ManagedBacklogTracerMBean.java | 12 +- .../mbean/ManagedBacklogDebugger.java | 10 ++ .../mbean/ManagedBacklogTracer.java | 10 ++ .../apache/camel/support/MessageHelper.java | 114 ++++++++++++++---- docs/components/modules/others/nav.adoc | 1 + .../modules/others/pages/kotlin-api.adoc | 1 + .../modules/ROOT/pages/backlog-debugger.adoc | 1 + .../modules/ROOT/pages/backlog-tracer.adoc | 2 + .../cli/connector/LocalCliConnector.java | 4 +- .../camel/dsl/jbang/core/commands/Debug.java | 5 + .../commands/action/MessageTableHelper.java | 38 ++++-- 24 files changed, 256 insertions(+), 43 deletions(-) create mode 120000 docs/components/modules/others/pages/kotlin-api.adoc diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json index 099d60d0bcc7a..127e310a2c674 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json @@ -143,6 +143,7 @@ { "name": "camel.debug.fallbackTimeout", "description": "Fallback Timeout in seconds (300 seconds as default) when block the message processing in Camel. A timeout used for waiting for a message to arrive at a given breakpoint.", "sourceType": "org.apache.camel.main.DebuggerConfigurationProperties", "type": "integer", "javaType": "long", "defaultValue": 300 }, { "name": "camel.debug.includeException", "description": "Trace messages to include exception if the message failed", "sourceType": "org.apache.camel.main.DebuggerConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": true }, { "name": "camel.debug.includeExchangeProperties", "description": "Whether to include the exchange properties in the traced message", "sourceType": "org.apache.camel.main.DebuggerConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": true }, + { "name": "camel.debug.includeExchangeVariables", "description": "Whether to include the exchange variables in the traced message", "sourceType": "org.apache.camel.main.DebuggerConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": true }, { "name": "camel.debug.loggingLevel", "description": "The debugger logging level to use when logging activity.", "sourceType": "org.apache.camel.main.DebuggerConfigurationProperties", "type": "object", "javaType": "org.apache.camel.LoggingLevel", "defaultValue": "INFO", "enum": [ "ERROR", "WARN", "INFO", "DEBUG", "TRACE", "OFF" ] }, { "name": "camel.debug.singleStepIncludeStartEnd", "description": "In single step mode, then when the exchange is created and completed, then simulate a breakpoint at start and end, that allows to suspend and watch the incoming\/complete exchange at the route (you can see message body as response, failed exception etc).", "sourceType": "org.apache.camel.main.DebuggerConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": "false" }, { "name": "camel.debug.standby", "description": "To set the debugger in standby mode, where the debugger will be installed by not automatic enabled. The debugger can then later be enabled explicit from Java, JMX or tooling.", "sourceType": "org.apache.camel.main.DebuggerConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": "false" }, diff --git a/components/camel-stub/src/main/java/org/apache/camel/component/stub/StubConsole.java b/components/camel-stub/src/main/java/org/apache/camel/component/stub/StubConsole.java index 4974e752ebe2c..841dbd2c67fe7 100644 --- a/components/camel-stub/src/main/java/org/apache/camel/component/stub/StubConsole.java +++ b/components/camel-stub/src/main/java/org/apache/camel/component/stub/StubConsole.java @@ -165,7 +165,7 @@ protected JsonObject doCallJson(Map options) { for (Exchange exchange : copy) { try { JsonObject msg - = MessageHelper.dumpAsJSonObject(exchange.getMessage(), false, true, true, false, true, + = MessageHelper.dumpAsJSonObject(exchange.getMessage(), false, true, true,true, false, true, 128 * 1024); arr.add(msg); } catch (Exception e) { diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/BacklogDebugger.java b/core/camel-api/src/main/java/org/apache/camel/spi/BacklogDebugger.java index b8582c98f1230..19d1b601b18e8 100644 --- a/core/camel-api/src/main/java/org/apache/camel/spi/BacklogDebugger.java +++ b/core/camel-api/src/main/java/org/apache/camel/spi/BacklogDebugger.java @@ -352,6 +352,16 @@ void setExchangePropertyOnBreakpoint(String nodeId, String exchangePropertyName, */ void setIncludeExchangeProperties(boolean includeExchangeProperties); + /** + * Whether to include the exchange variables in the traced message + */ + boolean isIncludeExchangeVariables(); + + /** + * Whether to include the exchange variables in the traced message + */ + void setIncludeExchangeVariables(boolean includeExchangeVariables); + /** * Trace messages to include exception if the message failed */ diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/BacklogTracer.java b/core/camel-api/src/main/java/org/apache/camel/spi/BacklogTracer.java index 3c894a95294e0..8e2f6db25ccee 100644 --- a/core/camel-api/src/main/java/org/apache/camel/spi/BacklogTracer.java +++ b/core/camel-api/src/main/java/org/apache/camel/spi/BacklogTracer.java @@ -109,6 +109,16 @@ public interface BacklogTracer { */ void setIncludeExchangeProperties(boolean includeExchangeProperties); + /** + * Trace messages to include exchange variables + */ + boolean isIncludeExchangeVariables(); + + /** + * Trace messages to include exchange variables + */ + void setIncludeExchangeVariables(boolean includeExchangeVariables); + /** * Trace messages to include exception if the message failed */ diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/debugger/BacklogTracer.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/debugger/BacklogTracer.java index a2c3dc003a334..bc49984feefb2 100644 --- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/debugger/BacklogTracer.java +++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/debugger/BacklogTracer.java @@ -61,6 +61,7 @@ public final class BacklogTracer extends ServiceSupport implements org.apache.ca private boolean bodyIncludeStreams; private boolean bodyIncludeFiles = true; private boolean includeExchangeProperties = true; + private boolean includeExchangeVariables = true; private boolean includeException = true; private boolean traceRests; private boolean traceTemplates; @@ -236,6 +237,16 @@ public void setIncludeExchangeProperties(boolean includeExchangeProperties) { this.includeExchangeProperties = includeExchangeProperties; } + @Override + public boolean isIncludeExchangeVariables() { + return includeExchangeVariables; + } + + @Override + public void setIncludeExchangeVariables(boolean includeExchangeVariables) { + this.includeExchangeVariables = includeExchangeVariables; + } + @Override public boolean isIncludeException() { return includeException; diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/debugger/DefaultBacklogDebugger.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/debugger/DefaultBacklogDebugger.java index ddf5dfa51a2e7..93f6e87d5e834 100644 --- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/debugger/DefaultBacklogDebugger.java +++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/debugger/DefaultBacklogDebugger.java @@ -82,6 +82,7 @@ public final class DefaultBacklogDebugger extends ServiceSupport implements Back private boolean bodyIncludeStreams; private boolean bodyIncludeFiles = true; private boolean includeExchangeProperties = true; + private boolean includeExchangeVariables = true; private boolean includeException = true; /** @@ -677,6 +678,16 @@ public void setIncludeExchangeProperties(boolean includeExchangeProperties) { this.includeExchangeProperties = includeExchangeProperties; } + @Override + public boolean isIncludeExchangeVariables() { + return includeExchangeVariables; + } + + @Override + public void setIncludeExchangeVariables(boolean includeExchangeVariables) { + this.includeExchangeVariables = includeExchangeVariables; + } + @Override public boolean isIncludeException() { return includeException; @@ -792,7 +803,7 @@ private void refreshBacklogTracerEventMessage(String nodeId, SuspendedExchange s * @return the XML */ private String dumpAsXml(Exchange exchange) { - return MessageHelper.dumpAsXml(exchange.getIn(), includeExchangeProperties, true, 2, true, + return MessageHelper.dumpAsXml(exchange.getIn(), includeExchangeProperties, includeExchangeVariables, true, 2, true, isBodyIncludeStreams(), isBodyIncludeFiles(), getBodyMaxChars()); } @@ -804,7 +815,7 @@ private String dumpAsXml(Exchange exchange) { * @return the JSon */ private String dumpAsJSon(Exchange exchange) { - return MessageHelper.dumpAsJSon(exchange.getIn(), includeExchangeProperties, true, 2, true, + return MessageHelper.dumpAsJSon(exchange.getIn(), includeExchangeProperties, includeExchangeVariables, true, 2, true, isBodyIncludeStreams(), isBodyIncludeFiles(), getBodyMaxChars(), true); } diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/CamelInternalProcessor.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/CamelInternalProcessor.java index f1560cf6122a2..9823a00f2f9ad 100644 --- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/CamelInternalProcessor.java +++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/CamelInternalProcessor.java @@ -636,10 +636,13 @@ public DefaultBacklogTracerEventMessage before(Exchange exchange) throws Excepti String toNode = processorDefinition.getId(); String exchangeId = exchange.getExchangeId(); boolean includeExchangeProperties = backlogTracer.isIncludeExchangeProperties(); - String messageAsXml = MessageHelper.dumpAsXml(exchange.getIn(), includeExchangeProperties, true, 4, + boolean includeExchangeVariables = backlogTracer.isIncludeExchangeVariables(); + String messageAsXml = MessageHelper.dumpAsXml(exchange.getIn(), includeExchangeProperties, + includeExchangeVariables, true, 4, true, backlogTracer.isBodyIncludeStreams(), backlogTracer.isBodyIncludeFiles(), backlogTracer.getBodyMaxChars()); - String messageAsJSon = MessageHelper.dumpAsJSon(exchange.getIn(), includeExchangeProperties, true, 4, + String messageAsJSon = MessageHelper.dumpAsJSon(exchange.getIn(), includeExchangeProperties, + includeExchangeVariables, true, 4, true, backlogTracer.isBodyIncludeStreams(), backlogTracer.isBodyIncludeFiles(), backlogTracer.getBodyMaxChars(), true); @@ -675,12 +678,15 @@ public void onDone(Exchange exchange) { String routeId = routeDefinition != null ? routeDefinition.getRouteId() : null; String exchangeId = exchange.getExchangeId(); boolean includeExchangeProperties = backlogTracer.isIncludeExchangeProperties(); + boolean includeExchangeVariables = backlogTracer.isIncludeExchangeVariables(); long created = exchange.getClock().getCreated(); - String messageAsXml = MessageHelper.dumpAsXml(exchange.getIn(), includeExchangeProperties, true, 4, + String messageAsXml = MessageHelper.dumpAsXml(exchange.getIn(), includeExchangeProperties, + includeExchangeVariables, true, 4, true, backlogTracer.isBodyIncludeStreams(), backlogTracer.isBodyIncludeFiles(), backlogTracer.getBodyMaxChars()); String messageAsJSon - = MessageHelper.dumpAsJSon(exchange.getIn(), includeExchangeProperties, true, 4, + = MessageHelper.dumpAsJSon(exchange.getIn(), includeExchangeProperties, includeExchangeVariables, + true, 4, true, backlogTracer.isBodyIncludeStreams(), backlogTracer.isBodyIncludeFiles(), backlogTracer.getBodyMaxChars(), true); DefaultBacklogTracerEventMessage pseudoLast = new DefaultBacklogTracerEventMessage( diff --git a/core/camel-main/src/generated/java/org/apache/camel/main/DebuggerConfigurationPropertiesConfigurer.java b/core/camel-main/src/generated/java/org/apache/camel/main/DebuggerConfigurationPropertiesConfigurer.java index c9b2f6c3d9278..b2bf189dfd5da 100644 --- a/core/camel-main/src/generated/java/org/apache/camel/main/DebuggerConfigurationPropertiesConfigurer.java +++ b/core/camel-main/src/generated/java/org/apache/camel/main/DebuggerConfigurationPropertiesConfigurer.java @@ -37,6 +37,8 @@ public boolean configure(CamelContext camelContext, Object obj, String name, Obj case "IncludeException": target.setIncludeException(property(camelContext, boolean.class, value)); return true; case "includeexchangeproperties": case "IncludeExchangeProperties": target.setIncludeExchangeProperties(property(camelContext, boolean.class, value)); return true; + case "includeexchangevariables": + case "IncludeExchangeVariables": target.setIncludeExchangeVariables(property(camelContext, boolean.class, value)); return true; case "logginglevel": case "LoggingLevel": target.setLoggingLevel(property(camelContext, org.apache.camel.LoggingLevel.class, value)); return true; case "singlestepincludestartend": @@ -68,6 +70,8 @@ public Class getOptionType(String name, boolean ignoreCase) { case "IncludeException": return boolean.class; case "includeexchangeproperties": case "IncludeExchangeProperties": return boolean.class; + case "includeexchangevariables": + case "IncludeExchangeVariables": return boolean.class; case "logginglevel": case "LoggingLevel": return org.apache.camel.LoggingLevel.class; case "singlestepincludestartend": @@ -100,6 +104,8 @@ public Object getOptionValue(Object obj, String name, boolean ignoreCase) { case "IncludeException": return target.isIncludeException(); case "includeexchangeproperties": case "IncludeExchangeProperties": return target.isIncludeExchangeProperties(); + case "includeexchangevariables": + case "IncludeExchangeVariables": return target.isIncludeExchangeVariables(); case "logginglevel": case "LoggingLevel": return target.getLoggingLevel(); case "singlestepincludestartend": diff --git a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json index 099d60d0bcc7a..127e310a2c674 100644 --- a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json +++ b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json @@ -143,6 +143,7 @@ { "name": "camel.debug.fallbackTimeout", "description": "Fallback Timeout in seconds (300 seconds as default) when block the message processing in Camel. A timeout used for waiting for a message to arrive at a given breakpoint.", "sourceType": "org.apache.camel.main.DebuggerConfigurationProperties", "type": "integer", "javaType": "long", "defaultValue": 300 }, { "name": "camel.debug.includeException", "description": "Trace messages to include exception if the message failed", "sourceType": "org.apache.camel.main.DebuggerConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": true }, { "name": "camel.debug.includeExchangeProperties", "description": "Whether to include the exchange properties in the traced message", "sourceType": "org.apache.camel.main.DebuggerConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": true }, + { "name": "camel.debug.includeExchangeVariables", "description": "Whether to include the exchange variables in the traced message", "sourceType": "org.apache.camel.main.DebuggerConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": true }, { "name": "camel.debug.loggingLevel", "description": "The debugger logging level to use when logging activity.", "sourceType": "org.apache.camel.main.DebuggerConfigurationProperties", "type": "object", "javaType": "org.apache.camel.LoggingLevel", "defaultValue": "INFO", "enum": [ "ERROR", "WARN", "INFO", "DEBUG", "TRACE", "OFF" ] }, { "name": "camel.debug.singleStepIncludeStartEnd", "description": "In single step mode, then when the exchange is created and completed, then simulate a breakpoint at start and end, that allows to suspend and watch the incoming\/complete exchange at the route (you can see message body as response, failed exception etc).", "sourceType": "org.apache.camel.main.DebuggerConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": "false" }, { "name": "camel.debug.standby", "description": "To set the debugger in standby mode, where the debugger will be installed by not automatic enabled. The debugger can then later be enabled explicit from Java, JMX or tooling.", "sourceType": "org.apache.camel.main.DebuggerConfigurationProperties", "type": "boolean", "javaType": "boolean", "defaultValue": "false" }, diff --git a/core/camel-main/src/main/docs/main.adoc b/core/camel-main/src/main/docs/main.adoc index cc34a460ad75e..c709db4e390ba 100644 --- a/core/camel-main/src/main/docs/main.adoc +++ b/core/camel-main/src/main/docs/main.adoc @@ -187,7 +187,7 @@ The camel.server supports 12 options, which are listed below. === Camel Debugger configurations -The camel.debug supports 12 options, which are listed below. +The camel.debug supports 13 options, which are listed below. [width="100%",cols="2,5,^1,2",options="header"] |=== @@ -200,6 +200,7 @@ The camel.debug supports 12 options, which are listed below. | *camel.debug.fallbackTimeout* | Fallback Timeout in seconds (300 seconds as default) when block the message processing in Camel. A timeout used for waiting for a message to arrive at a given breakpoint. | 300 | long | *camel.debug.includeException* | Trace messages to include exception if the message failed | true | boolean | *camel.debug.includeExchange{zwsp}Properties* | Whether to include the exchange properties in the traced message | true | boolean +| *camel.debug.includeExchange{zwsp}Variables* | Whether to include the exchange variables in the traced message | true | boolean | *camel.debug.loggingLevel* | The debugger logging level to use when logging activity. | INFO | LoggingLevel | *camel.debug.singleStepInclude{zwsp}StartEnd* | In single step mode, then when the exchange is created and completed, then simulate a breakpoint at start and end, that allows to suspend and watch the incoming/complete exchange at the route (you can see message body as response, failed exception etc). | false | boolean | *camel.debug.standby* | To set the debugger in standby mode, where the debugger will be installed by not automatic enabled. The debugger can then later be enabled explicit from Java, JMX or tooling. | false | boolean diff --git a/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java b/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java index 0537932ae48a2..e01c21dc44623 100644 --- a/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java +++ b/core/camel-main/src/main/java/org/apache/camel/main/BaseMainSupport.java @@ -1649,6 +1649,7 @@ private void setDebuggerProperties( debugger.setBodyIncludeStreams(config.isBodyIncludeStreams()); debugger.setBodyIncludeFiles(config.isBodyIncludeFiles()); debugger.setIncludeExchangeProperties(config.isIncludeExchangeProperties()); + debugger.setIncludeExchangeVariables(config.isIncludeExchangeVariables()); debugger.setIncludeException(config.isIncludeException()); debugger.setLoggingLevel(config.getLoggingLevel().name()); debugger.setSuspendMode(config.isWaitForAttach()); diff --git a/core/camel-main/src/main/java/org/apache/camel/main/DebuggerConfigurationProperties.java b/core/camel-main/src/main/java/org/apache/camel/main/DebuggerConfigurationProperties.java index 684e53d68bc5b..931ce75f93005 100644 --- a/core/camel-main/src/main/java/org/apache/camel/main/DebuggerConfigurationProperties.java +++ b/core/camel-main/src/main/java/org/apache/camel/main/DebuggerConfigurationProperties.java @@ -50,6 +50,8 @@ public class DebuggerConfigurationProperties implements BootstrapCloseable { @Metadata(defaultValue = "true") private boolean includeExchangeProperties = true; @Metadata(defaultValue = "true") + private boolean includeExchangeVariables = true; + @Metadata(defaultValue = "true") private boolean includeException = true; @Metadata(label = "advanced", defaultValue = "300") private long fallbackTimeout = 300; @@ -185,6 +187,17 @@ public void setIncludeExchangeProperties(boolean includeExchangeProperties) { this.includeExchangeProperties = includeExchangeProperties; } + public boolean isIncludeExchangeVariables() { + return includeExchangeVariables; + } + + /** + * Whether to include the exchange variables in the traced message + */ + public void setIncludeExchangeVariables(boolean includeExchangeVariables) { + this.includeExchangeVariables = includeExchangeVariables; + } + public boolean isIncludeException() { return includeException; } @@ -296,6 +309,14 @@ public DebuggerConfigurationProperties withIncludeExchangeProperties(boolean inc return this; } + /** + * Whether to include the exchange variables in the traced message + */ + public DebuggerConfigurationProperties withIncludeExchangeVariables(boolean includeExchangeVariables) { + this.includeExchangeVariables = includeExchangeVariables; + return this; + } + /** * Trace messages to include exception if the message failed */ diff --git a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedBacklogDebuggerMBean.java b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedBacklogDebuggerMBean.java index 3a1dc32a26ce4..783c6a5d2cd29 100644 --- a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedBacklogDebuggerMBean.java +++ b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedBacklogDebuggerMBean.java @@ -137,6 +137,12 @@ public interface ManagedBacklogDebuggerMBean { @ManagedAttribute(description = "Whether to include exchange properties in the trace message.") void setIncludeExchangeProperties(boolean includeExchangeProperties); + @ManagedAttribute(description = "Whether to include exchange variables in the trace message.") + boolean isIncludeExchangeVariables(); + + @ManagedAttribute(description = "Whether to include exchange variables in the trace message.") + void setIncludeExchangeVariables(boolean includeExchangeVariables); + @ManagedOperation(description = "Dumps the messages in XML format from the suspended breakpoint at the given node.") String dumpTracedMessagesAsXml(String nodeId); diff --git a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedBacklogTracerMBean.java b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedBacklogTracerMBean.java index d89f8b63b682d..0f343d4c60c86 100644 --- a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedBacklogTracerMBean.java +++ b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedBacklogTracerMBean.java @@ -93,15 +93,21 @@ public interface ManagedBacklogTracerMBean { @ManagedAttribute(description = "Whether to include exchange properties in the trace message.") boolean isIncludeExchangeProperties(); + @ManagedAttribute(description = "Whether to include exchange properties in the trace message.") + void setIncludeExchangeProperties(boolean includeExchangeProperties); + + @ManagedAttribute(description = "Whether to include exchange variables in the trace message.") + boolean isIncludeExchangeVariables(); + + @ManagedAttribute(description = "Whether to include exchange variables in the trace message.") + void setIncludeExchangeVariables(boolean includeExchangeVariables); + @ManagedAttribute(description = "Whether tracing routes created from Rest DSL.") boolean isTraceRests(); @ManagedAttribute(description = "Whether tracing routes created from route templates or kamelets.") boolean isTraceTemplates(); - @ManagedAttribute(description = "Whether to include exchange properties in the trace message.") - void setIncludeExchangeProperties(boolean includeExchangeProperties); - @ManagedOperation(description = "Dumps the traced messages for the given node or route") List dumpTracedMessages(String nodeOrRouteId); diff --git a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedBacklogDebugger.java b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedBacklogDebugger.java index f5980dced530b..edb5fc411dbfe 100644 --- a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedBacklogDebugger.java +++ b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedBacklogDebugger.java @@ -236,6 +236,16 @@ public void setIncludeExchangeProperties(boolean includeExchangeProperties) { backlogDebugger.setIncludeExchangeProperties(includeExchangeProperties); } + @Override + public boolean isIncludeExchangeVariables() { + return backlogDebugger.isIncludeExchangeVariables(); + } + + @Override + public void setIncludeExchangeVariables(boolean includeExchangeVariables) { + backlogDebugger.setIncludeExchangeVariables(includeExchangeVariables); + } + @Override public boolean isBodyIncludeStreams() { return backlogDebugger.isBodyIncludeStreams(); diff --git a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedBacklogTracer.java b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedBacklogTracer.java index d697e8d79afde..706d6ae5324d0 100644 --- a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedBacklogTracer.java +++ b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedBacklogTracer.java @@ -171,6 +171,16 @@ public void setIncludeExchangeProperties(boolean includeExchangeProperties) { backlogTracer.setIncludeExchangeProperties(includeExchangeProperties); } + @Override + public boolean isIncludeExchangeVariables() { + return backlogTracer.isIncludeExchangeVariables(); + } + + @Override + public void setIncludeExchangeVariables(boolean includeExchangeVariables) { + backlogTracer.setIncludeExchangeVariables(includeExchangeVariables); + } + @Override public boolean isTraceRests() { return backlogTracer.isTraceRests(); diff --git a/core/camel-support/src/main/java/org/apache/camel/support/MessageHelper.java b/core/camel-support/src/main/java/org/apache/camel/support/MessageHelper.java index 4382bb347d45f..e522fbad95ea5 100644 --- a/core/camel-support/src/main/java/org/apache/camel/support/MessageHelper.java +++ b/core/camel-support/src/main/java/org/apache/camel/support/MessageHelper.java @@ -470,15 +470,16 @@ public static String dumpAsXml(Message message, boolean includeBody, int indent) */ public static String dumpAsXml( Message message, boolean includeBody, int indent, boolean allowStreams, boolean allowFiles, int maxChars) { - return dumpAsXml(message, false, includeBody, indent, allowStreams, allowStreams, allowFiles, maxChars); + return dumpAsXml(message, false, false, includeBody, indent, allowStreams, allowStreams, allowFiles, maxChars); } /** * Dumps the message as a generic XML structure. * * @param message the message - * @param includeBody whether or not to include the message body * @param includeExchangeProperties whether or not to include exchange properties + * @param includeExchangeVariables whether or not to include exchange variables + * @param includeBody whether or not to include the message body * @param indent number of spaces to indent * @param allowCachedStreams whether to include message body if they are stream cache based * @param allowStreams whether to include message body if they are stream based @@ -488,8 +489,9 @@ public static String dumpAsXml( * @return the XML */ public static String dumpAsXml( - Message message, boolean includeExchangeProperties, boolean includeBody, int indent, - boolean allowCachedStreams, boolean allowStreams, boolean allowFiles, int maxChars) { + Message message, boolean includeExchangeProperties, boolean includeExchangeVariables, + boolean includeBody, int indent, boolean allowCachedStreams, boolean allowStreams, + boolean allowFiles, int maxChars) { StringBuilder sb = new StringBuilder(); StringBuilder prefix = new StringBuilder(); @@ -504,6 +506,41 @@ public static String dumpAsXml( .append("\" exchangeType=\"").append(exchangeType) .append("\" messageType=\"").append(messageType).append("\">\n"); + // exchange variables + if (includeExchangeVariables && message.getExchange().hasVariables()) { + sb.append(prefix); + sb.append(" \n"); + // sort the exchange variables so they are listed A..Z + Map variables = new TreeMap<>(message.getExchange().getVariables()); + for (Map.Entry entry : variables.entrySet()) { + String key = entry.getKey(); + Object value = entry.getValue(); + String type = ObjectHelper.classCanonicalName(value); + sb.append(prefix); + sb.append(" "); + + // dump value as XML, use Camel type converter to convert to String + if (value != null) { + try { + String xml = extractValueForLogging(value, message, allowCachedStreams, allowStreams, allowFiles, + maxChars); + if (xml != null) { + // must always xml encode + sb.append(StringHelper.xmlEncode(xml)); + } + } catch (Exception e) { + // ignore as the body is for logging purpose + } + } + sb.append("\n"); + } + sb.append(prefix); + sb.append(" \n"); + } // exchange properties if (includeExchangeProperties && message.getExchange().hasProperties()) { sb.append(prefix); @@ -525,12 +562,11 @@ public static String dumpAsXml( } sb.append(">"); - // dump header value as XML, use Camel type converter to convert - // to String + // dump value as XML, use Camel type converter to convert to String if (value != null) { try { - String xml = message.getExchange().getContext().getTypeConverter().tryConvertTo(String.class, - message.getExchange(), value); + String xml = extractValueForLogging(value, message, allowCachedStreams, allowStreams, allowFiles, + maxChars); if (xml != null) { // must always xml encode sb.append(StringHelper.xmlEncode(xml)); @@ -539,7 +575,6 @@ public static String dumpAsXml( // ignore as the body is for logging purpose } } - sb.append("\n"); } sb.append(prefix); @@ -561,12 +596,11 @@ public static String dumpAsXml( } sb.append(">"); - // dump header value as XML, use Camel type converter to convert - // to String + // dump value as XML, use Camel type converter to convert to String if (value != null) { try { - String xml = message.getExchange().getContext().getTypeConverter().tryConvertTo(String.class, - message.getExchange(), value); + String xml = extractValueForLogging(value, message, allowCachedStreams, allowStreams, allowFiles, + maxChars); if (xml != null) { // must always xml encode sb.append(StringHelper.xmlEncode(xml)); @@ -575,7 +609,6 @@ public static String dumpAsXml( // ignore as the body is for logging purpose } } - sb.append("\n"); } sb.append(prefix); @@ -859,7 +892,7 @@ public static String dumpAsJSon(Message message, boolean includeBody, int indent public static String dumpAsJSon( Message message, boolean includeBody, int indent, boolean allowStreams, boolean allowFiles, int maxChars, boolean pretty) { - return dumpAsJSon(message, false, includeBody, indent, false, allowStreams, allowFiles, maxChars, pretty); + return dumpAsJSon(message, false, false, includeBody, indent, false, allowStreams, allowFiles, maxChars, pretty); } /** @@ -867,6 +900,7 @@ public static String dumpAsJSon( * * @param message the message * @param includeExchangeProperties whether or not to include exchange properties + * @param includeExchangeVariables whether or not to include exchange variables * @param includeBody whether or not to include the message body * @param indent number of spaces to indent * @param allowCachedStreams whether to include message body if they are stream cached based @@ -878,10 +912,12 @@ public static String dumpAsJSon( * @return the JSon */ public static String dumpAsJSon( - Message message, boolean includeExchangeProperties, boolean includeBody, int indent, + Message message, boolean includeExchangeProperties, boolean includeExchangeVariables, boolean includeBody, + int indent, boolean allowCachedStreams, boolean allowStreams, boolean allowFiles, int maxChars, boolean pretty) { - JsonObject jo = dumpAsJSonObject(message, includeExchangeProperties, includeBody, allowCachedStreams, allowStreams, + JsonObject jo = dumpAsJSonObject(message, includeExchangeProperties, includeExchangeVariables, includeBody, + allowCachedStreams, allowStreams, allowFiles, maxChars); String answer = jo.toJson(); if (pretty) { @@ -899,6 +935,7 @@ public static String dumpAsJSon( * * @param message the message * @param includeExchangeProperties whether or not to include exchange properties + * @param includeExchangeVariables whether or not to include exchange variables * @param includeBody whether or not to include the message body * @param allowCachedStreams whether to include message body if they are stream cached based * @param allowStreams whether to include message body if they are stream based @@ -908,7 +945,7 @@ public static String dumpAsJSon( * @return the JSon Object */ public static JsonObject dumpAsJSonObject( - Message message, boolean includeExchangeProperties, boolean includeBody, + Message message, boolean includeExchangeProperties, boolean includeExchangeVariables, boolean includeBody, boolean allowCachedStreams, boolean allowStreams, boolean allowFiles, int maxChars) { JsonObject root = new JsonObject(); @@ -919,6 +956,41 @@ public static JsonObject dumpAsJSonObject( jo.put("exchangeType", ObjectHelper.classCanonicalName(message.getExchange())); jo.put("messageType", ObjectHelper.classCanonicalName(message)); + // exchange variables + if (includeExchangeVariables && message.getExchange().hasVariables()) { + JsonArray arr = new JsonArray(); + // sort the exchange variables so they are listed A..Z + Map properties = new TreeMap<>(message.getExchange().getVariables()); + for (Map.Entry entry : properties.entrySet()) { + Object value = entry.getValue(); + String type = ObjectHelper.classCanonicalName(value); + JsonObject jh = new JsonObject(); + String key = entry.getKey(); + jh.put("key", key); + if (type != null) { + jh.put("type", type); + } + if (value != null) { + Object s = Jsoner.trySerialize(value); + if (s == null) { + // cannot JSon serialize out of the box, so we need to use string value + try { + s = extractValueForLogging(value, message, allowCachedStreams, allowStreams, allowFiles, maxChars); + } catch (Exception e) { + // ignore + } + } else { + // use the value as-is because it can be serialized in json + s = value; + } + jh.put("value", s); + } + arr.add(jh); + } + if (!arr.isEmpty()) { + jo.put("exchangeVariables", arr); + } + } // exchange properties if (includeExchangeProperties && message.getExchange().hasProperties()) { JsonArray arr = new JsonArray(); @@ -942,8 +1014,7 @@ public static JsonObject dumpAsJSonObject( if (s == null) { // cannot JSon serialize out of the box, so we need to use string value try { - s = message.getExchange().getContext().getTypeConverter().tryConvertTo(String.class, - message.getExchange(), value); + s = extractValueForLogging(value, message, allowCachedStreams, allowStreams, allowFiles, maxChars); } catch (Exception e) { // ignore } @@ -978,8 +1049,7 @@ public static JsonObject dumpAsJSonObject( if (s == null) { // cannot JSon serialize out of the box, so we need to use string value try { - s = message.getExchange().getContext().getTypeConverter().tryConvertTo(String.class, - message.getExchange(), value); + s = extractValueForLogging(value, message, allowCachedStreams, allowStreams, allowFiles, maxChars); } catch (Exception e) { // ignore } diff --git a/docs/components/modules/others/nav.adoc b/docs/components/modules/others/nav.adoc index 84815e5fa037f..eadda6ee2ae62 100644 --- a/docs/components/modules/others/nav.adoc +++ b/docs/components/modules/others/nav.adoc @@ -18,6 +18,7 @@ *** xref:jsh-dsl.adoc[JavaShell DSL] *** xref:java-xml-jaxb-dsl.adoc[Jaxb XML Dsl] *** xref:kamelet-main.adoc[Kamelet Main] +*** xref:kotlin-api.adoc[Kotlin API] *** xref:kotlin-dsl.adoc[Kotlin DSL] *** xref:java-xml-io-dsl.adoc[XML Io Dsl] *** xref:yaml-dsl.adoc[YAML DSL] diff --git a/docs/components/modules/others/pages/kotlin-api.adoc b/docs/components/modules/others/pages/kotlin-api.adoc new file mode 120000 index 0000000000000..46b678a5edc08 --- /dev/null +++ b/docs/components/modules/others/pages/kotlin-api.adoc @@ -0,0 +1 @@ +../../../../../dsl/camel-kotlin-api/src/main/docs/kotlin-api.adoc \ No newline at end of file diff --git a/docs/user-manual/modules/ROOT/pages/backlog-debugger.adoc b/docs/user-manual/modules/ROOT/pages/backlog-debugger.adoc index 5af57f5f8f017..31ba85778b7d7 100644 --- a/docs/user-manual/modules/ROOT/pages/backlog-debugger.adoc +++ b/docs/user-manual/modules/ROOT/pages/backlog-debugger.adoc @@ -23,6 +23,7 @@ NOTE: This requires to enabled JMX by including `camel-management` JAR in the cl |`bodyIncludeStreams` |`false` |Whether to include the message body of stream based messages. If enabled then beware the stream may not be re-readable later. See more about Stream Caching. |`bodyMaxChars` |`128kb` |To limit the message body to a maximum size in the traced message. Use 0 or negative value to use unlimited size. |`includeExchangeProperties` |`true`|Whether to include the exchange properties in the traced message. +|`includeExchangeVariables` |`true`|Whether to include the exchange variables in the traced message. |`standby` | `false` |Whether the debugger is standby. If a debugger is in standby then the debugger is activated during startup and are ready to be enabled manually via JMX or calling the enableDebugger method. |`enabled` |`false` |Whether the debugger is enabled or not. |`singleStepMode` |`false` |Whether currently in single step mode of a single Exchange. diff --git a/docs/user-manual/modules/ROOT/pages/backlog-tracer.adoc b/docs/user-manual/modules/ROOT/pages/backlog-tracer.adoc index 9a3dd86686af4..03710e385d7e1 100644 --- a/docs/user-manual/modules/ROOT/pages/backlog-tracer.adoc +++ b/docs/user-manual/modules/ROOT/pages/backlog-tracer.adoc @@ -68,6 +68,8 @@ is that the file content has to be read from the file. |includeExchangeProperties |`true` |Trace messages to include exchange properties. +|includeExchangeVariables |`true` |Trace messages to include exchange variables. + |includeException |`true` |Trace messages to include exception if the message failed. |=== 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 bf2f3cacfc893..84183c072c3aa 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 @@ -476,7 +476,7 @@ private void doActionTransformTask(JsonObject root) throws Exception { jo.put("elapsed", watch.taken()); jo.put("status", "success"); // avoid double wrap - jo.put("message", MessageHelper.dumpAsJSonObject(out.getMessage(), true, true, true, true, true, + jo.put("message", MessageHelper.dumpAsJSonObject(out.getMessage(), true, true, true, true, true, true, BODY_MAX_CHARS).getMap("message")); IOHelper.writeText(jo.toJson(), outputFile); } @@ -581,7 +581,7 @@ public void process(Exchange exchange) throws Exception { jo.put("elapsed", watch.taken()); jo.put("status", "success"); // avoid double wrap - jo.put("message", MessageHelper.dumpAsJSonObject(out.getMessage(), true, true, true, true, true, + jo.put("message", MessageHelper.dumpAsJSonObject(out.getMessage(), true, true, true, true, true, true, BODY_MAX_CHARS).getMap("message")); IOHelper.writeText(jo.toJson(), outputFile); } else { diff --git a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Debug.java b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Debug.java index 3b06cb2d85283..c5e063d8b1e59 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Debug.java +++ b/dsl/camel-jbang/camel-jbang-core/src/main/java/org/apache/camel/dsl/jbang/core/commands/Debug.java @@ -91,6 +91,10 @@ public class Debug extends Run { description = "Show exchange properties in traced messages") boolean showExchangeProperties; + @CommandLine.Option(names = { "--show-exchange-variables" }, defaultValue = "false", + description = "Show exchange variables in traced messages") + boolean showExchangeVariables; + @CommandLine.Option(names = { "--show-headers" }, defaultValue = "true", description = "Show message headers in traced messages") boolean showHeaders = true; @@ -142,6 +146,7 @@ public Integer doCall() throws Exception { tableHelper.setPretty(pretty); tableHelper.setLoggingColor(loggingColor); tableHelper.setShowExchangeProperties(showExchangeProperties); + tableHelper.setShowExchangeVariables(showExchangeVariables); // read log input final AtomicBoolean quit = new AtomicBoolean(); 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 bf2b88dfcc6fa..96731766e93d0 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 @@ -43,6 +43,7 @@ public interface ColorChooser { private boolean loggingColor; private boolean pretty; private boolean showExchangeProperties; + private boolean showExchangeVariables; private ColorChooser exchangeIdColorChooser; public boolean isLoggingColor() { @@ -69,6 +70,14 @@ public void setShowExchangeProperties(boolean showExchangeProperties) { this.showExchangeProperties = showExchangeProperties; } + public boolean isShowExchangeVariables() { + return showExchangeVariables; + } + + public void setShowExchangeVariables(boolean showExchangeVariables) { + this.showExchangeVariables = showExchangeVariables; + } + public ColorChooser getExchangeIdColorChooser() { return exchangeIdColorChooser; } @@ -96,7 +105,7 @@ public String getDataAsTable( eRow = new TableRow("Endpoint", null, null, endpoint.getString("endpoint")); tab0 = AsciiTable.getTable(AsciiTable.NO_BORDERS, List.of(eRow), Arrays.asList( new Column().dataAlign(HorizontalAlign.LEFT) - .minWidth(showExchangeProperties ? 12 : 10).with(TableRow::kindAsString), + .minWidth(showExchangeProperties || showExchangeVariables ? 12 : 10).with(TableRow::kindAsString), new Column().dataAlign(HorizontalAlign.LEFT).with(TableRow::valueAsString))); } @@ -104,15 +113,23 @@ public String getDataAsTable( eRow = new TableRow("Exchange", root.getString("exchangeType"), exchangePattern, exchangeId); tab1 = AsciiTable.getTable(AsciiTable.NO_BORDERS, List.of(eRow), Arrays.asList( new Column().dataAlign(HorizontalAlign.LEFT) - .minWidth(showExchangeProperties ? 12 : 10).with(TableRow::kindAsString), + .minWidth(showExchangeProperties || showExchangeVariables ? 12 : 10).with(TableRow::kindAsString), new Column().dataAlign(HorizontalAlign.LEFT).with(TableRow::typeAsString))); tab1b = AsciiTable.getTable(AsciiTable.NO_BORDERS, List.of(eRow), Arrays.asList( new Column().dataAlign(HorizontalAlign.CENTER) .minWidth(18).maxWidth(18).with(TableRow::mepAsKey), new Column().dataAlign(HorizontalAlign.RIGHT) .maxWidth(80).with(TableRow::exchangeIdAsValue))); + // exchange variables + JsonArray arr = root.getCollection("exchangeVariables"); + if (arr != null) { + for (Object o : arr) { + JsonObject jo = (JsonObject) o; + rows.add(new TableRow("Variable", jo.getString("type"), jo.getString("key"), jo.get("value"))); + } + } // exchange properties - JsonArray arr = root.getCollection("exchangeProperties"); + arr = root.getCollection("exchangeProperties"); if (arr != null) { for (Object o : arr) { JsonObject jo = (JsonObject) o; @@ -129,7 +146,7 @@ public String getDataAsTable( } tab2 = AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, Arrays.asList( new Column().dataAlign(HorizontalAlign.LEFT) - .minWidth(showExchangeProperties ? 12 : 10).with(TableRow::kindAsString), + .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) @@ -142,7 +159,7 @@ public String getDataAsTable( 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 ? 12 : 10).with(TableRow::kindAsString), + .minWidth(showExchangeProperties || showExchangeVariables ? 12 : 10).with(TableRow::kindAsString), new Column().dataAlign(HorizontalAlign.LEFT).with(TableRow::typeAsString))); arr = root.getCollection("headers"); if (arr != null) { @@ -154,7 +171,7 @@ public String getDataAsTable( // headers tab4 = AsciiTable.getTable(AsciiTable.NO_BORDERS, rows, Arrays.asList( new Column().dataAlign(HorizontalAlign.LEFT) - .minWidth(showExchangeProperties ? 12 : 10).with(TableRow::kindAsString), + .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) @@ -169,7 +186,8 @@ public String getDataAsTable( "Body", jo.getString("type"), null, jo.get("value"), jo.getLong("size"), jo.getLong("position")); tab5 = AsciiTable.getTable(AsciiTable.NO_BORDERS, List.of(bodyRow), Arrays.asList( new Column().dataAlign(HorizontalAlign.LEFT) - .minWidth(showExchangeProperties ? 12 : 10).with(TableRow::kindAsString), + .minWidth(showExchangeProperties || showExchangeVariables ? 12 : 10) + .with(TableRow::kindAsString), new Column().dataAlign(HorizontalAlign.LEFT).with(TableRow::typeAndLengthAsString))); // body value only (span) if (bodyRow.value != null) { @@ -185,7 +203,7 @@ public String getDataAsTable( eRow = new TableRow("Exception", cause.getString("type"), null, cause.get("message")); tab7 = AsciiTable.getTable(AsciiTable.NO_BORDERS, List.of(eRow), Arrays.asList( new Column().dataAlign(HorizontalAlign.LEFT) - .minWidth(showExchangeProperties ? 12 : 10) + .minWidth(showExchangeProperties || showExchangeVariables ? 12 : 10) .with(TableRow::kindAsStringRed), new Column().dataAlign(HorizontalAlign.LEFT) .maxWidth(40, OverflowBehaviour.CLIP_LEFT).with(TableRow::typeAsString), @@ -302,6 +320,8 @@ String typeAsString() { s = type.substring(10); } else if (type.startsWith("org.apache.camel.support.")) { s = type.substring(25); + } else if (type.equals("org.apache.camel.converter.stream.CachedOutputStream.WrappedInputStream")) { + s = "WrappedInputStream"; } else if (type.startsWith("org.apache.camel.converter.stream.")) { s = type.substring(34); } else if (type.length() > 34) { @@ -331,6 +351,8 @@ String typeAndLengthAsString() { s = type.substring(10); } else if (type.startsWith("org.apache.camel.support.")) { s = type.substring(25); + } else if (type.equals("org.apache.camel.converter.stream.CachedOutputStream.WrappedInputStream")) { + s = "WrappedInputStream"; } else if (type.startsWith("org.apache.camel.converter.stream.")) { s = type.substring(34); } else {