add PlayJsonSupport
diff --git a/build.sbt b/build.sbt
index c4d2c35..1052ac6 100755
--- a/build.sbt
+++ b/build.sbt
@@ -47,7 +47,7 @@
.enablePlugins(sbtdocker.DockerPlugin, JavaAppPackaging)
lazy val s2http = project
- .dependsOn(s2core)
+ .dependsOn(s2core, s2graphql)
.settings(commonSettings: _*)
.settings(dockerSettings: _*)
.enablePlugins(sbtdocker.DockerPlugin, JavaAppPackaging)
diff --git a/s2http/src/main/scala/org/apache/s2graph/http/PlayJsonSupport.scala b/s2http/src/main/scala/org/apache/s2graph/http/PlayJsonSupport.scala
new file mode 100644
index 0000000..8b4e91c
--- /dev/null
+++ b/s2http/src/main/scala/org/apache/s2graph/http/PlayJsonSupport.scala
@@ -0,0 +1,34 @@
+package org.apache.s2graph.http
+
+import java.nio.charset.Charset
+
+import akka.http.scaladsl.marshalling.{Marshaller, ToEntityMarshaller}
+import akka.http.scaladsl.model._
+import akka.http.scaladsl.unmarshalling.{FromEntityUnmarshaller, Unmarshaller}
+import akka.util.ByteString
+import play.api.libs.json.{JsValue, Json}
+
+trait PlayJsonSupport {
+
+ val mediaTypes: Seq[MediaType.WithFixedCharset] =
+ Seq(MediaType.applicationWithFixedCharset("json", HttpCharsets.`UTF-8`, "js"))
+
+ val unmarshallerContentTypes: Seq[ContentTypeRange] = mediaTypes.map(ContentTypeRange.apply)
+
+ implicit val playJsonMarshaller: ToEntityMarshaller[JsValue] = {
+ Marshaller.oneOf(mediaTypes: _*) { mediaType =>
+ Marshaller.withFixedContentType(ContentType(mediaType)) {
+ json => HttpEntity(mediaType, json.toString)
+ }
+ }
+ }
+
+ implicit val playJsonUnmarshaller: FromEntityUnmarshaller[JsValue] = {
+ Unmarshaller.byteStringUnmarshaller
+ .forContentTypes(unmarshallerContentTypes: _*)
+ .map {
+ case ByteString.empty => throw Unmarshaller.NoContentException
+ case data => Json.parse(data.decodeString(Charset.forName("UTF-8")))
+ }
+ }
+}
diff --git a/s2http/src/main/scala/org/apache/s2graph/http/S2GraphAdminRoute.scala b/s2http/src/main/scala/org/apache/s2graph/http/S2GraphAdminRoute.scala
index c2b832e..8efd2ab 100644
--- a/s2http/src/main/scala/org/apache/s2graph/http/S2GraphAdminRoute.scala
+++ b/s2http/src/main/scala/org/apache/s2graph/http/S2GraphAdminRoute.scala
@@ -10,21 +10,20 @@
import org.slf4j.LoggerFactory
import play.api.libs.json._
-import scala.util.Try
+import scala.util._
object S2GraphAdminRoute {
- import scala.util._
-
trait AdminMessageFormatter[T] {
def toJson(msg: T): JsValue
}
import scala.language.reflectiveCalls
- type ToPlayJson = {def toJson: JsValue}
-
object AdminMessageFormatter {
+ type ToPlayJson = {
+ def toJson: JsValue
+ }
implicit def toPlayJson[A <: ToPlayJson] = new AdminMessageFormatter[A] {
def toJson(js: A) = js.toJson
@@ -56,7 +55,7 @@
}
}
-trait S2GraphAdminRoute {
+trait S2GraphAdminRoute extends PlayJsonSupport {
import S2GraphAdminRoute._
@@ -80,8 +79,7 @@
}
lazy val createService = path("createService") {
- entity(as[String]) { body =>
- val params = Json.parse(body)
+ entity(as[JsValue]) { params =>
val parseTry = Try(requestParser.toServiceElements(params))
val serviceTry = for {
@@ -94,8 +92,7 @@
}
lazy val createLabel = path("createLabel") {
- entity(as[String]) { body =>
- val params = Json.parse(body)
+ entity(as[JsValue]) { params =>
val labelTry = for {
label <- requestParser.toLabelElements(params)
diff --git a/s2http/src/main/scala/org/apache/s2graph/http/S2GraphTraversalRoute.scala b/s2http/src/main/scala/org/apache/s2graph/http/S2GraphTraversalRoute.scala
index 1814436..01b7a76 100644
--- a/s2http/src/main/scala/org/apache/s2graph/http/S2GraphTraversalRoute.scala
+++ b/s2http/src/main/scala/org/apache/s2graph/http/S2GraphTraversalRoute.scala
@@ -6,10 +6,10 @@
import akka.http.scaladsl.server.Route
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.model.headers.RawHeader
-import akka.http.scaladsl.model.{HttpHeader, StatusCodes}
+import akka.http.scaladsl.model._
import org.apache.s2graph.core.GraphExceptions.{BadQueryException, JsonParseException}
import org.apache.s2graph.core.rest.RestHandler
-
+import play.api.libs.json._
object S2GraphTraversalRoute {
@@ -20,7 +20,7 @@
}
}
-trait S2GraphTraversalRoute {
+trait S2GraphTraversalRoute extends PlayJsonSupport {
import S2GraphTraversalRoute._
@@ -40,15 +40,13 @@
val result = restHandler.doPost(request.uri.toRelative.toString(), body, request.headers)
val responseHeaders = result.headers.toList.map { case (k, v) => RawHeader(k, v) }
- val f = result.body.map(StatusCodes.OK -> _.toString).recover {
- case BadQueryException(msg, _) => StatusCodes.BadRequest -> msg
- case JsonParseException(msg) => StatusCodes.BadRequest -> msg
- case e: Exception => StatusCodes.InternalServerError -> e.toString
+ val f = result.body.map(StatusCodes.OK -> _).recover {
+ case BadQueryException(msg, _) => StatusCodes.BadRequest -> Json.obj("error" -> msg)
+ case JsonParseException(msg) => StatusCodes.BadRequest -> Json.obj("error" -> msg)
+ case e: Exception => StatusCodes.InternalServerError -> Json.obj("error" -> e.toString)
}
- respondWithHeaders(responseHeaders) {
- complete(f)
- }
+ respondWithHeaders(responseHeaders)(complete(f))
}
}
}
@@ -60,6 +58,5 @@
delegated // getEdges, experiments, etc.
)
}
-
}
diff --git a/s2http/src/test/scala/org/apache/s2graph/http/AdminRouteSpec.scala b/s2http/src/test/scala/org/apache/s2graph/http/AdminRouteSpec.scala
index 7e5d794..9239598 100644
--- a/s2http/src/test/scala/org/apache/s2graph/http/AdminRouteSpec.scala
+++ b/s2http/src/test/scala/org/apache/s2graph/http/AdminRouteSpec.scala
@@ -8,19 +8,19 @@
import org.scalatest.concurrent.ScalaFutures
import org.scalatest.{BeforeAndAfterAll, Matchers, WordSpec}
import org.slf4j.LoggerFactory
-import play.api.libs.json.{JsString, Json}
+import play.api.libs.json.{JsString, JsValue, Json}
-class AdminRoutesSpec extends WordSpec with Matchers with ScalaFutures with ScalatestRouteTest with S2GraphAdminRoute with BeforeAndAfterAll {
+class AdminRoutesSpec extends WordSpec with Matchers with ScalaFutures with ScalatestRouteTest with S2GraphAdminRoute with BeforeAndAfterAll with PlayJsonSupport {
+
val config = ConfigFactory.load()
val s2graph = new S2Graph(config)
+
override val logger = LoggerFactory.getLogger(this.getClass)
override def afterAll(): Unit = {
s2graph.shutdown()
}
- import akka.http.scaladsl.server.Directives._
-
lazy val routes = adminRoute
"AdminRoute" should {
@@ -30,14 +30,14 @@
"compressionAlgorithm" -> "gz"
)
- val serviceEntity = Marshal(serviceParam.toString).to[MessageEntity].futureValue
+ val serviceEntity = Marshal(serviceParam).to[MessageEntity].futureValue
val request = Post("/createService").withEntity(serviceEntity)
request ~> routes ~> check {
status should ===(StatusCodes.Created)
contentType should ===(ContentTypes.`application/json`)
- val response = Json.parse(entityAs[String])
+ val response = entityAs[JsValue]
(response \\ "name").head should ===(JsString("kakaoFavorites"))
(response \\ "status").head should ===(JsString("ok"))
@@ -51,7 +51,7 @@
status should ===(StatusCodes.OK)
contentType should ===(ContentTypes.`application/json`)
- val response = Json.parse(entityAs[String])
+ val response = entityAs[JsValue]
(response \\ "name").head should ===(JsString("kakaoFavorites"))
}