/* * Copyright 2016 Dennis Vriend * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.github.dnvriend.domain import java.time.Duration import akka.actor.ActorLogging import akka.event.LoggingReceive import akka.persistence.PersistentActor object Music { type Title = String type Year = Int final case class Song(title: Title, duration: Duration) sealed trait AlbumEvent final case class TitleChanged(title: Title) extends AlbumEvent final case class YearChanged(year: Year) extends AlbumEvent final case class SongAdded(song: Song) extends AlbumEvent final case class SongRemoved(song: Song) extends AlbumEvent sealed trait AlbumCommand final case class ChangeAlbumTitle(title: Title) extends AlbumCommand final case class ChangeAlbumYear(year: Year) extends AlbumCommand final case class AddSong(song: Song) extends AlbumCommand final case class RemoveSong(song: Song) extends AlbumCommand } class Album(val persistenceId: String) extends PersistentActor with ActorLogging { import Music._ var title: Title = _ var year: Year = _ var songs: Set[Song] = Set[Song]() override def receiveRecover: Receive = LoggingReceive { case e: TitleChanged ⇒ handleEvent(e) case e: YearChanged ⇒ handleEvent(e) case e: SongAdded ⇒ handleEvent(e) case e: SongRemoved ⇒ handleEvent(e) } def handleEvent(event: TitleChanged): Unit = { this.title = event.title log.debug(s"[TitleChanged]: Album $persistenceId => title: $title, year: $year songs: $songs") } def handleEvent(event: YearChanged): Unit = { this.year = event.year log.debug(s"[YearChanged]: Album $persistenceId => title: $title, year: $year songs: $songs") } def handleEvent(event: SongAdded): Unit = { this.songs = this.songs + event.song log.debug(s"[SongAdded]: Album $persistenceId => title: $title, year: $year songs: $songs") } def handleEvent(event: SongRemoved): Unit = { this.songs = this.songs - event.song log.debug(s"[SongRemoved]: Album $persistenceId => title: $title, year: $year songs: $songs") } override def receiveCommand: Receive = LoggingReceive { case ChangeAlbumTitle(newTitle) ⇒ persistAll(List(TitleChanged(newTitle))) { e ⇒ handleEvent(e) sender() ! akka.actor.Status.Success("") } case ChangeAlbumYear(newYear) ⇒ persistAll(List(YearChanged(newYear))) { e ⇒ handleEvent(e) sender() ! akka.actor.Status.Success("") } case AddSong(newSong) ⇒ persistAll(List(SongAdded(newSong))) { e ⇒ handleEvent(e) sender() ! akka.actor.Status.Success("") } case RemoveSong(oldSong) ⇒ persistAll(List(SongRemoved(oldSong))) { e ⇒ handleEvent(e) sender() ! akka.actor.Status.Success("") } } override def postStop(): Unit = { log.debug(s"Stopped $persistenceId") super.postStop() } }