You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2015/09/23 11:35:40 UTC

[04/16] camel git commit: CAMEL-8545: camel-swagger-java to run outside servlet - work in progress

CAMEL-8545: camel-swagger-java to run outside servlet - work in progress


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/3818efe3
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/3818efe3
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/3818efe3

Branch: refs/heads/master
Commit: 3818efe3ee2d1061134df37489d2f3a0dc100ea1
Parents: 8ce5a2b
Author: Claus Ibsen <da...@apache.org>
Authored: Tue Sep 22 14:07:39 2015 +0200
Committer: Claus Ibsen <da...@apache.org>
Committed: Wed Sep 23 07:51:03 2015 +0200

----------------------------------------------------------------------
 .../swagger/RestSwaggerAbstractServlet.java     | 241 -------------------
 .../camel/swagger/RestSwaggerCorsFilter.java    |  55 -----
 .../camel/swagger/RestSwaggerServlet.java       |  91 -------
 .../camel/swagger/RestSwaggerSupport.java       | 209 ++++++++++++++++
 .../swagger/servlet/RestSwaggerCorsFilter.java  |  55 +++++
 .../swagger/servlet/RestSwaggerServlet.java     | 127 ++++++++++
 .../servlet/ServletSwaggerApiProvider.java      |  55 +++++
 .../camel/swagger/spi/SwaggerApiProvider.java   |  32 +++
 .../src/main/webapp/WEB-INF/web.xml             |   6 +-
 9 files changed, 481 insertions(+), 390 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/3818efe3/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/RestSwaggerAbstractServlet.java
