public void AddAnswer(String controlId, ControlCatalog catalog, IEnumerable<ControlRule> rules, params Object[] answers) { var date = DateTime.UtcNow; ApplyChange(new ControlAnswered { ControlId = controlId, Date = date, FormId = FormDefinitionId, Id = Guid.NewGuid(), ReportingEntityInstanceId = ReportingEntityId, Version = Version, Values = answers, }); var msgs = ValidateAnswers(controlId, catalog, answers); foreach (var msg in msgs) { if (msg.IsValid) { ApplyChange(new ValidationPassed { ControlId = controlId, Date = date, FormId = FormDefinitionId, Id = Guid.NewGuid(), ReportingEntityInstanceId = ReportingEntityId, Message = msg.Message.Message, Version = Version, Validator = msg.Message.ObjectName, Values = answers, }); } else { ApplyChange(new ValidationFailed { ControlId = controlId, Date = date, FormId = FormDefinitionId, Id = Guid.NewGuid(), ReportingEntityInstanceId = ReportingEntityId, Message = msg.Message.Message, Version = Version, Validator = msg.Message.ObjectName, Values = answers, }); } } RunRules(controlId, catalog, rules, date, answers); }
private static ControlCatalog SetUpFormControls(Guid formId) { var catalog = new ControlCatalog(Guid.NewGuid(), formId, new List<ControlField> { new ControlField("FirstName", new List<String>(), new List<IControlValidator> { new RequiredValidator(), new MaxLengthValidator(new Dictionary<String, Object> { {"maxLength", 10 } }), new MinLengthValidator(new Dictionary<string, object> { { "minLength", 1 } }), }, "String"), new ControlField("LastName", new List<String>(), new List<IControlValidator> { new RequiredValidator(), new MaxLengthValidator(new Dictionary<String, Object> { {"maxLength", 40 } }), new MinLengthValidator(new Dictionary<string, object> { { "minLength", 3 } }), }, "String"), new ControlField("Age", new List<String>(), new List<IControlValidator> { new RequiredValidator(), new NumericValidator() }, "Number"), new ControlField("Email", new List<String>(), new List<IControlValidator> { new RegexValidator(new Dictionary<String, Object> { { "message", "BOO!" }, { "pattern", @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$" } }) }, "String"), new ControlField("FavoriteFood", new List<String>(), new List<IControlValidator> { new MaxLengthValidator(new Dictionary<String, Object> { {"maxLength", 40 } }), new MinLengthValidator(new Dictionary<string, object> { { "minLength", 2 } }), }, "String"), new ControlField("FirstPart", new List<String>(), new List<IControlValidator> { new NumericValidator(), }, "Number"), new ControlField("SecondPart", new List<String>(), new List<IControlValidator> { new NumericValidator(), }, "Number"), }); return catalog; }
private static void PerfLoadNewRei(Guid formId, String rei, Int32 snapInterval, ControlCatalog catalog, IEnumerable<ControlRule> rules) { var newInstance = new ReportingEntityInstance(formId, rei); var fields = new String[]{ "FirstName", "LastName", "Age", "Email", "FavoriteFood" }; Stopwatch sw = new Stopwatch(); Console.WriteLine($"Starting the creation of {rei}"); sw.Start(); for (int i = 0; i < 10000; i++) { var field = fields[i % 5]; newInstance.AddAnswer(field, catalog, rules, "answer" + i.ToString()); EventStore.PersistEvents(_eventCollection, newInstance); if (i > 0 && i%snapInterval == 0) { var snap = newInstance.TakeSnapshot(); EventStore.TakeSnapshot(_snapshotCollection, snap); } } sw.Stop(); Console.WriteLine($"Took {sw.ElapsedMilliseconds} ms to write 10000 answers with interval of {snapInterval}"); sw.Reset(); sw.Start(); var fullInstance = new ReportingEntityInstance(formId, rei); EventStore.LoadDomain(_eventCollection, fullInstance, formId, rei); sw.Stop(); Console.WriteLine($"Took {sw.ElapsedMilliseconds} ms to load domain by replaying events"); sw.Reset(); sw.Start(); var snapInstance = new ReportingEntityInstance(formId, rei); snapInstance.LoadSnapshot(EventStore.GetSnapshot(_snapshotCollection, rei)); EventStore.LoadDomainStartingAtVersion(_eventCollection, snapInstance, formId, rei, snapInstance.Version); sw.Stop(); Console.WriteLine($"Took {sw.ElapsedMilliseconds} ms to load domain from snapshot"); Console.WriteLine("Replay instance status: "); DisplayDomainStatus(fullInstance); Console.WriteLine("Snapshot instance status: "); DisplayDomainStatus(snapInstance); }
private static ReportingEntityInstance LoadDomainUpToVersion(Guid formId, String rei, Int64 maxVersion, ControlCatalog catalog) { var instance = new ReportingEntityInstance(formId, rei); EventStore.LoadDomainUpToVersion(_eventCollection, instance, formId, rei, maxVersion); return instance; }
private void RunRules(String controlId, ControlCatalog catalog, IEnumerable<ControlRule> rules, DateTime now, Object[] answers) { var results = new List<RuleEvaluated>(); var validRules = rules.Where(r => r.ControlId == controlId); var parameters = ControlAnswers.ToDictionary(kvp => kvp.Key, kvp => kvp.Value.Values.First()); foreach (var rule in validRules) { var calc = new NCalc.Expression(rule.Rule.If); foreach (var answer in answers) { calc.Parameters.Clear(); calc.Parameters = parameters; calc.Parameters[controlId] = answer; try { var result = (Boolean)calc.Evaluate(); String message = null; if (result) { switch (rule.Rule.Then.GetType().Name) { case "NoActionOutcome": message = rule.Rule.Then.Message; break; case "FailedValidationOutcome": var outcome = (FailedValidationOutcome)rule.Rule.Then; message = $"{outcome.ValidatorName} failed for {outcome.ControlId} with message {outcome.Message}"; break; default: message = rule.Rule.Then.Message; break; } } else { switch (rule.Rule.Else.GetType().Name) { case "NoActionOutcome": message = rule.Rule.Else.Message; break; case "FailedValidationOutcome": var outcome = (FailedValidationOutcome)rule.Rule.Else; message = $"{outcome.ValidatorName} failed for {outcome.ControlId} with message {outcome.Message}"; break; default: message = rule.Rule.Else.Message; break; } } ApplyChange(new RuleEvaluated { ControlId = controlId, Date = now, FormId = rule.FormId, Id = Guid.NewGuid(), ReportingEntityInstanceId = ReportingEntityId, Result = message, RuleName = rule.Rule.Name, Values = answers, Version = Version }); } catch (Exception e) { Console.WriteLine($"Error in expression: {e.Message}"); } } } }
private IEnumerable<ValidationMessage> ValidateAnswers(String controlId, ControlCatalog catalog, Object[] answers) { var msgs = new List<ValidationMessage>(); var control = catalog.ControlFields.FirstOrDefault(c => c.Name.Equals(controlId, StringComparison.OrdinalIgnoreCase)); if (control == null) { //not found return msgs; } foreach (var val in control.ControlValidations) { foreach (var answer in answers) { var msg = val.Validate(answer); msg.Message.ObjectName = val.GetType().Name; msgs.Add(msg); } } return msgs; }