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 2023/11/23 12:56:32 UTC
(camel) 01/01: CAMEL-20143: camel-core - Dump route when debugger enable should include source line
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch debug-source-line
in repository https://gitbox.apache.org/repos/asf/camel.git
commit 465a81b56735394938a598839567b29422745644
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Thu Nov 23 13:56:16 2023 +0100
CAMEL-20143: camel-core - Dump route when debugger enable should include source line
---
.../management/mbean/ManagedCamelContext.java | 9 ++
.../camel/management/mbean/ManagedRoute.java | 4 +
.../java/org/apache/camel/xml/jaxb/JaxbHelper.java | 108 ++++++++++++++++++++-
.../camel/xml/jaxb/JaxbModelToXMLDumper.java | 36 +------
4 files changed, 123 insertions(+), 34 deletions(-)
diff --git a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
index b709ad93c29..519eb33313a 100644
--- a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
+++ b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
@@ -488,6 +488,10 @@ public class ManagedCamelContext extends ManagedPerformanceCounter implements Ti
RoutesDefinition def = new RoutesDefinition();
def.setRoutes(routes);
+ // if we are debugging then ids is needed for the debugger
+ if (context.isDebugging()) {
+ generatedIds = true;
+ }
return PluginHelper.getModelToXMLDumper(context).dumpModelAsXml(context, def, resolvePlaceholders, generatedIds);
}
@@ -518,6 +522,11 @@ public class ManagedCamelContext extends ManagedPerformanceCounter implements Ti
RoutesDefinition def = new RoutesDefinition();
def.setRoutes(routes);
+ // if we are debugging then ids is needed for the debugger
+ if (context.isDebugging()) {
+ generatedIds = true;
+ }
+
return PluginHelper.getModelToYAMLDumper(context).dumpModelAsYaml(context, def, resolvePlaceholders, uriAsParameters,
generatedIds);
}
diff --git a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedRoute.java b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedRoute.java
index 0f7e00790e1..301739c0df4 100644
--- a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedRoute.java
+++ b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedRoute.java
@@ -396,6 +396,10 @@ public class ManagedRoute extends ManagedPerformanceCounter implements TimerList
String id = route.getId();
RouteDefinition def = context.getCamelContextExtension().getContextPlugin(Model.class).getRouteDefinition(id);
if (def != null) {
+ // if we are debugging then ids is needed for the debugger
+ if (context.isDebugging()) {
+ generatedIds = true;
+ }
return PluginHelper.getModelToXMLDumper(context).dumpModelAsXml(context, def, resolvePlaceholders, generatedIds);
}
diff --git a/core/camel-xml-jaxb/src/main/java/org/apache/camel/xml/jaxb/JaxbHelper.java b/core/camel-xml-jaxb/src/main/java/org/apache/camel/xml/jaxb/JaxbHelper.java
index 07d77c7a422..41099653e46 100644
--- a/core/camel-xml-jaxb/src/main/java/org/apache/camel/xml/jaxb/JaxbHelper.java
+++ b/core/camel-xml-jaxb/src/main/java/org/apache/camel/xml/jaxb/JaxbHelper.java
@@ -20,6 +20,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
@@ -195,6 +196,41 @@ public final class JaxbHelper {
}
}
+ /**
+ * Extract all source locations from the XML routes
+ *
+ * @param element the XML element
+ * @param locations the map of source locations for EIPs in the route
+ */
+ public static void extractSourceLocations(Element element, Map<String, KeyValueHolder<Integer, String>> locations) {
+ NamedNodeMap attributes = element.getAttributes();
+ String id = null;
+ Integer sourceLineNumber = null;
+ String sourceLocation = null;
+ for (int i = 0; i < attributes.getLength(); i++) {
+ Node item = attributes.item(i);
+ String name = item.getNodeName();
+ if ("id".equals(name)) {
+ id = item.getNodeValue();
+ } else if ("sourceLineNumber".equals(name)) {
+ sourceLineNumber = Integer.parseInt(item.getNodeValue());
+ } else if ("sourceLocation".equals(name)) {
+ sourceLocation = item.getNodeValue();
+ }
+ }
+ if (id != null && sourceLineNumber != null && sourceLocation != null) {
+ locations.put(id, new KeyValueHolder<>(sourceLineNumber, sourceLocation));
+ }
+
+ final NodeList children = element.getChildNodes();
+ for (int index = 0; index < children.getLength(); index++) {
+ final Node child = children.item(index);
+ if (child.getNodeType() == Node.ELEMENT_NODE) {
+ extractSourceLocations((Element) child, locations);
+ }
+ }
+ }
+
public static void applyNamespaces(RouteDefinition route, Map<String, String> namespaces) {
Collection<ExpressionNode> col = filterTypeInOutputs(route.getOutputs(), ExpressionNode.class);
for (ExpressionNode en : col) {
@@ -223,6 +259,24 @@ public final class JaxbHelper {
}
}
+ public static void applySourceLocations(RouteDefinition route, Map<String, KeyValueHolder<Integer, String>> locations) {
+ KeyValueHolder<Integer, String> kv = locations.get(route.getRouteId());
+ if (kv != null && route.getInput() != null) {
+ route.getInput().setLineNumber(kv.getKey());
+ route.getInput().setLocation(kv.getValue());
+ }
+
+ Collection<OptionalIdentifiedDefinition> def
+ = filterTypeInOutputs(route.getOutputs(), OptionalIdentifiedDefinition.class);
+ for (OptionalIdentifiedDefinition out : def) {
+ kv = locations.get(out.getId());
+ if (kv != null) {
+ out.setLineNumber(kv.getKey());
+ out.setLocation(kv.getValue());
+ }
+ }
+ }
+
public static <T extends NamedNode> T modelToXml(CamelContext context, String xml, Class<T> type) throws Exception {
JAXBContext jaxbContext = getJAXBContext(context);
@@ -237,6 +291,10 @@ public final class JaxbHelper {
throw new IllegalArgumentException("InputStream and XML is both null");
}
+ Map<String, KeyValueHolder<Integer, String>> locations = new HashMap<>();
+ if (context.isDebugging()) {
+ extractSourceLocations(dom.getDocumentElement(), locations);
+ }
Map<String, String> namespaces = new LinkedHashMap<>();
extractNamespaces(dom, namespaces);
@@ -251,19 +309,37 @@ public final class JaxbHelper {
if (result instanceof RouteTemplatesDefinition) {
List<RouteTemplateDefinition> templates = ((RouteTemplatesDefinition) result).getRouteTemplates();
for (RouteTemplateDefinition template : templates) {
- applyNamespaces(template.getRoute(), namespaces);
+ RouteDefinition route = template.getRoute();
+ applyNamespaces(route, namespaces);
+ if (!locations.isEmpty()) {
+ applySourceLocations(route, locations);
+ }
+ resolveEndpointDslUris(route);
}
} else if (result instanceof RouteTemplateDefinition) {
RouteTemplateDefinition template = (RouteTemplateDefinition) result;
- applyNamespaces(template.getRoute(), namespaces);
+ RouteDefinition route = template.getRoute();
+ applyNamespaces(route, namespaces);
+ if (!locations.isEmpty()) {
+ applySourceLocations(route, locations);
+ }
+ resolveEndpointDslUris(route);
} else if (result instanceof RoutesDefinition) {
List<RouteDefinition> routes = ((RoutesDefinition) result).getRoutes();
for (RouteDefinition route : routes) {
applyNamespaces(route, namespaces);
+ if (!locations.isEmpty()) {
+ applySourceLocations(route, locations);
+ }
+ resolveEndpointDslUris(route);
}
} else if (result instanceof RouteDefinition) {
RouteDefinition route = (RouteDefinition) result;
applyNamespaces(route, namespaces);
+ if (!locations.isEmpty()) {
+ applySourceLocations(route, locations);
+ }
+ resolveEndpointDslUris(route);
}
return type.cast(result);
@@ -530,4 +606,32 @@ public final class JaxbHelper {
}
}
+ public static void enrichLocations(Node node, Map<String, KeyValueHolder<Integer, String>> locations) {
+ if (node instanceof Element) {
+ Element el = (Element) node;
+
+ // from should grab it from parent (route)
+ String id = el.getAttribute("id");
+ if ("from".equals(el.getNodeName())) {
+ Node parent = el.getParentNode();
+ if (parent instanceof Element) {
+ id = ((Element) parent).getAttribute("id");
+ }
+ }
+ if (id != null) {
+ var loc = locations.get(id);
+ if (loc != null) {
+ el.setAttribute("sourceLineNumber", loc.getKey().toString());
+ el.setAttribute("sourceLocation", loc.getValue());
+ }
+ }
+ }
+ if (node.hasChildNodes()) {
+ for (int i = 0; i < node.getChildNodes().getLength(); i++) {
+ Node child = node.getChildNodes().item(i);
+ enrichLocations(child, locations);
+ }
+ }
+ }
+
}
diff --git a/core/camel-xml-jaxb/src/main/java/org/apache/camel/xml/jaxb/JaxbModelToXMLDumper.java b/core/camel-xml-jaxb/src/main/java/org/apache/camel/xml/jaxb/JaxbModelToXMLDumper.java
index 1c6c67f124b..9a0c4440553 100644
--- a/core/camel-xml-jaxb/src/main/java/org/apache/camel/xml/jaxb/JaxbModelToXMLDumper.java
+++ b/core/camel-xml-jaxb/src/main/java/org/apache/camel/xml/jaxb/JaxbModelToXMLDumper.java
@@ -58,12 +58,12 @@ import org.apache.camel.support.PluginHelper;
import org.apache.camel.util.KeyValueHolder;
import org.apache.camel.util.xml.XmlLineNumberParser;
+import static org.apache.camel.xml.jaxb.JaxbHelper.enrichLocations;
import static org.apache.camel.xml.jaxb.JaxbHelper.extractNamespaces;
import static org.apache.camel.xml.jaxb.JaxbHelper.extractSourceLocations;
import static org.apache.camel.xml.jaxb.JaxbHelper.getJAXBContext;
import static org.apache.camel.xml.jaxb.JaxbHelper.modelToXml;
import static org.apache.camel.xml.jaxb.JaxbHelper.newXmlConverter;
-import static org.apache.camel.xml.jaxb.JaxbHelper.removeAutoAssignedIds;
import static org.apache.camel.xml.jaxb.JaxbHelper.resolveEndpointDslUris;
/**
@@ -201,8 +201,9 @@ public class JaxbModelToXMLDumper implements ModelToXMLDumper {
pc.setLocalProperties(null);
}
- if (!changed.get()) {
- changed.set(!text.equals(after));
+ boolean updated = !text.equals(after);
+ if (updated && !changed.get()) {
+ changed.set(true);
}
return after;
@@ -212,7 +213,6 @@ public class JaxbModelToXMLDumper implements ModelToXMLDumper {
// okay there were some property placeholder or delegate endpoints
// replaced so re-create the model
if (changed.get()) {
- removeAutoAssignedIds(dom.getDocumentElement());
xml = context.getTypeConverter().mandatoryConvertTo(String.class, dom);
NamedNode copy = modelToXml(context, xml, NamedNode.class);
xml = PluginHelper.getModelToXMLDumper(context).dumpModelAsXml(context, copy, false, generatedIds);
@@ -268,34 +268,6 @@ public class JaxbModelToXMLDumper implements ModelToXMLDumper {
}
}
- private static void enrichLocations(Node node, Map<String, KeyValueHolder<Integer, String>> locations) {
- if (node instanceof Element) {
- Element el = (Element) node;
-
- // from should grab it from parent (route)
- String id = el.getAttribute("id");
- if ("from".equals(el.getNodeName())) {
- Node parent = el.getParentNode();
- if (parent instanceof Element) {
- id = ((Element) parent).getAttribute("id");
- }
- }
- if (id != null) {
- var loc = locations.get(id);
- if (loc != null) {
- el.setAttribute("sourceLineNumber", loc.getKey().toString());
- el.setAttribute("sourceLocation", loc.getValue());
- }
- }
- }
- if (node.hasChildNodes()) {
- for (int i = 0; i < node.getChildNodes().getLength(); i++) {
- Node child = node.getChildNodes().item(i);
- enrichLocations(child, locations);
- }
- }
- }
-
private static class BeanModelWriter implements CamelContextAware {
private final StringWriter buffer;