----------------------------------------------------------------------
diff --git a/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/RestSwaggerAbstractServlet.java b/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/RestSwaggerAbstractServlet.java
deleted file mode 100644
index a0a1a76..0000000
--- a/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/RestSwaggerAbstractServlet.java
+++ /dev/null
@@ -1,241 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.swagger;
-
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.List;
-import javax.servlet.ServletConfig;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import com.fasterxml.jackson.annotation.JsonInclude;
-import com.fasterxml.jackson.databind.ObjectMapper;
-import com.fasterxml.jackson.databind.SerializationFeature;
-import io.swagger.jaxrs.config.BeanConfig;
-import io.swagger.models.Contact;
-import io.swagger.models.Info;
-import io.swagger.models.License;
-import io.swagger.models.Swagger;
-import org.apache.camel.impl.DefaultClassResolver;
-import org.apache.camel.model.rest.RestDefinition;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import static org.apache.camel.swagger.SwaggerHelper.buildUrl;
-
-/**
- * Base class for rest-dsl swagger integration to use a servlet to service the swagger api.
- */
-public abstract class RestSwaggerAbstractServlet extends HttpServlet {
-
-    private Logger LOG = LoggerFactory.getLogger(RestSwaggerAbstractServlet.class);
-
-    private RestSwaggerReader reader = new RestSwaggerReader();
-    private BeanConfig swaggerConfig = new BeanConfig();
-    private boolean cors;
-    private volatile boolean initDone;
-
-    @Override
-    public void init(ServletConfig config) throws ServletException {
-        super.init(config);
-
-        // configure swagger options
-        String s = config.getInitParameter("swagger.version");
-        if (s != null) {
-            swaggerConfig.setVersion(s);
-        }
-        s = config.getInitParameter("base.path");
-        if (s != null) {
-            swaggerConfig.setBasePath(s);
-        }
-        s = config.getInitParameter("host");
-        if (s != null) {
-            swaggerConfig.setHost(s);
-        }
-        s = config.getInitParameter("cors");
-        if (s != null) {
-            cors = "true".equalsIgnoreCase(s);
-        }
-        s = config.getInitParameter("schemas");
-        if (s != null) {
-            String[] schemas = s.split(",");
-            swaggerConfig.setSchemes(schemas);
-        } else {
-            // assume http by default
-            swaggerConfig.setSchemes(new String[]{"http"});
-        }
-
-        String version = config.getInitParameter("api.version");
-        String title = config.getInitParameter("api.title");
-        String description = config.getInitParameter("api.description");
-        String termsOfService = config.getInitParameter("api.termsOfService");
-        String licenseName = config.getInitParameter("api.license.name");
-        String licenseUrl = config.getInitParameter("api.license.url");
-        String contactName = config.getInitParameter("api.contact.name");
-        String contactUrl = config.getInitParameter("api.contact.url");
-        String contactEmail = config.getInitParameter("api.contact.email");
-
-        Info info = new Info();
-        info.setVersion(version);
-        info.setTitle(title);
-        info.setDescription(description);
-        info.setTermsOfService(termsOfService);
-
-        if (licenseName != null || licenseUrl != null) {
-            License license = new License();
-            license.setName(licenseName);
-            license.setUrl(licenseUrl);
-            info.setLicense(license);
-        }
-
-        if (contactName != null || contactUrl != null || contactEmail != null) {
-            Contact contact = new Contact();
-            contact.setName(contactName);
-            contact.setUrl(contactUrl);
-            contact.setEmail(contactEmail);
-            info.setContact(contact);
-        }
-
-        swaggerConfig.setInfo(info);
-    }
-
-    public abstract List<RestDefinition> getRestDefinitions(String camelId) throws Exception;
-
-    public abstract List<String> findCamelContexts() throws Exception;
-
-    @Override
-    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
-
-        if (!initDone) {
-            initBaseAndApiPaths(request);
-        }
-
-        String contextId;
-        String route = request.getPathInfo();
-
-        try {
-
-            // render list of camel contexts as root
-            if (route == null || route.equals("") || route.equals("/")) {
-                renderCamelContexts(request, response);
-            } else {
-                // first part is the camel context
-                if (route.startsWith("/")) {
-                    route = route.substring(1);
-                }
-                // the remainder is the route part
-                contextId = route.split("/")[0];
-                if (route.startsWith(contextId)) {
-                    route = route.substring(contextId.length());
-                }
-
-                renderResourceListing(request, response, contextId, route);
-            }
-        } catch (Exception e) {
-            LOG.warn("Error rendering swagger due " + e.getMessage(), e);
-        }
-    }
-
-    private void renderResourceListing(HttpServletRequest request, HttpServletResponse response, String contextId, String route) throws Exception {
-        LOG.trace("renderResourceListing");
-
-        if (cors) {
-            response.addHeader("Access-Control-Allow-Headers", "Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");
-            response.addHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, CONNECT, PATCH");
-            response.addHeader("Access-Control-Allow-Origin", "*");
-        }
-
-        List<RestDefinition> rests = getRestDefinitions(contextId);
-        if (rests != null) {
-            // read the rest-dsl into swagger model
-            Swagger swagger = reader.read(rests, route, swaggerConfig, new DefaultClassResolver());
-
-            ObjectMapper mapper = new ObjectMapper();
-            mapper.enable(SerializationFeature.INDENT_OUTPUT);
-            mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
-            mapper.writeValue(response.getOutputStream(), swagger);
-        } else {
-            response.setStatus(204);
-        }
-    }
-
-    private void initBaseAndApiPaths(HttpServletRequest request) throws MalformedURLException {
-        String base = swaggerConfig.getBasePath();
-        if (base == null || !base.startsWith("http")) {
-            // base path is configured using relative, so lets calculate the absolute url now we have the http request
-            URL url = new URL(request.getRequestURL().toString());
-            if (base == null) {
-                base = "";
-            }
-            String path = translateContextPath(request);
-            swaggerConfig.setHost(url.getHost());
-
-            if (url.getPort() != 80 && url.getPort() != -1) {
-                swaggerConfig.setHost(url.getHost() + ":" + url.getPort());
-            } else {
-                swaggerConfig.setHost(url.getHost());
-            }
-            swaggerConfig.setBasePath(buildUrl(path, base));
-        }
-        initDone = true;
-    }
-
-    /**
-     * We do only want the base context-path and not sub paths
-     */
-    private String translateContextPath(HttpServletRequest request) {
-        String path = request.getContextPath();
-        if (path.isEmpty() || path.equals("/")) {
-            return "";
-        } else {
-            int idx = path.lastIndexOf("/");
-            if (idx > 0) {
-                return path.substring(0, idx);
-            }
-        }
-        return path;
-    }
-
-    /**
-     * Renders a list of available CamelContexts in the JVM
-     */
-    private void renderCamelContexts(HttpServletRequest request, HttpServletResponse response) throws Exception {
-        LOG.trace("renderCamelContexts");
-
-        if (cors) {
-            response.addHeader("Access-Control-Allow-Headers", "Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");
-            response.addHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, CONNECT, PATCH");
-            response.addHeader("Access-Control-Allow-Origin", "*");
-        }
-
-        List<String> contexts = findCamelContexts();
-        response.getWriter().print("[\n");
-        for (int i = 0; i < contexts.size(); i++) {
-            String name = contexts.get(i);
-            response.getWriter().print("{\"name\": \"" + name + "\"}");
-            if (i < contexts.size() - 1) {
-                response.getWriter().print(",\n");
-            }
-        }
-        response.getWriter().print("\n]");
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/camel/blob/3818efe3/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/RestSwaggerCorsFilter.java
----------------------------------------------------------------------
diff --git a/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/RestSwaggerCorsFilter.java b/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/RestSwaggerCorsFilter.java
deleted file mode 100644
index 0cf7303..0000000
--- a/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/RestSwaggerCorsFilter.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.swagger;
-
-import java.io.IOException;
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletResponse;
-
-/**
- * A simple CORS filter that can used to allow the swagger ui or other API browsers from remote origins to access the
- * Rest services exposes by this Camel swagger component.
- */
-public class RestSwaggerCorsFilter implements Filter {
-
-    @Override
-    public void init(FilterConfig filterConfig) throws ServletException {
-        // noop
-    }
-
-    @Override
-    public void destroy() {
-        // noop
-    }
-
-    @Override
-    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
-        HttpServletResponse res = (HttpServletResponse) response;
-
-        res.setHeader("Access-Control-Allow-Origin", "*");
-        res.setHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, CONNECT, PATCH");
-        res.setHeader("Access-Control-Max-Age", "3600");
-        res.setHeader("Access-Control-Allow-Headers", "Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");
-
-        chain.doFilter(request, response);
-    }
-}

