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 2021/12/10 09:21:32 UTC

[camel] branch main updated (d779451 -> 6831f37)

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

davsclaus pushed a change to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git.


    from d779451  Sync deps
     new 8d8aabd  CAMEL-17295: Added unit test
     new 6831f37  CAMEL-17295: rest-dsl - Fix parse uri template for query parameters.

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 ...rdsTest.java => RestServletQueryParamTest.java} |  39 +++---
 ...Test.java => RestServletQueryParamUriTest.java} |  33 ++---
 .../apache/camel/model/rest/RestDefinition.java    | 145 +++++++++++++--------
 3 files changed, 130 insertions(+), 87 deletions(-)
 copy components/camel-servlet/src/test/java/org/apache/camel/component/servlet/rest/{RestServletGetWildcardsTest.java => RestServletQueryParamTest.java} (65%)
 copy components/camel-servlet/src/test/java/org/apache/camel/component/servlet/rest/{RestServletGetWildcardsTest.java => RestServletQueryParamUriTest.java} (68%)

[camel] 02/02: CAMEL-17295: rest-dsl - Fix parse uri template for query parameters.

Posted by da...@apache.org.
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 6831f37c94e4906873a4836e8c1c2e34383951be
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Fri Dec 10 07:59:11 2021 +0100

    CAMEL-17295: rest-dsl - Fix parse uri template for query parameters.
---
 .../servlet/rest/RestServletQueryParamTest.java    |  20 ++-
 ...Test.java => RestServletQueryParamUriTest.java} |  28 ++--
 .../apache/camel/model/rest/RestDefinition.java    | 145 +++++++++++++--------
 3 files changed, 123 insertions(+), 70 deletions(-)

diff --git a/components/camel-servlet/src/test/java/org/apache/camel/component/servlet/rest/RestServletQueryParamTest.java b/components/camel-servlet/src/test/java/org/apache/camel/component/servlet/rest/RestServletQueryParamTest.java
index 68f7d29..4b49f8d 100644
--- a/components/camel-servlet/src/test/java/org/apache/camel/component/servlet/rest/RestServletQueryParamTest.java
+++ b/components/camel-servlet/src/test/java/org/apache/camel/component/servlet/rest/RestServletQueryParamTest.java
@@ -31,7 +31,7 @@ public class RestServletQueryParamTest extends ServletCamelRouterTestSupport {
     private ServletRestHttpBinding restHttpBinding = new ServletRestHttpBinding();
 
     @Test
-    public void testServletProducerGet() throws Exception {
+    public void testQueryTrue() throws Exception {
         WebRequest req = new GetMethodWebRequest(contextUrl + "/services/users/");
         req.setParameter("auth", "secret");
         WebResponse response = query(req, false);
@@ -41,25 +41,35 @@ public class RestServletQueryParamTest extends ServletCamelRouterTestSupport {
         assertEquals("secret;Donald Duck", response.getText());
     }
 
+    @Test
+    public void testQueryFalse() throws Exception {
+        WebRequest req = new GetMethodWebRequest(contextUrl + "/services/users/");
+        WebResponse response = query(req, false);
+
+        assertEquals(400, response.getResponseCode());
+    }
+
     @Override
     protected RouteBuilder createRouteBuilder() throws Exception {
         return new RouteBuilder() {
             @Override
             public void configure() throws Exception {
                 // configure to use servlet on localhost
-                restConfiguration().component("servlet").host("localhost").endpointProperty("httpBinding", "#myBinding");
+                restConfiguration().component("servlet").host("localhost").endpointProperty("httpBinding", "#myBinding")
+                        .clientRequestValidation(true);
 
                 // use the rest DSL to define the rest services
                 rest()
-                    .get("/users/?auth={myToken}")
+                    .get("/users/")
                         .param()
                             .name("auth")
                             .type(RestParamType.query)
+                            .required(true)
                         .endParam()
                     .route().to("mock:input").process(exchange -> {
                         String auth = exchange.getIn().getHeader("auth", String.class);
-                        exchange.getMessage().setBody(auth + ";Donald Duck");
-                    });
+                            exchange.getMessage().setBody(auth + ";Donald Duck");
+                        });
             }
         };
     }
diff --git a/components/camel-servlet/src/test/java/org/apache/camel/component/servlet/rest/RestServletQueryParamTest.java b/components/camel-servlet/src/test/java/org/apache/camel/component/servlet/rest/RestServletQueryParamUriTest.java
similarity index 73%
copy from components/camel-servlet/src/test/java/org/apache/camel/component/servlet/rest/RestServletQueryParamTest.java
copy to components/camel-servlet/src/test/java/org/apache/camel/component/servlet/rest/RestServletQueryParamUriTest.java
index 68f7d29..4ed1b34 100644
--- a/components/camel-servlet/src/test/java/org/apache/camel/component/servlet/rest/RestServletQueryParamTest.java
+++ b/components/camel-servlet/src/test/java/org/apache/camel/component/servlet/rest/RestServletQueryParamUriTest.java
@@ -20,18 +20,17 @@ import org.apache.camel.BindToRegistry;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.component.servlet.ServletCamelRouterTestSupport;
 import org.apache.camel.component.servlet.ServletRestHttpBinding;
-import org.apache.camel.model.rest.RestParamType;
 import org.junit.jupiter.api.Test;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 
-public class RestServletQueryParamTest extends ServletCamelRouterTestSupport {
+public class RestServletQueryParamUriTest extends ServletCamelRouterTestSupport {
 
     @BindToRegistry("myBinding")
     private ServletRestHttpBinding restHttpBinding = new ServletRestHttpBinding();
 
     @Test
-    public void testServletProducerGet() throws Exception {
+    public void testQueryTrue() throws Exception {
         WebRequest req = new GetMethodWebRequest(contextUrl + "/services/users/");
         req.setParameter("auth", "secret");
         WebResponse response = query(req, false);
@@ -41,25 +40,32 @@ public class RestServletQueryParamTest extends ServletCamelRouterTestSupport {
         assertEquals("secret;Donald Duck", response.getText());
     }
 
+    @Test
+    public void testQueryFalse() throws Exception {
+        WebRequest req = new GetMethodWebRequest(contextUrl + "/services/users/");
+        WebResponse response = query(req, false);
+
+        // we do not know if the query was required, so we cannot validate this
+        assertEquals(200, response.getResponseCode());
+        assertEquals("null;Donald Duck", response.getText());
+    }
+
     @Override
     protected RouteBuilder createRouteBuilder() throws Exception {
         return new RouteBuilder() {
             @Override
             public void configure() throws Exception {
                 // configure to use servlet on localhost
-                restConfiguration().component("servlet").host("localhost").endpointProperty("httpBinding", "#myBinding");
+                restConfiguration().component("servlet").host("localhost").endpointProperty("httpBinding", "#myBinding")
+                        .clientRequestValidation(true);
 
                 // use the rest DSL to define the rest services
                 rest()
-                    .get("/users/?auth={myToken}")
-                        .param()
-                            .name("auth")
-                            .type(RestParamType.query)
-                        .endParam()
+                    .get("/users/?auth={myAuth}")
                     .route().to("mock:input").process(exchange -> {
                         String auth = exchange.getIn().getHeader("auth", String.class);
-                        exchange.getMessage().setBody(auth + ";Donald Duck");
-                    });
+                            exchange.getMessage().setBody(auth + ";Donald Duck");
+                        });
             }
         };
     }
diff --git a/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestDefinition.java b/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestDefinition.java
index e56a633..df627cd 100644
--- a/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestDefinition.java
+++ b/core/camel-core-model/src/main/java/org/apache/camel/model/rest/RestDefinition.java
@@ -16,7 +16,6 @@
  */
 package org.apache.camel.model.rest;
 
-import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -792,13 +791,11 @@ public class RestDefinition extends OptionalIdentifiedDefinition<RestDefinition>
         }
 
         if (!options.isEmpty()) {
-            String query;
             try {
-                query = URISupport.createQueryString(options);
-            } catch (URISyntaxException e) {
+                from = URISupport.appendParametersToURI(from, options);
+            } catch (Exception e) {
                 throw RuntimeCamelException.wrapRuntimeCamelException(e);
             }
-            from = from + "?" + query;
         }
 
         // we use the same uri as the producer (so we have a little route for
@@ -885,9 +882,6 @@ public class RestDefinition extends OptionalIdentifiedDefinition<RestDefinition>
 
             route.setRestBindingDefinition(binding);
 
-            // create the from endpoint uri which is using the rest component
-            String from = buildFromUri(verb);
-
             // append options
             Map<String, Object> options = new HashMap<>();
             // verb takes precedence over configuration on rest
@@ -934,16 +928,6 @@ public class RestDefinition extends OptionalIdentifiedDefinition<RestDefinition>
                 options.put("description", description);
             }
 
-            if (!options.isEmpty()) {
-                String query;
-                try {
-                    query = URISupport.createQueryString(options);
-                } catch (URISyntaxException e) {
-                    throw RuntimeCamelException.wrapRuntimeCamelException(e);
-                }
-                from = from + "?" + query;
-            }
-
             String path = getPath();
             String s1 = FileUtil.stripTrailingSeparator(path);
             String s2 = FileUtil.stripLeadingSeparator(verb.getUri());
@@ -957,42 +941,17 @@ public class RestDefinition extends OptionalIdentifiedDefinition<RestDefinition>
             }
 
             // each {} is a parameter (url templating)
