This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push: new 9a88f03c2a7 Trydebug (#13847) 9a88f03c2a7 is described below commit 9a88f03c2a7bc1d364570585426234b04f2d0e7c Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Thu Apr 18 13:09:18 2024 +0200 Trydebug (#13847) * CAMEL-20685: Tidy up code a little bit * CAMEL-20685: Debugging doTry/doCatch/doFinally needs special logic for debugger to only move into blocks when debugging is accepted. --- .../main/java/org/apache/camel/MessageHistory.java | 12 ++++++++++++ .../src/main/java/org/apache/camel/NamedNode.java | 11 +++++++++++ .../camel/impl/engine/CamelInternalProcessor.java | 16 ++++++++++++---- .../impl/engine/DefaultMessageHistoryFactory.java | 4 +++- .../apache/camel/impl/console/DebugDevConsole.java | 1 + .../java/org/apache/camel/model/CatchDefinition.java | 10 ++++++++++ .../org/apache/camel/model/FinallyDefinition.java | 7 +++++++ .../org/apache/camel/processor/TryProcessor.java | 2 +- .../org/apache/camel/reifier/FinallyReifier.java | 12 +++--------- .../java/org/apache/camel/reifier/TryReifier.java | 11 ++++++----- .../apache/camel/management/mbean/ManagedDoTry.java | 2 +- .../apache/camel/support/DefaultMessageHistory.java | 11 +++++++++++ .../apache/camel/dsl/jbang/core/commands/Debug.java | 20 ++++++++++++-------- 13 files changed, 90 insertions(+), 29 deletions(-) diff --git a/core/camel-api/src/main/java/org/apache/camel/MessageHistory.java b/core/camel-api/src/main/java/org/apache/camel/MessageHistory.java index a86643b7d8d..38a5dbca676 100644 --- a/core/camel-api/src/main/java/org/apache/camel/MessageHistory.java +++ b/core/camel-api/src/main/java/org/apache/camel/MessageHistory.java @@ -58,4 +58,16 @@ public interface MessageHistory { */ Message getMessage(); + /** + * Used specially during debugging where some EIP nodes are not accepted for debugging and are essentially skipped. + * This allows tooling to avoid dumping message history for nodes that did not take part in the debugger. + */ + void setAcceptDebugger(boolean acceptDebugger); + + /** + * Used specially during debugging where some EIP nodes are not accepted for debugging and are essentially skipped. + * This allows tooling to avoid dumping message history for nodes that did not take part in the debugger. + */ + boolean isAcceptDebugger(); + } diff --git a/core/camel-api/src/main/java/org/apache/camel/NamedNode.java b/core/camel-api/src/main/java/org/apache/camel/NamedNode.java index aba445e31d1..f1208427531 100644 --- a/core/camel-api/src/main/java/org/apache/camel/NamedNode.java +++ b/core/camel-api/src/main/java/org/apache/camel/NamedNode.java @@ -54,4 +54,15 @@ public interface NamedNode extends LineNumberAware { */ NamedNode getParent(); + /** + * Whether this node can accept debugging the current exchange. This allows flexibility for some EIPs that need to + * compute whether to accept debugging or not + * + * @param exchange the current exchange + * @return true to accept debugging this node, or false to skip + */ + default boolean acceptDebugger(Exchange exchange) { + return 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 812794723bf..420de0211ec 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 @@ -767,7 +767,10 @@ public class CamelInternalProcessor extends DelegateAsyncProcessor implements In @Override public StopWatch before(Exchange exchange) throws Exception { - return backlogDebugger.beforeProcess(exchange, target, definition); + if (definition.acceptDebugger(exchange)) { + return backlogDebugger.beforeProcess(exchange, target, definition); + } + return null; } @Override @@ -795,13 +798,18 @@ public class CamelInternalProcessor extends DelegateAsyncProcessor implements In @Override public StopWatch before(Exchange exchange) throws Exception { - debugger.beforeProcess(exchange, target, definition); - return new StopWatch(); + if (definition.acceptDebugger(exchange)) { + debugger.beforeProcess(exchange, target, definition); + return new StopWatch(); + } + return null; } @Override public void after(Exchange exchange, StopWatch stopWatch) throws Exception { - debugger.afterProcess(exchange, target, definition, stopWatch.taken()); + if (stopWatch != null) { + debugger.afterProcess(exchange, target, definition, stopWatch.taken()); + } } } diff --git a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultMessageHistoryFactory.java b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultMessageHistoryFactory.java index c3ad60847a1..7f8c361b7e8 100644 --- a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultMessageHistoryFactory.java +++ b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultMessageHistoryFactory.java @@ -63,7 +63,9 @@ public class DefaultMessageHistoryFactory extends ServiceSupport implements Mess msg = exchange.getMessage().copy(); } - return new DefaultMessageHistory(routeId, node, msg); + DefaultMessageHistory answer = new DefaultMessageHistory(routeId, node, msg); + answer.setAcceptDebugger(node.acceptDebugger(exchange)); + return answer; } @ManagedAttribute(description = "Whether message history is enabled") diff --git a/core/camel-console/src/main/java/org/apache/camel/impl/console/DebugDevConsole.java b/core/camel-console/src/main/java/org/apache/camel/impl/console/DebugDevConsole.java index 2d1a542747c..4146bdd1b47 100644 --- a/core/camel-console/src/main/java/org/apache/camel/impl/console/DebugDevConsole.java +++ b/core/camel-console/src/main/java/org/apache/camel/impl/console/DebugDevConsole.java @@ -240,6 +240,7 @@ public class DebugDevConsole extends AbstractDevConsole { jo.put("routeId", h.getRouteId()); } jo.put("elapsed", h.getElapsed()); + jo.put("acceptDebugger", h.isAcceptDebugger()); if (h.getNode() != null) { jo.put("nodeId", h.getNode().getId()); if (h.getNode().getLocation() != null) { diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/CatchDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/CatchDefinition.java index 5b7c03da9c2..e019e3bd61b 100644 --- a/core/camel-core-model/src/main/java/org/apache/camel/model/CatchDefinition.java +++ b/core/camel-core-model/src/main/java/org/apache/camel/model/CatchDefinition.java @@ -26,6 +26,8 @@ import jakarta.xml.bind.annotation.XmlElementRef; import jakarta.xml.bind.annotation.XmlRootElement; import jakarta.xml.bind.annotation.XmlTransient; +import org.apache.camel.Exchange; +import org.apache.camel.ExchangePropertyKey; import org.apache.camel.Predicate; import org.apache.camel.spi.AsPredicate; import org.apache.camel.spi.Metadata; @@ -92,6 +94,14 @@ public class CatchDefinition extends OutputDefinition<CatchDefinition> { this.exceptionClasses = exceptionClasses; } + @Override + public boolean acceptDebugger(Exchange exchange) { + // only accept if not handled by a previous catch clause handled, and that there is an exception + boolean previous = exchange.getProperty(ExchangePropertyKey.EXCEPTION_HANDLED) != null; + final Exception e = exchange.getException(); + return !previous && e != null; + } + // Fluent API // ------------------------------------------------------------------------- diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/FinallyDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/FinallyDefinition.java index 7765809b69f..5b14e241330 100644 --- a/core/camel-core-model/src/main/java/org/apache/camel/model/FinallyDefinition.java +++ b/core/camel-core-model/src/main/java/org/apache/camel/model/FinallyDefinition.java @@ -23,6 +23,7 @@ import jakarta.xml.bind.annotation.XmlAccessorType; import jakarta.xml.bind.annotation.XmlElementRef; import jakarta.xml.bind.annotation.XmlRootElement; +import org.apache.camel.Exchange; import org.apache.camel.spi.Metadata; /** @@ -58,4 +59,10 @@ public class FinallyDefinition extends OutputDefinition<FinallyDefinition> { public void setOutputs(List<ProcessorDefinition<?>> outputs) { super.setOutputs(outputs); } + + @Override + public boolean acceptDebugger(Exchange exchange) { + // we should only debug if there are any outputs in the finally-block + return !getOutputs().isEmpty(); + } } diff --git a/core/camel-core-processor/src/main/java/org/apache/camel/processor/TryProcessor.java b/core/camel-core-processor/src/main/java/org/apache/camel/processor/TryProcessor.java index 8db60f2cfcc..8dd9bd9aefc 100644 --- a/core/camel-core-processor/src/main/java/org/apache/camel/processor/TryProcessor.java +++ b/core/camel-core-processor/src/main/java/org/apache/camel/processor/TryProcessor.java @@ -160,7 +160,7 @@ public class TryProcessor extends AsyncProcessorSupport implements Navigate<Proc if (tryProcessor != null) { answer.add(tryProcessor); } - if (catchClauses != null) { + if (catchClauses != null && !catchClauses.isEmpty()) { answer.addAll(catchClauses); } if (finallyProcessor != null) { diff --git a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/FinallyReifier.java b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/FinallyReifier.java index 8eac51e20a6..b53028f8a3f 100644 --- a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/FinallyReifier.java +++ b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/FinallyReifier.java @@ -22,8 +22,6 @@ import org.apache.camel.model.FinallyDefinition; import org.apache.camel.model.ProcessorDefinition; import org.apache.camel.model.TryDefinition; import org.apache.camel.processor.FinallyProcessor; -import org.apache.camel.spi.IdAware; -import org.apache.camel.spi.RouteIdAware; public class FinallyReifier extends ProcessorReifier<FinallyDefinition> { @@ -41,13 +39,9 @@ public class FinallyReifier extends ProcessorReifier<FinallyDefinition> { // do finally does mandate a child processor FinallyProcessor processor = new FinallyProcessor(this.createChildProcessor(false)); // inject id - if (processor instanceof IdAware) { - String id = getId(definition); - ((IdAware) processor).setId(id); - } - if (processor instanceof RouteIdAware) { - ((RouteIdAware) processor).setRouteId(route.getRouteId()); - } + String id = getId(definition); + processor.setId(id); + processor.setRouteId(route.getRouteId()); return wrapProcessor(processor); } diff --git a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/TryReifier.java b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/TryReifier.java index f4aa1697c50..197df107f96 100644 --- a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/TryReifier.java +++ b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/TryReifier.java @@ -47,6 +47,12 @@ public class TryReifier extends ProcessorReifier<TryDefinition> { } } + // user must have configured at least one catch or finally + if (definition.getFinallyClause() == null && definition.getCatchClauses() == null) { + throw new IllegalArgumentException("doTry must have one or more catch or finally blocks on " + this); + } + + // must have finally processor as it set some state after completing the entire doTry block FinallyDefinition finallyDefinition = definition.getFinallyClause(); if (finallyDefinition == null) { finallyDefinition = new FinallyDefinition(); @@ -54,11 +60,6 @@ public class TryReifier extends ProcessorReifier<TryDefinition> { } Processor finallyProcessor = createProcessor(finallyDefinition); - // must have either a catch or finally - if (definition.getFinallyClause() == null && definition.getCatchClauses() == null) { - throw new IllegalArgumentException("doTry must have one or more catch or finally blocks on " + this); - } - return new TryProcessor(camelContext, tryProcessor, catchProcessors, finallyProcessor); } diff --git a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedDoTry.java b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedDoTry.java index c05e7b856d0..f126eff9cea 100644 --- a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedDoTry.java +++ b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedDoTry.java @@ -48,7 +48,7 @@ public class ManagedDoTry extends ManagedProcessor implements ManagedDoTryMBean super(context, processor, definition); this.processor = processor; - if (processor.getCatchClauses() != null) { + if (processor.getCatchClauses() != null && !processor.getCatchClauses().isEmpty()) { catchProcessors = new ArrayList<>(); for (Processor p : processor.getCatchClauses()) { Channel c = (Channel) p; diff --git a/core/camel-support/src/main/java/org/apache/camel/support/DefaultMessageHistory.java b/core/camel-support/src/main/java/org/apache/camel/support/DefaultMessageHistory.java index dc4b6edd4b2..936058103c4 100644 --- a/core/camel-support/src/main/java/org/apache/camel/support/DefaultMessageHistory.java +++ b/core/camel-support/src/main/java/org/apache/camel/support/DefaultMessageHistory.java @@ -30,6 +30,7 @@ public class DefaultMessageHistory implements MessageHistory { private final String nodeId; private final MonotonicClock clock = new MonotonicClock(); private final Message message; + private boolean acceptDebugger; private long elapsed; public DefaultMessageHistory(String routeId, NamedNode node) { @@ -73,6 +74,16 @@ public class DefaultMessageHistory implements MessageHistory { return message; } + @Override + public void setAcceptDebugger(boolean acceptDebugger) { + this.acceptDebugger = acceptDebugger; + } + + @Override + public boolean isAcceptDebugger() { + return acceptDebugger; + } + @Override public String toString() { return "DefaultMessageHistory[" 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 4a76e5251c1..702489f69e5 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 @@ -407,14 +407,18 @@ public class Debug extends Run { lines = jo.getCollection("history"); if (lines != null) { for (JsonObject line : lines) { - History history = new History(); - history.routeId = line.getString("routeId"); - history.nodeId = line.getString("nodeId"); - history.elapsed = line.getLongOrDefault("elapsed", 0); - history.location = line.getString("location"); - history.line = line.getIntegerOrDefault("line", -1); - history.code = line.getString("code"); - row.history.add(history); + // only include if accepted for debugging + boolean accept = line.getBooleanOrDefault("acceptDebugger", true); + if (accept) { + History history = new History(); + history.routeId = line.getString("routeId"); + history.nodeId = line.getString("nodeId"); + history.elapsed = line.getLongOrDefault("elapsed", 0); + history.location = line.getString("location"); + history.line = line.getIntegerOrDefault("line", -1); + history.code = line.getString("code"); + row.history.add(history); + } } } rows.add(row);