Akka Json Unmarshalling Sprayer

I have a problem with unmarshalling objects for Json using spray akka.

When I want to use members that return Future [List [Person]], this will not work.

If I use the dao object directly, it works.

Here are my codes:

PersonDao.scala

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future

case class Person(id: Int, name: String, surname: String)

object PersonDao {

  def getAll: Future[List[Person]] = Future {
    List[Person](Person(1, "Bilal", "Alp"), Person(2, "Ahmet", "Alp"))
  }
}

EntityServiceActor.scala

import akka.actor.Actor
import com.bilalalp.akkakafka.model.PersonDao
import com.bilalalp.akkakafka.service.ServiceOperation.FIND_ALL

object ServiceOperation {

  case object FIND_ALL

}

class EntityServiceActor extends Actor {

  override def receive: Receive = {

    case FIND_ALL => PersonDao.getAll
  }
}

ServerSupervisor.scala

import akka.actor.{Actor, ActorRefFactory}
import com.bilalalp.akkakafka.webservice.TaskWebService
import spray.routing.RejectionHandler.Default


class ServerSupervisor extends Actor with PersonWebService {

  implicit val system = context.system

  override def receive: Receive = runRoute(entityServiceRoutes)

  override implicit def actorRefFactory: ActorRefFactory = context
}

WebServiceTrait.scala

import akka.util.Timeout

import spray.routing.HttpService

import scala.concurrent.duration._
import scala.language.postfixOps

import org.json4s.NoTypeHints
import org.json4s.native.Serialization._

trait WebServiceTrait extends HttpService {

  implicit def executionContext = actorRefFactory.dispatcher

  implicit val json4sFormats = formats(NoTypeHints)

  implicit val timeout = Timeout(120 seconds)
}

PersonWebService.scala

trait PersonWebService extends WebServiceTrait with Json4sSupport {

  val json3sFormats = DefaultFormats

  val entityServiceWorker = actorRefFactory.actorOf(Props[EntityServiceActor], "entityServiceActor")

  val entityServiceRoutes = {
    pathPrefix("person") {
      pathEndOrSingleSlash {
        get {
          ctx => ctx.complete((entityServiceWorker ? FIND_ALL).mapTo[Person])
        }
      }
    }
  }
}

Application.scala

import akka.actor.{ActorRef, ActorSystem, Props}
import akka.io.IO
import com.bilalalp.akkakafka.server.ServerSupervisor
import spray.can.Http


object Application extends App {

  implicit val system = ActorSystem("actorSystem")

  val mainHandler: ActorRef = system.actorOf(Props[ServerSupervisor])
  IO(Http)! Http.Bind(mainHandler, interface = Configuration.appInterface, port = Configuration.appPort)

}

When I run this code, it gives nothing and waits for a while.

After waiting, the browser displays the following message:

The server was unable to respond to your request in a timely manner.

And console output

[] [11/22/2015 21:15: 24.109] [ActorSystem-akka.actor.default--7] [akka.actor.ActorSystemImpl(actorSystem)] HttpRequest (GET, http://localhost:3001/person/,List(Host: localhost: 3001, Connection: keep-alive, Cache-C ontrol: no-cache, Pragma: no-cache, User-Agent: Mozilla/5.0 (Windows NT 6.3, WOW64) AppleWebKit/537.36 (KHTML, Gecko) Maxthon/4.4.6.1000 Chrome/30.0.1599.101 Safari/537.36, DNT: 1, Accept-Encoding: gzip, deflate, Accept-: tr-TR), Empty, HTTP/1.1) akka.pattern.AskTimeoutException: [ [Akka://actorSystem//$/entityServiceActor # -1810673919]] [120000 ]. [null] "Com.bilalalp.akkakafka.service.ServiceOperation $find_all $".          akka.pattern.PromiseActorRef $$ anonfun $1.apply $mcV $sp (AskSupport.scala: 415)         at akka.actor.Scheduler $$ anon $7.run(Scheduler.scala: 132)          scala.concurrent.Future $InternalCallbackExecutor $.unbatchedExecute(Future.scala: 599)         at scala.concurrent.BatchingExecutor $class.execute(BatchingExecutor.scala: 109)          scala.concurrent.Future $InternalCallbackExecutor $.execute(Future.scala: 597)

PersonWebService.scala :

trait PersonWebService extends WebServiceTrait with Json4sSupport {

  val json3sFormats = DefaultFormats

  val entityServiceWorker = actorRefFactory.actorOf(Props[EntityServiceActor], "entityServiceActor")

  val entityServiceRoutes = {
    pathPrefix("person") {
      pathEndOrSingleSlash {
        get (
//                    ctx => ctx.complete((entityServiceWorker ? FIND_ALL).mapTo[Person])
          ctx => ctx.complete(PersonDao getAll)
        )
      }
    }
  }
}

:

[{ "ID": 1, "": "", "": "Alp" }, { "ID": 2, "": "", "": "" }]

. , , .

? ?

.

+4
2

, (PersonWebService.scala):

pathEndOrSingleSlash {
    get {
      complete {
       (entityServiceWorker ? FindAll).mapTo[List[Person]]
    }
  }

@Timothy , "sender! getAll.onComplete

, getAll Future, , , EntityServiceActor.scala:

// import the pipe pattern (see pipeTo below):
import akka.pattern.pipe
import context.dispatcher

override def receive: Receive = {
  case FindAll => 
    PersonDao.getAll()
      .recover({ case err => List() /* could log error here */ })
      .pipeTo(sender()) // do this instead of onComplete, it safer

getAll Future , , , List .

, PersonWebService.scala .mapTo [List [Person]]

+4

:

case FIND_ALL =>
  PersonDao.getAll.pipeTo(sender())
+3

Source: https://habr.com/ru/post/1616967/


All Articles