add schema TC

Project: http://git-wip-us.apache.org/repos/asf/incubator-s2graph/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-s2graph/commit/ca35bb56
Tree: http://git-wip-us.apache.org/repos/asf/incubator-s2graph/tree/ca35bb56
Diff: http://git-wip-us.apache.org/repos/asf/incubator-s2graph/diff/ca35bb56

Branch: refs/heads/master
Commit: ca35bb5649343f057a847d212e1d7206d94be079
Parents: e1f2bb4
Author: daewon <[email protected]>
Authored: Tue Mar 6 18:50:08 2018 +0900
Committer: daewon <[email protected]>
Committed: Tue Mar 6 18:50:08 2018 +0900

----------------------------------------------------------------------
 .../graphql/repository/GraphRepository.scala    |   1 +
 .../graphql/types/S2ManagementType.scala        | 129 ++++++-------
 .../apache/s2graph/graphql/types/S2Type.scala   |  61 ++----
 .../types/SangriaPlayJsonScalarType.scala       | 152 +++++++--------
 .../apache/s2graph/graphql/types/package.scala  |  14 +-
 s2graphql/src/test/resources/application.conf   |  17 +-
 .../s2graph/graphql/ArgumentParseTest.scala     |  18 --
 .../org/apache/s2graph/graphql/SchemaTest.scala | 191 +++++++++++++++++++
 8 files changed, 368 insertions(+), 215 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/ca35bb56/s2graphql/src/main/scala/org/apache/s2graph/graphql/repository/GraphRepository.scala
----------------------------------------------------------------------
diff --git 
a/s2graphql/src/main/scala/org/apache/s2graph/graphql/repository/GraphRepository.scala
 
