`
sillycat
  • 浏览: 2486264 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

Play framework with Akka and WS

 
阅读更多
Play framework with Akka and WS

1 Set Up Akka in Playframework
In my controller which I believe it is single, I set up the AKKA system.
package controllers

import actors._
import actors.jobs.{JobServiceActor, JobParseActor}
import actors.resumes.{ResumeServiceActor, ResumeParseActor, ResumeAttachActor}
import akka.actor.Props
import com.sillycat.dao.{IpplyJobDAO, DAO}
import com.sillycat.util.IncludeLogger
import com.wordnik.swagger.annotations._
import models.ScanTriggerRequest
import play.api.libs.concurrent.Akka
import play.api.libs.json.{JsError, Json}
import play.api.mvc.{BodyParsers, Action, Controller}
import play.api.Play.current
import akka.contrib.throttle.TimerBasedThrottler
import akka.contrib.throttle.Throttler._
import scala.concurrent.duration._
import com.wordnik.swagger.annotations._

object ScanTriggerController extends Controller with IncludeLogger with IncludeWSConfig{

  implicit val scanTriggerWrites = Json.writes[ScanTriggerRequest]
  implicit val scanTriggerReads = Json.reads[ScanTriggerRequest]

  Akka.system.actorOf(JobParseActor.props, name = "job-parse-actor")

  Akka.system.actorOf(JobServiceActor.props, name = "job-service-actor")

  Akka.system.actorOf(ResumeAttachActor.props, name = "resume-attach-actor")

  Akka.system.actorOf(ResumeParseActor.props, name = "resume-parse-actor")

  Akka.system.actorOf(ResumeServiceActor.props, name = "resume-service-actor")

  Akka.system.actorOf(TriggerActor.props, name = "trigger-actor")

  val contextIOActor = Akka.system.actorOf(ContextIOActor.props, name = "contextio-actor")

  val contextIOThrottler = Akka.system.actorOf(Props(classOf[TimerBasedThrottler], contextio_throttle msgsPer 60.second), name = "conetxt-io-throttler")

  contextIOThrottler ! SetTarget(Some(contextIOActor))

  def trigger = Action(BodyParsers.parse.json) { request =>
    val b = request.body.validate[ScanTriggerRequest]
    logger.debug("Processing request with param = " + request.body)
    b.fold(
      errors => {
        BadRequest(Json.obj("status" -> "OK", "message" -> JsError.toJson(errors)))
      },
      trigger => {
        //TODO more validation on the params
        logger.debug("Param validation success, param = " + trigger)

        val triggerActor = Akka.system.actorSelection("/user/trigger-actor")
        logger.debug("Prepare the trigger action = " + triggerActor + ", and fire message!")
        triggerActor ! trigger
        Ok(Json.obj("status" -> "OK"))
      }
    )
  }

}

In any other actors or any other controllers, we can do as follow:
val jobServiceActor = context.actorSelection("/user/job-service-actor")
jobServiceActor ! JobContentPersistMessage(msg.jobId, jobCity, msg.emailContent)

In my case I have one controller to trigger my actions, maybe in the future I need to set up the AKKA system in global class or some where.

2 WS to call other Micro Service
Here is how I call other micro service
import akka.actor.{Actor, Props}
import com.sillycat.dao.{DAO, IpplyJobDAO, ResumeDAO}
import com.sillycat.util.IncludeLogger
import models.messages.jobs.{JobPersistMessage, JobScanMessage, JobContentParseMessage, JobContentScanMessage}
import models.messages.resumes._
import models.{ResumeScanResponse, ResumeScanAttachmentResponse, JobContentResponse, JobScanResponse}
import play.api.libs.json.Json
import play.api.libs.ws.{WS, WSResponse}
import utils.IncludeRegex
import play.api.Play.current
import scala.concurrent.ExecutionContext.Implicits.global

import scala.concurrent.Future
…snip...
    case msg:JobContentScanMessage => {
      logger.debug("receiving the message JobContentScanMessage" + msg)
      //context.io fetch job content, actually it is email content, I need the city and location info
      val future:Future[WSResponse] = WS.url(contextio_host + "/jobs/" + msg.accountCode +"/" + msg.messageCode ).get()
      //scan jobs success
      future onSuccess {
        case response if response.status == 200 => {
          logger.trace("Scanning job content = " + response.json)

          response.json.asOpt[JobContentResponse].map { job =>
            logger.trace("Scanning result job content = " + job)
            val jobContentParseMessage = JobContentParseMessage(msg.jobId, job.content)
            logger.debug("fire the message to job-parse-actor to parse email content.")
            jobParseActor ! jobContentParseMessage
          }
        }
        case response => {
          //handling error
          logger.error("Error handle with status = " + response.status + " message = " + response.body)
        }
      }
      //scan jobs fail
      future onFailure {
        case t => logger.error("An error has occured: " + t.getMessage)
      }
    }

For post
      val request_data = Json.obj(
        "provider" -> "CRAIGSLIST",
        "accountCode" -> msg.accountCode,
        "dateBefore" -> msg.dateBefore.toString(default_date_time_format),
        "dateAfter" -> msg.dateAfter.toString(default_date_time_format),
        "limit" -> msg.limit,
        "offset" -> msg.offset
      )
      logger.debug("Send json request parameter = " + request_data)
      val future:Future[WSResponse] = WS.url(contextio_host + "/jobs/scan").post(request_data)

References:
https://www.playframework.com/documentation/2.4.3/ScalaWS
https://www.playframework.com/documentation/2.4.3/ScalaAkka

akka system
http://sillycat.iteye.com/blog/1767866
http://sillycat.iteye.com/blog/1768625
http://sillycat.iteye.com/blog/1768626
http://sillycat.iteye.com/blog/2099267
http://sillycat.iteye.com/blog/2100232
http://sillycat.iteye.com/blog/2102694
http://sillycat.iteye.com/blog/2175999
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics