Пример #1
0
        public bool Execute(WonkaProduct poNewTrxRecord)
        {
            bool bResult = false;

            var RulesEngine = moEthEngineInit.Engine.RulesEngine;

            // Validate that the .NET implementation and the rules markup are both working properly
            WonkaBizRuleTreeReport Report = RulesEngine.Validate(poNewTrxRecord);

            if (Report.OverallRuleTreeResult == ERR_CD.CD_SUCCESS)
            {
                bResult = true;
            }
            else if (Report.GetRuleSetFailureCount() > 0)
            {
                bResult = false;
                // NOTE: Notification about the error should be returned
            }
            else
            {
                bResult = false;
            }

            return(bResult);
        }
Пример #2
0
        public static string GetErrors(this WonkaBizRuleTreeReport report)
        {
            var ErrorReport = new StringBuilder();

            foreach (var ReportNode in report.GetRuleSetSevereFailures())
            {
                if (ReportNode.RuleResults.Count > 0)
                {
                    foreach (var RuleReportNode in ReportNode.RuleResults)
                    {
                        if (ErrorReport.Length > 0)
                        {
                            ErrorReport.Append("\n");
                        }

                        ErrorReport.Append(RuleReportNode.VerboseError.Replace("/", ""));
                    }
                }
                else
                {
                    ErrorReport.Append(ReportNode.ErrorDescription);
                }
            }

            return(ErrorReport.ToString());
        }
        public static async Task <string> PublishReportToIpfs(this WonkaBizRuleTreeReport poReport,
                                                              string psIpfsFilePath,
                                                              IpfsService poIpfsService,
                                                              bool pbPinFlag       = true,
                                                              string psIpfsGateway = CONST_INFURA_IPFS_API_GATEWAY_URL)
        {
            string sIpfsHash = "";
            string sReport   = "";

            // NOTE: Not yet ready
            // sReport = poReport.SerializeToXml();
            sReport = poReport.GetErrors();

            if (String.IsNullOrEmpty(psIpfsFilePath))
            {
                psIpfsFilePath = "testreport";
            }

            if (String.IsNullOrEmpty(sReport))
            {
                throw new Exception("ERROR!  No report to be serialized.");
            }

            var IpfsNode =
                await poIpfsService.AddTextAsync(psIpfsGateway, sReport, psIpfsFilePath, pbPinFlag).ConfigureAwait(false);

            sIpfsHash = IpfsNode.Hash.ToString();

            return(sIpfsHash);
        }
Пример #4
0
        /// <summary>
        ///
        /// This method will execute the RuleTree collection of a Grove, invoking each one either on the chain or off the chain.
        /// All of the invocations will be assembled and then returned in a report about the execution of the Grove.
        ///
        /// NOTE: UNDER CONSTRUCTION
        ///
        /// <param name="poGrove">The Grove that we are looking to execute, especially its pool of RuleTree members</param>
        /// <returns>The report that will hold the aggregated reports about the execution of each Grove member</returns>
        /// </summary>
        public static async Task <WonkaBizGroveReport> ExecuteAsync(this WonkaBizGrove poGrove, Wonka.Eth.Init.WonkaEthEngineInitialization poEngineInitData)
        {
            if (poGrove.RuleTreeMembers.Count == 0)
            {
                throw new WonkaEthException("ERROR!  Execute() cannot be invoked for Grove(" + poGrove.GroveDesc + ") when it has no members.");
            }

            if (poEngineInitData == null)
            {
                throw new WonkaEthException("ERROR!  Cannot invoke the Grove(" + poGrove.GroveDesc + ") since the EthEngineInit data provided is empty.");
            }

            var GroveReport = new WonkaBizGroveReport(poGrove);

            foreach (WonkaBizRulesEngine RuleTreeMember in poGrove.RuleTreeMembers)
            {
                if (poGrove.ExecuteRuleTreesOnChain.Contains(RuleTreeMember))
                {
                    var OnChainReport = new Wonka.Eth.Extensions.RuleTreeReport();

                    // NOTE: We assume here that that the Wonka contract instance (mentioned within 'poEngineInitData') and certain RuleTrees of 'poGrove'
                    //       exist on the chain - maybe we should check that fact?

                    string sTrxHash = await RuleTreeMember.ExecuteOnChainAsync(poEngineInitData, OnChainReport).ConfigureAwait(false);

                    GroveReport.RuleTreeReports[RuleTreeMember.DetermineRuleTreeChainID()] = OnChainReport;
                }
                else
                {
                    var OffChainReport = new WonkaBizRuleTreeReport();

                    WonkaProduct CurrValues = new WonkaProduct();

                    bool bResult =
                        await CurrValues.PopulateWithDataFromChainAsync(RuleTreeMember.RefEnvHandle, RuleTreeMember.SourceMap, poEngineInitData.Web3HttpUrl).ConfigureAwait(false);

                    OffChainReport = RuleTreeMember.Validate(CurrValues);

                    GroveReport.RuleTreeReports[RuleTreeMember.DetermineRuleTreeChainID()] = OffChainReport;
                }

                if (poGrove.ExecutionBreakpointDelegate != null)
                {
                    poGrove.ExecutionBreakpointDelegate.Invoke(poGrove, RuleTreeMember);
                }

                if ((GroveReport.GetTotalGasUsed() >= poGrove.MaxGasCostAllowed) && (poGrove.MaxGasCostExceededDelegate != null))
                {
                    poGrove.MaxGasCostExceededDelegate.Invoke(poGrove, RuleTreeMember);
                }
            }

            GroveReport.EndTime = DateTime.Now;

            return(GroveReport);
        }
