From 517d0a37fb0f38f4ce0d308f1761a76ba928df46 Mon Sep 17 00:00:00 2001 From: Claus Ibsen Date: Sun, 3 Mar 2024 15:15:01 +0100 Subject: [PATCH 1/4] #989: Camel debug - Add support for exchange variables. --- .../runner/debugger/CamelDebuggerSession.java | 8 +-- .../runner/debugger/CamelDebuggerTarget.java | 4 ++ .../debugger/stack/CamelMessageInfo.java | 37 ++++++++++++-- .../debugger/stack/CamelStackFrame.java | 11 ++--- .../runner/debugger/util/DebuggerUtils.java | 49 +++++++++++++++++++ 5 files changed, 95 insertions(+), 14 deletions(-) create mode 100644 camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/util/DebuggerUtils.java diff --git a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/CamelDebuggerSession.java b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/CamelDebuggerSession.java index fe785cc9..4c4b53d6 100644 --- a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/CamelDebuggerSession.java +++ b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/CamelDebuggerSession.java @@ -20,6 +20,7 @@ import com.github.cameltooling.idea.runner.debugger.breakpoint.CamelBreakpoint; import com.github.cameltooling.idea.runner.debugger.stack.CamelMessageInfo; import com.github.cameltooling.idea.runner.debugger.util.ClasspathUtils; +import com.github.cameltooling.idea.runner.debugger.util.DebuggerUtils; import com.github.cameltooling.idea.service.CamelRuntime; import com.github.cameltooling.idea.util.IdeaUtils; import com.github.cameltooling.idea.util.StringUtils; @@ -543,8 +544,7 @@ private boolean doConnect() { //Init DOM Documents String routes = camelContext.dumpRoutesAsXml(false); - DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); - DocumentBuilder documentBuilder = dbf.newDocumentBuilder(); + DocumentBuilder documentBuilder = DebuggerUtils.createDocumentBuilder();; InputStream targetStream = new ByteArrayInputStream(routes.getBytes()); this.routesDOMDocument = documentBuilder.parse(targetStream); @@ -796,7 +796,7 @@ private String dumpTracedMessagesAsXml(String id) { xml = (String) serverConnection.invoke(this.debuggerMBeanObjectName, "dumpTracedMessagesAsXml", new Object[]{id}, new String[]{"java.lang.String"}); } catch (Exception ex) { - LOG.error("Could not invoke dumpTracedMessagesAsXml(" + id + ")", e); + LOG.warn("Could not invoke dumpTracedMessagesAsXml(" + id + ")", e); return ""; } } @@ -817,7 +817,7 @@ private List getStack(String breakpointId, String messageInfoA new String[]{"java.lang.String"}); InputStream targetStream = new ByteArrayInputStream(messageHistory.getBytes()); - Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(targetStream); + Document document = DebuggerUtils.createDocumentBuilder().parse(targetStream); NodeList historyEntries = document.getElementsByTagName("messageHistoryEntry"); for (int i = 0; i < historyEntries.getLength(); i++) { diff --git a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/CamelDebuggerTarget.java b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/CamelDebuggerTarget.java index f8b3f3cc..b87ba02e 100644 --- a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/CamelDebuggerTarget.java +++ b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/CamelDebuggerTarget.java @@ -28,6 +28,10 @@ public enum CamelDebuggerTarget { * The target used to modify one specific exchange property. */ EXCHANGE_PROPERTY("Exchange Property"), + /** + * The target used to modify one specific exchange variable. + */ + EXCHANGE_VARIABLE("Exchange Variable"), /** * The target used to modify the body. */ diff --git a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/stack/CamelMessageInfo.java b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/stack/CamelMessageInfo.java index f1eb5a3a..86263de1 100644 --- a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/stack/CamelMessageInfo.java +++ b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/stack/CamelMessageInfo.java @@ -16,6 +16,7 @@ */ package com.github.cameltooling.idea.runner.debugger.stack; +import com.github.cameltooling.idea.runner.debugger.util.DebuggerUtils; import com.github.cameltooling.idea.util.StringUtils; import com.intellij.psi.PsiElement; import com.intellij.util.ArrayUtil; @@ -26,11 +27,14 @@ import org.w3c.dom.Element; import org.w3c.dom.NodeList; +import javax.xml.XMLConstants; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -38,6 +42,7 @@ public class CamelMessageInfo { private Map headers; private Map properties; + private Map variables; private Value body; private String exchangeId; @@ -62,7 +67,7 @@ public CamelMessageInfo(@NotNull String messageInfoAsXML, String processor, List stack) throws Exception { this.messageInfoAsXML = messageInfoAsXML; - this.documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + this.documentBuilder = DebuggerUtils.createDocumentBuilder(); this.position = position; this.tag = tag; this.routeId = routeId; @@ -76,7 +81,7 @@ private void init() throws Exception { InputStream targetStream = new ByteArrayInputStream(messageInfoAsXML.getBytes()); Document document = documentBuilder.parse(targetStream); - headers = new HashMap<>(); + headers = new LinkedHashMap<>(); //parse headers NodeList headersNodeList = document.getElementsByTagName("header"); @@ -111,11 +116,11 @@ private void init() throws Exception { NodeList propertiesNodeList = document.getElementsByTagName("exchangeProperty"); if (propertiesNodeList.getLength() > 0) { - properties = new HashMap<>(); + properties = new LinkedHashMap<>(); } for (int i = 0; i < propertiesNodeList.getLength(); i++) { Element nextProp = (Element) propertiesNodeList.item(i); - String key = nextProp.getAttribute("name"); + String key = nextProp.getAttribute("key"); String type = nextProp.getAttribute("type"); String value = nextProp.getTextContent(); @@ -128,6 +133,25 @@ private void init() throws Exception { Value newValue = new Value(type, value); properties.put(key, new Value[]{newValue}); } + NodeList variablesNodeList = document.getElementsByTagName("exchangeVariable"); + if (variablesNodeList.getLength() > 0) { + variables = new HashMap<>(); + } + for (int i = 0; i < variablesNodeList.getLength(); i++) { + Element nextProp = (Element) variablesNodeList.item(i); + String key = nextProp.getAttribute("key"); + String type = nextProp.getAttribute("type"); + String value = nextProp.getTextContent(); + + if (StringUtils.isEmpty(type)) { + type = "java.lang.String"; + } + if (StringUtils.isEmpty(value)) { + value = ""; + } + Value newValue = new Value(type, value); + variables.put(key, new Value[]{newValue}); + } } public Map getHeaders() { @@ -139,6 +163,11 @@ public Map getProperties() { return properties; } + @Nullable + public Map getVariables() { + return variables; + } + public Value getBody() { return body; } diff --git a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/stack/CamelStackFrame.java b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/stack/CamelStackFrame.java index c34212aa..fc603a3a 100644 --- a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/stack/CamelStackFrame.java +++ b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/stack/CamelStackFrame.java @@ -16,7 +16,6 @@ */ package com.github.cameltooling.idea.runner.debugger.stack; - import com.github.cameltooling.idea.runner.debugger.CamelDebuggerSession; import com.github.cameltooling.idea.runner.debugger.CamelDebuggerTarget; import com.github.cameltooling.idea.runner.debugger.evaluator.CamelExpressionEvaluator; @@ -37,7 +36,6 @@ public class CamelStackFrame extends XStackFrame { private final CamelDebuggerSession session; private final CamelMessageInfo camelMessageInfo; - public CamelStackFrame(@NotNull CamelDebuggerSession session, CamelMessageInfo camelMessageInfo) { this.session = session; this.camelMessageInfo = camelMessageInfo; @@ -75,7 +73,6 @@ public Object getEqualityObject() { return CamelStackFrame.class; } - @Override public void computeChildren(@NotNull XCompositeNode node) { final XValueChildrenList children = new XValueChildrenList(); @@ -83,11 +80,13 @@ public void computeChildren(@NotNull XCompositeNode node) { children.add("Body", new ObjectFieldDefinitionValue(CamelDebuggerTarget.BODY, null, this.session, this.camelMessageInfo.getBody(), AllIcons.Debugger.Value)); children.add("Headers", new MapOfObjectFieldDefinitionValue(CamelDebuggerTarget.MESSAGE_HEADER, this.session, this.camelMessageInfo.getHeaders(), AllIcons.Debugger.Value)); final var properties = this.camelMessageInfo.getProperties(); - if (properties == null) { - children.add("WARNING: ", JavaStackFrame.createMessageNode("Exchange Properties in Debugger are only available in Camel version 3.15 or later", AllIcons.Nodes.WarningMark)); - } else { + if (properties != null) { children.add("Exchange Properties", new MapOfObjectFieldDefinitionValue(CamelDebuggerTarget.EXCHANGE_PROPERTY, this.session, properties, AllIcons.Debugger.Value)); } + final var variables = this.camelMessageInfo.getVariables(); + if (variables != null) { + children.add("Exchange Variables", new MapOfObjectFieldDefinitionValue(CamelDebuggerTarget.EXCHANGE_VARIABLE, this.session, variables, AllIcons.Debugger.Value)); + } node.addChildren(children, true); } } diff --git a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/util/DebuggerUtils.java b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/util/DebuggerUtils.java new file mode 100644 index 00000000..10d96fc5 --- /dev/null +++ b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/util/DebuggerUtils.java @@ -0,0 +1,49 @@ +/* + * 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 com.github.cameltooling.idea.runner.debugger.util; + +import javax.xml.XMLConstants; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +public final class DebuggerUtils { + + public static DocumentBuilder createDocumentBuilder() throws ParserConfigurationException { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setNamespaceAware(true); + factory.setValidating(false); + factory.setIgnoringElementContentWhitespace(true); + factory.setIgnoringComments(true); + try { + // Set secure processing + factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, Boolean.TRUE); + } catch (ParserConfigurationException e) { + } + try { + // Disable the external-general-entities by default + factory.setFeature("http://xml.org/sax/features/external-general-entities", false); + } catch (ParserConfigurationException e) { + } + try { + // Disable the external-parameter-entities by default + factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + } catch (ParserConfigurationException e) { + } + return factory.newDocumentBuilder(); + } +} From 6e9eb7f2c4572cf012d38eb0af9a090ddfc49e12 Mon Sep 17 00:00:00 2001 From: Claus Ibsen Date: Sun, 3 Mar 2024 15:16:02 +0100 Subject: [PATCH 2/4] #989: Camel debug - Add support for exchange variables. --- .../idea/runner/debugger/CamelDebuggerSession.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/CamelDebuggerSession.java b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/CamelDebuggerSession.java index 4c4b53d6..94acb98e 100644 --- a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/CamelDebuggerSession.java +++ b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/CamelDebuggerSession.java @@ -93,6 +93,7 @@ import static com.github.cameltooling.idea.runner.debugger.CamelDebuggerContext.CAMEL; import static com.github.cameltooling.idea.runner.debugger.CamelDebuggerTarget.BODY; import static com.github.cameltooling.idea.runner.debugger.CamelDebuggerTarget.EXCHANGE_PROPERTY; +import static com.github.cameltooling.idea.runner.debugger.CamelDebuggerTarget.EXCHANGE_VARIABLE; import static com.github.cameltooling.idea.runner.debugger.CamelDebuggerTarget.MESSAGE_HEADER; public class CamelDebuggerSession implements AbstractDebuggerSession { @@ -289,6 +290,10 @@ public void setValue(CamelDebuggerTarget target, serverConnection.invoke(this.debuggerMBeanObjectName, "setExchangePropertyOnBreakpoint", new Object[]{breakpointId, targetName, value}, new String[]{"java.lang.String", "java.lang.String", "java.lang.Object"}); + } else if (target == EXCHANGE_VARIABLE) { + serverConnection.invoke(this.debuggerMBeanObjectName, "setExchangeVariableOnBreakpoint", + new Object[]{breakpointId, targetName, value}, + new String[]{"java.lang.String", "java.lang.String", "java.lang.Object"}); } else if (target == BODY) { serverConnection.invoke(this.debuggerMBeanObjectName, "setMessageBodyOnBreakpoint", new Object[]{breakpointId, value}, From 1140e19057686b3265c71eb2a2452fd00731d868 Mon Sep 17 00:00:00 2001 From: Claus Ibsen Date: Sun, 3 Mar 2024 15:22:50 +0100 Subject: [PATCH 3/4] #989: Camel debug - Add support for exchange variables. --- camel-idea-plugin/src/main/resources/META-INF/plugin.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/camel-idea-plugin/src/main/resources/META-INF/plugin.xml b/camel-idea-plugin/src/main/resources/META-INF/plugin.xml index 0dd6698e..cead896d 100644 --- a/camel-idea-plugin/src/main/resources/META-INF/plugin.xml +++ b/camel-idea-plugin/src/main/resources/META-INF/plugin.xml @@ -11,7 +11,7 @@ -
  • Bug fixes
  • +
  • Debugger now supports Exchange variables (Camel 4.4)
  • ]]>
    From 6e501d541d7f3caea5ea618635bb793ac1e79291 Mon Sep 17 00:00:00 2001 From: Claus Ibsen Date: Sun, 3 Mar 2024 15:28:41 +0100 Subject: [PATCH 4/4] #989: Camel debug - Add support for exchange variables. --- .../idea/runner/debugger/CamelDebuggerSession.java | 2 +- .../cameltooling/idea/runner/debugger/util/DebuggerUtils.java | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/CamelDebuggerSession.java b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/CamelDebuggerSession.java index 94acb98e..c5e77cd0 100644 --- a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/CamelDebuggerSession.java +++ b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/CamelDebuggerSession.java @@ -549,7 +549,7 @@ private boolean doConnect() { //Init DOM Documents String routes = camelContext.dumpRoutesAsXml(false); - DocumentBuilder documentBuilder = DebuggerUtils.createDocumentBuilder();; + DocumentBuilder documentBuilder = DebuggerUtils.createDocumentBuilder(); InputStream targetStream = new ByteArrayInputStream(routes.getBytes()); this.routesDOMDocument = documentBuilder.parse(targetStream); diff --git a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/util/DebuggerUtils.java b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/util/DebuggerUtils.java index 10d96fc5..e06aa8d0 100644 --- a/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/util/DebuggerUtils.java +++ b/camel-idea-plugin/src/main/java/com/github/cameltooling/idea/runner/debugger/util/DebuggerUtils.java @@ -23,6 +23,9 @@ public final class DebuggerUtils { + private DebuggerUtils() { + } + public static DocumentBuilder createDocumentBuilder() throws ParserConfigurationException { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); @@ -46,4 +49,5 @@ public static DocumentBuilder createDocumentBuilder() throws ParserConfiguration } return factory.newDocumentBuilder(); } + }