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/2e39b2c2 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/2e39b2c2 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/2e39b2c2 Branch: refs/heads/master Commit: 2e39b2c25c690e45ca5c0fa2827c99dc0b6e9c33 Parents: 56b3152 Author: Claus Ibsen <[email protected]> Authored: Wed Aug 24 16:00:39 2016 +0200 Committer: Claus Ibsen <[email protected]> Committed: Fri Aug 26 16:53:31 2016 +0200 ---------------------------------------------------------------------- .../component/jetty/JettyHttpComponent.java | 8 ++- .../JettyRestProducerGetQueryParamTest.java | 57 +++++++++++++++++++ .../src/test/resources/hello-api.json | 15 +++++ .../swagger/component/SwaggerComponent.java | 7 +++ .../swagger/component/SwaggerEndpoint.java | 18 ++++++ .../swagger/component/SwaggerProducer.java | 7 +++ .../component/DummyRestProducerFactory.java | 7 ++- .../component/SwaggerGetUriParamTest.java | 59 ++++++++++++++++++++ .../src/test/resources/hello-api.json | 15 +++++ 9 files changed, 189 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/2e39b2c2/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 9ba3f04..6b9394f 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 @@ -1158,6 +1158,7 @@ public abstract class JettyHttpComponent extends HttpCommonComponent implements // avoid leading slash basePath = FileUtil.stripLeadingSeparator(basePath); uriTemplate = FileUtil.stripLeadingSeparator(uriTemplate); + resolvedUriTemplate = FileUtil.stripLeadingSeparator(resolvedUriTemplate); // does the uri template use path parameters? if (uriTemplate.contains("{") && resolvedUriTemplate != null) { @@ -1165,13 +1166,14 @@ public abstract class JettyHttpComponent extends HttpCommonComponent implements String overrideUri = String.format("%s://%s/%s/%s", scheme, host, basePath, resolvedUriTemplate); exchange.getIn().setHeader(Exchange.HTTP_URI, overrideUri); } + if (queryParameters != null) { + // use a header for the query parameters + exchange.getIn().setHeader(Exchange.HTTP_QUERY, queryParameters); + } // get the endpoint String url = "jetty:%s://%s/%s/%s"; url = String.format(url, scheme, host, basePath, uriTemplate); - if (queryParameters != null) { - url = url + "&" + queryParameters; - } JettyHttpEndpoint endpoint = camelContext.getEndpoint(url, JettyHttpEndpoint.class); if (parameters != null && !parameters.isEmpty()) { http://git-wip-us.apache.org/repos/asf/camel/blob/2e39b2c2/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/rest/producer/JettyRestProducerGetQueryParamTest.java ---------------------------------------------------------------------- diff --git a/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/rest/producer/JettyRestProducerGetQueryParamTest.java b/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/rest/producer/JettyRestProducerGetQueryParamTest.java new file mode 100644 index 0000000..565d51d --- /dev/null +++ b/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/rest/producer/JettyRestProducerGetQueryParamTest.java @@ -0,0 +1,57 @@ +/** + * 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.RoutesBuilder; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.jetty.BaseJettyTest; +import org.apache.camel.swagger.component.SwaggerComponent; +import org.junit.Test; + +public class JettyRestProducerGetQueryParamTest extends BaseJettyTest { + + @Test + public void testSwaggerGet() throws Exception { + getMockEndpoint("mock:result").expectedBodiesReceived("Bye Donald Duck"); + + template.sendBodyAndHeader("direct:start", null, "name", "Donald Duck"); + + assertMockEndpointsSatisfied(); + } + + @Override + protected RoutesBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + SwaggerComponent sc = new SwaggerComponent(); + sc.setComponentName("jetty"); + context.addComponent("swagger", sc); + + String host = "localhost:" + getPort(); + + from("direct:start") + .to("swagger:hello-api.json:get:bye?host=" + host) + .to("mock:result"); + + from("jetty:http://localhost:{{port}}/api/bye/?matchOnUriPrefix=true") + .transform().simple("Bye ${header.name}"); + } + }; + } + +} http://git-wip-us.apache.org/repos/asf/camel/blob/2e39b2c2/components/camel-jetty9/src/test/resources/hello-api.json ---------------------------------------------------------------------- diff --git a/components/camel-jetty9/src/test/resources/hello-api.json b/components/camel-jetty9/src/test/resources/hello-api.json index 82d61f8..6cc6a72 100644 --- a/components/camel-jetty9/src/test/resources/hello-api.json +++ b/components/camel-jetty9/src/test/resources/hello-api.json @@ -21,6 +21,21 @@ "type" : "string" } ] } + }, + "/bye" : { + "get" : { + "tags" : [ "bye" ], + "summary" : "Saying bye", + "consumes" : [ "application/json" ], + "produces" : [ "application/json" ], + "parameters" : [ { + "name" : "name", + "in" : "query", + "description" : "Who is it", + "required" : true, + "type" : "string" + } ] + } } } } http://git-wip-us.apache.org/repos/asf/camel/blob/2e39b2c2/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/component/SwaggerComponent.java ---------------------------------------------------------------------- diff --git a/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/component/SwaggerComponent.java b/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/component/SwaggerComponent.java index bf012f4..75eecec 100644 --- a/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/component/SwaggerComponent.java +++ b/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/component/SwaggerComponent.java @@ -20,6 +20,7 @@ import java.util.Map; import org.apache.camel.Endpoint; import org.apache.camel.impl.UriEndpointComponent; +import org.apache.camel.util.URISupport; public class SwaggerComponent extends UriEndpointComponent { @@ -60,6 +61,12 @@ public class SwaggerComponent extends UriEndpointComponent { } endpoint.setPath(path); + setProperties(endpoint, parameters); + + // the rest is URI parameters on path + String query = URISupport.createQueryString(parameters); + endpoint.setQueryParameters(query); + return endpoint; } http://git-wip-us.apache.org/repos/asf/camel/blob/2e39b2c2/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/component/SwaggerEndpoint.java ---------------------------------------------------------------------- diff --git a/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/component/SwaggerEndpoint.java b/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/component/SwaggerEndpoint.java index df1dc02..3ccfb74 100644 --- a/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/component/SwaggerEndpoint.java +++ b/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/component/SwaggerEndpoint.java @@ -54,6 +54,8 @@ public class SwaggerEndpoint extends DefaultEndpoint { private String componentName; @UriParam private String host; + @UriParam(multiValue = true) + private String queryParameters; public SwaggerEndpoint(String endpointUri, Component component) { super(endpointUri, component); @@ -72,6 +74,11 @@ public class SwaggerEndpoint extends DefaultEndpoint { } @Override + public boolean isLenientProperties() { + return true; + } + + @Override public boolean isSingleton() { return true; } @@ -109,6 +116,17 @@ public class SwaggerEndpoint extends DefaultEndpoint { this.path = path; } + public String getQueryParameters() { + return queryParameters; + } + + /** + * Query parameters for the HTTP service to call + */ + public void setQueryParameters(String queryParameters) { + this.queryParameters = queryParameters; + } + public String getComponentName() { return componentName; } http://git-wip-us.apache.org/repos/asf/camel/blob/2e39b2c2/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/component/SwaggerProducer.java ---------------------------------------------------------------------- diff --git a/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/component/SwaggerProducer.java b/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/component/SwaggerProducer.java index e410e28..a5d0c18 100644 --- a/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/component/SwaggerProducer.java +++ b/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/component/SwaggerProducer.java @@ -37,6 +37,7 @@ import org.apache.camel.impl.DefaultAsyncProducer; import org.apache.camel.spi.RestProducerFactory; import org.apache.camel.util.AsyncProcessorConverterHelper; import org.apache.camel.util.CollectionStringBuffer; +import org.apache.camel.util.ObjectHelper; import org.apache.camel.util.ServiceHelper; import org.apache.camel.util.StringHelper; import org.apache.camel.util.URISupport; @@ -209,6 +210,9 @@ public class SwaggerProducer extends DefaultAsyncProducer { if (name != null) { String value = exchange.getIn().getHeader(name, String.class); if (value != null) { + // we need to remove the header as they are sent as query instead + // TODO: we could use a header filter strategy to skip these headers + exchange.getIn().removeHeader(param.getName()); query.put(name, value); } else if (param.getRequired()) { throw new NoSuchHeaderException(exchange, name, String.class); @@ -217,6 +221,9 @@ public class SwaggerProducer extends DefaultAsyncProducer { } else if ("path".equals(param.getIn())) { String value = exchange.getIn().getHeader(param.getName(), String.class); if (value != null) { + // we need to remove the header as they are sent as path instead + // TODO: we could use a header filter strategy to skip these headers + exchange.getIn().removeHeader(param.getName()); String token = "{" + param.getName() + "}"; resolvedUriTemplate = StringHelper.replaceAll(resolvedUriTemplate, token, value); } else if (param.getRequired()) { http://git-wip-us.apache.org/repos/asf/camel/blob/2e39b2c2/components/camel-swagger-java/src/test/java/org/apache/camel/swagger/component/DummyRestProducerFactory.java ---------------------------------------------------------------------- diff --git a/components/camel-swagger-java/src/test/java/org/apache/camel/swagger/component/DummyRestProducerFactory.java b/components/camel-swagger-java/src/test/java/org/apache/camel/swagger/component/DummyRestProducerFactory.java index 096b440..4f1da5c 100644 --- a/components/camel-swagger-java/src/test/java/org/apache/camel/swagger/component/DummyRestProducerFactory.java +++ b/components/camel-swagger-java/src/test/java/org/apache/camel/swagger/component/DummyRestProducerFactory.java @@ -24,6 +24,7 @@ import org.apache.camel.Exchange; import org.apache.camel.Producer; import org.apache.camel.impl.DefaultProducer; import org.apache.camel.spi.RestProducerFactory; +import org.apache.camel.util.ObjectHelper; public class DummyRestProducerFactory implements RestProducerFactory { @@ -40,8 +41,12 @@ public class DummyRestProducerFactory implements RestProducerFactory { public void process(Exchange exchange) throws Exception { // for testing purpose, check if we have {name} in template if (uriTemplate.contains("{name}")) { - String name = exchange.getIn().getHeader("name", String.class); + int pos = resolvedUriTemplate.lastIndexOf('/'); + String name = resolvedUriTemplate.substring(pos + 1); exchange.getIn().setBody("Hello " + name); + } else if (queryParameters.contains("name=")) { + String name = ObjectHelper.after(queryParameters, "name="); + exchange.getIn().setBody("Bye " + name); } } }; http://git-wip-us.apache.org/repos/asf/camel/blob/2e39b2c2/components/camel-swagger-java/src/test/java/org/apache/camel/swagger/component/SwaggerGetUriParamTest.java ---------------------------------------------------------------------- diff --git a/components/camel-swagger-java/src/test/java/org/apache/camel/swagger/component/SwaggerGetUriParamTest.java b/components/camel-swagger-java/src/test/java/org/apache/camel/swagger/component/SwaggerGetUriParamTest.java new file mode 100644 index 0000000..04d8642 --- /dev/null +++ b/components/camel-swagger-java/src/test/java/org/apache/camel/swagger/component/SwaggerGetUriParamTest.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 + * + * 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.swagger.component; + +import org.apache.camel.RoutesBuilder; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.impl.JndiRegistry; +import org.apache.camel.test.junit4.CamelTestSupport; +import org.junit.Test; + +public class SwaggerGetUriParamTest extends CamelTestSupport { + + @Override + protected JndiRegistry createRegistry() throws Exception { + JndiRegistry jndi = super.createRegistry(); + jndi.bind("dummy", new DummyRestProducerFactory()); + return jndi; + } + + @Test + public void testSwaggerGet() throws Exception { + getMockEndpoint("mock:result").expectedBodiesReceived("Bye Donald+Duck"); + + template.sendBodyAndHeader("direct:start", null, "name", "Donald Duck"); + + assertMockEndpointsSatisfied(); + } + + @Override + protected RoutesBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + SwaggerComponent sc = new SwaggerComponent(); + sc.setComponentName("dummy"); + + context.addComponent("swagger", sc); + + from("direct:start") + .to("swagger:hello-api.json:get:bye?name={name}") + .to("mock:result"); + } + }; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/2e39b2c2/components/camel-swagger-java/src/test/resources/hello-api.json ---------------------------------------------------------------------- diff --git a/components/camel-swagger-java/src/test/resources/hello-api.json b/components/camel-swagger-java/src/test/resources/hello-api.json index 82d61f8..6cc6a72 100644 --- a/components/camel-swagger-java/src/test/resources/hello-api.json +++ b/components/camel-swagger-java/src/test/resources/hello-api.json @@ -21,6 +21,21 @@ "type" : "string" } ] } + }, + "/bye" : { + "get" : { + "tags" : [ "bye" ], + "summary" : "Saying bye", + "consumes" : [ "application/json" ], + "produces" : [ "application/json" ], + "parameters" : [ { + "name" : "name", + "in" : "query", + "description" : "Who is it", + "required" : true, + "type" : "string" + } ] + } } } }