Пример #5
0
        /// <summary>
        ///
        /// This method will begin the evaluation of a RuleTree when applied to both the incoming and current Product
        /// records.
        ///
        /// <param name="poRootRuleSet">The root RuleSet of the RuleTree whose rules are being applied against the provided records</param>
        /// <param name="poIncomingProduct">The incoming Product record</param>
        /// <param name="poCurrentProduct">The current Product record (i.e., in the database)</param>
        /// <param name="poRuleTreeReport">The report that will contain all evaluations of RuleSets in the RuleTree</param>
        /// <returns>Indicates whether or not the RuleSet evaluated to a success</returns>
        /// </summary>
        public static bool MediateRuleTreeExecution(WonkaBizRuleSet poRootRuleSet,
                                                    WonkaProduct poIncomingProduct,
                                                    WonkaProduct poCurrentProduct,
                                                    WonkaBizRuleTreeReport poRuleTreeReport)
        {
            bool bRuleTreeResult = true;

            bRuleTreeResult =
                MediateRuleSetExecution(poRootRuleSet, poIncomingProduct, poCurrentProduct, poRuleTreeReport);

            // NOTE: Should we do anything else here?

            return(bRuleTreeResult);
        }
Пример #6
0
        /// <summary>
        ///
        /// This method will:
        ///
        /// 1.) Grab the current product by retrieving it through the invocation of th delegate
        /// 2.) Validate the incoming product (and possibly the current product) using the RuleTree initialized in the constructor
        ///
        /// <param name="poIncomingProduct">The product that we are attempting to validate</param>
        /// <returns>Contains a detailed report of the RuleTree's application to the provided product</returns>
        /// </summary>
        public WonkaBizRuleTreeReport Validate(WonkaProduct poIncomingProduct)
        {
            WonkaRefEnvironment         WonkaRefEnv = WonkaRefEnvironment.GetInstance();
            Dictionary <string, string> ProductKeys = GetProductKeys(poIncomingProduct);

            if (poIncomingProduct == null)
            {
                throw new WonkaBizRuleException("ERROR!  Provided incoming product is null!");
            }

            if ((TransactionState != null) && !TransactionState.IsTransactionConfirmed())
            {
                throw new WonkaBizPermissionsException("ERROR!  Pending transaction has not yet been confirmed!", TransactionState);
            }

            WonkaBizRuleTreeReport RuleTreeReport = new WonkaBizRuleTreeReport();

            try
            {
                if (GetCurrentProductDelegate != null)
                {
                    CurrentProductOnDB = GetCurrentProductDelegate.Invoke(ProductKeys);
                }
                else
                {
                    CurrentProductOnDB = new WonkaProduct();
                }

                WonkaBizRuleMediator.MediateRuleTreeExecution(RuleTreeRoot, poIncomingProduct, CurrentProductOnDB, RuleTreeReport);

                /*
                 * NOTE: Do we need anything like this method
                 *
                 * if (PostApplicationDelegate != null)
                 *  PostApplicationDelegate.Invoke(poIncomingProduct, CurrentProductOnDB);
                 */
            }
            finally
            {
                if (TransactionState != null)
                {
                    TransactionState.ClearPendingTransaction();
                }
            }

            RuleTreeReport.EndTime = DateTime.Now;

            return(RuleTreeReport);
        }
