diff --git a/common/src/main/scala/com/lbs/common/Logger.scala b/common/src/main/scala/com/lbs/common/Logger.scala index 71f6888..7de9d8e 100644 --- a/common/src/main/scala/com/lbs/common/Logger.scala +++ b/common/src/main/scala/com/lbs/common/Logger.scala @@ -59,4 +59,9 @@ trait Logger { log.info(msg) } + def trace(msg: => String): Unit = { + if (log.isTraceEnabled) + log.trace(msg) + } + } diff --git a/server/build.gradle b/server/build.gradle index 86c1e83..cc10620 100644 --- a/server/build.gradle +++ b/server/build.gradle @@ -23,6 +23,8 @@ dependencies { compile project(':bot') compile project(':common') + compile('com.lihaoyi:sourcecode_2.12:0.1.4') + compile('org.springframework.boot:spring-boot-starter') compile('org.springframework.boot:spring-boot-starter-data-jpa') diff --git a/server/src/main/scala/com/lbs/server/actor/StaticDataForBooking.scala b/server/src/main/scala/com/lbs/server/actor/StaticDataForBooking.scala index 2db606e..8e0637a 100644 --- a/server/src/main/scala/com/lbs/server/actor/StaticDataForBooking.scala +++ b/server/src/main/scala/com/lbs/server/actor/StaticDataForBooking.scala @@ -51,7 +51,7 @@ trait StaticDataForBooking extends Conversation[BookingData] { } } - protected def staticData(staticDataConfig: => StaticDataConfig)(functions: BookingData => Step => MessageProcessorFn)(requestNext: Step): Step = { + protected def staticData(staticDataConfig: => StaticDataConfig)(functions: BookingData => Step => MessageProcessorFn)(requestNext: Step)(implicit functionName: sourcecode.Name): Step = { ask { _ => staticData ! InitConversation staticData ! StartConversation diff --git a/server/src/main/scala/com/lbs/server/actor/conversation/Conversation.scala b/server/src/main/scala/com/lbs/server/actor/conversation/Conversation.scala index 05d7508..93d5a5f 100644 --- a/server/src/main/scala/com/lbs/server/actor/conversation/Conversation.scala +++ b/server/src/main/scala/com/lbs/server/actor/conversation/Conversation.scala @@ -17,7 +17,7 @@ trait Conversation[D] extends Actor with Domain[D] with Logger { private val defaultMsgHandler: MessageProcessorFn = { case Msg(any, data) => - debug(s"Unhandled message received. [$any, $data]") + warn(s"Unhandled message received in step '${currentStep.stepName}'. Message: [$any]. Data: [$data]") NextStep(currentStep, Some(data)) } @@ -35,7 +35,7 @@ trait Conversation[D] extends Actor with Domain[D] with Logger { try { currentStep match { case qa: Dialogue => qa.askFn(currentData) - case Process(fn) => + case Process(_, fn) => val nextStep = fn(currentData) moveToNextStep(nextStep) case _ => //do nothing @@ -56,10 +56,10 @@ trait Conversation[D] extends Actor with Domain[D] with Logger { } currentStep match { - case Dialogue(_, fn) => + case Dialogue(_, _, fn) => val fact = Msg(any, currentData) handle(fact, fn, msgHandler) - case Monologue(fn) => + case Monologue(_, fn) => val fact = Msg(any, currentData) handle(fact, fn, msgHandler) case _ => //do nothing @@ -67,6 +67,7 @@ trait Conversation[D] extends Actor with Domain[D] with Logger { } private def moveToNextStep(nextStep: NextStep): Unit = { + debug(s"Moving from step '${currentStep.stepName}' to step '${nextStep.step.stepName}'") currentStep = nextStep.step nextStep.data.foreach { data => currentData = data @@ -84,14 +85,20 @@ trait Conversation[D] extends Actor with Domain[D] with Logger { init() } - protected def monologue(answerFn: MessageProcessorFn): Monologue = Monologue(answerFn) + protected def monologue(answerFn: MessageProcessorFn)(implicit functionName: sourcecode.Name): Monologue = Monologue(functionName.value, answerFn) protected def ask(askFn: D => Unit): Ask = Ask(askFn) - protected def process(processFn: ProcessFn): Process = Process(processFn) + protected def process(processFn: ProcessFn)(implicit functionName: sourcecode.Name): Process = Process(functionName.value, processFn) protected def end(): NextStep = NextStep(End) + protected implicit class AskOps(ask: Ask) { + def onReply(replyProcessorFn: MessageProcessorFn)(implicit functionName: sourcecode.Name): Dialogue = { + Dialogue(functionName.value, ask.askFn, replyProcessorFn) + } + } + protected def goto(step: Step): NextStep = { self ! ContinueConversation NextStep(step) diff --git a/server/src/main/scala/com/lbs/server/actor/conversation/Domain.scala b/server/src/main/scala/com/lbs/server/actor/conversation/Domain.scala index 572742f..cef284c 100644 --- a/server/src/main/scala/com/lbs/server/actor/conversation/Domain.scala +++ b/server/src/main/scala/com/lbs/server/actor/conversation/Domain.scala @@ -9,24 +9,24 @@ trait Domain[D] { protected case class Msg(message: Any, data: D) - sealed trait Step + sealed trait Step { + def stepName: String + } - private[conversation] object End extends Step + private[conversation] object End extends Step { + val stepName: String = "end" + } - protected case class Process(processFn: ProcessFn) extends Step + protected case class Process(stepName: String, processFn: ProcessFn) extends Step - protected case class Dialogue(askFn: AskFn, replyProcessorFn: MessageProcessorFn) extends Step + protected case class Dialogue(stepName: String, askFn: AskFn, replyProcessorFn: MessageProcessorFn) extends Step - protected case class Monologue(replyProcessorFn: MessageProcessorFn) extends Step + protected case class Monologue(stepName: String, replyProcessorFn: MessageProcessorFn) extends Step private[conversation] case class NextStep(step: Step, data: Option[D] = None) private[conversation] case class Ask(askFn: AskFn) - protected implicit class RichQuestion(ask: Ask) { - def onReply(replyProcessorFn: MessageProcessorFn): Dialogue = Dialogue(ask.askFn, replyProcessorFn) - } - protected implicit class NextStepOps(nextStep: NextStep) { def using(data: D): NextStep = { nextStep.copy(data = Some(data))