Skip to content
This repository has been archived by the owner on Sep 14, 2022. It is now read-only.

ref #214 - Vendor Extensions support in API Info #215

Open
wants to merge 12 commits into
base: play-2.6
Choose a base branch
from
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ cache:
language: scala

scala:
- 2.11.12
- 2.12.6
- 2.12.10
- 2.13.1

script:
- sbt ++$TRAVIS_SCALA_VERSION compile test
Expand Down
20 changes: 18 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,20 @@

# Swagger Play2 Module

## Note

This branch (`master`) holds the latest version (major version `2.x`) for latest play version supported (`2.7`); branch [play-2.6](https://github.com/swagger-api/swagger-play/tree/play-2.6) holds the swagger-play version for play `2.6` version (major.minor version `1.6.x`).

Older versions are available though not anymore supported in the [archive](https://github.com/swagger-api/swagger-play/tree/archive) branch.

## Overview

This is a module to support Swagger annotations within [Play Framework](http://www.playframework.org) controllers. It is based on the library https://github.com/swagger-api/swagger-play with several improvements. This library uses Swagger 1.5 and Play 2.6. It can be used for both Scala and Java based applications.

We also would like to support Swagger 2.0 in the future and contributions to that end will be gladly accepted.


###New and Noteworthy
### New and Noteworthy

- Minimal dependencies: only depends on the core Play module, so it won't bring unnecessary dependencies on the Akka HTTP server or anything else from Play.
- `SwaggerPlugin` no longer depends on on `Application`.
Expand All @@ -19,15 +25,25 @@ We also would like to support Swagger 2.0 in the future and contributions to tha
- Handle route delegation properly (https://github.com/swagger-api/swagger-play/pull/132 updated for Play 2.6)
- Add support for `dataTypeClass` in `ApiImplicitParam` (https://github.com/swagger-api/swagger-play/pull/174)
- Add support for API keys (https://github.com/swagger-api/swagger-play/pull/117)
<<<<<<< HEAD
- Add support for OAuth2 (https://github.com/swagger-api/swagger-play/pull/183)

## Usage
=======

Usage
-----
>>>>>>> 32d3d11b9b19c7dccf1052fe63a6f7edc397cf8a

You can depend on pre-built libraries in maven central by adding the following dependency:

```
libraryDependencies ++= Seq(
<<<<<<< HEAD
"io.swagger" %% "swagger-play2" % "2.0.1-SNAPSHOT"
=======
"io.swagger" %% "swagger-play2" % "1.6.2-SNAPSHOT"
>>>>>>> 32d3d11b9b19c7dccf1052fe63a6f7edc397cf8a
)
```

Expand Down Expand Up @@ -103,7 +119,7 @@ paramaters (variables) are passed to the method implicitly by the framework. AL
with `ApiImplicitParam` annotations. If they are `queryParam`s or `pathParam`s, you can use `ApiParam` annotations.


# application.conf - config options
## application.conf - config options
```
api.version (String) - version of API | default: "beta"
swagger.api.basepath (String) - base url | default: "http://localhost:9000"
Expand Down
2 changes: 1 addition & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ libraryDependencies ++= Seq(
"org.scala-lang.modules" %% "scala-collection-compat" % "2.1.2",
"org.slf4j" % "slf4j-api" % "1.7.21",

"com.typesafe.play" %% "play-ebean" % "5.0.2" % "test",
"com.typesafe.play" %% "play-ebean" % "5.0.1" % "test",
"org.specs2" %% "specs2-core" % Specs2Version % "test",
"org.specs2" %% "specs2-mock" % Specs2Version % "test",
"org.specs2" %% "specs2-junit" % Specs2Version % "test",
Expand Down
6 changes: 6 additions & 0 deletions src/main/scala/play/modules/swagger/PlayApiScanner.scala
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ class PlayApiScanner @Inject()(config: PlaySwaggerConfig, routes: RouteWrapper,
.name(config.license)
.url(config.licenseUrl))
}

val vendorExtensions = config.vendorExtensions.map { extension =>
extension.name -> extension.value
}.toMap.asJava

info.setVendorExtensions(vendorExtensions)
swagger.info(info)
}

Expand Down
14 changes: 12 additions & 2 deletions src/main/scala/play/modules/swagger/PlaySwaggerConfig.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ import com.typesafe.config.Config
import javax.annotation.Nullable
import play.api.Configuration

import scala.collection.JavaConverters._

case class Extension(name: String, value: AnyRef)

case class PlaySwaggerConfig(
title: String,
version: String,
Expand All @@ -15,7 +19,8 @@ case class PlaySwaggerConfig(
host: String,
basePath: String,
schemes: Seq[String],
filterClass: Option[String]
filterClass: Option[String],
vendorExtensions: List[Extension]
) {
// Java APIs for reading the configuration
def getSchemes: Array[String] = schemes.toArray
Expand All @@ -37,7 +42,12 @@ object PlaySwaggerConfig {
termsOfServiceUrl = configuration.get[String]("swagger.api.info.termsOfServiceUrl"),
license = configuration.get[String]("swagger.api.info.license"),
licenseUrl = configuration.get[String]("swagger.api.info.licenseUrl"),
filterClass = configuration.get[Option[String]]("swagger.filter")
filterClass = configuration.get[Option[String]]("swagger.filter"),
vendorExtensions = configuration.get[Option[Config]]("swagger.api.info").toList.map(_.entrySet()).flatMap { entries =>
entries.asScala.filter(_.getKey.startsWith("x-")).map { entry =>
Extension(entry.getKey, entry.getValue.unwrapped())
}.toList.reverse
}
)
}

Expand Down
21 changes: 21 additions & 0 deletions src/test/resources/reference.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

api.version = beta

swagger.filter = null
swagger.api {
basepath = "/"
host = "localhost:9000"
title = "Test API"
schemes = []

info {
title = "Test"
description = "Test API endpoint"
termsOfServiceUrl = ""
contact = "[email protected]"
license = "Apache2"
licenseUrl = "http://licenseUrl" # needs to be a valid url to validate against schema
x-api-key: "test"
x-tags: ["test", "api"]
}
}
25 changes: 25 additions & 0 deletions src/test/scala/PlayApiInfoConfigParserSpec.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import com.typesafe.config.ConfigFactory
import org.specs2.mutable.Specification
import play.modules.swagger.PlaySwaggerConfig

class PlayApiInfoConfigParserSpec extends Specification {

private val config = ConfigFactory.load()

"API Info " should {
"proper build Info object" in {
val probe = PlaySwaggerConfig(config)
probe.title === "Test"
probe.description === "Test API endpoint"
probe.termsOfServiceUrl.isEmpty === true
probe.contact === "[email protected]"
probe.license === "Apache2"
probe.licenseUrl === "http://licenseUrl"
probe.vendorExtensions.size shouldEqual(2)
probe.vendorExtensions.head.name === "x-api-key"
probe.vendorExtensions.head.value === "test"
probe.vendorExtensions.tail.head.name === "x-tags"
probe.vendorExtensions.tail.head.value === java.util.Arrays.asList("test", "api")
}
}
}
5 changes: 4 additions & 1 deletion src/test/scala/PlayApiListingCacheSpec.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import java.io.File

import com.typesafe.config.ConfigValueFactory
import io.swagger.config.ScannerFactory
import io.swagger.models.{HttpMethod, ModelImpl}
import io.swagger.models.parameters.{BodyParameter, PathParameter, QueryParameter}
Expand Down Expand Up @@ -57,7 +58,8 @@ PUT /api/dog/api/:id testdata.DogController.add0(id:String)
license = "license",
licenseUrl = "http://licenseUrl",
filterClass = None,
schemes = Seq.empty
schemes = Seq.empty,
vendorExtensions = List(Extension("x-api-key","test"), Extension("x-tags", java.util.Arrays.asList("api", "secure","test")))
)

val env = Environment.simple()
Expand Down Expand Up @@ -90,6 +92,7 @@ PUT /api/dog/api/:id testdata.DogController.add0(id:String)
swagger.getInfo.getTermsOfService must beEqualTo(swaggerConfig.termsOfServiceUrl)
swagger.getInfo.getLicense.getName must beEqualTo(swaggerConfig.license)
swagger.getSecurityDefinitions.size() must beEqualTo(1)
swagger.getInfo.getVendorExtensions.size() must beEqualTo(2)

val pathDoc = swagger.getPaths.get("/document/{settlementId}/files/{fileId}/accept")
pathDoc.getOperations.size must beEqualTo(1)
Expand Down