From 9cb5df86335b01e770eb656aa5eda3692410276e Mon Sep 17 00:00:00 2001 From: vlad Date: Sun, 17 Jul 2016 20:46:10 -0400 Subject: App interruption and formats for Time --- src/main/scala/com/drivergrp/core/app.scala | 26 ++++++++++++++++++++------ src/main/scala/com/drivergrp/core/rest.scala | 25 +++++++++++++++++++++---- 2 files changed, 41 insertions(+), 10 deletions(-) (limited to 'src/main/scala') diff --git a/src/main/scala/com/drivergrp/core/app.scala b/src/main/scala/com/drivergrp/core/app.scala index 97e09b5..53239e0 100644 --- a/src/main/scala/com/drivergrp/core/app.scala +++ b/src/main/scala/com/drivergrp/core/app.scala @@ -12,6 +12,9 @@ import com.drivergrp.core.rest.Swagger import com.typesafe.config.Config import org.slf4j.LoggerFactory +import scala.concurrent.Await +import scala.concurrent.duration._ + object app { @@ -21,22 +24,33 @@ object app { config: Config = com.drivergrp.core.config.loadDefaultConfig, interface: String = "localhost", port: Int = 8080) { + implicit private lazy val actorSystem = ActorSystem("spray-routing", config) + implicit private lazy val executionContext = actorSystem.dispatcher + implicit private lazy val materializer = ActorMaterializer()(actorSystem) + private lazy val http = Http()(actorSystem) + + def run() = { activateServices(modules) scheduleServicesDeactivation(modules) bindHttp(modules) + Console.print(s"${this.getClass.getName} App is started") + } + + def stop() = { + http.shutdownAllConnectionPools().onComplete { _ => + actorSystem.terminate() + Await.result(actorSystem.whenTerminated, 30.seconds) + Console.print(s"${this.getClass.getName} App is stopped") + } } - protected def bindHttp(modules: Seq[Module]) { - implicit val actorSystem = ActorSystem("spray-routing", config) - implicit val executionContext = actorSystem.dispatcher - implicit val materializer = ActorMaterializer()(actorSystem) + protected def bindHttp(modules: Seq[Module]) { val serviceTypes = modules.flatMap(_.routeTypes) val swaggerService = new Swagger(actorSystem, serviceTypes, config) val swaggerRoutes = swaggerService.routes ~ swaggerService.swaggerUI - - Http()(actorSystem).bindAndHandle( + http.bindAndHandle( route2HandlerFlow(logRequestResult("log")(modules.map(_.route).foldLeft(swaggerRoutes) { _ ~ _ })), interface, port)(materializer) } diff --git a/src/main/scala/com/drivergrp/core/rest.scala b/src/main/scala/com/drivergrp/core/rest.scala index 421f5d1..4e8ea3e 100644 --- a/src/main/scala/com/drivergrp/core/rest.scala +++ b/src/main/scala/com/drivergrp/core/rest.scala @@ -11,12 +11,12 @@ import akka.stream.ActorMaterializer import akka.util.Timeout import com.drivergrp.core.logging.Logger import com.drivergrp.core.stats.Stats -import com.drivergrp.core.time.TimeRange +import com.drivergrp.core.time.{Time, TimeRange} import com.drivergrp.core.time.provider.TimeProvider import com.github.swagger.akka.model._ import com.github.swagger.akka.{HasActorSystem, SwaggerHttpService} import com.typesafe.config.Config -import spray.json.{DeserializationException, JsNumber, JsString, JsValue, RootJsonFormat} +import spray.json.{DeserializationException, JsNumber, JsObject, JsString, JsValue, RootJsonFormat} import scala.concurrent.duration._ import scala.concurrent.{ExecutionContext, Future} @@ -72,8 +72,7 @@ object rest { def IdInPath[T]: PathMatcher1[Id[T]] = PathMatcher("""[+-]?\d*""".r) flatMap { string ⇒ - try Some(Id[T](string.toLong)) - catch { case _: IllegalArgumentException ⇒ None } + try Some(Id[T](string.toLong)) catch { case _: IllegalArgumentException ⇒ None } } implicit def idFormat[T] = new RootJsonFormat[Id[T]] { @@ -97,6 +96,24 @@ object rest { case _ => throw new DeserializationException("Name expects string") } } + + def TimeInPath[T]: PathMatcher1[Time] = + PathMatcher("""[+-]?\d*""".r) flatMap { string ⇒ + try Some(Time(string.toLong)) catch { case _: IllegalArgumentException ⇒ None } + } + + implicit def timeFormat[T] = new RootJsonFormat[Time] { + def write(time: Time) = JsObject("timestamp" -> JsNumber(time.millis)) + + def read(value: JsValue): Time = value match { + case JsObject(fields) => + fields.get("timestamp").flatMap { + case JsNumber(millis) => Some(Time(millis.toLong)) + case _ => None + }.getOrElse(throw new DeserializationException("Time expects number")) + case _ => throw new DeserializationException("Time expects number") + } + } } trait OptionTDirectives { -- cgit v1.2.3