-            if (allPath != null) {
-                String[] arr = allPath.split("\\/");
-                for (String a : arr) {
-                    // need to resolve property placeholders first
-                    try {
-                        a = camelContext.resolvePropertyPlaceholders(a);
-                    } catch (Exception e) {
-                        throw RuntimeCamelException.wrapRuntimeCamelException(e);
-                    }
-
-                    Matcher m = Pattern.compile("\\{(.*?)\\}").matcher(a);
-                    while (m.find()) {
-                        String key = m.group(1);
-                        //  merge if exists
-                        boolean found = false;
-                        for (RestOperationParamDefinition param : verb.getParams()) {
-                            // name is mandatory
-                            String name = param.getName();
-                            StringHelper.notEmpty(name, "parameter name");
-                            // need to resolve property placeholders first
-                            try {
-                                name = camelContext.resolvePropertyPlaceholders(name);
-                            } catch (Exception e) {
-                                throw RuntimeCamelException.wrapRuntimeCamelException(e);
-                            }
-                            if (name.equalsIgnoreCase(key)) {
-                                param.type(RestParamType.path);
-                                found = true;
-                                break;
-                            }
-                        }
-                        if (!found) {
-                            param(verb).name(key).type(RestParamType.path).endParam();
-                        }
-                    }
-                }
+            Set<String> toRemove = null;
+            if (allPath != null && allPath.contains("?")) {
+                // special when having query parameters
+                String path1 = StringHelper.before(allPath, "?");
+                uriTemplating(camelContext, verb, path1, false);
+                String path2 = StringHelper.after(allPath, "?");
+                // there may be some query parameters that are templates which we then must remove
+                toRemove = uriTemplating(camelContext, verb, path2, true);
+            } else {
+                // no query parameters
+                uriTemplating(camelContext, verb, allPath, false);
             }
 
             if (verb.getType() != null) {
@@ -1010,6 +969,36 @@ public class RestDefinition extends OptionalIdentifiedDefinition<RestDefinition>
                 }
             }
 
+            // create the from endpoint uri which is using the rest component
+            String from = buildFromUri(verb);
+
+            // rebuild uri without these query parameters
+            if (toRemove != null && !toRemove.isEmpty()) {
+                try {
+                    Map<String, Object> query = URISupport.parseQuery(URISupport.extractQuery(from));
+                    // remove if the value matches, eg: auth={myAuth}
+                    toRemove.forEach(v -> {
+                        query.values().removeIf(qv -> qv.toString().equals(v));
+                    });
+                    from = URISupport.stripQuery(from);
+                    if (!query.isEmpty()) {
+                        String q = URISupport.createQueryString(query);
+                        from = URISupport.stripQuery(from) + "?" + q;
+                    }
+                } catch (Exception e) {
+                    throw RuntimeCamelException.wrapRuntimeCamelException(e);
+                }
+            }
+
+            // append additional options
+            if (!options.isEmpty()) {
+                try {
+                    from = URISupport.appendParametersToURI(from, options);
+                } catch (Exception e) {
+                    throw RuntimeCamelException.wrapRuntimeCamelException(e);
+                }
+            }
+
             // the route should be from this rest endpoint
             route.fromRest(from);
             route.setRestDefinition(this);
