public AccountActor() { /* Hanlde Recovery */ Recover <SnapshotOffer>(offer => offer.Snapshot is AccountState, offer => ApplySnapShot(offer)); Recover <AccountCreated>(@event => ApplyPastEvent("AccountCreated", @event)); Recover <ObligationAddedToAccount>(@event => ApplyPastEvent("ObligationAddedToAccount", @event)); Recover <ObligationAssessedConcept>(@event => ApplyPastEvent("ObligationAssessedConcept", @event)); Recover <SuperSimpleSuperCoolDomainEventFoundByRules>( @event => ApplyPastEvent("SuperSimpleSuperCoolEventFoundByRules", @event)); Recover <PaymentAppliedToObligation>( @event => ApplyPastEvent("PaymentAppliedToObligation", @event)); /** * Creating the account's initial state is more of a one-time thing * For the demo there no business rules are assumed when adding an * maintenanceFee to an account, but there most likely will be in reality * */ Command <CreateAccount>(command => InitiateAccount(command)); Command <AddObligationToAccount>(command => AddObligation(command)); Command <CheckYoSelf>(command => RegisterStartup() /*effectively a noop */); /* Example of running comannds through business rules */ Command <BillingAssessment>(command => ProcessBilling(command)); Command <BusinessRuleApplicationResultModel>(model => ApplyBusinessRules(model)); Command <PayAccount>(cmd => ProcessPayment(cmd)); Command <AskToBeSupervised>(command => GetSupervised(command)); Command <PublishAccountStateToKafka>(msg => PublishToKafka(msg)); Command <CompleteBoardingProcess>(msg => CompleteBoardingProcess()); /** Special handlers below; we can decide how to handle snapshot processin outcomes. */ Command <SaveSnapshotSuccess>(success => PurgeOldSnapShots(success)); Command <DeleteSnapshotsSuccess>(msg => { }); Command <SaveSnapshotFailure>( failure => _log.Error( $"[SaveSnapshotFailure]: Actor {Self.Path.Name} was unable to save a snapshot. {failure.Cause.Message}")); Command <TellMeYourStatus>(asking => Sender.Tell( new MyAccountStatus( $"{Self.Path.Name} I am alive! I was last booted up on {_lastBootedOn:yyyy-MM-dd hh:mm:ss}"))); Command <TellMeYourInfo>( asking => Sender.Tell(new MyAccountStatus("", (AccountState)_accountState.Clone()))); Command <DeleteMessagesSuccess>( msg => _log.Debug( $"[DeleteMessagesSuccess]: Successfully cleared log after snapshot ({msg.ToString()})")); CommandAny(msg => _log.Error($"[CommandAny]: Unhandled message in {Self.Path.Name} from {Sender.Path.Name}. Message:{msg.ToString()}")); }
private void ProcessPayment(PayAccount cmd) { try { var luckObligation = _accountState.Obligations.FirstOrDefault(x => x.Key == "AccountAdjustments").Value; if (luckObligation == null) { throw new Exception($"[ProcessPayment]: Inconvibable! Why is there no obligation?"); } var @event = new PaymentAppliedToObligation( luckObligation.ObligationNumber , new CreditCardPayment(cmd.AmountToPay) , cmd.AmountToPay , "CreditCard Payment Applied To Dues" ); Persist(@event, s => { _accountState = _accountState.ApplyEvent(@event); Self.Tell(new PublishAccountStateToKafka()); ApplySnapShotStrategy(); Sender.Tell(new MyAccountStatus("Payment Applied", (AccountState)_accountState.Clone())); }); } catch (Exception e) { _log.Error($"[ProcessPayment]: {e.Message} {e.StackTrace}"); throw; } }