b/s2graphql/src/main/scala/org/apache/s2graph/graphql/repository/GraphRepository.scala
index 2a0a2bf..2e34c27 100644
--- 
a/s2graphql/src/main/scala/org/apache/s2graph/graphql/repository/GraphRepository.scala
+++ 
b/s2graphql/src/main/scala/org/apache/s2graph/graphql/repository/GraphRepository.scala
@@ -194,6 +194,7 @@ class GraphRepository(val graph: S2GraphLike) {
     val ret = partialColumns.map { pc =>
       val serviceName = pc.serviceName
       val columnName = pc.columnName
+
       Try {
         pc.props.foreach { prop =>
           Management.addVertexProp(serviceName, columnName, prop.name, 
prop.dataType, prop.defaultValue, prop.storeInGlobalIndex)

http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/ca35bb56/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/S2ManagementType.scala
----------------------------------------------------------------------
diff --git 
a/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/S2ManagementType.scala
 
b/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/S2ManagementType.scala
index 0ea12e1..3317755 100644
--- 
a/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/S2ManagementType.scala
+++ 
b/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/S2ManagementType.scala
@@ -42,8 +42,8 @@ object S2ManagementType {
 
   case class MutationResponse[T](result: Try[T])
 
-  def makeMutationResponseType[T](name: String, desc: String, tpe: 
ObjectType[_, T]) = {
-    ObjectType(
+  def makeMutationResponseType[T](name: String, desc: String, tpe: 
ObjectType[_, T]): ObjectType[Unit, MutationResponse[T]] = {
+    val retType = ObjectType(
       name,
       desc,
       () => fields[Unit, MutationResponse[T]](
@@ -64,6 +64,8 @@ object S2ManagementType {
         )
       )
     )
+
+    retType
   }
 }
 
@@ -75,7 +77,7 @@ class S2ManagementType(repo: GraphRepository) {
 
   lazy val serviceColumnOnServiceWithPropInputObjectFields = 
repo.allServices.map { service =>
     InputField(service.serviceName, OptionInputType(InputObjectType(
-      s"columnWithProp",
+      s"Input_Column_Props",
       description = "desc here",
       fields = List(
         InputField("columnName", makeServiceColumnEnumTypeOnService(service)),
@@ -87,7 +89,7 @@ class S2ManagementType(repo: GraphRepository) {
 
   lazy val serviceColumnOnServiceInputObjectFields = repo.allServices.map { 
service =>
     InputField(service.serviceName, OptionInputType(InputObjectType(
-      s"column",
+      s"Input_Column",
       description = "desc here",
       fields = List(
         InputField("columnName", makeServiceColumnEnumTypeOnService(service))
@@ -98,7 +100,7 @@ class S2ManagementType(repo: GraphRepository) {
   def makeServiceColumnEnumTypeOnService(service: Service): EnumType[String] = 
{
     val columns = service.serviceColumns(false).toList
     EnumType(
-      s"${service.serviceName}_columns",
+      s"Enum_${service.serviceName}_ServiceColumn",
       description = Option("desc here"),
       values = dummyEnum +: columns.map { column =>
         EnumValue(column.columnName, value = column.columnName)
@@ -106,9 +108,9 @@ class S2ManagementType(repo: GraphRepository) {
     )
   }
 
-  lazy val labelMetaInputObjectFields = repo.allLabels.map { label =>
+  lazy val labelPropsInputFields = repo.allLabels.map { label =>
     InputField(label.label, OptionInputType(InputObjectType(
-      s"labelMetaOnLabel",
+      s"Input_${label.label}_props",
       description = "desc here",
       fields = List(
         InputField("props", ListInputType(InputPropType))
@@ -138,7 +140,7 @@ class S2ManagementType(repo: GraphRepository) {
   val dummyEnum = EnumValue("_", value = "_")
 
   lazy val ServiceListType = EnumType(
-    s"ServiceList",
+    s"Enum_Service",
     description = Option("desc here"),
     values =
       dummyEnum +: repo.allServices.map { service =>
@@ -147,7 +149,7 @@ class S2ManagementType(repo: GraphRepository) {
   )
 
   lazy val ServiceColumnListType = EnumType(
-    s"ServiceColumnList",
+    s"Enum_ServiceColumn",
     description = Option("desc here"),
     values =
       dummyEnum +: repo.allServiceColumns.map { serviceColumn =>
@@ -155,8 +157,8 @@ class S2ManagementType(repo: GraphRepository) {
       }
   )
 
-  lazy val LabelListType = EnumType(
-    s"LabelList",
+  lazy val EnumLabelsType = EnumType(
+    s"Enum_Label",
     description = Option("desc here"),
     values =
       dummyEnum +: repo.allLabels.map { label =>
@@ -177,24 +179,11 @@ class S2ManagementType(repo: GraphRepository) {
   )
 
   lazy val LabelMutationResponseType = makeMutationResponseType[Label](
-    "MutateLabelLabel",
+    "MutateLabel",
     "desc here",
     LabelType
   )
 
-  lazy val serviceColumnField: Field[GraphRepository, Any] = Field(
-    "ServiceColumn",
-    ListType(ServiceColumnType),
-    description = Option("desc here"),
-    arguments = List(ServiceNameRawArg, ColumnNameArg, PropArg),
-    resolve = { c =>
-      c.argOpt[String]("name") match {
-        case Some(name) => c.ctx.allServiceColumns.filter(_.columnName == name)
-        case None => c.ctx.allServiceColumns
-      }
-    }
-  )
-
   lazy val labelField: Field[GraphRepository, Any] = Field(
     "Labels",
     ListType(LabelType),
@@ -217,53 +206,29 @@ class S2ManagementType(repo: GraphRepository) {
   ).map { case (name, _type) => Argument(name, OptionInputType(_type)) }
 
   val AddPropServiceType = InputObjectType[Vector[PartialServiceColumn]](
-    "serviceName",
+    "Input_Service_ServiceColumn_Props",
     description = "desc",
     fields = serviceColumnOnServiceWithPropInputObjectFields
   )
 
   val ServiceColumnSelectType = InputObjectType[Vector[PartialServiceColumn]](
-    "serviceColumnSelect",
+    "Input_Service_ServiceColumn",
     description = "desc",
     fields = serviceColumnOnServiceInputObjectFields
   )
 
   val LabelPropType = InputObjectType[Vector[PartialLabelMeta]](
-    "labelMetaProp",
+    "Input_Label_Props",
     description = "desc",
-    fields = labelMetaInputObjectFields
+    fields = labelPropsInputFields
   )
 
-  val SourceServiceType = InputObjectType[PartialServiceColumn](
-    "sourceService",
+  val InputServiceType = InputObjectType[PartialServiceColumn](
+    "Input_Service",
     description = "desc",
     fields = serviceColumnOnServiceInputObjectFields
   )
 
-  val TargetServiceType = InputObjectType[PartialServiceColumn](
-    "sourceService",
-    description = "desc",
-    fields = serviceColumnOnServiceInputObjectFields
-  )
-
-  lazy val labelRequiredArg = List(
-    "sourceService" -> SourceServiceType,
-    "targetService" -> TargetServiceType
-  ).map { case (name, _type) => Argument(name, _type) }
-
-  val labelOptsArgs = List(
-    "serviceName" -> ServiceListType,
-    "consistencyLevel" -> ConsistencyLevelType,
-    "isDirected" -> BooleanType,
-    "isAsync" -> BooleanType,
-    "schemaVersion" -> StringType
-  ).map { case (name, _type) => Argument(name, OptionInputType(_type)) }
-
-
-  /**
-    * Management query
-    */
-
   lazy val serviceField: Field[GraphRepository, Any] = Field(
     "Services",
     ListType(ServiceType),
@@ -277,17 +242,34 @@ class S2ManagementType(repo: GraphRepository) {
     }
   )
 
+  /**
+    * Query Fields
+    * Provide s2graph management query API
+    */
   lazy val queryFields: List[Field[GraphRepository, Any]] = List(serviceField, 
labelField)
 
   /**
     * Mutation fields
-    * Provide s2graph management API
+    * Provide s2graph management mutate API
     *
     * - createService
     * - createLabel
     * - ...
     */
 
+  lazy val labelRequiredArg = List(
+    Argument("sourceService", InputServiceType),
+    Argument("targetService", InputServiceType)
+  )
+
+  val labelOptsArgs = List(
+    Argument("serviceName", OptionInputType(ServiceListType)),
+    Argument("consistencyLevel", OptionInputType(ConsistencyLevelType)),
+    Argument("isDirected", OptionInputType(BooleanType)),
+    Argument("isAsync", OptionInputType(BooleanType)),
+    Argument("schemaVersion", OptionInputType(StringType))
+  )
+
   val NameArg = Argument("name", StringType, description = "desc here")
 
   lazy val ServiceNameArg = Argument("name", OptionInputType(ServiceListType), 
description = "desc here")
@@ -298,7 +280,7 @@ class S2ManagementType(repo: GraphRepository) {
 
   lazy val ColumnTypeArg = Argument("columnType", DataTypeType, description = 
"desc here")
 
-  lazy val LabelNameArg = Argument("name", OptionInputType(LabelListType), 
description = "desc here")
+  lazy val LabelNameArg = Argument("name", OptionInputType(EnumLabelsType), 
description = "desc here")
 
   lazy val PropArg = Argument("props", 
OptionInputType(ListInputType(InputPropType)), description = "desc here")
 
@@ -310,11 +292,29 @@ class S2ManagementType(repo: GraphRepository) {
       arguments = NameArg :: serviceOptArgs,
       resolve = c => MutationResponse(c.ctx.createService(c.args))
     ),
+
+    Field("createLabel",
+      LabelMutationResponseType,
+      arguments = NameArg :: PropArg :: IndicesArg :: labelRequiredArg ::: 
labelOptsArgs,
+      resolve = c => MutationResponse(c.ctx.createLabel(c.args))
+    ),
+    Field("deleteLabel",
+      LabelMutationResponseType,
+      arguments = LabelNameArg :: Nil,
+      resolve = c => MutationResponse(c.ctx.deleteLabel(c.args))
+    ),
+
     Field("createServiceColumn",
       ServiceColumnMutationResponseType,
       arguments = List(ServiceNameRawArg, Argument("columnName", StringType), 
ColumnTypeArg, PropArg),
       resolve = c => MutationResponse(c.ctx.createServiceColumn(c.args))
     ),
+    Field("deleteServiceColumn",
+      ListType(ServiceColumnMutationResponseType),
+      arguments = Argument("serviceName", ServiceColumnSelectType) :: Nil,
+      resolve = c => c.ctx.deleteServiceColumn(c.args).map(MutationResponse(_))
+    ),
+
     Field("addPropsToServiceColumn",
       ListType(ServiceColumnMutationResponseType),
       arguments = Argument("serviceName", AddPropServiceType) :: Nil,
@@ -324,21 +324,6 @@ class S2ManagementType(repo: GraphRepository) {
       ListType(LabelMutationResponseType),
       arguments = Argument("labelName", LabelPropType) :: Nil,
       resolve = c => c.ctx.addPropsToLabel(c.args) map (MutationResponse(_))
-    ),
-    Field("deleteServiceColumn",
-      ListType(ServiceColumnMutationResponseType),
-      arguments = Argument("serviceName", ServiceColumnSelectType) :: Nil,
-      resolve = c => c.ctx.deleteServiceColumn(c.args).map(MutationResponse(_))
-    ),
-    Field("createLabel",
-      LabelMutationResponseType,
-      arguments = NameArg :: PropArg :: IndicesArg :: labelRequiredArg ::: 
labelOptsArgs,
-      resolve = c => MutationResponse(c.ctx.createLabel(c.args))
-    ),
-    Field("deleteLabel",
-      LabelMutationResponseType,
-      arguments = LabelNameArg :: Nil,
-      resolve = c => MutationResponse(c.ctx.deleteLabel(c.args))
     )
   )
 }

http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/ca35bb56/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/S2Type.scala
----------------------------------------------------------------------
diff --git 
a/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/S2Type.scala 
b/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/S2Type.scala
index 14e83e8..451dda3 100644
--- a/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/S2Type.scala
+++ b/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/S2Type.scala
@@ -35,6 +35,7 @@ import scala.util.{Failure, Success, Try}
 import org.apache.s2graph.graphql.marshaller._
 
 object S2Type {
+
   case class PartialLabelMeta(labelName: String,
                               props: Seq[Prop] = Nil)
 
@@ -100,7 +101,7 @@ object S2Type {
   def makeInputPartialVertexParamType(service: Service,
                                       serviceColumn: ServiceColumn): 
InputObjectType[PartialVertexParam] = {
     lazy val InputPropsType = InputObjectType[Map[String, ScalarType[_]]](
-      s"${service.serviceName}_${serviceColumn.columnName}_props",
+      s"Input_${service.serviceName}_${serviceColumn.columnName}_vertex_props",
       description = "desc here",
       () => serviceColumn.metas.filter(ColumnMeta.isValid).map { lm =>
         InputField(lm.name, OptionInputType(s2TypeToScalarType(lm.dataType)))
@@ -112,7 +113,7 @@ object S2Type {
     )
 
     InputObjectType[PartialVertexParam](
-      s"${service.serviceName}_on_${serviceColumn.columnName}_mutate",
+      
s"Input_${service.serviceName}_${serviceColumn.columnName}_vertex_mutate",
       description = "desc here",
       () =>
         if (!serviceColumn.metas.exists(ColumnMeta.isValid)) fields
@@ -122,7 +123,7 @@ object S2Type {
 
   def makeInputPartialEdgeParamType(label: Label): 
InputObjectType[PartialEdgeParam] = {
     lazy val InputPropsType = InputObjectType[Map[String, ScalarType[_]]](
-      s"${label.label}_props",
+      s"Input_${label.label}_edge_props",
       description = "desc here",
       () => label.labelMetaSet.toList.map { lm =>
         InputField(lm.name, OptionInputType(s2TypeToScalarType(lm.dataType)))
@@ -137,7 +138,7 @@ object S2Type {
     )
 
     InputObjectType[PartialEdgeParam](
-      s"${label.label}_mutate",
+      s"Input_${label.label}_edge_mutate",
       description = "desc here",
       () =>
         if (label.labelMetaSet.isEmpty) labelFields
@@ -156,13 +157,14 @@ object S2Type {
       val reservedFields = List("id" -> column.columnType, "timestamp" -> 
"long")
 
       val vertexPropFields = makePropFields(reservedFields ++ columnMetasKv)
-      lazy val LabelType = ObjectType(
-        s"${service.serviceName}_${column.columnName}",
+
+      lazy val ConnectedLabelType = ObjectType(
+        s"Input_${service.serviceName}_${column.columnName}",
         () => fields[GraphRepository, Any](vertexPropFields ++ 
connectedLabelFields: _*)
       )
 
       Field(column.columnName,
-        ListType(LabelType),
+        ListType(ConnectedLabelType),
         arguments = List(
           Argument("id", 
OptionInputType(s2TypeToScalarType(column.columnType))),
           Argument("ids", 
OptionInputType(ListInputType(s2TypeToScalarType(column.columnType)))),
@@ -197,10 +199,14 @@ object S2Type {
     val labelColumns = List("from" -> label.srcColumnType, "to" -> 
label.tgtColumnType, "timestamp" -> "long")
     val labelProps = label.labelMetas.map { lm => lm.name -> lm.dataType }
 
-    lazy val EdgeType = ObjectType(label.label, () => fields[GraphRepository, 
Any](edgeFields ++ connectedLabelFields: _*))
+    lazy val EdgeType = ObjectType(
+      s"Label_${label.label}",
+      () => fields[GraphRepository, Any](edgeFields ++ connectedLabelFields: 
_*)
+    )
+
     lazy val edgeFields: List[Field[GraphRepository, Any]] = 
makePropFields(labelColumns ++ labelProps)
     lazy val edgeTypeField: Field[GraphRepository, Any] = Field(
-      label.label,
+      s"${label.label}",
       ListType(EdgeType),
       arguments = DirArg :: Nil,
       description = Some("edges"),
@@ -236,7 +242,7 @@ class S2Type(repo: GraphRepository) {
   lazy val serviceFields: List[Field[GraphRepository, Any]] = 
repo.allServices.map { service =>
     lazy val serviceFields = paddingDummyField(makeServiceField(service, 
repo.allLabels))
     lazy val ServiceType = ObjectType(
-      service.serviceName,
+      s"Service_${service.serviceName}",
       fields[GraphRepository, Any](serviceFields: _*)
     )
 
@@ -251,38 +257,11 @@ class S2Type(repo: GraphRepository) {
   /**
     * arguments
     */
-  lazy val addVertexArg = repo.allServices.map { service =>
-    val columnFields = service.serviceColumns(false).map { serviceColumn =>
-
-      val columnMetas = serviceColumn.metas.filter(ColumnMeta.isValid).map { 
lm =>
-        InputField(lm.name, OptionInputType(s2TypeToScalarType(lm.dataType)))
-      }
-
-      lazy val InputPropsType = InputObjectType[Map[String, ScalarType[_]]](
-        s"${service.serviceName}_${serviceColumn.columnName}_props",
-        description = "desc here",
-        () => if (columnMetas.isEmpty) List(DummyInputField) else 
columnMetas.toList
-      )
-
-      val tpe = InputObjectType[PartialServiceVertexParam](
-        serviceColumn.columnName,
-        fields = List(
-          InputField("id", s2TypeToScalarType(serviceColumn.columnType)),
-          InputField("timestamp", OptionInputType(LongType)),
-          InputField("props", OptionInputType(InputPropsType))
-        )
-      )
-
-      InputField(serviceColumn.columnName, OptionInputType(tpe))
+  lazy val addVertexArg = repo.allServices.flatMap { service =>
+    service.serviceColumns(false).map { serviceColumn =>
+      val inputPartialVertexParamType = 
makeInputPartialVertexParamType(service, serviceColumn)
+      Argument(serviceColumn.columnName, 
OptionInputType(inputPartialVertexParamType))
     }
-
-    val vertexParamType = InputObjectType[Vector[PartialServiceVertexParam]](
-      s"${service.serviceName}_column",
-      description = "desc here",
-      fields = if (columnFields.isEmpty) List(DummyInputField) else 
columnFields.toList
-    )
-
-    Argument(service.serviceName, OptionInputType(vertexParamType))
   }
 
   lazy val addVerticesArg = repo.allServices.flatMap { service =>

http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/ca35bb56/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/SangriaPlayJsonScalarType.scala
----------------------------------------------------------------------
diff --git 
a/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/SangriaPlayJsonScalarType.scala
 
b/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/SangriaPlayJsonScalarType.scala
index dcb3621..723392c 100644
--- 
a/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/SangriaPlayJsonScalarType.scala
+++ 
b/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/SangriaPlayJsonScalarType.scala
@@ -1,76 +1,76 @@
-/*
- * 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.
- */
-
-package org.apache.s2graph.graphql.types
-
-import sangria.ast._
-import sangria.validation.ValueCoercionViolation
-
-// https://gist.github.com/OlegIlyenko/5b96f4b54f656aac226d3c4bc33fd2a6
-
-object PlayJsonPolyType {
-
-  import play.api.libs.json._
-  import sangria.ast
-  import sangria.schema._
-
-  case object JsonCoercionViolation extends ValueCoercionViolation("Not valid 
JSON")
-
-  def scalarTypeToJsValue(v: sangria.ast.Value): JsValue = v match {
-    case v: IntValue => JsNumber(v.value)
-    case v: BigIntValue => JsNumber(BigDecimal(v.value.bigInteger))
-    case v: FloatValue => JsNumber(v.value)
-    case v: BigDecimalValue => JsNumber(v.value)
-    case v: StringValue => JsString(v.value)
-    case v: BooleanValue => JsBoolean(v.value)
-    case v: ListValue => JsNull
-    case v: VariableValue => JsNull
-    case v: NullValue => JsNull
-    case v: ObjectValue => JsNull
-    case _ => throw new RuntimeException("Error!")
-  }
-
-  implicit val PolyType = ScalarType[JsValue]("Poly",
-    description = Some("Type Poly = String | Number | Boolean"),
-    coerceOutput = (value, _) ⇒ value match {
-      case JsString(s) => s
-      case JsNumber(n) => n
-      case JsBoolean(b) => b
-      case JsNull => null
-      case _ => value
-    },
-    coerceUserInput = {
-      case v: String => Right(JsString(v))
-      case v: Boolean => Right(JsBoolean(v))
-      case v: Int => Right(JsNumber(v))
-      case v: Long => Right(JsNumber(v))
-      case v: Float => Right(JsNumber(v.toDouble))
-      case v: Double => Right(JsNumber(v))
-      case v: BigInt => Right(JsNumber(BigDecimal(v)))
-      case v: BigDecimal => Right(JsNumber(v))
-      case _ => Left(JsonCoercionViolation)
-    },
-    coerceInput = {
-      case value: ast.StringValue => Right(JsString(value.value))
-      case value: ast.IntValue => Right(JsNumber(value.value))
-      case value: ast.FloatValue => Right(JsNumber(value.value))
-      case value: ast.BigIntValue => 
Right(JsNumber(BigDecimal(value.value.bigInteger)))
-      case _ => Left(JsonCoercionViolation)
-    })
-}
+///*
+// * 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.
+// */
+//
+//package org.apache.s2graph.graphql.types
+//
+//import sangria.ast._
+//import sangria.validation.ValueCoercionViolation
+//
+//// https://gist.github.com/OlegIlyenko/5b96f4b54f656aac226d3c4bc33fd2a6
+//
+//object PlayJsonPolyType {
+//
+//  import play.api.libs.json._
+//  import sangria.ast
+//  import sangria.schema._
+//
+//  case object JsonCoercionViolation extends ValueCoercionViolation("Not 
valid JSON")
+//
+//  def scalarTypeToJsValue(v: sangria.ast.Value): JsValue = v match {
+//    case v: IntValue => JsNumber(v.value)
+//    case v: BigIntValue => JsNumber(BigDecimal(v.value.bigInteger))
+//    case v: FloatValue => JsNumber(v.value)
+//    case v: BigDecimalValue => JsNumber(v.value)
+//    case v: StringValue => JsString(v.value)
+//    case v: BooleanValue => JsBoolean(v.value)
+//    case v: ListValue => JsNull
+//    case v: VariableValue => JsNull
+//    case v: NullValue => JsNull
+//    case v: ObjectValue => JsNull
+//    case _ => throw new RuntimeException("Error!")
+//  }
+//
+//  implicit val PolyType = ScalarType[JsValue]("Poly",
+//    description = Some("Type Poly = String | Number | Boolean"),
+//    coerceOutput = (value, _) ⇒ value match {
+//      case JsString(s) => s
+//      case JsNumber(n) => n
+//      case JsBoolean(b) => b
+//      case JsNull => null
+//      case _ => value
+//    },
+//    coerceUserInput = {
+//      case v: String => Right(JsString(v))
+//      case v: Boolean => Right(JsBoolean(v))
+//      case v: Int => Right(JsNumber(v))
+//      case v: Long => Right(JsNumber(v))
+//      case v: Float => Right(JsNumber(v.toDouble))
+//      case v: Double => Right(JsNumber(v))
+//      case v: BigInt => Right(JsNumber(BigDecimal(v)))
+//      case v: BigDecimal => Right(JsNumber(v))
+//      case _ => Left(JsonCoercionViolation)
+//    },
+//    coerceInput = {
+//      case value: ast.StringValue => Right(JsString(value.value))
+//      case value: ast.IntValue => Right(JsNumber(value.value))
+//      case value: ast.FloatValue => Right(JsNumber(value.value))
+//      case value: ast.BigIntValue => 
Right(JsNumber(BigDecimal(value.value.bigInteger)))
+//      case _ => Left(JsonCoercionViolation)
+//    })
+//}

http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/ca35bb56/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/package.scala
----------------------------------------------------------------------
diff --git 
a/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/package.scala 
b/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/package.scala
index 1cbf130..8bfb706 100644
--- a/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/package.scala
+++ b/s2graphql/src/main/scala/org/apache/s2graph/graphql/types/package.scala
@@ -50,7 +50,7 @@ package object types {
   }
 
   val MutateResponseType = deriveObjectType[GraphRepository, MutateResponse](
-    ObjectTypeName("MutateResponse"),
+    ObjectTypeName("MutateGraphElement"),
     ObjectTypeDescription("desc here"),
     AddFields(
       Field("isSuccess", BooleanType, resolve = c => c.value.isSuccess)
@@ -58,7 +58,7 @@ package object types {
   )
 
   val DataTypeType = EnumType(
-    "DataType",
+    "Enum_DataType",
     description = Option("desc here"),
     values = List(
       EnumValue("string", value = "string"),
@@ -70,7 +70,7 @@ package object types {
   )
 
   val DirectionType = EnumType(
-    "Direction",
+    "Enum_Direction",
     description = Option("desc here"),
     values = List(
       EnumValue("out", value = "out"),
@@ -89,7 +89,7 @@ package object types {
   )
 
   val InputIndexType = InputObjectType[Index](
-    "Index",
+    "Input_Index",
     description = "desc here",
     fields = List(
       InputField("name", StringType),
@@ -98,7 +98,7 @@ package object types {
   )
 
   val InputPropType = InputObjectType[Prop](
-    "Prop",
+    "Input_Prop",
     description = "desc here",
     fields = List(
       InputField("name", StringType),
@@ -109,7 +109,7 @@ package object types {
   )
 
   val CompressionAlgorithmType = EnumType(
-    "CompressionAlgorithm",
+    "Enum_CompressionAlgorithm",
     description = Option("desc here"),
     values = List(
       EnumValue("gz", description = Option("desc here"), value = "gz"),
@@ -118,7 +118,7 @@ package object types {
   )
 
   val ConsistencyLevelType = EnumType(
-    "ConsistencyList",
+    "Enum_Consistency",
     description = Option("desc here"),
     values = List(
       EnumValue("weak", description = Option("desc here"), value = "weak"),

http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/ca35bb56/s2graphql/src/test/resources/application.conf
----------------------------------------------------------------------
diff --git a/s2graphql/src/test/resources/application.conf 
b/s2graphql/src/test/resources/application.conf
index 5fb2552..d070a59 100644
--- a/s2graphql/src/test/resources/application.conf
+++ b/s2graphql/src/test/resources/application.conf
@@ -15,4 +15,19 @@
 # KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations
 # under the License.
-#
\ No newline at end of file
+#
+akka {
+  loggers = ["akka.event.slf4j.Slf4jLogger"]
+  event-handlers = ["akka.event.slf4j.Slf4jEventHandler"]
+  loglevel = "INFO"
+}
+
+db.default.url="jdbc:h2:file:./var/metastore;MODE=MYSQL",
+db.default.password = sa
+db.default.user = sa
+s2graph.storage.backend = rocks
+
+rocks.storage.file.path = rocks_db
+rocks.storage.mode = production
+rocks.storage.ttl = -1
+rocks.storage.read.only = false
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/ca35bb56/s2graphql/src/test/scala/org/apache/s2graph/graphql/ArgumentParseTest.scala
----------------------------------------------------------------------
diff --git 
a/s2graphql/src/test/scala/org/apache/s2graph/graphql/ArgumentParseTest.scala 
b/s2graphql/src/test/scala/org/apache/s2graph/graphql/ArgumentParseTest.scala
deleted file mode 100644
index a1c076a..0000000
--- 
a/s2graphql/src/test/scala/org/apache/s2graph/graphql/ArgumentParseTest.scala
+++ /dev/null
@@ -1,18 +0,0 @@
-package org.apache.s2graph.graphql
-
-import org.scalatest.{FunSuite, Matchers}
-import play.api.libs.json.{JsObject, JsString, Json}
-import sangria.ast.Document
-
-import scala.concurrent.Await
-import scala.concurrent.duration._
-import scala.concurrent.ExecutionContext.Implicits.global
-import sangria.macros._
-import sangria.execution.Executor
-import sangria.execution.deferred.DeferredResolver
-
-class ArgumentParseTest extends FunSuite with Matchers {
-  test("parseAddPropsToServiceColumn") {
-    true
-  }
-}

http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/ca35bb56/s2graphql/src/test/scala/org/apache/s2graph/graphql/SchemaTest.scala
----------------------------------------------------------------------
diff --git 
a/s2graphql/src/test/scala/org/apache/s2graph/graphql/SchemaTest.scala 
b/s2graphql/src/test/scala/org/apache/s2graph/graphql/SchemaTest.scala
new file mode 100644
index 0000000..6ff3d02
--- /dev/null
+++ b/s2graphql/src/test/scala/org/apache/s2graph/graphql/SchemaTest.scala
@@ -0,0 +1,191 @@
+package org.apache.s2graph.graphql
+
+import com.typesafe.config.{Config, ConfigFactory}
+import org.apache.s2graph.core.Management.JsonModel.Prop
+import org.apache.s2graph.core.mysqls.{Label, Service}
+import org.apache.s2graph.core.{Management, S2Graph}
+import org.apache.s2graph.core.rest.RequestParser
+import org.apache.s2graph.graphql.repository.GraphRepository
+import org.scalatest.{BeforeAndAfterAll, FunSuite, Matchers}
+import play.api.libs.json.{JsObject, JsString, Json}
+import sangria.ast.Document
+
+import scala.concurrent.Await
+import scala.concurrent.duration._
+import scala.concurrent.ExecutionContext.Implicits.global
+import sangria.macros._
+import sangria.execution.Executor
+import sangria.execution.deferred.DeferredResolver
+import sangria.parser.QueryParser
+import sangria.renderer.SchemaRenderer
+
+import scala.util._
+
+class SchemaTest extends FunSuite with Matchers with BeforeAndAfterAll {
+  var graph: S2Graph = _
+  var parser: RequestParser = _
+  var management: Management = _
+  var config: Config = _
+  var s2Repository: GraphRepository = _
+
+  override def beforeAll = {
+    config = ConfigFactory.load()
+    graph = new 
S2Graph(config)(scala.concurrent.ExecutionContext.Implicits.global)
+    management = new Management(graph)
+    parser = new RequestParser(graph)
+    s2Repository = new GraphRepository(graph)
+
+    // Init test data
+    val serviceName = "kakao"
+    val labelName = "friends"
+    val columnName = "user"
+
+    Management.deleteService(serviceName)
+    val serviceTry: Try[Service] =
+      management.createService(
+        serviceName,
+        "localhost",
+        s"${serviceName}_table",
+        1,
+        None
+      )
+
+    val serviceColumnTry = serviceTry.map { _ =>
+      management.createServiceColumn(
+        serviceName,
+        columnName,
+        "string",
+        List(
+          Prop("age", "0", "int"),
+          Prop("gender", "", "string")
+        )
+      )
+    }
+
+    Management.deleteLabel(labelName)
+    val labelTry: Try[Label] =
+      management.createLabel(
+        labelName,
+        serviceName, columnName, "string",
+        serviceName, columnName, "string",
+        true, serviceName,
+        Nil,
+        Seq(Prop("score", "0", "int")),
+        "strong"
+      )
+
+    val isPrepared = List(serviceTry, serviceColumnTry, 
labelTry).forall(_.isSuccess)
+
+    require(isPrepared, "should created metadata")
+  }
+
+  override def afterAll(): Unit = {
+    graph.shutdown(true)
+  }
+
+  test("s2 schema") {
+    val s2Schema = new SchemaDef(s2Repository).S2GraphSchema
+    println(SchemaRenderer.renderSchema(s2Schema))
+
+    true
+  }
+
+  test("s2 schema should has types") {
+    val s2Schema = new SchemaDef(s2Repository).S2GraphSchema
+
+    val Success(query) = QueryParser.parse(
+      """
+        query IntrospectionTypeQuery {
+          __schema {
+            types {
+              name
+            }
+          }
+        }
+        """)
+
+    val expected: Map[String, Map[String, Map[String, Vector[Map[String, 
String]]]]] =
+      Map("data" ->
+        Map("__schema" ->
+          Map("types" -> Vector(
+            Map("name" -> "Enum_CompressionAlgorithm"),
+            Map("name" -> "Enum_Consistency"),
+            Map("name" -> "Enum_DataType"),
+            Map("name" -> "Enum_Direction"),
+
+            Map("name" -> "MutateLabel"),
+            Map("name" -> "MutateGraphElement"),
+            Map("name" -> "MutateService"),
+            Map("name" -> "MutateServiceColumn"),
+
+            Map("name" -> "Input_Service"),
+            Map("name" -> "Input_Index"),
+            Map("name" -> "Input_Prop"),
+            Map("name" -> "Input_Label_Props"),
+            Map("name" -> "Input_Column"),
+            Map("name" -> "Input_Column_Props"),
+
+            Map("name" -> "ColumnMeta"),
+            Map("name" -> "LabelMeta"),
+
+            Map("name" -> "Label"),
+            Map("name" -> "LabelIndex"),
+
+            Map("name" -> "Service"),
+            Map("name" -> "ServiceColumn"),
+
+            Map("name" -> "Input_friends_edge_mutate"),
+            Map("name" -> "Input_friends_edge_props"),
+
+            Map("name" -> "Input_friends_props"),
+
+            Map("name" -> "Input_Service_ServiceColumn"),
+            Map("name" -> "Input_Service_ServiceColumn_Props"),
+
+            Map("name" -> "Input_kakao_user"),
+            Map("name" -> "Input_kakao_user_vertex_mutate"),
+            Map("name" -> "Input_kakao_user_vertex_props"),
+
+            Map("name" -> "Enum_Service"),
+            Map("name" -> "Enum_Label"),
+            Map("name" -> "Enum_kakao_ServiceColumn"),
+
+            Map("name" -> "Service_kakao"),
+            Map("name" -> "Label_friends"),
+
+            // root object type
+            Map("name" -> "Query"),
+            Map("name" -> "QueryManagement"),
+            Map("name" -> "Mutation"),
+            Map("name" -> "MutationManagement"),
+
+            // graphql internal type
+            Map("name" -> "__Directive"),
+            Map("name" -> "__DirectiveLocation"),
+            Map("name" -> "__EnumValue"),
+            Map("name" -> "__Field"),
+            Map("name" -> "__InputValue"),
+            Map("name" -> "__Schema"),
+            Map("name" -> "__Type"),
+            Map("name" -> "__TypeKind"),
+            Map("name" -> "Boolean"),
+            Map("name" -> "Int"),
+            Map("name" -> "Long"),
+            Map("name" -> "String"))
+          )
+        )
+      )
+
+
+    val ret = Await.result(Executor.execute(s2Schema, query, s2Repository), 
Duration("10 sec"))
+    val maps = ret.asInstanceOf[Map[String, Map[String, Map[String, 
Vector[Map[String, String]]]]]]("data")("__schema")("types")
+
+    val expectedSet = 
(expected("data")("__schema")("types").flatMap(_.values.headOption).toSet)
+    val retSet = (maps.flatMap(_.values.headOption).toSet)
+
+    println(expectedSet -- retSet)
+    println(retSet -- expectedSet)
+
+    retSet should be(expectedSet)
+  }
+}

Reply via email to