private void ApplyBusinessRules(BusinessRuleApplicationResultModel resultModel) { Monitor(); /** * Here we can call Business Rules to validate and do whatever. * Then, based on the outcome generated events. * In this example, we are simply going to accept it and updated our state. */ _log.Debug( $"[FetchAccountBusinessRules]: There were {resultModel.GeneratedEvents.Count} events. And success={resultModel.Success}"); if (!resultModel.Success) { _log.Error($"{Self.Path.Name} Business Rule Validation Failure."); Context.Parent.Tell(new FailedAccountBillingAssessment(Self.Path.Name, resultModel)); return; } /* I may want to do old vs new state comparisons for other reasons * but ultimately we just update the state.. */ var events = resultModel.GeneratedEvents; foreach (var @event in events) { Persist(@event, s => { _accountState = _accountState.ApplyEvent(@event); _log.Debug( $"[FetchAccountBusinessRules]: Persisted event {@event.GetType().Name} on account {_accountState.AccountNumber}" + $" account balance after is {_accountState.CurrentBalance:C} "); //ReportMyState(resultModel.TotalBilledAmount, (double) _accountState.CurrentBalance); //Report current state to Kafka Self.Tell(new PublishAccountStateToKafka()); if (_messagesReceived++ % 10000 == 0) { _log.Info( $"AccountActor: FetchAccountBusinessRules()/Persist() {PersistenceId} No. Events {events.Count}."); } ApplySnapShotStrategy(); }); } }
private void DoBusinessLogic(MappedBusinessRules rules) { var resultModel = new BusinessRuleApplicationResultModel { TotalBilledAmount = rules.FetchAccountBusinessRules.TotalBilledAmount }; //TODO what a hack! Ha! try { var pipedState = rules.FetchAccountBusinessRules.AccountState; foreach (var reglaDeNegocio in rules.Rules) { if (reglaDeNegocio == null) { throw new Exception("Why is this business rule null?"); } reglaDeNegocio.SetAccountState(pipedState); reglaDeNegocio.RunRule(rules.FetchAccountBusinessRules.Command); _logger.Debug( $"Found {reglaDeNegocio.GetType().Name} rule for account {rules.FetchAccountBusinessRules.AccountState.AccountNumber}" + $" and its Success={reglaDeNegocio.RuleAppliedSuccessfuly()}"); if (reglaDeNegocio.RuleAppliedSuccessfuly()) { //Save the rule and results into the return model 'resultModel'. resultModel.RuleProcessedResults.Add(reglaDeNegocio, $"Business Rule {reglaDeNegocio.GetType().Name} applied successfully to account " + $"{rules.FetchAccountBusinessRules.AccountState.AccountNumber}. Details: {reglaDeNegocio.GetResultDetails()}"); //Save all the events resulting from runnin this rule. var events = reglaDeNegocio.GetGeneratedEvents().ToList(); foreach (var @event in events) { resultModel.GeneratedEvents.Add(@event); } // Rule output -> next rule input (Pipes & Filters approach) // Replace pipedState wth the state resulting from running the rule. pipedState = (AccountState)(reglaDeNegocio.GetGeneratedState()).Clone(); resultModel.Success = true; _logger.Debug( $"Business Rule {reglaDeNegocio.GetType().Name} applied successfully to account {rules.FetchAccountBusinessRules.AccountState.AccountNumber}"); } else { resultModel.Success = false; resultModel.RuleProcessedResults.Add(reglaDeNegocio, $"Business Rule Failed Application. {reglaDeNegocio.GetResultDetails()}"); _logger.Error($"Business Rule {reglaDeNegocio.GetType().Name} " + $"application failed on account {rules.FetchAccountBusinessRules.AccountState.AccountNumber} " + $"due to {reglaDeNegocio.GetResultDetails()}"); rules.FetchAccountBusinessRules.AccountRef.Tell(resultModel); //we stop processing any further rules. return; } } } catch (Exception e) { _logger.Error($"[DoBusinessLogic]: {e.Message} \n {e.StackTrace}"); throw; } //for each rule in rules // pass the info to the rule and call rule // create event of result of calling rule & apply event to state // return new state rules.FetchAccountBusinessRules.AccountRef.Tell(resultModel); }
public FailedAccountBillingAssessment(string accountNumber, BusinessRuleApplicationResultModel applicationResult) { AccountNumber = accountNumber; ApplicationResult = applicationResult; }