Repository: cxf Updated Branches: refs/heads/master 0f7b744eb -> 7988c4a97
[CXF-6476] Introduce Swagger 2.0 API to the swagger feature Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/7988c4a9 Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/7988c4a9 Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/7988c4a9 Branch: refs/heads/master Commit: 7988c4a974118cc5c2a8bd956fe396a7d5e8bb5c Parents: 0f7b744 Author: Akitoshi Yoshida <[email protected]> Authored: Fri Jul 3 12:15:10 2015 +0200 Committer: Akitoshi Yoshida <[email protected]> Committed: Sat Jul 4 01:03:53 2015 +0200 ---------------------------------------------------------------------- .../jax_rs/description_swagger2/README.txt | 23 +++ .../samples/jax_rs/description_swagger2/pom.xml | 163 +++++++++++++++++++ .../java/demo/jaxrs/swagger/server/Item.java | 49 ++++++ .../java/demo/jaxrs/swagger/server/Sample.java | 130 +++++++++++++++ .../java/demo/jaxrs/swagger/server/Server.java | 74 +++++++++ .../META-INF/cxf/org.apache.cxf.Logger | 1 + .../webjars/swagger-ui/2.1.0/index.html | 84 ++++++++++ .../src/main/resources/logback.xml | 16 ++ parent/pom.xml | 24 ++- rt/rs/description/pom.xml | 5 + .../jaxrs/swagger/AbstractSwaggerFeature.java | 128 +++++++++++++++ .../cxf/jaxrs/swagger/Swagger2Feature.java | 107 ++++++++++++ .../cxf/jaxrs/swagger/SwaggerFeature.java | 103 +----------- 13 files changed, 799 insertions(+), 108 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/7988c4a9/distribution/src/main/release/samples/jax_rs/description_swagger2/README.txt ---------------------------------------------------------------------- diff --git a/distribution/src/main/release/samples/jax_rs/description_swagger2/README.txt b/distribution/src/main/release/samples/jax_rs/description_swagger2/README.txt new file mode 100644 index 0000000..0ceee5b --- /dev/null +++ b/distribution/src/main/release/samples/jax_rs/description_swagger2/README.txt @@ -0,0 +1,23 @@ +JAX-RS Search Demo +================= + +The demo shows a basic usage of Swagger API documentation with REST based Web Services using +JAX-RS 2.0 (JSR-339). Swagger UI is available at: http://localhost:9000/ + +Building and running the demo using Maven +--------------------------------------- + +From the base directory of this sample (i.e., where this README file is +located), the Maven pom.xml file can be used to build and run the demo. + + +Using either UNIX or Windows: + + mvn install + mvn -Pserver (from one command line window) + + +To remove the target dir, run mvn clean". + + + http://git-wip-us.apache.org/repos/asf/cxf/blob/7988c4a9/distribution/src/main/release/samples/jax_rs/description_swagger2/pom.xml ---------------------------------------------------------------------- diff --git a/distribution/src/main/release/samples/jax_rs/description_swagger2/pom.xml b/distribution/src/main/release/samples/jax_rs/description_swagger2/pom.xml new file mode 100644 index 0000000..313383e --- /dev/null +++ b/distribution/src/main/release/samples/jax_rs/description_swagger2/pom.xml @@ -0,0 +1,163 @@ +<?xml version="1.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. +--> +<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> + <artifactId>jax_rs_description_swagger2</artifactId> + <name>JAX-RS Swagger Demo</name> + <description>JAX-RS Basic Demo</description> + <parent> + <groupId>org.apache.cxf.samples</groupId> + <artifactId>cxf-samples</artifactId> + <version>3.1.2-SNAPSHOT</version> + <relativePath>../..</relativePath> + </parent> + + <properties> + <cxf.version>${project.version}</cxf.version> + <httpclient.version>3.1</httpclient.version> + </properties> + + <profiles> + <profile> + <id>server</id> + <build> + <defaultGoal>test</defaultGoal> + <plugins> + <plugin> + <groupId>org.codehaus.mojo</groupId> + <artifactId>exec-maven-plugin</artifactId> + <executions> + <execution> + <phase>test</phase> + <goals> + <goal>java</goal> + </goals> + <configuration> + <mainClass>demo.jaxrs.swagger.server.Server</mainClass> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + </profile> + </profiles> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-dependency-plugin</artifactId> + <version>2.9</version> + <executions> + <execution> + <phase>generate-resources</phase> + <goals> + <goal>unpack</goal> + </goals> + <configuration> + <artifactItems> + <artifactItem> + <groupId>org.webjars</groupId> + <artifactId>swagger-ui</artifactId> + <version>2.1.0</version> + <overWrite>true</overWrite> + <outputDirectory>${project.build.directory}/classes</outputDirectory> + <excludes>**/index.html</excludes> + </artifactItem> + </artifactItems> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> + + <dependencies> + <dependency> + <groupId>io.swagger</groupId> + <artifactId>swagger-jaxrs</artifactId> + <exclusions> + <exclusion> + <groupId>javax.ws.rs</groupId> + <artifactId>jsr311-api</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.webjars</groupId> + <artifactId>swagger-ui</artifactId> + <version>2.1.0</version> + <scope>provided</scope> + </dependency> + <dependency> + <groupId>javassist</groupId> + <artifactId>javassist</artifactId> + <version>3.12.1.GA</version> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.jaxrs</groupId> + <artifactId>jackson-jaxrs-json-provider</artifactId> + <version>2.4.1</version> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.core</groupId> + <artifactId>jackson-core</artifactId> + <version>2.4.1</version> + </dependency> + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-rt-transports-http</artifactId> + <version>3.1.2-SNAPSHOT</version> + </dependency> + <!-- This dependency is needed if you're using the Jetty container --> + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-rt-transports-http-jetty</artifactId> + <version>3.1.2-SNAPSHOT</version> + </dependency> + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-rt-frontend-jaxrs</artifactId> + <version>3.1.2-SNAPSHOT</version> + </dependency> + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-rt-rs-service-description</artifactId> + <version>3.1.2-SNAPSHOT</version> + </dependency> + <dependency> + <groupId>commons-lang</groupId> + <artifactId>commons-lang</artifactId> + </dependency> + <dependency> + <groupId>commons-httpclient</groupId> + <artifactId>commons-httpclient</artifactId> + </dependency> + <dependency> + <groupId>javax.ws.rs</groupId> + <artifactId>javax.ws.rs-api</artifactId> + </dependency> + <dependency> + <groupId>org.eclipse.jetty</groupId> + <artifactId>jetty-webapp</artifactId> + </dependency> + </dependencies> +</project> http://git-wip-us.apache.org/repos/asf/cxf/blob/7988c4a9/distribution/src/main/release/samples/jax_rs/description_swagger2/src/main/java/demo/jaxrs/swagger/server/Item.java ---------------------------------------------------------------------- diff --git a/distribution/src/main/release/samples/jax_rs/description_swagger2/src/main/java/demo/jaxrs/swagger/server/Item.java b/distribution/src/main/release/samples/jax_rs/description_swagger2/src/main/java/demo/jaxrs/swagger/server/Item.java new file mode 100644 index 0000000..1b5be9b --- /dev/null +++ b/distribution/src/main/release/samples/jax_rs/description_swagger2/src/main/java/demo/jaxrs/swagger/server/Item.java @@ -0,0 +1,49 @@ +/** + * 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 demo.jaxrs.swagger.server; + +public class Item { + private String name; + private String value; + + public Item() { + } + + public Item(final String name, final String value) { + this.name = name; + this.value = value; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} http://git-wip-us.apache.org/repos/asf/cxf/blob/7988c4a9/distribution/src/main/release/samples/jax_rs/description_swagger2/src/main/java/demo/jaxrs/swagger/server/Sample.java ---------------------------------------------------------------------- diff --git a/distribution/src/main/release/samples/jax_rs/description_swagger2/src/main/java/demo/jaxrs/swagger/server/Sample.java b/distribution/src/main/release/samples/jax_rs/description_swagger2/src/main/java/demo/jaxrs/swagger/server/Sample.java new file mode 100644 index 0000000..56d3213 --- /dev/null +++ b/distribution/src/main/release/samples/jax_rs/description_swagger2/src/main/java/demo/jaxrs/swagger/server/Sample.java @@ -0,0 +1,130 @@ +/** + * 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 demo.jaxrs.swagger.server; + +import java.util.Arrays; + +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.DefaultValue; +import javax.ws.rs.FormParam; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; + +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; + +@Path("/sample") +@Api(value = "/sample", description = "Sample JAX-RS service with Swagger documentation") +public class Sample { + @Produces({ MediaType.APPLICATION_JSON }) + @GET + @ApiOperation( + value = "Get operation with Response and @Default value", + notes = "Get operation with Response and @Default value", + response = Item.class, + responseContainer = "List" + ) + public Response getItems( + @ApiParam(value = "Page to fetch", required = true) @QueryParam("page") @DefaultValue("1") int page) { + return Response.ok( + Arrays.asList( + new Item("Item 1", "Value 1"), + new Item("Item 2", "Value 2") + ) + ).build(); + } + + @Produces({ MediaType.APPLICATION_JSON }) + @Path("/{name}") + @GET + @ApiOperation( + value = "Get operation with type and headers", + notes = "Get operation with type and headers", + response = Item.class + ) + public Item getItem( + @ApiParam(value = "language", required = true) @HeaderParam("Accept-Language") final String language, + @ApiParam(value = "name", required = true) @PathParam("name") String name) { + return new Item("name", "Value in " + language); + } + + @Consumes({ MediaType.APPLICATION_JSON }) + @POST + @ApiOperation( + value = "Post operation with entity in a body", + notes = "Post operation with entity in a body", + response = Item.class + ) + public Response createItem( + @Context final UriInfo uriInfo, + @ApiParam(value = "item", required = true) final Item item) { + + return Response + .created(uriInfo.getBaseUriBuilder().path(item.getName()).build()) + .entity(item).build(); + } + + @Produces({ MediaType.APPLICATION_JSON }) + @Path("/{name}") + @PUT + @ApiOperation( + value = "Put operation with form parameter", + notes = "Put operation with form parameter", + response = Item.class + ) + public Item updateItem( + @ApiParam(value = "name", required = true) @PathParam("name") String name, + @ApiParam(value = "value", required = true) @FormParam("value") String value) { + return new Item(name, value); + } + + @Path("/{name}") + @DELETE + @ApiOperation( + value = "Delete operation with implicit header", + notes = "Delete operation with implicit header" + ) + @ApiImplicitParams( + @ApiImplicitParam( + name = "Accept-Language", + value = "language", + required = true, + dataType = "String", + paramType = "header" + ) + ) + public Response delete(@ApiParam(value = "name", required = true) @PathParam("name") String name) { + return Response.ok().build(); + } +} http://git-wip-us.apache.org/repos/asf/cxf/blob/7988c4a9/distribution/src/main/release/samples/jax_rs/description_swagger2/src/main/java/demo/jaxrs/swagger/server/Server.java ---------------------------------------------------------------------- diff --git a/distribution/src/main/release/samples/jax_rs/description_swagger2/src/main/java/demo/jaxrs/swagger/server/Server.java b/distribution/src/main/release/samples/jax_rs/description_swagger2/src/main/java/demo/jaxrs/swagger/server/Server.java new file mode 100644 index 0000000..e06d496 --- /dev/null +++ b/distribution/src/main/release/samples/jax_rs/description_swagger2/src/main/java/demo/jaxrs/swagger/server/Server.java @@ -0,0 +1,74 @@ +/** + * 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 demo.jaxrs.swagger.server; + +import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider; + +import org.apache.commons.lang.StringUtils; +import org.apache.cxf.jaxrs.provider.MultipartProvider; +import org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet; +import org.apache.cxf.jaxrs.swagger.Swagger2Feature; +import org.eclipse.jetty.servlet.DefaultServlet; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.servlet.ServletHolder; + +public class Server { + + protected Server() throws Exception { + org.eclipse.jetty.server.Server server = new org.eclipse.jetty.server.Server(9000); + + // Configuring all static web resource + final ServletHolder staticHolder = new ServletHolder(new DefaultServlet()); + // Register and map the dispatcher servlet + final ServletHolder servletHolder = new ServletHolder(new CXFNonSpringJaxrsServlet()); + final ServletContextHandler context = new ServletContextHandler(); + context.setContextPath("/"); + context.addServlet(staticHolder, "/static/*"); + context.addServlet(servletHolder, "/*"); + context.setResourceBase( + getClass().getResource("/META-INF/resources/webjars/swagger-ui/2.1.0").toURI().toString()); + + servletHolder.setInitParameter("redirects-list", + "/ /index.html /.*[.]js /css/.* /images/.* lib/.* .*ico"); + servletHolder.setInitParameter("redirect-servlet-name", staticHolder.getName()); + servletHolder.setInitParameter("redirect-attributes", "javax.servlet.include.request_uri"); + servletHolder.setInitParameter("jaxrs.serviceClasses", Sample.class.getName()); + servletHolder.setInitParameter("jaxrs.features", Swagger2Feature.class.getName()); + servletHolder.setInitParameter("jaxrs.providers", StringUtils.join( + new String[] { + MultipartProvider.class.getName(), + JacksonJsonProvider.class.getName() + }, ",") + ); + + server.setHandler(context); + server.start(); + server.join(); + } + + public static void main(String args[]) throws Exception { + new Server(); + System.out.println("Server ready..."); + + Thread.sleep(5 * 6000 * 1000); + System.out.println("Server exiting"); + System.exit(0); + } +} http://git-wip-us.apache.org/repos/asf/cxf/blob/7988c4a9/distribution/src/main/release/samples/jax_rs/description_swagger2/src/main/resources/META-INF/cxf/org.apache.cxf.Logger ---------------------------------------------------------------------- diff --git a/distribution/src/main/release/samples/jax_rs/description_swagger2/src/main/resources/META-INF/cxf/org.apache.cxf.Logger b/distribution/src/main/release/samples/jax_rs/description_swagger2/src/main/resources/META-INF/cxf/org.apache.cxf.Logger new file mode 100644 index 0000000..27dd788 --- /dev/null +++ b/distribution/src/main/release/samples/jax_rs/description_swagger2/src/main/resources/META-INF/cxf/org.apache.cxf.Logger @@ -0,0 +1 @@ +org.apache.cxf.common.logging.Slf4jLogger \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cxf/blob/7988c4a9/distribution/src/main/release/samples/jax_rs/description_swagger2/src/main/resources/META-INF/resources/webjars/swagger-ui/2.1.0/index.html ---------------------------------------------------------------------- diff --git a/distribution/src/main/release/samples/jax_rs/description_swagger2/src/main/resources/META-INF/resources/webjars/swagger-ui/2.1.0/index.html b/distribution/src/main/release/samples/jax_rs/description_swagger2/src/main/resources/META-INF/resources/webjars/swagger-ui/2.1.0/index.html new file mode 100644 index 0000000..6095ccc --- /dev/null +++ b/distribution/src/main/release/samples/jax_rs/description_swagger2/src/main/resources/META-INF/resources/webjars/swagger-ui/2.1.0/index.html @@ -0,0 +1,84 @@ +<!DOCTYPE html> +<html> +<!-- This page is generated from swagger-ui-2.1.0/index.html.gz --> +<head> + <title>Swagger UI + JAX-RS demo</title> + <link href='css/reset.css' media='screen' rel='stylesheet' type='text/css'/> + <link href='css/screen.css' media='screen' rel='stylesheet' type='text/css'/> + <link href='css/reset.css' media='print' rel='stylesheet' type='text/css'/> + <link href='css/print.css' media='print' rel='stylesheet' type='text/css'/> + <script src='lib/jquery-1.8.0.min.js' type='text/javascript'></script> + <script src='lib/jquery.slideto.min.js' type='text/javascript'></script> + <script src='lib/jquery.wiggle.min.js' type='text/javascript'></script> + <script src='lib/jquery.ba-bbq.min.js' type='text/javascript'></script> + <script src='lib/handlebars-2.0.0.js' type='text/javascript'></script> + <script src='lib/underscore-min.js' type='text/javascript'></script> + <script src='lib/backbone-min.js' type='text/javascript'></script> + <script src='swagger-ui.js' type='text/javascript'></script> + <script src='lib/highlight.7.3.pack.js' type='text/javascript'></script> + <script src='lib/marked.js' type='text/javascript'></script> + <script src='lib/swagger-oauth.js' type='text/javascript'></script> + + <script type="text/javascript"> + $(function () { + var url = "/swagger.json"; + window.swaggerUi = new SwaggerUi({ + url: url, + dom_id: "swagger-ui-container", + supportedSubmitMethods: ['get', 'post', 'put', 'delete', 'patch'], + onComplete: function(swaggerApi, swaggerUi){ + if(typeof initOAuth == "function") { + initOAuth({ + clientId: "your-client-id", + realm: "your-realms", + appName: "your-app-name" + }); + } + + $('pre code').each(function(i, e) { + hljs.highlightBlock(e) + }); + + addApiKeyAuthorization(); + }, + onFailure: function(data) { + log("Unable to Load SwaggerUI"); + }, + docExpansion: "none", + apisSorter: "alpha", + showRequestHeaders: false + }); + + function addApiKeyAuthorization(){ + var key = encodeURIComponent($('#input_apiKey')[0].value); + if(key && key.trim() != "") { + var apiKeyAuth = new SwaggerClient.ApiKeyAuthorization("api_key", key, "query"); + window.swaggerUi.api.clientAuthorizations.add("api_key", apiKeyAuth); + log("added key " + key); + } + } + + $('#input_apiKey').change(addApiKeyAuthorization); + + // if you have an apiKey you would like to pre-populate on the page for demonstration purposes... + /* + var apiKey = "myApiKeyXXXX123456789"; + $('#input_apiKey').val(apiKey); + */ + + window.swaggerUi.load(); + + function log() { + if ('console' in window) { + console.log.apply(console, arguments); + } + } + }); + </script> +</head> + +<body class="swagger-section"> +<div id="message-bar" class="swagger-ui-wrap"> </div> +<div id="swagger-ui-container" class="swagger-ui-wrap"></div> +</body> +</html> http://git-wip-us.apache.org/repos/asf/cxf/blob/7988c4a9/distribution/src/main/release/samples/jax_rs/description_swagger2/src/main/resources/logback.xml ---------------------------------------------------------------------- diff --git a/distribution/src/main/release/samples/jax_rs/description_swagger2/src/main/resources/logback.xml b/distribution/src/main/release/samples/jax_rs/description_swagger2/src/main/resources/logback.xml new file mode 100644 index 0000000..0a3e031 --- /dev/null +++ b/distribution/src/main/release/samples/jax_rs/description_swagger2/src/main/resources/logback.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<configuration scan="true" scanPeriod="5 seconds"> + <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> + <encoder> + <pattern>[%level] %d{yyyy-MM-dd HH:mm:ss.SSS} %logger{36} - [%X] %msg%n</pattern> + </encoder> + </appender> + + <root level="INFO"> + <appender-ref ref="STDOUT" /> + </root> + + <logger category="com.wordnik.swagger" name="swagger"> + <level name="DEBUG"/> + </logger> +</configuration> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cxf/blob/7988c4a9/parent/pom.xml ---------------------------------------------------------------------- diff --git a/parent/pom.xml b/parent/pom.xml index 0af2cf6..9052b21 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -142,6 +142,7 @@ <cxf.spring.ldap.version>1.3.1.RELEASE</cxf.spring.ldap.version> <cxf.spring.mock>spring-test</cxf.spring.mock> <cxf.swagger.version>1.3.12</cxf.swagger.version> + <cxf.swagger2.version>1.5.0</cxf.swagger2.version> <cxf.velocity.version>1.7</cxf.velocity.version> <cxf.woodstox.core.version>4.4.1</cxf.woodstox.core.version> <cxf.woodstox.stax2-api.version>3.1.4</cxf.woodstox.stax2-api.version> @@ -579,7 +580,7 @@ ${cxf.osgi.dynamic.import} </DynamicImport-Package> <Export-Service> - ${cxf.export.service} + ${cxf.export.service} </Export-Service> <Bundle-Activator>${cxf.bundle.activator}</Bundle-Activator> </instructions> @@ -1237,10 +1238,10 @@ <version>${cxf.spring.security.version}</version> </dependency> <dependency> - <groupId>org.apache.olingo</groupId> - <artifactId>olingo-odata2-core</artifactId> - <version>${cxf.olingo.version}</version> - </dependency> + <groupId>org.apache.olingo</groupId> + <artifactId>olingo-odata2-core</artifactId> + <version>${cxf.olingo.version}</version> + </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-core</artifactId> @@ -1771,16 +1772,21 @@ <artifactId>swagger-jaxrs_2.10</artifactId> <version>${cxf.swagger.version}</version> </dependency> - <dependency> + <dependency> + <groupId>io.swagger</groupId> + <artifactId>swagger-jaxrs</artifactId> + <version>${cxf.swagger2.version}</version> + </dependency> + <dependency> <groupId>org.apache.tika</groupId> <artifactId>tika-core</artifactId> <version>${cxf.tika.version}</version> - </dependency> - <dependency> + </dependency> + <dependency> <groupId>org.apache.tika</groupId> <artifactId>tika-parsers</artifactId> <version>${cxf.tika.version}</version> - </dependency> + </dependency> <dependency> <groupId>io.dropwizard.metrics</groupId> <artifactId>metrics-core</artifactId> http://git-wip-us.apache.org/repos/asf/cxf/blob/7988c4a9/rt/rs/description/pom.xml ---------------------------------------------------------------------- diff --git a/rt/rs/description/pom.xml b/rt/rs/description/pom.xml index c5575ad..2d768d6 100644 --- a/rt/rs/description/pom.xml +++ b/rt/rs/description/pom.xml @@ -87,6 +87,11 @@ <artifactId>swagger-jaxrs_2.10</artifactId> <optional>true</optional> </dependency> + <dependency> + <groupId>io.swagger</groupId> + <artifactId>swagger-jaxrs</artifactId> + <optional>true</optional> + </dependency> </dependencies> <build> <plugins> http://git-wip-us.apache.org/repos/asf/cxf/blob/7988c4a9/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/swagger/AbstractSwaggerFeature.java ---------------------------------------------------------------------- diff --git a/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/swagger/AbstractSwaggerFeature.java b/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/swagger/AbstractSwaggerFeature.java new file mode 100644 index 0000000..5b45829 --- /dev/null +++ b/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/swagger/AbstractSwaggerFeature.java @@ -0,0 +1,128 @@ +/** + * 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.cxf.jaxrs.swagger; + +import org.apache.cxf.Bus; +import org.apache.cxf.endpoint.Server; +import org.apache.cxf.feature.AbstractFeature; +import org.apache.cxf.jaxrs.JAXRSServiceFactoryBean; +import org.apache.cxf.jaxrs.model.AbstractResourceInfo; + +abstract class AbstractSwaggerFeature extends AbstractFeature { + protected boolean scan = true; + protected boolean runAsFilter; + private String resourcePackage; + private String version = "1.0.0"; + private String basePath; + private String title = "Sample REST Application"; + private String description = "The Application"; + private String contact = "[email protected]"; + private String license = "Apache 2.0 License"; + private String licenseUrl = "http://www.apache.org/licenses/LICENSE-2.0.html"; + + @Override + public void initialize(Server server, Bus bus) { + calculateDefaultResourcePackage(server); + calculateDefaultBasePath(server); + addSwaggerResource(server); + + initializeProvider(server.getEndpoint(), bus); + } + + protected abstract void addSwaggerResource(Server server); + + private void calculateDefaultResourcePackage(Server server) { + JAXRSServiceFactoryBean serviceFactoryBean = + (JAXRSServiceFactoryBean)server.getEndpoint().get(JAXRSServiceFactoryBean.class.getName()); + AbstractResourceInfo resourceInfo = serviceFactoryBean.getClassResourceInfo().get(0); + + if ((resourceInfo != null) + && (getResourcePackage() == null || getResourcePackage().length() == 0)) { + setResourcePackage(resourceInfo.getServiceClass().getPackage().getName()); + } + } + + private void calculateDefaultBasePath(Server server) { + if (getBasePath() == null || getBasePath().length() == 0) { + String address = server.getEndpoint().getEndpointInfo().getAddress(); + setBasePath(address); + } + } + public String getResourcePackage() { + return resourcePackage; + } + public void setResourcePackage(String resourcePackage) { + this.resourcePackage = resourcePackage; + } + public String getVersion() { + return version; + } + public void setVersion(String version) { + this.version = version; + } + public String getBasePath() { + return basePath; + } + public void setBasePath(String basePath) { + this.basePath = basePath; + } + public String getTitle() { + return title; + } + public void setTitle(String title) { + this.title = title; + } + public String getDescription() { + return description; + } + public void setDescription(String description) { + this.description = description; + } + public String getContact() { + return contact; + } + public void setContact(String contact) { + this.contact = contact; + } + public String getLicense() { + return license; + } + public void setLicense(String license) { + this.license = license; + } + public String getLicenseUrl() { + return licenseUrl; + } + public void setLicenseUrl(String licenseUrl) { + this.licenseUrl = licenseUrl; + } + public boolean isScan() { + return scan; + } + public void setScan(boolean scan) { + this.scan = scan; + } + + public boolean isRunAsFilter() { + return runAsFilter; + } + public void setRunAsFilter(boolean runAsFilter) { + this.runAsFilter = runAsFilter; + } +} http://git-wip-us.apache.org/repos/asf/cxf/blob/7988c4a9/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/swagger/Swagger2Feature.java ---------------------------------------------------------------------- diff --git a/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/swagger/Swagger2Feature.java b/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/swagger/Swagger2Feature.java new file mode 100644 index 0000000..d21c559 --- /dev/null +++ b/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/swagger/Swagger2Feature.java @@ -0,0 +1,107 @@ +/** + * 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.cxf.jaxrs.swagger; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerRequestFilter; +import javax.ws.rs.container.PreMatching; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; + +import org.apache.cxf.endpoint.Server; +import org.apache.cxf.jaxrs.JAXRSServiceFactoryBean; +import org.apache.cxf.jaxrs.ext.MessageContext; +import org.apache.cxf.jaxrs.model.ClassResourceInfo; +import org.apache.cxf.jaxrs.provider.ServerProviderFactory; +import org.apache.cxf.jaxrs.utils.InjectionUtils; + +import io.swagger.jaxrs.config.BeanConfig; +import io.swagger.jaxrs.listing.ApiListingResource; +import io.swagger.jaxrs.listing.SwaggerSerializers; + +public class Swagger2Feature extends AbstractSwaggerFeature { + + @Override + protected void addSwaggerResource(Server server) { + ApiListingResource apiListingResource = new ApiListingResource(); + if (!runAsFilter) { + List<Object> serviceBeans = new ArrayList<Object>(); + serviceBeans.add(apiListingResource); + JAXRSServiceFactoryBean sfb = + (JAXRSServiceFactoryBean)server.getEndpoint().get(JAXRSServiceFactoryBean.class.getName()); + sfb.setResourceClassesFromBeans(serviceBeans); + for (ClassResourceInfo cri : sfb.getClassResourceInfo()) { + if (ApiListingResource.class == cri.getResourceClass()) { + InjectionUtils.injectContextProxiesAndApplication(cri, apiListingResource, null); + } + } + } + List<Object> providers = new ArrayList<Object>(); + if (runAsFilter) { + providers.add(new SwaggerContainerRequestFilter(apiListingResource)); + } + providers.add(new SwaggerSerializers()); + ((ServerProviderFactory)server.getEndpoint().get( + ServerProviderFactory.class.getName())).setUserProviders(providers); + + BeanConfig beanConfig = new BeanConfig(); + beanConfig.setResourcePackage(getResourcePackage()); + beanConfig.setVersion(getVersion()); + beanConfig.setBasePath(getBasePath()); + beanConfig.setTitle(getTitle()); + beanConfig.setDescription(getDescription()); + beanConfig.setContact(getContact()); + beanConfig.setLicense(getLicense()); + beanConfig.setLicenseUrl(getLicenseUrl()); + beanConfig.setScan(isScan()); + } + + @PreMatching + private static class SwaggerContainerRequestFilter implements ContainerRequestFilter { + private static final String APIDOCS_LISTING_PATH_JSON = "swagger.json"; + private static final String APIDOCS_LISTING_PATH_YAML = "swagger.yaml"; + + private ApiListingResource apiListingResource; + @Context + private MessageContext mc; + public SwaggerContainerRequestFilter(ApiListingResource apiListingResource) { + this.apiListingResource = apiListingResource; + } + + @Override + public void filter(ContainerRequestContext requestContext) throws IOException { + UriInfo ui = mc.getUriInfo(); + if (ui.getPath().endsWith(APIDOCS_LISTING_PATH_JSON)) { + Response r = + apiListingResource.getListingJson(null, mc.getServletConfig(), mc.getHttpHeaders(), ui); + requestContext.abortWith(r); + } else if (ui.getPath().endsWith(APIDOCS_LISTING_PATH_YAML)) { + Response r = + apiListingResource.getListingYaml(null, mc.getServletConfig(), mc.getHttpHeaders(), ui); + requestContext.abortWith(r); + } + } + + } +} http://git-wip-us.apache.org/repos/asf/cxf/blob/7988c4a9/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/swagger/SwaggerFeature.java ---------------------------------------------------------------------- diff --git a/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/swagger/SwaggerFeature.java b/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/swagger/SwaggerFeature.java index 85ef7a8..b4191e3 100644 --- a/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/swagger/SwaggerFeature.java +++ b/rt/rs/description/src/main/java/org/apache/cxf/jaxrs/swagger/SwaggerFeature.java @@ -36,31 +36,15 @@ import com.wordnik.swagger.jaxrs.listing.ApiDeclarationProvider; import com.wordnik.swagger.jaxrs.listing.ApiListingResourceJSON; import com.wordnik.swagger.jaxrs.listing.ResourceListingProvider; -import org.apache.cxf.Bus; import org.apache.cxf.endpoint.Server; -import org.apache.cxf.feature.AbstractFeature; import org.apache.cxf.jaxrs.JAXRSServiceFactoryBean; import org.apache.cxf.jaxrs.ext.MessageContext; -import org.apache.cxf.jaxrs.model.AbstractResourceInfo; import org.apache.cxf.jaxrs.provider.ServerProviderFactory; -public class SwaggerFeature extends AbstractFeature { - - private String resourcePackage; - private String version = "1.0.0"; - private String basePath; - private String title = "Sample REST Application"; - private String description = "The Application"; - private String contact = "[email protected]"; - private String license = "Apache 2.0 License"; - private String licenseUrl = "http://www.apache.org/licenses/LICENSE-2.0.html"; - private boolean scan = true; - private boolean runAsFilter; - +public class SwaggerFeature extends AbstractSwaggerFeature { + @Override - public void initialize(Server server, Bus bus) { - calculateDefaultResourcePackage(server); - calculateDefaultBasePath(server); + protected void addSwaggerResource(Server server) { ApiListingResourceJSON apiListingResource = new ApiListingResourceJSON(); if (!runAsFilter) { List<Object> serviceBeans = new ArrayList<Object>(); @@ -87,86 +71,7 @@ public class SwaggerFeature extends AbstractFeature { beanConfig.setLicense(getLicense()); beanConfig.setLicenseUrl(getLicenseUrl()); beanConfig.setScan(isScan()); - initializeProvider(server.getEndpoint(), bus); - } - private void calculateDefaultResourcePackage(Server server) { - JAXRSServiceFactoryBean serviceFactoryBean = - (JAXRSServiceFactoryBean)server.getEndpoint().get(JAXRSServiceFactoryBean.class.getName()); - AbstractResourceInfo resourceInfo = serviceFactoryBean.getClassResourceInfo().get(0); - - if ((resourceInfo != null) - && (getResourcePackage() == null || getResourcePackage().length() == 0)) { - setResourcePackage(resourceInfo.getServiceClass().getPackage().getName()); - } - } - - private void calculateDefaultBasePath(Server server) { - if (getBasePath() == null || getBasePath().length() == 0) { - String address = server.getEndpoint().getEndpointInfo().getAddress(); - setBasePath(address); - } - } - public String getResourcePackage() { - return resourcePackage; - } - public void setResourcePackage(String resourcePackage) { - this.resourcePackage = resourcePackage; - } - public String getVersion() { - return version; - } - public void setVersion(String version) { - this.version = version; - } - public String getBasePath() { - return basePath; - } - public void setBasePath(String basePath) { - this.basePath = basePath; - } - public String getTitle() { - return title; - } - public void setTitle(String title) { - this.title = title; - } - public String getDescription() { - return description; - } - public void setDescription(String description) { - this.description = description; - } - public String getContact() { - return contact; - } - public void setContact(String contact) { - this.contact = contact; - } - public String getLicense() { - return license; - } - public void setLicense(String license) { - this.license = license; - } - public String getLicenseUrl() { - return licenseUrl; - } - public void setLicenseUrl(String licenseUrl) { - this.licenseUrl = licenseUrl; - } - public boolean isScan() { - return scan; - } - public void setScan(boolean scan) { - this.scan = scan; - } - - public boolean isRunAsFilter() { - return runAsFilter; - } - public void setRunAsFilter(boolean runAsFilter) { - this.runAsFilter = runAsFilter; - } + } @PreMatching private static class SwaggerContainerRequestFilter implements ContainerRequestFilter {
