private static ProcessingRulEngStore OperationDxProcessing(this ProcessingRulEngStore newState, List <Guid> ruleResultIds, List <Operation> operationprescriptionsToProcessList, List <EntMatch> acceptableDestinations) { foreach (var ruleResultIdToProcess in ruleResultIds) { // Get all of the operations relevant to the Rule var relevantOps = operationprescriptionsToProcessList .Where(o => o.RuleResultId == ruleResultIdToProcess) .ToList(); if (!relevantOps.Any()) { // TODO: confirm if we should be doing this if there was nothing relevant to process //newState.RuleResults.RemoveWhere(r => r.RuleResultId == ruleResultIdToProcess); continue; } // Process the acceptable foreach (var relevantOp in relevantOps) { var firstEnt = new EntMatch { EntityId = relevantOp.Operands[0].EntityId, EntType = relevantOp.Operands[0].EntType }; if (!acceptableDestinations.Any(ad => ad.EntType == firstEnt.EntType && ad.EntityId == firstEnt.EntityId)) { continue; } //Console.WriteLine(result); switch (firstEnt.EntType) { case EntityType.Rule: var removeRl = newState.Rules.FirstOrDefault(r => r.RuleId == firstEnt.EntityId); var removeRr = newState.RuleResults.FirstOrDefault(r => r.RuleId == firstEnt.EntityId); var rrId = removeRr.RuleResultId; newState.Rules.Remove(removeRl); newState.RuleResults.Remove(removeRr); // The directly dependent Operations and Requests are now orphaned // They should be deleted, they will never execute again var removeOp = newState.Operations.Where(o => o.RuleResultId == rrId); var removeRq = newState.Requests.Where(r => r.RuleResultId == rrId); foreach (var op in removeOp) { newState.Operations.Remove(op); } foreach (var rq in removeRq) { newState.Requests.Remove(rq); } break; case EntityType.Operation: newState.Operations.RemoveWhere(r => r.OperationId == firstEnt.EntityId); break; case EntityType.Request: newState.Requests.RemoveWhere(r => r.RequestId == firstEnt.EntityId); break; case EntityType.Value: var removeVal = newState.Values.FirstOrDefault(v => v.ValueId == firstEnt.EntityId); newState.Values.Remove(removeVal); break; } // Mark the operation as Executed var actionDate = DateTime.UtcNow; // Mark this Rule as executed relevantOp.LastExecuted = actionDate; } // newState.RuleResults.RemoveWhere(r => r.RuleResultId == ruleResultIdToProcess); } return(newState); }
private static ProcessingRulEngStore OperationMxProcessing(this ProcessingRulEngStore newState, RulEngStore previousState, List <Guid> ruleResultIds, List <Operation> operationprescriptionsToProcessList, List <EntMatch> acceptableDestinations) { // Get all of the sources from the previous state var acceptableSourceIds = new List <Guid>(); foreach (var opPresProc in operationprescriptionsToProcessList) { var opPresOperands = opPresProc.Operands; var matchFound = false; foreach (var opo in opPresOperands) { if (!acceptableDestinations .Any(ad => ad.EntType == opo.EntType && ad.EntityId == opo.EntityId)) { continue; } matchFound = true; break; } if (!matchFound) { continue; } acceptableSourceIds.AddRange(opPresOperands.SelectMany(oo => oo.SourceEntityIds)); } var acceptableSources = previousState.Values .Where(v => acceptableSourceIds.Contains(v.EntityId)) .ToList(); var e = new Engine(); var regexToken = new Regex(@".*?(?<Token>\$\{(?<Index>\d+)\}).*?"); foreach (var ruleResultIdToProcess in ruleResultIds) { // Get all of the operations relevant to the Rule var relevantOps = operationprescriptionsToProcessList .Where(o => o.RuleResultId == ruleResultIdToProcess) .ToList(); if (!relevantOps.Any()) { // TODO: confirm if we should be doing this if there was nothing relevant to process //newState.RuleResults.RemoveWhere(r => r.RuleResultId == ruleResultIdToProcess); continue; } // Process the acceptable foreach (var relevantOp in relevantOps) { // Ensure the first entity in the operation is an acceptable destination EntMatch firstEnt = relevantOp.Operands[0]; if (!acceptableDestinations.Any(ad => ad.EntType == firstEnt.EntType && ad.EntityId == firstEnt.EntityId)) { continue; } var destEntsToProcess = relevantOp.Operands .Select(de => new { de.EntityId, EntType = Convert.ToInt32(de.EntType), sourceValues = de.SourceEntityIds .Select(sv => JObject.Parse($"{{\"Id\":\"{sv}\",\"Value\":{acceptableSources.FirstOrDefault(a => a.EntityId == sv)?.Detail.ToString(Formatting.None)}}}")) .ToArray() }) .ToList(); var jTempl = relevantOp.OperationTemplate; var jCode = jTempl; foreach (var destEnt in destEntsToProcess) { var sourceVals = destEnt.sourceValues; var isSubstOk = true; foreach (Match match in regexToken.Matches(jTempl)) { var token = match.Groups["Token"].Value; var indexOk = int.TryParse(match.Groups["Index"].Value, out var index); if (!indexOk) { break; } if (sourceVals.Length < index) { isSubstOk = false; break; } jCode = jCode.Replace(token, sourceVals[index]["Value"].ToString(Formatting.None)); } if (!isSubstOk) { Console.WriteLine(jCode); continue; } JToken result = null; if (jCode.StartsWith("{")) { result = JObject.FromObject(e.Execute(jCode).GetCompletionValue().ToObject()); } if (jCode.StartsWith("[")) { result = JArray.FromObject(e.Execute(jCode).GetCompletionValue().ToObject()); } //Console.WriteLine(result); switch ((EntityType)destEnt.EntType) { case EntityType.Rule: // Create/Update a rule using destEnt.EntityId and result newState.FromOperationResultAddUpdateRule(result, destEnt.EntityId); break; case EntityType.Operation: // Create/Update an Operation using destEnt.EntityId and result newState.FromOperationResultAddUpdateOperation(result, destEnt.EntityId); break; case EntityType.Request: // Create/Update a Request using destEnt.EntityId and result newState.FromOperationResultAddUpdateRequest(result, destEnt.EntityId); break; case EntityType.Value: // Create/Update a Value using destEnt.EntityId and result newState.FromOperationResultAddUpdateValue(result, destEnt.EntityId); break; } // Mark the operation as Executed var actionDate = DateTime.UtcNow; // Mark this Rule as executed relevantOp.LastExecuted = actionDate; } } // newState.RuleResults.RemoveWhere(r => r.RuleResultId == ruleResultIdToProcess); } return(newState); }