Пример #1
0
        static void CacheRetention_NeverRetain()
        {
            Console.WriteLine();
            Console.WriteLine("--------------------------------------------------------");
            Console.WriteLine("--- CacheRetention_NeverRetain()");
            Console.WriteLine("--------------------------------------------------------");

            // Ensure RuleApplication cache is empty
            RuleSession.RuleApplicationCache.Clear();
            Console.WriteLine("1) Cached RuleApplications: " + RuleSession.RuleApplicationCache.Count);    // Expecting 0

            // Usage #1 Attempt to explicitly add a RuleApplication to the cache with CacheRetention.NeverRetain via RuleApplicationCache.Add() - RuleApp is compiled, but not reusable
            RuleSession.RuleApplicationCache.Add("NewRuleApplication.ruleappx", CacheRetention.NeverRetain);
            Console.WriteLine("2) Cached RuleApplications: " + RuleSession.RuleApplicationCache.Count);    // Expecting 0

            // Usage #2 Attempt to explicitly add a RuleApplication to the cache with CacheRetention.NeverRetain via RuleApplicationReference.Compile() - RuleApp is compiled, but not reusable
            RuleApplicationReference ruleAppReference = "NewRuleApplication.ruleappx";   // Note: RuleApplicationReference supports implicit casting from file path string, or RuleApplicationDef instance

            ruleAppReference.Compile(CacheRetention.NeverRetain);
            Console.WriteLine("3) Cached RuleApplications: " + RuleSession.RuleApplicationCache.Count);    // Expecting 0

            // Usage #3 Attempt to implicitly add a RuleApplication to the cache with CacheRetention.NeverRetain via RuleSession() - RuleApp is compiled, but not reusable outside of RuleSession
            using (RuleSession session = new RuleSession("NewRuleApplication.ruleappx", CacheRetention.NeverRetain))
            {
                session.CreateEntity("Entity1");
            }
            Console.WriteLine("4) Cached RuleApplications: " + RuleSession.RuleApplicationCache.Count);    // Expecting 0
        }
Пример #2
0
        static void ExplicitCache()
        {
            Console.WriteLine();
            Console.WriteLine("--------------------------------------------------------");
            Console.WriteLine("--- ExplicitCache()");
            Console.WriteLine("--------------------------------------------------------");

            // Ensure RuleApplication cache is empty
            RuleSession.RuleApplicationCache.Clear();
            Console.WriteLine("1) Cached RuleApplications: " + RuleSession.RuleApplicationCache.Count);    // Expecting 0

            // Create in-memory RuleApplications
            RuleApplicationDef ruleAppDef1 = new RuleApplicationDef("MyApp1");

            ruleAppDef1.Entities.Add(new EntityDef("Entity1"));
            RuleApplicationDef ruleAppDef2 = new RuleApplicationDef("MyApp2");

            ruleAppDef2.Entities.Add(new EntityDef("Entity2"));

            // Explicit Cache Usage #1: Explicitly cache MyApp1 via RuleApplicationCache
            RuleApplicationReference ruleAppReference1 = RuleSession.RuleApplicationCache.Add(ruleAppDef1);

            Console.WriteLine("2) Cached RuleApplications: " + RuleSession.RuleApplicationCache.Count);    // Expecting 1

            // Explicit Cache Usage #2: Explicitly cache MyApp2 via RuleApplicationReference.Compile()
            RuleApplicationReference ruleAppReference2 = new InMemoryRuleApplicationReference(ruleAppDef2);

            ruleAppReference2.Compile();
            Console.WriteLine("3) Cached RuleApplications: " + RuleSession.RuleApplicationCache.Count);    // Expecting 2

            // Consumption Usage #1: Create RuleSession with source RuleApplicationDef
            using (RuleSession session = new RuleSession(ruleAppDef1))
            {
                session.CreateEntity("Entity1");
            }
            using (RuleSession session = new RuleSession(ruleAppDef2))
            {
                session.CreateEntity("Entity2");
            }
            Console.WriteLine("4) Cached RuleApplications: " + RuleSession.RuleApplicationCache.Count);    // Still only expecting 2

            // Consumption Usage #2: Create RuleSession with RuleApplicationReference
            using (RuleSession session = new RuleSession(ruleAppReference1))
            {
                session.CreateEntity("Entity1");
            }
            using (RuleSession session = new RuleSession(ruleAppReference2))
            {
                session.CreateEntity("Entity2");
            }
            Console.WriteLine("5) Cached RuleApplications: " + RuleSession.RuleApplicationCache.Count);    // Still only expecting 2
        }
