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 2016/08/26 16:02:47 UTC

[19/23] camel git commit: CAMEL-10164: swagger component for making rest calls with swagger schema validation and facade to actual HTTP client in use

CAMEL-10164: swagger component for making rest calls with swagger schema validation and facade to actual HTTP client in use


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/5c061e7e
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/5c061e7e
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/5c061e7e

Branch: refs/heads/master
Commit: 5c061e7e68c8cc01206536320b7cce578d5af1c9
Parents: 6012ddc
Author: Claus Ibsen <da...@apache.org>
Authored: Fri Aug 26 15:12:59 2016 +0200
Committer: Claus Ibsen <da...@apache.org>
Committed: Fri Aug 26 16:53:31 2016 +0200

----------------------------------------------------------------------
 .../camel/component/rest/RestComponent.java     | 10 ++--
 .../camel/component/rest/RestEndpoint.java      |  2 +-
 .../apache/camel/spi/RestProducerFactory.java   |  4 +-
 .../common/HttpRestHeaderFilterStrategy.java    | 56 ++++++++++++++++++
 .../component/jetty/JettyHttpComponent.java     | 15 +++--
 .../rest/producer/JettyRestProducerGetTest.java | 34 ++++++-----
 .../JettyRestProducerGetUriParameterTest.java   | 59 +++++++++++++++++++
 .../netty4/http/NettyHttpComponent.java         | 12 ++--
 .../http/NettyHttpRestHeaderFilterStrategy.java | 60 ++++++++++++++++++++
 .../http/rest/RestNettyProducerGetTest.java     |  3 +-
 .../RestNettyProducerGetUriParameterTest.java   | 60 ++++++++++++++++++++
 .../component/restlet/RestletComponent.java     |  2 +-
 .../RestRestletProducerGetUriParameterTest.java | 60 ++++++++++++++++++++
 .../component/undertow/UndertowComponent.java   | 11 ++--
 .../UndertowRestHeaderFilterStrategy.java       | 56 ++++++++++++++++++
 ...RestUndertowProducerGetUriParameterTest.java | 59 +++++++++++++++++++
 16 files changed, 463 insertions(+), 40 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/5c061e7e/camel-core/src/main/java/org/apache/camel/component/rest/RestComponent.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/component/rest/RestComponent.java b/camel-core/src/main/java/org/apache/camel/component/rest/RestComponent.java
index d5c471c..f8245c6 100644
--- a/camel-core/src/main/java/org/apache/camel/component/rest/RestComponent.java
+++ b/camel-core/src/main/java/org/apache/camel/component/rest/RestComponent.java
@@ -59,14 +59,14 @@ public class RestComponent extends UriEndpointComponent {
         }
         answer.setHost(h);
 
