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 4d3b74b1cd0b CAMEL-26864: camel-console - the processor-detail console
names the route input by the id of its from, as the trace does (#29659)
4d3b74b1cd0b is described below
commit 4d3b74b1cd0b03ac51f68cbecfa270986d80dd40
Author: Claus Ibsen <[email protected]>
AuthorDate: Thu Nov 12 14:53:42 2026 +0100
CAMEL-26864: camel-console - the processor-detail console names the route
input by the id of its from, as the trace does (#29659)
* CAMEL-26864: camel-console - the processor-detail console names the route
input by the id of its from, as the trace does
The trace, the message history and the debugger name the from of a route by
its node id (from1), while the processor-detail console named it by the route
id, so an agent saw two ids for the same step. The TUI Diagram still finds the
detail of the from by the route id it draws it with.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Signed-off-by: Claus Ibsen <[email protected]>
* CAMEL-26864: Regen
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Signed-off-by: Claus Ibsen <[email protected]>
---------
Signed-off-by: Claus Ibsen <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
---
.../apache/camel/catalog/dev-consoles-openapi.json | 4 +-
.../catalog/dev-consoles/processor-detail.json | 4 +-
.../apache/camel/dev-console/processor-detail.json | 4 +-
.../impl/console/ProcessorDetailDevConsole.java | 12 +++-
.../impl/console/ProcessorDetailFromIdTest.java | 66 ++++++++++++++++++++++
.../ROOT/pages/camel-4x-upgrade-guide-4_24.adoc | 6 ++
.../core/commands/tui/DiagramDetailSupport.java | 15 +++++
.../core/commands/tui/DiagramDetailFromIdTest.java | 55 ++++++++++++++++++
8 files changed, 157 insertions(+), 9 deletions(-)
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dev-consoles-openapi.json
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dev-consoles-openapi.json
index 14a36d69d974..2c3ca58c2b86 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dev-consoles-openapi.json
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dev-consoles-openapi.json
@@ -5134,7 +5134,7 @@
"properties": {
"id": {
"type": "string",
-
"description": "The processor ID"
+
"description": "The processor ID (the id of the
from for the route input, as in the trace and message history)"
},
"type": {
"type": "string",
@@ -5175,7 +5175,7 @@
"properties": {
"id": {
"type": "string",
-
"description": "The
processor ID"
+
"description": "The
processor ID (the id of the from for the route input, as in the trace and
message history)"
},
"type": {
"type": "string",
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dev-consoles/processor-detail.json
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dev-consoles/processor-detail.json
index e280d7a3314c..097481df5898 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dev-consoles/processor-detail.json
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/dev-consoles/processor-detail.json
@@ -42,7 +42,7 @@
"properties": {
"id": {
"type": "string",
- "description": "The processor ID"
+ "description": "The processor ID (the id of the from for the
route input, as in the trace and message history)"
},
"type": {
"type": "string",
@@ -83,7 +83,7 @@
"properties": {
"id": {
"type": "string",
- "description": "The processor ID"
+ "description": "The processor ID (the id of the from for
the route input, as in the trace and message history)"
},
"type": {
"type": "string",
diff --git
a/core/camel-console/src/generated/resources/META-INF/org/apache/camel/dev-console/processor-detail.json
b/core/camel-console/src/generated/resources/META-INF/org/apache/camel/dev-console/processor-detail.json
index e280d7a3314c..097481df5898 100644
---
a/core/camel-console/src/generated/resources/META-INF/org/apache/camel/dev-console/processor-detail.json
+++
b/core/camel-console/src/generated/resources/META-INF/org/apache/camel/dev-console/processor-detail.json
@@ -42,7 +42,7 @@
"properties": {
"id": {
"type": "string",
- "description": "The processor ID"
+ "description": "The processor ID (the id of the from for the
route input, as in the trace and message history)"
},
"type": {
"type": "string",
@@ -83,7 +83,7 @@
"properties": {
"id": {
"type": "string",
- "description": "The processor ID"
+ "description": "The processor ID (the id of the from for
the route input, as in the trace and message history)"
},
"type": {
"type": "string",
diff --git
a/core/camel-console/src/main/java/org/apache/camel/impl/console/ProcessorDetailDevConsole.java
b/core/camel-console/src/main/java/org/apache/camel/impl/console/ProcessorDetailDevConsole.java
index 4577ed631f8d..858f41feebff 100644
---
a/core/camel-console/src/main/java/org/apache/camel/impl/console/ProcessorDetailDevConsole.java
+++
b/core/camel-console/src/main/java/org/apache/camel/impl/console/ProcessorDetailDevConsole.java
@@ -52,7 +52,7 @@ public class ProcessorDetailDevConsole extends
AbstractDevConsole {
public static final String ROUTE_ID = "routeId";
public record ProcessorEntry(
- @Metadata(description = "The processor ID") String id,
+ @Metadata(description = "The processor ID (the id of the from for
the route input, as in the trace and message history)") String id,
@Metadata(description = "The processor type (the XML element name,
or 'from' for the route input)") String type,
@Metadata(description = "The endpoint URI (only present for the
route input entry)") String endpointUri,
@Metadata(description = "The source line number (only present when
known)") Integer line,
@@ -160,6 +160,8 @@ public class ProcessorDetailDevConsole extends
AbstractDevConsole {
List<ProcessorEntry> processors = new ArrayList<>();
Integer fromLine = null;
+ // the from has a node id of its own (from1), which the trace and
message history name it by
+ String fromId = routeId;
try {
String xml = mr.dumpRouteAsXml(false, true, true);
@@ -175,7 +177,11 @@ public class ProcessorDetailDevConsole extends
AbstractDevConsole {
// extract source line number for the from entry from the
<from> child element
NodeList fromNodes = routeElement.getElementsByTagName("from");
if (fromNodes.getLength() > 0) {
- fromLine = extractSourceLineNumber((Element)
fromNodes.item(0));
+ Element from = (Element) fromNodes.item(0);
+ fromLine = extractSourceLineNumber(from);
+ if (!from.getAttribute("id").isEmpty()) {
+ fromId = from.getAttribute("id");
+ }
}
collectProcessors(routeElement, processors);
@@ -184,7 +190,7 @@ public class ProcessorDetailDevConsole extends
AbstractDevConsole {
// ignore
}
- ProcessorEntry fromEntry = new ProcessorEntry(routeId, "from",
mr.getEndpointUri(), fromLine, new LinkedHashMap<>());
+ ProcessorEntry fromEntry = new ProcessorEntry(fromId, "from",
mr.getEndpointUri(), fromLine, new LinkedHashMap<>());
processors.add(0, fromEntry);
return new RouteDetail(routeId, processors);
diff --git
a/core/camel-console/src/test/java/org/apache/camel/impl/console/ProcessorDetailFromIdTest.java
b/core/camel-console/src/test/java/org/apache/camel/impl/console/ProcessorDetailFromIdTest.java
new file mode 100644
index 000000000000..8d3af1e0a4b4
--- /dev/null
+++
b/core/camel-console/src/test/java/org/apache/camel/impl/console/ProcessorDetailFromIdTest.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.impl.console;
+
+import java.util.Map;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.console.DevConsole;
+import org.apache.camel.model.ModelCamelContext;
+import org.apache.camel.support.PluginHelper;
+import org.apache.camel.util.json.JsonArray;
+import org.apache.camel.util.json.JsonObject;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+/**
+ * The route input is named by the id of its from (from1), as the trace and
the message history name it, not by the id
+ * of the route (CAMEL-26864).
+ */
+class ProcessorDetailFromIdTest extends ContextTestSupport {
+
+ @Override
+ protected boolean useJmx() {
+ // the processor-detail console reads the routes from JMX
+ return true;
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() {
+ return new RouteBuilder() {
+ @Override
+ public void configure() {
+ from("direct:start").routeId("myRoute").to("mock:result");
+ }
+ };
+ }
+
+ @Test
+ void theFromIsNamedByItsNodeId() {
+ DevConsole con =
PluginHelper.getDevConsoleResolver(context).resolveDevConsole("processor-detail");
+ JsonObject out = (JsonObject) con.call(DevConsole.MediaType.JSON,
Map.of("routeId", "myRoute"));
+
+ JsonObject from = (JsonObject) ((JsonArray)
out.get("processors")).get(0);
+ String fromId = ((ModelCamelContext)
context).getRouteDefinition("myRoute").getInput().getId();
+ Assertions.assertEquals("from", from.getString("type"));
+ Assertions.assertNotNull(fromId);
+ Assertions.assertEquals(fromId, from.getString("id"));
+ Assertions.assertNotEquals("myRoute", from.getString("id"));
+ Assertions.assertEquals("myRoute", out.getString("routeId"));
+ }
+}
diff --git
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
index 99980745c2a4..c2068729eeb0 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc
@@ -303,6 +303,12 @@ new `reply` component; its seven-argument constructor is
kept and creates an edg
A `wireTap` or a `toD` to an endpoint the route names, rather than one it
computes with an expression, is now an edge
too (a wire tap never waits for the answer), and an external endpoint when no
route consumes from it.
+=== camel-console - the processor-detail console names the route input by the
id of its from
+
+The first entry of the `processor-detail` developer console, the route input
(`type` is `from`), now has the id of the
+`from` of the route as `id` (such as `from1`, or the id given to the `from`),
which the tracer, the message history and
+the backlog debugger name it by. It had the route id before, which is still
the `routeId` of the response.
+
=== camel-management - LastExchangeCompletedExchangeId is updated at most once
per millisecond
The JMX attribute `LastExchangeCompletedExchangeId`, of the `CamelContext`,
route and processor MBeans, is now updated
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DiagramDetailSupport.java
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DiagramDetailSupport.java
index 2fe5127a1e1a..b0302ea6ef6a 100644
---
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DiagramDetailSupport.java
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/main/java/org/apache/camel/dsl/jbang/core/commands/tui/DiagramDetailSupport.java
@@ -38,6 +38,7 @@ import org.apache.camel.catalog.CamelCatalog;
import org.apache.camel.diagram.RouteDiagramLayoutEngine;
import org.apache.camel.dsl.jbang.core.commands.tui.diagram.DiagramColors;
import org.apache.camel.util.TimeUtils;
+import org.apache.camel.util.json.JsonArray;
import org.apache.camel.util.json.JsonObject;
import static org.apache.camel.dsl.jbang.core.commands.tui.EipDocSupport.*;
@@ -133,6 +134,10 @@ final class DiagramDetailSupport {
}
}
+ void setRouteDetailForTesting(JsonObject routeDetail) {
+ cachedRouteDetail = routeDetail;
+ }
+
JsonObject findProcessorEntry(String nodeId) {
if (cachedRouteDetail == null || nodeId == null) {
return null;
@@ -142,6 +147,16 @@ final class DiagramDetailSupport {
return p;
}
}
+ // the diagram names the input of a route by the route id, the app by
the id of its from (from1)
+ JsonArray routes = (JsonArray) cachedRouteDetail.get("routes");
+ for (Object r : routes != null ? routes : List.of()) {
+ JsonObject route = (JsonObject) r;
+ JsonArray procs = (JsonArray) route.get("processors");
+ if (nodeId.equals(route.getString("routeId")) && procs != null &&
!procs.isEmpty()
+ && "from".equals(((JsonObject)
procs.get(0)).getString("type"))) {
+ return (JsonObject) procs.get(0);
+ }
+ }
return null;
}
diff --git
a/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/DiagramDetailFromIdTest.java
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/DiagramDetailFromIdTest.java
new file mode 100644
index 000000000000..7e661e19cf8b
--- /dev/null
+++
b/dsl/camel-jbang/camel-jbang-plugin-tui/src/test/java/org/apache/camel/dsl/jbang/core/commands/tui/DiagramDetailFromIdTest.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.dsl.jbang.core.commands.tui;
+
+import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.apache.camel.util.json.JsonObject;
+import org.apache.camel.util.json.Jsoner;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * CAMEL-26864: the app names the input of a route by the id of its from
(from1), as the trace does; the diagram names
+ * it by the route id. The detail panel finds it by either, and by the route
id with an app that still says so.
+ */
+class DiagramDetailFromIdTest {
+
+ @Test
+ void theFromIsFoundByItsIdAndByTheRouteId() throws Exception {
+ MonitorContext ctx = new MonitorContext(new
AtomicReference<>(List.of()), new AtomicReference<>(List.of()));
+ DiagramDetailSupport detail = new DiagramDetailSupport(ctx, new
DiagramSupport());
+ detail.setRouteDetailForTesting((JsonObject) Jsoner.deserialize("""
+ {"routes": [
+ {"routeId": "hello", "processors": [
+ {"id": "from1", "type": "from", "endpointUri":
"timer://tick"},
+ {"id": "setBody1", "type": "setBody"}]},
+ {"routeId": "seven", "processors": [
+ {"id": "seven", "type": "from", "endpointUri":
"direct://seven"}]}]}
+ """));
+
+
assertThat(detail.findProcessorEntry("from1").getString("endpointUri")).isEqualTo("timer://tick");
+
assertThat(detail.findProcessorEntry("hello").getString("endpointUri")).as("the
diagram's from node")
+ .isEqualTo("timer://tick");
+
assertThat(detail.findProcessorEntry("setBody1").getString("type")).isEqualTo("setBody");
+
assertThat(detail.findProcessorEntry("seven").getString("endpointUri")).as("an
app before CAMEL-26864")
+ .isEqualTo("direct://seven");
+ assertThat(detail.findProcessorEntry("nope")).isNull();
+ }
+}