You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by zr...@apache.org on 2019/05/07 11:53:26 UTC

[camel] branch camel-2.x updated (7d38e13 -> 9dcd4b1)

This is an automated email from the ASF dual-hosted git repository.

zregvart pushed a change to branch camel-2.x
in repository https://gitbox.apache.org/repos/asf/camel.git.


    from 7d38e13  CAMEL-13481 - Upgrade Shiro to version 1.4.1
     new c4fb25c  Improve docs a bit for camel-rest-swagger when loading swagger spec from https. Also fixed so catching wider exception in fallback to let swagger attempt to load.
     new cf5c1c7  CAMEL-13192: Path resolution in rest-swagger fa...
     new 9dcd4b1  CAMEL-13490: Consider API key in query paramete...

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../src/main/docs/rest-swagger-component.adoc      |   12 +-
 .../rest/swagger/RestSwaggerComponent.java         |   12 +-
 .../rest/swagger/RestSwaggerEndpoint.java          |   66 +-
 .../component/rest/swagger/RestSwaggerHelper.java  |    2 +-
 .../rest/swagger/RestSwaggerComponentTest.java     |   46 +
 .../rest/swagger/RestSwaggerEndpointTest.java      |   61 +-
 .../src/test/resources/alt-petstore.json           | 1039 ++++++++++++++++++++
 .../RestSwaggerComponentConfiguration.java         |   12 +-
 8 files changed, 1212 insertions(+), 38 deletions(-)
 create mode 100644 components/camel-rest-swagger/src/test/resources/alt-petstore.json


[camel] 01/03: Improve docs a bit for camel-rest-swagger when loading swagger spec from https. Also fixed so catching wider exception in fallback to let swagger attempt to load.

Posted by zr...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

zregvart pushed a commit to branch camel-2.x
in repository https://gitbox.apache.org/repos/asf/camel.git

commit c4fb25cfecd2d7b715710d7fcc671ce9e14260e1
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Tue Feb 12 09:43:24 2019 +0100

    Improve docs a bit for camel-rest-swagger when loading swagger spec from https. Also fixed so catching wider exception in fallback to let swagger attempt to load.
    
    (cherry picked from commit 9a0628caf438ed5bd5f688392e97c8e3d8a9ed46)
---
 .../src/main/docs/rest-swagger-component.adoc            | 12 ++++++------
 .../component/rest/swagger/RestSwaggerComponent.java     | 12 ++++++------
 .../component/rest/swagger/RestSwaggerEndpoint.java      | 16 ++++++++++------
 .../camel/component/rest/swagger/RestSwaggerHelper.java  |  2 +-
 .../springboot/RestSwaggerComponentConfiguration.java    | 12 ++++++------
 5 files changed, 29 insertions(+), 25 deletions(-)

diff --git a/components/camel-rest-swagger/src/main/docs/rest-swagger-component.adoc b/components/camel-rest-swagger/src/main/docs/rest-swagger-component.adoc
index 8e211a8..08baabe 100644
--- a/components/camel-rest-swagger/src/main/docs/rest-swagger-component.adoc
+++ b/components/camel-rest-swagger/src/main/docs/rest-swagger-component.adoc
@@ -92,11 +92,11 @@ The REST Swagger component supports 9 options, which are listed below.
 |===
 | Name | Description | Default | Type
 | *basePath* (producer) | API basePath, for example /v2. Default is unset, if set overrides the value present in Swagger specification. |  | String
-| *componentName* (producer) | Name of the Camel component that will perform the requests. The compnent must be present in Camel registry and it must implement RestProducerFactory service provider interface. If not set CLASSPATH is searched for single component that implements RestProducerFactory SPI. Can be overriden in endpoint configuration. |  | String
-| *consumes* (producer) | What payload type this component capable of consuming. Could be one type, like application/json or multiple types as application/json, application/xml; q=0.5 according to the RFC7231. This equates to the value of Accept HTTP header. If set overrides any value found in the Swagger specification. Can be overriden in endpoint configuration |  | String
-| *host* (producer) | Scheme hostname and port to direct the HTTP requests to in the form of https://hostname:port. Can be configured at the endpoint, component or in the correspoding REST configuration in the Camel Context. If you give this component a name (e.g. petstore) that REST configuration is consulted first, rest-swagger next, and global configuration last. If set overrides any value found in the Swagger specification, RestConfiguration. Can be overriden in endpoint configuratio [...]
-| *produces* (producer) | What payload type this component is producing. For example application/json according to the RFC7231. This equates to the value of Content-Type HTTP header. If set overrides any value present in the Swagger specification. Can be overriden in endpoint configuration. |  | String
-| *specificationUri* (producer) | Path to the Swagger specification file. The scheme, host base path are taken from this specification, but these can be overriden with properties on the component or endpoint level. If not given the component tries to load swagger.json resource. Note that the host defined on the component and endpoint of this Component should contain the scheme, hostname and optionally the port in the URI syntax (i.e. https://api.example.com:8080). Can be overriden in end [...]
+| *componentName* (producer) | Name of the Camel component that will perform the requests. The component must be present in Camel registry and it must implement RestProducerFactory service provider interface. If not set CLASSPATH is searched for single component that implements RestProducerFactory SPI. Can be overridden in endpoint configuration. |  | String
+| *consumes* (producer) | What payload type this component capable of consuming. Could be one type, like application/json or multiple types as application/json, application/xml; q=0.5 according to the RFC7231. This equates to the value of Accept HTTP header. If set overrides any value found in the Swagger specification. Can be overridden in endpoint configuration |  | String
+| *host* (producer) | Scheme hostname and port to direct the HTTP requests to in the form of https://hostname:port. Can be configured at the endpoint, component or in the correspoding REST configuration in the Camel Context. If you give this component a name (e.g. petstore) that REST configuration is consulted first, rest-swagger next, and global configuration last. If set overrides any value found in the Swagger specification, RestConfiguration. Can be overridden in endpoint configurati [...]
+| *produces* (producer) | What payload type this component is producing. For example application/json according to the RFC7231. This equates to the value of Content-Type HTTP header. If set overrides any value present in the Swagger specification. Can be overridden in endpoint configuration. |  | String
+| *specificationUri* (producer) | Path to the Swagger specification file. The scheme, host base path are taken from this specification, but these can be overriden with properties on the component or endpoint level. If not given the component tries to load swagger.json resource. Note that the host defined on the component and endpoint of this Component should contain the scheme, hostname and optionally the port in the URI syntax (i.e. https://api.example.com:8080). Can be overridden in en [...]
 | *sslContextParameters* (security) | Customize TLS parameters used by the component. If not set defaults to the TLS parameters set in the Camel context |  | SSLContextParameters
 | *useGlobalSslContext Parameters* (security) | Enable usage of global SSL context parameters. | false | boolean
 | *resolveProperty Placeholders* (advanced) | Whether the component should resolve property placeholders on itself when starting. Only properties which are of String type can use property placeholders. | true | boolean
@@ -118,7 +118,7 @@ with the following path and query parameters:
 [width="100%",cols="2,5,^1,2",options="header"]
 |===
 | Name | Description | Default | Type
-| *specificationUri* | Path to the Swagger specification file. The scheme, host base path are taken from this specification, but these can be overriden with properties on the component or endpoint level. If not given the component tries to load swagger.json resource. Note that the host defined on the component and endpoint of this Component should contain the scheme, hostname and optionally the port in the URI syntax (i.e. https://api.example.com:8080). Overrides component configuration. [...]
+| *specificationUri* | Path to the Swagger specification file. The scheme, host base path are taken from this specification, but these can be overridden with properties on the component or endpoint level. If not given the component tries to load swagger.json resource from the classpath. Note that the host defined on the component and endpoint of this Component should contain the scheme, hostname and optionally the port in the URI syntax (i.e. http://api.example.com:8080). Overrides compo [...]
 | *operationId* | *Required* ID of the operation from the Swagger specification. |  | String
 |===
 
diff --git a/components/camel-rest-swagger/src/main/java/org/apache/camel/component/rest/swagger/RestSwaggerComponent.java b/components/camel-rest-swagger/src/main/java/org/apache/camel/component/rest/swagger/RestSwaggerComponent.java
index 89a5e1e..9835310 100644
--- a/components/camel-rest-swagger/src/main/java/org/apache/camel/component/rest/swagger/RestSwaggerComponent.java
+++ b/components/camel-rest-swagger/src/main/java/org/apache/camel/component/rest/swagger/RestSwaggerComponent.java
@@ -88,9 +88,9 @@ public final class RestSwaggerComponent extends DefaultComponent implements SSLC
         defaultValue = "", label = "producer", required = "false")
     private String basePath = "";
 
-    @Metadata(description = "Name of the Camel component that will perform the requests. The compnent must be present"
+    @Metadata(description = "Name of the Camel component that will perform the requests. The component must be present"
         + " in Camel registry and it must implement RestProducerFactory service provider interface. If not set"
-        + " CLASSPATH is searched for single component that implements RestProducerFactory SPI. Can be overriden in"
+        + " CLASSPATH is searched for single component that implements RestProducerFactory SPI. Can be overridden in"
         + " endpoint configuration.", label = "producer", required = "false")
     private String componentName;
 
@@ -98,7 +98,7 @@ public final class RestSwaggerComponent extends DefaultComponent implements SSLC
         description = "What payload type this component capable of consuming. Could be one type, like `application/json`"
             + " or multiple types as `application/json, application/xml; q=0.5` according to the RFC7231. This equates"
             + " to the value of `Accept` HTTP header. If set overrides any value found in the Swagger specification."
-            + " Can be overriden in endpoint configuration",
+            + " Can be overridden in endpoint configuration",
         label = "producer", required = "false")
     private String consumes;
 
@@ -106,14 +106,14 @@ public final class RestSwaggerComponent extends DefaultComponent implements SSLC
         + " `http[s]://hostname[:port]`. Can be configured at the endpoint, component or in the correspoding"
         + " REST configuration in the Camel Context. If you give this component a name (e.g. `petstore`) that"
         + " REST configuration is consulted first, `rest-swagger` next, and global configuration last. If set"
-        + " overrides any value found in the Swagger specification, RestConfiguration. Can be overriden in endpoint"
+        + " overrides any value found in the Swagger specification, RestConfiguration. Can be overridden in endpoint"
         + " configuration.", label = "producer", required = "false")
     private String host;
 
     @Metadata(
         description = "What payload type this component is producing. For example `application/json`"
             + " according to the RFC7231. This equates to the value of `Content-Type` HTTP header. If set overrides"
-            + " any value present in the Swagger specification. Can be overriden in endpoint configuration.",
+            + " any value present in the Swagger specification. Can be overridden in endpoint configuration.",
         label = "producer", required = "false")
     private String produces;
 
@@ -121,7 +121,7 @@ public final class RestSwaggerComponent extends DefaultComponent implements SSLC
         + " specification, but these can be overriden with properties on the component or endpoint level. If not"
         + " given the component tries to load `swagger.json` resource. Note that the `host` defined on the"
         + " component and endpoint of this Component should contain the scheme, hostname and optionally the"
-        + " port in the URI syntax (i.e. `https://api.example.com:8080`). Can be overriden in endpoint"
+        + " port in the URI syntax (i.e. `https://api.example.com:8080`). Can be overridden in endpoint"
         + " configuration.", defaultValue = DEFAULT_SPECIFICATION_URI_STR, label = "producer", required = "false")
     private URI specificationUri;
 
diff --git a/components/camel-rest-swagger/src/main/java/org/apache/camel/component/rest/swagger/RestSwaggerEndpoint.java b/components/camel-rest-swagger/src/main/java/org/apache/camel/component/rest/swagger/RestSwaggerEndpoint.java
index 93ff96e..2ee3f34 100644
--- a/components/camel-rest-swagger/src/main/java/org/apache/camel/component/rest/swagger/RestSwaggerEndpoint.java
+++ b/components/camel-rest-swagger/src/main/java/org/apache/camel/component/rest/swagger/RestSwaggerEndpoint.java
@@ -128,10 +128,14 @@ public final class RestSwaggerEndpoint extends DefaultEndpoint {
 
     @UriPath(
         description = "Path to the Swagger specification file. The scheme, host base path are taken from this"
-            + " specification, but these can be overriden with properties on the component or endpoint level. If not"
-            + " given the component tries to load `swagger.json` resource. Note that the `host` defined on the"
+            + " specification, but these can be overridden with properties on the component or endpoint level. If not"
+            + " given the component tries to load `swagger.json` resource from the classpath. Note that the `host` defined on the"
             + " component and endpoint of this Component should contain the scheme, hostname and optionally the"
-            + " port in the URI syntax (i.e. `https://api.example.com:8080`). Overrides component configuration.",
+            + " port in the URI syntax (i.e. `http://api.example.com:8080`). Overrides component configuration."
+            + " The Swagger specification can be loaded from different sources by prefixing with file: classpath: http: https:."
+            + " Support for https is limited to using the JDK installed UrlHandler, and as such it can be cumbersome to setup"
+            + " TLS/SSL certificates for https (such as setting a number of javax.net.ssl JVM system properties)."
+            + " How to do that consult the JDK documentation for UrlHandler.",
         defaultValue = RestSwaggerComponent.DEFAULT_SPECIFICATION_URI_STR,
         defaultValueNote = "By default loads `swagger.json` file", label = "producer")
     private URI specificationUri = RestSwaggerComponent.DEFAULT_SPECIFICATION_URI;
@@ -432,7 +436,7 @@ public final class RestSwaggerEndpoint extends DefaultEndpoint {
 
         final boolean areTheSame = "rest-swagger".equals(assignedComponentName);
 
-        throw new IllegalStateException("Unable to determine destionation host for requests. The Swagger specification"
+        throw new IllegalStateException("Unable to determine destination host for requests. The Swagger specification"
             + " does not specify `scheme` and `host` parameters, the specification URI is not absolute with `http` or"
             + " `https` scheme, and no RestConfigurations configured with `scheme`, `host` and `port` were found for `"
             + (areTheSame ? "rest-swagger` component" : assignedComponentName + "` or `rest-swagger` components")
@@ -569,7 +573,7 @@ public final class RestSwaggerEndpoint extends DefaultEndpoint {
             final JsonNode node = mapper.readTree(stream);
 
             return swaggerParser.read(node);
-        } catch (final IOException e) {
+        } catch (Exception e) {
             // try Swaggers loader
             final Swagger swagger = swaggerParser.read(uriAsString);
 
@@ -580,7 +584,7 @@ public final class RestSwaggerEndpoint extends DefaultEndpoint {
             throw new IllegalArgumentException("The given Swagger specification could not be loaded from `" + uri
                 + "`. Tried loading using Camel's resource resolution and using Swagger's own resource resolution."
                 + " Swagger tends to swallow exceptions while parsing, try specifying Java system property `debugParser`"
-                + " (e.g. `-DdebugParser=true`), the exception that occured when loading using Camel's resource"
+                + " (e.g. `-DdebugParser=true`), the exception that occurred when loading using Camel's resource"
                 + " loader follows", e);
         }
     }
diff --git a/components/camel-rest-swagger/src/main/java/org/apache/camel/component/rest/swagger/RestSwaggerHelper.java b/components/camel-rest-swagger/src/main/java/org/apache/camel/component/rest/swagger/RestSwaggerHelper.java
index ca7e972..28285e8 100644
--- a/components/camel-rest-swagger/src/main/java/org/apache/camel/component/rest/swagger/RestSwaggerHelper.java
+++ b/components/camel-rest-swagger/src/main/java/org/apache/camel/component/rest/swagger/RestSwaggerHelper.java
@@ -42,7 +42,7 @@ final class RestSwaggerHelper {
 
         if (!matcher.matches()) {
             throw new IllegalArgumentException(
-                "host must be an apsolute URI (e.g. http://api.example.com), given: `" + hostUri + "`");
+                "host must be an absolute URI (e.g. http://api.example.com), given: `" + hostUri + "`");
         }
 
         return hostUri;
diff --git a/platforms/spring-boot/components-starter/camel-rest-swagger-starter/src/main/java/org/apache/camel/component/rest/swagger/springboot/RestSwaggerComponentConfiguration.java b/platforms/spring-boot/components-starter/camel-rest-swagger-starter/src/main/java/org/apache/camel/component/rest/swagger/springboot/RestSwaggerComponentConfiguration.java
index 08fe84d..5f14ed4 100644
--- a/platforms/spring-boot/components-starter/camel-rest-swagger-starter/src/main/java/org/apache/camel/component/rest/swagger/springboot/RestSwaggerComponentConfiguration.java
+++ b/platforms/spring-boot/components-starter/camel-rest-swagger-starter/src/main/java/org/apache/camel/component/rest/swagger/springboot/RestSwaggerComponentConfiguration.java
@@ -43,11 +43,11 @@ public class RestSwaggerComponentConfiguration
      */
     private String basePath;
     /**
-     * Name of the Camel component that will perform the requests. The compnent
+     * Name of the Camel component that will perform the requests. The component
      * must be present in Camel registry and it must implement
      * RestProducerFactory service provider interface. If not set CLASSPATH is
      * searched for single component that implements RestProducerFactory SPI.
-     * Can be overriden in endpoint configuration.
+     * Can be overridden in endpoint configuration.
      */
     private String componentName;
     /**
@@ -55,7 +55,7 @@ public class RestSwaggerComponentConfiguration
      * like application/json or multiple types as application/json,
      * application/xml; q=0.5 according to the RFC7231. This equates to the
      * value of Accept HTTP header. If set overrides any value found in the
-     * Swagger specification. Can be overriden in endpoint configuration
+     * Swagger specification. Can be overridden in endpoint configuration
      */
     private String consumes;
     /**
@@ -65,14 +65,14 @@ public class RestSwaggerComponentConfiguration
      * this component a name (e.g. petstore) that REST configuration is
      * consulted first, rest-swagger next, and global configuration last. If set
      * overrides any value found in the Swagger specification,
-     * RestConfiguration. Can be overriden in endpoint configuration.
+     * RestConfiguration. Can be overridden in endpoint configuration.
      */
     private String host;
     /**
      * What payload type this component is producing. For example
      * application/json according to the RFC7231. This equates to the value of
      * Content-Type HTTP header. If set overrides any value present in the
-     * Swagger specification. Can be overriden in endpoint configuration.
+     * Swagger specification. Can be overridden in endpoint configuration.
      */
     private String produces;
     /**
@@ -82,7 +82,7 @@ public class RestSwaggerComponentConfiguration
      * load swagger.json resource. Note that the host defined on the component
      * and endpoint of this Component should contain the scheme, hostname and
      * optionally the port in the URI syntax (i.e.
-     * https://api.example.com:8080). Can be overriden in endpoint
+     * https://api.example.com:8080). Can be overridden in endpoint
      * configuration.
      */
     private URI specificationUri;


[camel] 02/03: CAMEL-13192: Path resolution in rest-swagger fa...

Posted by zr...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

zregvart pushed a commit to branch camel-2.x
in repository https://gitbox.apache.org/repos/asf/camel.git

commit cf5c1c7f193eae441e71f3c6d32fd18b1f870c1e
Author: Zoran Regvart <zr...@apache.org>
AuthorDate: Wed Feb 13 14:27:17 2019 +0100

    CAMEL-13192: Path resolution in rest-swagger fa...
    
    ...ils to include the whole path
    
    This fixes the path resolution in `rest-swagger` component so that any
    trailing path characters are not lost when resolving.
    
    (cherry picked from commit 61083cab91aa29511ec132840e60ff11cf131e2e)
---
 .../component/rest/swagger/RestSwaggerEndpoint.java |  8 ++++++--
 .../rest/swagger/RestSwaggerEndpointTest.java       | 21 +++++++++++++++++++++
 2 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/components/camel-rest-swagger/src/main/java/org/apache/camel/component/rest/swagger/RestSwaggerEndpoint.java b/components/camel-rest-swagger/src/main/java/org/apache/camel/component/rest/swagger/RestSwaggerEndpoint.java
index 2ee3f34..e41e45d 100644
--- a/components/camel-rest-swagger/src/main/java/org/apache/camel/component/rest/swagger/RestSwaggerEndpoint.java
+++ b/components/camel-rest-swagger/src/main/java/org/apache/camel/component/rest/swagger/RestSwaggerEndpoint.java
@@ -502,10 +502,14 @@ public final class RestSwaggerEndpoint extends DefaultEndpoint {
                 resolved.append('{').append(name).append('}');
             }
 
-            pos = end;
+            pos = end + 1;
             start = uriTemplate.indexOf('{', pos);
         }
 
+        if (pos < uriTemplate.length()) {
+            resolved.append(uriTemplate.substring(pos));
+        }
+
         return resolved.toString();
     }
 
@@ -573,7 +577,7 @@ public final class RestSwaggerEndpoint extends DefaultEndpoint {
             final JsonNode node = mapper.readTree(stream);
 
             return swaggerParser.read(node);
-        } catch (Exception e) {
+        } catch (final Exception e) {
             // try Swaggers loader
             final Swagger swagger = swaggerParser.read(uriAsString);
 
diff --git a/components/camel-rest-swagger/src/test/java/org/apache/camel/component/rest/swagger/RestSwaggerEndpointTest.java b/components/camel-rest-swagger/src/test/java/org/apache/camel/component/rest/swagger/RestSwaggerEndpointTest.java
index cb88a8c..7597f9f 100644
--- a/components/camel-rest-swagger/src/test/java/org/apache/camel/component/rest/swagger/RestSwaggerEndpointTest.java
+++ b/components/camel-rest-swagger/src/test/java/org/apache/camel/component/rest/swagger/RestSwaggerEndpointTest.java
@@ -21,10 +21,12 @@ import java.net.URI;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.Map;
 
 import io.swagger.models.Operation;
 import io.swagger.models.Scheme;
 import io.swagger.models.Swagger;
+import io.swagger.models.parameters.Parameter;
 import io.swagger.models.parameters.PathParameter;
 import io.swagger.models.parameters.QueryParameter;
 
@@ -360,6 +362,25 @@ public class RestSwaggerEndpointTest {
     }
 
     @Test
+    public void shouldResolveUris() {
+        final RestSwaggerEndpoint endpoint = new RestSwaggerEndpoint();
+        endpoint.parameters = new HashMap<>();
+        endpoint.parameters.put("param1", "value1");
+
+        final Map<String, Parameter> pathParameters = new HashMap<>();
+        pathParameters.put("param1", new PathParameter().name("param1"));
+        pathParameters.put("param2", new PathParameter().name("param2"));
+
+        assertThat(endpoint.resolveUri("/path", pathParameters)).isEqualTo("/path");
+        assertThat(endpoint.resolveUri("/path/{param1}", pathParameters)).isEqualTo("/path/value1");
+        assertThat(endpoint.resolveUri("/{param1}/path", pathParameters)).isEqualTo("/value1/path");
+        assertThat(endpoint.resolveUri("/{param1}/path/{param2}", pathParameters)).isEqualTo("/value1/path/{param2}");
+        assertThat(endpoint.resolveUri("/{param1}/{param2}", pathParameters)).isEqualTo("/value1/{param2}");
+        assertThat(endpoint.resolveUri("/path/{param1}/to/{param2}/rest", pathParameters))
+            .isEqualTo("/path/value1/to/{param2}/rest");
+    }
+
+    @Test
     public void shouldSerializeGivenLiteralValues() {
         final RestSwaggerEndpoint endpoint = new RestSwaggerEndpoint();
         endpoint.parameters = new HashMap<>();


[camel] 03/03: CAMEL-13490: Consider API key in query paramete...

Posted by zr...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

zregvart pushed a commit to branch camel-2.x
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 9dcd4b1008dd4d494c894a5b9bedbcfd6fff5a12
Author: Zoran Regvart <zr...@apache.org>
AuthorDate: Tue May 7 13:24:59 2019 +0200

    CAMEL-13490: Consider API key in query paramete...
    
    ...rs when configuring REST producers
    
    This will include any query API keys that are specified in the security
    requirement for a operation in the query parameters configured on the
    `rest` endpoint.
    
    (cherry picked from commit b753eecae3ddeabbd2a3391fffbeb3c6abe001ed)
---
 .../rest/swagger/RestSwaggerEndpoint.java          |   58 +-
 .../rest/swagger/RestSwaggerComponentTest.java     |   46 +
 .../rest/swagger/RestSwaggerEndpointTest.java      |   40 +-
 .../src/test/resources/alt-petstore.json           | 1039 ++++++++++++++++++++
 4 files changed, 1164 insertions(+), 19 deletions(-)

diff --git a/components/camel-rest-swagger/src/main/java/org/apache/camel/component/rest/swagger/RestSwaggerEndpoint.java b/components/camel-rest-swagger/src/main/java/org/apache/camel/component/rest/swagger/RestSwaggerEndpoint.java
index e41e45d..9bbff63 100644
--- a/components/camel-rest-swagger/src/main/java/org/apache/camel/component/rest/swagger/RestSwaggerEndpoint.java
+++ b/components/camel-rest-swagger/src/main/java/org/apache/camel/component/rest/swagger/RestSwaggerEndpoint.java
@@ -20,6 +20,7 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.net.URI;
 import java.net.URISyntaxException;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
@@ -28,6 +29,7 @@ import java.util.Map.Entry;
 import java.util.Optional;
 import java.util.function.Function;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import static java.util.Optional.ofNullable;
 
@@ -39,7 +41,11 @@ import io.swagger.models.Operation;
 import io.swagger.models.Path;
 import io.swagger.models.Scheme;
 import io.swagger.models.Swagger;
+import io.swagger.models.auth.ApiKeyAuthDefinition;
+import io.swagger.models.auth.In;
+import io.swagger.models.auth.SecuritySchemeDefinition;
 import io.swagger.models.parameters.Parameter;
+import io.swagger.models.parameters.QueryParameter;
 import io.swagger.parser.SwaggerParser;
 import io.swagger.util.Json;
 
@@ -126,16 +132,15 @@ public final class RestSwaggerEndpoint extends DefaultEndpoint {
         + " any value present in the Swagger specification. Overrides all other configuration.", label = "producer")
     private String produces;
 
-    @UriPath(
-        description = "Path to the Swagger specification file. The scheme, host base path are taken from this"
-            + " specification, but these can be overridden with properties on the component or endpoint level. If not"
-            + " given the component tries to load `swagger.json` resource from the classpath. Note that the `host` defined on the"
-            + " component and endpoint of this Component should contain the scheme, hostname and optionally the"
-            + " port in the URI syntax (i.e. `http://api.example.com:8080`). Overrides component configuration."
-            + " The Swagger specification can be loaded from different sources by prefixing with file: classpath: http: https:."
-            + " Support for https is limited to using the JDK installed UrlHandler, and as such it can be cumbersome to setup"
-            + " TLS/SSL certificates for https (such as setting a number of javax.net.ssl JVM system properties)."
-            + " How to do that consult the JDK documentation for UrlHandler.",
+    @UriPath(description = "Path to the Swagger specification file. The scheme, host base path are taken from this"
+        + " specification, but these can be overridden with properties on the component or endpoint level. If not"
+        + " given the component tries to load `swagger.json` resource from the classpath. Note that the `host` defined on the"
+        + " component and endpoint of this Component should contain the scheme, hostname and optionally the"
+        + " port in the URI syntax (i.e. `http://api.example.com:8080`). Overrides component configuration."
+        + " The Swagger specification can be loaded from different sources by prefixing with file: classpath: http: https:."
+        + " Support for https is limited to using the JDK installed UrlHandler, and as such it can be cumbersome to setup"
+        + " TLS/SSL certificates for https (such as setting a number of javax.net.ssl JVM system properties)."
+        + " How to do that consult the JDK documentation for UrlHandler.",
         defaultValue = RestSwaggerComponent.DEFAULT_SPECIFICATION_URI_STR,
         defaultValueNote = "By default loads `swagger.json` file", label = "producer")
     private URI specificationUri = RestSwaggerComponent.DEFAULT_SPECIFICATION_URI;
@@ -357,13 +362,14 @@ public final class RestSwaggerEndpoint extends DefaultEndpoint {
             parameters.put("produces", determinedProducers);
         }
 
-        final String queryParameters = operation.getParameters().stream().filter(p -> "query".equals(p.getIn()))
-            .map(this::queryParameter).collect(Collectors.joining("&"));
+        final String queryParameters = determineQueryParameters(swagger, operation).map(this::queryParameter)
+            .collect(Collectors.joining("&"));
         if (isNotEmpty(queryParameters)) {
             parameters.put("queryParameters", queryParameters);
         }
 
-        // pass properties that might be applied if the delegate component is created, i.e. if it's not
+        // pass properties that might be applied if the delegate component is
+        // created, i.e. if it's not
         // present in the Camel Context already
         final Map<String, Object> componentParameters = new HashMap<>();
 
@@ -534,6 +540,32 @@ public final class RestSwaggerEndpoint extends DefaultEndpoint {
         return null;
     }
 
+    static Stream<Parameter> determineQueryParameters(final Swagger swagger, final Operation operation) {
+        final List<Map<String, List<String>>> securityRequirements = operation.getSecurity();
+        final List<QueryParameter> apiKeyQueryParameters = new ArrayList<>();
+        if (securityRequirements != null) {
+            final Map<String, SecuritySchemeDefinition> securityDefinitions = swagger.getSecurityDefinitions();
+
+            for (final Map<String, List<String>> securityRequirement : securityRequirements) {
+                for (final String securityRequirementName : securityRequirement.keySet()) {
+                    final SecuritySchemeDefinition securitySchemeDefinition = securityDefinitions
+                        .get(securityRequirementName);
+                    if (securitySchemeDefinition instanceof ApiKeyAuthDefinition) {
+                        final ApiKeyAuthDefinition apiKeyDefinition = (ApiKeyAuthDefinition) securitySchemeDefinition;
+
+                        if (apiKeyDefinition.getIn() == In.QUERY) {
+                            apiKeyQueryParameters.add(new QueryParameter().name(apiKeyDefinition.getName())
+                                .required(true).type("string").description(apiKeyDefinition.getDescription()));
+                        }
+                    }
+                }
+            }
+        }
+
+        return Stream.concat(apiKeyQueryParameters.stream(),
+            operation.getParameters().stream().filter(p -> "query".equals(p.getIn())));
+    }
+
     static String hostFrom(final RestConfiguration restConfiguration) {
         if (restConfiguration == null) {
             return null;
diff --git a/components/camel-rest-swagger/src/test/java/org/apache/camel/component/rest/swagger/RestSwaggerComponentTest.java b/components/camel-rest-swagger/src/test/java/org/apache/camel/component/rest/swagger/RestSwaggerComponentTest.java
index dfe5c6f..fdd00d2 100644
--- a/components/camel-rest-swagger/src/test/java/org/apache/camel/component/rest/swagger/RestSwaggerComponentTest.java
+++ b/components/camel-rest-swagger/src/test/java/org/apache/camel/component/rest/swagger/RestSwaggerComponentTest.java
@@ -23,6 +23,8 @@ import java.nio.file.Files;
 import java.nio.file.Paths;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
 
 import javax.xml.bind.JAXBContext;
 import javax.xml.bind.Marshaller;
@@ -113,6 +115,39 @@ public class RestSwaggerComponentTest extends CamelTestSupport {
     }
 
     @Test
+    public void shouldBeGettingPetsByIdWithApiKeysInHeader() {
+        final Map<String, Object> headers = new HashMap<>();
+        headers.put("petId", 14);
+        headers.put("api_key", "dolphins");
+        final Pet pet = template.requestBodyAndHeaders("direct:getPetById", NO_BODY, headers, Pet.class);
+
+        assertNotNull(pet);
+
+        assertEquals(Integer.valueOf(14), pet.id);
+        assertEquals("Olafur Eliason Arnalds", pet.name);
+
+        petstore.verify(
+            getRequestedFor(urlEqualTo("/v2/pet/14")).withHeader("Accept", equalTo("application/xml, application/json"))
+                .withHeader("api_key", equalTo("dolphins")));
+    }
+
+    @Test
+    public void shouldBeGettingPetsByIdWithApiKeysInQueryParameter() {
+        final Map<String, Object> headers = new HashMap<>();
+        headers.put("petId", 14);
+        headers.put("api_key", "dolphins");
+        final Pet pet = template.requestBodyAndHeaders("altPetStore:getPetById", NO_BODY, headers, Pet.class);
+
+        assertNotNull(pet);
+
+        assertEquals(Integer.valueOf(14), pet.id);
+        assertEquals("Olafur Eliason Arnalds", pet.name);
+
+        petstore.verify(getRequestedFor(urlEqualTo("/v2/pet/14?api_key=dolphins")).withHeader("Accept",
+            equalTo("application/xml, application/json")));
+    }
+
+    @Test
     public void shouldBeGettingPetsByStatus() {
         final Pets pets = template.requestBodyAndHeader("direct:findPetsByStatus", NO_BODY, "status", "available",
             Pets.class);
@@ -136,6 +171,13 @@ public class RestSwaggerComponentTest extends CamelTestSupport {
 
         camelContext.addComponent("petStore", component);
 
+        final RestSwaggerComponent altPetStore = new RestSwaggerComponent();
+        altPetStore.setComponentName(componentName);
+        altPetStore.setHost("http://localhost:" + petstore.port());
+        altPetStore.setSpecificationUri(RestSwaggerComponentTest.class.getResource("/alt-petstore.json").toURI());
+
+        camelContext.addComponent("altPetStore", altPetStore);
+
         return camelContext;
     }
 
@@ -184,6 +226,10 @@ public class RestSwaggerComponentTest extends CamelTestSupport {
         petstore.stubFor(get(urlPathEqualTo("/v2/pet/findByStatus")).withQueryParam("status", equalTo("available"))
             .willReturn(aResponse().withStatus(HttpURLConnection.HTTP_OK).withBody(
                 "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><pets><Pet><id>1</id><name>Olafur Eliason Arnalds</name></Pet><Pet><name>Jean-Luc Picard</name></Pet></pets>")));
+
+        petstore.stubFor(get(urlEqualTo("/v2/pet/14?api_key=dolphins"))
+            .willReturn(aResponse().withStatus(HttpURLConnection.HTTP_OK).withBody(
+                "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><Pet><id>14</id><name>Olafur Eliason Arnalds</name></Pet>")));
     }
 
 }
diff --git a/components/camel-rest-swagger/src/test/java/org/apache/camel/component/rest/swagger/RestSwaggerEndpointTest.java b/components/camel-rest-swagger/src/test/java/org/apache/camel/component/rest/swagger/RestSwaggerEndpointTest.java
index 7597f9f..bd419f2 100644
--- a/components/camel-rest-swagger/src/test/java/org/apache/camel/component/rest/swagger/RestSwaggerEndpointTest.java
+++ b/components/camel-rest-swagger/src/test/java/org/apache/camel/component/rest/swagger/RestSwaggerEndpointTest.java
@@ -26,6 +26,8 @@ import java.util.Map;
 import io.swagger.models.Operation;
 import io.swagger.models.Scheme;
 import io.swagger.models.Swagger;
+import io.swagger.models.auth.ApiKeyAuthDefinition;
+import io.swagger.models.auth.In;
 import io.swagger.models.parameters.Parameter;
 import io.swagger.models.parameters.PathParameter;
 import io.swagger.models.parameters.QueryParameter;
@@ -119,18 +121,18 @@ public class RestSwaggerEndpointTest {
             .isEqualTo("/");
 
         restConfiguration.setContextPath("/rest");
-        assertThat(endpoint.determineBasePath(swagger))
-            .as("When base path is specified in REST configuration and not specified in component the base path should be from the REST configuration")
+        assertThat(endpoint.determineBasePath(swagger)).as(
+            "When base path is specified in REST configuration and not specified in component the base path should be from the REST configuration")
             .isEqualTo("/rest");
 
         swagger.basePath("/specification");
-        assertThat(endpoint.determineBasePath(swagger))
-            .as("When base path is specified in the specification it should take precedence the one specified in the REST configuration")
+        assertThat(endpoint.determineBasePath(swagger)).as(
+            "When base path is specified in the specification it should take precedence the one specified in the REST configuration")
             .isEqualTo("/specification");
 
         component.setBasePath("/component");
-        assertThat(endpoint.determineBasePath(swagger))
-            .as("When base path is specified on the component it should take precedence over Swagger specification and REST configuration")
+        assertThat(endpoint.determineBasePath(swagger)).as(
+            "When base path is specified on the component it should take precedence over Swagger specification and REST configuration")
             .isEqualTo("/component");
 
         endpoint.setBasePath("/endpoint");
@@ -328,6 +330,32 @@ public class RestSwaggerEndpointTest {
     }
 
     @Test
+    public void shouldIncludeApiKeysQueryParameters() {
+        final CamelContext camelContext = mock(CamelContext.class);
+
+        final RestSwaggerComponent component = new RestSwaggerComponent();
+        component.setCamelContext(camelContext);
+
+        final RestSwaggerEndpoint endpoint = new RestSwaggerEndpoint("uri", "remaining", component,
+            Collections.emptyMap());
+        endpoint.setHost("http://petstore.swagger.io");
+
+        final Swagger swagger = new Swagger();
+        final ApiKeyAuthDefinition apiKeys = new ApiKeyAuthDefinition("key", In.HEADER);
+        swagger.securityDefinition("apiKeys", apiKeys);
+
+        final Operation operation = new Operation().parameter(new QueryParameter().name("q").required(true));
+        operation.addSecurity("apiKeys", Collections.emptyList());
+
+        assertThat(endpoint.determineEndpointParameters(swagger, operation))
+            .containsOnly(entry("host", "http://petstore.swagger.io"), entry("queryParameters", "q={q}"));
+
+        apiKeys.setIn(In.QUERY);
+        assertThat(endpoint.determineEndpointParameters(swagger, operation))
+            .containsOnly(entry("host", "http://petstore.swagger.io"), entry("queryParameters", "key={key}&q={q}"));
+    }
+
+    @Test
     public void shouldLoadSwaggerSpecifications() throws IOException {
         final CamelContext camelContext = mock(CamelContext.class);
         when(camelContext.getClassResolver()).thenReturn(new DefaultClassResolver());
diff --git a/components/camel-rest-swagger/src/test/resources/alt-petstore.json b/components/camel-rest-swagger/src/test/resources/alt-petstore.json
new file mode 100644
index 0000000..98fb926
--- /dev/null
+++ b/components/camel-rest-swagger/src/test/resources/alt-petstore.json
@@ -0,0 +1,1039 @@
+{
+    "swagger": "2.0",
+    "info": {
+        "description": "This is a sample server Petstore server.  You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/).  For this sample, you can use the api key `special-key` to test the authorization filters.",
+        "version": "1.0.0",
+        "title": "Swagger Petstore",
+        "termsOfService": "http://swagger.io/terms/",
+        "contact": {
+            "email": "apiteam@swagger.io"
+        },
+        "license": {
+            "name": "Apache 2.0",
+            "url": "http://www.apache.org/licenses/LICENSE-2.0.html"
+        }
+    },
+    "host": "petstore.swagger.io",
+    "basePath": "/v2",
+    "tags": [
+        {
+            "name": "pet",
+            "description": "Everything about your Pets",
+            "externalDocs": {
+                "description": "Find out more",
+                "url": "http://swagger.io"
+            }
+        },
+        {
+            "name": "store",
+            "description": "Access to Petstore orders"
+        },
+        {
+            "name": "user",
+            "description": "Operations about user",
+            "externalDocs": {
+                "description": "Find out more about our store",
+                "url": "http://swagger.io"
+            }
+        }
+    ],
+    "schemes": [
+        "http"
+    ],
+    "paths": {
+        "/pet": {
+            "post": {
+                "tags": [
+                    "pet"
+                ],
+                "summary": "Add a new pet to the store",
+                "description": "",
+                "operationId": "addPet",
+                "consumes": [
+                    "application/json",
+                    "application/xml"
+                ],
+                "produces": [
+                    "application/xml",
+                    "application/json"
+                ],
+                "parameters": [
+                    {
+                        "in": "body",
+                        "name": "body",
+                        "description": "Pet object that needs to be added to the store",
+                        "required": true,
+                        "schema": {
+                            "$ref": "#/definitions/Pet"
+                        }
+                    }
+                ],
+                "responses": {
+                    "405": {
+                        "description": "Invalid input"
+                    }
+                },
+                "security": [
+                    {
+                        "petstore_auth": [
+                            "write:pets",
+                            "read:pets"
+                        ]
+                    }
+                ]
+            },
+            "put": {
+                "tags": [
+                    "pet"
+                ],
+                "summary": "Update an existing pet",
+                "description": "",
+                "operationId": "updatePet",
+                "consumes": [
+                    "application/json",
+                    "application/xml"
+                ],
+                "produces": [
+                    "application/xml",
+                    "application/json"
+                ],
+                "parameters": [
+                    {
+                        "in": "body",
+                        "name": "body",
+                        "description": "Pet object that needs to be added to the store",
+                        "required": true,
+                        "schema": {
+                            "$ref": "#/definitions/Pet"
+                        }
+                    }
+                ],
+                "responses": {
+                    "400": {
+                        "description": "Invalid ID supplied"
+                    },
+                    "404": {
+                        "description": "Pet not found"
+                    },
+                    "405": {
+                        "description": "Validation exception"
+                    }
+                },
+                "security": [
+                    {
+                        "petstore_auth": [
+                            "write:pets",
+                            "read:pets"
+                        ]
+                    }
+                ]
+            }
+        },
+        "/pet/findByStatus": {
+            "get": {
+                "tags": [
+                    "pet"
+                ],
+                "summary": "Finds Pets by status",
+                "description": "Multiple status values can be provided with comma separated strings",
+                "operationId": "findPetsByStatus",
+                "produces": [
+                    "application/xml",
+                    "application/json"
+                ],
+                "parameters": [
+                    {
+                        "name": "status",
+                        "in": "query",
+                        "description": "Status values that need to be considered for filter",
+                        "required": true,
+                        "type": "array",
+                        "items": {
+                            "type": "string",
+                            "enum": [
+                                "available",
+                                "pending",
+                                "sold"
+                            ],
+                            "default": "available"
+                        },
+                        "collectionFormat": "multi"
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "successful operation",
+                        "schema": {
+                            "type": "array",
+                            "items": {
+                                "$ref": "#/definitions/Pet"
+                            }
+                        }
+                    },
+                    "400": {
+                        "description": "Invalid status value"
+                    }
+                },
+                "security": [
+                    {
+                        "petstore_auth": [
+                            "write:pets",
+                            "read:pets"
+                        ]
+                    }
+                ]
+            }
+        },
+        "/pet/findByTags": {
+            "get": {
+                "tags": [
+                    "pet"
+                ],
+                "summary": "Finds Pets by tags",
+                "description": "Muliple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.",
+                "operationId": "findPetsByTags",
+                "produces": [
+                    "application/xml",
+                    "application/json"
+                ],
+                "parameters": [
+                    {
+                        "name": "tags",
+                        "in": "query",
+                        "description": "Tags to filter by",
+                        "required": true,
+                        "type": "array",
+                        "items": {
+                            "type": "string"
+                        },
+                        "collectionFormat": "multi"
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "successful operation",
+                        "schema": {
+                            "type": "array",
+                            "items": {
+                                "$ref": "#/definitions/Pet"
+                            }
+                        }
+                    },
+                    "400": {
+                        "description": "Invalid tag value"
+                    }
+                },
+                "security": [
+                    {
+                        "petstore_auth": [
+                            "write:pets",
+                            "read:pets"
+                        ]
+                    }
+                ],
+                "deprecated": true
+            }
+        },
+        "/pet/{petId}": {
+            "get": {
+                "tags": [
+                    "pet"
+                ],
+                "summary": "Find pet by ID",
+                "description": "Returns a single pet",
+                "operationId": "getPetById",
+                "produces": [
+                    "application/xml",
+                    "application/json"
+                ],
+                "parameters": [
+                    {
+                        "name": "petId",
+                        "in": "path",
+                        "description": "ID of pet to return",
+                        "required": true,
+                        "type": "integer",
+                        "format": "int64"
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "successful operation",
+                        "schema": {
+                            "$ref": "#/definitions/Pet"
+                        }
+                    },
+                    "400": {
+                        "description": "Invalid ID supplied"
+                    },
+                    "404": {
+                        "description": "Pet not found"
+                    }
+                },
+                "security": [
+                    {
+                        "api_key": [
+                        ]
+                    }
+                ]
+            },
+            "post": {
+                "tags": [
+                    "pet"
+                ],
+                "summary": "Updates a pet in the store with form data",
+                "description": "",
+                "operationId": "updatePetWithForm",
+                "consumes": [
+                    "application/x-www-form-urlencoded"
+                ],
+                "produces": [
+                    "application/xml",
+                    "application/json"
+                ],
+                "parameters": [
+                    {
+                        "name": "petId",
+                        "in": "path",
+                        "description": "ID of pet that needs to be updated",
+                        "required": true,
+                        "type": "integer",
+                        "format": "int64"
+                    },
+                    {
+                        "name": "name",
+                        "in": "formData",
+                        "description": "Updated name of the pet",
+                        "required": false,
+                        "type": "string"
+                    },
+                    {
+                        "name": "status",
+                        "in": "formData",
+                        "description": "Updated status of the pet",
+                        "required": false,
+                        "type": "string"
+                    }
+                ],
+                "responses": {
+                    "405": {
+                        "description": "Invalid input"
+                    }
+                },
+                "security": [
+                    {
+                        "petstore_auth": [
+                            "write:pets",
+                            "read:pets"
+                        ]
+                    }
+                ]
+            },
+            "delete": {
+                "tags": [
+                    "pet"
+                ],
+                "summary": "Deletes a pet",
+                "description": "",
+                "operationId": "deletePet",
+                "produces": [
+                    "application/xml",
+                    "application/json"
+                ],
+                "parameters": [
+                    {
+                        "name": "api_key",
+                        "in": "header",
+                        "required": false,
+                        "type": "string"
+                    },
+                    {
+                        "name": "petId",
+                        "in": "path",
+                        "description": "Pet id to delete",
+                        "required": true,
+                        "type": "integer",
+                        "format": "int64"
+                    }
+                ],
+                "responses": {
+                    "400": {
+                        "description": "Invalid ID supplied"
+                    },
+                    "404": {
+                        "description": "Pet not found"
+                    }
+                },
+                "security": [
+                    {
+                        "petstore_auth": [
+                            "write:pets",
+                            "read:pets"
+                        ]
+                    }
+                ]
+            }
+        },
+        "/pet/{petId}/uploadImage": {
+            "post": {
+                "tags": [
+                    "pet"
+                ],
+                "summary": "uploads an image",
+                "description": "",
+                "operationId": "uploadFile",
+                "consumes": [
+                    "multipart/form-data"
+                ],
+                "produces": [
+                    "application/json"
+                ],
+                "parameters": [
+                    {
+                        "name": "petId",
+                        "in": "path",
+                        "description": "ID of pet to update",
+                        "required": true,
+                        "type": "integer",
+                        "format": "int64"
+                    },
+                    {
+                        "name": "additionalMetadata",
+                        "in": "formData",
+                        "description": "Additional data to pass to server",
+                        "required": false,
+                        "type": "string"
+                    },
+                    {
+                        "name": "file",
+                        "in": "formData",
+                        "description": "file to upload",
+                        "required": false,
+                        "type": "file"
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "successful operation",
+                        "schema": {
+                            "$ref": "#/definitions/ApiResponse"
+                        }
+                    }
+                },
+                "security": [
+                    {
+                        "petstore_auth": [
+                            "write:pets",
+                            "read:pets"
+                        ]
+                    }
+                ]
+            }
+        },
+        "/store/inventory": {
+            "get": {
+                "tags": [
+                    "store"
+                ],
+                "summary": "Returns pet inventories by status",
+                "description": "Returns a map of status codes to quantities",
+                "operationId": "getInventory",
+                "produces": [
+                    "application/json"
+                ],
+                "parameters": [
+                ],
+                "responses": {
+                    "200": {
+                        "description": "successful operation",
+                        "schema": {
+                            "type": "object",
+                            "additionalProperties": {
+                                "type": "integer",
+                                "format": "int32"
+                            }
+                        }
+                    }
+                },
+                "security": [
+                    {
+                        "api_key": [
+                        ]
+                    }
+                ]
+            }
+        },
+        "/store/order": {
+            "post": {
+                "tags": [
+                    "store"
+                ],
+                "summary": "Place an order for a pet",
+                "description": "",
+                "operationId": "placeOrder",
+                "produces": [
+                    "application/xml",
+                    "application/json"
+                ],
+                "parameters": [
+                    {
+                        "in": "body",
+                        "name": "body",
+                        "description": "order placed for purchasing the pet",
+                        "required": true,
+                        "schema": {
+                            "$ref": "#/definitions/Order"
+                        }
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "successful operation",
+                        "schema": {
+                            "$ref": "#/definitions/Order"
+                        }
+                    },
+                    "400": {
+                        "description": "Invalid Order"
+                    }
+                }
+            }
+        },
+        "/store/order/{orderId}": {
+            "get": {
+                "tags": [
+                    "store"
+                ],
+                "summary": "Find purchase order by ID",
+                "description": "For valid response try integer IDs with value >= 1 and <= 10. Other values will generated exceptions",
+                "operationId": "getOrderById",
+                "produces": [
+                    "application/xml",
+                    "application/json"
+                ],
+                "parameters": [
+                    {
+                        "name": "orderId",
+                        "in": "path",
+                        "description": "ID of pet that needs to be fetched",
+                        "required": true,
+                        "type": "integer",
+                        "maximum": 10.0,
+                        "minimum": 1.0,
+                        "format": "int64"
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "successful operation",
+                        "schema": {
+                            "$ref": "#/definitions/Order"
+                        }
+                    },
+                    "400": {
+                        "description": "Invalid ID supplied"
+                    },
+                    "404": {
+                        "description": "Order not found"
+                    }
+                }
+            },
+            "delete": {
+                "tags": [
+                    "store"
+                ],
+                "summary": "Delete purchase order by ID",
+                "description": "For valid response try integer IDs with positive integer value. Negative or non-integer values will generate API errors",
+                "operationId": "deleteOrder",
+                "produces": [
+                    "application/xml",
+                    "application/json"
+                ],
+                "parameters": [
+                    {
+                        "name": "orderId",
+                        "in": "path",
+                        "description": "ID of the order that needs to be deleted",
+                        "required": true,
+                        "type": "integer",
+                        "minimum": 1.0,
+                        "format": "int64"
+                    }
+                ],
+                "responses": {
+                    "400": {
+                        "description": "Invalid ID supplied"
+                    },
+                    "404": {
+                        "description": "Order not found"
+                    }
+                }
+            }
+        },
+        "/user": {
+            "post": {
+                "tags": [
+                    "user"
+                ],
+                "summary": "Create user",
+                "description": "This can only be done by the logged in user.",
+                "operationId": "createUser",
+                "produces": [
+                    "application/xml",
+                    "application/json"
+                ],
+                "parameters": [
+                    {
+                        "in": "body",
+                        "name": "body",
+                        "description": "Created user object",
+                        "required": true,
+                        "schema": {
+                            "$ref": "#/definitions/User"
+                        }
+                    }
+                ],
+                "responses": {
+                    "default": {
+                        "description": "successful operation"
+                    }
+                }
+            }
+        },
+        "/user/createWithArray": {
+            "post": {
+                "tags": [
+                    "user"
+                ],
+                "summary": "Creates list of users with given input array",
+                "description": "",
+                "operationId": "createUsersWithArrayInput",
+                "produces": [
+                    "application/xml",
+                    "application/json"
+                ],
+                "parameters": [
+                    {
+                        "in": "body",
+                        "name": "body",
+                        "description": "List of user object",
+                        "required": true,
+                        "schema": {
+                            "type": "array",
+                            "items": {
+                                "$ref": "#/definitions/User"
+                            }
+                        }
+                    }
+                ],
+                "responses": {
+                    "default": {
+                        "description": "successful operation"
+                    }
+                }
+            }
+        },
+        "/user/createWithList": {
+            "post": {
+                "tags": [
+                    "user"
+                ],
+                "summary": "Creates list of users with given input array",
+                "description": "",
+                "operationId": "createUsersWithListInput",
+                "produces": [
+                    "application/xml",
+                    "application/json"
+                ],
+                "parameters": [
+                    {
+                        "in": "body",
+                        "name": "body",
+                        "description": "List of user object",
+                        "required": true,
+                        "schema": {
+                            "type": "array",
+                            "items": {
+                                "$ref": "#/definitions/User"
+                            }
+                        }
+                    }
+                ],
+                "responses": {
+                    "default": {
+                        "description": "successful operation"
+                    }
+                }
+            }
+        },
+        "/user/login": {
+            "get": {
+                "tags": [
+                    "user"
+                ],
+                "summary": "Logs user into the system",
+                "description": "",
+                "operationId": "loginUser",
+                "produces": [
+                    "application/xml",
+                    "application/json"
+                ],
+                "parameters": [
+                    {
+                        "name": "username",
+                        "in": "query",
+                        "description": "The user name for login",
+                        "required": true,
+                        "type": "string"
+                    },
+                    {
+                        "name": "password",
+                        "in": "query",
+                        "description": "The password for login in clear text",
+                        "required": true,
+                        "type": "string"
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "successful operation",
+                        "schema": {
+                            "type": "string"
+                        },
+                        "headers": {
+                            "X-Rate-Limit": {
+                                "type": "integer",
+                                "format": "int32",
+                                "description": "calls per hour allowed by the user"
+                            },
+                            "X-Expires-After": {
+                                "type": "string",
+                                "format": "date-time",
+                                "description": "date in UTC when token expires"
+                            }
+                        }
+                    },
+                    "400": {
+                        "description": "Invalid username/password supplied"
+                    }
+                }
+            }
+        },
+        "/user/logout": {
+            "get": {
+                "tags": [
+                    "user"
+                ],
+                "summary": "Logs out current logged in user session",
+                "description": "",
+                "operationId": "logoutUser",
+                "produces": [
+                    "application/xml",
+                    "application/json"
+                ],
+                "parameters": [
+                ],
+                "responses": {
+                    "default": {
+                        "description": "successful operation"
+                    }
+                }
+            }
+        },
+        "/user/{username}": {
+            "get": {
+                "tags": [
+                    "user"
+                ],
+                "summary": "Get user by user name",
+                "description": "",
+                "operationId": "getUserByName",
+                "produces": [
+                    "application/xml",
+                    "application/json"
+                ],
+                "parameters": [
+                    {
+                        "name": "username",
+                        "in": "path",
+                        "description": "The name that needs to be fetched. Use user1 for testing. ",
+                        "required": true,
+                        "type": "string"
+                    }
+                ],
+                "responses": {
+                    "200": {
+                        "description": "successful operation",
+                        "schema": {
+                            "$ref": "#/definitions/User"
+                        }
+                    },
+                    "400": {
+                        "description": "Invalid username supplied"
+                    },
+                    "404": {
+                        "description": "User not found"
+                    }
+                }
+            },
+            "put": {
+                "tags": [
+                    "user"
+                ],
+                "summary": "Updated user",
+                "description": "This can only be done by the logged in user.",
+                "operationId": "updateUser",
+                "produces": [
+                    "application/xml",
+                    "application/json"
+                ],
+                "parameters": [
+                    {
+                        "name": "username",
+                        "in": "path",
+                        "description": "name that need to be updated",
+                        "required": true,
+                        "type": "string"
+                    },
+                    {
+                        "in": "body",
+                        "name": "body",
+                        "description": "Updated user object",
+                        "required": true,
+                        "schema": {
+                            "$ref": "#/definitions/User"
+                        }
+                    }
+                ],
+                "responses": {
+                    "400": {
+                        "description": "Invalid user supplied"
+                    },
+                    "404": {
+                        "description": "User not found"
+                    }
+                }
+            },
+            "delete": {
+                "tags": [
+                    "user"
+                ],
+                "summary": "Delete user",
+                "description": "This can only be done by the logged in user.",
+                "operationId": "deleteUser",
+                "produces": [
+                    "application/xml",
+                    "application/json"
+                ],
+                "parameters": [
+                    {
+                        "name": "username",
+                        "in": "path",
+                        "description": "The name that needs to be deleted",
+                        "required": true,
+                        "type": "string"
+                    }
+                ],
+                "responses": {
+                    "400": {
+                        "description": "Invalid username supplied"
+                    },
+                    "404": {
+                        "description": "User not found"
+                    }
+                }
+            }
+        }
+    },
+    "securityDefinitions": {
+        "petstore_auth": {
+            "type": "oauth2",
+            "authorizationUrl": "http://petstore.swagger.io/oauth/dialog",
+            "flow": "implicit",
+            "scopes": {
+                "write:pets": "modify pets in your account",
+                "read:pets": "read your pets"
+            }
+        },
+        "api_key": {
+            "type": "apiKey",
+            "name": "api_key",
+            "in": "query"
+        }
+    },
+    "definitions": {
+        "Order": {
+            "type": "object",
+            "properties": {
+                "id": {
+                    "type": "integer",
+                    "format": "int64"
+                },
+                "petId": {
+                    "type": "integer",
+                    "format": "int64"
+                },
+                "quantity": {
+                    "type": "integer",
+                    "format": "int32"
+                },
+                "shipDate": {
+                    "type": "string",
+                    "format": "date-time"
+                },
+                "status": {
+                    "type": "string",
+                    "description": "Order Status",
+                    "enum": [
+                        "placed",
+                        "approved",
+                        "delivered"
+                    ]
+                },
+                "complete": {
+                    "type": "boolean",
+                    "default": false
+                }
+            },
+            "xml": {
+                "name": "Order"
+            }
+        },
+        "Category": {
+            "type": "object",
+            "properties": {
+                "id": {
+                    "type": "integer",
+                    "format": "int64"
+                },
+                "name": {
+                    "type": "string"
+                }
+            },
+            "xml": {
+                "name": "Category"
+            }
+        },
+        "User": {
+            "type": "object",
+            "properties": {
+                "id": {
+                    "type": "integer",
+                    "format": "int64"
+                },
+                "username": {
+                    "type": "string"
+                },
+                "firstName": {
+                    "type": "string"
+                },
+                "lastName": {
+                    "type": "string"
+                },
+                "email": {
+                    "type": "string"
+                },
+                "password": {
+                    "type": "string"
+                },
+                "phone": {
+                    "type": "string"
+                },
+                "userStatus": {
+                    "type": "integer",
+                    "format": "int32",
+                    "description": "User Status"
+                }
+            },
+            "xml": {
+                "name": "User"
+            }
+        },
+        "Tag": {
+            "type": "object",
+            "properties": {
+                "id": {
+                    "type": "integer",
+                    "format": "int64"
+                },
+                "name": {
+                    "type": "string"
+                }
+            },
+            "xml": {
+                "name": "Tag"
+            }
+        },
+        "Pet": {
+            "type": "object",
+            "required": [
+                "name",
+                "photoUrls"
+            ],
+            "properties": {
+                "id": {
+                    "type": "integer",
+                    "format": "int64"
+                },
+                "category": {
+                    "$ref": "#/definitions/Category"
+                },
+                "name": {
+                    "type": "string",
+                    "example": "doggie"
+                },
+                "photoUrls": {
+                    "type": "array",
+                    "xml": {
+                        "name": "photoUrl",
+                        "wrapped": true
+                    },
+                    "items": {
+                        "type": "string"
+                    }
+                },
+                "tags": {
+                    "type": "array",
+                    "xml": {
+                        "name": "tag",
+                        "wrapped": true
+                    },
+                    "items": {
+                        "$ref": "#/definitions/Tag"
+                    }
+                },
+                "status": {
+                    "type": "string",
+                    "description": "pet status in the store",
+                    "enum": [
+                        "available",
+                        "pending",
+                        "sold"
+                    ]
+                }
+            },
+            "xml": {
+                "name": "Pet"
+            }
+        },
+        "ApiResponse": {
+            "type": "object",
+            "properties": {
+                "code": {
+                    "type": "integer",
+                    "format": "int32"
+                },
+                "type": {
+                    "type": "string"
+                },
+                "message": {
+                    "type": "string"
+                }
+            }
+        }
+    },
+    "externalDocs": {
+        "description": "Find out more about Swagger",
+        "url": "http://swagger.io"
+    }
+}