Repository: servicemix-bundles Updated Branches: refs/heads/master 6189ee82d -> a1970a9cb
[SM-2476] Create OSGi bundles for swagger-core_2.11 and swagger-jaxrs_2.11 Project: http://git-wip-us.apache.org/repos/asf/servicemix-bundles/repo Commit: http://git-wip-us.apache.org/repos/asf/servicemix-bundles/commit/a1970a9c Tree: http://git-wip-us.apache.org/repos/asf/servicemix-bundles/tree/a1970a9c Diff: http://git-wip-us.apache.org/repos/asf/servicemix-bundles/diff/a1970a9c Branch: refs/heads/master Commit: a1970a9cb7e14e9cd061066adfa3530e84bf6dce Parents: 6189ee8 Author: Jean-Baptiste Onofré <[email protected]> Authored: Mon Mar 23 11:20:55 2015 +0100 Committer: Jean-Baptiste Onofré <[email protected]> Committed: Mon Mar 23 11:20:55 2015 +0100 ---------------------------------------------------------------------- pom.xml | 2 + swagger-core_2.11-1.3.12/pom.xml | 115 ++++++++++++ .../src/main/resources/OSGI-INF/bundle.info | 10 ++ swagger-jaxrs_2.11-1.3.12/pom.xml | 130 ++++++++++++++ .../src/main/resources/OSGI-INF/bundle.info | 10 ++ .../swagger/jaxrs/listing/ApiListing.scala | 176 +++++++++++++++++++ 6 files changed, 443 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/servicemix-bundles/blob/a1970a9c/pom.xml ---------------------------------------------------------------------- diff --git a/pom.xml b/pom.xml index 2d3f1ec..0c3288f 100644 --- a/pom.xml +++ b/pom.xml @@ -117,6 +117,8 @@ <module>swagger-jaxrs-1.3.11</module> <module>swagger-jaxrs-1.3.12</module> <module>json4s_2.11-3.2.11</module> + <module>swagger-jaxrs_2.11-1.3.12</module> + <module>swagger-core_2.11-1.3.12</module> </modules> </project> http://git-wip-us.apache.org/repos/asf/servicemix-bundles/blob/a1970a9c/swagger-core_2.11-1.3.12/pom.xml ---------------------------------------------------------------------- diff --git a/swagger-core_2.11-1.3.12/pom.xml b/swagger-core_2.11-1.3.12/pom.xml new file mode 100644 index 0000000..ccdcfc4 --- /dev/null +++ b/swagger-core_2.11-1.3.12/pom.xml @@ -0,0 +1,115 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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/xsd/maven-4.0.0.xsd"> + + <!-- + + 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. + --> + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.servicemix.bundles</groupId> + <artifactId>bundles-pom</artifactId> + <version>12-SNAPSHOT</version> + <relativePath>../bundles-pom/pom.xml</relativePath> + </parent> + + <groupId>org.apache.servicemix.bundles</groupId> + <artifactId>org.apache.servicemix.bundles.swagger-core</artifactId> + <version>1.3.12_1-SNAPSHOT</version> + <packaging>bundle</packaging> + <name>Apache ServiceMix :: Bundles :: ${pkgArtifactId}</name> + <description>This OSGi bundle wraps ${pkgArtifactId} ${pkgVersion} jar file.</description> + + <properties> + <pkgGroupId>com.wordnik</pkgGroupId> + <pkgArtifactId>swagger-core_2.11</pkgArtifactId> + <pkgVersion>1.3.12</pkgVersion> + <servicemix.osgi.export.pkg> + com.wordnik.swagger* + </servicemix.osgi.export.pkg> + <servicemix.osgi.import.pkg> + sun.reflect.generics.reflectiveObjects;resolution:=optional, + scala*;version="[2.10,3)", + org.slf4j;version="[1.6,2)";resolution:=optional, + * + </servicemix.osgi.import.pkg> + </properties> + + <dependencies> + <dependency> + <groupId>${pkgGroupId}</groupId> + <artifactId>${pkgArtifactId}</artifactId> + <version>${pkgVersion}</version> + <exclusions> + <exclusion> + <groupId>com.wordnik</groupId> + <artifactId>swagger-annotations</artifactId> + </exclusion> + </exclusions> + </dependency> + + <!-- sources --> + <dependency> + <groupId>${pkgGroupId}</groupId> + <artifactId>${pkgArtifactId}</artifactId> + <version>${pkgVersion}</version> + <classifier>sources</classifier> + <optional>true</optional> + <exclusions> + <exclusion> + <groupId>com.wordnik</groupId> + <artifactId>swagger-annotations</artifactId> + </exclusion> + </exclusions> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-shade-plugin</artifactId> + <executions> + <execution> + <phase>package</phase> + <goals> + <goal>shade</goal> + </goals> + <configuration> + <artifactSet> + <includes> + <include>${pkgGroupId}:${pkgArtifactId}</include> + </includes> + </artifactSet> + <filters> + <filter> + <artifact>${pkgGroupId}:${pkgArtifactId}</artifact> + <excludes> + <exclude>**</exclude> + </excludes> + </filter> + </filters> + <promoteTransitiveDependencies>true</promoteTransitiveDependencies> + <createDependencyReducedPom>true</createDependencyReducedPom> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project> http://git-wip-us.apache.org/repos/asf/servicemix-bundles/blob/a1970a9c/swagger-core_2.11-1.3.12/src/main/resources/OSGI-INF/bundle.info ---------------------------------------------------------------------- diff --git a/swagger-core_2.11-1.3.12/src/main/resources/OSGI-INF/bundle.info b/swagger-core_2.11-1.3.12/src/main/resources/OSGI-INF/bundle.info new file mode 100644 index 0000000..cc40a73 --- /dev/null +++ b/swagger-core_2.11-1.3.12/src/main/resources/OSGI-INF/bundle.info @@ -0,0 +1,10 @@ +\u001B[1mSYNOPSIS\u001B[0m + ${project.description} + + Original Maven URL: + \u001B[33mmvn:${pkgGroupId}/${pkgArtifactId}/${pkgVersion}\u001B[0m + +\u001B[1mDESCRIPTION\u001B[0m + Swagger is a specification and complete framework implementation for describing, producing, consuming, and visualizing RESTful web services. The overarching goal of Swagger is to enable client and documentation systems to update at the same pace as the server. The documentation of methods, parameters, and models are tightly integrated into the server code, allowing APIs to always stay in sync. With Swagger, deploying managing, and using powerful APIs has never been easier. +\u001B[1mSEE ALSO\u001B[0m + \u001B[36mhttps://developers.helloreverb.com/swagger/\u001B[0m http://git-wip-us.apache.org/repos/asf/servicemix-bundles/blob/a1970a9c/swagger-jaxrs_2.11-1.3.12/pom.xml ---------------------------------------------------------------------- diff --git a/swagger-jaxrs_2.11-1.3.12/pom.xml b/swagger-jaxrs_2.11-1.3.12/pom.xml new file mode 100644 index 0000000..ba69d4e --- /dev/null +++ b/swagger-jaxrs_2.11-1.3.12/pom.xml @@ -0,0 +1,130 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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/xsd/maven-4.0.0.xsd"> + + <!-- + + 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. + --> + + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.servicemix.bundles</groupId> + <artifactId>bundles-pom</artifactId> + <version>12-SNAPSHOT</version> + <relativePath>../bundles-pom/pom.xml</relativePath> + </parent> + + <groupId>org.apache.servicemix.bundles</groupId> + <artifactId>org.apache.servicemix.bundles.swagger-jaxrs_2.11</artifactId> + <version>1.3.12_1-SNAPSHOT</version> + <packaging>bundle</packaging> + <name>Apache ServiceMix :: Bundles :: ${pkgArtifactId}</name> + <description>This OSGi bundle wraps ${pkgArtifactId} ${pkgVersion} jar file.</description> + + <properties> + <pkgGroupId>com.wordnik</pkgGroupId> + <pkgArtifactId>swagger-jaxrs_2.11</pkgArtifactId> + <pkgVersion>1.3.12</pkgVersion> + <servicemix.osgi.export.pkg> + com.wordnik.swagger.jaxrs* + </servicemix.osgi.export.pkg> + <servicemix.osgi.import.pkg> + javax.ws.rs*;version="[1.1,3)", + scala*;version="[2.10,3)", + org.slf4j;version="[1.6,2)";resolution:=optional, + * + </servicemix.osgi.import.pkg> + </properties> + + <dependencies> + <dependency> + <groupId>${pkgGroupId}</groupId> + <artifactId>${pkgArtifactId}</artifactId> + <version>${pkgVersion}</version> + </dependency> + + <!-- sources --> + <dependency> + <groupId>${pkgGroupId}</groupId> + <artifactId>${pkgArtifactId}</artifactId> + <version>${pkgVersion}</version> + <classifier>sources</classifier> + <optional>true</optional> + </dependency> + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>servlet-api</artifactId> + <version>2.5</version> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>net.alchim31.maven</groupId> + <artifactId>scala-maven-plugin</artifactId> + <executions> + <execution> + <id>scala-compile-first</id> + <phase>process-resources</phase> + <goals> + <goal>add-source</goal> + <goal>compile</goal> + </goals> + </execution> + <execution> + <id>scala-test-compile</id> + <phase>process-test-resources</phase> + <goals> + <goal>testCompile</goal> + </goals> + </execution> + </executions> + </plugin> + + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-shade-plugin</artifactId> + <executions> + <execution> + <phase>package</phase> + <goals> + <goal>shade</goal> + </goals> + <configuration> + <artifactSet> + <includes> + <include>${pkgGroupId}:${pkgArtifactId}</include> + </includes> + </artifactSet> + <filters> + <filter> + <artifact>${pkgGroupId}:${pkgArtifactId}</artifact> + <excludes> + <exclude>**</exclude> + </excludes> + </filter> + </filters> + <promoteTransitiveDependencies>true</promoteTransitiveDependencies> + <createDependencyReducedPom>true</createDependencyReducedPom> + </configuration> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project> http://git-wip-us.apache.org/repos/asf/servicemix-bundles/blob/a1970a9c/swagger-jaxrs_2.11-1.3.12/src/main/resources/OSGI-INF/bundle.info ---------------------------------------------------------------------- diff --git a/swagger-jaxrs_2.11-1.3.12/src/main/resources/OSGI-INF/bundle.info b/swagger-jaxrs_2.11-1.3.12/src/main/resources/OSGI-INF/bundle.info new file mode 100644 index 0000000..cc40a73 --- /dev/null +++ b/swagger-jaxrs_2.11-1.3.12/src/main/resources/OSGI-INF/bundle.info @@ -0,0 +1,10 @@ +\u001B[1mSYNOPSIS\u001B[0m + ${project.description} + + Original Maven URL: + \u001B[33mmvn:${pkgGroupId}/${pkgArtifactId}/${pkgVersion}\u001B[0m + +\u001B[1mDESCRIPTION\u001B[0m + Swagger is a specification and complete framework implementation for describing, producing, consuming, and visualizing RESTful web services. The overarching goal of Swagger is to enable client and documentation systems to update at the same pace as the server. The documentation of methods, parameters, and models are tightly integrated into the server code, allowing APIs to always stay in sync. With Swagger, deploying managing, and using powerful APIs has never been easier. +\u001B[1mSEE ALSO\u001B[0m + \u001B[36mhttps://developers.helloreverb.com/swagger/\u001B[0m http://git-wip-us.apache.org/repos/asf/servicemix-bundles/blob/a1970a9c/swagger-jaxrs_2.11-1.3.12/src/main/scala/com/wordnik/swagger/jaxrs/listing/ApiListing.scala ---------------------------------------------------------------------- diff --git a/swagger-jaxrs_2.11-1.3.12/src/main/scala/com/wordnik/swagger/jaxrs/listing/ApiListing.scala b/swagger-jaxrs_2.11-1.3.12/src/main/scala/com/wordnik/swagger/jaxrs/listing/ApiListing.scala new file mode 100644 index 0000000..dd7c6d0 --- /dev/null +++ b/swagger-jaxrs_2.11-1.3.12/src/main/scala/com/wordnik/swagger/jaxrs/listing/ApiListing.scala @@ -0,0 +1,176 @@ +package com.wordnik.swagger.jaxrs.listing + +import com.wordnik.swagger.config._ +import com.wordnik.swagger.reader._ +import com.wordnik.swagger.core.util._ +import com.wordnik.swagger.model._ +import com.wordnik.swagger.core.filter._ +import com.wordnik.swagger.annotations._ +import com.wordnik.swagger.jaxrs._ +import com.wordnik.swagger.jaxrs.config._ + +import org.slf4j.LoggerFactory + +import java.lang.annotation.Annotation +import java.lang.reflect.Method + +import javax.ws.rs.core.{ UriInfo, HttpHeaders, Context, Response, MediaType, Application, MultivaluedMap } +import javax.ws.rs.core.Response._ +import javax.ws.rs._ +import javax.ws.rs.ext.Provider + +import javax.servlet.ServletConfig +import java.util.HashMap + +import scala.collection.mutable.LinkedHashMap + +import scala.collection.JavaConverters._ +import scala.collection.mutable.ListBuffer + +object ApiListingCache { + private val LOGGER = LoggerFactory.getLogger(ApiListingCache.getClass) + + var _cache: Option[Map[String, ApiListing]] = None + + var caches: java.util.Map[Object, Option[Map[String, ApiListing]]] = new HashMap[Object, Option[Map[String, ApiListing]]] + + def listing(docRoot: String, app: Application, sc: ServletConfig): Option[Map[String, ApiListing]] = { + val scanner = sc.getServletContext().getAttribute("SCANNER") + if (scanner != null) { + _cache = caches.get(scanner) + } + if (_cache == null) { + _cache = None + } + _cache.orElse{ + LOGGER.debug("loading cache") + ClassReaders.reader.map{reader => + + val classes = scanner match { + case scanner: JaxrsScanner => scanner.asInstanceOf[JaxrsScanner].classesFromContext(app, null) + case _ => List() + } + // For each top level resource, parse it and look for swagger annotations. + val listings = (for(cls <- classes) yield reader.read(docRoot, cls, ConfigFactory.config)).flatten.toList + _cache = Some((listings.map(m => { + // always start with "/" + val resourcePath = m.resourcePath.startsWith ("/") match { + case true => m.resourcePath + case false => "/" + m.resourcePath + } + LOGGER.debug("adding resource path " + resourcePath) + (resourcePath, m) + })).toMap) + + ; + } + _cache + } + caches.put(scanner, _cache) + if(_cache != None) + LOGGER.debug("cache has " + _cache.get.keys + " keys") + else + LOGGER.debug("cache is empty") + _cache + } + + def invalidateCache() = { + _cache = None + } +} + +class ApiListingResource { + private val LOGGER = LoggerFactory.getLogger(classOf[ApiListingResource]) + + @GET + def resourceListing ( + @Context app: Application, + @Context sc: ServletConfig, + @Context headers: HttpHeaders, + @Context uriInfo: UriInfo + ): Response = { + val docRoot = this.getClass.getAnnotation(classOf[Path]).value + val f = new SpecFilter + val listings = ApiListingCache.listing(docRoot, app, sc).map(specs => { + (for(spec <- specs.values) + yield f.filter(spec, FilterFactory.filter, paramsToMap(uriInfo.getQueryParameters), cookiesToMap(headers), headersToMap(headers)) + ).filter(m => m.apis.size > 0) + }) + val references = (for(listing <- listings.getOrElse(List())) yield { + ApiListingReference(listing.resourcePath, listing.description, listing.position) + }).toList.sortWith(_.position < _.position) + + val config = ConfigFactory.config + val resourceListing = ResourceListing(config.apiVersion, + config.swaggerVersion, + references, + config.authorizations, + config.info + ) + Response.ok(resourceListing).build + } + + /** + * individual api listing + **/ + @GET + @Path("/{route: .+}") + def apiDeclaration ( + @PathParam("route") route: String, + @Context app: Application, + @Context sc: ServletConfig, + @Context headers: HttpHeaders, + @Context uriInfo: UriInfo + ): Response = { + LOGGER.debug("requested apiDeclaration for " + route) + val docRoot = this.getClass.getAnnotation(classOf[Path]).value + val f = new SpecFilter + val pathPart = cleanRoute(route) + LOGGER.debug("requested route " + pathPart) + val listings = ApiListingCache.listing(docRoot, app, sc).map(specs => { + (for(spec <- specs.values) yield { + LOGGER.debug("inspecting path " + spec.resourcePath) + f.filter(spec, FilterFactory.filter, paramsToMap(uriInfo.getQueryParameters), cookiesToMap(headers), headersToMap(headers)) + }).filter(m => { + val resourcePath = m.resourcePath match { + case e: String if(e.startsWith("/")) => e + case e: String => "/" + e + } + resourcePath == pathPart + }) + }).toList.flatten + + listings.size match { + case 1 => Response.ok(listings(0)).build + case _ => Response.status(404).build + } + } + + // ensure leading slash, remove trailing + def cleanRoute(route: String) = { + val cleanStart = { + if(route.startsWith("/")) route + else "/" + route + } + if(cleanStart.endsWith("/")) cleanStart.substring(0, cleanStart.length - 1) + else cleanStart + } + + def invalidateCache() = { + ApiListingCache.invalidateCache() + } + + def paramsToMap(params: MultivaluedMap[String, String]): Map[String, List[String]] = { + (for((key, list) <- params.asScala) yield (key, list.asScala.toList)).toMap + } + + def cookiesToMap(headers: HttpHeaders): Map[String, String] = { + Option(headers).map(h => { + (for((name, cookie) <- h.getCookies.asScala) yield (name, cookie.getValue)).toMap + }).getOrElse(Map()) + } + + def headersToMap(headers: HttpHeaders): Map[String, List[String]] = { + (for((key, values) <- headers.getRequestHeaders.asScala) yield (key, values.asScala.toList)).toMap + } +} \ No newline at end of file
