Guest User

Untitled

a guest
May 27th, 2018
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.24 KB | None | 0 0
  1. package akka.persistence.typed.scaladsl
  2.  
  3. import akka.actor.typed.Behavior
  4. import akka.persistence.typed.scaladsl.PersistentBehaviors.{CommandHandler, _}
  5.  
  6. class AccountSpec {
  7.  
  8. sealed trait AccountCommand
  9. case object CreateAccount extends AccountCommand
  10. case class Deposit(amount: Double) extends AccountCommand
  11. case class Withdraw(amount: Double) extends AccountCommand
  12. case object CloseAccount extends AccountCommand
  13.  
  14. sealed trait AccountEvent
  15. case object AccountCreated extends AccountEvent
  16. case class Deposited(amount: Double) extends AccountEvent
  17. case class Withdrawn(amount: Double) extends AccountEvent
  18. case object AccountClosed extends AccountEvent
  19.  
  20. sealed trait Account
  21. case class OpenedAccount(balance: Double) extends Account
  22. case object ClosedAccount extends Account
  23.  
  24. private def initial: CommandHandler[AccountCommand, AccountEvent, Option[Account]] =
  25. (_, _, cmd) =>
  26. cmd match {
  27. case CreateAccount ⇒ Effect.persist(AccountCreated)
  28. }
  29.  
  30. private def openedAccountHandlers(acc: OpenedAccount): CommandHandler[AccountCommand, AccountEvent, Option[Account]] =
  31. (ctx, _, cmd) => cmd match {
  32. case Deposit(amount) ⇒ Effect.persist(Deposited(amount))
  33.  
  34. case Withdraw(amount) if (acc.balance - amount) < 0.0 =>
  35. throw new RuntimeException("Insufficient balance")
  36.  
  37. case Withdraw(amount) =>
  38. Effect
  39. .persist(Withdrawn(amount))
  40. .andThen { st => // can't even use a PF here because this method is overloaded
  41. st match { // need to pattern match because state is Account, Effect is invariant on State
  42. case Some(OpenedAccount(balance)) =>
  43. // do some side-effect using balance
  44. println(balance)
  45. }
  46. }
  47. case CloseAccount if acc.balance == 0.0 =>
  48. Effect.persist(AccountClosed)
  49. case CloseAccount =>
  50. throw new RuntimeException("Account balance is not zero")
  51.  
  52. }
  53.  
  54. private def commandHandlers: CommandHandler[AccountCommand, AccountEvent, Option[Account]] =
  55. CommandHandler.byState {
  56. case None => CommandHandler.command {
  57. case CreateAccount => Effect.persist(AccountCreated)
  58. }
  59. case Some(acc@OpenedAccount(_)) => openedAccountHandlers(acc)
  60. case Some(ClosedAccount) => throw new RuntimeException("account already closed")
  61. }
  62.  
  63. private def eventHandler(stateOpt: Option[Account], event: AccountEvent):Option[Account] =
  64. (stateOpt, event) match {
  65.  
  66. case (None, AccountCreated) => Some(OpenedAccount(0.0))
  67.  
  68. case (Some(acc@OpenedAccount(_)), Deposited(amount)) =>
  69. Some(acc.copy(balance = acc.balance + amount))
  70.  
  71. case (Some(acc@OpenedAccount(_)), Withdrawn(amount)) =>
  72. Some(acc.copy(balance = acc.balance - amount))
  73.  
  74. case (Some(acc@OpenedAccount(_)), AccountClosed) =>
  75. Some(ClosedAccount)
  76.  
  77. // this or compiler warning. We should not need to do it
  78. case _ => throw new RuntimeException("this should never happen")
  79. }
  80.  
  81.  
  82. def behavior(accountNumber: String): Behavior[AccountCommand] =
  83. PersistentBehaviors.receive[AccountCommand, AccountEvent, Option[Account]](
  84. persistenceId = accountNumber,
  85. initialState = None,
  86. commandHandler = commandHandlers,
  87. eventHandler = eventHandler
  88. )
  89. }
Add Comment
Please, Sign In to add comment