Пример #3
0
        // This policy does not have a maximum depth and does not use the CacheRetention.Weight - It only checks the property MyCacheRetention.Name
        public bool AllowCacheEntry(RuleApplicationReference candidate, IEnumerable <RuleApplicationReference> cachedItems, out IEnumerable <RuleApplicationReference> itemsToExpire)
        {
            // If cache retention is not our own MyCacheRetention, don't cache
            MyCacheRetention retention = candidate.CacheRetention as MyCacheRetention;

            if (retention == null)
            {
                itemsToExpire = null;
                return(false);
            }

            // Do not cache specific retention names
            if (retention.Name == "NOCACHE" || retention.Name == "INVALID")
            {
                itemsToExpire = null;
                return(false);
            }

            // Identify cached items to expire - Expire any RuleApplication whose MyCacheRetention has duplicate name as candidate
            itemsToExpire = cachedItems.Where(item => ((MyCacheRetention)item.CacheRetention).Name == retention.Name);
            return(true);
        }
Пример #4
0
        private static async Task <bool> RetrieveAndWriteIrJSFromDistributionService(RuleApplicationReference ruleRef, string distroKey, string outputPath)
        {
            Console.WriteLine();

            Console.WriteLine("Requesting compiled JS library from Distribution Service...");
            var js = await CallDistributionServiceAsync(ruleRef, "https://api.distribution.inrule.com/", distroKey);

            if (!string.IsNullOrEmpty(js))
            {
                Console.WriteLine("Received compiled library, writing out to " + outputPath);
                try
                {
                    File.WriteAllText(outputPath, js);
                    Console.WriteLine("Compiled and wrote out Javascript Rule App");
                    Console.WriteLine();
                    return(true);
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Error writing out compiled JavaScript file: " + ex.Message);
                }
            }
            return(false);
        }
Пример #5
0
        public static async Task <string> CallDistributionServiceAsync(RuleApplicationReference ruleApplicationRef, string serviceUri, string subscriptionKey)
        {
            using (var client = new HttpClient())
                using (var requestContent = new MultipartFormDataContent())
                {
                    HttpResponseMessage result = null;
                    try
                    {
                        client.BaseAddress = new Uri(serviceUri);

                        // Build up our request by reading in the rule application
                        var ruleApplication = ruleApplicationRef.GetRuleApplicationDef();
                        var httpContent     = new ByteArrayContent(Encoding.UTF8.GetBytes(ruleApplication.GetXml()));
                        requestContent.Add(httpContent, "ruleApplication", ruleApplication.Name + ".ruleapp");

                        // Tell the server we are sending form data
                        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("multipart/form-data"));
                        client.DefaultRequestHeaders.Add("subscription-key", subscriptionKey);

                        // Post the rule application to the irDistribution service API,
                        // enabling Execution and State Change logging, Display Name metadata, and the developer example.
                        var distributionUrl = "package?logOption=Execution&logOption=StateChanges&subscriptionkey=" + subscriptionKey;
                        result = await client.PostAsync(distributionUrl, requestContent).ConfigureAwait(false);

                        // Get the return package from the result

                        dynamic returnPackage = JObject.Parse(await result.Content.ReadAsStringAsync());
                        var     errors        = new StringBuilder();
                        if (returnPackage.Status.ToString() == "Fail")
                        {
                            foreach (var error in returnPackage.Errors)
                            {
                                // Handle errors
                                errors.AppendLine("* " + error.Description.ToString());
                            }
                            foreach (var unsupportedError in returnPackage.UnsupportedFeatures)
                            {
                                // Handle errors
                                errors.AppendLine("* " + unsupportedError.Feature.ToString());
                            }
                            // Still need to stop processing
                            return(errors.ToString());
                        }

                        // Build the download url of the file
                        var downloadUrl = returnPackage.PackagedApplicationDownloadUrl.ToString();

                        // Get the contents
                        HttpResponseMessage resultDownload = await client.GetAsync(downloadUrl);

                        if (!resultDownload.IsSuccessStatusCode)
                        {
                            // Handle errors
                            errors.AppendLine(await resultDownload.Content.ReadAsStringAsync());
                            return(errors.ToString());
                        }
                        return(await resultDownload.Content.ReadAsStringAsync());
                    }
                    catch (InRuleCatalogException icex)
                    {
                        Console.WriteLine("Error retrieving Rule Application to compile: " + icex.Message);
                        return(null);
                    }
                    catch (JsonReaderException)
                    {
                        if (result != null)
                        {
                            Console.WriteLine("Error requesting compiled Rule Application: " + await result.Content.ReadAsStringAsync());
                        }
                        else
                        {
                            Console.WriteLine("Error requesting compiled Rule Application.");
                        }

                        return(null);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("Error requesting compiled Rule Application.");
                        Console.WriteLine(ex.ToString());
                        return(null);
                    }
                }
        }
