Skip to content

Instantly share code, notes, and snippets.

@josephpconley
Last active August 29, 2015 13:56
Show Gist options
  • Save josephpconley/9345957 to your computer and use it in GitHub Desktop.
Save josephpconley/9345957 to your computer and use it in GitHub Desktop.
object MetaDataFilter extends EssentialFilter{
def apply(next: EssentialAction) = new EssentialAction {
def apply(rh: RequestHeader): Iteratee[Array[Byte], Result] = {
val timeStart = System.currentTimeMillis
def bodyToStr: Enumeratee[Any, String] = Enumeratee.map(s => s.toString)
def addMetadata(result: PlainResult): Result = {
val timeElapsed = System.currentTimeMillis - timeStart
result match {
case SimpleResult(header, content) => {
val metaDataId = rh.headers.get("MetaData-Id").getOrElse("-1")
val urls = MetaData.findUrlsById(metaDataId)
//convert body to a string
val contentStr = content.through(bodyToStr)
//consume body, if it's a JsArray, ignore, otherwise add the metadata
val body: String = Await.result(Iteratee.flatten(contentStr(Iteratee.consume[String]())).run, Duration.Inf)
//add metadata if this is a JsObject
val newBody = Try(Json.parse(body)).map {
case js:JsObject => (js ++ Json.obj("TIME" -> timeElapsed, "METADATA" -> urls)).toString()
case _ => body
}.recover{
case _ => body
}.get
SimpleResult(result.header, Enumerator(newBody))
}
case _ => Logger.info("NO MATCH"); result
}
}
val iteratee: Iteratee[Array[Byte], Result] = next(rh).map {
case plain: PlainResult if (plain.header.headers.getOrElse("Content-Type", "").contains("json") && !rh.uri.contains("api-docs")) => addMetadata(plain)
case async: AsyncResult => async.transform(addMetadata)
case r: Result => r
}
iteratee
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment