public Wonka.Eth.Orchestration.Init.OrchestrationInitData GenerateInitData() { Wonka.Eth.Orchestration.Init.OrchestrationInitData InitData = null; if (moOrchInitData != null) { InitData = moOrchInitData; } else { InitData = new Wonka.Eth.Orchestration.Init.OrchestrationInitData(); InitData.BlockchainEngine = new WonkaBizSource("N", msSenderAddress, msPassword, msWonkaContractAddress, msAbiWonka, null, null, null); InitData.AttributesMetadataSource = new WonkaMetadataVATSource(); InitData.DefaultBlockchainDataSource = moDefaultSource; InitData.BlockchainDataSources = moAttrSourceMap; InitData.BlockchainCustomOpFunctions = moCustomOpMap; InitData.TrxStateContractAddress = moOrchInitData.TrxStateContractAddress; } return(InitData); }
// This constructor will be called in the case that we wish to initialize the framework // with configuration files locally (embedded resources, local filesystem, etc.) public WonkaCQSOrchTest() { moAttrSourceMap = new Dictionary <string, WonkaBizSource>(); moCustomOpMap = new Dictionary <string, WonkaBizSource>(); var TmpAssembly = Assembly.GetExecutingAssembly(); // Using the metadata source, we create an instance of a defined data domain WonkaRefEnvironment RefEnv = WonkaRefEnvironment.CreateInstance(false, moMetadataSource); // Read the XML markup that lists the business rules (i.e., the RuleTree) using (var RulesReader = new StreamReader(TmpAssembly.GetManifestResourceStream("WonkaSystem.TestData.VATCalculationExample.xml"))) { msRulesContents = RulesReader.ReadToEnd(); } // Read the configuration file that contains all the initialization details regarding the rules engine // (like addresses of contracts, senders, passwords, etc.) using (var XmlReader = new System.IO.StreamReader(TmpAssembly.GetManifestResourceStream("WonkaSystem.TestData.VATCalculationExample.init.xml"))) { string sInitXml = XmlReader.ReadToEnd(); // We deserialize/parse the contents of the config file System.Xml.Serialization.XmlSerializer WonkaEthSerializer = new System.Xml.Serialization.XmlSerializer(typeof(Wonka.Eth.Init.WonkaEthInitialization), new System.Xml.Serialization.XmlRootAttribute("Wonka.EthInitialization")); Wonka.Eth.Init.WonkaEthInitialization WonkaInit = WonkaEthSerializer.Deserialize(new System.IO.StringReader(sInitXml)) as Wonka.Eth.Init.WonkaEthInitialization; // Here, any embeddeded resources mentioned in the config file (instead of simple file URLs) are accessed here WonkaInit.RetrieveEmbeddedResources(TmpAssembly); // The initialization data is transformed into a structure used by the Wonka.Eth namespace moOrchInitData = WonkaInit.TransformIntoOrchestrationInit(moMetadataSource); System.Console.WriteLine("Number of custom operators: (" + WonkaInit.CustomOperatorList.Length + ")."); } // Read the configuration file that contains all the initialization details regarding the rules registry // (like Ruletree info, Grove info, etc.) - this information will allow us to add our RuleTree to the // Registry so that it can be discovered by users and so it can be added to a Grove (where it can be executed // as a member of a collection) using (var XmlReader = new System.IO.StreamReader(TmpAssembly.GetManifestResourceStream("WonkaSystem.TestData.WonkaRegistry.init.xml"))) { string sInitRegistryXml = XmlReader.ReadToEnd(); // We deserialize/parse the contents of the config file System.Xml.Serialization.XmlSerializer WonkaEthSerializer = new System.Xml.Serialization.XmlSerializer(typeof(Wonka.Eth.Init.WonkaEthRegistryInitialization), new System.Xml.Serialization.XmlRootAttribute("Wonka.EthRegistryInitialization")); moWonkaRegistryInit = WonkaEthSerializer.Deserialize(new System.IO.StringReader(sInitRegistryXml)) as Wonka.Eth.Init.WonkaEthRegistryInitialization; // Here, any embeddeded resources mentioned in the config file (instead of simple file URLs) are accessed here moWonkaRegistryInit.RetrieveEmbeddedResources(TmpAssembly); } // Here, we save all data from the config files to member properties // This region and the usage of member properties isn't necessary, but it's useful for debugging #region Set Class Member Variables msSenderAddress = moOrchInitData.BlockchainEngine.SenderAddress; msPassword = moOrchInitData.BlockchainEngine.Password; if (moOrchInitData.BlockchainEngine.ContractAddress == null) { msWonkaContractAddress = DeployWonkaContract(); } else { msWonkaContractAddress = moOrchInitData.BlockchainEngine.ContractAddress; } if (moOrchInitData.DefaultBlockchainDataSource.ContractAddress == null) { msOrchContractAddress = DeployOrchestrationContract(); } else { msOrchContractAddress = moOrchInitData.DefaultBlockchainDataSource.ContractAddress; } msAbiWonka = moOrchInitData.BlockchainEngine.ContractABI; msAbiOrchContract = moOrchInitData.DefaultBlockchainDataSource.ContractABI; moDefaultSource = new WonkaBizSource(moOrchInitData.DefaultBlockchainDataSource.SourceId, moOrchInitData.DefaultBlockchainDataSource.SenderAddress, moOrchInitData.DefaultBlockchainDataSource.Password, moOrchInitData.DefaultBlockchainDataSource.ContractAddress, moOrchInitData.DefaultBlockchainDataSource.ContractABI, moOrchInitData.DefaultBlockchainDataSource.MethodName, moOrchInitData.DefaultBlockchainDataSource.SetterMethodName, RetrieveValueMethod); foreach (WonkaRefAttr TempAttr in RefEnv.AttrCache) { moAttrSourceMap[TempAttr.AttrName] = moDefaultSource; } moCustomOpMap = moOrchInitData.BlockchainCustomOpFunctions; #endregion // We initialize the proxy that will be used to communicate with the Registry on the blockchain Wonka.Eth.Contracts.WonkaRuleTreeRegistry WonkaRegistry = Wonka.Eth.Contracts.WonkaRuleTreeRegistry.CreateInstance(moWonkaRegistryInit.BlockchainRegistry.ContractSender, moWonkaRegistryInit.BlockchainRegistry.ContractPassword, moWonkaRegistryInit.BlockchainRegistry.ContractAddress, moWonkaRegistryInit.BlockchainRegistry.ContractABI, moWonkaRegistryInit.Web3HttpUrl); // Here, the data domain is serialized to the blockchain for use by the RuleTree(s) RefEnv.Serialize(moOrchInitData.BlockchainEngineOwner, msPassword, msSenderAddress, msWonkaContractAddress, msAbiWonka, moOrchInitData.Web3HttpUrl); }
public void Execute() { WonkaRefEnvironment RefEnv = WonkaRefEnvironment.GetInstance(); // Now we assemble the data record for processing - in our VAT Calculation example, parts of the // logical record can exist within contract(s) within the blockchain (which has been specified // via Orchestration metadata), like a logistics or supply contract - these properties below // (NewSaleEAN, NewSaleItemType, CountryOfSale) would be supplied by a client, like an // eCommerce site, and be persisted to the blockchain so we may apply the RuleTree to the logical record CQS.Contracts.SalesTrxCreateCommand SalesTrxCommand = new CQS.Contracts.SalesTrxCreateCommand(); SalesTrxCommand.NewSaleEAN = 9781234567890; SalesTrxCommand.NewSaleItemType = "Widget"; SalesTrxCommand.CountryOfSale = "UK"; Wonka.Eth.Orchestration.Init.OrchestrationInitData InitData = GenerateInitData(); #region Invoking the RuleTree for the first time as a single entity // The engine's proxy for the blockchain is instantiated here, which will be responsible for serializing // and executing the RuleTree within the engine CQS.Generation.SalesTransactionGenerator TrxGenerator = new CQS.Generation.SalesTransactionGenerator(SalesTrxCommand, new StringBuilder(msRulesContents), InitData); // Here, we invoke the Rules engine on the blockchain, which will calculate the VAT for a sale and then // retrieve all values of this logical record (including the VAT) and assemble them within 'SalesTrxCommand' bool bValid = TrxGenerator.GenerateSalesTransaction(SalesTrxCommand); if (!bValid) { throw new Exception("Oh heavens to Betsy! Something bad happened!"); } // Since the purpose of this example was to showcase the calculated VAT, we examine them here // (while interactively debugging in Visual Studio) string sNewSellTaxAmt = Convert.ToString(SalesTrxCommand.NewSellTaxAmt); string sNewVATAmtForHMRC = Convert.ToString(SalesTrxCommand.NewVATAmtForHMRC); #endregion #region Invoking the RuleTree as a registered entity and as a member of a Grove // Here, we attempt to call the same RuleTree as above, but we are going to invoke the execution of // its Grove "NewSaleGroup" - since it is the sole member of the Grove, it will still be the only RuleTree // applied to the record - in this scenario, we pretend that we know nothing about the RuleTree or the Grove, // effectively treating it as a black box and only looking to retrieve the VAT Wonka.Eth.Contracts.WonkaRuleGrove NewSaleGrove = new Wonka.Eth.Contracts.WonkaRuleGrove("NewSaleGroup"); NewSaleGrove.PopulateFromRegistry(this.msAbiWonka); // The engine's lightweight proxy for the blockchain is instantiated here Wonka.Eth.Orchestration.WonkaOrchestratorProxy <CQS.Contracts.SalesTrxCreateCommand> TrxGeneratorProxy = new Wonka.Eth.Orchestration.WonkaOrchestratorProxy <CQS.Contracts.SalesTrxCreateCommand>(SalesTrxCommand, InitData); // We reset the values here and in the blockchain (by serializing) SalesTrxCommand.NewSellTaxAmt = 0; SalesTrxCommand.NewVATAmtForHMRC = 0; TrxGeneratorProxy.SerializeRecordToBlockchain(SalesTrxCommand); // NOTE: Only useful when debugging // TrxGeneratorProxy.DeserializeRecordFromBlockchain(SalesTrxCommand); Dictionary <string, Wonka.Eth.Contracts.IOrchestrate> GroveMembers = new Dictionary <string, Wonka.Eth.Contracts.IOrchestrate>(); GroveMembers[NewSaleGrove.OrderedRuleTrees[0].RuleTreeId] = TrxGeneratorProxy; // With their provided proxies for each RuleTree, we can now execute the Grove (or, in this case, our sole RuleTree) NewSaleGrove.Orchestrate(SalesTrxCommand, GroveMembers); // Again, since the purpose of this example was to showcase the calculated VAT, we examine them here // (while interactively debugging in Visual Studio) sNewSellTaxAmt = Convert.ToString(SalesTrxCommand.NewSellTaxAmt); sNewVATAmtForHMRC = Convert.ToString(SalesTrxCommand.NewVATAmtForHMRC); #endregion // Now test exporting the RuleTree from the blockchain var RegistryItem = NewSaleGrove.OrderedRuleTrees[0]; var ExportedXml = RegistryItem.ExportXmlString(InitData.Web3HttpUrl); System.Console.WriteLine("DEBUG: The payload is: \n(\n" + ExportedXml + "\n)\n"); }
// This constructor will be called in the case that we wish to initialize the framework // with configuration files that will be accessed through IPFS public WonkaCQSOrchTest(StringBuilder psPeerKeyId, string psRulesMarkupFile, string psRulesInitFile, string psRegistryInitFile) { moAttrSourceMap = new Dictionary <string, WonkaBizSource>(); moCustomOpMap = new Dictionary <string, WonkaBizSource>(); var TmpAssembly = Assembly.GetExecutingAssembly(); WonkaRefEnvironment RefEnv = WonkaRefEnvironment.CreateInstance(false, moMetadataSource); Wonka.IpfsW.WonkaIpfsEnvironment IpfsEnv = Wonka.IpfsW.WonkaIpfsEnvironment.CreateInstance(); // Read the XML markup that lists the business rules msRulesContents = IpfsEnv.GetFile(psPeerKeyId.ToString(), psRulesMarkupFile); // Read the configuration file that contains all the initialization details regarding the rules engine // (like addresses of contracts, senders, passwords, etc.) string sInitXml = IpfsEnv.GetFile(psPeerKeyId.ToString(), psRulesInitFile); if (!String.IsNullOrEmpty(sInitXml)) { System.Xml.Serialization.XmlSerializer WonkaEthSerializer = new System.Xml.Serialization.XmlSerializer(typeof(Wonka.Eth.Init.WonkaEthInitialization), new System.Xml.Serialization.XmlRootAttribute("Wonka.EthInitialization")); Wonka.Eth.Init.WonkaEthInitialization WonkaInit = WonkaEthSerializer.Deserialize(new System.IO.StringReader(sInitXml)) as Wonka.Eth.Init.WonkaEthInitialization; WonkaInit.RetrieveEmbeddedResources(TmpAssembly); moOrchInitData = WonkaInit.TransformIntoOrchestrationInit(moMetadataSource); System.Console.WriteLine("Number of custom operators: (" + WonkaInit.CustomOperatorList.Length + ")."); } // Read the configuration file that contains all the initialization details regarding the rules registry // (like Ruletree info, Grove info, etc.) string sInitRegistryXml = IpfsEnv.GetFile(psPeerKeyId.ToString(), psRegistryInitFile); if (!String.IsNullOrEmpty(sInitRegistryXml)) { System.Xml.Serialization.XmlSerializer WonkaEthSerializer = new System.Xml.Serialization.XmlSerializer(typeof(Wonka.Eth.Init.WonkaEthRegistryInitialization), new System.Xml.Serialization.XmlRootAttribute("Wonka.EthRegistryInitialization")); moWonkaRegistryInit = WonkaEthSerializer.Deserialize(new System.IO.StringReader(sInitRegistryXml)) as Wonka.Eth.Init.WonkaEthRegistryInitialization; moWonkaRegistryInit.RetrieveEmbeddedResources(TmpAssembly); } #region Set Class Member Variables msSenderAddress = moOrchInitData.BlockchainEngine.SenderAddress; msPassword = moOrchInitData.BlockchainEngine.Password; if (moOrchInitData.BlockchainEngine.ContractAddress == null) { msWonkaContractAddress = DeployWonkaContract(); } else { msWonkaContractAddress = moOrchInitData.BlockchainEngine.ContractAddress; } if (moOrchInitData.DefaultBlockchainDataSource.ContractAddress == null) { msOrchContractAddress = DeployOrchestrationContract(); } else { msOrchContractAddress = moOrchInitData.DefaultBlockchainDataSource.ContractAddress; } msAbiWonka = moOrchInitData.BlockchainEngine.ContractABI; msAbiOrchContract = moOrchInitData.DefaultBlockchainDataSource.ContractABI; moDefaultSource = new WonkaBizSource(moOrchInitData.DefaultBlockchainDataSource.SourceId, moOrchInitData.DefaultBlockchainDataSource.SenderAddress, moOrchInitData.DefaultBlockchainDataSource.Password, moOrchInitData.DefaultBlockchainDataSource.ContractAddress, moOrchInitData.DefaultBlockchainDataSource.ContractABI, moOrchInitData.DefaultBlockchainDataSource.MethodName, moOrchInitData.DefaultBlockchainDataSource.SetterMethodName, 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 RefEnv.AttrCache) { moAttrSourceMap[TempAttr.AttrName] = moDefaultSource; } // 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 moCustomOpMap = moOrchInitData.BlockchainCustomOpFunctions; #endregion Wonka.Eth.Contracts.WonkaRuleTreeRegistry WonkaRegistry = Wonka.Eth.Contracts.WonkaRuleTreeRegistry.CreateInstance(moWonkaRegistryInit.BlockchainRegistry.ContractSender, moWonkaRegistryInit.BlockchainRegistry.ContractPassword, moWonkaRegistryInit.BlockchainRegistry.ContractAddress, moWonkaRegistryInit.BlockchainRegistry.ContractABI, moWonkaRegistryInit.Web3HttpUrl); RefEnv.Serialize(moOrchInitData.BlockchainEngineOwner, msPassword, msSenderAddress, msWonkaContractAddress, msAbiWonka, moOrchInitData.Web3HttpUrl); }