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