Пример #7
0
        public override WonkaBizRuleTreeReport SimulateValidate(AccountUpdateCommand poCommand)
        {
            /**
            ** NOTE: Since the Ethereum engine does not currently support record notation as specified in the markup
            ** (where O.* indicates existing records in the blockchain, N.* indicates new records about to be fed into the blockchain, etc.),
            ** we don't need to actually get an old product from anywhere
            **/
            moRulesEngine.GetCurrentProductDelegate = GetEmptyProduct;

            WonkaProduct NewProduct = GetWonkaProductViaReflection(poCommand);

            WonkaBizRuleTreeReport Report = moRulesEngine.Validate(NewProduct);

            return(Report);
        }
Пример #8
0
        /// <summary>
        ///
        /// This method will apply the Rules of the RuleSet to either one or both of the incoming Product record
        /// and the current Product record.  The collective result of those applied Rules will then determine
        /// whether or not the RuleSet was evaluated as a success.
        ///
        /// <param name="poTargetRuleSet">The RuleSet whose rules are being applied against the provided records</param>
        /// <param name="poIncomingProduct">The incoming Product record</param>
        /// <param name="poCurrentProduct">The current Product record (i.e., in the database)</param>
        /// <param name="poRuleTreeReport">The report that will contain all evaluations of RuleSets in the RuleTree</param>
        /// <param name="poRuleSetErrorMessage">The buffer that will contain an error message if the 'poTargetRuleSet' fails</param>
        /// <returns>Indicates whether or not the RuleSet evaluated to a success</returns>
        /// </summary>
        private static bool MediateRulesExecution(WonkaBizRuleSet poTargetRuleSet,
                                                  WonkaProduct poIncomingProduct,
                                                  WonkaProduct poCurrentProduct,
                                                  WonkaBizRuleTreeReport poRuleTreeReport,
                                                  StringBuilder poRuleSetErrorMessage)
        {
            bool bRuleSetResult = true;

            StringBuilder RuleErrorMsgBuilder = new StringBuilder();
            List <bool>   RuleResultList      = new List <bool>();

            foreach (WonkaBizRule TempRule in poTargetRuleSet.EvaluativeRules)
            {
                bool   bRuleResult      = true;
                string sRuleResult      = string.Empty;
                string sFinalRuleErrMsg = string.Empty;

                RuleErrorMsgBuilder.Clear();
                bRuleResult = TempRule.Execute(poIncomingProduct, poCurrentProduct, RuleErrorMsgBuilder);

                if (TempRule.IsPassive)
                {
                    if (TempRule.NotOperator)
                    {
                        bRuleResult = !bRuleResult;
                    }
                }

                RuleResultList.Add(bRuleResult);

                if (bRuleResult)
                {
                    poRuleSetErrorMessage.Append("SUCCESS");
                }
                else
                {
                    var RuleSetReport =
                        poRuleTreeReport.FindRuleSetReport(poTargetRuleSet.RuleSetId, true);

                    if (RuleSetReport != null)
                    {
                        if (poTargetRuleSet.ErrorSeverity == RULE_SET_ERR_LVL.ERR_LVL_SEVERE)
                        {
                            sRuleResult = "SEVERE";
                            RuleSetReport.SevereFailureCount++;
                        }
                        else
                        {
                            sRuleResult = "WARNING";
                            RuleSetReport.WarningFailureCount++;
                        }
                    }

                    sFinalRuleErrMsg = RuleErrorMsgBuilder.ToString() + " / " + poTargetRuleSet.CustomFailureMsg;
                }

                poRuleTreeReport.ArchiveRuleExecution(TempRule,
                                                      bRuleResult ? ERR_CD.CD_SUCCESS : ERR_CD.CD_FAILURE,
                                                      sRuleResult,
                                                      sFinalRuleErrMsg);
            }

            // Calculate the final outcome of the RuleSet
            if (RuleResultList.Count > 0)
            {
                bRuleSetResult = RuleResultList[0];

                foreach (bool bTempRuleResult in RuleResultList)
                {
                    if (poTargetRuleSet.RulesEvalOperator == RULE_OP.OP_AND)
                    {
                        bRuleSetResult = bRuleSetResult && bTempRuleResult;
                    }
                    else if (poTargetRuleSet.RulesEvalOperator == RULE_OP.OP_OR)
                    {
                        bRuleSetResult = bRuleSetResult || bTempRuleResult;
                    }
                    else
                    {
                        bRuleSetResult = bRuleSetResult && bTempRuleResult;
                    }
                }
            }

            // Only apply the assertive rules if the evaluative rules are applied successfully
            if (bRuleSetResult && (poTargetRuleSet.AssertiveRules.Count() > 0))
            {
                foreach (WonkaBizRule TempRule in poTargetRuleSet.AssertiveRules)
                {
                    bool bRuleResult = true;

                    string sRuleResult      = string.Empty;
                    string sFinalRuleErrMsg = string.Empty;

                    RuleErrorMsgBuilder.Clear();
                    bRuleResult = TempRule.Execute(poIncomingProduct, poCurrentProduct, RuleErrorMsgBuilder);

                    RuleResultList.Add(bRuleResult);

                    poRuleSetErrorMessage.Append("SUCCESS");

                    poRuleTreeReport.ArchiveRuleExecution(TempRule,
                                                          bRuleResult ? ERR_CD.CD_SUCCESS : ERR_CD.CD_FAILURE,
                                                          sRuleResult,
                                                          sFinalRuleErrMsg);
                }
            }

            return(bRuleSetResult);
        }
