Exemplo n.º 1
0
        // NOTE: That says "po-Op-Source", but if you want to look at it as "poOp-Source", well, that's up to you,
        // and try not laugh yourself silly
        public void AddCustomOperator(string psCustomOpName, WonkaBreSource poOpSource = null)
        {
            if (BasicOps.Contains(psCustomOpName))
            {
                throw new Exception("ERROR!  Provided operator is already a basic operator within the rules engine.");
            }

            if (ArithmeticLimitOps.Contains(psCustomOpName))
            {
                throw new Exception("ERROR!  Provided operator is already a arithmetic limit operator within the rules engine.");
            }

            if (DateLimitOps.Contains(psCustomOpName))
            {
                throw new Exception("ERROR!  Provided operator is already a date limit operator within the rules engine.");
            }

            if (poOpSource != null)
            {
                CustomOpSources[psCustomOpName] = poOpSource;
            }
            else
            {
                CustomOpSources[psCustomOpName] = new WonkaBreSource("", "", "", "", "", "", "", null);
            }
        }
Exemplo n.º 2
0
        public WonkaBreRulesEngine(StringBuilder psRules,
                                   Dictionary <string, WonkaBreSource> poSourceMap,
                                   Dictionary <string, WonkaBreSource> poCustomOpBlockchainSources,
                                   IMetadataRetrievable piMetadataSource = null,
                                   bool pbAddToRegistry = true)
        {
            if ((psRules == null) || (psRules.Length <= 0))
            {
                throw new WonkaBreException("ERROR!  Provided rules are null or empty!");
            }

            UsingOrchestrationMode = true;
            AddToRegistry          = pbAddToRegistry;

            RefEnvHandle = Init(piMetadataSource);

            WonkaBreXmlReader BreXmlReader = new WonkaBreXmlReader(psRules, piMetadataSource, this);

            foreach (string sKey in poCustomOpBlockchainSources.Keys)
            {
                WonkaBreSource oTargetSource = poCustomOpBlockchainSources[sKey];

                BreXmlReader.AddCustomOperator(sKey, oTargetSource);
            }

            RuleTreeRoot = BreXmlReader.ParseRuleTree();
            SourceMap    = poSourceMap;
            CustomOpMap  = poCustomOpBlockchainSources;
            AllRuleSets  = BreXmlReader.AllParsedRuleSets;

            this.RetrieveCurrRecord = AssembleCurrentProduct;
        }
Exemplo n.º 3
0
        public CustomOperatorRule(int pnRuleID,
                                  TARGET_RECORD peTargetRecord,
                                  int pnTargetAttrId,
                                  string psCustomOpName,
                                  WonkaBreXmlReader.ExecuteCustomOperator poCustomOpDelegate,
                                  WonkaBreSource poCustomOpContractSource) :
            base(pnRuleID, RULE_TYPE.RT_CUSTOM_OP)
        {
            Init(peTargetRecord, pnTargetAttrId, null);

            CustomOpName           = psCustomOpName;
            CustomOpDelegate       = poCustomOpDelegate;
            CustomOpContractSource = poCustomOpContractSource;
        }
Exemplo n.º 4
0
        public Nethereum.Contracts.Contract GetContract(WonkaBreSource poBlockchainSource)
        {
            var account = new Account(poBlockchainSource.Password);

            Nethereum.Web3.Web3 web3 = null;
            if ((moInitData != null) && !String.IsNullOrEmpty(moInitData.Web3HttpUrl))
            {
                web3 = new Nethereum.Web3.Web3(account, moInitData.Web3HttpUrl);
            }
            else
            {
                web3 = new Nethereum.Web3.Web3(account);
            }

            var contract = web3.Eth.GetContract(poBlockchainSource.ContractABI, poBlockchainSource.ContractAddress);

            return(contract);
        }
