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/b2508f19
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/b2508f19
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/b2508f19

Branch: refs/heads/master
Commit: b2508f1961d900558eb22387ec28f4c35c510e0b
Parents: adde56a
Author: Claus Ibsen <[email protected]>
Authored: Wed Aug 24 14:15:53 2016 +0200
Committer: Claus Ibsen <[email protected]>
Committed: Fri Aug 26 16:53:31 2016 +0200

----------------------------------------------------------------------
 .../component/jetty/JettyHttpComponent.java     | 40 +++++++++++++-
 .../rest/producer/JettyRestProducerGetTest.java | 57 ++++++++++++++++++++
 .../src/test/resources/hello-api.json           | 26 +++++++++
 .../src/test/resources/log4j2.properties        |  1 +
 .../swagger/component/SwaggerProducer.java      |  2 +
 .../swagger/RestSwaggerReaderApiDocsTest.java   |  1 -
 .../component/DummyRestProducerFactory.java     |  6 ++-
 7 files changed, 129 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/b2508f19/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 8e06626..b1972fc 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,9 @@ 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;
 import org.apache.camel.http.common.CamelServlet;
 import org.apache.camel.http.common.HttpBinding;
@@ -55,11 +57,12 @@ import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.RestApiConsumerFactory;
 import org.apache.camel.spi.RestConfiguration;
 import org.apache.camel.spi.RestConsumerFactory;
-import org.apache.camel.spi.UriParam;
+import org.apache.camel.spi.RestProducerFactory;
 import org.apache.camel.util.FileUtil;
 import org.apache.camel.util.HostUtils;
 import org.apache.camel.util.IntrospectionSupport;
 import org.apache.camel.util.ObjectHelper;
+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;
@@ -95,7 +98,7 @@ import org.slf4j.LoggerFactory;
  *
  * @version 
  */
