From f5c3a9cab68fce13635ebbb27ce2f438b2cc2bbc Mon Sep 17 00:00:00 2001 From: Kevin Samoei Date: Tue, 11 Aug 2020 17:28:46 -0400 Subject: [PATCH] Issue 51: Make event/state proto registration optional (#63) * issue #51: skip proto validations * issue #51: fix tests --- docker/docker-compose.yml | 2 - readme.md | 1 + service/src/main/resources/application.conf | 10 +- .../AggregateCommandHandler.scala | 34 +++--- .../chiefofstate/AggregateEventHandler.scala | 18 ++- .../namely/chiefofstate/HandlerSetting.scala | 12 +- service/src/test/resources/application.conf | 2 + .../src/test/resources/handler-settings.conf | 2 + .../AggregateCommandHandlerSpec.scala | 35 +++++- .../AggregateEventHandlerSpec.scala | 108 ++++++++++++++++-- .../chiefofstate/HandlerSettingSpec.scala | 12 ++ .../chiefofstate/ReadSideHandlerSpec.scala | 12 +- 12 files changed, 202 insertions(+), 46 deletions(-) diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 435553a5..4e23d82f 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -62,8 +62,6 @@ services: COS_PORT: 9000 WRITE_SIDE_HANDLER_SERVICE_HOST: host.docker.internal WRITE_SIDE_HANDLER_SERVICE_PORT: 50052 - HANDLER_SERVICE_STATES_PROTOS: "" - HANDLER_SERVICE_EVENTS_PROTOS: "" TRACE_HOST: tracer TRACE_PORT: 14268 COS_SERVICE_NAME: "chiefofstate" diff --git a/readme.md b/readme.md index 8dbfa5ea..1dcd8cb0 100644 --- a/readme.md +++ b/readme.md @@ -86,6 +86,7 @@ Chief-Of-State heavily relies on the robustness of [lagom-pb](https://github.com | COS_ENCRYPTION_CLASS | java class to use for encryption | io.superflat.lagompb.encryption.NoEncryption | | WRITE_SIDE_HANDLER_SERVICE_HOST | address of the gRPC writeSide handler service | | | WRITE_SIDE_HANDLER_SERVICE_PORT | port for the gRPC writeSide handler service | | +| HANDLER_SERVICE_ENABLE_PROTO_VALIDATION | enable validation of the handler service states and events proto message FQN. If not set to `true` the validation will be skipped. | false | | HANDLER_SERVICE_STATES_PROTOS | handler service states proto message FQN (fully qualified typeUrl). Format: `packagename.messagename`. This will be a comma separated list of values | | | HANDLER_SERVICE_EVENTS_PROTOS | handler service events proto message FQN (fully qualified typeUrl). Format: `packagename.messagename`. This will be a comma separated list of values | | | COS_SERVICE_NAME | service name | chiefofstate | diff --git a/service/src/main/resources/application.conf b/service/src/main/resources/application.conf index 4aef5cce..9c82869b 100644 --- a/service/src/main/resources/application.conf +++ b/service/src/main/resources/application.conf @@ -246,12 +246,18 @@ chief-of-state { # define settings for the handler services handlers-settings { + # Whether to allow validation of the state and events FQNs + # if set to true, validation is done, by default it is false. + enable-proto-validation = false + enable-proto-validation = ${?HANDLER_SERVICE_ENABLE_PROTO_VALIDATION} # define the fully qualified type url of the state proto # example: namely.org_units.OrgUnit - states-proto = ${HANDLER_SERVICE_STATES_PROTOS} + states-proto = "" + states-proto = ${?HANDLER_SERVICE_STATES_PROTOS} # list if the fully qualified type url of the events handled # example: "namely.org_units.OrgUnitTypeCreated", "namely.org_units.OrgUnitTypeUpdated" - events-protos = ${HANDLER_SERVICE_EVENTS_PROTOS} + events-protos = "" + events-protos = ${?HANDLER_SERVICE_EVENTS_PROTOS} } send-command { diff --git a/service/src/main/scala/com/namely/chiefofstate/AggregateCommandHandler.scala b/service/src/main/scala/com/namely/chiefofstate/AggregateCommandHandler.scala index 0c8ee10a..c1440564 100644 --- a/service/src/main/scala/com/namely/chiefofstate/AggregateCommandHandler.scala +++ b/service/src/main/scala/com/namely/chiefofstate/AggregateCommandHandler.scala @@ -156,24 +156,32 @@ class AggregateCommandHandler( val eventFQN: String = Util.getProtoFullyQualifiedName(persistAndReply.getEvent) log.debug(s"[ChiefOfState] command handler event to persist $eventFQN") - - if (handlerSetting.eventFQNs.contains(eventFQN)) { - log.debug(s"[ChiefOfState] command handler event to persist $eventFQN is valid.") + if (handlerSetting.enableProtoValidations) { + if (handlerSetting.eventFQNs.contains(eventFQN)) { + log.debug(s"[ChiefOfState] command handler event to persist $eventFQN is valid.") + CommandHandlerResponse() + .withSuccessResponse( + SuccessCommandHandlerResponse() + .withEvent(Any.pack(Event().withEvent(persistAndReply.getEvent))) + ) + } else { + log.error( + s"[ChiefOfState] command handler event to persist $eventFQN is not configured. Failing request" + ) + CommandHandlerResponse() + .withFailedResponse( + FailedCommandHandlerResponse() + .withReason(s"received unknown event type $eventFQN") + .withCause(FailureCause.ValidationError) + ) + } + } else { + log.debug(s"[ChiefOfState] command handler event to persist $eventFQN. FQN validation skipped.") CommandHandlerResponse() .withSuccessResponse( SuccessCommandHandlerResponse() .withEvent(Any.pack(Event().withEvent(persistAndReply.getEvent))) ) - } else { - log.error( - s"[ChiefOfState] command handler event to persist $eventFQN is not configured. Failing request" - ) - CommandHandlerResponse() - .withFailedResponse( - FailedCommandHandlerResponse() - .withReason(s"received unknown event type $eventFQN") - .withCause(FailureCause.ValidationError) - ) } case Reply(_) => diff --git a/service/src/main/scala/com/namely/chiefofstate/AggregateEventHandler.scala b/service/src/main/scala/com/namely/chiefofstate/AggregateEventHandler.scala index a9c1ed3a..efff5401 100644 --- a/service/src/main/scala/com/namely/chiefofstate/AggregateEventHandler.scala +++ b/service/src/main/scala/com/namely/chiefofstate/AggregateEventHandler.scala @@ -61,15 +61,21 @@ class AggregateEventHandler( log.debug(s"[ChiefOfState]: event handler state $stateFQN") - if (handlerSetting.stateFQNs.contains(stateFQN)) { + if (handlerSetting.enableProtoValidations) { + if (handlerSetting.stateFQNs.contains(stateFQN)) { - log.debug(s"[ChiefOfState]: event handler state $stateFQN is valid.") + log.debug(s"[ChiefOfState]: event handler state $stateFQN is valid.") - priorState.update(_.currentState := handleEventResponse.getResultingState) + priorState.update(_.currentState := handleEventResponse.getResultingState) + } else { + throw new GlobalException( + s"[ChiefOfState]: command handler state to persist $stateFQN is not configured. Failing request" + ) + } } else { - throw new GlobalException( - s"[ChiefOfState]: command handler state to persist $stateFQN is not configured. Failing request" - ) + log.debug(s"[ChiefOfState]: event handler state: $stateFQN. FQN validation skipped.") + + priorState.update(_.currentState := handleEventResponse.getResultingState) } } } diff --git a/service/src/main/scala/com/namely/chiefofstate/HandlerSetting.scala b/service/src/main/scala/com/namely/chiefofstate/HandlerSetting.scala index 279a12ec..0c318ba3 100644 --- a/service/src/main/scala/com/namely/chiefofstate/HandlerSetting.scala +++ b/service/src/main/scala/com/namely/chiefofstate/HandlerSetting.scala @@ -7,7 +7,7 @@ import com.typesafe.config.{Config, ConfigException} * This class need to be kick started on boot. When the configuration variables are not set * an exception should be thrown forcing the implementor to set the appropriate value */ -case class HandlerSetting(stateFQNs: Seq[String], eventFQNs: Seq[String]) +case class HandlerSetting(enableProtoValidations: Boolean, stateFQNs: Seq[String], eventFQNs: Seq[String]) object HandlerSetting { @@ -36,9 +36,13 @@ object HandlerSetting { .map(_.trim) .filter(_.nonEmpty) - if (stateProtos.isEmpty || eventProtos.isEmpty) - throw new RuntimeException("[ChiefOfState] handler service settings not properly set.") + val enableProtoValidations = config.getBoolean("chief-of-state.handlers-settings.enable-proto-validation") - new HandlerSetting(stateProtos, eventProtos) + if (enableProtoValidations) { + if (stateProtos.isEmpty || eventProtos.isEmpty) + throw new RuntimeException("[ChiefOfState] handler service settings not properly set.") + } + + new HandlerSetting(enableProtoValidations, stateProtos, eventProtos) } } diff --git a/service/src/test/resources/application.conf b/service/src/test/resources/application.conf index 0e8bba27..f723ea4b 100644 --- a/service/src/test/resources/application.conf +++ b/service/src/test/resources/application.conf @@ -25,6 +25,8 @@ akka { chief-of-state { # define settings for the handler services handlers-settings { + # Whether to allow validation of the state and events FQNs + enable-proto-validation = false # define the fully qualified type url of the state proto # example: namely.org_units.OrgUnit states-proto = "" diff --git a/service/src/test/resources/handler-settings.conf b/service/src/test/resources/handler-settings.conf index 843af471..22b0aa30 100644 --- a/service/src/test/resources/handler-settings.conf +++ b/service/src/test/resources/handler-settings.conf @@ -1,6 +1,8 @@ chief-of-state { # define settings for the handler services handlers-settings { + # Whether to allow validation of the state and events FQNs + enable-proto-validation = true # define the fully qualified type url of the state proto # example: namely.org_units.OrgUnit states-proto = "" diff --git a/service/src/test/scala/com/namely/chiefofstate/AggregateCommandHandlerSpec.scala b/service/src/test/scala/com/namely/chiefofstate/AggregateCommandHandlerSpec.scala index 777744e1..b60c8d14 100644 --- a/service/src/test/scala/com/namely/chiefofstate/AggregateCommandHandlerSpec.scala +++ b/service/src/test/scala/com/namely/chiefofstate/AggregateCommandHandlerSpec.scala @@ -61,7 +61,7 @@ class AggregateCommandHandlerSpec extends BaseSpec with MockFactory { val testHandlerSetting: HandlerSetting = { val stateProto: Seq[String] = Seq(Util.getProtoFullyQualifiedName(Any.pack(Account.defaultInstance))) val eventsProtos: Seq[String] = Seq(Util.getProtoFullyQualifiedName(Any.pack(AccountOpened.defaultInstance))) - HandlerSetting(stateProto, eventsProtos) + HandlerSetting(enableProtoValidations = true, stateProto, eventsProtos) } "main commandHandler" should { @@ -326,7 +326,7 @@ class AggregateCommandHandlerSpec extends BaseSpec with MockFactory { ) // let us execute the request - val badHandlerSettings: HandlerSetting = HandlerSetting(Seq(), Seq()) + val badHandlerSettings: HandlerSetting = HandlerSetting(enableProtoValidations = true, Seq(), Seq()) val cmdhandler = new AggregateCommandHandler(null, null, badHandlerSettings) val result: CommandHandlerResponse = cmdhandler.handleRemoteResponseSuccess(badResponse) @@ -341,6 +341,33 @@ class AggregateCommandHandlerSpec extends BaseSpec with MockFactory { } + "handle command when event type in handler settings is disabled as expected" in { + + val event = AccountOpened() + .withAccountNumber("123445") + .withAccountUuid(UUID.randomUUID.toString) + + val response = HandleCommandResponse() + .withPersistAndReply( + PersistAndReply() + .withEvent(Any.pack(event)) + ) + + // set enableProtoValidations to false and not provide event and state protos + val handlerSettings: HandlerSetting = HandlerSetting(enableProtoValidations = false, Seq(), Seq()) + val cmdhandler = new AggregateCommandHandler(null, null, handlerSettings) + val result: CommandHandlerResponse = cmdhandler.handleRemoteResponseSuccess(response) + + result shouldBe ( + CommandHandlerResponse() + .withSuccessResponse( + SuccessCommandHandlerResponse() + .withEvent(Any.pack(Event().withEvent(Any.pack(event)))) + ) + ) + + } + "handle command successfully as expected with no event to persist" in { // let us execute the request val cmdhandler = new AggregateCommandHandler(null, null, testHandlerSetting) @@ -456,7 +483,7 @@ class AggregateCommandHandlerSpec extends BaseSpec with MockFactory { // create a CommandHandler with a mock client val stateProto: Seq[String] = Seq(Util.getProtoFullyQualifiedName(Any.pack(Account.defaultInstance))) val eventsProtos: Seq[String] = Seq(Util.getProtoFullyQualifiedName(Any.pack(AccountOpened.defaultInstance))) - val handlerSetting: HandlerSetting = HandlerSetting(stateProto, eventsProtos) + val handlerSetting: HandlerSetting = HandlerSetting(enableProtoValidations = true, stateProto, eventsProtos) val mockGrpcClient = mock[WriteSideHandlerServiceClient] val cmdhandler = new AggregateCommandHandler(null, mockGrpcClient, handlerSetting) @@ -481,7 +508,7 @@ class AggregateCommandHandlerSpec extends BaseSpec with MockFactory { // create a CommandHandler with a mock client val stateProto: Seq[String] = Seq(Util.getProtoFullyQualifiedName(Any.pack(Account.defaultInstance))) val eventsProtos: Seq[String] = Seq(Util.getProtoFullyQualifiedName(Any.pack(AccountOpened.defaultInstance))) - val handlerSetting: HandlerSetting = HandlerSetting(stateProto, eventsProtos) + val handlerSetting: HandlerSetting = HandlerSetting(enableProtoValidations = true, stateProto, eventsProtos) val mockGrpcClient = mock[WriteSideHandlerServiceClient] val cmdhandler = new AggregateCommandHandler(null, mockGrpcClient, handlerSetting) diff --git a/service/src/test/scala/com/namely/chiefofstate/AggregateEventHandlerSpec.scala b/service/src/test/scala/com/namely/chiefofstate/AggregateEventHandlerSpec.scala index deb20e51..8894d912 100644 --- a/service/src/test/scala/com/namely/chiefofstate/AggregateEventHandlerSpec.scala +++ b/service/src/test/scala/com/namely/chiefofstate/AggregateEventHandlerSpec.scala @@ -7,11 +7,7 @@ import com.google.protobuf.any.Any import com.namely.protobuf.chief_of_state.common import com.namely.protobuf.chief_of_state.persistence.{Event, State} import com.namely.protobuf.chief_of_state.tests.{Account, AccountOpened} -import com.namely.protobuf.chief_of_state.writeside.{ - HandleEventRequest, - HandleEventResponse, - WriteSideHandlerServiceClient -} +import com.namely.protobuf.chief_of_state.writeside.{HandleEventRequest, HandleEventResponse, WriteSideHandlerServiceClient} import io.grpc.Status import io.superflat.lagompb.GlobalException import io.superflat.lagompb.protobuf.core.MetaData @@ -34,7 +30,7 @@ class AggregateEventHandlerSpec extends BaseSpec with MockFactory { val eventsProtos: Seq[String] = Seq(Util.getProtoFullyQualifiedName(Any.pack(AccountOpened.defaultInstance))) - val handlerSetting: HandlerSetting = HandlerSetting(stateProto, eventsProtos) + val handlerSetting: HandlerSetting = HandlerSetting(enableProtoValidations = true, stateProto, eventsProtos) val event = AccountOpened() .withAccountNumber(accountNumber) @@ -85,7 +81,54 @@ class AggregateEventHandlerSpec extends BaseSpec with MockFactory { val eventsProtos: Seq[String] = Seq(Util.getProtoFullyQualifiedName(Any.pack(AccountOpened.defaultInstance))) - val handlerSetting: HandlerSetting = HandlerSetting(stateProto, eventsProtos) + val handlerSetting: HandlerSetting = HandlerSetting(enableProtoValidations = true, stateProto, eventsProtos) + + val event = AccountOpened() + .withAccountNumber(accountNumber) + .withAccountUuid(accouuntId) + + val resultingState = Account() + .withAccountNumber(accountNumber) + .withAccountUuid(accouuntId) + .withBalance(100) + + // let us create a mock instance of the handler service client + val mockGrpcClient = mock[WriteSideHandlerServiceClient] + + (mockGrpcClient + .handleEvent(_: HandleEventRequest)) + .expects( + HandleEventRequest() + .withEvent(Any.pack(event)) + .withCurrentState(priorState.getCurrentState) + .withMeta( + common + .MetaData() + .withData(eventMeta.data) + .withRevisionDate(eventMeta.getRevisionDate) + .withRevisionNumber(eventMeta.revisionNumber) + ) + ) + .returning( + Future.successful( + HandleEventResponse() + .withResultingState(Any.pack(resultingState)) + ) + ) + + val eventHandler: AggregateEventHandler = new AggregateEventHandler(null, mockGrpcClient, handlerSetting) + a[GlobalException] shouldBe thrownBy( + eventHandler.handle(Event().withEvent(Any.pack(event)), priorState, eventMeta) + ) + } + + "handle event when event protos validation is disabled in handler settings as expected" in { + val priorState: State = State.defaultInstance + val eventMeta: MetaData = MetaData.defaultInstance + val accouuntId: String = UUID.randomUUID.toString + val accountNumber: String = "123445" + + val handlerSetting: HandlerSetting = HandlerSetting(enableProtoValidations = false, Seq.empty, Seq.empty) val event = AccountOpened() .withAccountNumber(accountNumber) @@ -121,6 +164,53 @@ class AggregateEventHandlerSpec extends BaseSpec with MockFactory { ) val eventHandler: AggregateEventHandler = new AggregateEventHandler(null, mockGrpcClient, handlerSetting) + + noException shouldBe thrownBy(eventHandler.handle(Event().withEvent(Any.pack(event)), priorState, eventMeta)) + } + + "handle event when event validation is enabled and the FQNs not provided in handler settings as expected" in { + val priorState: State = State.defaultInstance + val eventMeta: MetaData = MetaData.defaultInstance + val accouuntId: String = UUID.randomUUID.toString + val accountNumber: String = "123445" + + val handlerSetting: HandlerSetting = HandlerSetting(enableProtoValidations = true, Seq.empty, Seq.empty) + + val event = AccountOpened() + .withAccountNumber(accountNumber) + .withAccountUuid(accouuntId) + + val resultingState = Account() + .withAccountNumber(accountNumber) + .withAccountUuid(accouuntId) + .withBalance(100) + + // let us create a mock instance of the handler service client + val mockGrpcClient = mock[WriteSideHandlerServiceClient] + + (mockGrpcClient + .handleEvent(_: HandleEventRequest)) + .expects( + HandleEventRequest() + .withEvent(Any.pack(event)) + .withCurrentState(priorState.getCurrentState) + .withMeta( + common + .MetaData() + .withData(eventMeta.data) + .withRevisionDate(eventMeta.getRevisionDate) + .withRevisionNumber(eventMeta.revisionNumber) + ) + ) + .returning( + Future.successful( + HandleEventResponse() + .withResultingState(Any.pack(resultingState)) + ) + ) + + val eventHandler: AggregateEventHandler = new AggregateEventHandler(null, mockGrpcClient, handlerSetting) + a[GlobalException] shouldBe thrownBy( eventHandler.handle(Event().withEvent(Any.pack(event)), priorState, eventMeta) ) @@ -136,7 +226,7 @@ class AggregateEventHandlerSpec extends BaseSpec with MockFactory { val eventsProtos: Seq[String] = Seq(Util.getProtoFullyQualifiedName(Any.pack(AccountOpened.defaultInstance))) - val handlerSetting: HandlerSetting = HandlerSetting(stateProto, eventsProtos) + val handlerSetting: HandlerSetting = HandlerSetting(enableProtoValidations = true, stateProto, eventsProtos) val event = AccountOpened() .withAccountNumber(accountNumber) @@ -177,7 +267,7 @@ class AggregateEventHandlerSpec extends BaseSpec with MockFactory { val eventsProtos: Seq[String] = Seq(Util.getProtoFullyQualifiedName(Any.pack(AccountOpened.defaultInstance))) - val handlerSetting: HandlerSetting = HandlerSetting(stateProto, eventsProtos) + val handlerSetting: HandlerSetting = HandlerSetting(enableProtoValidations = true, stateProto, eventsProtos) val event = AccountOpened() .withAccountNumber(accountNumber) diff --git a/service/src/test/scala/com/namely/chiefofstate/HandlerSettingSpec.scala b/service/src/test/scala/com/namely/chiefofstate/HandlerSettingSpec.scala index f8e92961..e1f4d6c3 100644 --- a/service/src/test/scala/com/namely/chiefofstate/HandlerSettingSpec.scala +++ b/service/src/test/scala/com/namely/chiefofstate/HandlerSettingSpec.scala @@ -12,6 +12,18 @@ class HandlerSettingSpec extends BaseSpec { an[RuntimeException] shouldBe thrownBy(HandlerSetting(config)) } + "success to load settings when enable-validation is disabled" in { + val config: Config = ConfigFactory + .parseResources("handler-settings.conf") + .withValue( + "chief-of-state.handlers-settings.enable-proto-validation", + ConfigValueFactory.fromAnyRef(false) + ) + .resolve() + + noException shouldBe thrownBy(HandlerSetting(config)) + } + "fail to load settings because env variables for events-protos not set" in { val config: Config = ConfigFactory .parseResources("handler-settings.conf") diff --git a/service/src/test/scala/com/namely/chiefofstate/ReadSideHandlerSpec.scala b/service/src/test/scala/com/namely/chiefofstate/ReadSideHandlerSpec.scala index 29d5beef..bd5e5153 100644 --- a/service/src/test/scala/com/namely/chiefofstate/ReadSideHandlerSpec.scala +++ b/service/src/test/scala/com/namely/chiefofstate/ReadSideHandlerSpec.scala @@ -63,7 +63,7 @@ class ReadSideHandlerSpec val eventsProtos: Seq[String] = Seq(Util.getProtoFullyQualifiedName(Any.pack(AccountOpened.defaultInstance))) - val handlerSetting: HandlerSetting = HandlerSetting(stateProto, eventsProtos) + val handlerSetting: HandlerSetting = HandlerSetting(enableProtoValidations = true, stateProto, eventsProtos) val event = AccountOpened() .withAccountNumber(accountNumber) @@ -152,7 +152,7 @@ class ReadSideHandlerSpec val eventsProtos: Seq[String] = Seq(Util.getProtoFullyQualifiedName(Any.pack(AccountOpened.defaultInstance))) - val handlerSetting: HandlerSetting = HandlerSetting(stateProto, eventsProtos) + val handlerSetting: HandlerSetting = HandlerSetting(enableProtoValidations = true, stateProto, eventsProtos) val event = AccountOpened() .withAccountNumber(accountNumber) @@ -239,7 +239,7 @@ class ReadSideHandlerSpec val eventsProtos: Seq[String] = Seq(Util.getProtoFullyQualifiedName(Any.pack(AccountOpened.defaultInstance))) - val handlerSetting: HandlerSetting = HandlerSetting(stateProto, eventsProtos) + val handlerSetting: HandlerSetting = HandlerSetting(enableProtoValidations = true, stateProto, eventsProtos) val event = AccountOpened() .withAccountNumber(accountNumber) @@ -321,7 +321,7 @@ class ReadSideHandlerSpec val eventsProtos: Seq[String] = Seq(Util.getProtoFullyQualifiedName(Any.pack(AccountOpened.defaultInstance))) - val handlerSetting: HandlerSetting = HandlerSetting(stateProto, eventsProtos) + val handlerSetting: HandlerSetting = HandlerSetting(enableProtoValidations = true, stateProto, eventsProtos) val event = AccountOpened() .withAccountNumber(accountNumber) @@ -407,7 +407,7 @@ class ReadSideHandlerSpec val eventsProtos: Seq[String] = Seq(Util.getProtoFullyQualifiedName(Any.pack(AccountOpened.defaultInstance))) - val handlerSetting: HandlerSetting = HandlerSetting(stateProto, eventsProtos) + val handlerSetting: HandlerSetting = HandlerSetting(enableProtoValidations = true, stateProto, eventsProtos) val event = AccountOpened() .withAccountNumber(accountNumber) @@ -493,7 +493,7 @@ class ReadSideHandlerSpec val eventsProtos: Seq[String] = Seq(Util.getProtoFullyQualifiedName(Any.pack(AccountOpened.defaultInstance))) - val handlerSetting: HandlerSetting = HandlerSetting(stateProto, eventsProtos) + val handlerSetting: HandlerSetting = HandlerSetting(enableProtoValidations = true, stateProto, eventsProtos) val event = AccountOpened() .withAccountNumber(accountNumber)