http://git-wip-us.apache.org/repos/asf/camel/blob/3818efe3/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/RestSwaggerServlet.java
----------------------------------------------------------------------
diff --git a/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/RestSwaggerServlet.java b/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/RestSwaggerServlet.java
deleted file mode 100644
index 7d85e76..0000000
--- a/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/RestSwaggerServlet.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.swagger;
-
-import java.lang.management.ManagementFactory;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
-import javax.management.MBeanServer;
-import javax.management.ObjectName;
-
-import org.apache.camel.model.ModelHelper;
-import org.apache.camel.model.rest.RestDefinition;
-import org.apache.camel.model.rest.RestsDefinition;
-import org.apache.camel.util.CamelVersionHelper;
-
-/**
- * The default Camel swagger servlet to use when exposing the APIs of the rest-dsl using swagger.
- * <p/>
- * This requires Camel version 2.15 or better at runtime (and JMX to be enabled).
- */
-public class RestSwaggerServlet extends RestSwaggerAbstractServlet {
-
-    @Override
-    public List<RestDefinition> getRestDefinitions(String camelId) throws Exception {
-        ObjectName found = null;
-
-        MBeanServer server = ManagementFactory.getPlatformMBeanServer();
-        Set<ObjectName> names = server.queryNames(new ObjectName("org.apache.camel:type=context,*"), null);
-        for (ObjectName on : names) {
-            String id = on.getKeyProperty("name");
-            if (id.startsWith("\"") && id.endsWith("\"")) {
-                id = id.substring(1, id.length() - 1);
-            }
-            if (camelId == null || camelId.equals(id)) {
-                // filter out older Camel versions as this requires Camel 2.15 or better (rest-dsl)
-                String version = (String) server.getAttribute(on, "CamelVersion");
-                if (CamelVersionHelper.isGE("2.15.0", version)) {
-                    found = on;
-                }
-            }
-        }
-
-        if (found != null) {
-            String xml = (String) server.invoke(found, "dumpRestsAsXml", null, null);
-            if (xml != null) {
-                RestsDefinition rests = ModelHelper.createModelFromXml(null, xml, RestsDefinition.class);
-                if (rests != null) {
-                    return rests.getRests();
-                }
-            }
-        }
-
-        return null;
-    }
-
-    @Override
-    public List<String> findCamelContexts() throws Exception {
-        List<String> answer = new ArrayList<>();
-
-        MBeanServer server = ManagementFactory.getPlatformMBeanServer();
-        Set<ObjectName> names = server.queryNames(new ObjectName("*:type=context,*"), null);
-        for (ObjectName on : names) {
-            String id = on.getKeyProperty("name");
-            if (id.startsWith("\"") && id.endsWith("\"")) {
-                id = id.substring(1, id.length() - 1);
-            }
-
-            // filter out older Camel versions as this requires Camel 2.15 or better (rest-dsl)
-            String version = (String) server.getAttribute(on, "CamelVersion");
-            if (CamelVersionHelper.isGE("2.15.0", version)) {
-                answer.add(id);
-            }
-        }
-        return answer;
-    }
-}