-public abstract class JettyHttpComponent extends HttpCommonComponent 
implements RestConsumerFactory, RestApiConsumerFactory {
+public abstract class JettyHttpComponent extends HttpCommonComponent 
implements RestConsumerFactory, RestApiConsumerFactory, RestProducerFactory {
     public static final String TMP_DIR = "CamelJettyTempDir";
     
     protected static final HashMap<String, ConnectorRef> CONNECTORS = new 
HashMap<String, ConnectorRef>();
@@ -1147,6 +1150,39 @@ public abstract class JettyHttpComponent extends 
HttpCommonComponent implements
         return consumer;
     }
 
+    @Override
+    public Producer createProducer(CamelContext camelContext, Exchange 
exchange, String scheme, String host,
+                                   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);
+
+        // does the uri template use placeholders?
+        if (uriTemplate.contains("{")) {
+            // us a header for the dynamic uri template so we reuse same 
endpoint
+            // TODO: fix me later
+            String path = StringHelper.replaceAll(uriTemplate, "{name}", 
"Donald Duck");
+            String overrideUri = String.format("%s://%s/%s/%s", scheme, host, 
basePath, path);
+            exchange.getIn().setHeader(Exchange.HTTP_URI, overrideUri);
+        }
+
+        // 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()) {
+            setProperties(camelContext, endpoint, parameters);
+        }
+
+        return endpoint.createProducer();
+    }
+
     protected CamelServlet createServletForConnector(Server server, Connector 
connector,
                                                      List<Handler> handlers, 
JettyHttpEndpoint endpoint) throws Exception {
         ServletContextHandler context = new ServletContextHandler(server, "/", 
ServletContextHandler.NO_SECURITY | ServletContextHandler.NO_SESSIONS);

http://git-wip-us.apache.org/repos/asf/camel/blob/b2508f19/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
new file mode 100644
index 0000000..69422d1
--- /dev/null
+++ 
b/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/rest/producer/JettyRestProducerGetTest.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 JettyRestProducerGetTest extends BaseJettyTest {
+
+    @Test
+    public void testSwaggerGet() throws Exception {
+        getMockEndpoint("mock:result").expectedBodiesReceived("Hello 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:hello/hi/{name}?host=" 
+ host)
+                        .to("mock:result");
+
+                
from("jetty:http://localhost:{{port}}/api/hello/hi/?matchOnUriPrefix=true";)
+                    .transform().constant("Hello Donald Duck");
+            }
+        };
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b2508f19/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
new file mode 100644
index 0000000..82d61f8
--- /dev/null
+++ b/components/camel-jetty9/src/test/resources/hello-api.json
@@ -0,0 +1,26 @@
+{
+  "swagger" : "2.0",
+  "host" : "localhost:8080",
+  "basePath" : "/api",
+  "tags" : [ {
+    "name" : "hello"
+  } ],
+  "schemes" : [ "http" ],
+  "paths" : {
+    "/hello/hi/{name}" : {
+      "get" : {
+        "tags" : [ "hello" ],
+        "summary" : "Saying hi",
+        "consumes" : [ "application/json" ],
+        "produces" : [ "application/json" ],
+        "parameters" : [ {
+          "name" : "name",
+          "in" : "path",
+          "description" : "Who is it",
+          "required" : true,
+          "type" : "string"
+        } ]
+      }
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/b2508f19/components/camel-jetty9/src/test/resources/log4j2.properties
----------------------------------------------------------------------
diff --git a/components/camel-jetty9/src/test/resources/log4j2.properties 
b/components/camel-jetty9/src/test/resources/log4j2.properties
index c863dc3..b91c7b3 100644
--- a/components/camel-jetty9/src/test/resources/log4j2.properties
+++ b/components/camel-jetty9/src/test/resources/log4j2.properties
@@ -25,4 +25,5 @@ appender.out.name = out
 appender.out.layout.type = PatternLayout
 appender.out.layout.pattern = %d [%-15.15t] %-5p %-30.30c{1} - %m%n
 rootLogger.level = INFO
+rootLogger.appenderRef.out.ref = out
 rootLogger.appenderRef.file.ref = file

http://git-wip-us.apache.org/repos/asf/camel/blob/b2508f19/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 019bdd3..1456dc5 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.ServiceHelper;
 import org.apache.camel.util.URISupport;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -100,6 +101,7 @@ public class SwaggerProducer extends DefaultAsyncProducer {
             // TODO: create the producer once and reuse (create HTTP_XXX 
headers for dynamic values)
             Producer producer = createHttpProducer(exchange, operation, verb, 
path, options);
             if (producer != null) {
+                ServiceHelper.startService(producer);
                 AsyncProcessor async = 
AsyncProcessorConverterHelper.convert(producer);
                 return async.process(exchange, callback);
             }

http://git-wip-us.apache.org/repos/asf/camel/blob/b2508f19/components/camel-swagger-java/src/test/java/org/apache/camel/swagger/RestSwaggerReaderApiDocsTest.java
----------------------------------------------------------------------
diff --git 
a/components/camel-swagger-java/src/test/java/org/apache/camel/swagger/RestSwaggerReaderApiDocsTest.java
 
b/components/camel-swagger-java/src/test/java/org/apache/camel/swagger/RestSwaggerReaderApiDocsTest.java
index e1a31ed..14a7bf2 100644
--- 
a/components/camel-swagger-java/src/test/java/org/apache/camel/swagger/RestSwaggerReaderApiDocsTest.java
+++ 
b/components/camel-swagger-java/src/test/java/org/apache/camel/swagger/RestSwaggerReaderApiDocsTest.java
@@ -74,7 +74,6 @@ public class RestSwaggerReaderApiDocsTest extends 
CamelTestSupport {
         String json = mapper.writeValueAsString(swagger);
 
         log.info(json);
-        System.out.println(json);
 
         assertTrue(json.contains("\"host\" : \"localhost:8080\""));
         assertTrue(json.contains("\"basePath\" : \"/api\""));

http://git-wip-us.apache.org/repos/asf/camel/blob/b2508f19/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 d960dbe..d092f16 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
@@ -19,6 +19,7 @@ package org.apache.camel.swagger.component;
 import java.util.Map;
 
 import org.apache.camel.CamelContext;
+import org.apache.camel.Endpoint;
 import org.apache.camel.Exchange;
 import org.apache.camel.Producer;
 import org.apache.camel.impl.DefaultProducer;
@@ -31,7 +32,10 @@ public class DummyRestProducerFactory implements 
RestProducerFactory {
                             String verb, String basePath, final String 
uriTemplate, final String queryParameters,
                             String consumes, String produces, Map<String, 
Object> parameters) throws Exception {
 
-        return new DefaultProducer(null) {
+        // use a dummy endpoint
+        Endpoint endpoint = camelContext.getEndpoint("stub:dummy");
+
+        return new DefaultProducer(endpoint) {
             @Override
             public void process(Exchange exchange) throws Exception {
                 // for testing purpose, check if we have {name} in template

Reply via email to