/app/xivo/services/XivoDirectory.scala
https://gitlab.com/winckell.benjamin.isart/xucserver · Scala · 205 lines · 179 code · 26 blank · 0 comment · 5 complexity · 942210ca4071b3a352d89ba103e9ab4b MD5 · raw file
- package xivo.services
- import akka.actor.{ActorRef, Actor, ActorLogging, Props}
- import play.api.libs.json._
- import services.directory.DirectoryTransformer
- import DirectoryTransformer.RawDirectoryResult
- import services.config.ConfigRepository
- import services.request._
- import xivo.network.XiVOWSdef
- import xivo.services.XivoDirectory.Action.Action
- import xivo.services.XivoDirectory._
- import xivo.xuc.XucConfig
- import models.{XivoUser, DirSearchResult, Token}
- import scala.concurrent.Await
- import scala.concurrent.duration._
- import play.api.libs.ws.{WSResponse, WSRequestHolder}
- object XivoDirectory {
- def props(xauth: ActorRef, dirTransformer: ActorRef, configRepo: ConfigRepository, xivoWS: XiVOWSdef): Props =
- Props(new XivoDirectory(xauth, dirTransformer, configRepo, xivoWS))
- sealed trait XivoDirectoryMsg
- case class DirLookupResult(result: DirSearchResult) extends XucRequest with XivoDirectoryMsg
- case class Favorites(result: DirSearchResult) extends XucRequest with XivoDirectoryMsg
- object Action extends Enumeration {
- type Action = Value
- val Added = Value
- val AddFail = Value
- val Removed = Value
- val RemoveFail = Value
- implicit val actionWrites = new Writes[Action] {
- def writes(enum: Action) = JsString(enum.toString)
- }
- }
- case class FavoriteUpdated(action: Action, contactId: String, source: String) extends XucRequest with XivoDirectoryMsg
- object FavoriteUpdated {
- implicit val writes = new Writes[FavoriteUpdated] {
- def writes(f: FavoriteUpdated): JsValue =
- JsObject(
- Seq("action" -> JsString(f.action.toString),
- "contact_id" -> JsString(f.contactId),
- "source" -> JsString(f.source)
- )
- )
- }
- }
- case object TokenRetrievalTimeout extends XucRequest with XivoDirectoryMsg
- case object XivoAuthTimeout extends XucRequest with XivoDirectoryMsg
- case object XivoAuthError extends XucRequest with XivoDirectoryMsg
- case object XivoDirdTimeout extends XucRequest with XivoDirectoryMsg
- }
- class XivoDirectory(xauth: ActorRef, dirTransformer: ActorRef, configRepo: ConfigRepository, xivoWS: XiVOWSdef)
- extends Actor with ActorLogging {
- def receive: Receive = {
- case UserBaseRequest(ref, request: DirectoryRequest, user) =>
- configRepo.getUser(user.ctiUsername) match {
- case None =>
- log.error(s"Got directory look up for unknown user ${user.ctiUsername}")
- case Some(user) =>
- log.debug(s"Received $request by user ${user.id}")
- getToken(user, BaseRequest(ref, request))
- }
- case (t: Token, BaseRequest(ref, DirectoryLookUp(term))) =>
- search(term, t) match {
- case r: DirLookupResult =>
- dirTransformer ! RawDirectoryResult(ref, r)
- case other =>
- ref ! other
- }
- case (t: Token, BaseRequest(ref, GetFavorites)) =>
- getFavorites(t) match {
- case f: Favorites =>
- dirTransformer ! RawDirectoryResult(ref, f)
- case other =>
- ref ! other
- }
- case (t: Token, BaseRequest(ref, AddFavorite(contactId, directory))) =>
- setFavorite(contactId, directory, t) match {
- case r: FavoriteUpdated =>
- log.debug(s"sending $r")
- dirTransformer ! RawDirectoryResult(ref, r)
- case other =>
- log.debug(s"sending $other")
- ref ! other
- }
- case (t: Token, BaseRequest(ref, RemoveFavorite(contactId, directory))) =>
- removeFavorite(contactId, directory, t) match {
- case r: FavoriteUpdated =>
- dirTransformer ! RawDirectoryResult(ref, r)
- case other =>
- ref ! other
- }
- case any =>
- log.debug(s"Received unprocessed message $any")
- }
- private def getToken(user: XivoUser, baseRequest: BaseRequest): Unit = {
- val replyTo = self
- context.actorOf(Props(new Actor() {
- xauth ! XivoAuthentication.GetToken(user.id)
- def receive: Receive = {
- case TokenRetrievalTimeout =>
- log.error("Get token timeout")
- baseRequest.requester ! XivoAuthTimeout
- context.stop(self)
- case t: Token =>
- log.debug(s"Got token, searching")
- replyTo ! (t, baseRequest)
- timeout.cancel()
- context.stop(self)
- case any =>
- log.error(s"Received unexpected response $any")
- baseRequest.requester ! XivoAuthError
- context.stop(self)
- }
- import context.dispatcher
- val timeout = context.system.scheduler.scheduleOnce(XucConfig.defaultWSTimeout) {
- self ! TokenRetrievalTimeout
- }
- }))
- }
- private def search(term: String, t: Token): XivoDirectoryMsg = {
- val searchURI = s"${XucConfig.XivoDir.searchURI}/${XucConfig.XivoDir.defaultProfile}${XucConfig.XivoDir.searchArg}$term"
- val request = xivoWS.get(XucConfig.xivoHost, searchURI, headers=Map("X-Auth-Token"-> t.token),
- port=Some(XucConfig.XivoDir.port))
- executeSearchRequest(request, t)
- }
- private def getFavorites(t: Token): XivoDirectoryMsg = {
- val requestURI = s"${XucConfig.XivoDir.favoriteURI}/${XucConfig.XivoDir.defaultProfile}"
- val request = xivoWS.get(XucConfig.xivoHost, requestURI, headers=Map("X-Auth-Token"-> t.token),
- port=Some(XucConfig.XivoDir.port))
- executeSearchRequest(request, t, true)
- }
- private def executeSearchRequest(request: WSRequestHolder, t: Token, favorites: Boolean = false): XivoDirectoryMsg = {
- import context.dispatcher
- val wsResult = request.execute().map(resp => DirSearchResult.parse(resp.json))
- val searchResult = Await.result(wsResult, XucConfig.defaultWSTimeout)
- searchResult match {
- case r: DirSearchResult =>
- log.debug(s"Got dird result: $r")
- if (!favorites) {
- DirLookupResult(r)
- }
- else {
- Favorites(r)
- }
- case _ =>
- log.debug(s"Timeout when searching directory by user: ${t.xivoUserUuid}")
- XivoDirdTimeout
- }
- }
- private def setFavorite(contactId: String, directory: String, t: Token): XivoDirectoryMsg = {
- val requestURI = s"${XucConfig.XivoDir.favoriteURI}/$directory/$contactId"
- val request = xivoWS.put(XucConfig.xivoHost, requestURI, headers = Map("X-Auth-Token" -> t.token),
- port = Some(XucConfig.XivoDir.port))
- processFavoriteRequest(request, contactId, directory, Action.Added, Action.AddFail)
- }
- private def removeFavorite(contactId: String, directory: String, t: Token): XivoDirectoryMsg = {
- val requestURI = s"${XucConfig.XivoDir.favoriteURI}/$directory/$contactId"
- val request = xivoWS.del(XucConfig.xivoHost, requestURI, headers=Map("X-Auth-Token"-> t.token),
- port=Some(XucConfig.XivoDir.port))
- processFavoriteRequest(request, contactId, directory, Action.Removed,
- Action.RemoveFail)
- }
- private def processFavoriteRequest(request: WSRequestHolder, contactId: String, directory: String,
- actionSuccess: Action, actionFail: Action): XivoDirectoryMsg = {
- val wsResult = request.execute()
- val searchResult = Await.result(wsResult, XucConfig.defaultWSTimeout)
- searchResult match {
- case r: WSResponse =>
- log.debug(s"Got set favorite result: ${r.status}")
- if (r.status == 204) {
- FavoriteUpdated(actionSuccess, contactId, directory)
- }
- else {
- FavoriteUpdated(actionFail, contactId, directory)
- }
- case _ =>
- log.debug(s"Timeout when processing favorite action ${actionSuccess} for $contactId/$directory")
- XivoDirdTimeout
- }
- }
- }