CAMEL-7354: Rest DSL. Integrate with camel-jetty. Work in progress.

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

Branch: refs/heads/master
Commit: 36d64201745e3b4e73104f8ccb5a56860f0786bd
Parents: 60fd9e9
Author: Claus Ibsen <davscl...@apache.org>
Authored: Sun Jul 27 08:39:58 2014 +0200
Committer: Claus Ibsen <davscl...@apache.org>
Committed: Mon Jul 28 10:50:48 2014 +0200

----------------------------------------------------------------------
 .../component/jetty/CamelMultipartFilter.java   |   1 +
 .../component/jetty/JettyHttpComponent.java     |  18 ++--
 .../camel/component/jetty/JettyRestFilter.java  |   5 +-
 .../component/jetty/JettyRestHttpBinding.java   |  60 +++++++++++
 ...JettyRestServletResolveConsumerStrategy.java | 101 +++++++++++++++++++
 .../component/jetty/rest/RestJettyGetTest.java  |   4 +-
 6 files changed, 178 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/36d64201/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/CamelMultipartFilter.java
----------------------------------------------------------------------
diff --git 
a/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/CamelMultipartFilter.java
 
b/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/CamelMultipartFilter.java
index 1229ed7..9a0c6ea 100644
--- 
a/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/CamelMultipartFilter.java
+++ 
b/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/CamelMultipartFilter.java
@@ -17,6 +17,7 @@
 package org.apache.camel.component.jetty;
 
 import javax.servlet.Filter;
+
 /**
  * Please use the CamelFilterWrapper instead of using this classs
  */

http://git-wip-us.apache.org/repos/asf/camel/blob/36d64201/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java
----------------------------------------------------------------------
diff --git 
a/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java
 
b/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java
index 77bb504..1aee4be 100644
--- 
a/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java
+++ 
b/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java
@@ -381,7 +381,6 @@ public class JettyHttpComponent extends HttpComponent 
implements RestConsumerFac
                 // special for rest filter
                 FilterHolder filterHolder = new FilterHolder();
                 filterHolder.setFilter(new CamelFilterWrapper(filter));
-//                context.getServletHandler().addFilter(filterHolder);
                 addFilter(context, filterHolder, "*");
             } else {
                 FilterHolder filterHolder = new FilterHolder();
@@ -997,14 +996,16 @@ public class JettyHttpComponent extends HttpComponent 
implements RestConsumerFac
         setProperties(endpoint, parameters);
 
         // add our filter
-        List<Filter> list = endpoint.getFilters();
-        if (list == null) {
-            list = new ArrayList<Filter>();
-        }
-        list.add(0, new JettyRestFilter());
-        endpoint.setFilters(list);
+        //List<Filter> list = endpoint.getFilters();
+        //if (list == null) {
+        //    list = new ArrayList<Filter>();
+        //}
+        //list.add(0, new JettyRestFilter());
+        //endpoint.setFilters(list);
         // disable this filter as we want to use ours
         endpoint.setEnableMultipartFilter(false);
+        // use the rest binding
+        endpoint.setBinding(new JettyRestHttpBinding());
 
         // configure consumer properties
         Consumer consumer = endpoint.createConsumer(processor);
@@ -1048,6 +1049,9 @@ public class JettyHttpComponent extends HttpComponent 
implements RestConsumerFac
         holder.setServlet(camelServlet);
         context.addServlet(holder, "/*");
 
+        // use rest enabled resolver in case we use rest
+        camelServlet.setServletResolveConsumerStrategy(new 
JettyRestServletResolveConsumerStrategy());
+
         return camelServlet;
     }
     

http://git-wip-us.apache.org/repos/asf/camel/blob/36d64201/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyRestFilter.java
----------------------------------------------------------------------
diff --git 
a/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyRestFilter.java
 
