From 619dfb5e64ff7891ab5c70236618d7b6d2dbad1a Mon Sep 17 00:00:00 2001 From: Ylenia Battistini Date: Wed, 30 Sep 2020 21:35:06 +0200 Subject: [PATCH] minor changes --- .../server/GreenHouseController.scala | 213 ++++++++++-------- 1 file changed, 124 insertions(+), 89 deletions(-) diff --git a/src/main/scala/it/unibo/intelliserra/server/GreenHouseController.scala b/src/main/scala/it/unibo/intelliserra/server/GreenHouseController.scala index 47a7807..0c8719b 100644 --- a/src/main/scala/it/unibo/intelliserra/server/GreenHouseController.scala +++ b/src/main/scala/it/unibo/intelliserra/server/GreenHouseController.scala @@ -1,13 +1,15 @@ package it.unibo.intelliserra.server -import akka.actor.{Actor, ActorLogging, ActorRef, ActorSystem, Props} +import akka.actor.{Actor, ActorRef, ActorSystem, Props} import akka.pattern.ask -import akka.util.Timeout +import it.unibo.intelliserra.common.akka.actor.{DefaultExecutionContext, DefaultTimeout} import it.unibo.intelliserra.common.communication.Messages +import it.unibo.intelliserra.common.communication.Messages.ZoneManagerRequest import it.unibo.intelliserra.common.communication.Protocol._ +import it.unibo.intelliserra.server.GreenHouseController.ResponseMap +import it.unibo.intelliserra.server.entityManager.DeviceChannel -import scala.concurrent.duration._ -import scala.concurrent.{ExecutionContext, Future} +import scala.concurrent.Future import scala.util.{Failure, Success, Try} /** @@ -17,122 +19,155 @@ import scala.util.{Failure, Success, Try} * @param zoneManagerActor , actorRef * @param entityManagerActor , actorRef */ -//noinspection ScalaStyle -private[server] class GreenHouseController(zoneManagerActor: ActorRef, entityManagerActor: ActorRef, ruleEngineServiceActor: ActorRef) extends Actor with ActorLogging { - type ResponseMap[T] = PartialFunction[Try[T], ServiceResponse] +private[server] class GreenHouseController(zoneManagerActor: ActorRef, + entityManagerActor: ActorRef, + ruleEngineServiceActor: ActorRef) + extends Actor + with DefaultExecutionContext + with DefaultTimeout { private implicit val system: ActorSystem = context.system - private implicit val timeout: Timeout = Timeout(5 seconds) - implicit val ec: ExecutionContext = context.dispatcher - private def sendResponseWithFallback[T](request: Future[T], replyTo: ActorRef)(mapSend: ResponseMap[T]): Unit = { - request onComplete { - sendResponseWithFallback(replyTo)(mapSend) + /* --- ON RECEIVE ACTIONS --- */ + override def receive: Receive = { + + case CreateZone(zoneName) => onCreateZone(zoneName) + + case DeleteZone(zoneName) => onDeleteZone(zoneName) + + case GetZones() => onGetZones() + + case GetState(zoneName) => onGetState(zoneName) + + case AssignEntity(zoneName, entityId) => onAssignEntity(zoneName, entityId) + + case DissociateEntity(entityId) => onDissociateEntity(entityId) + + case RemoveEntity(entityId) => onRemoveEntity(entityId) + + case GetRules => onGetRules() + + case EnableRule(ruleID) => onEnableRule(ruleID) + + case DisableRule(ruleID) => onDisableRule(ruleID) + } + + private def onCreateZone(zoneName: String): Unit = { + sendResponseWithFallback(zoneManagerActor ? Messages.CreateZone(zoneName), sender()) { + case Success(Messages.ZoneCreated) => ServiceResponse(Created) + case Success(Messages.ZoneAlreadyExists) => ServiceResponse(Conflict, "Zone already exists") } } - private def sendResponse[T](replyTo: ActorRef)(mapSend: ResponseMap[T]): Try[T] => Unit = replyTo ! mapSend(_) + private def onDeleteZone(zoneName: String): Unit = { + sendResponseWithFallback(zoneManagerActor ? Messages.RemoveZone(zoneName), sender()) { + case Success(Messages.ZoneRemoved) => ServiceResponse(Deleted) + case Success(Messages.ZoneNotFound) => ServiceResponse(NotFound, "Zone not found") + } + } - private def sendResponseWithFallback[T](replyTo: ActorRef)(mapSend: ResponseMap[T]): Try[T] => Unit = sendResponse(replyTo)(mapSend orElse fallback) + private def onGetZones(): Unit = { + sendResponseWithFallback(zoneManagerActor ? Messages.GetZones, sender()) { + case Success(Messages.ZonesResult(zones)) => ServiceResponse(Ok, zones) + } + } - private def fallback[T]: ResponseMap[T] = { - case Failure(exception) => ServiceResponse(Error, exception.toString) - case _ => ServiceResponse(Error, "Internal Error") + private def onGetState(zoneName: String): Unit = { + sendResponseWithFallback(zoneManagerActor ? Messages.GetZoneState(zoneName), sender()) { + case Success(Messages.MyState(state)) => ServiceResponse(Ok, state) + case Success(Messages.ZoneNotFound) => ServiceResponse(NotFound, "Zone not found") + } } - /* --- ON RECEIVE ACTIONS --- */ - override def receive: Receive = { + private def onAssignEntity(zoneName: String, entityId: String): Unit = { + val association = sendToZoneManager(entityId, channel => Messages.AssignEntityToZone(zoneName,channel)) + + sendResponseWithFallback(association, sender()) { + case Success(Messages.EntityNotFound) => ServiceResponse(NotFound, "Entity not found") + case Success(Messages.ZoneNotFound) => ServiceResponse(NotFound, "Zone not found") + case Success(Messages.AlreadyAssigned(zone)) => ServiceResponse(Conflict, "Entity already assigned to " + zone) + case Success(Messages.AssignOk) => ServiceResponse(Ok) + case Success(Messages.AssignError(error)) => ServiceResponse(Error, error) + } + } + + private def onDissociateEntity(entityId: String): Unit = { + val association = sendToZoneManager(entityId, Messages.DissociateEntityFromZone) - case CreateZone(zoneName) => - sendResponseWithFallback(zoneManagerActor ? Messages.CreateZone(zoneName), sender()) { - case Success(Messages.ZoneCreated) => ServiceResponse(Created) - case Success(Messages.ZoneAlreadyExists) => ServiceResponse(Conflict,"Zone already exists") - } - - case DeleteZone(zoneName) => - sendResponseWithFallback(zoneManagerActor ? Messages.RemoveZone(zoneName), sender()) { - case Success(Messages.ZoneRemoved) => ServiceResponse(Deleted) - case Success(Messages.ZoneNotFound) => ServiceResponse(NotFound, "Zone not found") - } - - case GetZones() => - sendResponseWithFallback(zoneManagerActor ? Messages.GetZones, sender()) { - case Success(Messages.ZonesResult(zones)) => ServiceResponse(Ok, zones) - } - - case GetState(zoneName) => - sendResponseWithFallback(zoneManagerActor ? Messages.GetZoneState(zoneName), sender()) { - case Success(Messages.MyState(state)) => ServiceResponse(Ok, state) - case Success(Messages.ZoneNotFound) => ServiceResponse(NotFound, "Zone not found") - } - - case AssignEntity(zoneName, entityId) => - val association = - entityManagerActor ? Messages.GetEntity(entityId) flatMap { - case Messages.EntityResult(entity) => - zoneManagerActor ? Messages.AssignEntityToZone(zoneName, entity) - case msg => Future.successful(msg) - } - sendResponseWithFallback(association, sender()) { - case Success(Messages.EntityNotFound) => ServiceResponse(NotFound, "Entity not found") - case Success(Messages.ZoneNotFound) => ServiceResponse(NotFound, "Zone not found") - case Success(Messages.AlreadyAssigned(zone)) => ServiceResponse(Conflict, "Entity already assigned to " + zone) - case Success(Messages.AssignOk) => ServiceResponse(Ok) - case Success(Messages.AssignError(error)) => ServiceResponse(Error, error) - } - - case DissociateEntity(entityId) => - val association = - entityManagerActor ? Messages.GetEntity(entityId) flatMap { - case Messages.EntityResult(entity) => - zoneManagerActor ? Messages.DissociateEntityFromZone(entity) - case msg => Future.successful(msg) - } - sendResponseWithFallback(association, sender()) { - case Success(Messages.DissociateOk) => ServiceResponse(Ok) - case Success(Messages.AlreadyDissociated) => ServiceResponse(Error, "Entity already dissociated") - case Success(Messages.EntityNotFound) => ServiceResponse(NotFound, "Entity not found") - } - - case RemoveEntity(entityId) => - sendResponseWithFallback(entityManagerActor ? Messages.RemoveEntity(entityId), sender()) { - case Success(Messages.EntityNotFound) => ServiceResponse(NotFound, "Entity not found") - case Success(Messages.EntityRemoved) => ServiceResponse(Deleted) - } - - case GetRules => - sendResponseWithFallback(ruleEngineServiceActor ? Messages.GetRules, sender()) { - case Success(Messages.Rules(rules)) => ServiceResponse(Ok, rules) - } - - case EnableRule(ruleID) => sendResponseWithFallback(ruleEngineServiceActor ? Messages.EnableRule(ruleID), sender()) { + sendResponseWithFallback(association, sender()) { + case Success(Messages.DissociateOk) => ServiceResponse(Ok) + case Success(Messages.AlreadyDissociated) => ServiceResponse(Error, "Entity already dissociated") + case Success(Messages.EntityNotFound) => ServiceResponse(NotFound, "Entity not found") + } + } + + private def sendToZoneManager(entityId: String, request: DeviceChannel => ZoneManagerRequest): Future[Any] = { + entityManagerActor ? Messages.GetEntity(entityId) flatMap { + case Messages.EntityResult(entity) => + zoneManagerActor ? request(entity) + case msg => Future.successful(msg) + } + } + + private def onRemoveEntity(entityId: String): Unit = { + sendResponseWithFallback(entityManagerActor ? Messages.RemoveEntity(entityId), sender()) { + case Success(Messages.EntityNotFound) => ServiceResponse(NotFound, "Entity not found") + case Success(Messages.EntityRemoved) => ServiceResponse(Deleted) + } + } + + private def onGetRules(): Unit = { + sendResponseWithFallback(ruleEngineServiceActor ? Messages.GetRules, sender()) { + case Success(Messages.Rules(rules)) => ServiceResponse(Ok, rules) + } + } + + private def onEnableRule(ruleID: String): Unit = { + sendResponseWithFallback(ruleEngineServiceActor ? Messages.EnableRule(ruleID), sender()) { case Success(Messages.EnableOk) => ServiceResponse(Ok, "Rule enabled") case Success(Messages.Error) => ServiceResponse(Error, "not possible") } + } - case DisableRule(ruleID) => sendResponseWithFallback(ruleEngineServiceActor ? Messages.DisableRule(ruleID), sender()) { + private def onDisableRule(ruleID: String): Unit = { + sendResponseWithFallback(ruleEngineServiceActor ? Messages.DisableRule(ruleID), sender()) { case Success(Messages.DisableOk) => ServiceResponse(Ok, "Rule disabled") case Success(Messages.Error) => ServiceResponse(Error, "not possible") } } + + private def sendResponseWithFallback[T](request: Future[T], replyTo: ActorRef)(mapSend: ResponseMap[T]): Unit = { + request onComplete { + sendResponseWithFallback(replyTo)(mapSend) + } + } + + private def sendResponse[T](replyTo: ActorRef)(mapSend: ResponseMap[T]): Try[T] => Unit = replyTo ! mapSend(_) + + private def sendResponseWithFallback[T](replyTo: ActorRef)(mapSend: ResponseMap[T]): Try[T] => Unit = sendResponse(replyTo)(mapSend orElse fallback) + + private def fallback[T]: ResponseMap[T] = { + case Failure(exception) => ServiceResponse(Error, exception.toString) + case _ => ServiceResponse(Error, "Internal Error") + } } /** Factory for [[it.unibo.intelliserra.server.GreenHouseController]] instances. */ object GreenHouseController { + type ResponseMap[T] = PartialFunction[Try[T], ServiceResponse] + val name = "GreenHouseController" /** * Creates a GreenHouseController actor with a given the actorRef from the other actors. * - * @param zoneManagerActor actorRef representing a zoneManager actor, - * @param entityManagerActor actorRef representing a entityManager actor, + * @param zoneManagerActor actorRef representing a zoneManager actor, + * @param entityManagerActor actorRef representing a entityManager actor, * @param ruleEngineServiceActor actorRef representing a ruleEngineService actor, - * @param actorSystem represent the actorSystem, + * @param actorSystem represent the actorSystem, * @return actorRef representing an actor, which is a new GreenHouseController * that contains the actorRef of the other actors and the specified name. */ def apply(zoneManagerActor: ActorRef, entityManagerActor: ActorRef, ruleEngineServiceActor: ActorRef)(implicit actorSystem: ActorSystem): ActorRef = actorSystem actorOf(Props(new GreenHouseController(zoneManagerActor, entityManagerActor, ruleEngineServiceActor)), name) -} - - +} \ No newline at end of file