http://git-wip-us.apache.org/repos/asf/camel/blob/3818efe3/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/RestSwaggerSupport.java
----------------------------------------------------------------------
diff --git a/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/RestSwaggerSupport.java b/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/RestSwaggerSupport.java
new file mode 100644
index 0000000..6b7f56d
--- /dev/null
+++ b/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/RestSwaggerSupport.java
@@ -0,0 +1,209 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.swagger;
+
+import java.lang.management.ManagementFactory;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializationFeature;
+import io.swagger.jaxrs.config.BeanConfig;
+import io.swagger.models.Contact;
+import io.swagger.models.Info;
+import io.swagger.models.License;
+import io.swagger.models.Swagger;
+import org.apache.camel.impl.DefaultClassResolver;
+import org.apache.camel.model.ModelHelper;
+import org.apache.camel.model.rest.RestDefinition;
+import org.apache.camel.model.rest.RestsDefinition;
+import org.apache.camel.swagger.spi.SwaggerApiProvider;
+import org.apache.camel.util.CamelVersionHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class RestSwaggerSupport {
+
+    private static final Logger LOG = LoggerFactory.getLogger(RestSwaggerSupport.class);
+    private RestSwaggerReader reader = new RestSwaggerReader();
+    private boolean cors;
+
+    public void initSwagger(BeanConfig swaggerConfig, SwaggerApiProvider config) {
+        // configure swagger options
+        String s = config.getInitParameter("swagger.version");
+        if (s != null) {
+            swaggerConfig.setVersion(s);
+        }
+        s = config.getInitParameter("base.path");
+        if (s != null) {
+            swaggerConfig.setBasePath(s);
+        }
+        s = config.getInitParameter("host");
+        if (s != null) {
+            swaggerConfig.setHost(s);
+        }
+        s = config.getInitParameter("cors");
+        if (s != null) {
+            cors = "true".equalsIgnoreCase(s);
+        }
+        s = config.getInitParameter("schemas");
+        if (s != null) {
+            String[] schemas = s.split(",");
+            swaggerConfig.setSchemes(schemas);
+        } else {
+            // assume http by default
+            swaggerConfig.setSchemes(new String[]{"http"});
+        }
+
+        String version = config.getInitParameter("api.version");
+        String title = config.getInitParameter("api.title");
+        String description = config.getInitParameter("api.description");
+        String termsOfService = config.getInitParameter("api.termsOfService");
+        String licenseName = config.getInitParameter("api.license.name");
+        String licenseUrl = config.getInitParameter("api.license.url");
+        String contactName = config.getInitParameter("api.contact.name");
+        String contactUrl = config.getInitParameter("api.contact.url");
+        String contactEmail = config.getInitParameter("api.contact.email");
+
+        Info info = new Info();
+        info.setVersion(version);
+        info.setTitle(title);
+        info.setDescription(description);
+        info.setTermsOfService(termsOfService);
+
+        if (licenseName != null || licenseUrl != null) {
+            License license = new License();
+            license.setName(licenseName);
+            license.setUrl(licenseUrl);
+            info.setLicense(license);
+        }
+
+        if (contactName != null || contactUrl != null || contactEmail != null) {
+            Contact contact = new Contact();
+            contact.setName(contactName);
+            contact.setUrl(contactUrl);
+            contact.setEmail(contactEmail);
+            info.setContact(contact);
+        }
+
+        swaggerConfig.setInfo(info);
+    }
+
+    public List<RestDefinition> getRestDefinitions(String camelId) throws Exception {
+        ObjectName found = null;
+
+        MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+        Set<ObjectName> names = server.queryNames(new ObjectName("org.apache.camel:type=context,*"), null);
+        for (ObjectName on : names) {
+            String id = on.getKeyProperty("name");
+            if (id.startsWith("\"") && id.endsWith("\"")) {
+                id = id.substring(1, id.length() - 1);
+            }
+            if (camelId == null || camelId.equals(id)) {
+                // filter out older Camel versions as this requires Camel 2.15 or better (rest-dsl)
+                String version = (String) server.getAttribute(on, "CamelVersion");
+                if (CamelVersionHelper.isGE("2.15.0", version)) {
+                    found = on;
+                }
+            }
+        }
+
+        if (found != null) {
+            String xml = (String) server.invoke(found, "dumpRestsAsXml", null, null);
+            if (xml != null) {
+                RestsDefinition rests = ModelHelper.createModelFromXml(null, xml, RestsDefinition.class);
+                if (rests != null) {
+                    return rests.getRests();
+                }
+            }
+        }
+
+        return null;
+    }
+
+    public List<String> findCamelContexts() throws Exception {
+        List<String> answer = new ArrayList<>();
+
+        MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+        Set<ObjectName> names = server.queryNames(new ObjectName("*:type=context,*"), null);
+        for (ObjectName on : names) {
+            String id = on.getKeyProperty("name");
+            if (id.startsWith("\"") && id.endsWith("\"")) {
+                id = id.substring(1, id.length() - 1);
+            }
+
+            // filter out older Camel versions as this requires Camel 2.15 or better (rest-dsl)
+            String version = (String) server.getAttribute(on, "CamelVersion");
+            if (CamelVersionHelper.isGE("2.15.0", version)) {
+                answer.add(id);
+            }
+        }
+        return answer;
+    }
+
+    public void renderResourceListing(SwaggerApiProvider provider, BeanConfig swaggerConfig, String contextId, String route) throws Exception {
+        LOG.trace("renderResourceListing");
+
+        if (cors) {
+            provider.addHeader("Access-Control-Allow-Headers", "Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");
+            provider.addHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, CONNECT, PATCH");
+            provider.addHeader("Access-Control-Allow-Origin", "*");
+        }
+
+        List<RestDefinition> rests = getRestDefinitions(contextId);
+        if (rests != null) {
+            // read the rest-dsl into swagger model
+            Swagger swagger = reader.read(rests, route, swaggerConfig, new DefaultClassResolver());
+
+            ObjectMapper mapper = new ObjectMapper();
+            mapper.enable(SerializationFeature.INDENT_OUTPUT);
+            mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+            mapper.writeValue(provider.getOutputStream(), swagger);
+        } else {
+            provider.noContent();
+        }
+    }
+
+    /**
+     * Renders a list of available CamelContexts in the JVM
+     */
+    public void renderCamelContexts(SwaggerApiProvider provider) throws Exception {
+        LOG.trace("renderCamelContexts");
+
+        if (cors) {
+            provider.addHeader("Access-Control-Allow-Headers", "Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");
+            provider.addHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, CONNECT, PATCH");
+            provider.addHeader("Access-Control-Allow-Origin", "*");
+        }
+
+        List<String> contexts = findCamelContexts();
+        provider.getOutputStream().write("[\n".getBytes());
+        for (int i = 0; i < contexts.size(); i++) {
+            String name = contexts.get(i);
+            provider.getOutputStream().write(("{\"name\": \"" + name + "\"}").getBytes());
+            if (i < contexts.size() - 1) {
+                provider.getOutputStream().write(",\n".getBytes());
+            }
+        }
+        provider.getOutputStream().write("\n]".getBytes());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/3818efe3/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/servlet/RestSwaggerCorsFilter.java
----------------------------------------------------------------------
diff --git a/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/servlet/RestSwaggerCorsFilter.java b/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/servlet/RestSwaggerCorsFilter.java
new file mode 100644
index 0000000..4aca487
--- /dev/null
+++ b/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/servlet/RestSwaggerCorsFilter.java
@@ -0,0 +1,55 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.swagger.servlet;
+
+import java.io.IOException;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.FilterConfig;
+import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * A simple CORS filter that can used to allow the swagger ui or other API browsers from remote origins to access the
+ * Rest services exposes by this Camel swagger component.
+ */
+public class RestSwaggerCorsFilter implements Filter {
+
+    @Override
+    public void init(FilterConfig filterConfig) throws ServletException {
+        // noop
+    }
+
+    @Override
+    public void destroy() {
+        // noop
+    }
+
+    @Override
+    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
+        HttpServletResponse res = (HttpServletResponse) response;
+
+        res.setHeader("Access-Control-Allow-Origin", "*");
+        res.setHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, CONNECT, PATCH");
+        res.setHeader("Access-Control-Max-Age", "3600");
+        res.setHeader("Access-Control-Allow-Headers", "Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers");
+
+        chain.doFilter(request, response);
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/3818efe3/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/servlet/RestSwaggerServlet.java
----------------------------------------------------------------------
diff --git a/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/servlet/RestSwaggerServlet.java b/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/servlet/RestSwaggerServlet.java
new file mode 100644
index 0000000..75d0290
--- /dev/null
+++ b/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/servlet/RestSwaggerServlet.java
@@ -0,0 +1,127 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.swagger.servlet;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import javax.servlet.ServletConfig;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import io.swagger.jaxrs.config.BeanConfig;
+import org.apache.camel.swagger.RestSwaggerSupport;
+import org.apache.camel.swagger.spi.SwaggerApiProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.apache.camel.swagger.SwaggerHelper.buildUrl;
+
+/**
+ * The default Camel swagger servlet to use when exposing the APIs of the rest-dsl using swagger.
+ * <p/>
+ * This requires Camel version 2.15 or better at runtime (and JMX to be enabled).
+ */
+public class RestSwaggerServlet extends HttpServlet {
+
+    private static final Logger LOG = LoggerFactory.getLogger(RestSwaggerServlet.class);
+    private BeanConfig swaggerConfig = new BeanConfig();
+    private RestSwaggerSupport swagger = new RestSwaggerSupport();
+    private volatile boolean initDone;
+
+    @Override
+    public void init(final ServletConfig config) throws ServletException {
+        super.init(config);
+
+        swagger.initSwagger(swaggerConfig, new ServletSwaggerApiProvider(config, null));
+    }
+
+    @Override
+    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+
+        if (!initDone) {
+            initBaseAndApiPaths(request);
+        }
+
+        SwaggerApiProvider resp = new ServletSwaggerApiProvider(null, response);
+
+        String contextId;
+        String route = request.getPathInfo();
+
+        try {
+
+            // render list of camel contexts as root
+            if (route == null || route.equals("") || route.equals("/")) {
+                swagger.renderCamelContexts(resp);
+            } else {
+                // first part is the camel context
+                if (route.startsWith("/")) {
+                    route = route.substring(1);
+                }
+                // the remainder is the route part
+                contextId = route.split("/")[0];
+                if (route.startsWith(contextId)) {
+                    route = route.substring(contextId.length());
+                }
+
+                swagger.renderResourceListing(resp, swaggerConfig, contextId, route);
+            }
+        } catch (Exception e) {
+            LOG.warn("Error rendering swagger due " + e.getMessage(), e);
+        }
+    }
+
+    private void initBaseAndApiPaths(HttpServletRequest request) throws MalformedURLException {
+        String base = swaggerConfig.getBasePath();
+        if (base == null || !base.startsWith("http")) {
+            // base path is configured using relative, so lets calculate the absolute url now we have the http request
+            URL url = new URL(request.getRequestURL().toString());
+            if (base == null) {
+                base = "";
+            }
+            String path = translateContextPath(request);
+            swaggerConfig.setHost(url.getHost());
+
+            if (url.getPort() != 80 && url.getPort() != -1) {
+                swaggerConfig.setHost(url.getHost() + ":" + url.getPort());
+            } else {
+                swaggerConfig.setHost(url.getHost());
+            }
+            swaggerConfig.setBasePath(buildUrl(path, base));
+        }
+        initDone = true;
+    }
+
+    /**
+     * We do only want the base context-path and not sub paths
+     */
+    private String translateContextPath(HttpServletRequest request) {
+        String path = request.getContextPath();
+        if (path.isEmpty() || path.equals("/")) {
+            return "";
+        } else {
+            int idx = path.lastIndexOf("/");
+            if (idx > 0) {
+                return path.substring(0, idx);
+            }
+        }
+        return path;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/3818efe3/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/servlet/ServletSwaggerApiProvider.java
----------------------------------------------------------------------
diff --git a/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/servlet/ServletSwaggerApiProvider.java b/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/servlet/ServletSwaggerApiProvider.java
new file mode 100644
index 0000000..3d39825
--- /dev/null
+++ b/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/servlet/ServletSwaggerApiProvider.java
@@ -0,0 +1,55 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.swagger.servlet;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import javax.servlet.ServletConfig;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.camel.swagger.spi.SwaggerApiProvider;
+
+public class ServletSwaggerApiProvider implements SwaggerApiProvider {
+
+    private final ServletConfig config;
+    private final HttpServletResponse response;
+
+    public ServletSwaggerApiProvider(ServletConfig config, HttpServletResponse response) {
+        this.config = config;
+        this.response = response;
+    }
+
+    @Override
+    public String getInitParameter(String key) {
+        return config.getInitParameter(key);
+    }
+
+    @Override
+    public void addHeader(String name, String value) {
+        response.addHeader(name, value);
+    }
+
+    @Override
+    public OutputStream getOutputStream() throws IOException {
+        return response.getOutputStream();
+    }
+
+    @Override
+    public void noContent() {
+        response.setStatus(HttpServletResponse.SC_NO_CONTENT);
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/3818efe3/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/spi/SwaggerApiProvider.java
----------------------------------------------------------------------
diff --git a/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/spi/SwaggerApiProvider.java b/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/spi/SwaggerApiProvider.java
new file mode 100644
index 0000000..42e6a2d
--- /dev/null
+++ b/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/spi/SwaggerApiProvider.java
@@ -0,0 +1,32 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.swagger.spi;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+public interface SwaggerApiProvider {
+
+    String getInitParameter(String key);
+
+    void addHeader(String name, String value);
+
+    OutputStream getOutputStream() throws IOException;
+
+    void noContent();
+
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/3818efe3/examples/camel-example-swagger-java/src/main/webapp/WEB-INF/web.xml
----------------------------------------------------------------------
diff --git a/examples/camel-example-swagger-java/src/main/webapp/WEB-INF/web.xml b/examples/camel-example-swagger-java/src/main/webapp/WEB-INF/web.xml
index 35527aa..cfde29f 100755
--- a/examples/camel-example-swagger-java/src/main/webapp/WEB-INF/web.xml
+++ b/examples/camel-example-swagger-java/src/main/webapp/WEB-INF/web.xml
@@ -44,7 +44,7 @@
   <!-- to setup Camel Swagger servlet -->
   <servlet>
     <servlet-name>ApiDeclarationServlet</servlet-name>
-    <servlet-class>org.apache.camel.swagger.RestSwaggerServlet</servlet-class>
+    <servlet-class>org.apache.camel.swagger.servlet.RestSwaggerServlet</servlet-class>
     <init-param>
       <!-- we specify the base.path using relative notation, that means the actual path will be calculated at runtime as
            http://server:port/contextpath/rest -->
@@ -91,7 +91,7 @@
   <!-- enable CORS filter so people can use swagger ui to browse and test the apis -->
   <filter>
     <filter-name>RestSwaggerCorsFilter</filter-name>
-    <filter-class>org.apache.camel.swagger.RestSwaggerCorsFilter</filter-class>
+    <filter-class>org.apache.camel.swagger.servlet.RestSwaggerCorsFilter</filter-class>
   </filter>
 
   <filter-mapping>
@@ -101,7 +101,7 @@
   </filter-mapping>
 
   <welcome-file-list>
-      <welcome-file>home.html</welcome-file>
+    <welcome-file>home.html</welcome-file>
   </welcome-file-list>
 
 </web-app>
\ No newline at end of file