b/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyRestFilter.java
index 2203c82..9dd612e 100644
--- 
a/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyRestFilter.java
+++ 
b/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyRestFilter.java
@@ -26,6 +26,10 @@ import javax.servlet.ServletResponse;
 
 public class JettyRestFilter implements Filter {
 
+    // TODO: we may want to use a filter so we can reuse this for camel-servlet
+    // to have it match the request with list of accepted paths
+
+
     @Override
     public void init(FilterConfig filterConfig) throws ServletException {
         // noop
@@ -33,7 +37,6 @@ public class JettyRestFilter implements Filter {
 
     @Override
     public void doFilter(ServletRequest servletRequest, ServletResponse 
servletResponse, FilterChain filterChain) throws IOException, ServletException {
-        System.out.println("Doing my filter here");
         filterChain.doFilter(servletRequest, servletResponse);
     }
 

http://git-wip-us.apache.org/repos/asf/camel/blob/36d64201/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyRestHttpBinding.java
----------------------------------------------------------------------
diff --git 
a/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyRestHttpBinding.java
 
b/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyRestHttpBinding.java
new file mode 100644
index 0000000..b92cf3f
--- /dev/null
+++ 
b/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyRestHttpBinding.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.jetty;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.camel.component.http.DefaultHttpBinding;
+import org.apache.camel.component.http.HttpMessage;
+
+public class JettyRestHttpBinding extends DefaultHttpBinding {
+
+    // TODO: a better and faster rest pattern matcher, without the .split as 
they may be slower
+
+    @Override
+    protected void populateRequestParameters(HttpServletRequest request, 
HttpMessage message) throws Exception {
+        super.populateRequestParameters(request, message);
+
+        String path = request.getPathInfo();
+        if (path == null) {
+            return;
+        }
+
+        // in the endpoint the user may have defined rest {} placeholders
+        // so we need to map those placeholders with data from the incoming 
request context path
+
+        JettyHttpEndpoint endpoint = (JettyHttpEndpoint) 
message.getExchange().getFromEndpoint();
+        String consumerPath = endpoint.getPath();
+
+        String[] paths = path.split("/");
+        String[] consumerPaths = consumerPath.split("/");
+
+        for (int i = 0; i < consumerPaths.length; i++) {
+            if (paths.length < i) {
+                break;
+            }
+            String p1 = consumerPaths[i];
+            if (p1.startsWith("{") && p1.endsWith("}")) {
+                String key = p1.substring(1, p1.length() - 1);
+                String value = paths[i];
+                if (value != null) {
+                    message.setHeader(key, value);
+                }
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/36d64201/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyRestServletResolveConsumerStrategy.java
----------------------------------------------------------------------
diff --git 
a/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyRestServletResolveConsumerStrategy.java
 
b/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyRestServletResolveConsumerStrategy.java
new file mode 100644
index 0000000..4832f84
--- /dev/null
+++ 
b/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyRestServletResolveConsumerStrategy.java
@@ -0,0 +1,101 @@
+/**
+ * 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.jetty;
+
+import java.util.Map;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.camel.component.http.HttpConsumer;
+import org.apache.camel.component.http.HttpServletResolveConsumerStrategy;
+import org.apache.camel.util.ObjectHelper;
+
+/**
+ * A {@link 
org.apache.camel.component.http.HttpServletResolveConsumerStrategy} that 
supports the Rest DSL.
+ */
+public class JettyRestServletResolveConsumerStrategy extends 
HttpServletResolveConsumerStrategy {
+
+    // TODO: a better and faster rest pattern matcher, without the .split as 
they may be slower
+
+    @Override
+    public HttpConsumer resolve(HttpServletRequest request, Map<String, 
HttpConsumer> consumers) {
+        HttpConsumer answer = super.resolve(request, consumers);
+
+        if (answer == null) {
+
+            String path = request.getPathInfo();
+            if (path == null) {
+                return null;
+            }
+
+            for (String key : consumers.keySet()) {
+                String consumerPath = normalizePath(key);
+                String requestPath = normalizePath(path);
+                if (matchPaths(requestPath, consumerPath)) {
+                    answer = consumers.get(key);
+                    break;
+                }
+            }
+        }
+
+        return answer;
+    }
+
+    private boolean matchPaths(String requestPath, String consumerPath) {
+        String[] requestPaths = requestPath.split("/");
+        String[] consumerPaths = consumerPath.split("/");
+
+        // must be same length
+        if (requestPaths.length != consumerPaths.length) {
+            return false;
+        }
+
+        for (int i = 0; i < requestPaths.length; i++) {
+            String p1 = requestPaths[i];
+            String p2 = consumerPaths[i];
+
+            if (p2.equals("*")) {
+                // always matches
+                continue;
+            }
+
+            if (!p1.equals(p2)) {
+                return false;
+            }
+        }
+
+        // assume matching
+        return true;
+    }
+
+    protected String normalizePath(String path) {
+        StringBuilder sb = new StringBuilder();
+        String[] paths = path.split("/");
+        for (String s : paths) {
+            if (ObjectHelper.isEmpty(s)) {
+                continue;
+            }
+            sb.append("/");
+            if (s.startsWith("{") && s.endsWith("}")) {
+                sb.append("*");
+            } else {
+                sb.append(s);
+            }
+        }
+        return sb.toString();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/36d64201/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/rest/RestJettyGetTest.java
----------------------------------------------------------------------
diff --git 
a/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/rest/RestJettyGetTest.java
 
b/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/rest/RestJettyGetTest.java
index 438bb86..04863d1 100644
--- 
a/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/rest/RestJettyGetTest.java
+++ 
b/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/rest/RestJettyGetTest.java
@@ -20,10 +20,8 @@ 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.Ignore;
 import org.junit.Test;
 
-@Ignore
 public class RestJettyGetTest extends BaseJettyTest {
 
     @Test
@@ -37,7 +35,7 @@ public class RestJettyGetTest extends BaseJettyTest {
         return new RouteBuilder() {
             @Override
             public void configure() throws Exception {
-                // configure to use restlet on localhost with the given port
+                // configure to use jetty on localhost with the given port
                 
restConfiguration().component("jetty").host("localhost").port(getPort());
 
                 // use the rest DSL to define the rest services

Reply via email to