@@ -1017,6 +1006,54 @@ public class RestDefinition extends OptionalIdentifiedDefinition<RestDefinition>
         }
     }
 
+    private Set<String> uriTemplating(
+            CamelContext camelContext, VerbDefinition verb,
+            String path, boolean query) {
+
+        if (path == null) {
+            return null;
+        }
+
+        Set<String> params = new HashSet<>();
+        String[] arr = path.split("\\/");
+        for (String a : arr) {
+            // need to resolve property placeholders first
+            try {
+                a = camelContext.resolvePropertyPlaceholders(a);
+            } catch (Exception e) {
+                throw RuntimeCamelException.wrapRuntimeCamelException(e);
+            }
+
+            Matcher m = Pattern.compile("\\{(.*?)\\}").matcher(a);
+            while (m.find()) {
+                String key = m.group(1);
+                params.add("{" + key + "}");
+                //  merge if exists
+                boolean found = false;
+                for (RestOperationParamDefinition param : verb.getParams()) {
+                    // name is mandatory
+                    String name = param.getName();
+                    StringHelper.notEmpty(name, "parameter name");
+                    // need to resolve property placeholders first
+                    try {
+                        name = camelContext.resolvePropertyPlaceholders(name);
+                    } catch (Exception e) {
+                        throw RuntimeCamelException.wrapRuntimeCamelException(e);
+                    }
+                    if (name.equalsIgnoreCase(key)) {
+                        param.type(query ? RestParamType.query : RestParamType.path);
+                        found = true;
+                        break;
+                    }
+                }
+                if (!found) {
+                    param(verb).name(key).type(query ? RestParamType.query : RestParamType.path).endParam();
+                }
+            }
+        }
+        return params;
+    }
+
     private String buildUri(VerbDefinition verb) {
         if (path != null && verb.getUri() != null) {
             return path + ":" + verb.getUri();

[camel] 01/02: CAMEL-17295: Added unit test

Posted by da...@apache.org.
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 8d8aabdb549ff63d77c0401a6b6d72d768998ca0
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Thu Dec 9 18:22:20 2021 +0100

    CAMEL-17295: Added unit test
---
 .../servlet/rest/RestServletQueryParamTest.java    | 67 ++++++++++++++++++++++
 1 file changed, 67 insertions(+)

diff --git a/components/camel-servlet/src/test/java/org/apache/camel/component/servlet/rest/RestServletQueryParamTest.java b/components/camel-servlet/src/test/java/org/apache/camel/component/servlet/rest/RestServletQueryParamTest.java
new file mode 100644
index 0000000..68f7d29
--- /dev/null
+++ b/components/camel-servlet/src/test/java/org/apache/camel/component/servlet/rest/RestServletQueryParamTest.java
@@ -0,0 +1,67 @@
+/*
+ * 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.component.servlet.rest;
+
+import org.apache.camel.BindToRegistry;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.servlet.ServletCamelRouterTestSupport;
+import org.apache.camel.component.servlet.ServletRestHttpBinding;
+import org.apache.camel.model.rest.RestParamType;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class RestServletQueryParamTest extends ServletCamelRouterTestSupport {
+
+    @BindToRegistry("myBinding")
+    private ServletRestHttpBinding restHttpBinding = new ServletRestHttpBinding();
+
+    @Test
+    public void testServletProducerGet() throws Exception {
+        WebRequest req = new GetMethodWebRequest(contextUrl + "/services/users/");
+        req.setParameter("auth", "secret");
+        WebResponse response = query(req, false);
+
+        assertEquals(200, response.getResponseCode());
+
+        assertEquals("secret;Donald Duck", response.getText());
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                // configure to use servlet on localhost
+                restConfiguration().component("servlet").host("localhost").endpointProperty("httpBinding", "#myBinding");
+
+                // use the rest DSL to define the rest services
+                rest()
+                    .get("/users/?auth={myToken}")
+                        .param()
+                            .name("auth")
+                            .type(RestParamType.query)
+                        .endParam()
+                    .route().to("mock:input").process(exchange -> {
+                        String auth = exchange.getIn().getHeader("auth", String.class);
+                        exchange.getMessage().setBody(auth + ";Donald Duck");
+                    });
+            }
+        };
+    }
+
+}