You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2025/08/04 18:18:43 UTC
(camel) branch main updated: CAMEL-22315: camel-core: Backlog debugger should have skip over step (#18817)
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 671f31bc32b CAMEL-22315: camel-core: Backlog debugger should have skip over step (#18817)
671f31bc32b is described below
commit 671f31bc32b1f464a93b300c10fcf7d5bf735753
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Mon Aug 4 20:18:37 2025 +0200
CAMEL-22315: camel-core: Backlog debugger should have skip over step (#18817)
---
.../java/org/apache/camel/ExchangeConstantProvider.java | 3 ++-
.../src/main/java/org/apache/camel/Exchange.java | 1 +
.../main/java/org/apache/camel/ExchangePropertyKey.java | 3 +++
.../src/main/java/org/apache/camel/MessageHistory.java | 10 ++++++++++
.../main/java/org/apache/camel/spi/BacklogDebugger.java | 5 +++++
.../camel/impl/debugger/DefaultBacklogDebugger.java | 12 ++++++++++++
.../apache/camel/impl/engine/CamelInternalProcessor.java | 16 ++++++++++++++++
.../org/apache/camel/impl/console/DebugDevConsole.java | 3 +++
.../camel/main/DefaultConfigurationProperties.java | 11 ++++++-----
.../management/mbean/ManagedBacklogDebuggerMBean.java | 3 +++
.../camel/management/mbean/ManagedBacklogDebugger.java | 5 +++++
.../org/apache/camel/support/DefaultMessageHistory.java | 11 +++++++++++
.../user-manual/modules/ROOT/pages/backlog-debugger.adoc | 4 +++-
.../org/apache/camel/dsl/jbang/core/commands/Debug.java | 14 +++++++++++---
14 files changed, 91 insertions(+), 10 deletions(-)
diff --git a/core/camel-api/src/generated/java/org/apache/camel/ExchangeConstantProvider.java b/core/camel-api/src/generated/java/org/apache/camel/ExchangeConstantProvider.java
index 51dfe0d93d7..9af5075afb0 100644
--- a/core/camel-api/src/generated/java/org/apache/camel/ExchangeConstantProvider.java
+++ b/core/camel-api/src/generated/java/org/apache/camel/ExchangeConstantProvider.java
@@ -13,7 +13,7 @@ public class ExchangeConstantProvider {
private static final Map<String, String> MAP;
static {
- Map<String, String> map = new HashMap<>(161);
+ Map<String, String> map = new HashMap<>(162);
map.put("ACCEPT_CONTENT_TYPE", "CamelAcceptContentType");
map.put("AGGREGATED_COLLECTION_GUARD", "CamelAggregatedCollectionGuard");
map.put("AGGREGATED_COMPLETED_BY", "CamelAggregatedCompletedBy");
@@ -146,6 +146,7 @@ public class ExchangeConstantProvider {
map.put("SAXPARSER_FACTORY", "CamelSAXParserFactory");
map.put("SCHEDULER_POLLED_MESSAGES", "CamelSchedulerPolledMessages");
map.put("SKIP_GZIP_ENCODING", "CamelSkipGzipEncoding");
+ map.put("SKIP_OVER", "CamelSkipOver");
map.put("SKIP_WWW_FORM_URLENCODED", "CamelSkipWwwFormUrlEncoding");
map.put("SLIP_ENDPOINT", "CamelSlipEndpoint");
map.put("SLIP_PRODUCER", "CamelSlipProducer");
diff --git a/core/camel-api/src/main/java/org/apache/camel/Exchange.java b/core/camel-api/src/main/java/org/apache/camel/Exchange.java
index 7ac40e9981b..da6a6bfe08c 100644
--- a/core/camel-api/src/main/java/org/apache/camel/Exchange.java
+++ b/core/camel-api/src/main/java/org/apache/camel/Exchange.java
@@ -287,6 +287,7 @@ public interface Exchange extends VariableAware {
@Deprecated(since = "3.15.0")
String SOAP_ACTION = "CamelSoapAction";
String SKIP_GZIP_ENCODING = "CamelSkipGzipEncoding";
+ String SKIP_OVER = "CamelSkipOver";
String SKIP_WWW_FORM_URLENCODED = "CamelSkipWwwFormUrlEncoding";
@Metadata(label = "routingSlip", description = "The endpoint uri of this routing slip", javaType = "String")
String SLIP_ENDPOINT = "CamelSlipEndpoint";
diff --git a/core/camel-api/src/main/java/org/apache/camel/ExchangePropertyKey.java b/core/camel-api/src/main/java/org/apache/camel/ExchangePropertyKey.java
index 8caf3a56e7a..97b8c0bd7c2 100644
--- a/core/camel-api/src/main/java/org/apache/camel/ExchangePropertyKey.java
+++ b/core/camel-api/src/main/java/org/apache/camel/ExchangePropertyKey.java
@@ -71,6 +71,7 @@ public enum ExchangePropertyKey {
PARENT_UNIT_OF_WORK(Exchange.PARENT_UNIT_OF_WORK),
RECEIVED_TIMESTAMP(Exchange.RECEIVED_TIMESTAMP),
RECIPIENT_LIST_ENDPOINT(Exchange.RECIPIENT_LIST_ENDPOINT),
+ SKIP_OVER(Exchange.SKIP_OVER),
SLIP_ENDPOINT(Exchange.SLIP_ENDPOINT),
SLIP_PRODUCER(Exchange.SLIP_PRODUCER),
SPLIT_COMPLETE(Exchange.SPLIT_COMPLETE),
@@ -191,6 +192,8 @@ public enum ExchangePropertyKey {
return RECEIVED_TIMESTAMP;
case Exchange.RECIPIENT_LIST_ENDPOINT:
return RECIPIENT_LIST_ENDPOINT;
+ case Exchange.SKIP_OVER:
+ return SKIP_OVER;
case Exchange.SLIP_ENDPOINT:
return SLIP_ENDPOINT;
case Exchange.SLIP_PRODUCER:
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 38a5dbca676..42deab6c8c2 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
@@ -70,4 +70,14 @@ public interface MessageHistory {
*/
boolean isAcceptDebugger();
+ /**
+ * Used specially during debugging to know that an EIP was skipped over
+ */
+ void setDebugSkipOver(boolean skipOver);
+
+ /**
+ * Used specially during debugging to know that an EIP was skipped over
+ */
+ boolean isDebugSkipOver();
+
}
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 24dd4846ba0..cba446fba1e 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
@@ -286,6 +286,11 @@ public interface BacklogDebugger extends StatefulService {
*/
void stepOver();
+ /**
+ * To skip over (does not call the node) to next node when in single step mode.
+ */
+ void skipOver();
+
/**
* Gets node ids for all current suspended exchanges at breakpoints
*/
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 a594c4d510a..af167ed56b9 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
@@ -79,6 +79,7 @@ public final class DefaultBacklogDebugger extends ServiceSupport implements Back
private final AtomicReference<CountDownLatch> suspend = new AtomicReference<>();
private final Deque<String> singleStepExchangeId = new ArrayDeque<>();
private final AtomicBoolean stepOverMode = new AtomicBoolean();
+ private final AtomicBoolean skipOverMode = new AtomicBoolean();
private boolean suspendMode;
private String initialBreakpoints;
@@ -644,9 +645,13 @@ public final class DefaultBacklogDebugger extends ServiceSupport implements Back
suspendedBreakpointMessages.remove(node);
SuspendedExchange se = suspendedBreakpoints.remove(node);
if (se != null) {
+ if (skipOverMode.get()) {
+ se.getExchange().setProperty(ExchangePropertyKey.SKIP_OVER, Boolean.TRUE);
+ }
se.getLatch().countDown();
}
}
+ skipOverMode.set(false);
}
@Override
@@ -655,6 +660,12 @@ public final class DefaultBacklogDebugger extends ServiceSupport implements Back
step();
}
+ @Override
+ public void skipOver() {
+ skipOverMode.set(true);
+ step();
+ }
+
@Override
public Set<String> getSuspendedBreakpointNodeIds() {
return new LinkedHashSet<>(suspendedBreakpoints.keySet());
@@ -1012,6 +1023,7 @@ public final class DefaultBacklogDebugger extends ServiceSupport implements Back
@Override
public void afterProcess(Exchange exchange, Processor processor, NamedNode definition, long timeTaken) {
stepOverMode.set(false);
+ skipOverMode.set(false);
}
@Override
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 a9eb63950fa..a3766d842d1 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
@@ -323,6 +323,22 @@ public class CamelInternalProcessor extends DelegateAsyncProcessor implements In
}
}
+ // debugger can skip processing the exchange
+ Object skip = exchange.removeProperty(ExchangePropertyKey.SKIP_OVER);
+ if (Boolean.TRUE == skip) {
+ if (LOG.isTraceEnabled()) {
+ LOG.trace("Skipping exchange for exchangeId: {} -> {}", exchange.getExchangeId(), exchange);
+ }
+ List<MessageHistory> list = exchange.getProperty(ExchangePropertyKey.MESSAGE_HISTORY, List.class);
+ if (list != null && !list.isEmpty()) {
+ MessageHistory last = list.get(list.size() - 1);
+ last.setDebugSkipOver(true);
+ }
+ // skip because the processor is specially disabled (such as from debugger)
+ originalCallback.done(true);
+ return true;
+ }
+
if (exchange.isTransacted()) {
return processTransacted(exchange, afterTask);
}
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 c1ac690a827..d8e4f021b08 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
@@ -126,6 +126,8 @@ public class DebugDevConsole extends AbstractDevConsole {
}
} else if ("stepover".equalsIgnoreCase(command)) {
backlog.stepOver();
+ } else if ("skipover".equalsIgnoreCase(command)) {
+ backlog.skipOver();
} else if ("add".equalsIgnoreCase(command) && ObjectHelper.isNotEmpty(breakpoint)) {
backlog.addBreakpoint(breakpoint);
} else if ("remove".equalsIgnoreCase(command)) {
@@ -244,6 +246,7 @@ public class DebugDevConsole extends AbstractDevConsole {
}
jo.put("elapsed", h.getElapsed());
jo.put("acceptDebugger", h.isAcceptDebugger());
+ jo.put("skipOver", h.isDebugSkipOver());
if (h.getNode() != null) {
jo.put("nodeId", h.getNode().getId());
if (h.getNode().getLocation() != null) {
diff --git a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java
index 7baf3a7946a..c10fb6838e0 100644
--- a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java
+++ b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java
@@ -322,13 +322,14 @@ public abstract class DefaultConfigurationProperties<T> {
}
/**
- * Directory to load additional properties files that contains configurations that takes precedence
- * (except for camel.main.xxx configurations).
+ * Directory to load additional properties files that contains configurations that takes precedence (except for
+ * camel.main.xxx configurations).
*
- * This can be used to refer to files that may have secret configuration that has been mounted on the file system for containers.
+ * This can be used to refer to files that may have secret configuration that has been mounted on the file system
+ * for containers.
*
- * You can specify a pattern to load from file-system (not classpath) and a name pattern such as /var/app/secret/*.properties,
- * multiple directories can be separated by comma.
+ * You can specify a pattern to load from file-system (not classpath) and a name pattern such as
+ * /var/app/secret/*.properties, multiple directories can be separated by comma.
*/
public void setFileConfigurations(String fileConfigurations) {
this.fileConfigurations = fileConfigurations;
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 3bdcceb26b2..2c318990dd3 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
@@ -98,6 +98,9 @@ public interface ManagedBacklogDebuggerMBean {
@ManagedOperation(description = "Steps over the next node in step mode")
void stepOver();
+ @ManagedOperation(description = "Skips over the next node in step mode")
+ void skipOver();
+
@ManagedOperation(description = "Return the node ids which has breakpoints")
Set<String> breakpoints();
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 a80ac72bb0f..bb14a1bcbd2 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
@@ -206,6 +206,11 @@ public class ManagedBacklogDebugger implements ManagedBacklogDebuggerMBean {
backlogDebugger.stepOver();
}
+ @Override
+ public void skipOver() {
+ backlogDebugger.skipOver();
+ }
+
@Override
public Set<String> suspendedBreakpointNodeIds() {
return backlogDebugger.getSuspendedBreakpointNodeIds();
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 936058103c4..a8293d7eb61 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
@@ -31,6 +31,7 @@ public class DefaultMessageHistory implements MessageHistory {
private final MonotonicClock clock = new MonotonicClock();
private final Message message;
private boolean acceptDebugger;
+ private boolean debugSkipOver;
private long elapsed;
public DefaultMessageHistory(String routeId, NamedNode node) {
@@ -84,6 +85,16 @@ public class DefaultMessageHistory implements MessageHistory {
return acceptDebugger;
}
+ @Override
+ public boolean isDebugSkipOver() {
+ return debugSkipOver;
+ }
+
+ @Override
+ public void setDebugSkipOver(boolean debugSkipOver) {
+ this.debugSkipOver = debugSkipOver;
+ }
+
@Override
public String toString() {
return "DefaultMessageHistory["
diff --git a/docs/user-manual/modules/ROOT/pages/backlog-debugger.adoc b/docs/user-manual/modules/ROOT/pages/backlog-debugger.adoc
index 349c189ab9e..53ad7b33b44 100644
--- a/docs/user-manual/modules/ROOT/pages/backlog-debugger.adoc
+++ b/docs/user-manual/modules/ROOT/pages/backlog-debugger.adoc
@@ -57,7 +57,9 @@ NOTE: This requires to enabled JMX by including `camel-management` JAR in the cl
|`setMessageBodyOnBreakpoint(nodeId,body)` |`void` |To update the message body on the suspended Exchange at the node.
|`setMessageHeaderOnBreakpoint(nodeId,headerName,value)` |`void` |To update/add the message header on the suspended Exchange at the node.
|`stepBreakpoint(nodeId)` |`void` |To start single step mode from a suspended breakpoint at the given node. Then invoke `step` to step to next node in the route.
-|`step` |`void` |To step to next node when in single step mode.
+|`step` |`void` |To step into the next node when in single step mode.
+|`stepOver` |`void` |To step over the next node when in single step mode.
+|`skipOver` |`void` |To skip over the next node when in single step mode.
|`validateConditionalBreakpoint` |`String` |Used for validating if a given predicate is valid or not. Returns null if valid, otherwise a string with the error message.
|`messageHistoryOnBreakpointAsXml(nodeId)` |`String` |Returns message history at the given node Id in XML format
|=======================================================================
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 a1de3e1db54..49531f09b7e 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
@@ -223,6 +223,8 @@ public class Debug extends Run {
String cmd = "step";
if (line.equalsIgnoreCase("o") || line.equalsIgnoreCase("over")) {
cmd = "stepover";
+ } else if (line.equalsIgnoreCase("s") || line.equalsIgnoreCase("skip")) {
+ cmd = "skipover";
}
sendDebugCommand(spawnPid, cmd, null);
}
@@ -438,6 +440,7 @@ public class Debug extends Run {
history.routeId = line.getString("routeId");
history.nodeId = line.getString("nodeId");
history.elapsed = line.getLongOrDefault("elapsed", 0);
+ history.skipOver = line.getBooleanOrDefault("skipOver", false);
history.location = line.getString("location");
history.line = line.getIntegerOrDefault("line", -1);
history.code = line.getString("code");
@@ -471,6 +474,7 @@ public class Debug extends Run {
this.waitForUser.set(true);
}
if (this.waitForUser.get()) {
+ boolean first = this.suspendedRow != null && this.suspendedRow.first;
// save current message to file
if (output != null && this.suspendedRow != null) {
JsonObject j = this.suspendedRow.message;
@@ -492,10 +496,10 @@ public class Debug extends Run {
}
String msg;
- if (isStepOverSupported(version)) {
- msg = " Breakpoint suspended (i = step into (default), o = step over). Press ENTER to continue.";
+ if (!first && isStepOverSupported(version)) {
+ msg = " Breakpoint suspended (i = step into (default), o = step over, s = skip over). Press ENTER to continue (q = quit).";
} else {
- msg = " Breakpoint suspended. Press ENTER to continue.";
+ msg = " Breakpoint suspended. Press ENTER to continue (q = quit).";
}
if (loggingColor) {
AnsiConsole.out().println(Ansi.ansi().a(Ansi.Attribute.INTENSITY_BOLD).a(msg).reset());
@@ -603,6 +607,9 @@ public class Debug extends Run {
}
long e = i == 2 ? 0 : h.elapsed; // the pseudo from should have 0 as elapsed
String elapsed = "(" + e + "ms)";
+ if (h.skipOver) {
+ elapsed = "(skipped)";
+ }
String c = "";
if (h.code != null) {
@@ -861,6 +868,7 @@ public class Debug extends Run {
String routeId;
String nodeId;
long elapsed;
+ boolean skipOver;
String location;
int line;
String code;