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:25:15 UTC
[camel] 01/02: 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 main
in repository https://gitbox.apache.org/repos/asf/camel.git
commit 5d8a27a27a4256beae0c6c88abfc84ac4dd4f11c
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 | 18 ++++++++++
.../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 | 32 +++++++++++++++++
4 files changed, 95 insertions(+)
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 ff02e0c330f..3664b88a99b 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
@@ -808,4 +808,22 @@ public final class URISupport {
return sb.toString();
}
+ /**
+ * Remove whitespace noise from uri, xxxUri attributes, eg new lines, and tabs etc, which allows end users to format
+ * their Camel routes in more human-readable format, but at runtime those attributes must be trimmed.
+ * The parser removes most of the noise, but keeps spaces in the attribute values
+ */
+ 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)) {
+ return before.trim() + "?" + changed;
+ }
+ }
+ 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 c90d0acfd1c..2f9a63b373b 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;
@@ -200,6 +202,45 @@ public class ModelParserTest {
Assertions.assertEquals(4, param.getAllowableValues().size());
}
+ @Test
+ public void testUriLineBreak() throws Exception {
+ final String fromFrag1 = "seda:a?concurrentConsumers=2&";
+ 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&";
+ 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("&", "&");
+ final String jpaUri = jpaFrag1 + " " + jpaSpaces + jpaFrag2; // \n is changed to a single space
+ final String toUri = (toFrag1 + toFrag2 + toFrag3).replace("&", "&");
+
+ 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 68c9e7d4be3..d54eb37e9a9 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 jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBException;
import jakarta.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.RestsDefinition;
import org.apache.camel.spi.NamespaceAware;
import org.apache.camel.support.PluginHelper;
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);
@@ -310,6 +314,7 @@ public final class JaxbHelper {
throws Exception {
XmlConverter xmlConverter = newXmlConverter(context);
Document dom = xmlConverter.toDOMDocument(inputStream, null);
+ removeNoiseFromUris(dom.getDocumentElement());
JAXBContext jaxbContext = getJAXBContext(context);
@@ -350,6 +355,7 @@ public final class JaxbHelper {
throws Exception {
XmlConverter xmlConverter = newXmlConverter(context);
Document dom = xmlConverter.toDOMDocument(inputStream, null);
+ removeNoiseFromUris(dom.getDocumentElement());
JAXBContext jaxbContext = getJAXBContext(context);
@@ -398,6 +404,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 +455,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 +482,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);
+ }
+ }
+ }
+
}