Exemplo n.º 5
0
        /// <summary>
        ///
        /// This method will assemble the new product by iterating through each specified source
        /// and retrieving the data from it.
        ///
        /// <param name="poKeyValues">The keys for the product whose data we wish to extract/param>
        /// <returns>Contains the assembled product data that represents the current product</returns>
        /// </summary>
        public WonkaProduct AssembleCurrentProduct(Dictionary <string, string> poKeyValues)
        {
            WonkaProduct CurrentProduct = new WonkaProduct();

            // NOTE: Do work here
            if (SourceMap != null)
            {
                foreach (string sTmpAttName in SourceMap.Keys)
                {
                    WonkaBreSource TmpSource  = SourceMap[sTmpAttName];
                    WonkaRefAttr   TargetAttr = RefEnvHandle.GetAttributeByAttrName(sTmpAttName);

                    string sTmpValue = TmpSource.RetrievalDelegate.Invoke(TmpSource, TargetAttr.AttrName);

                    CurrentProduct.SetAttribute(TargetAttr, sTmpValue);
                }
            }

            return(CurrentProduct);
        }
Exemplo n.º 6
0
        public virtual void SerializeRecordToBlockchain(ICommand poCommand)
        {
            Hashtable DataValues = new Hashtable();

            GetPropertiesViaReflection(poCommand, DataValues);

            Dictionary <string, Contract> Sources = new Dictionary <string, Contract>();

            foreach (string sAttrName in moRulesEngine.SourceMap.Keys)
            {
                var contract = this.GetContract(moRulesEngine.SourceMap[sAttrName]);

                Sources[moRulesEngine.SourceMap[sAttrName].SourceId] = contract;
            }

            // Out of gas exception
            // var gas = setValueOnRecordFunction.EstimateGasAsync(sSenderAddress, "SomeAttr", "SomeValue").Result;
            var gas = new Nethereum.Hex.HexTypes.HexBigInteger(1000000);

            foreach (String sTempAttrName in DataValues.Keys)
            {
                WonkaBreSource TempSource = moRulesEngine.SourceMap[sTempAttrName];

                string sSenderAddr = TempSource.SenderAddress;
                string sAttrValue  = (string)DataValues[sTempAttrName];

                var contract = Sources[TempSource.SourceId];

                var setValueOnRecordFunction = contract.GetFunction(TempSource.SetterMethodName);

                if (!String.IsNullOrEmpty(sAttrValue))
                {
                    var receiptSetValueOnRecord =
                        setValueOnRecordFunction.SendTransactionAsync(sSenderAddr, gas, null, sTempAttrName, sAttrValue).Result;
                }
            }
        }
Exemplo n.º 7
0
        public virtual void DeserializeRecordFromBlockchain(ICommand poCommand)
        {
            Hashtable DataValues = new Hashtable();

            Dictionary <string, Contract> Sources = new Dictionary <string, Contract>();

            foreach (string sAttrName in moInitData.BlockchainDataSources.Keys)
            {
                var contract = this.GetContract(moInitData.BlockchainDataSources[sAttrName]);

                Sources[moInitData.BlockchainDataSources[sAttrName].SourceId] = contract;
            }

            // Out of gas exception
            // var gas = setValueOnRecordFunction.EstimateGasAsync(sSenderAddress, "SomeAttr", "SomeValue").Result;
            var gas = new Nethereum.Hex.HexTypes.HexBigInteger(1000000);

            foreach (String sTempAttrName in moInitData.BlockchainDataSources.Keys)
            {
                WonkaBreSource TempSource = moInitData.BlockchainDataSources[sTempAttrName];

                string sSenderAddr = TempSource.SenderAddress;

                var contract = Sources[TempSource.SourceId];

                var getValueOnRecordFunction = contract.GetFunction(TempSource.MethodName);

                string sAttrValue = getValueOnRecordFunction.CallAsync <string>(sTempAttrName).Result;

                if (!String.IsNullOrEmpty(sAttrValue))
                {
                    DataValues[sTempAttrName] = sAttrValue;
                }
            }

            AssignPropertiesViaReflection(poCommand, DataValues);
        }
Exemplo n.º 8
0
        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);
        }
Exemplo n.º 9
0
        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?!");
                }
            }
        }
