Skip to content

Instantly share code, notes, and snippets.

@geoHeil
Last active May 21, 2016 09:32
Show Gist options
  • Save geoHeil/943a18d43279762ad4cdfe9aa2e40770 to your computer and use it in GitHub Desktop.
Save geoHeil/943a18d43279762ad4cdfe9aa2e40770 to your computer and use it in GitHub Desktop.
Very strange scala error with future. Description http://stackoverflow.com/questions/37352685/scala-future-null-pointer-match-error ; if run via sbt console and executed manually it works fine if run via sbt run I get a null pointer exception
package jobs.outlier
import java.sql.Timestamp
import java.text.SimpleDateFormat
import play.api.libs.json._
import play.api.libs.ws.WSResponse
import play.api.libs.ws.ning.NingWSClient
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.{ Await, Future }
object TestingOlStrange extends App {
trait HasToMap {
def toMap: Map[String, Any]
}
implicit object timestampFormat extends Format[Timestamp] {
val format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS")
def reads(json: JsValue) = {
val str = json.as[String]
JsSuccess(new Timestamp(format.parse(str).getTime))
}
def writes(ts: Timestamp) = JsString(format.format(ts))
}
case class OutlierPortalTimeSeriesData(period: Timestamp, sumTotalAmount: Double, isOutlier: Int) extends HasToMap {
def toMap: Map[String, Any] = Map(
"period" -> period,
"sumTotalAmount" -> sumTotalAmount,
"isOutlier" -> isOutlier
)
}
object OutlierPortalTimeSeriesData {
implicit val outlierResultFormat = Json.format[OutlierPortalTimeSeriesData]
}
case class OutlierPortal(portal: String, timeData: Seq[OutlierPortalTimeSeriesData]) extends HasToMap {
def toMap: Map[String, Any] = Map(
"portal" -> portal,
"timeData" -> timeData.map {
_.toMap
}
)
}
object OutlierPortal {
implicit val outlierResultFormat = Json.format[OutlierPortal]
}
implicit val outlierPortalTimeSeriesDataReads = Json.reads[OutlierPortalTimeSeriesData]
implicit val outlierPortalReads = Json.reads[OutlierPortal]
override def main(args: Array[String]) = {
val requestString =
"""{
"json": [{
"portal": "testPortal",
"period": "2000-01-01 00:00:00.0",
"sumTotalAmount": 5000
}, {
"portal": "testPortal",
"period": "2000-02-01 00:00:00.0",
"sumTotalAmount": 6000
}, {
"portal": "testPortal",
"period": "2000-03-01 00:00:00.0",
"sumTotalAmount": 40000
}, {
"portal": "testPortal",
"period": "2000-04-01 00:00:00.0",
"sumTotalAmount": 7000
}, {
"portal": "testPortal",
"period": "2000-05-01 00:00:00.0",
"sumTotalAmount": 5500
}, {
"portal": "testPortal",
"period": "2000-06-01 00:00:00.0",
"sumTotalAmount": 50000
}, {
"portal": "testPortal",
"period": "2000-07-01 00:00:00.0",
"sumTotalAmount": 6000
}, {
"portal": "testPortal",
"period": "2000-08-01 00:00:00.0",
"sumTotalAmount": 6500
}, {
"portal": "testPortal",
"period": "2000-09-01 00:00:00.0",
"sumTotalAmount": 5000
}, {
"portal": "testPortal",
"period": "2000-10-01 00:00:00.0",
"sumTotalAmount": 1100
}, {
"portal": "testPortal",
"period": "2000-11-01 00:00:00.0",
"sumTotalAmount": 7500
}, {
"portal": "testPortal",
"period": "2000-12-01 00:00:00.0",
"sumTotalAmount": 8000
}],
"windowWidth": 11,
"minDiff": 500
}"""
val payload = Json.parse(requestString)
val baseUrl = "http://localhost:8044/ocpu/library/"
val url = "possibly/R/portalOutliers/json"
val wsClient = NingWSClient()
println("################# result ###########################")
val result = wsClient.url(baseUrl + url).withHeaders("Content-Type" -> "application/json").post(payload).flatMap(parseOutlierResponse)
Await.result(result, 5.minutes)
println("################# end result ###########################")
}
def parseOutlierResponse(response: WSResponse): Future[Seq[Map[String, Any]]] = {
if (response.status < 400) {
println(response)
println("alll ######################")
println(response.json)
response.json.validate[Seq[OutlierPortal]].fold(
error => {
println(s"Unable to parse response: $error")
Future.failed(new RuntimeException("parse-json-failed"))
},
outlierResponse => Future.successful(outlierResponse.map {
_.toMap
})
)
} else {
println("Unable to parse response, cannot contact WS\n" + debugResponse(response))
Future.failed(new RuntimeException("ws-error"))
}
}
def debugResponse(r: WSResponse) = {
s"(${r.status}) ${r.body}})"
}
}
###################################################
docker yml
###################################################
version: '2'
services:
opencpu:
image: possibly/opencpu:1.5.4
ports:
- 8044:80
@geoHeil
Copy link
Author

geoHeil commented May 21, 2016

docker yml is added below so you can try the whole thing. play-ws in version 2.4.6 is used

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment