in s2core/src/main/scala/org/apache/s2graph/core/rest/RequestParser.scala [365:446]
def toQuery(jsValue: JsValue, impIdOpt: Option[String]): Query = {
try {
val vertices = for {
value <- (jsValue \ "srcVertices").asOpt[Seq[JsValue]].getOrElse(Nil)
vertex <- toVertex(value)
} yield vertex
if (vertices.isEmpty) throw BadQueryException("srcVertices`s id is empty")
val steps = parse[Vector[JsValue]](jsValue, "steps")
val queryOption = toQueryOption(jsValue, impIdOpt)
val querySteps =
steps.zipWithIndex.map { case (step, stepIdx) =>
val labelWeights = step match {
case obj: JsObject =>
val converted = for {
(k, v) <- (obj \ "weights").asOpt[JsObject].getOrElse(Json.obj()).fields
l <- Label.findByName(k)
} yield {
l.id.get -> v.toString().toDouble
}
converted.toMap
case _ => Map.empty[Int, Double]
}
val queryParamJsVals = step match {
case arr: JsArray => arr.as[List[JsValue]]
case obj: JsObject => (obj \ "step").as[List[JsValue]]
case _ => List.empty[JsValue]
}
val nextStepScoreThreshold = step match {
case obj: JsObject => (obj \ "nextStepThreshold").asOpt[Double].getOrElse(QueryParam.DefaultThreshold)
case _ => QueryParam.DefaultThreshold
}
val nextStepLimit = step match {
case obj: JsObject => (obj \ "nextStepLimit").asOpt[Int].getOrElse(-1)
case _ => -1
}
val cacheTTL = step match {
case obj: JsObject => (obj \ "cacheTTL").asOpt[Int].getOrElse(-1)
case _ => -1
}
val queryParams =
for {
labelGroup <- queryParamJsVals
queryParam <- parseQueryParam(labelGroup, queryOption)
} yield {
val (_, columnName) =
if (queryParam.dir == GraphUtil.directions("out")) {
(queryParam.label.srcService.serviceName, queryParam.label.srcColumnName)
} else {
(queryParam.label.tgtService.serviceName, queryParam.label.tgtColumnName)
}
//FIXME:
if (stepIdx == 0 && vertices.nonEmpty && !vertices.exists(v => v.columnName == columnName)) {
throw BadQueryException("srcVertices contains incompatiable serviceName or columnName with first step.")
}
queryParam
}
val groupBy = extractGroupBy((step \ "groupBy").asOpt[JsValue])
Step(queryParams = queryParams,
labelWeights = labelWeights,
nextStepScoreThreshold = nextStepScoreThreshold,
nextStepLimit = nextStepLimit,
cacheTTL = cacheTTL,
groupBy = groupBy)
}
Query(vertices, querySteps, queryOption)
} catch {
case e: BadQueryException =>
throw e
case e: ModelNotFoundException =>
throw BadQueryException(e.getMessage, e)
case e: Exception =>
throw BadQueryException(s"$jsValue, $e", e)
}
}