Пример #6
0
        static async Task <int> Main(string[] args)
        {
            //Required Parameters
            bool   showHelp          = false;
            string irDistributionKey = null;
            string OutputFilePath    = null;
            //Option 1
            string RuleAppFilePath = null;
            //Option 2
            string CatalogUri          = null;
            string CatalogUsername     = null;
            string CatalogPassword     = null;
            string CatalogRuleAppName  = null;
            string CatalogRuleAppLabel = "LIVE";

            var clParams = new OptionSet {
                { "h|help", "Display Help.", k => showHelp = true },
                { "k|DistributionKey=", "The irDistributionKey for your account.", k => irDistributionKey = k },
                { "o|OutputPath=", "Desired Path for the compiled output library.", p => OutputFilePath = p },
                //Option 1
                { "r|RuleAppPath=", "Path to the Rule Application to be compiled.", p => RuleAppFilePath = p },
                //Option 2
                { "c|CatUri=", "Web URI for the IrCatalog Service endpoint.", p => CatalogUri = p },
                { "u|CatUsername="******"IrCatalog Username for authentication.", p => CatalogUsername = p },
                { "p|CatPassword="******"IrCatalog Password for authentication.", p => CatalogPassword = p },
                { "n|CatRuleAppName=", "Name of the Rule Application.", p => CatalogRuleAppName = p },
                { "l|CatLabel=", "Label of the Rule Application to retrieve (LIVE).", p => CatalogRuleAppLabel = p },
            };

            try
            {
                clParams.Parse(args);
            }
            catch (OptionException e)
            {
                Console.Write("Failed parsing execution parameters: " + e.Message);
                showHelp = true;
            }

            RuleApplicationReference ruleApp = null;

            if (showHelp)
            {
                ShowHelp(clParams);
                return(1);
            }
            else if (string.IsNullOrEmpty(irDistributionKey))
            {
                Console.WriteLine("Error: Missing required parameter DistributionKey.");
                return(1);
            }
            else if (string.IsNullOrEmpty(OutputFilePath))
            {
                Console.WriteLine("Error: Missing required parameter OutputPath.");
                return(1);
            }

            if (!string.IsNullOrEmpty(RuleAppFilePath))
            {
                try
                {
                    ruleApp = new FileSystemRuleApplicationReference(RuleAppFilePath);
                }
                catch (IntegrationException ie)
                {
                    Console.WriteLine("Error creating reference to file-based Rule App: " + ie.Message); //Rule App file not found
                }
            }

            if (!string.IsNullOrEmpty(CatalogUri) &&
                !string.IsNullOrEmpty(CatalogUsername) &&
                !string.IsNullOrEmpty(CatalogPassword) &&
                !string.IsNullOrEmpty(CatalogRuleAppName))
            {
                if (ruleApp != null)
                {
                    Console.WriteLine("Error: Parameters were provided for both File- and Catalog-based Rule App; only one may be specified.");
                    return(1);
                }
                else
                {
                    ruleApp = new CatalogRuleApplicationReference(CatalogUri, CatalogRuleAppName, CatalogUsername, CatalogPassword, CatalogRuleAppLabel);
                }
            }

            if (ruleApp == null)
            {
                Console.WriteLine("You must provide either RuleAppPath or all of CatUri, CatUsername, CatPassword, and CatRuleAppName (with optional CatLabel)");
                return(1);
            }
            else
            {
                var success = await RetrieveAndWriteIrJSFromDistributionService(ruleApp, irDistributionKey, OutputFilePath);

                if (success)
                {
                    return(0);
                }
                else
                {
                    return(1);
                }
            }
        }
