Skip to content

Commit

Permalink
Merge pull request #45 from cafienne/extending-metadata
Browse files Browse the repository at this point in the history
Allow subtyping of MetaData / CommandMetaData
  • Loading branch information
hervandevliert authored Sep 7, 2018
2 parents 901ace6 + 61bb117 commit b5a7086
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ trait AggregateRootId extends Id
* @param timestamp the moment the event was created
* @param userContext contains an assumed known user, events generated via an HTTP API will most of the time be authenticated
*/
case class CommandMetaData(
timestamp: ZonedDateTime,
userContext: Option[UserContext],
commandId: UUID = UUID.randomUUID()
)
trait CommandMetaData {
def timestamp: ZonedDateTime
def userContext: Option[UserContext]
def commandId: UUID = UUID.randomUUID()
}

trait DomainCommand {

Expand All @@ -40,24 +40,12 @@ trait DomainCommand {
* @param buildInfo contains the build information of the application. The Version is used to ensure version specific routing of messages.
* @param runTimeInfo contains information on the runtime the event is generated and stored
*/
case class MetaData(
timestamp: ZonedDateTime,
userContext: Option[UserContext],
causedByCommand: Option[UUID],
buildInfo: BuildInfo,
runTimeInfo: RuntimeInfo
)

object MetaData {
def fromCommand(metadata: CommandMetaData)(implicit buildInfo: BuildInfo, runtimeInfo: RuntimeInfo): MetaData = {
MetaData(
metadata.timestamp,
metadata.userContext,
Some(metadata.commandId),
buildInfo,
runtimeInfo
)
}
trait MetaData {
def timestamp: ZonedDateTime
def userContext: Option[UserContext]
def causedByCommand: Option[UUID]
def buildInfo: BuildInfo
def runTimeInfo: RuntimeInfo
}

trait DomainEvent extends Persistable {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
package io.cafienne.bounded.eventmaterializers

import java.time.ZonedDateTime
import java.util.UUID

import akka.Done
import akka.actor.{ActorSystem, PoisonPill, Props}
Expand All @@ -23,7 +24,15 @@ import org.slf4j.LoggerFactory
import scala.concurrent.Future
import scala.concurrent.duration._

case class TestedEvent(metaData: MetaData, text: String) extends DomainEvent {
case class TestMetaData(
timestamp: ZonedDateTime,
userContext: Option[UserContext],
causedByCommand: Option[UUID],
buildInfo: BuildInfo,
runTimeInfo: RuntimeInfo
) extends MetaData

case class TestedEvent(metaData: TestMetaData, text: String) extends DomainEvent {
override def id: AggregateRootId = new AggregateRootId {
override def idAsString: String = "testaggregate"
}
Expand Down Expand Up @@ -52,7 +61,8 @@ class AbstractReplayableEventMaterializerWithRuntimeEventFilterSpec
val previousBuild = buildInfo.copy(version = "0.9")
val futureBuild = buildInfo.copy(version = "1.1")

val currentMeta = MetaData(ZonedDateTime.parse("2018-01-01T17:43:00+01:00"), None, None, currentBuild, currentRuntime)
val currentMeta =
TestMetaData(ZonedDateTime.parse("2018-01-01T17:43:00+01:00"), None, None, currentBuild, currentRuntime)

val testSet = Seq(
TestedEvent(currentMeta, "current-current"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,12 @@ class TestAggregateRoot(aggregateRootId: AggregateRootId, buildInfo: BuildInfo,
override def handleCommand(command: DomainCommand, aggregateState: Option[TestAggregateRootState]): Reply = {
command match {
case CreateInitialState(metaData, aggregateRootId, state) =>
Ok(Seq[DomainEvent](InitialStateCreated(MetaData.fromCommand(metaData), aggregateRootId, state)))
val testMetaData = metaData.asInstanceOf[TestCommandMetaData]
Ok(Seq[DomainEvent](InitialStateCreated(TestMetaData.fromCommand(testMetaData), aggregateRootId, state)))
case UpdateState(metaData, aggregateRootId, state) =>
val testMetaData = metaData.asInstanceOf[TestCommandMetaData]
if (aggregateState.isDefined && aggregateState.get.state.equals("new")) {
Ok(Seq(StateUpdated(MetaData.fromCommand(metaData), aggregateRootId, state)))
Ok(Seq(StateUpdated(TestMetaData.fromCommand(testMetaData), aggregateRootId, state)))
} else {
Ko(InvalidState(s"The current state $aggregateState does not allow an update to $state"))
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright (C) 2016-2018 Cafienne B.V. <https://www.cafienne.io/bounded>
*/

package io.cafienne.bounded.test

import java.time.ZonedDateTime
import java.util.UUID

import io.cafienne.bounded.aggregate.{CommandMetaData, MetaData}
import io.cafienne.bounded.{BuildInfo, RuntimeInfo, UserContext}

case class TestCommandMetaData(
timestamp: ZonedDateTime,
val userContext: Option[UserContext],
override val commandId: UUID = UUID.randomUUID()
) extends CommandMetaData

case class TestMetaData(
timestamp: ZonedDateTime,
userContext: Option[UserContext],
causedByCommand: Option[UUID],
buildInfo: BuildInfo,
runTimeInfo: RuntimeInfo
) extends MetaData

object TestMetaData {
def fromCommand(
metadata: TestCommandMetaData
)(implicit buildInfo: BuildInfo, runtimeInfo: RuntimeInfo): TestMetaData = {
TestMetaData(
metadata.timestamp,
metadata.userContext,
Some(metadata.commandId),
buildInfo,
runtimeInfo
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import akka.event.{Logging, LoggingAdapter}
import akka.testkit.TestKit
import akka.util.Timeout
import io.cafienne.bounded.{BuildInfo, RuntimeInfo}
import io.cafienne.bounded.aggregate.{CommandMetaData, MetaData}
import io.cafienne.bounded.test.TestableAggregateRoot.{CommandHandlingException, IllegalCommandException}
import io.cafienne.bounded.test.DomainProtocol._
import io.cafienne.bounded.test.TestAggregateRoot.TestAggregateRootState
Expand All @@ -31,7 +30,7 @@ class TestableAggregateRootSpec extends AsyncWordSpec with Matchers with ScalaFu

val testAggregateRootCreator = new TestAggregateRootCreator(system)

val currentMeta = MetaData(ZonedDateTime.parse("2018-01-01T17:43:00+01:00"), None, None, buildInfo, runtimeInfo)
val currentMeta = TestMetaData(ZonedDateTime.parse("2018-01-01T17:43:00+01:00"), None, None, buildInfo, runtimeInfo)

"The testable aggregate root" must {

Expand Down Expand Up @@ -65,7 +64,7 @@ class TestableAggregateRootSpec extends AsyncWordSpec with Matchers with ScalaFu

"handle the command to OK in when" in {
val testAggregateRootId1 = TestAggregateRootId("3")
val commandMetaData = CommandMetaData(currentMeta.timestamp, None)
val commandMetaData = TestCommandMetaData(currentMeta.timestamp, None)
val updateStateCommand = UpdateState(commandMetaData, testAggregateRootId1, "updated")
val targetState = TestAggregateRootState("updated")

Expand All @@ -77,7 +76,7 @@ class TestableAggregateRootSpec extends AsyncWordSpec with Matchers with ScalaFu
)
.when(updateStateCommand)

ar.events should contain(StateUpdated(MetaData.fromCommand(commandMetaData), testAggregateRootId1, "updated"))
ar.events should contain(StateUpdated(TestMetaData.fromCommand(commandMetaData), testAggregateRootId1, "updated"))

ar.currentState map { state =>
assert(state.isDefined, s"There is no defined state but expected $targetState")
Expand All @@ -87,8 +86,8 @@ class TestableAggregateRootSpec extends AsyncWordSpec with Matchers with ScalaFu

"handle the CommandHandlingException to KO in when" in {
val testAggregateRootId1 = TestAggregateRootId("3")
val commandMetaData = CommandMetaData(currentMeta.timestamp, None)
val updateStateCommand = UpdateState(commandMetaData, testAggregateRootId1, "updated")
val metaData = TestCommandMetaData(currentMeta.timestamp, None)
val updateStateCommand = UpdateState(metaData, testAggregateRootId1, "updated")

an[CommandHandlingException] should be thrownBy {
TestableAggregateRoot
Expand All @@ -104,7 +103,7 @@ class TestableAggregateRootSpec extends AsyncWordSpec with Matchers with ScalaFu
"handle the IllegalCommandException to KO in when" in {
val testAggregateRootId1 = TestAggregateRootId("4")
val testAggregateRootIdWrongForCommand = TestAggregateRootId("5")
val commandMetaData = CommandMetaData(currentMeta.timestamp, None)
val commandMetaData = TestCommandMetaData(currentMeta.timestamp, None)
val updateStateCommand = UpdateState(commandMetaData, testAggregateRootIdWrongForCommand, "updated")

an[IllegalCommandException] should be thrownBy {
Expand Down
2 changes: 1 addition & 1 deletion version.sbt
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@

version in ThisBuild := "0.1.1"
version in ThisBuild := "0.1.2"

0 comments on commit b5a7086

Please sign in to comment.