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/04/02 12:16:31 UTC

[camel] branch camel-3.x updated: CAMEL-19173 - Splitting long uris in XML DSLs (#9611)

This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch camel-3.x
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/camel-3.x by this push:
     new cfca1dcc6be CAMEL-19173 - Splitting long uris in XML DSLs (#9611)
cfca1dcc6be is described below

commit cfca1dcc6becacd0fad9c67c56d7b1865e0bba00
Author: jacekszymanski <ja...@gmail.com>
AuthorDate: Sun Apr 2 14:16:19 2023 +0200

    CAMEL-19173 - Splitting long uris in XML DSLs (#9611)
    
    * CAMEL-19173: support splitting long URIs in XML IO
    
    * CAMEL-19173: support splitting long URIs in XML JAXB
    
    * CAMEL-19173: XML IO DSL: removing spaces only before parameter names
    
    * CAMEL-19173: XML JAXB DSL: removing spaces only before parameter names
    
    * CAMEL-19173: refactor: code removing noise now in URISupport
---
 .../java/org/apache/camel/util/URISupport.java     | 13 +++++++
 .../java/org/apache/camel/xml/in/BaseParser.java   |  4 +++
 .../org/apache/camel/xml/in/ModelParserTest.java   | 41 ++++++++++++++++++++++
 .../java/org/apache/camel/xml/jaxb/JaxbHelper.java | 33 ++++++++++++++++-
 4 files changed, 90 insertions(+), 1 deletion(-)

diff --git a/core/camel-util/src/main/java/org/apache/camel/util/URISupport.java b/core/camel-util/src/main/java/org/apache/camel/util/URISupport.java
index 82de5b94ad9..3a26d3c5105 100644
--- a/core/camel-util/src/main/java/org/apache/camel/util/URISupport.java
+++ b/core/camel-util/src/main/java/org/apache/camel/util/URISupport.java
@@ -794,4 +794,17 @@ public final class URISupport {
         return joined.toString();
     }
 
+    public static String removeNoiseFromUri(String uri) {
+        String before = StringHelper.before(uri, "?");
+        String after = StringHelper.after(uri, "?");
+
+        if (before != null && after != null) {
+            String changed = after.replaceAll("&\\s+", "&").trim();
+            if (!after.equals(changed)) {
+                String newAtr = before.trim() + "?" + changed;
+                return newAtr;
+            }
+        }
+        return uri;
+    }
 }
diff --git a/core/camel-xml-io/src/main/java/org/apache/camel/xml/in/BaseParser.java b/core/camel-xml-io/src/main/java/org/apache/camel/xml/in/BaseParser.java
index 96f892e7a8f..acb837499dc 100644
--- a/core/camel-xml-io/src/main/java/org/apache/camel/xml/in/BaseParser.java
+++ b/core/camel-xml-io/src/main/java/org/apache/camel/xml/in/BaseParser.java
@@ -35,6 +35,7 @@ import org.apache.camel.LineNumberAware;
 import org.apache.camel.model.language.ExpressionDefinition;
 import org.apache.camel.spi.NamespaceAware;
 import org.apache.camel.spi.Resource;
+import org.apache.camel.util.URISupport;
 import org.apache.camel.xml.io.MXParser;
 import org.apache.camel.xml.io.XmlPullParser;
 import org.apache.camel.xml.io.XmlPullParserException;
@@ -105,6 +106,9 @@ public class BaseParser {
             String name = parser.getAttributeName(i);
             String ns = parser.getAttributeNamespace(i);
             String val = parser.getAttributeValue(i);
+            if (name.equals("uri") || name.endsWith("Uri")) {
+                val = URISupport.removeNoiseFromUri(val);
+            }
             if (Objects.equals(ns, "") || Objects.equals(ns, namespace)) {
                 if (attributeHandler == null || !attributeHandler.accept(definition, name, val)) {
                     handleUnexpectedAttribute(namespace, name);
diff --git a/core/camel-xml-io/src/test/java/org/apache/camel/xml/in/ModelParserTest.java b/core/camel-xml-io/src/test/java/org/apache/camel/xml/in/ModelParserTest.java
index a8b49a5d483..dc42173eb4a 100644
--- a/core/camel-xml-io/src/test/java/org/apache/camel/xml/in/ModelParserTest.java
+++ b/core/camel-xml-io/src/test/java/org/apache/camel/xml/in/ModelParserTest.java
@@ -28,12 +28,14 @@ import java.util.Map;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
+import org.apache.camel.model.FromDefinition;
 import org.apache.camel.model.PropertyDefinition;
 import org.apache.camel.model.RouteDefinition;
 import org.apache.camel.model.RouteTemplatesDefinition;
 import org.apache.camel.model.RoutesDefinition;
 import org.apache.camel.model.SetBodyDefinition;
 import org.apache.camel.model.TemplatedRoutesDefinition;
+import org.apache.camel.model.ToDefinition;
 import org.apache.camel.model.language.XPathExpression;
 import org.apache.camel.model.rest.ParamDefinition;
 import org.apache.camel.model.rest.RestDefinition;
@@ -199,6 +201,45 @@ public class ModelParserTest {
         Assertions.assertEquals(4, param.getAllowableValues().size());
     }
 
+    @Test
+    public void testUriLineBreak() throws Exception {
+        final String fromFrag1 = "seda:a?concurrentConsumers=2&amp;";
+        final String fromFrag2 = "defaultPollTimeout=500";
+        final String jpaFrag1 = "jpa:SomeClass?query=update Object o";
+        final String jpaSpaces = "        ";
+        final String jpaFrag2 = "set o.status = 0";
+        final String toFrag1 = "seda:b?";
+        final String toFrag2 = "lazyStartProducer=true&amp;";
+        final String toFrag3 = "defaultBlockWhenFull=true";
+        final String routesXml = "<routes xmlns=\"" + NAMESPACE + "\">\n"
+                                 + "  <route>\n"
+                                 + "    <from uri=\"" + fromFrag1 + "\n"
+                                 + "        " + fromFrag2 + "\n"
+                                 + "        \"/>\n"
+                                 + "    <to uri=\"" + jpaFrag1 + "\n"
+                                 + jpaSpaces + jpaFrag2 + "\"/>\n"
+                                 + "    <to uri=\"" + toFrag1 + "\n"
+                                 + "        " + toFrag2 + "\n"
+                                 + "        " + toFrag3 + "\"/>\n"
+                                 + "  </route>\n"
+                                 + "</routes>";
+        final RoutesDefinition routes
+                = new ModelParser(new StringReader(routesXml), NAMESPACE).parseRoutesDefinition().orElse(null);
+        final RouteDefinition route = routes.getRoutes().get(0);
+        final FromDefinition from = route.getInput();
+
+        final ToDefinition jpa = (ToDefinition) route.getOutputs().get(0);
+        final ToDefinition to = (ToDefinition) route.getOutputs().get(1);
+
+        final String fromUri = (fromFrag1 + fromFrag2).replace("&amp;", "&");
+        final String jpaUri = jpaFrag1 + " " + jpaSpaces + jpaFrag2; // \n is changed to a single space
+        final String toUri = (toFrag1 + toFrag2 + toFrag3).replace("&amp;", "&");
+
+        Assertions.assertEquals(fromUri, from.getEndpointUri());
+        Assertions.assertEquals(jpaUri, jpa.getEndpointUri());
+        Assertions.assertEquals(toUri, to.getEndpointUri());
+    }
+
     private Path getResourceFolder() {
         String url = getClass().getClassLoader().getResource("barInterceptorRoute.xml").toString();
         if (url.startsWith("file:")) {
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 9e22aec53f9..7f4a830cc57 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
@@ -29,10 +29,12 @@ import javax.xml.bind.JAXBContext;
 import javax.xml.bind.JAXBException;
 import javax.xml.bind.Unmarshaller;
 
+import org.w3c.dom.Attr;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.NamedNodeMap;
 import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
 
 import org.apache.camel.CamelContext;
 import org.apache.camel.Expression;
@@ -59,6 +61,7 @@ import org.apache.camel.model.rest.RestDefinition;
 import org.apache.camel.model.rest.RestsDefinition;
 import org.apache.camel.spi.NamespaceAware;
 import org.apache.camel.util.KeyValueHolder;
+import org.apache.camel.util.URISupport;
 
 import static org.apache.camel.model.ProcessorDefinitionHelper.filterTypeInOutputs;
 
@@ -270,6 +273,7 @@ public final class JaxbHelper {
     public static RoutesDefinition loadRoutesDefinition(CamelContext context, InputStream inputStream) throws Exception {
         XmlConverter xmlConverter = newXmlConverter(context);
         Document dom = xmlConverter.toDOMDocument(inputStream, null);
+        removeNoiseFromUris(dom.getDocumentElement());
 
         JAXBContext jaxbContext = getJAXBContext(context);
 
@@ -350,6 +354,7 @@ public final class JaxbHelper {
             throws Exception {
         XmlConverter xmlConverter = newXmlConverter(context);
         Document dom = xmlConverter.toDOMDocument(inputStream, null);
+        removeNoiseFromUris(dom.getDocumentElement());
 
         JAXBContext jaxbContext = getJAXBContext(context);
 
@@ -388,7 +393,7 @@ public final class JaxbHelper {
 
     /**
      * Un-marshals the content of the input stream to an instance of {@link TemplatedRoutesDefinition}.
-     * 
+     *
      * @param  context     the Camel context from which the JAXBContext is extracted
      * @param  inputStream the input stream to unmarshal
      * @return             the content unmarshalled as a {@link TemplatedRoutesDefinition}.
@@ -398,6 +403,7 @@ public final class JaxbHelper {
             throws Exception {
         XmlConverter xmlConverter = newXmlConverter(context);
         Document dom = xmlConverter.toDOMDocument(inputStream, null);
+        removeNoiseFromUris(dom.getDocumentElement());
 
         JAXBContext jaxbContext = getJAXBContext(context);
 
@@ -448,6 +454,7 @@ public final class JaxbHelper {
     public static RestsDefinition loadRestsDefinition(CamelContext context, InputStream inputStream) throws Exception {
         // load routes using JAXB
         Document dom = newXmlConverter(context).toDOMDocument(inputStream, null);
+        removeNoiseFromUris(dom.getDocumentElement());
 
         if (!CAMEL_NS.equals(dom.getDocumentElement().getNamespaceURI())) {
             addNamespaceToDom(dom);
@@ -474,4 +481,28 @@ public final class JaxbHelper {
 
         return answer;
     }
+
+    private static void removeNoiseFromUris(Element element) {
+        final NamedNodeMap attrs = element.getAttributes();
+
+        for (int index = 0; index < attrs.getLength(); index++) {
+            final Attr attr = (Attr) attrs.item(index);
+            final String attName = attr.getName();
+
+            if (attName.equals("uri") || attName.endsWith("Uri")) {
+                attr.setValue(URISupport.removeNoiseFromUri(attr.getValue()));
+            }
+        }
+
+        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) {
+                removeNoiseFromUris((Element) child);
+            }
+        }
+    }
+
 }