-        setProperties(answer, parameters);
-        answer.setParameters(parameters);
-        // the rest is URI parameters on path
-        String query = URISupport.createQueryString(parameters);
-        if (ObjectHelper.isNotEmpty(query)) {
+        String query = ObjectHelper.after(uri, "?");
+        if (query != null) {
             answer.setQueryParameters(query);
         }
 
+        setProperties(answer, parameters);
+        answer.setParameters(parameters);
+
         if (!remaining.contains(":")) {
             throw new IllegalArgumentException("Invalid syntax. Must be rest:method:path[:uriTemplate] where uriTemplate is optional");
         }

http://git-wip-us.apache.org/repos/asf/camel/blob/5c061e7e/camel-core/src/main/java/org/apache/camel/component/rest/RestEndpoint.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/component/rest/RestEndpoint.java b/camel-core/src/main/java/org/apache/camel/component/rest/RestEndpoint.java
index daaa459..741c408 100644
--- a/camel-core/src/main/java/org/apache/camel/component/rest/RestEndpoint.java
+++ b/camel-core/src/main/java/org/apache/camel/component/rest/RestEndpoint.java
@@ -316,7 +316,7 @@ public class RestEndpoint extends DefaultEndpoint {
 
         if (factory != null) {
             LOG.debug("Using RestProducerFactory: {}", factory);
-            Producer producer = factory.createProducer(getCamelContext(), host, method, path, uriTemplate, consumes, produces, parameters);
+            Producer producer = factory.createProducer(getCamelContext(), host, method, path, uriTemplate, queryParameters, consumes, produces, parameters);
             return new RestProducer(this, producer);
         } else {
             throw new IllegalStateException("Cannot find RestProducerFactory in Registry or as a Component to use");

http://git-wip-us.apache.org/repos/asf/camel/blob/5c061e7e/camel-core/src/main/java/org/apache/camel/spi/RestProducerFactory.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/spi/RestProducerFactory.java b/camel-core/src/main/java/org/apache/camel/spi/RestProducerFactory.java
index f3ab1f7..23dc995 100644
--- a/camel-core/src/main/java/org/apache/camel/spi/RestProducerFactory.java
+++ b/camel-core/src/main/java/org/apache/camel/spi/RestProducerFactory.java
@@ -36,6 +36,7 @@ public interface RestProducerFactory {
      * @param verb                HTTP verb such as GET, POST
      * @param basePath            base path
      * @param uriTemplate         uri template
+     * @param queryParameters     uri query parameters
      * @param consumes            media-types for what the REST service consume as input (accept-type), is <tt>null</tt> or <tt>&#42;/&#42;</tt> for anything
      * @param produces            media-types for what the REST service produces as output, can be <tt>null</tt>
      * @param parameters          additional parameters
@@ -43,5 +44,6 @@ public interface RestProducerFactory {
      * @throws Exception can be thrown
      */
     Producer createProducer(CamelContext camelContext, String host,
-                            String verb, String basePath, String uriTemplate, String consumes, String produces, Map<String, Object> parameters) throws Exception;
+                            String verb, String basePath, String uriTemplate, String queryParameters,
+                            String consumes, String produces, Map<String, Object> parameters) throws Exception;
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/5c061e7e/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpRestHeaderFilterStrategy.java
----------------------------------------------------------------------
diff --git a/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpRestHeaderFilterStrategy.java b/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpRestHeaderFilterStrategy.java
new file mode 100644
index 0000000..762fe03
--- /dev/null
+++ b/components/camel-http-common/src/main/java/org/apache/camel/http/common/HttpRestHeaderFilterStrategy.java
@@ -0,0 +1,56 @@
+/**
+ * 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.http.common;
+
+import org.apache.camel.Exchange;
+
+public class HttpRestHeaderFilterStrategy extends HttpHeaderFilterStrategy {
+
+    private final String templateUri;
+    private final String queryParameters;
+
+    public HttpRestHeaderFilterStrategy(String templateUri, String queryParameters) {
+        super();
+        this.templateUri = templateUri;
+        this.queryParameters = queryParameters;
+    }
+
+    @Override
+    public boolean applyFilterToCamelHeaders(String headerName, Object headerValue, Exchange exchange) {
+        boolean answer = super.applyFilterToExternalHeaders(headerName, headerValue, exchange);
+        // using rest producer then headers are mapping to uri and query parameters using {key} syntax
+        // if there is a match to an existing Camel Message header, then we should filter (=true) this
+        // header as its already been mapped by the RestProducer from camel-core, and we do not want
+        // the header to included as HTTP header also (eg as duplicate value)
+        if (!answer) {
+            if (templateUri != null) {
+                String token = "{" + headerName + "}";
+                if (templateUri.contains(token)) {
+                    answer = true;
+                }
+            }
+            if (!answer && queryParameters != null) {
+                String token = "=%7B" + headerName + "%7D"; // encoded values for { }
+                if (queryParameters.contains(token)) {
+                    answer = true;
+                }
+            }
+        }
+        return answer;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/5c061e7e/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java
----------------------------------------------------------------------
diff --git a/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java b/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java
index 3f1ea94..9c79767 100644
--- a/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java
+++ b/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java
@@ -38,7 +38,6 @@ import javax.servlet.http.HttpServletResponse;
 import org.apache.camel.CamelContext;
 import org.apache.camel.Consumer;
 import org.apache.camel.Endpoint;
-import org.apache.camel.Exchange;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
 import org.apache.camel.RuntimeCamelException;
@@ -48,6 +47,7 @@ import org.apache.camel.http.common.HttpCommonComponent;
 import org.apache.camel.http.common.HttpCommonEndpoint;
 import org.apache.camel.http.common.HttpConfiguration;
 import org.apache.camel.http.common.HttpConsumer;
+import org.apache.camel.http.common.HttpRestHeaderFilterStrategy;
 import org.apache.camel.http.common.HttpRestServletResolveConsumerStrategy;
 import org.apache.camel.http.common.UrlRewrite;
 import org.apache.camel.spi.HeaderFilterStrategy;
@@ -63,7 +63,6 @@ import org.apache.camel.util.HostUtils;
 import org.apache.camel.util.IntrospectionSupport;
 import org.apache.camel.util.ObjectHelper;
 import org.apache.camel.util.ServiceHelper;
-import org.apache.camel.util.StringHelper;
 import org.apache.camel.util.URISupport;
 import org.apache.camel.util.UnsafeUriCharactersEncoder;
 import org.apache.camel.util.jsse.SSLContextParameters;
@@ -1156,7 +1155,7 @@ public abstract class JettyHttpComponent extends HttpCommonComponent implements
 
     @Override
     public Producer createProducer(CamelContext camelContext, String host,
-                                   String verb, String basePath, String uriTemplate,
+                                   String verb, String basePath, String uriTemplate, String queryParameters,
                                    String consumes, String produces, Map<String, Object> parameters) throws Exception {
 
         // avoid leading slash
@@ -1164,13 +1163,19 @@ public abstract class JettyHttpComponent extends HttpCommonComponent implements
         uriTemplate = FileUtil.stripLeadingSeparator(uriTemplate);
 
         // get the endpoint
-        String url = "jetty:%s/%s/%s";
-        url = String.format(url, host, basePath, uriTemplate);
+        String url;
+        if (uriTemplate != null) {
+            url = String.format("jetty:%s/%s/%s", host, basePath, uriTemplate);
+        } else {
+            url = String.format("jetty:%s/%s", host, basePath);
+        }
 
         JettyHttpEndpoint endpoint = camelContext.getEndpoint(url, JettyHttpEndpoint.class);
         if (parameters != null && !parameters.isEmpty()) {
             setProperties(camelContext, endpoint, parameters);
         }
+        String path = uriTemplate != null ? uriTemplate : basePath;
+        endpoint.setHeaderFilterStrategy(new HttpRestHeaderFilterStrategy(path, queryParameters));
 
         return endpoint.createProducer();
     }

http://git-wip-us.apache.org/repos/asf/camel/blob/5c061e7e/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/rest/producer/JettyRestProducerGetTest.java
----------------------------------------------------------------------
diff --git a/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/rest/producer/JettyRestProducerGetTest.java b/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/rest/producer/JettyRestProducerGetTest.java
index 58720cd..89c19cf 100644
--- a/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/rest/producer/JettyRestProducerGetTest.java
+++ b/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/rest/producer/JettyRestProducerGetTest.java
@@ -16,6 +16,8 @@
  */
 package org.apache.camel.component.jetty.rest.producer;
 
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
 import org.apache.camel.RoutesBuilder;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.component.jetty.BaseJettyTest;
@@ -24,27 +26,33 @@ import org.junit.Test;
 public class JettyRestProducerGetTest extends BaseJettyTest {
 
     @Test
-    public void testRestGet() throws Exception {
-        getMockEndpoint("mock:result").expectedBodiesReceived("Hello Donald Duck");
-
-        template.sendBodyAndHeader("direct:start", null, "name", "Donald Duck");
-
-        assertMockEndpointsSatisfied();
+    public void testJettyProducerGet() throws Exception {
+        String out = fluentTemplate.withHeader("id", "123").to("direct:start").request(String.class);
+        assertEquals("123;Donald Duck", out);
     }
 
     @Override
-    protected RoutesBuilder createRouteBuilder() throws Exception {
+    protected RouteBuilder createRouteBuilder() throws Exception {
         return new RouteBuilder() {
             @Override
             public void configure() throws Exception {
-                restConfiguration().producerComponent("jetty").host("localhost").port(getPort());
+                // configure to use localhost with the given port
+                restConfiguration().component("jetty").host("localhost").port(getPort());
 
                 from("direct:start")
-                        .to("rest:get:api:hello/hi/{name}")
-                        .to("mock:result");
-
-                from("jetty:http://localhost:{{port}}/api/hello/hi/?matchOnUriPrefix=true")
-                    .transform().constant("Hello Donald Duck");
+                        .to("rest:get:users/{id}/basic");
+
+                // use the rest DSL to define the rest services
+                rest("/users/")
+                        .get("{id}/basic")
+                        .route()
+                        .to("mock:input")
+                        .process(new Processor() {
+                            public void process(Exchange exchange) throws Exception {
+                                String id = exchange.getIn().getHeader("id", String.class);
+                                exchange.getOut().setBody(id + ";Donald Duck");
+                            }
+                        });
             }
         };
     }

http://git-wip-us.apache.org/repos/asf/camel/blob/5c061e7e/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/rest/producer/JettyRestProducerGetUriParameterTest.java
----------------------------------------------------------------------
diff --git a/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/rest/producer/JettyRestProducerGetUriParameterTest.java b/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/rest/producer/JettyRestProducerGetUriParameterTest.java
new file mode 100644
index 0000000..efa8975
--- /dev/null
+++ b/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/rest/producer/JettyRestProducerGetUriParameterTest.java
@@ -0,0 +1,59 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.jetty.rest.producer;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.jetty.BaseJettyTest;
+import org.junit.Test;
+
+public class JettyRestProducerGetUriParameterTest extends BaseJettyTest {
+
+    @Test
+    public void testJettyProducerGet() throws Exception {
+        String out = fluentTemplate.withHeader("id", "123").to("direct:start").request(String.class);
+        assertEquals("123;Donald Duck", out);
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                // configure to use localhost with the given port
+                restConfiguration().component("jetty").host("localhost").port(getPort());
+
+                from("direct:start")
+                        .to("rest:get:users/basic?id={id}");
+
+                // use the rest DSL to define the rest services
+                rest("/users/")
+                        .get("basic/?id={id}")
+                        .route()
+                        .to("mock:input")
+                        .process(new Processor() {
+                            public void process(Exchange exchange) throws Exception {
+                                String id = exchange.getIn().getHeader("id", String.class);
+                                exchange.getOut().setBody(id + ";Donald Duck");
+                            }
+                        });
+            }
+        };
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/5c061e7e/components/camel-netty4-http/src/main/java/org/apache/camel/component/netty4/http/NettyHttpComponent.java
----------------------------------------------------------------------
diff --git a/components/camel-netty4-http/src/main/java/org/apache/camel/component/netty4/http/NettyHttpComponent.java b/components/camel-netty4-http/src/main/java/org/apache/camel/component/netty4/http/NettyHttpComponent.java
index c623250..5cbea53 100644
--- a/components/camel-netty4-http/src/main/java/org/apache/camel/component/netty4/http/NettyHttpComponent.java
+++ b/components/camel-netty4-http/src/main/java/org/apache/camel/component/netty4/http/NettyHttpComponent.java
@@ -381,28 +381,28 @@ public class NettyHttpComponent extends NettyComponent implements HeaderFilterSt
 
     @Override
     public Producer createProducer(CamelContext camelContext, String host,
-                                   String verb, String basePath, String uriTemplate,
+                                   String verb, String basePath, String uriTemplate, String queryParameters,
                                    String consumes, String produces, Map<String, Object> parameters) throws Exception {
 
         // avoid leading slash
         basePath = FileUtil.stripLeadingSeparator(basePath);
         uriTemplate = FileUtil.stripLeadingSeparator(uriTemplate);
 
-        // restlet method must be in upper-case
-        String restletMethod = verb.toUpperCase(Locale.US);
-
         // get the endpoint
         String url;
         if (uriTemplate != null) {
-            url = String.format("netty4-http:%s/%s/%s?restletMethods=%s", host, basePath, uriTemplate, restletMethod);
+            url = String.format("netty4-http:%s/%s/%s", host, basePath, uriTemplate);
         } else {
-            url = String.format("netty4-http:%s/%s?restletMethods=%s", host, basePath, restletMethod);
+            url = String.format("netty4-http:%s/%s", host, basePath);
         }
 
+
         NettyHttpEndpoint endpoint = camelContext.getEndpoint(url, NettyHttpEndpoint.class);
         if (parameters != null && !parameters.isEmpty()) {
             setProperties(camelContext, endpoint, parameters);
         }
+        String path = uriTemplate != null ? uriTemplate : basePath;
+        endpoint.setHeaderFilterStrategy(new NettyHttpRestHeaderFilterStrategy(path, queryParameters));
 
         // the endpoint must be started before creating the producer
         ServiceHelper.startService(endpoint);

http://git-wip-us.apache.org/repos/asf/camel/blob/5c061e7e/components/camel-netty4-http/src/main/java/org/apache/camel/component/netty4/http/NettyHttpRestHeaderFilterStrategy.java
----------------------------------------------------------------------
diff --git a/components/camel-netty4-http/src/main/java/org/apache/camel/component/netty4/http/NettyHttpRestHeaderFilterStrategy.java b/components/camel-netty4-http/src/main/java/org/apache/camel/component/netty4/http/NettyHttpRestHeaderFilterStrategy.java
new file mode 100644
index 0000000..c168ed0
--- /dev/null
+++ b/components/camel-netty4-http/src/main/java/org/apache/camel/component/netty4/http/NettyHttpRestHeaderFilterStrategy.java
@@ -0,0 +1,60 @@
+/**
+ * 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.netty4.http;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.spi.HeaderFilterStrategy;
+
+/**
+ * Default Netty {@link HeaderFilterStrategy} used when binding with {@link NettyHttpBinding}.
+ */
+public class NettyHttpRestHeaderFilterStrategy extends NettyHttpHeaderFilterStrategy {
+
+    private final String templateUri;
+    private final String queryParameters;
+
+    public NettyHttpRestHeaderFilterStrategy(String templateUri, String queryParameters) {
+        super();
+        this.templateUri = templateUri;
+        this.queryParameters = queryParameters;
+    }
+
+    @Override
+    public boolean applyFilterToCamelHeaders(String headerName, Object headerValue, Exchange exchange) {
+        boolean answer = super.applyFilterToExternalHeaders(headerName, headerValue, exchange);
+        // using rest producer then headers are mapping to uri and query parameters using {key} syntax
+        // if there is a match to an existing Camel Message header, then we should filter (=true) this
+        // header as its already been mapped by the RestProducer from camel-core, and we do not want
+        // the header to included as HTTP header also (eg as duplicate value)
+        if (!answer) {
+            if (templateUri != null) {
+                String token = "{" + headerName + "}";
+                if (templateUri.contains(token)) {
+                    answer = true;
+                }
+            }
+            if (!answer && queryParameters != null) {
+                String token = "=%7B" + headerName + "%7D"; // encoded values for { }
+                if (queryParameters.contains(token)) {
+                    answer = true;
+                }
+            }
+        }
+        return answer;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/5c061e7e/components/camel-netty4-http/src/test/java/org/apache/camel/component/netty4/http/rest/RestNettyProducerGetTest.java
----------------------------------------------------------------------
diff --git a/components/camel-netty4-http/src/test/java/org/apache/camel/component/netty4/http/rest/RestNettyProducerGetTest.java b/components/camel-netty4-http/src/test/java/org/apache/camel/component/netty4/http/rest/RestNettyProducerGetTest.java
index bcef723..d97214d 100644
--- a/components/camel-netty4-http/src/test/java/org/apache/camel/component/netty4/http/rest/RestNettyProducerGetTest.java
+++ b/components/camel-netty4-http/src/test/java/org/apache/camel/component/netty4/http/rest/RestNettyProducerGetTest.java
@@ -28,8 +28,7 @@ public class RestNettyProducerGetTest extends BaseNettyTest {
     public void testNettyProducerGet() throws Exception {
         String out = fluentTemplate.withHeader("id", "123").to("direct:start").request(String.class);
         assertNotNull(out);
-        // TODO: [123, 123];Donald Duck
-        // assertEquals("123;Donald Duck", out);
+        assertEquals("123;Donald Duck", out);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/camel/blob/5c061e7e/components/camel-netty4-http/src/test/java/org/apache/camel/component/netty4/http/rest/RestNettyProducerGetUriParameterTest.java
----------------------------------------------------------------------
diff --git a/components/camel-netty4-http/src/test/java/org/apache/camel/component/netty4/http/rest/RestNettyProducerGetUriParameterTest.java b/components/camel-netty4-http/src/test/java/org/apache/camel/component/netty4/http/rest/RestNettyProducerGetUriParameterTest.java
new file mode 100644
index 0000000..f42e28b
--- /dev/null
+++ b/components/camel-netty4-http/src/test/java/org/apache/camel/component/netty4/http/rest/RestNettyProducerGetUriParameterTest.java
@@ -0,0 +1,60 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.netty4.http.rest;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.netty4.http.BaseNettyTest;
+import org.junit.Test;
+
+public class RestNettyProducerGetUriParameterTest extends BaseNettyTest {
+
+    @Test
+    public void testNettyProducerGet() throws Exception {
+        String out = fluentTemplate.withHeader("id", "123").to("direct:start").request(String.class);
+        assertNotNull(out);
+        assertEquals("123;Donald Duck", out);
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                // configure to use netty on localhost with the given port
+                restConfiguration().component("netty4-http").host("localhost").port(getPort());
+
+                from("direct:start")
+                        .to("rest:get:users/basic/?id={id}");
+
+                // use the rest DSL to define the rest services
+                rest("/users/")
+                        .get("basic/?id={id}")
+                        .route()
+                        .to("mock:input")
+                        .process(new Processor() {
+                            public void process(Exchange exchange) throws Exception {
+                                String id = exchange.getIn().getHeader("id", String.class);
+                                exchange.getOut().setBody(id + ";Donald Duck");
+                            }
+                        });
+            }
+        };
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/5c061e7e/components/camel-restlet/src/main/java/org/apache/camel/component/restlet/RestletComponent.java
----------------------------------------------------------------------
diff --git a/components/camel-restlet/src/main/java/org/apache/camel/component/restlet/RestletComponent.java b/components/camel-restlet/src/main/java/org/apache/camel/component/restlet/RestletComponent.java
index 4a29ff0..fdbca18 100644
--- a/components/camel-restlet/src/main/java/org/apache/camel/component/restlet/RestletComponent.java
+++ b/components/camel-restlet/src/main/java/org/apache/camel/component/restlet/RestletComponent.java
@@ -809,7 +809,7 @@ public class RestletComponent extends HeaderFilterStrategyComponent implements R
 
     @Override
     public Producer createProducer(CamelContext camelContext, String host,
-                                   String verb, String basePath, String uriTemplate,
+                                   String verb, String basePath, String uriTemplate, String queryParameters,
                                    String consumes, String produces, Map<String, Object> parameters) throws Exception {
 
         // avoid leading slash

http://git-wip-us.apache.org/repos/asf/camel/blob/5c061e7e/components/camel-restlet/src/test/java/org/apache/camel/component/restlet/RestRestletProducerGetUriParameterTest.java
----------------------------------------------------------------------
diff --git a/components/camel-restlet/src/test/java/org/apache/camel/component/restlet/RestRestletProducerGetUriParameterTest.java b/components/camel-restlet/src/test/java/org/apache/camel/component/restlet/RestRestletProducerGetUriParameterTest.java
new file mode 100644
index 0000000..e875af1
--- /dev/null
+++ b/components/camel-restlet/src/test/java/org/apache/camel/component/restlet/RestRestletProducerGetUriParameterTest.java
@@ -0,0 +1,60 @@
+/**
+ * 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.restlet;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.RouteBuilder;
+import org.junit.Test;
+
+/**
+ * @version 
+ */
+public class RestRestletProducerGetUriParameterTest extends RestletTestSupport {
+    
+    @Test
+    public void testRestletProducerGet() throws Exception {
+        String out = fluentTemplate.withHeader("id", "123").to("direct:start").request(String.class);
+        assertEquals("123;Donald Duck", out);
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                // configure to use restlet on localhost with the given port
+                restConfiguration().component("restlet").host("localhost").port(portNum);
+
+                from("direct:start")
+                    .to("rest:get:users/basic?id={id}");
+
+                // use the rest DSL to define the rest services
+                rest("/users/")
+                        .get("basic/?id={id}")
+                        .route()
+                        .to("mock:input")
+                        .process(new Processor() {
+                            public void process(Exchange exchange) throws Exception {
+                                String id = exchange.getIn().getHeader("id", String.class);
+                                exchange.getOut().setBody(id + ";Donald Duck");
+                            }
+                        });
+            }
+        };
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/5c061e7e/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowComponent.java
----------------------------------------------------------------------
diff --git a/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowComponent.java b/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowComponent.java
index 98cf710..225fd42 100644
--- a/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowComponent.java
+++ b/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowComponent.java
@@ -235,28 +235,27 @@ public class UndertowComponent extends UriEndpointComponent implements RestConsu
 
     @Override
     public Producer createProducer(CamelContext camelContext, String host,
-                                   String verb, String basePath, String uriTemplate,
+                                   String verb, String basePath, String uriTemplate, String queryParameters,
                                    String consumes, String produces, Map<String, Object> parameters) throws Exception {
 
         // avoid leading slash
         basePath = FileUtil.stripLeadingSeparator(basePath);
         uriTemplate = FileUtil.stripLeadingSeparator(uriTemplate);
 
-        // restlet method must be in upper-case
-        String restletMethod = verb.toUpperCase(Locale.US);
-
         // get the endpoint
         String url;
         if (uriTemplate != null) {
-            url = String.format("undertow:%s/%s/%s?restletMethods=%s", host, basePath, uriTemplate, restletMethod);
+            url = String.format("undertow:%s/%s/%s", host, basePath, uriTemplate);
         } else {
-            url = String.format("undertow:%s/%s?restletMethods=%s", host, basePath, restletMethod);
+            url = String.format("undertow:%s/%s", host, basePath);
         }
 
         UndertowEndpoint endpoint = camelContext.getEndpoint(url, UndertowEndpoint.class);
         if (parameters != null && !parameters.isEmpty()) {
             setProperties(camelContext, endpoint, parameters);
         }
+        String path = uriTemplate != null ? uriTemplate : basePath;
+        endpoint.setHeaderFilterStrategy(new UndertowRestHeaderFilterStrategy(path, queryParameters));
 
         // the endpoint must be started before creating the producer
         ServiceHelper.startService(endpoint);

http://git-wip-us.apache.org/repos/asf/camel/blob/5c061e7e/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowRestHeaderFilterStrategy.java
----------------------------------------------------------------------
diff --git a/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowRestHeaderFilterStrategy.java b/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowRestHeaderFilterStrategy.java
new file mode 100644
index 0000000..a091d62
--- /dev/null
+++ b/components/camel-undertow/src/main/java/org/apache/camel/component/undertow/UndertowRestHeaderFilterStrategy.java
@@ -0,0 +1,56 @@
+/**
+ * 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.undertow;
+
+import org.apache.camel.Exchange;
+
+public class UndertowRestHeaderFilterStrategy extends UndertowHeaderFilterStrategy {
+
+    private final String templateUri;
+    private final String queryParameters;
+
+    public UndertowRestHeaderFilterStrategy(String templateUri, String queryParameters) {
+        super();
+        this.templateUri = templateUri;
+        this.queryParameters = queryParameters;
+    }
+
+    @Override
+    public boolean applyFilterToCamelHeaders(String headerName, Object headerValue, Exchange exchange) {
+        boolean answer = super.applyFilterToExternalHeaders(headerName, headerValue, exchange);
+        // using rest producer then headers are mapping to uri and query parameters using {key} syntax
+        // if there is a match to an existing Camel Message header, then we should filter (=true) this
+        // header as its already been mapped by the RestProducer from camel-core, and we do not want
+        // the header to included as HTTP header also (eg as duplicate value)
+        if (!answer) {
+            if (templateUri != null) {
+                String token = "{" + headerName + "}";
+                if (templateUri.contains(token)) {
+                    answer = true;
+                }
+            }
+            if (!answer && queryParameters != null) {
+                String token = "=%7B" + headerName + "%7D"; // encoded values for { }
+                if (queryParameters.contains(token)) {
+                    answer = true;
+                }
+            }
+        }
+        return answer;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/5c061e7e/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/rest/RestUndertowProducerGetUriParameterTest.java
----------------------------------------------------------------------
diff --git a/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/rest/RestUndertowProducerGetUriParameterTest.java b/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/rest/RestUndertowProducerGetUriParameterTest.java
new file mode 100644
index 0000000..10466c6
--- /dev/null
+++ b/components/camel-undertow/src/test/java/org/apache/camel/component/undertow/rest/RestUndertowProducerGetUriParameterTest.java
@@ -0,0 +1,59 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.undertow.rest;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.undertow.BaseUndertowTest;
+import org.junit.Test;
+
+public class RestUndertowProducerGetUriParameterTest extends BaseUndertowTest {
+
+    @Test
+    public void testUndertowProducerGet() throws Exception {
+        String out = fluentTemplate.withHeader("id", "123").to("direct:start").request(String.class);
+        assertEquals("123;Donald Duck", out);
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                // configure to use undertow on localhost with the given port
+                restConfiguration().component("undertow").host("localhost").port(getPort());
+
+                from("direct:start")
+                        .to("rest:get:users/basic?id={id}");
+
+                // use the rest DSL to define the rest services
+                rest("/users/")
+                        .get("basic/?id={id}")
+                        .route()
+                        .to("mock:input")
+                        .process(new Processor() {
+                            public void process(Exchange exchange) throws Exception {
+                                String id = exchange.getIn().getHeader("id", String.class);
+                                exchange.getOut().setBody(id + ";Donald Duck");
+                            }
+                        });
+            }
+        };
+    }
+
+}