Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package com.ctilogic.cvd.webtr
- import akka.pattern.{pipe, ask}
- import akka.actor.{Props, ActorRef, ActorLogging, Actor}
- import akka.util.Timeout
- import com.ctilogic.cvd.acl.api.REST.{AuthRequest, AuthResponse}
- import com.ctilogic.cvd.acl.api.REST.Marshalling._
- import com.ctilogic.cvd.common.ActorHelpers.ExtendedDispatchers
- import com.ctilogic.cvd.common.{ActorHelpers, CommonConfig}
- import com.ctilogic.cvd.common.http.CommonPaths
- import com.ctilogic.cvd.common.messaging.ErrorResponse
- import com.github.levkhomich.akka.tracing.{TracingSupport, ActorTracing}
- import com.github.levkhomich.akka.tracing.http.TracingDirectives
- import shapeless._
- import spray.http.HttpRequest
- import spray.httpx.marshalling._
- import spray.httpx.unmarshalling._
- import spray.routing.{Route, HttpService}
- import scala.concurrent.{ExecutionContext, Future}
- import com.ctilogic.cvd.acl.api.REST.Marshalling._
- import com.ctilogic.cvd.acl.api.REST._
- import com.ctilogic.cvd.common.marshalling.CommonMarshalling._
- class StubRequestProcessor extends Actor with ActorTracing {
- override def receive = {
- case r: TracingSupport ⇒ sender() ! Left(ErrorResponse.ServiceUnavailable.asChildOf(r))
- }
- }
- class HttpRequestDispatcher
- extends Actor
- with ActorTracing
- with HttpService
- with TracingDirectives
- with ActorLogging
- with CommonPaths
- with ActorHelpers
- {
- override implicit def actorRefFactory = context
- type RestResult[T] = Future[Either[ErrorResponse, T]]
- implicit protected def requestTimeout: Timeout = CommonConfig.Timeouts.Background
- implicit protected val executionContext: ExecutionContext = context.system.dispatchers.lookupHttpDispatcher
- /**
- * Request processor actor. All requests routed to this actor by call [[restProcess]].
- */
- protected val requestProcessor = context.actorOf(Props[StubRequestProcessor])
- /**
- * Process rest request by `requestProcessor`
- * @param request request.
- * @tparam A type of request
- * @tparam B type of response
- * @return future with response or error.
- */
- protected def restProcess[A, B](request: A): RestResult[B] = {
- (requestProcessor ? request).mapTo[Either[ErrorResponse, B]]
- }
- // TODO: FIXME tracing support
- /**
- * Handle request using [[restProcess]] with tracing.
- * @param um request unmarshaller
- * @param m response marshaller
- * @tparam A request type
- * @tparam B response type
- * @return spray route which handle the request
- */
- def tracedHandleRest[A <: TracingSupport, B]
- (implicit um: FromRequestUnmarshaller[A], m: ToResponseMarshaller[B])
- : Route = tracedHandleWith(restProcess[A, B])
- def tracedHandleWith[A <: TracingSupport, B, G <: HList](extracted: G)(f: A ⇒ B)
- (implicit um: Deserializer[HttpRequest :: G, A], m: ToResponseMarshaller[B], ma: Manifest[A]): Route = {
- implicit val umm = wrap(extracted)
- tracedHandleWith(f)
- }
- private def wrap[A, G <: HList](extracted: G)(implicit um: Deserializer[HttpRequest :: G, A]): FromRequestUnmarshaller[A] =
- new Deserializer[HttpRequest, A] {
- override def apply(httpRequest: HttpRequest): Deserialized[A] = {
- um(::(httpRequest, extracted))
- }
- }
- override def receive = runRoute(aclRoute)
- val aclRoute =
- pathPrefix("api") {
- pathPrefix(AuthPath) {
- (pathEnd & post) {
- tracedHandleRest[AuthRequest, AuthResponse]
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement