This is an automated email from the ASF dual-hosted git repository. acosentino pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/master by this push: new e1ebc60 CAMEL-14303: Handle duplicate matchOnUriPrefix on api docs. Polish. e1ebc60 is described below commit e1ebc6071187a424fb293699683f39c415d3b47d Author: Bob Paulin <b...@bobpaulin.com> AuthorDate: Wed Dec 18 21:28:12 2019 -0600 CAMEL-14303: Handle duplicate matchOnUriPrefix on api docs. Polish. --- components/camel-servlet/pom.xml | 5 ++ .../camel/component/servlet/ServletComponent.java | 35 ++--------- .../servlet/rest/RestApiMatchUriServletTest.java | 62 +++++++++++++++++++ .../apache/camel/support/RestComponentHelper.java | 71 +++++++++++++++++++--- 4 files changed, 136 insertions(+), 37 deletions(-) diff --git a/components/camel-servlet/pom.xml b/components/camel-servlet/pom.xml index 7a3f699..1594d44 100644 --- a/components/camel-servlet/pom.xml +++ b/components/camel-servlet/pom.xml @@ -144,6 +144,11 @@ <scope>test</scope> </dependency> <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-swagger-java</artifactId> + <scope>test</scope> + </dependency> + <dependency> <groupId>io.rest-assured</groupId> <artifactId>rest-assured</artifactId> <version>${rest-assured-version}</version> diff --git a/components/camel-servlet/src/main/java/org/apache/camel/component/servlet/ServletComponent.java b/components/camel-servlet/src/main/java/org/apache/camel/component/servlet/ServletComponent.java index b62aa8f..de4b955 100644 --- a/components/camel-servlet/src/main/java/org/apache/camel/component/servlet/ServletComponent.java +++ b/components/camel-servlet/src/main/java/org/apache/camel/component/servlet/ServletComponent.java @@ -35,6 +35,7 @@ import org.apache.camel.spi.RestApiConsumerFactory; import org.apache.camel.spi.RestConfiguration; import org.apache.camel.spi.RestConsumerFactory; import org.apache.camel.spi.annotations.Component; +import org.apache.camel.support.RestComponentHelper; import org.apache.camel.util.FileUtil; import org.apache.camel.util.StringHelper; import org.apache.camel.util.URISupport; @@ -279,43 +280,19 @@ public class ServletComponent extends HttpCommonComponent implements RestConsume config = camelContext.getRestConfiguration("servlet", true); } - Map<String, Object> map = new HashMap<>(); - // build query string, and append any endpoint configuration properties - if (config.getComponent() == null || config.getComponent().equals("servlet")) { - // setup endpoint options - if (config.getEndpointProperties() != null && !config.getEndpointProperties().isEmpty()) { - map.putAll(config.getEndpointProperties()); - } - } + Map<String, Object> map = RestComponentHelper.initRestEndpointProperties("servlet", config); boolean cors = config.isEnableCORS(); if (cors) { // allow HTTP Options as we want to handle CORS in rest-dsl map.put("optionsEnabled", "true"); } - - // do not append with context-path as the servlet path should be without context-path - - String query = URISupport.createQueryString(map); - - String url; + if (api) { - url = "servlet:///%s?matchOnUriPrefix=true&httpMethodRestrict=%s"; - } else { - url = "servlet:///%s?httpMethodRestrict=%s"; - } + map.put("matchOnUriPrefix", "true"); + } - // must use upper case for restrict - String restrict = verb.toUpperCase(Locale.US); - if (cors) { - restrict += ",OPTIONS"; - } - // get the endpoint - url = String.format(url, path, restrict); - - if (!query.isEmpty()) { - url = url + "&" + query; - } + String url = RestComponentHelper.createRestConsumerUrl("servlet", verb, path, cors, map); ServletEndpoint endpoint = camelContext.getEndpoint(url, ServletEndpoint.class); setProperties(camelContext, endpoint, parameters); diff --git a/components/camel-servlet/src/test/java/org/apache/camel/component/servlet/rest/RestApiMatchUriServletTest.java b/components/camel-servlet/src/test/java/org/apache/camel/component/servlet/rest/RestApiMatchUriServletTest.java new file mode 100644 index 0000000..003506f --- /dev/null +++ b/components/camel-servlet/src/test/java/org/apache/camel/component/servlet/rest/RestApiMatchUriServletTest.java @@ -0,0 +1,62 @@ +/* + * 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 com.meterware.httpunit.GetMethodWebRequest; +import com.meterware.httpunit.WebRequest; +import com.meterware.httpunit.WebResponse; +import com.meterware.servletunit.ServletUnitClient; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.servlet.ServletCamelRouterTestSupport; +import org.apache.camel.model.rest.RestBindingMode; +import org.junit.Test; + +public class RestApiMatchUriServletTest extends ServletCamelRouterTestSupport { + + @Test + public void testApiDocGet() throws Exception { + WebRequest req = new GetMethodWebRequest(CONTEXT_URL + "/services/api-doc"); + req.setHeaderField("Accept", "application/json"); + ServletUnitClient client = newClient(); + client.setExceptionsThrownOnErrorStatus(false); + WebResponse response = client.getResponse(req); + + assertEquals(200, response.getResponseCode()); + + assertMockEndpointsSatisfied(); + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + restConfiguration().component("servlet") + .apiContextPath("/api-doc") + .endpointProperty("matchOnUriPrefix", "true") + .apiProperty("cors", "true").apiProperty("api.title", "The hello rest thing").apiProperty("api.version", "1.2.3") + .bindingMode(RestBindingMode.auto); + + // use the rest DSL to define the rest services + rest("/users/") + .post("new").consumes("application/json").type(UserPojo.class) + .to("mock:input"); + } + }; + } + +} diff --git a/core/camel-support/src/main/java/org/apache/camel/support/RestComponentHelper.java b/core/camel-support/src/main/java/org/apache/camel/support/RestComponentHelper.java index 6603dfd..39c0632 100644 --- a/core/camel-support/src/main/java/org/apache/camel/support/RestComponentHelper.java +++ b/core/camel-support/src/main/java/org/apache/camel/support/RestComponentHelper.java @@ -26,10 +26,21 @@ import org.apache.camel.spi.RestConfiguration; import org.apache.camel.util.HostUtils; import org.apache.camel.util.URISupport; +/** + * Helper class for rest-dsl components. + */ public final class RestComponentHelper { + private RestComponentHelper() { } + /** + * + * @param queryMap the map of Endpoint options to apply the HTTP restrict settings to + * @param verb the HTTP verb for the route + * @param cors is cors enabled/disabled + * @return the map of Endpoint Properties with HTTP Restrict Options set + */ public static Map<String, Object> addHttpRestrictParam(Map<String, Object> queryMap, String verb, Boolean cors) { String restrict = verb.toUpperCase(Locale.US); if (cors) { @@ -39,6 +50,14 @@ public final class RestComponentHelper { return queryMap; } + /** + * + * Creates an Endpoint Property Map based on properies set in the component's RestConfiguration. + * + * @param componentName the Rest Component name + * @param config the RestConfiguration + * @return the map of Endpoint Properties set in the RestConfiguration + */ public static Map<String, Object> initRestEndpointProperties(String componentName, RestConfiguration config) { Map<String, Object> map = new HashMap<>(); // build query string, and append any endpoint configuration properties @@ -51,6 +70,15 @@ public final class RestComponentHelper { return map; } + /** + * + * Sets the Rest consumer host based on RestConfiguration + * + * @param host the existing host configuration + * @param config the RestConfiguration + * @return the host based on RestConfiguration + * @throws UnknownHostException thrown when local host or local ip can't be resolved via network interfaces. + */ public static String resolveRestHostName(String host, RestConfiguration config) throws UnknownHostException { if (config.getHostNameResolver() == RestConfiguration.RestHostNameResolver.allLocalIp) { host = "0.0.0.0"; @@ -62,33 +90,60 @@ public final class RestComponentHelper { return host; } + /** + * + * Creates the Rest consumers url based on component and url options. + * + * @param componentName the name of the rest component + * @param verb the HTTP verb for the route + * @param path the HTTP path of the route + * @param cors is cors enabled/disabled + * @param queryMap the endpoint query options + * @return a string of the component route url + * @throws URISyntaxException - is thrown if uri has invalid syntax. + */ public static String createRestConsumerUrl(String componentName, String verb, String path, Boolean cors, Map<String, Object> queryMap) throws URISyntaxException { String query = generateComponentQueryString(verb, cors, queryMap); - return applyFormatAndQuery("%s:/%s?", query, componentName, path); + return applyFormatAndQuery("%s:/%s", query, componentName, path); } + /** + * + * Creates the Rest consumers url based on component and url options. + * + * @param componentName the name of the rest component + * @param verb the HTTP verb for the route + * @param scheme the scheme of the HTTP route http/https + * @param host the host of the HTTP route + * @param port the port the route will be exposed through + * @param path the HTTP path of the route + * @param cors is cors enabled/disabled + * @param queryMap the endpoint query options + * @return a string of the component route url + * @throws URISyntaxException - is thrown if uri has invalid syntax. + */ public static String createRestConsumerUrl(String componentName, String verb, String scheme, String host, int port, String path, Boolean cors, Map<String, Object> queryMap) throws URISyntaxException { String query = generateComponentQueryString(verb, cors, queryMap); - return applyFormatAndQuery("%s:%s://%s:%s/%s?", query, componentName, scheme, host, port, path); + return applyFormatAndQuery("%s:%s://%s:%s/%s", query, componentName, scheme, host, port, path); } private static String generateComponentQueryString(String verb, Boolean cors, Map<String, Object> queryMap) throws URISyntaxException { addHttpRestrictParam(queryMap, verb, cors); - String query = URISupport.createQueryString(queryMap); - return query; + return URISupport.createQueryString(queryMap); } private static String applyFormatAndQuery(String format, String query, Object... formatOptions) { - // get the endpoint - String url = String.format(format, formatOptions); + // get the endpoint + StringBuilder urlBuilder = new StringBuilder(String.format(format, formatOptions)); if (!query.isEmpty()) { - url = url + query; + urlBuilder.append("?"); + urlBuilder.append(query); } - return url; + return urlBuilder.toString(); } }