/// <summary>
        /// CTOR
        /// </summary>
        /// <param name="variable">The execution variable to be added to the decision result</param>
        /// <param name="multipleHitRules">The decision table rules with positive hit to be added to the decision result</param>
        public DmnDecisionSingleResult(DmnExecutionVariable variable, IEnumerable <DmnDecisionTableRule> multipleHitRules) : this(variable)
        {
            if (multipleHitRules == null)
            {
                throw new ArgumentNullException(nameof(multipleHitRules));
            }

            HitRulesInternal.AddRange(multipleHitRules);
        }
        /// <summary>
        /// CTOR
        /// </summary>
        /// <param name="variable">The execution variable to be added to the decision result</param>
        public DmnDecisionSingleResult(DmnExecutionVariable variable)
        {
            if (variable == null)
            {
                throw new ArgumentNullException(nameof(variable));
            }

            VariablesInternal.Add(new DmnResultVariable(variable));
        }
        /// <summary>
        /// CTOR
        /// </summary>
        /// <param name="variable">The execution variable to be added to the decision result</param>
        /// <param name="hitRule">The decision table rule with positive hit to be added to the decision result</param>
        public DmnDecisionSingleResult(DmnExecutionVariable variable, DmnDecisionTableRule hitRule) : this(variable)

        {
            if (hitRule == null)
            {
                throw new ArgumentNullException(nameof(hitRule));
            }

            HitRulesInternal.Add(hitRule);
        }
Exemple #4
0
        /// <summary>
        /// Evaluates the output expressions for  positive rules and stores generates the table execution results ( (rule, output)-&gt;temp variable with result)
        /// </summary>
        /// <param name="context">Engine execution context</param>
        /// <param name="executionId">Identifier of the execution run</param>
        /// <param name="positiveRules">List of positive rules</param>
        /// <returns>Table execution results</returns>
        private DmnDecisionTableRuleExecutionResults EvaluateOutputsForPositiveRulesParallel(DmnExecutionContext context, string executionId, IEnumerable <DmnDecisionTableRule> positiveRules)
        {
            Logger.InfoCorr(executionId, $"Evaluating decision table {Name} positive rules outputs...");
            var results         = new DmnDecisionTableRuleExecutionResultsParallel();
            var rulesAndOutputs = positiveRules.SelectMany(
                r => r.Outputs,
                (rule, output) => new { rule, output });

            Parallel.ForEach(rulesAndOutputs, ruleAndOutput =>


            {
                var positiveRule = ruleAndOutput.rule;
                var ruleOutput   = ruleAndOutput.output;

                if (string.IsNullOrWhiteSpace(ruleOutput.Expression))
                {
                    results.SetResult(positiveRule, ruleOutput, null);
                }
                else
                {
                    var result = context.EvalExpression(ruleOutput.Expression,
                                                        ruleOutput.Output.Variable.Type ?? typeof(object),
                                                        executionId);

                    // check allowed output values
                    var allowedValues = ruleOutput.Output.AllowedValues;
                    if (allowedValues != null && allowedValues.Length > 0 &&
                        !string.IsNullOrWhiteSpace(result?.ToString()))
                    {
                        if (!ruleOutput.Output.AllowedValues.Contains(result.ToString()))
                        {
                            throw Logger.ErrorCorr <DmnExecutorException>(
                                executionId,
                                $"Decision table {Name}, rule {positiveRule}: Output value '{result}' is not in allowed values list ({string.Join(",", allowedValues)})");
                        }
                    }

                    var output = new DmnExecutionVariable(ruleOutput.Output.Variable)
                    {
                        Value = result
                    };
                    results.SetResult(positiveRule, ruleOutput, output);
                    if (Logger.IsTraceEnabled)
                    {
                        Logger.TraceCorr(executionId,
                                         $"Positive decision table {Name} rule {positiveRule}: output {output.Name}, value {output.Value}");
                    }
                }
            });

            Logger.InfoCorr(executionId, $"Evaluated decision table {Name} positive rules outputs");
            return(results.FinalizeConcurrentResults());
        }
        /// <summary>
        /// CTOR
        /// </summary>
        /// <param name="executionVariable">Execution variable to build the result variable from</param>
        /// <exception cref="ArgumentNullException"><paramref name="executionVariable"/> is null</exception>
        /// <exception cref="ArgumentException">Missing variable name in <paramref name="executionVariable"/></exception>
        public DmnResultVariable(DmnExecutionVariable executionVariable)
        {
            if (executionVariable == null)
            {
                throw new ArgumentNullException(nameof(executionVariable));
            }
            if (string.IsNullOrWhiteSpace(executionVariable.Name?.Trim()))
            {
                throw new ArgumentException("Missing variable name", nameof(executionVariable));
            }

            Name             = executionVariable.Name;
            Type             = executionVariable.Type;
            IsInputParameter = executionVariable.IsInputParameter;
            Value            = executionVariable.Value;
        }
        /// <summary>
        /// Evaluates the output expressions for  positive rules and stores generates the table execution results ( (rule, output)-&gt;temp variable with result)
        /// </summary>
        /// <param name="context">Engine execution context</param>
        /// <param name="correlationId">Correlation ID used for logging</param>
        /// <param name="positiveRules">List of positive rules</param>
        /// <returns>Table execution results</returns>
        private DmnDecisionTableRuleExecutionResults EvaluateOutputsForPositiveRules(DmnExecutionContext context, string correlationId, IEnumerable <DmnDecisionTableRule> positiveRules)
        {
            Logger.InfoCorr(correlationId, $"Evaluating decision table {Name} positive rules outputs...");
            var results = new DmnDecisionTableRuleExecutionResults();

            foreach (var positiveRule in positiveRules)
            {
                //outputs
                foreach (var ruleOutput in positiveRule.Outputs)
                {
                    if (string.IsNullOrWhiteSpace(ruleOutput.Expression))
                    {
                        results.SetResult(positiveRule, ruleOutput, null);
                        continue;
                    }

                    var result = context.EvalExpression(ruleOutput.Expression, ruleOutput.Output.Variable.Type ?? typeof(object));

                    // check allowed output values
                    var allowedValues = ruleOutput.Output.AllowedValues;
                    if (allowedValues != null && allowedValues.Count > 0 &&
                        !string.IsNullOrWhiteSpace(result?.ToString()))
                    {
                        if (!ruleOutput.Output.AllowedValues.Contains(result.ToString()))
                        {
                            throw Logger.ErrorCorr <DmnExecutorException>(
                                      correlationId,
                                      $"Decision table {Name}, rule {positiveRule}: Output value '{result}' is not in allowed values list ({string.Join(",", allowedValues)})");
                        }
                    }

                    var output = new DmnExecutionVariable(ruleOutput.Output.Variable)
                    {
                        Value = result
                    };
                    results.SetResult(positiveRule, ruleOutput, output);
                    if (Logger.IsTraceEnabled)
                    {
                        Logger.TraceCorr(correlationId,
                                         $"Positive decision table {Name} rule {positiveRule}: output {output.Name}, value {output.Value}");
                    }
                }
            }

            Logger.InfoCorr(correlationId, $"Evaluated decision table {Name} positive rules outputs");
            return(results);
        }