Пример #7
0
        static void PreCompileExecutableFunctions()
        {
            Console.WriteLine();
            Console.WriteLine("--------------------------------------------------------");
            Console.WriteLine("--- PreCompileExecutableFunctions()");
            Console.WriteLine("--------------------------------------------------------");

            // Ensure RuleApplication cache is empty
            RuleSession.RuleApplicationCache.Clear();
            Console.WriteLine("1)  Cached RuleApplications: " + RuleSession.RuleApplicationCache.Count);    // Expecting 0

            // Create 4 in-memory RuleApplications
            RuleApplicationDef ra1 = new RuleApplicationDef("ra1");

            ra1.Entities.Add(new EntityDef("Entity1")).Fields.Add(new FieldDef("Calculation1", "1 + 2", DataType.Integer));
            RuleApplicationDef ra2 = new RuleApplicationDef("ra2");

            ra2.Entities.Add(new EntityDef("Entity1")).Fields.Add(new FieldDef("Calculation1", "1 + 2", DataType.Integer));
            RuleApplicationDef ra3 = new RuleApplicationDef("ra3");

            ra3.Entities.Add(new EntityDef("Entity1")).Fields.Add(new FieldDef("Calculation1", "1 + 2", DataType.Integer));
            RuleApplicationDef ra4 = new RuleApplicationDef("ra4");

            ra4.Entities.Add(new EntityDef("Entity1")).Fields.Add(new FieldDef("Calculation1", "1 + 2", DataType.Integer));

            // Create 4 RuleApplicationReferences - Note the implicit casting
            RuleApplicationReference raRef1 = ra1;
            RuleApplicationReference raRef2 = ra2;
            RuleApplicationReference raRef3 = ra3;
            RuleApplicationReference raRef4 = ra4;

            // Usage #1: Pre-compile RuleApplications via RuleApplicationCache.Add() - Note EngineLogOptions are compiled into the executable functions
            raRef1.Compile(CompileSettings.Create(EngineLogOptions.Execution | EngineLogOptions.SummaryStatistics));
            raRef2.Compile();
            raRef3.Compile(CompileSettings.Create(EngineLogOptions.SummaryStatistics));
            raRef4.Compile(CompileSettings.Default);
            Console.WriteLine("2)  Cached RuleApplications: " + RuleSession.RuleApplicationCache.Count);    // Expecting 4

            // Usage #2: Pre-compile RuleApplications via RuleApplicationReference.Compile()
            RuleSession.RuleApplicationCache.Add(ra1, CompileSettings.Create(EngineLogOptions.Execution | EngineLogOptions.SummaryStatistics));
            RuleSession.RuleApplicationCache.Add(ra2);
            RuleSession.RuleApplicationCache.Add(ra3, CompileSettings.Create(EngineLogOptions.SummaryStatistics));
            RuleSession.RuleApplicationCache.Add(ra4, CompileSettings.Default);
            Console.WriteLine("3)  Cached RuleApplications: " + RuleSession.RuleApplicationCache.Count);    // Expecting same 4

            // Test ra1 - Metadata + Functions pre-compiled
            Console.WriteLine("--------------------------------------------------------");
            Console.WriteLine("4)  RuleApplication '{0}' Metadata Compile timestamp: {1}", ra1.Name, raRef1.LastMetadataCompile);
            Console.WriteLine("5)  RuleApplication '{0}' Function Compile timestamp: {1}", ra1.Name, raRef1.GetLastFunctionCompile(CompileSettings.Create(EngineLogOptions.Execution | EngineLogOptions.SummaryStatistics)));
            using (RuleSession session = new RuleSession(raRef1))
            {
                session.Settings.LogOptions = EngineLogOptions.Execution | EngineLogOptions.SummaryStatistics;
                session.CreateEntity("Entity1");
                session.ApplyRules();
                Console.WriteLine("6) RuleApplication '{0}' Dynamic Function Compile Count during rule execution: {1}", ra1.Name, session.Statistics.FunctionCompileTime.SampleCount); // Expecting 0 due to function pre-compile
            }

            // Test ra2 - Only Metadata pre-compiled
            Console.WriteLine("--------------------------------------------------------");
            Console.WriteLine("7)  RuleApplication '{0}' Metadata Compile timestamp: {1}", ra2.Name, raRef2.LastMetadataCompile);
            Console.WriteLine("8)  RuleApplication '{0}' Function Compile timestamp: {1}", ra2.Name, raRef2.GetLastFunctionCompile(CompileSettings.Create(EngineLogOptions.Execution | EngineLogOptions.SummaryStatistics)));
            using (RuleSession session = new RuleSession(raRef2))
            {
                session.Settings.LogOptions = EngineLogOptions.Execution | EngineLogOptions.SummaryStatistics;
                session.CreateEntity("Entity1");
                session.ApplyRules();
                Console.WriteLine("9)  RuleApplication '{0}' Dynamic Function Compile Count during rule execution: {1}", ra2.Name, session.Statistics.FunctionCompileTime.SampleCount); // Expecting 1 due to functions not pre-compile
            }

            // Test ra3 - Metadata + Functions pre-compiled
            Console.WriteLine("--------------------------------------------------------");
            Console.WriteLine("10) RuleApplication '{0}' Metadata Compile timestamp: {1}", ra3.Name, raRef3.LastMetadataCompile);
            Console.WriteLine("11) RuleApplication '{0}' Function Compile timestamp: {1}", ra3.Name, raRef3.GetLastFunctionCompile(CompileSettings.Create(EngineLogOptions.SummaryStatistics)));
            using (RuleSession session = new RuleSession(raRef3))
            {
                session.Settings.LogOptions = EngineLogOptions.SummaryStatistics;
                session.CreateEntity("Entity1");
                session.ApplyRules();
                Console.WriteLine("12) RuleApplication '{0}' Dynamic Function Compile Count during rule execution: {1}", ra3.Name, session.Statistics.FunctionCompileTime.SampleCount); // Expecting 0 due to function pre-copile
            }

            // Test ra4 - Metadata + Functions pre-compiled
            Console.WriteLine("--------------------------------------------------------");
            Console.WriteLine("13) RuleApplication '{0}' Metadata Compile timestamp: {1}", ra4.Name, raRef4.LastMetadataCompile);
            Console.WriteLine("14) RuleApplication '{0}' Function Compile timestamp (Default): {1}", ra4.Name, raRef4.GetLastFunctionCompile(CompileSettings.Default));
            // Note: RuleSession Statistics requires EngineLogOptions.SummaryStatistics to be enabled; CompileSettings.Default does not enable SummaryStatistics unless Info logging is enabled in the .config file.

            // Test ra4 Function Compile timestamp for different type of CompileSettings
            Console.WriteLine("15) RuleApplication '{0}' Function Compile timestamp (EngineLogOptions.Execution): {1}", ra4.Name, raRef4.GetLastFunctionCompile(CompileSettings.Create(EngineLogOptions.Execution)));    // Should be missing because we only checked compiled functions for the Default options
        }
