public WonkaNoviceOnlineChainTest(string psContractAddress, bool pbInitChainEnv = true, bool pbRetrieveMarkupFromIpfs = false) { msSenderAddress = "0x12890D2cce102216644c59daE5baed380d84830c"; msPassword = "******"; msAbiWonka = WonkaEth.Autogen.WonkaEngine.WonkaEngineDeployment.ABI; msByteCodeWonka = WonkaEth.Autogen.WonkaEngine.WonkaEngineDeployment.BYTECODE; msAbiRegistry = WonkaEth.Autogen.WonkaRegistry.WonkaRegistryDeployment.ABI; msByteCodeRegistry = WonkaEth.Autogen.WonkaRegistry.WonkaRegistryDeployment.BYTECODE; msAbiOrchTest = WonkaEth.Autogen.WonkaTestContract.WonkaTestContractDeployment.ABI; msByteCodeOrchTest = WonkaEth.Autogen.WonkaTestContract.WonkaTestContractDeployment.BYTECODE; // Create an instance of the class that will provide us with PmdRefAttributes (i.e., the data domain) // that define our data record moMetadataSource = new WonkaBre.Samples.WonkaBreMetadataTestSource(); WonkaRefEnvironment.CreateInstance(false, moMetadataSource); // NOTE: As a reminder, you must have a IPFS daemon configured and running (perhaps on your machine) // in order for the Ipfs.Api to work successfully if (pbRetrieveMarkupFromIpfs) { using (System.Net.WebClient client = new System.Net.WebClient()) { string sIpfsUrl = String.Format("{0}/{1}", CONST_INFURA_IPFS_GATEWAY_URL, "QmXcsGDQthxbGW8C3Sx9r4tV9PGSj4MxJmtXF7dnXN5XUT"); msRulesContents = client.DownloadString(sIpfsUrl); } } else { var TmpAssembly = Assembly.GetExecutingAssembly(); // Read the XML markup that lists the business rules using (var RulesReader = new StreamReader(TmpAssembly.GetManifestResourceStream("WonkaSystem.TestData.SimpleAccountCheck.xml"))) { msRulesContents = RulesReader.ReadToEnd(); } } // By setting the addresses to NULL, we indicates that we want the API to deploy the contracts for us if (psContractAddress == null) { msEngineContractAddress = null; msRegistryContractAddress = null; msTestContractAddress = null; } // By using the indicator "DEPLOY" here, we will manually deploy the contracts ourselves else if (psContractAddress == "DEPLOY") { msEngineContractAddress = DeployWonka(); } // Else, we will use existing contracts on the test chain else { if (psContractAddress == "") { msEngineContractAddress = "0xfB419DEA1f28283edAD89103fc1f1272f7573E6A"; } else { msEngineContractAddress = psContractAddress; } msRegistryContractAddress = "0x7E618a3948F6a5D2EA6b92D8Ce6723a468540CaA"; msTestContractAddress = "0x4092bc250ef6c384804af2f871Af9c679b672d0B"; } Init(pbInitChainEnv); }
public async Task <bool> Execute(bool pbValidateTransaction = false) { bool bResult = false; var RefEnv = WonkaRefEnvironment.GetInstance(); var RulesEngine = moEthEngineInit.Engine.RulesEngine; var SourceMap = moEthEngineInit.Engine.SourceMap; 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 = moProduct; string sStatusValueBefore = NewProduct.GetAttributeValue(AccountStsAttr); string sFlagValueBefore = NewProduct.GetAttributeValue(RvwFlagAttr); // Validate that the .NET implementation and the rules markup are both working properly Wonka.BizRulesEngine.Reporting.WonkaBizRuleTreeReport Report = RulesEngine.Validate(NewProduct); string sStatusValueAfter = NewProduct.GetAttributeValue(AccountStsAttr); string sFlagValueAfter = NewProduct.GetAttributeValue(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(moEthEngineInit.StorageContractAddress)) { /** ** 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 = await ExecuteWithReportAsync(RulesEngine, pbValidateTransaction).ConfigureAwait(false); 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?!"); } } return(bResult); }
/// <summary> /// /// This method will apply the arithmetic limit rule to either the incoming record or the current (i.e., database) /// record, using the other record as a reference. /// /// <param name="poTransactionRecord">The incoming record</param> /// <param name="poCurrentRecord">The current record (i.e., the already existing record)</param> /// <param name="poErrorMessage">The buffer that will contain an error message if the rule fails</param> /// <returns>Indicates whether or not the target product passed the rule successfully</returns> /// </summary> public override bool Execute(WonkaProduct poTransactionRecord, WonkaProduct poCurrentRecord, StringBuilder poErrorMessage) { bool bResult = false; WonkaProduct TargetRecord = null; WonkaRefEnvironment WonkaRefEnv = WonkaRefEnvironment.GetInstance(); if (RecordOfInterest == TARGET_RECORD.TRID_NEW_RECORD) { TargetRecord = poTransactionRecord; } else if (RecordOfInterest == TARGET_RECORD.TRID_OLD_RECORD) { TargetRecord = poCurrentRecord; } else { throw new Exception("ERROR! The target record is none!"); } string sTargetData = TargetRecord.GetPrimaryAttributeData(TargetAttribute.GroupId, TargetAttribute.AttrId); if (!string.IsNullOrEmpty(sTargetData)) { RefreshMinAndMax(poTransactionRecord, poCurrentRecord); try { double dTargetValue = Convert.ToDouble(sTargetData); if ((this.MaxValue >= dTargetValue) && (dTargetValue >= this.MinValue)) { bResult = true; } else { bResult = false; } if (poErrorMessage != null) { poErrorMessage.Clear(); poErrorMessage.Append(GetVerboseError(TargetRecord)); } } catch (Exception ex) { bResult = false; if (poErrorMessage != null) { poErrorMessage.Clear(); poErrorMessage.Append(ex.ToString()); } } } return(bResult); }
/// <summary> /// /// This method will initialize an instance of the Wonka.Net engine, using all the data provided. /// /// <returns>None</returns> /// </summary> public static void InitEngine(this WonkaEthEngineInitialization poEngineInitData, bool pbRequireRetrieveValueMethod = true) { var EngineProps = poEngineInitData.Engine; if (EngineProps == null) { throw new Exception("ERROR! No engine properties provided."); } if ((EngineProps.RulesEngine == null) && !String.IsNullOrEmpty(EngineProps.RulesMarkupXml)) { if (pbRequireRetrieveValueMethod && (EngineProps.DotNetRetrieveMethod == null)) { throw new WonkaEthInitException("ERROR! Retrieve method not provided for the Wonka.NET engine.", poEngineInitData); } if (EngineProps.MetadataSource == null) { throw new WonkaEthInitException("ERROR! No metadata source has been provided.", poEngineInitData); } // Using the metadata source, we create an instance of a defined data domain WonkaRefEnvironment WonkaRefEnv = WonkaRefEnvironment.CreateInstance(false, EngineProps.MetadataSource); var account = new Account(poEngineInitData.EthPassword); Nethereum.Web3.Web3 web3 = null; if (!String.IsNullOrEmpty(poEngineInitData.Web3HttpUrl)) { web3 = new Nethereum.Web3.Web3(account, poEngineInitData.Web3HttpUrl); } else { web3 = new Nethereum.Web3.Web3(account); } if (String.IsNullOrEmpty(poEngineInitData.RulesEngineContractAddress)) { var EngineDeployment = new Autogen.WonkaEngine.WonkaEngineDeployment(); HexBigInteger nDeployGas = new HexBigInteger(CONST_DEPLOY_ENGINE_CONTRACT_GAS_COST); poEngineInitData.RulesEngineContractAddress = EngineDeployment.DeployContract(web3, poEngineInitData.RulesEngineABI, poEngineInitData.EthSenderAddress, nDeployGas, poEngineInitData.Web3HttpUrl); } if (String.IsNullOrEmpty(poEngineInitData.RegistryContractAddress)) { var RegistryDeployment = new Autogen.WonkaRegistry.WonkaRegistryDeployment(); HexBigInteger nDeployGas = new HexBigInteger(CONST_DEPLOY_DEFAULT_CONTRACT_GAS_COST); poEngineInitData.RegistryContractAddress = RegistryDeployment.DeployContract(web3, poEngineInitData.RegistryContractABI, poEngineInitData.EthSenderAddress, nDeployGas, poEngineInitData.Web3HttpUrl); } if (String.IsNullOrEmpty(poEngineInitData.StorageContractAddress)) { var TestContractDeployment = new Autogen.WonkaTestContract.WonkaTestContractDeployment(); HexBigInteger nDeployGas = new HexBigInteger(CONST_DEPLOY_DEFAULT_CONTRACT_GAS_COST); poEngineInitData.StorageContractAddress = TestContractDeployment.DeployContract(web3, poEngineInitData.StorageContractABI, poEngineInitData.EthSenderAddress, nDeployGas, poEngineInitData.Web3HttpUrl); } if ((EngineProps.SourceMap == null) || (EngineProps.SourceMap.Count == 0)) { EngineProps.SourceMap = new Dictionary <string, WonkaBre.RuleTree.WonkaBreSource>(); // 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 WonkaRefEnv.AttrCache) { WonkaBreSource TempSource = new WonkaBreSource(poEngineInitData.StorageDefaultSourceId, poEngineInitData.EthSenderAddress, poEngineInitData.EthPassword, poEngineInitData.StorageContractAddress, poEngineInitData.StorageContractABI, poEngineInitData.StorageGetterMethod, poEngineInitData.StorageSetterMethod, EngineProps.DotNetRetrieveMethod); EngineProps.SourceMap[TempAttr.AttrName] = TempSource; } } EngineProps.RulesEngine = new WonkaBreRulesEngine(new StringBuilder(EngineProps.RulesMarkupXml), EngineProps.SourceMap, EngineProps.MetadataSource); EngineProps.RulesEngine.DefaultSource = poEngineInitData.StorageDefaultSourceId; EngineProps.RulesEngine.SetDefaultStdOps(poEngineInitData.EthPassword, poEngineInitData.Web3HttpUrl); } }
public WonkaSimpleCustomOpsTest(string psSenderAddress, string psPassword, string psContractAddress, bool pbSerializeMetadataToBlockchain = true) { msSenderAddress = psSenderAddress; msPassword = psPassword; msContractAddress = psContractAddress; // Create an instance of the class that will provide us with PmdRefAttributes (i.e., the data domain) // that define our data record moMetadataSource = new WonkaMetadataVATSource(); var TmpAssembly = Assembly.GetExecutingAssembly(); // Read the ABI of the Ethereum contract for the Wonka rules engine using (var AbiReader = new StreamReader(TmpAssembly.GetManifestResourceStream("WonkaSystem.TestData.WonkaEngine.abi"))) { msAbiWonka = AbiReader.ReadToEnd(); } // Read the bytecodes of the Ethereum contract for the Wonka rules engine using (var ByteCodeReader = new StreamReader(TmpAssembly.GetManifestResourceStream("WonkaSystem.TestData.WonkaEngine.bin"))) { msByteCodeWonka = ByteCodeReader.ReadToEnd(); } // Read the ABI of the Ethereum contract that will demonstrate both our Custom Operator functionality and our Orchestration functionality using (var AbiReader = new StreamReader(TmpAssembly.GetManifestResourceStream("WonkaSystem.TestData.OrchTest.abi"))) { msAbiOrchTest = AbiReader.ReadToEnd(); } // Read the bytecodes of the Ethereum contract that will hold our data record and provide Custom Operator functionality using (var ByteCodeReader = new StreamReader(TmpAssembly.GetManifestResourceStream("WonkaSystem.TestData.OrchTest.bin"))) { msByteCodeOrchTest = ByteCodeReader.ReadToEnd(); } // Read the XML markup that lists the business rules using (var RulesReader = new StreamReader(TmpAssembly.GetManifestResourceStream("WonkaSystem.TestData.VATCalculationExample.xml"))) { msRulesContents = RulesReader.ReadToEnd(); } // Using the metadata source, we create an instance of a defined data domain WonkaRefEnvironment WonkaRefEnv = WonkaRefEnvironment.CreateInstance(false, moMetadataSource); WonkaRefAttr NewSalesTransSeqAttr = WonkaRefEnv.GetAttributeByAttrName("NewSalesTransSeq"); WonkaRefAttr NewSaleVATRateDenomAttr = WonkaRefEnv.GetAttributeByAttrName("NewSaleVATRateDenom"); WonkaRefAttr NewSaleItemTypeAttr = WonkaRefEnv.GetAttributeByAttrName("NewSaleItemType"); WonkaRefAttr CountryOfSaleAttr = WonkaRefEnv.GetAttributeByAttrName("CountryOfSale"); WonkaRefAttr NewSalePriceAttr = WonkaRefEnv.GetAttributeByAttrName("NewSalePrice"); WonkaRefAttr PrevSellTaxAmountAttr = WonkaRefEnv.GetAttributeByAttrName("PrevSellTaxAmount"); WonkaRefAttr NewSellTaxAmountAttr = WonkaRefEnv.GetAttributeByAttrName("NewSellTaxAmount"); WonkaRefAttr NewVATAmountForHMRCAttr = WonkaRefEnv.GetAttributeByAttrName("NewVATAmountForHMRC"); WonkaRefAttr NewSaleEANAttr = WonkaRefEnv.GetAttributeByAttrName("NewSaleEAN"); // We create a target list of the Attributes of the old (i.e., existing) record that currently exists on the blockchain // and which we want to pull back during the engine's execution moTargetAttrList = new List <WonkaRefAttr>(); moTargetAttrList = new List <WonkaRefAttr>() { NewSalesTransSeqAttr, NewSaleVATRateDenomAttr, NewSaleItemTypeAttr, CountryOfSaleAttr, NewSalePriceAttr, PrevSellTaxAmountAttr, NewSellTaxAmountAttr, NewVATAmountForHMRCAttr, NewSaleEANAttr }; if (pbSerializeMetadataToBlockchain) { SerializeMetadataToBlockchain(); } }
/// <summary> /// /// This method will apply the assignment rule to either the transaction record or the current (i.e., database) /// record, using the other record as a reference. /// /// <param name="poTransactionRecord">The incoming record</param> /// <param name="poCurrentRecord">The current record (i.e., in the database)</param> /// <param name="poErrorMessage">The buffer that will contain an error message if the rule fails</param> /// <returns>Indicates whether or not the target product passed the rule successfully</returns> /// </summary> public override bool Execute(WonkaProduct poTransactionRecord, WonkaProduct poCurrentRecord, StringBuilder poErrorMessage) { bool bResult = false; bool bAssignValue = true; int nAttrId = TargetAttribute.AttrId; int nGroupId = TargetAttribute.GroupId; WonkaProduct TargetRecord = null; WonkaRefEnvironment WonkaRefEnv = WonkaRefEnvironment.GetInstance(); if (poTransactionRecord == null) { throw new Exception("ERROR! The new Product is null."); } if (poCurrentRecord == null) { throw new Exception("ERROR! The old Product is null."); } if (RecordOfInterest == TARGET_RECORD.TRID_NEW_RECORD) { TargetRecord = poTransactionRecord; } else if (RecordOfInterest == TARGET_RECORD.TRID_OLD_RECORD) { TargetRecord = poCurrentRecord; } else { throw new Exception("ERROR! The target record is none!"); } if (DefaultAssignment) { WonkaPrdGroup TempProductGroup = null; if (RecordOfInterest == TARGET_RECORD.TRID_NEW_RECORD) { TempProductGroup = poTransactionRecord.GetProductGroup(nGroupId); } else { TempProductGroup = poCurrentRecord.GetProductGroup(nGroupId); } string sCurrentValue = ""; if (TempProductGroup.GetRowCount() > 0) { if (TempProductGroup[0].ContainsKey(nAttrId)) { sCurrentValue = TempProductGroup[0][nAttrId]; } } if (!String.IsNullOrEmpty(sCurrentValue)) { bAssignValue = false; } } if (bAssignValue) { RefreshAssignValue(poTransactionRecord, poCurrentRecord); WonkaPrdGroup TempProductGroup = null; if (RecordOfInterest == TARGET_RECORD.TRID_NEW_RECORD) { TempProductGroup = poTransactionRecord.GetProductGroup(nGroupId); } else { TempProductGroup = poCurrentRecord.GetProductGroup(nGroupId); } TempProductGroup[0][nAttrId] = AssignValue; } return(bResult); }
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); }
/// <summary> /// /// This method will iterate through all of the data in the contained groups and detect whether /// any of them are not valid according to the designated type for that Attribute. /// /// <param name="poErrors">The list to which we will add any errors concerning the validation of types</param> /// <returns>Indicates whether or not there any errors with validating types</returns> /// </summary> public bool ValidateTypes(List <WonkaProductError> poErrors) { WonkaRefEnvironment RefEnv = WonkaRefEnvironment.GetInstance(); bool bResult = true; foreach (int nGrpId in this.ProductGroups.Keys) { WonkaPrdGroup TempGroup = ProductGroups[nGrpId]; foreach (WonkaPrdGroupDataRow TempDataRow in TempGroup) { foreach (int nAttrId in TempDataRow.Keys) { string sAttrValue = TempDataRow[nAttrId]; if (!String.IsNullOrEmpty(sAttrValue)) { WonkaRefAttr TempAttr = RefEnv.GetAttributeByAttrId(nAttrId); if (TempAttr.IsDecimal) { try { Decimal dValue = Convert.ToDecimal(sAttrValue); } catch (Exception ex) { poErrors.Add(new WonkaProductError() { AttrName = TempAttr.AttrName, ErrorMessage = "ERROR! Value(" + sAttrValue + ") is not a valid decimal!" }); } } else if (TempAttr.IsNumeric) { try { long nValue = Convert.ToInt64(sAttrValue); } catch (Exception ex) { poErrors.Add(new WonkaProductError() { AttrName = TempAttr.AttrName, ErrorMessage = "ERROR! Value(" + sAttrValue + ") is not a valid number!" }); } } else if (TempAttr.IsDate) { try { DateTime dtValue = DateTime.Parse(sAttrValue); } catch (Exception ex) { poErrors.Add(new WonkaProductError() { AttrName = TempAttr.AttrName, ErrorMessage = "ERROR! Value(" + sAttrValue + ") is not a valid date!" }); } } } } } } return(bResult); }
public WonkaSimpleOrchestrationTest(string psSenderAddress, string psPassword, string psContractAddress, bool pbSerializeMetadataToBlockchain = true) { msSenderAddress = psSenderAddress; msPassword = psPassword; msContractAddress = psContractAddress; // Create an instance of the class that will provide us with PmdRefAttributes (i.e., the data domain) // that define our data record moMetadataSource = new WonkaMetadataTestSource(); var TmpAssembly = Assembly.GetExecutingAssembly(); // Read the ABI of the Ethereum contract for the Wonka rules engine using (var AbiReader = new StreamReader(TmpAssembly.GetManifestResourceStream("WonkaSystem.TestData.WonkaEngine.abi"))) { msAbiWonka = AbiReader.ReadToEnd(); } // Read the bytecodes of the Ethereum contract for the Wonka rules engine using (var ByteCodeReader = new StreamReader(TmpAssembly.GetManifestResourceStream("WonkaSystem.TestData.WonkaEngine.bin"))) { msByteCodeWonka = ByteCodeReader.ReadToEnd(); } // Read the ABI of the Ethereum contract that will demonstrate our Orchestration functionality by getting/setting Attribute values using (var AbiReader = new StreamReader(TmpAssembly.GetManifestResourceStream("WonkaSystem.TestData.OrchTest.abi"))) { msAbiOrchTest = AbiReader.ReadToEnd(); } // Read the bytecodes of the Ethereum contract that will hold our data record using (var ByteCodeReader = new StreamReader(TmpAssembly.GetManifestResourceStream("WonkaSystem.TestData.OrchTest.bin"))) { msByteCodeOrchTest = ByteCodeReader.ReadToEnd(); } // Read the XML markup that lists the business rules using (var RulesReader = new StreamReader(TmpAssembly.GetManifestResourceStream("WonkaSystem.TestData.SimpleAccountCheck.xml"))) { msRulesContents = RulesReader.ReadToEnd(); } // Using the metadata source, we create an instance of a defined data domain WonkaRefEnvironment WonkaRefEnv = WonkaRefEnvironment.CreateInstance(false, moMetadataSource); WonkaRefAttr AccountIDAttr = WonkaRefEnv.GetAttributeByAttrName("BankAccountID"); WonkaRefAttr AccountNameAttr = WonkaRefEnv.GetAttributeByAttrName("BankAccountName"); WonkaRefAttr AccountStsAttr = WonkaRefEnv.GetAttributeByAttrName("AccountStatus"); WonkaRefAttr AccountCurrValAttr = WonkaRefEnv.GetAttributeByAttrName("AccountCurrValue"); WonkaRefAttr AccountTypeAttr = WonkaRefEnv.GetAttributeByAttrName("AccountType"); WonkaRefAttr AccountCurrencyAttr = WonkaRefEnv.GetAttributeByAttrName("AccountCurrency"); WonkaRefAttr RvwFlagAttr = WonkaRefEnv.GetAttributeByAttrName("AuditReviewFlag"); // We create a target list of the Attributes of the old (i.e., existing) record that currently exists on the blockchain // and which we want to pull back during the engine's execution moTargetAttrList = new List <WonkaRefAttr>(); moTargetAttrList = new List <WonkaRefAttr>() { AccountIDAttr, AccountNameAttr, AccountStsAttr, AccountCurrValAttr, AccountTypeAttr, AccountCurrencyAttr, RvwFlagAttr }; // Serialize the data domain to the blockchain if (pbSerializeMetadataToBlockchain) { SerializeMetadataToBlockchain(); } }
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; } // 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 WonkaNoviceNethereumTest(string psSenderAddress, string psPassword, string psContractAddress = null, bool bSerializeMetadataAndEngine = true) { msSenderAddress = psSenderAddress; msPassword = psPassword; // Create an instance of the class that will provide us with PmdRefAttributes (i.e., the data domain) // that define our data records moMetadataSource = new WonkaMetadataTestSource(); var TmpAssembly = Assembly.GetExecutingAssembly(); // Read the ABI of the Ethereum contract for the Wonka rules engine and holds our data record using (var AbiReader = new StreamReader(TmpAssembly.GetManifestResourceStream("WonkaSystem.TestData.WonkaEngine.abi"))) { msAbiWonka = AbiReader.ReadToEnd(); } // Read the bytecodes of the Ethereum contract for the Wonka rules engine and holds our data record using (var ByteCodeReader = new StreamReader(TmpAssembly.GetManifestResourceStream("WonkaSystem.TestData.WonkaEngine.bin"))) { msByteCodeWonka = ByteCodeReader.ReadToEnd(); } // Read the XML markup that lists the business rules using (var RulesReader = new StreamReader(TmpAssembly.GetManifestResourceStream("WonkaSystem.TestData.SimpleAccountCheck.xml"))) { msRulesContents = RulesReader.ReadToEnd(); } // Using the metadata source, we create an instance of a defined data domain WonkaRefEnvironment WonkaRefEnv = WonkaRefEnvironment.CreateInstance(false, moMetadataSource); WonkaRefAttr AccountIDAttr = WonkaRefEnv.GetAttributeByAttrName("BankAccountID"); WonkaRefAttr AccountNameAttr = WonkaRefEnv.GetAttributeByAttrName("BankAccountName"); WonkaRefAttr AccountStsAttr = WonkaRefEnv.GetAttributeByAttrName("AccountStatus"); WonkaRefAttr AccountCurrValAttr = WonkaRefEnv.GetAttributeByAttrName("AccountCurrValue"); WonkaRefAttr AccountTypeAttr = WonkaRefEnv.GetAttributeByAttrName("AccountType"); WonkaRefAttr AccountCurrencyAttr = WonkaRefEnv.GetAttributeByAttrName("AccountCurrency"); // We create a target list of the Attributes of the old (i.e., existing) record that currently exists on the blockchain // and which we want to pull back during the engine's execution moTargetAttrList = new List <WonkaRefAttr>(); moTargetAttrList = new List <WonkaRefAttr>() { AccountIDAttr, AccountNameAttr, AccountStsAttr, AccountCurrValAttr, AccountTypeAttr, AccountCurrencyAttr }; if (psContractAddress == null) { msContractAddress = DeployContract(); } else { msContractAddress = psContractAddress; } if (bSerializeMetadataAndEngine) { // Now we serialize the data domain to the blockchain SerializeMetadataToBlockchain(); // And serialize the rules engine to the blockchain SerializeRulesEngineToBlockchain(); } }
public void Execute() { // Using the metadata source, we create an instance of a defined data domain WonkaRefEnvironment RefEnv = WonkaRefEnvironment.CreateInstance(false, moMetadataSource); var sWeb3Url = "https://mainnet.infura.io/v3/7238211010344719ad14a89db874158c"; var sSenderAddress = "0x12890D2cce102216644c59daE5baed380d84830c"; var sPassword = "******"; var sERC20Address = "0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2"; // To test whether the data domain has been created, we pull back one attribute WonkaRefAttr AccountStsAttr = RefEnv.GetAttributeByAttrName("AccountStatus"); WonkaRefAttr AuditRvwFlagAttr = RefEnv.GetAttributeByAttrName("AuditReviewFlag"); Dictionary <string, WonkaBizSource> SourceMap = new Dictionary <string, WonkaBizSource>(); /* * WonkaBizSource DefaultSource = * new WonkaBizSource(sContractSourceId, msSenderAddress, msPassword, sContractAddress, sContractAbi, sOrchGetterMethod, sOrchSetterMethod, RetrieveValueMethod); */ WonkaBizSource DefaultSource = new WonkaBizSource("", "", "", "", null); // 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 RefEnv.AttrCache) { SourceMap[TempAttr.AttrName] = DefaultSource; } var WonkaEthEngInit = new WonkaEthEngineInitialization() { EthSenderAddress = sSenderAddress, EthPassword = sPassword, ERC20ContractAddress = sERC20Address, ERC721ContractAddress = "", Web3HttpUrl = sWeb3Url }; // Creating an instance of the rules engine using our rules and the metadata WonkaBizRulesEngine RulesEngine = new WonkaEthRulesEngine(new StringBuilder(msRulesContents), SourceMap, WonkaEthEngInit, 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); // RulesEngine.GetCurrentProductDelegate = GetOldProduct; // Validate the new record using our rules engine and its initialized RuleTree Wonka.BizRulesEngine.Reporting.WonkaBizRuleTreeReport 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); string sAuditRvwFlagAfter = GetAttributeValue(NewProduct, AuditRvwFlagAttr); if (Report.GetRuleSetFailureCount() > 0) { throw new Exception("Oh heavens to Betsy! Something bad happened!"); } }