Exemplo n.º 10
0
        // 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, WonkaBreSource>();
            moCustomOpMap   = new Dictionary <string, WonkaBreSource>();

            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(WonkaEth.Init.WonkaEthInitialization),
                                                               new System.Xml.Serialization.XmlRootAttribute("WonkaEthInitialization"));

                WonkaEth.Init.WonkaEthInitialization WonkaInit =
                    WonkaEthSerializer.Deserialize(new System.IO.StringReader(sInitXml)) as WonkaEth.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 WonkaEth 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(WonkaEth.Init.WonkaEthRegistryInitialization),
                                                               new System.Xml.Serialization.XmlRootAttribute("WonkaEthRegistryInitialization"));

                moWonkaRegistryInit =
                    WonkaEthSerializer.Deserialize(new System.IO.StringReader(sInitRegistryXml)) as WonkaEth.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 WonkaBreSource(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
            WonkaEth.Contracts.WonkaRuleTreeRegistry WonkaRegistry =
                WonkaEth.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);
        }
Exemplo n.º 11
0
        // 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, WonkaBreSource>();
            moCustomOpMap   = new Dictionary <string, WonkaBreSource>();

            var TmpAssembly = Assembly.GetExecutingAssembly();

            WonkaRefEnvironment RefEnv = WonkaRefEnvironment.CreateInstance(false, moMetadataSource);

            WonkaIpfs.WonkaIpfsEnvironment IpfsEnv = WonkaIpfs.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(WonkaEth.Init.WonkaEthInitialization),
                                                               new System.Xml.Serialization.XmlRootAttribute("WonkaEthInitialization"));

                WonkaEth.Init.WonkaEthInitialization WonkaInit =
                    WonkaEthSerializer.Deserialize(new System.IO.StringReader(sInitXml)) as WonkaEth.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(WonkaEth.Init.WonkaEthRegistryInitialization),
                                                               new System.Xml.Serialization.XmlRootAttribute("WonkaEthRegistryInitialization"));

                moWonkaRegistryInit =
                    WonkaEthSerializer.Deserialize(new System.IO.StringReader(sInitRegistryXml)) as WonkaEth.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 WonkaBreSource(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

            WonkaEth.Contracts.WonkaRuleTreeRegistry WonkaRegistry =
                WonkaEth.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);
        }
Exemplo n.º 12
0
        // This constructor will be called in the case that we wish to initialize the framework
        // with provided parameters
        public WonkaCQSOrchTest(string psSenderAddress, string psPassword, string psWonkaContractAddress, string psOrchContractAddress)
        {
            var TmpAssembly = Assembly.GetExecutingAssembly();

            moAttrSourceMap = new Dictionary <string, WonkaBreSource>();
            moCustomOpMap   = new Dictionary <string, WonkaBreSource>();

            // 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 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")))
            {
                msAbiOrchContract = AbiReader.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 RefEnv =
                WonkaRefEnvironment.CreateInstance(false, moMetadataSource);

            msSenderAddress = psSenderAddress;
            msPassword      = psPassword;

            moMetadataSource = new WonkaMetadataTestSource();

            if (psWonkaContractAddress == null)
            {
                msWonkaContractAddress = DeployWonkaContract();
            }
            else
            {
                msWonkaContractAddress = psWonkaContractAddress;
            }

            if (psOrchContractAddress == null)
            {
                msOrchContractAddress = DeployOrchestrationContract();
            }
            else
            {
                msOrchContractAddress = psOrchContractAddress;
            }

            // Serialize the data domain to the blockchain
            RefEnv.Serialize(msSenderAddress, msPassword, msSenderAddress, msWonkaContractAddress, msAbiWonka);

            moDefaultSource =
                new WonkaBreSource(CONST_ORCH_CONTRACT_MARKUP_ID,
                                   msSenderAddress,
                                   msPassword,
                                   psOrchContractAddress,
                                   msAbiOrchContract,
                                   CONST_ORCH_CONTRACT_GET_METHOD,
                                   CONST_ORCH_CONTRACT_SET_METHOD,
                                   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;
            }

            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(CONST_CUSTOM_OP_MARKUP_ID,
                                   msSenderAddress,
                                   msPassword,
                                   psOrchContractAddress,
                                   msAbiOrchContract,
                                   LookupVATDenominator,
                                   CONST_CUSTOM_OP_CONTRACT_METHOD);

            moCustomOpMap[CONST_CUSTOM_OP_MARKUP_ID] = CustomOpSource;
        }
Exemplo n.º 13
0
        /// <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);
            }
        }
Exemplo n.º 14
0
        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);
        }
Exemplo n.º 15
0
        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?!");
                }
            }
        }