blob: 8efd2ab9615e8f0049c055e369900eed6c694b7d [file] [log] [blame]
package org.apache.s2graph.http
import akka.http.scaladsl.model._
import org.apache.s2graph.core.rest.RequestParser
import org.apache.s2graph.core.{Management, S2Graph}
import akka.http.scaladsl.server.Route
import akka.http.scaladsl.server.Directives._
import org.slf4j.LoggerFactory
import play.api.libs.json._
import scala.util._
object S2GraphAdminRoute {
trait AdminMessageFormatter[T] {
def toJson(msg: T): JsValue
}
import scala.language.reflectiveCalls
object AdminMessageFormatter {
type ToPlayJson = {
def toJson: JsValue
}
implicit def toPlayJson[A <: ToPlayJson] = new AdminMessageFormatter[A] {
def toJson(js: A) = js.toJson
}
implicit def fromPlayJson[T <: JsValue] = new AdminMessageFormatter[T] {
def toJson(js: T) = js
}
}
def toHttpEntity[A: AdminMessageFormatter](opt: Option[A], status: StatusCode = StatusCodes.OK, message: String = ""): HttpResponse = {
val ev = implicitly[AdminMessageFormatter[A]]
val res = opt.map(ev.toJson).getOrElse(Json.obj("message" -> message))
HttpResponse(
status = status,
entity = HttpEntity(ContentTypes.`application/json`, res.toString)
)
}
def toHttpEntity[A: AdminMessageFormatter](opt: Try[A]): HttpResponse = {
val ev = implicitly[AdminMessageFormatter[A]]
val (status, res) = opt match {
case Success(m) => StatusCodes.Created -> Json.obj("status" -> "ok", "message" -> ev.toJson(m))
case Failure(e) => StatusCodes.OK -> Json.obj("status" -> "failure", "message" -> e.toString)
}
toHttpEntity(Option(res), status = status)
}
}
trait S2GraphAdminRoute extends PlayJsonSupport {
import S2GraphAdminRoute._
val s2graph: S2Graph
val logger = LoggerFactory.getLogger(this.getClass)
lazy val management: Management = s2graph.management
lazy val requestParser: RequestParser = new RequestParser(s2graph)
// routes impl
lazy val getLabel = path("getLabel" / Segment) { labelName =>
val labelOpt = Management.findLabel(labelName)
complete(toHttpEntity(labelOpt, message = s"Label not found: ${labelName}"))
}
lazy val getService = path("getService" / Segment) { serviceName =>
val serviceOpt = Management.findService(serviceName)
complete(toHttpEntity(serviceOpt, message = s"Service not found: ${serviceName}"))
}
lazy val createService = path("createService") {
entity(as[JsValue]) { params =>
val parseTry = Try(requestParser.toServiceElements(params))
val serviceTry = for {
(serviceName, cluster, tableName, preSplitSize, ttl, compressionAlgorithm) <- parseTry
service <- management.createService(serviceName, cluster, tableName, preSplitSize, ttl, compressionAlgorithm)
} yield service
complete(toHttpEntity(serviceTry))
}
}
lazy val createLabel = path("createLabel") {
entity(as[JsValue]) { params =>
val labelTry = for {
label <- requestParser.toLabelElements(params)
} yield label
complete(toHttpEntity(labelTry))
}
}
// expose routes
lazy val adminRoute: Route =
get {
concat(
getService,
getLabel
)
} ~ post {
concat(
createService,
createLabel
)
}
}