Repository: camel Updated Branches: refs/heads/master 156f21f08 -> 8e11b7ace
CAMEL-9726: camel-swagger-java now supports yaml as output format. Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/8e11b7ac Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/8e11b7ac Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/8e11b7ac Branch: refs/heads/master Commit: 8e11b7ace433c3b368c0694c19186682de96f09a Parents: 156f21f Author: Claus Ibsen <[email protected]> Authored: Sun Mar 20 11:21:33 2016 +0100 Committer: Claus Ibsen <[email protected]> Committed: Sun Mar 20 11:30:09 2016 +0100 ---------------------------------------------------------------------- .../jetty/rest/RestApiJettyYamlTest.java | 35 +++++++++ components/camel-swagger-java/pom.xml | 4 +- .../camel/swagger/RestSwaggerProcessor.java | 24 +++++- .../camel/swagger/RestSwaggerSupport.java | 79 ++++++++++++++------ .../swagger/servlet/RestSwaggerServlet.java | 25 ++++++- 5 files changed, 139 insertions(+), 28 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/8e11b7ac/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/rest/RestApiJettyYamlTest.java ---------------------------------------------------------------------- diff --git a/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/rest/RestApiJettyYamlTest.java b/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/rest/RestApiJettyYamlTest.java new file mode 100644 index 0000000..907f3eb --- /dev/null +++ b/components/camel-jetty9/src/test/java/org/apache/camel/component/jetty/rest/RestApiJettyYamlTest.java @@ -0,0 +1,35 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.jetty.rest; + +import org.junit.Test; + +public class RestApiJettyYamlTest extends RestApiJettyTest { + + @Test + public void testApi() throws Exception { + String out = template.requestBody("jetty:http://localhost:{{port}}/api-doc/swagger.yaml", null, String.class); + assertNotNull(out); + assertTrue(out.contains("version: \"1.2.3\"")); + assertTrue(out.contains("title: \"The hello rest thing")); + assertTrue(out.contains("/hello/bye:")); + assertTrue(out.contains("- \"hello\"")); + assertTrue(out.contains("/hello/bye/{name}:")); + assertTrue(out.contains("- name: \"name\"")); + } + +} http://git-wip-us.apache.org/repos/asf/camel/blob/8e11b7ac/components/camel-swagger-java/pom.xml ---------------------------------------------------------------------- diff --git a/components/camel-swagger-java/pom.xml b/components/camel-swagger-java/pom.xml index a19a25c..f2afa26 100644 --- a/components/camel-swagger-java/pom.xml +++ b/components/camel-swagger-java/pom.xml @@ -15,7 +15,8 @@ See the License for the specific language governing permissions and limitations under the License. --> -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> @@ -43,6 +44,7 @@ <artifactId>camel-core</artifactId> </dependency> + <!-- json --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> http://git-wip-us.apache.org/repos/asf/camel/blob/8e11b7ac/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/RestSwaggerProcessor.java ---------------------------------------------------------------------- diff --git a/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/RestSwaggerProcessor.java b/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/RestSwaggerProcessor.java index 5a34355..51ffd12 100644 --- a/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/RestSwaggerProcessor.java +++ b/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/RestSwaggerProcessor.java @@ -53,13 +53,33 @@ public class RestSwaggerProcessor implements Processor { String contextId = exchange.getContext().getName(); String route = exchange.getIn().getHeader(Exchange.HTTP_PATH, String.class); + String accept = exchange.getIn().getHeader(Exchange.ACCEPT_CONTENT_TYPE, String.class); RestApiResponseAdapter adapter = new ExchangeRestApiResponseAdapter(exchange); + // whether to use json or yaml + boolean json = false; + boolean yaml = false; + if (route != null && route.endsWith("/swagger.json")) { + json = true; + route = route.substring(0, route.length() - 13); + } else if (route != null && route.endsWith("/swagger.yaml")) { + yaml = true; + route = route.substring(0, route.length() - 13); + } + if (accept != null && !json && !yaml) { + json = accept.contains("json"); + yaml = accept.contains("yaml"); + } + if (!json && !yaml) { + // json is default + json = true; + } + try { // render list of camel contexts as root if (contextIdListing && (ObjectHelper.isEmpty(route) || route.equals("/"))) { - support.renderCamelContexts(adapter, contextId, contextIdPattern); + support.renderCamelContexts(adapter, contextId, contextIdPattern, json, yaml); } else { String name; if (ObjectHelper.isNotEmpty(route)) { @@ -92,7 +112,7 @@ public class RestSwaggerProcessor implements Processor { if (!match) { adapter.noContent(); } else { - support.renderResourceListing(adapter, swaggerConfig, name, route, exchange.getContext().getClassResolver()); + support.renderResourceListing(adapter, swaggerConfig, name, route, json, yaml, exchange.getContext().getClassResolver()); } } } catch (Exception e) { http://git-wip-us.apache.org/repos/asf/camel/blob/8e11b7ac/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 index 7b51ada..0cef5b5 100644 --- 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 @@ -28,6 +28,7 @@ import javax.management.MBeanServer; import javax.management.ObjectName; import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import io.swagger.jaxrs.config.BeanConfig; @@ -35,6 +36,7 @@ import io.swagger.models.Contact; import io.swagger.models.Info; import io.swagger.models.License; import io.swagger.models.Swagger; +import io.swagger.util.Yaml; import org.apache.camel.Exchange; import org.apache.camel.model.ModelHelper; import org.apache.camel.model.rest.RestDefinition; @@ -187,7 +189,8 @@ public class RestSwaggerSupport { return answer; } - public void renderResourceListing(RestApiResponseAdapter response, BeanConfig swaggerConfig, String contextId, String route, ClassResolver classResolver) throws Exception { + public void renderResourceListing(RestApiResponseAdapter response, BeanConfig swaggerConfig, String contextId, String route, boolean json, boolean yaml, + ClassResolver classResolver) throws Exception { LOG.trace("renderResourceListing"); if (cors) { @@ -198,20 +201,41 @@ public class RestSwaggerSupport { List<RestDefinition> rests = getRestDefinitions(contextId); if (rests != null) { - response.setHeader(Exchange.CONTENT_TYPE, "application/json"); + if (json) { + response.setHeader(Exchange.CONTENT_TYPE, "text/json"); - // read the rest-dsl into swagger model - Swagger swagger = reader.read(rests, route, swaggerConfig, contextId, classResolver); + // read the rest-dsl into swagger model + Swagger swagger = reader.read(rests, route, swaggerConfig, contextId, classResolver); - ObjectMapper mapper = new ObjectMapper(); - mapper.enable(SerializationFeature.INDENT_OUTPUT); - mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); - byte[] bytes = mapper.writeValueAsBytes(swagger); + ObjectMapper mapper = new ObjectMapper(); + mapper.enable(SerializationFeature.INDENT_OUTPUT); + mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + byte[] bytes = mapper.writeValueAsBytes(swagger); - int len = bytes.length; - response.setHeader(Exchange.CONTENT_LENGTH, "" + len); + int len = bytes.length; + response.setHeader(Exchange.CONTENT_LENGTH, "" + len); - response.writeBytes(bytes); + response.writeBytes(bytes); + } else { + response.setHeader(Exchange.CONTENT_TYPE, "text/yaml"); + + // read the rest-dsl into swagger model + Swagger swagger = reader.read(rests, route, swaggerConfig, contextId, classResolver); + + ObjectMapper mapper = new ObjectMapper(); + mapper.enable(SerializationFeature.INDENT_OUTPUT); + mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + byte[] jsonData = mapper.writeValueAsBytes(swagger); + + // json to yaml + JsonNode node = mapper.readTree(jsonData); + byte[] bytes = Yaml.mapper().writerWithDefaultPrettyPrinter().writeValueAsBytes(node); + + int len = bytes.length; + response.setHeader(Exchange.CONTENT_LENGTH, "" + len); + + response.writeBytes(bytes); + } } else { response.noContent(); } @@ -220,7 +244,7 @@ public class RestSwaggerSupport { /** * Renders a list of available CamelContexts in the JVM */ - public void renderCamelContexts(RestApiResponseAdapter response, String contextId, String contextIdPattern) throws Exception { + public void renderCamelContexts(RestApiResponseAdapter response, String contextId, String contextIdPattern, boolean json, boolean yaml) throws Exception { LOG.trace("renderCamelContexts"); if (cors) { @@ -229,10 +253,6 @@ public class RestSwaggerSupport { response.setHeader("Access-Control-Allow-Origin", "*"); } - response.setHeader(Exchange.CONTENT_TYPE, "application/json"); - - StringBuffer sb = new StringBuffer(); - List<String> contexts = findCamelContexts(); // filter non matched CamelContext's @@ -253,15 +273,28 @@ public class RestSwaggerSupport { } } - sb.append("[\n"); - for (int i = 0; i < contexts.size(); i++) { - String name = contexts.get(i); - sb.append("{\"name\": \"").append(name).append("\"}"); - if (i < contexts.size() - 1) { - sb.append(",\n"); + StringBuffer sb = new StringBuffer(); + + if (json) { + response.setHeader(Exchange.CONTENT_TYPE, "text/json"); + + sb.append("[\n"); + for (int i = 0; i < contexts.size(); i++) { + String name = contexts.get(i); + sb.append("{\"name\": \"").append(name).append("\"}"); + if (i < contexts.size() - 1) { + sb.append(",\n"); + } + } + sb.append("\n]"); + } else { + response.setHeader(Exchange.CONTENT_TYPE, "text/yaml"); + + for (int i = 0; i < contexts.size(); i++) { + String name = contexts.get(i); + sb.append("- \"").append(name).append("\"\n"); } } - sb.append("\n]"); int len = sb.length(); response.setHeader(Exchange.CONTENT_LENGTH, "" + len); http://git-wip-us.apache.org/repos/asf/camel/blob/8e11b7ac/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 index 48b7ee5..cfa8539 100644 --- 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 @@ -30,6 +30,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import io.swagger.jaxrs.config.BeanConfig; +import org.apache.camel.Exchange; import org.apache.camel.impl.DefaultClassResolver; import org.apache.camel.spi.ClassResolver; import org.apache.camel.swagger.RestApiResponseAdapter; @@ -116,13 +117,33 @@ public class RestSwaggerServlet extends HttpServlet { String contextId = null; String route = request.getPathInfo(); + String accept = request.getHeader(Exchange.ACCEPT_CONTENT_TYPE); + + // whether to use json or yaml + boolean json = false; + boolean yaml = false; + if (route != null && route.endsWith("/swagger.json")) { + json = true; + route = route.substring(0, route.length() - 13); + } else if (route != null && route.endsWith("/swagger.yaml")) { + yaml = true; + route = route.substring(0, route.length() - 13); + } + if (accept != null && !json && !yaml) { + json = accept.contains("json"); + yaml = accept.contains("yaml"); + } + if (!json && !yaml) { + // json is default + json = true; + } RestApiResponseAdapter adapter = new ServletRestApiResponseAdapter(response); try { // render list of camel contexts as root if (apiContextIdListing && (ObjectHelper.isEmpty(route) || route.equals("/"))) { - support.renderCamelContexts(adapter, contextId, apiContextIdPattern); + support.renderCamelContexts(adapter, contextId, apiContextIdPattern, json, yaml); } else { String name = null; if (ObjectHelper.isNotEmpty(route)) { @@ -162,7 +183,7 @@ public class RestSwaggerServlet extends HttpServlet { if (!match) { adapter.noContent(); } else { - support.renderResourceListing(adapter, swaggerConfig, name, route, classResolver); + support.renderResourceListing(adapter, swaggerConfig, name, route, json, yaml, classResolver); } } } catch (Exception e) {