Пример #8
0
        private static int RunTestSuite(RuleApplicationReference ruleApp, string testSuiteFilePath)
        {
            RuleApplicationDef ruleAppDef = null;
            TestSuiteDef       suite      = null;

            try
            {
                ruleAppDef = ruleApp.GetRuleApplicationDef();
            }
            catch (Exception ex)
            {
                Console.WriteLine("ERROR: Unable to load Rule App: " + ex.Message);
                return(2);
            }

            try
            {
                if (File.Exists(testSuiteFilePath))
                {
                    Console.WriteLine("Using Test Suite " + testSuiteFilePath);
                }
                else
                {
                    Console.WriteLine("ERROR: Test Suite file not found at " + testSuiteFilePath);
                    throw new FileNotFoundException("ERROR: Test Suite file not found at " + testSuiteFilePath);
                }

                suite = TestSuiteDef.LoadFrom(new ZipFileTestSuitePersistenceProvider(testSuiteFilePath));
                suite.ActiveRuleApplicationDef = ruleAppDef;
            }
            catch (Exception ex)
            {
                Console.WriteLine("ERROR: Unable to load Test Suite: " + ex.Message);
                return(2);
            }

            try
            {
                TestResultCollection results;
                using (TestingSessionManager manager = new TestingSessionManager(new InProcessConnectionFactory()))
                {
                    var session = new RegressionTestingSession(manager, suite);
                    results = session.ExecuteAllTests();
                }

                bool hadFailures = false;
                foreach (var result in results)
                {
                    if (result.RuntimeErrorMessage != null)
                    {
                        Console.WriteLine($"ERROR: Failed to execute test {result.TestDef.DisplayName}: {result.RuntimeErrorMessage}");
                        hadFailures = true;
                    }
                    else if (result.Passed)
                    {
                        Console.WriteLine($"PASS: {result.TestDef.DisplayName}");
                    }
                    else
                    {
                        hadFailures = true;
                        Console.WriteLine($"FAIL: {result.TestDef.DisplayName}");
                        foreach (var failedAssertionResult in result.AssertionResults.Where(ar => ar.Passed == false))
                        {
                            Console.WriteLine($"  {failedAssertionResult.Target} was {failedAssertionResult.ActualValue}, expected value {failedAssertionResult.ExpectedValue}");
                        }
                    }
                }

                if (hadFailures)
                {
                    return(1);
                }
                else
                {
                    return(0);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("ERROR: Failed to execute test suite: " + ex.Message);
                return(2);
            }
        }