public AbstractWonkaOrchestrator(T poCommand, StringBuilder psRules, OrchestrationInitData poOrchInitData, string psGroveId = "", uint pnGroveIndex = 0) { msRulesContents = psRules; Init(poCommand, poOrchInitData); moInitData = poOrchInitData; moRulesEngine = new WonkaBreRulesEngine(msRulesContents, poOrchInitData.BlockchainDataSources, poOrchInitData.BlockchainCustomOpFunctions, poOrchInitData.AttributesMetadataSource, true); if (!String.IsNullOrEmpty(psGroveId) && (pnGroveIndex > 0)) { moRulesEngine.GroveId = psGroveId; moRulesEngine.GroveIndex = pnGroveIndex; } if (poOrchInitData.DefaultBlockchainDataSource != null) { moRulesEngine.DefaultSource = poOrchInitData.DefaultBlockchainDataSource.SourceId; } SerializeRulesEngineToBlockchain(); }
private void SerializeRulesEngineToBlockchain() { WonkaRefEnvironment RefEnv = WonkaRefEnvironment.GetInstance(); // Creating an instance of the rules engine using our rules and the metadata moRulesEngine = new WonkaBreRulesEngine(new StringBuilder(msRulesContents), moMetadataSource); var contract = GetContract(); var hasRuleTreeFunction = contract.GetFunction(CONST_CONTRACT_FUNCTION_HAS_RT); // Out of gas exception // var gas = new Nethereum.Hex.HexTypes.HexBigInteger(1000000); var gas = hasRuleTreeFunction.EstimateGasAsync(this.msSenderAddress).Result; bool bTreeAlreadyExists = hasRuleTreeFunction.CallAsync <bool>(this.msSenderAddress, gas, null, this.msSenderAddress).Result; if (!bTreeAlreadyExists) { moRulesEngine.Serialize(msSenderAddress, msPassword, msSenderAddress, msContractAddress, msAbiWonka); } }
public void HandleEvents(WonkaBreRulesEngine poRulesEngine, RuleTreeReport poRuleTreeReport) { var ruleTreeLog = RuleTreeEvents.GetFilterChanges <CallRuleTreeEvent>(RuleTreeEventFilter).Result; var ruleSetLog = RuleSetEvents.GetFilterChanges <CallRuleSetEvent>(RuleSetEventFilter).Result; var ruleLog = RuleEvents.GetFilterChanges <CallRuleEvent>(RuleEventFilter).Result; var ruleSetErrLog = RuleSetErrorEvents.GetFilterChanges <RuleSetErrorEvent>(RuleSetErrorEventFilter).Result; /** * if (ruleTreeLog.Count > 0) * System.Console.WriteLine("RuleTree Called that Belongs to : (" + ruleTreeLog[0].Event.TreeOwner + ")"); **/ if (ruleSetLog.Count > 0) { foreach (EventLog <CallRuleSetEvent> TmpRuleSetEvent in ruleSetLog) { if (TmpRuleSetEvent.Event != null) { poRuleTreeReport.RuleSetIds.Add(TmpRuleSetEvent.Event.RuleSetId); } } } if (ruleLog.Count > 0) { foreach (EventLog <CallRuleEvent> TmpRuleEvent in ruleLog) { if (TmpRuleEvent.Event != null) { poRuleTreeReport.RuleIds.Add(TmpRuleEvent.Event.RuleId); // TmpRuleEvent.Event.RuleType } } } if (ruleSetErrLog.Count > 0) { foreach (EventLog <RuleSetErrorEvent> TmpRuleSetError in ruleSetErrLog) { if (TmpRuleSetError.Event != null) { if (TmpRuleSetError.Event.SevereFailure) { poRuleTreeReport.RuleSetFailures.Add(TmpRuleSetError.Event.RuleSetId); } else { poRuleTreeReport.RuleSetWarnings.Add(TmpRuleSetError.Event.RuleSetId); } } } } }
public AbstractWonkaValidator(T poCommand, StringBuilder psRules, string psWeb3HttpUrl = null, bool bDeployEngineToBlockchain = false) { BlockchainEngine = new WonkaBlockchainEngine(); BlockchainEngineOwner = ""; msRulesFilepath = null; msRulesContents = psRules; msWeb3HttpUrl = psWeb3HttpUrl; Init(); moRulesEngine = new WonkaBreRulesEngine(msRulesContents); }
public WonkaBreXmlReader(StringBuilder psBreXml, IMetadataRetrievable piMetadataSource = null, WonkaBreRulesEngine poRulesHostEngine = null) { if ((psBreXml == null) || (psBreXml.Length <= 0)) { throw new WonkaBreException(-1, -1, "ERROR! The rules file provided is null."); } BreXmlFilepath = null; BreXmlContents = psBreXml.ToString(); RulesHostEngine = poRulesHostEngine; Init(piMetadataSource); }
private void SerializeRulesEngineToBlockchain(WonkaBreRulesEngine poEngine) { var contract = GetContract(); var hasRuleTreeFunction = contract.GetFunction(CONST_CONTRACT_FUNCTION_HAS_RT); var gas = hasRuleTreeFunction.EstimateGasAsync(this.msSenderAddress).Result; bool bTreeAlreadyExists = hasRuleTreeFunction.CallAsync <bool>(this.msSenderAddress, gas, null, this.msSenderAddress).Result; if (!bTreeAlreadyExists) { poEngine.Serialize(msSenderAddress, msPassword, msSenderAddress, msContractAddress, msAbiWonka); } }
public void Execute() { // Using the metadata source, we create an instance of a defined data domain WonkaRefEnvironment RefEnv = WonkaRefEnvironment.GetInstance(); // To test whether the data domain has been created, we plan on retrieving the value // of the "AccountStatus" Attribute WonkaRefAttr AccountStsAttr = RefEnv.GetAttributeByAttrName("AccountStatus"); // Creating an instance of the rules engine using our rules and the metadata WonkaBreRulesEngine RulesEngine = new WonkaBreRulesEngine(new StringBuilder(msRulesContents), moMetadataSource); // Gets a predefined data record that will be our analog for new data coming into the system WonkaProduct NewProduct = GetNewProduct(); // Check that the data has been populated correctly on the "new" record - also, we will use // it later for comparison purposes string sStatusValueBefore = GetAttributeValue(NewProduct, AccountStsAttr); // Since the rules can reference values from different records (like O.Price for the existing // record's price and N.Price for the new record's price), we need to provide the delegate // that can pull the existing (i.e., old) record from the blockchain using a key RulesEngine.GetCurrentProductDelegate = GetOldProduct; // Validate the new record using our rules engine and its initialized RuleTree WonkaBre.Reporting.WonkaBreRuleTreeReport Report = RulesEngine.Validate(NewProduct); // Now retrieve the AccountStatus value and see if the rules have altered it (which should // not be the case) string sStatusValueAfter = GetAttributeValue(NewProduct, AccountStsAttr); // We will evaluate whether or not any failures of the rules were detected during the engine's execution if (Report.OverallRuleTreeResult == ERR_CD.CD_SUCCESS) { // If successful, we will write the record back into the contract on the blockchain Serialize(NewProduct); } else if (Report.GetRuleSetFailureCount() > 0) { throw new Exception("Oh heavens to Betsy! Something bad happened!"); } else { throw new Exception("What in the world is happening?!"); } }
public WonkaBreXmlReader(string psBreXmlFilepath, IMetadataRetrievable piMetadataSource = null, WonkaBreRulesEngine poRulesHostEngine = null) { if (String.IsNullOrEmpty(psBreXmlFilepath)) { throw new WonkaBreException(-1, -1, "ERROR! The rules file provided is null."); } if (!File.Exists(psBreXmlFilepath)) { throw new WonkaBreException(-1, -1, "ERROR! The rules file(" + psBreXmlFilepath + ") does not exist."); } BreXmlFilepath = psBreXmlFilepath; BreXmlContents = null; RulesHostEngine = poRulesHostEngine; Init(piMetadataSource); }
private static string GetCurrentBlockNum(WonkaBreRulesEngine poEngine, string psUnusedVal) { string sCurrBlockNum = ""; if (EngineWeb3Accounts.ContainsKey(poEngine)) { Nethereum.Web3.Web3 EngineWeb3 = EngineWeb3Accounts[poEngine]; sCurrBlockNum = EngineWeb3.Eth.Blocks.GetBlockNumber.SendRequestAsync().Result.HexValue.ToString(); } if (sCurrBlockNum.HasHexPrefix()) { sCurrBlockNum = sCurrBlockNum.RemoveHexPrefix(); } return(sCurrBlockNum); }
public async Task <RuleTreeReport> ExecuteWithReportAsync(WonkaBreRulesEngine poRulesEngine, bool pbValidateWithinTransaction) { WonkaRefEnvironment RefEnv = WonkaRefEnvironment.GetInstance(); WonkaRefAttr CurrValueAttr = RefEnv.GetAttributeByAttrName("AccountCurrValue"); WonkaRefAttr ReviewFlagAttr = RefEnv.GetAttributeByAttrName("AuditReviewFlag"); var contract = GetContract(); var senderAddress = moEthEngineInit.EthSenderAddress; var executeWithReportFunction = contract.GetFunction(CONST_CONTRACT_FUNCTION_EXEC_RPT); RuleTreeReport ruleTreeReport = null; if (pbValidateWithinTransaction) { var FlagSource = poRulesEngine.SourceMap[ReviewFlagAttr.AttrName]; var CurrValSource = poRulesEngine.SourceMap[CurrValueAttr.AttrName]; var executeGetLastReportFunction = contract.GetFunction(CONST_CONTRACT_FUNCTION_GET_LAST_RPT); string sFlagBeforeOrchestrationAssignment = await RetrieveValueMethodAsync(FlagSource, ReviewFlagAttr.AttrName).ConfigureAwait(false); string sValueBeforeOrchestrationAssignment = await RetrieveValueMethodAsync(CurrValSource, CurrValueAttr.AttrName).ConfigureAwait(false); var EthRuleTreeReport = new WonkaEth.Extensions.RuleTreeReport(); await poRulesEngine.ExecuteOnChainAsync(moEthEngineInit, EthRuleTreeReport).ConfigureAwait(false); string sFlagAfterOrchestrationAssignment = await RetrieveValueMethodAsync(FlagSource, ReviewFlagAttr.AttrName).ConfigureAwait(false); string sValueAfterOrchestrationAssignment = await RetrieveValueMethodAsync(CurrValSource, CurrValueAttr.AttrName).ConfigureAwait(false); ruleTreeReport = await executeGetLastReportFunction.CallDeserializingToObjectAsync <RuleTreeReport>().ConfigureAwait(false); } else { ruleTreeReport = await executeWithReportFunction.CallDeserializingToObjectAsync <RuleTreeReport>(senderAddress).ConfigureAwait(false); } return(ruleTreeReport); }
public RuleTreeReport ExecuteWithReport(WonkaBreRulesEngine poRulesEngine, bool pbValidateWithinTransaction) { WonkaRefEnvironment RefEnv = WonkaRefEnvironment.GetInstance(); WonkaRefAttr CurrValueAttr = RefEnv.GetAttributeByAttrName("AccountCurrValue"); WonkaRefAttr ReviewFlagAttr = RefEnv.GetAttributeByAttrName("AuditReviewFlag"); Dictionary <string, string> PrdKeys = new Dictionary <string, string>(); var contract = GetContract(); var senderAddress = moEthEngineInit.EthSenderAddress; var executeWithReportFunction = contract.GetFunction(CONST_CONTRACT_FUNCTION_EXEC_RPT); RuleTreeReport ruleTreeReport = null; if (pbValidateWithinTransaction) { var FlagSource = poRulesEngine.SourceMap[ReviewFlagAttr.AttrName]; var CurrValSource = poRulesEngine.SourceMap[CurrValueAttr.AttrName]; var executeGetLastReportFunction = contract.GetFunction(CONST_CONTRACT_FUNCTION_GET_LAST_RPT); WonkaProduct OrchContractCurrValues = poRulesEngine.AssembleCurrentProduct(new Dictionary <string, string>()); string sFlagBeforeOrchestrationAssignment = RetrieveValueMethod(FlagSource, ReviewFlagAttr.AttrName); string sValueBeforeOrchestrationAssignment = RetrieveValueMethod(CurrValSource, CurrValueAttr.AttrName); var EthRuleTreeReport = new WonkaEth.Extensions.RuleTreeReport(); poRulesEngine.ExecuteOnChain(moEthEngineInit, EthRuleTreeReport); string sFlagAfterOrchestrationAssignment = RetrieveValueMethod(FlagSource, ReviewFlagAttr.AttrName); string sValueAfterOrchestrationAssignment = RetrieveValueMethod(CurrValSource, CurrValueAttr.AttrName); ruleTreeReport = executeGetLastReportFunction.CallDeserializingToObjectAsync <RuleTreeReport>().Result; } else { ruleTreeReport = executeWithReportFunction.CallDeserializingToObjectAsync <RuleTreeReport>(senderAddress).Result; } return(ruleTreeReport); }
public RuleTreeReport ExecuteWithReport(WonkaBreRulesEngine poRulesEngine, bool pbValidateWithinTransaction, WonkaBreSource poFlagSource) { WonkaRefEnvironment RefEnv = WonkaRefEnvironment.GetInstance(); WonkaRefAttr CurrValueAttr = RefEnv.GetAttributeByAttrName("AccountCurrValue"); WonkaRefAttr ReviewFlagAttr = RefEnv.GetAttributeByAttrName("AuditReviewFlag"); Dictionary <string, string> PrdKeys = new Dictionary <string, string>(); var contract = GetContract(); var executeWithReportFunction = contract.GetFunction(CONST_CONTRACT_FUNCTION_EXEC_RPT); RuleTreeReport ruleTreeReport = null; if (pbValidateWithinTransaction) { var executeGetLastReportFunction = contract.GetFunction(CONST_CONTRACT_FUNCTION_GET_LAST_RPT); // NOTE: Caused exception to be thrown // var gas = executeWithReportFunction.EstimateGasAsync(msSenderAddress).Result; var gas = new Nethereum.Hex.HexTypes.HexBigInteger(1000000); WonkaProduct OrchContractCurrValues = poRulesEngine.AssembleCurrentProduct(new Dictionary <string, string>()); string sFlagBeforeOrchestrationAssignment = RetrieveValueMethod(poFlagSource, ReviewFlagAttr.AttrName); string sValueBeforeOrchestrationAssignment = RetrieveValueMethod(poFlagSource, CurrValueAttr.AttrName); var receiptAddAttribute = executeWithReportFunction.SendTransactionAsync(msSenderAddress, gas, null, msSenderAddress).Result; string sFlagAfterOrchestrationAssignment = RetrieveValueMethod(poFlagSource, ReviewFlagAttr.AttrName); string sValueAfterOrchestrationAssignment = RetrieveValueMethod(poFlagSource, CurrValueAttr.AttrName); ruleTreeReport = executeGetLastReportFunction.CallDeserializingToObjectAsync <RuleTreeReport>().Result; } else { ruleTreeReport = executeWithReportFunction.CallDeserializingToObjectAsync <RuleTreeReport>(msSenderAddress).Result; } return(ruleTreeReport); }
/// <summary> /// /// This method will register the default set of standard operations (especially Nethereum-related ones) that can be /// invoked from within the Wonka rules engine /// /// <param name="poEngine">The target instance of an engine</param> /// <returns>None</returns> /// </summary> public static void SetDefaultStdOps(this WonkaBreRulesEngine poEngine, string psPassword, string psWeb3HttpUrl = null) { var account = new Account(psPassword); Nethereum.Web3.Web3 web3 = null; if (!String.IsNullOrEmpty(psWeb3HttpUrl)) { web3 = new Nethereum.Web3.Web3(account, psWeb3HttpUrl); } else { web3 = new Nethereum.Web3.Web3(account); } EngineWeb3Accounts[poEngine] = web3; Dictionary <STD_OP_TYPE, WonkaBreRulesEngine.RetrieveStdOpValDelegate> DefaultStdOpMap = new Dictionary <STD_OP_TYPE, WonkaBreRulesEngine.RetrieveStdOpValDelegate>(); DefaultStdOpMap[STD_OP_TYPE.STD_OP_BLOCK_NUM] = GetCurrentBlockNum; poEngine.StdOpMap = DefaultStdOpMap; }
public void Execute() { // Using the metadata source, we create an instance of a defined data domain WonkaRefEnvironment RefEnv = WonkaRefEnvironment.CreateInstance(false, moMetadataSource); // To test whether the data domain has been created, we pull back one attribute WonkaRefAttr AccountStsAttr = RefEnv.GetAttributeByAttrName("AccountStatus"); // Creating an instance of the rules engine using our rules and the metadata WonkaBreRulesEngine RulesEngine = new WonkaBreRulesEngine(new StringBuilder(msRulesContents), moMetadataSource); // Gets a predefined data record that will be our analog for new data coming into the system WonkaProduct NewProduct = GetNewProduct(); // Check that the data has been populated correctly on the "new" record string sStatusValueBefore = GetAttributeValue(NewProduct, AccountStsAttr); // Since the rules can reference values from different records (like O.Price for the existing // record's price and N.Price for the new record's price), we need to provide the delegate // that can pull the existing (i.e., old) record using a key RulesEngine.GetCurrentProductDelegate = GetOldProduct; // Validate the new record using our rules engine and its initialized RuleTree WonkaBre.Reporting.WonkaBreRuleTreeReport Report = RulesEngine.Validate(NewProduct); // Now retrieve the AccountStatus value and see if the rules have altered it (which should // not be the case) string sStatusValueAfter = GetAttributeValue(NewProduct, AccountStsAttr); if (Report.GetRuleSetFailureCount() > 0) { throw new Exception("Oh heavens to Betsy! Something bad happened!"); } }
public void Execute(string psOrchestrationTestAddress = null, bool pbValidateWithinTransaction = false) { WonkaRefEnvironment RefEnv = WonkaRefEnvironment.GetInstance(); Dictionary <string, WonkaBre.RuleTree.WonkaBreSource> SourceMap = new Dictionary <string, WonkaBre.RuleTree.WonkaBreSource>(); string sDefaultSource = "S"; string sContractSourceId = sDefaultSource; string sContractAddress = ""; string sContractAbi = ""; string sOrchGetterMethod = ""; string sOrchSetterMethod = ""; // If a 'psOrchestrationTestAddress' value has been provided, it indicates that the user wishes // to use Orchestration if (!String.IsNullOrEmpty(psOrchestrationTestAddress)) { // Here we set the values for Orchestration (like the target contract) and the implemented // methods that have the expected function signatures for getting/setting Attribute values sContractAddress = psOrchestrationTestAddress; sContractAbi = msAbiOrchTest; sOrchGetterMethod = "getAttrValueBytes32"; sOrchSetterMethod = "setAttrValueBytes32"; } else { sContractAddress = msContractAddress; sContractAbi = msAbiWonka; sOrchGetterMethod = "getValueOnRecord"; sOrchSetterMethod = ""; } // Here a mapping is created, where each Attribute points to a specific contract and its "accessor" methods // - the class that contains this information (contract, accessors, etc.) is of the WonkaBreSource type foreach (WonkaRefAttr TempAttr in moTargetAttrList) { WonkaBreSource TempSource = new WonkaBreSource(sContractSourceId, msSenderAddress, msPassword, sContractAddress, sContractAbi, sOrchGetterMethod, sOrchSetterMethod, RetrieveValueMethod); SourceMap[TempAttr.AttrName] = TempSource; } // Creating an instance of the rules engine using our rules and the metadata WonkaBreRulesEngine RulesEngine = null; if (psOrchestrationTestAddress == null) { RulesEngine = new WonkaBreRulesEngine(new StringBuilder(msRulesContents), moMetadataSource); } else { RulesEngine = new WonkaBreRulesEngine(new StringBuilder(msRulesContents), SourceMap, moMetadataSource); RulesEngine.DefaultSource = sDefaultSource; } RulesEngine.SetDefaultStdOps(msPassword); // The contract dictates that the RuleTree (and its other info, like the Source mapping) is serialized // to the blockchain before interacting with it SerializeRulesEngineToBlockchain(RulesEngine); WonkaRefAttr AccountStsAttr = RefEnv.GetAttributeByAttrName("AccountStatus"); WonkaRefAttr RvwFlagAttr = RefEnv.GetAttributeByAttrName("AuditReviewFlag"); // Gets a predefined data record that will be our analog for new data coming into the system // We are only using this record to test the .NET implementation WonkaProduct NewProduct = GetNewProduct(); string sStatusValueBefore = GetAttributeValue(NewProduct, AccountStsAttr); string sFlagValueBefore = GetAttributeValue(NewProduct, RvwFlagAttr); // SerializeProductToBlockchain(NewProduct); // Validate that the .NET implementation and the rules markup are both working properly WonkaBre.Reporting.WonkaBreRuleTreeReport Report = RulesEngine.Validate(NewProduct); string sStatusValueAfter = GetAttributeValue(NewProduct, AccountStsAttr); string sFlagValueAfter = GetAttributeValue(NewProduct, RvwFlagAttr); if (Report.OverallRuleTreeResult == ERR_CD.CD_SUCCESS) { // NOTE: This should only be used for further testing // Serialize(NewProduct); } else if (Report.GetRuleSetFailureCount() > 0) { System.Console.WriteLine(".NET Engine says \"Oh heavens to Betsy! Something bad happened!\""); } else { System.Console.WriteLine(".NET Engine says \"What in the world is happening?\""); } // If a 'psOrchestrationTestAddress' value has been provided, it indicates that the user wishes // to use Orchestration if (!String.IsNullOrEmpty(psOrchestrationTestAddress)) { /** ** Now execute the rules engine on the blockchain. ** ** NOTE: Based on the value of the argument 'pbValidateWithinTransaction', we will act accordingly - ** If set to 'true', we issue a call() when we execute the rules engine, since we are only ** looking to validate here. However, if the value if 'false', we issue a sendTransaction() ** so that we can attempts to set values (i.e., change the blockchain) will take effect. ** In that case, we might want to pull back the record afterwards with a subsequent function ** call, in order to examine the record here. ** **/ var BlockchainReport = ExecuteWithReport(RulesEngine, pbValidateWithinTransaction, SourceMap[RvwFlagAttr.AttrName]); if (BlockchainReport.NumberOfRuleFailures == 0) { // Indication of a success } else if (BlockchainReport.NumberOfRuleFailures > 0) { throw new Exception("Oh heavens to Betsy! Something bad happened!"); } else { throw new Exception("Seriously, what in the world is happening?!"); } } }
public void Execute(string psOrchestrationTestAddress = null, bool pbValidateWithinTransaction = false) { WonkaRefEnvironment RefEnv = WonkaRefEnvironment.GetInstance(); Dictionary <string, WonkaBre.RuleTree.WonkaBreSource> SourceMap = new Dictionary <string, WonkaBre.RuleTree.WonkaBreSource>(); string sDefaultSourceId = "S"; string sContractSourceId = sDefaultSourceId; string sContractAddress = ""; string sContractAbi = ""; string sOrchGetterMethod = ""; string sOrchSetterMethod = ""; // These values indicate the Custom Operator "INVOKE_VAT_LOOKUP" which has been used in the markup - // its implementation can be found in the method "lookupVATDenominator" string sCustomOpId = "INVOKE_VAT_LOOKUP"; string sCustomOpMethod = "lookupVATDenominator"; // If a 'psOrchestrationTestAddress' value has been provided, it indicates that the user wishes // to use Orchestration if (!String.IsNullOrEmpty(psOrchestrationTestAddress)) { sContractAddress = psOrchestrationTestAddress; sContractAbi = msAbiOrchTest; sOrchGetterMethod = "getAttrValueBytes32"; sOrchSetterMethod = "setAttrValueBytes32"; } else { sContractAddress = msContractAddress; sContractAbi = msAbiWonka; sOrchGetterMethod = "getValueOnRecord"; sOrchSetterMethod = ""; } WonkaBreSource DefaultSource = new WonkaBreSource(sContractSourceId, msSenderAddress, msPassword, sContractAddress, sContractAbi, sOrchGetterMethod, sOrchSetterMethod, RetrieveValueMethod); // Here a mapping is created, where each Attribute points to a specific contract and its "accessor" methods // - the class that contains this information (contract, accessors, etc.) is of the WonkaBreSource type foreach (WonkaRefAttr TempAttr in moTargetAttrList) { SourceMap[TempAttr.AttrName] = DefaultSource; } Dictionary <string, WonkaBreSource> CustomOpSourceMap = new Dictionary <string, WonkaBreSource>(); // Here a mapping is created, where each Custom Operator points to a specific contract and its "implementation" method // - the class that contains this information (contract, accessors, etc.) is of the WonkaBreSource type WonkaBreSource CustomOpSource = new WonkaBreSource(sCustomOpId, msSenderAddress, msPassword, sContractAddress, sContractAbi, LookupVATDenominator, sCustomOpMethod); CustomOpSourceMap[sCustomOpId] = CustomOpSource; // Creating an instance of the rules engine using our rules and the metadata WonkaBreRulesEngine RulesEngine = new WonkaBreRulesEngine(new StringBuilder(msRulesContents), SourceMap, CustomOpSourceMap, moMetadataSource, false); RulesEngine.DefaultSource = sDefaultSourceId; // The contract dictates that the RuleTree (and its other info, like the Orchestration and CU metadata) // is serialized to the blockchain before interacting with it SerializeRulesEngineToBlockchain(RulesEngine); WonkaRefAttr NewSellTaxAmountAttr = RefEnv.GetAttributeByAttrName("NewSellTaxAmount"); WonkaRefAttr NewVATAmountForHMRCAttr = RefEnv.GetAttributeByAttrName("NewVATAmountForHMRC"); // Gets a predefined data record that will be our analog for new data coming into the system // We are only using this record to test the .NET implementation WonkaProduct NewProduct = GetNewProduct(); string sSellAmtBefore = GetAttributeValue(NewProduct, NewSellTaxAmountAttr); string sVATAmtBefore = GetAttributeValue(NewProduct, NewVATAmountForHMRCAttr); /** ** Test the .NET side */ WonkaBre.Reporting.WonkaBreRuleTreeReport Report = RulesEngine.Validate(NewProduct); string sSellAmtAfter = GetAttributeValue(NewProduct, NewSellTaxAmountAttr); string sVATAmtAfter = GetAttributeValue(NewProduct, NewVATAmountForHMRCAttr); if (Report.OverallRuleTreeResult == ERR_CD.CD_SUCCESS) { // NOTE: This should only be used for further testing // Serialize(NewProduct); } else if (Report.GetRuleSetFailureCount() > 0) { System.Console.WriteLine(".NET Engine says \"Oh heavens to Betsy! Something bad happened!\""); } else { System.Console.WriteLine(".NET Engine says \"What in the world is happening?\""); } // If a 'psOrchestrationTestAddress' value has been provided, it indicates that the user wishes // to use Orchestration if (!String.IsNullOrEmpty(psOrchestrationTestAddress)) { /** ** Now execute the rules engine on the blockchain, using both Orchestration to call accessors ** on other contract(s) and Custom Operators to invoke the "INVOKE_VAT_LOOKUP" operator ** (i.e., the "lookupVATDenominator()" method) implemented on a contract. ** ** NOTE: Based on the value of the argument 'pbValidateWithinTransaction', we will act accordingly - ** If set to 'true', we issue a call() when we execute the rules engine, since we are only ** looking to validate here. However, if the value if 'false', we issue a sendTransaction() ** so that we can attempts to set values (i.e., change the blockchain) will take effect. ** In that case, we might want to pull back the record afterwards with a subsequent function ** call, in order to examine the record here. ** **/ var BlockchainReport = ExecuteWithReport(RulesEngine, pbValidateWithinTransaction, SourceMap[NewSellTaxAmountAttr.AttrName], psOrchestrationTestAddress); if (BlockchainReport.NumberOfRuleFailures == 0) { // Indication of a success } else if (BlockchainReport.NumberOfRuleFailures > 0) { throw new Exception("Oh heavens to Betsy! Something bad happened!"); } else { throw new Exception("Seriously, what in the world is happening?!"); } } }
public RuleTreeReport ExecuteWithReport(WonkaBreRulesEngine poRulesEngine, bool pbValidateWithinTransaction, WonkaBreSource poSource, string psOrchestrationAddress) { WonkaRefEnvironment RefEnv = WonkaRefEnvironment.GetInstance(); WonkaRefAttr NewSellTaxAmountAttr = RefEnv.GetAttributeByAttrName("NewSellTaxAmount"); WonkaRefAttr NewVATAmountForHMRCAttr = RefEnv.GetAttributeByAttrName("NewVATAmountForHMRC"); WonkaRefAttr NewSalesTransSeqAttr = RefEnv.GetAttributeByAttrName("NewSalesTransSeq"); WonkaRefAttr NewSaleVATRateDenomAttr = RefEnv.GetAttributeByAttrName("NewSaleVATRateDenom"); WonkaRefAttr PrevSellTaxAmtAttr = RefEnv.GetAttributeByAttrName("PrevSellTaxAmount"); WonkaRefAttr NewSaleItemTypeAttr = RefEnv.GetAttributeByAttrName("NewSaleItemType"); WonkaRefAttr CountryOfSaleAttr = RefEnv.GetAttributeByAttrName("CountryOfSale"); bool bTestLookupMethod = true; Dictionary <string, string> PrdKeys = new Dictionary <string, string>(); var contract = GetContract(); var executeWithReportFunction = contract.GetFunction(CONST_CONTRACT_FUNCTION_EXEC_RPT); RuleTreeReport ruleTreeReport = null; if (bTestLookupMethod) { var contractOrchTest = GetContractOrchTest(psOrchestrationAddress); var gas = new Nethereum.Hex.HexTypes.HexBigInteger(1000000); var executeLookupFunction = contractOrchTest.GetFunction("lookupVATDenominator"); var lookupValue = executeLookupFunction.CallAsync <string>("Widget", "UK", "", "").Result; var getValOnRecordFunction = contract.GetFunction("getValueOnRecord"); var attrVal = getValOnRecordFunction.CallAsync <string>(poSource.SenderAddress, "NewSaleItemType").Result; } if (pbValidateWithinTransaction) { var executeGetLastReportFunction = contract.GetFunction(CONST_CONTRACT_FUNCTION_GET_LAST_RPT); // NOTE: Caused exception to be thrown // var gas = executeWithReportFunction.EstimateGasAsync(msSenderAddress).Result; var gas = new Nethereum.Hex.HexTypes.HexBigInteger(2000000); WonkaProduct OrchContractCurrValues = poRulesEngine.AssembleCurrentProduct(new Dictionary <string, string>()); string sNSTABeforeOrchestrationAssignment = RetrieveValueMethod(poSource, NewSellTaxAmountAttr.AttrName); string sNVABeforeOrchestrationAssignment = RetrieveValueMethod(poSource, NewVATAmountForHMRCAttr.AttrName); string sNSTSBeforeOrchestrationAssignment = RetrieveValueMethod(poSource, NewSalesTransSeqAttr.AttrName); string sNSVRDBeforeOrchestrationAssignment = RetrieveValueMethod(poSource, NewSaleVATRateDenomAttr.AttrName); string sPSTABeforeOrchestrationAssignment = RetrieveValueMethod(poSource, PrevSellTaxAmtAttr.AttrName); string sNSITDBeforeOrchestrationAssignment = RetrieveValueMethod(poSource, NewSaleItemTypeAttr.AttrName); string sCoSBeforeOrchestrationAssignment = RetrieveValueMethod(poSource, CountryOfSaleAttr.AttrName); var receiptAddAttribute = executeWithReportFunction.SendTransactionAsync(msSenderAddress, gas, null, msSenderAddress).Result; string sNSTAfterOrchestrationAssignment = RetrieveValueMethod(poSource, NewSellTaxAmountAttr.AttrName); string sNVAAfterOrchestrationAssignment = RetrieveValueMethod(poSource, NewVATAmountForHMRCAttr.AttrName); string sNSTSAfterOrchestrationAssignment = RetrieveValueMethod(poSource, NewSalesTransSeqAttr.AttrName); string sNSVRDAfterOrchestrationAssignment = RetrieveValueMethod(poSource, NewSaleVATRateDenomAttr.AttrName); string sPSTAAfterOrchestrationAssignment = RetrieveValueMethod(poSource, PrevSellTaxAmtAttr.AttrName); string sNSITDAfterOrchestrationAssignment = RetrieveValueMethod(poSource, NewSaleItemTypeAttr.AttrName); string sCoSAfterOrchestrationAssignment = RetrieveValueMethod(poSource, CountryOfSaleAttr.AttrName); ruleTreeReport = executeGetLastReportFunction.CallDeserializingToObjectAsync <RuleTreeReport>().Result; } else { ruleTreeReport = executeWithReportFunction.CallDeserializingToObjectAsync <RuleTreeReport>(msSenderAddress).Result; } return(ruleTreeReport); }