Пример #9
0
        /// <summary>
        ///
        /// This method helps to direct the navigation of a branch within the RuleTree.  If the rules of 'poTargetRuleSet'
        /// evaluate to a success when applied to the records, then we will continue to traverse the branch by enumerating
        /// through the child branches that sprout from this node (i.e., by calling this method again recursively).  If not,
        /// we will stop the traversal here and return back to the parent node of 'poTargetRuleSet'.
        ///
        /// <param name="poTargetRuleSet">The RuleSet whose rules are being applied against the provided records</param>
        /// <param name="poIncomingProduct">The incoming Product record</param>
        /// <param name="poCurrentProduct">The current Product record (i.e., in the database)</param>
        /// <param name="poRuleTreeReport">The report that will contain all evaluations of RuleSets in the RuleTree</param>
        /// <returns>Indicates whether or not the RuleSet evaluated to a success</returns>
        /// </summary>
        private static bool MediateRuleSetExecution(WonkaBizRuleSet poTargetRuleSet,
                                                    WonkaProduct poIncomingProduct,
                                                    WonkaProduct poCurrentProduct,
                                                    WonkaBizRuleTreeReport poRuleTreeReport)
        {
            bool   bTotalRuleSetResult  = true;
            bool   bTempRulesResult     = true;
            bool   bTempRuleSetResult   = true;
            bool   bTraverseChildren    = true;
            string sGeneralRuleSetError = "ERROR!  One of the rules failed.";

            StringBuilder RuleSetErrorBuilder = new StringBuilder();

            poRuleTreeReport.LastRuleSetExecuted = poTargetRuleSet;

            /*
             * GOOD PLACE FOR TESTING
             *
             * if (!String.IsNullOrEmpty(poTargetRuleSet.Description))
             * {
             *  if (poTargetRuleSet.Description.Contains("Test RuleSet"))
             *  {
             *      int x = 1;
             *  }
             * }
             */

            bTempRulesResult =
                MediateRulesExecution(poTargetRuleSet,
                                      poIncomingProduct,
                                      poCurrentProduct,
                                      poRuleTreeReport,
                                      RuleSetErrorBuilder);

            if (bTempRulesResult)
            {
                poRuleTreeReport.SetRuleSetStatus(poTargetRuleSet.RuleSetId,
                                                  poTargetRuleSet.Description,
                                                  poTargetRuleSet.CustomId,
                                                  ERR_CD.CD_SUCCESS);
            }
            else
            {
                poRuleTreeReport.SetRuleSetStatus(poTargetRuleSet.RuleSetId,
                                                  poTargetRuleSet.Description,
                                                  poTargetRuleSet.CustomId,
                                                  ERR_CD.CD_FAILURE);

                var TargetRuleSetReport = poRuleTreeReport.FindRuleSetReport(poTargetRuleSet.RuleSetId);

                if ((TargetRuleSetReport.SevereFailureCount > 0) || (TargetRuleSetReport.WarningFailureCount > 0))
                {
                    poRuleTreeReport.AddResultSetFailure(poTargetRuleSet, ERR_CD.CD_FAILURE, sGeneralRuleSetError);
                }

                bTraverseChildren = false;
            }

            if (!bTraverseChildren)
            {
                // We should return here, preventing the recursion that will further traverse the branches of the RuleTree
                return(bTotalRuleSetResult);
            }

            foreach (WonkaBizRuleSet ChildRuleSet in poTargetRuleSet.ChildRuleSets)
            {
                bTempRuleSetResult =
                    MediateRuleSetExecution(ChildRuleSet, poIncomingProduct, poCurrentProduct, poRuleTreeReport);

                if (!bTempRuleSetResult)
                {
                    // NOTE: Currently, this condition will never happen...but at some point, should it?
                }
            }

            return(bTotalRuleSetResult);
        }