Skip to content

Instantly share code, notes, and snippets.

@sirmes
Last active December 28, 2015 05:59
Show Gist options
  • Select an option

  • Save sirmes/7453724 to your computer and use it in GitHub Desktop.

Select an option

Save sirmes/7453724 to your computer and use it in GitHub Desktop.
ServiceCore - Proposed trait Query changes
package com.s5a.service.messages
import play.api.libs.json._
import org.slf4j.{LoggerFactory, Logger}
import com.eaio.uuid.UUID
import org.joda.time.Instant
import play.api.libs.json.JsSuccess
//{"query" : "inventory", "product_code":"04827348293"}
trait Query{
val id: UUID = new UUID()
val createdOn: Instant = Instant.now()
def endpointName: String
}
sealed abstract class ProductQuery(val endpointName: String = "product") extends Query
case class ProductByProductCode(productCode: String) extends ProductQuery()
case class ProductByUpc(upc: String) extends ProductQuery()
case class InventoryByProductCode(productCode: String,
override val id: UUID = new UUID(),
override val endpointName: String = "inventory") extends Query
case class InventoryByUpc(upc: String,
override val id: UUID = new UUID(),
override val endpointName: String = "inventory") extends Query
case class PriceByProductCode(productCode: String,
override val id: UUID = new UUID(),
override val endpointName: String = "price") extends Query
case class PriceByUpc(upc: String,
override val id: UUID = new UUID(),
override val endpointName: String = "price") extends Query
// Extracter [example]
object Query {
private val log: Logger = LoggerFactory.getLogger(classOf[Query])
import UUIDJSON.readUUID
implicit val readQuery: Reads[Query] = new Reads[Query] {
def reads(json: JsValue): JsResult[Query] = {
log.debug("Query.reads: " + json)
val queryType: JsResult[String] = (json \ "query").validate[String]
val jsResult: JsResult[Query] = queryType match {
case JsSuccess(queryName, _) => {
queryName match {
case "product_request" => {makeQueryJsResult(json, "product", ProductByProductCode.apply, ProductByUpc.apply)}
case "inventory_request" => {makeQueryJsResult(json, "inventory", InventoryByProductCode.apply, InventoryByUpc.apply)}
case "price_request" => {makeQueryJsResult(json, "price", PriceByProductCode.apply, PriceByUpc.apply)}
}
}
case error:JsError => {
log.error("Could not parse json into valid Query object: " + json.toString)
error
}
}
jsResult
}
}
def makeQueryJsResult(json: JsValue,
endpointName: String,
productCodeConstructor: (String, UUID, String) => Query,
upcCodeConstructor: (String, UUID, String) => Query): JsResult[Query] = {
val productCodeAndId: JsResult[(String, UUID)] = for {
productCode <- (json \ "product_code" ).validate[String]
id <- (json \ "correlation_id").validate[UUID]
} yield (productCode, id)
productCodeAndId match{
case JsSuccess(tup, _) => {JsSuccess(productCodeConstructor(tup._1, tup._2, endpointName))}
case JsError(_) => {
val upcCodeAndId: JsResult[(String, UUID)] = for {
upcCode <- (json \ "upc_code" ).validate[String]
id <- (json \ "correlation_id").validate[UUID]
} yield (upcCode, id)
upcCodeAndId match{
case JsSuccess(tup, _) => {JsSuccess(upcCodeConstructor(tup._1, tup._2, endpointName ))}
case error: JsError => {
log.error("Could not parse json into valid Query object: " + json.toString)
error
}
}
}
}
}
implicit val writeQuery: Writes[Query] = new Writes[Query] {
import UUIDJSON.writeUUID
def writes(o: Query): JsValue = {
log.debug("Query.writes: " + o)
o match {
case ProductByProductCode(s, id, _) => {
Json.obj("query" -> "product_request", "product_code" -> s, "correlation_id" -> id)
}
case ProductByUpc(s, id, _) => {
Json.obj("query" -> "product_request", "upc_code" -> s, "correlation_id" -> id)
}
case InventoryByProductCode(s, id, _) => {
Json.obj("query" -> "inventory_request", "product_code" -> s, "correlation_id" -> id)
}
case InventoryByUpc(s, id, _) => {
Json.obj("query" -> "inventory_request", "upc_code" -> s, "correlation_id" -> id)
}
case PriceByProductCode(s, id, _) => {
Json.obj("query" -> "price_request", "product_code" -> s, "correlation_id" -> id)
}
case PriceByUpc(s, id, _) => {
Json.obj("query" -> "price_request", "upc_code" -> s, "correlation_id" -> id)
}
}
}
}
def unapply(in: JsValue): Option[Query] = {
log.debug("unapply: " + in)
readQuery.reads(in).asOpt
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment