aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/xyz/driver/core/rest/Swagger.scala
diff options
context:
space:
mode:
authorJakob Odersky <jakob@driver.xyz>2018-01-22 14:28:13 -0800
committerJakob Odersky <jakob@driver.xyz>2018-01-22 15:01:01 -0800
commitb9a1319214e8efdfe2af737236e7ce6d45f08fc2 (patch)
tree206e055f14291e09a65f794b675d82a67eb5fee5 /src/main/scala/xyz/driver/core/rest/Swagger.scala
parent199446c2f878992be2a21a00a9263b6330738151 (diff)
downloaddriver-core-b9a1319214e8efdfe2af737236e7ce6d45f08fc2.tar.gz
driver-core-b9a1319214e8efdfe2af737236e7ce6d45f08fc2.tar.bz2
driver-core-b9a1319214e8efdfe2af737236e7ce6d45f08fc2.zip
Include swagger UI in core
These changes centralize the location of the swagger UI web files. The git attributes instruct GitHub to treat the web files as vendored code, as to not be included in the project code statistics. See https://github.com/github/linguist for a more detailed explanation.
Diffstat (limited to 'src/main/scala/xyz/driver/core/rest/Swagger.scala')
-rw-r--r--src/main/scala/xyz/driver/core/rest/Swagger.scala74
1 files changed, 58 insertions, 16 deletions
diff --git a/src/main/scala/xyz/driver/core/rest/Swagger.scala b/src/main/scala/xyz/driver/core/rest/Swagger.scala
index de785a7..ab5ad76 100644
--- a/src/main/scala/xyz/driver/core/rest/Swagger.scala
+++ b/src/main/scala/xyz/driver/core/rest/Swagger.scala
@@ -1,25 +1,69 @@
package xyz.driver.core.rest
-import akka.actor.ActorSystem
import akka.http.scaladsl.server.Route
-import akka.stream._
+import com.github.swagger.akka.SwaggerHttpService
import com.github.swagger.akka.model._
-import com.github.swagger.akka.{HasActorSystem, SwaggerHttpService}
import com.typesafe.config.Config
+import com.typesafe.scalalogging.Logger
import io.swagger.models.Scheme
+import io.swagger.util.Json
-import scala.reflect.runtime.universe._
+import scala.reflect.runtime.universe
+import scala.reflect.runtime.universe.Type
+import scala.util.control.NonFatal
class Swagger(
override val host: String,
- override val scheme: Scheme,
+ override val schemes: List[Scheme],
version: String,
- override val actorSystem: ActorSystem,
- override val apiTypes: Seq[Type],
- val config: Config)
- extends SwaggerHttpService with HasActorSystem {
+ val apiTypes: Seq[Type],
+ val config: Config,
+ val logger: Logger)
+ extends SwaggerHttpService {
- val materializer: ActorMaterializer = ActorMaterializer()(actorSystem)
+ lazy val mirror = universe.runtimeMirror(getClass.getClassLoader)
+
+ override val apiClasses = apiTypes.map { tpe =>
+ mirror.runtimeClass(tpe.typeSymbol.asClass)
+ }.toSet
+
+ // Note that the reason for overriding this is a subtle chain of causality:
+ //
+ // 1. Some of our endpoints require a single trailing slash and will not
+ // function if it is omitted
+ // 2. Swagger omits trailing slashes in its generated api doc
+ // 3. To work around that, a space is added after the trailing slash in the
+ // swagger Path annotations
+ // 4. This space is removed manually in the code below
+ //
+ // TODO: Ideally we'd like to drop this custom override and fix the issue in
+ // 1, by dropping the slash requirement and accepting api endpoints with and
+ // without trailing slashes. This will require inspecting and potentially
+ // fixing all service endpoints.
+ override def generateSwaggerJson: String = {
+ import io.swagger.models.{Swagger => JSwagger}
+
+ import scala.collection.JavaConverters._
+ try {
+ val swagger: JSwagger = reader.read(apiClasses.asJava)
+
+ // Removing trailing spaces
+ swagger.setPaths(
+ swagger.getPaths.asScala
+ .map {
+ case (key, path) =>
+ key.trim -> path
+ }
+ .toMap
+ .asJava)
+
+ Json.pretty().writeValueAsString(swagger)
+ } catch {
+ case NonFatal(t) =>
+ logger.error("Issue with creating swagger.json", t)
+ throw t
+ }
+ }
override val basePath: String = config.getString("swagger.basePath")
override val apiDocsPath: String = config.getString("swagger.docsPath")
@@ -43,11 +87,9 @@ class Swagger(
vendorExtensions = Map.empty[String, AnyRef]
)
- def swaggerUI: Route = get {
- pathPrefix("") {
- pathEndOrSingleSlash {
- getFromResource("swagger-ui/index.html")
- }
+ def swaggerUI: Route =
+ pathEndOrSingleSlash {
+ getFromResource("swagger-ui/index.html")
} ~ getFromResourceDirectory("swagger-ui")
- }
+
}