public override RuleResult Run()

in Source/Rules/BatchFrequencyRule.cs [43:130]


        public override RuleResult Run(IEnumerable<ServiceCallItem> items, ServiceCallStats stats)
        {
            RuleResult result = InitializeResult(DisplayName,Description);
            //check invalid log versions
            if (items.Count(item => item.m_logVersion == Constants.Version1509) > 0)
            {
                result.AddViolation(ViolationLevel.Warning, "Data version does not support this rule. You need an updated Xbox Live SDK to support this rule");
                return result;
            }

            StringBuilder description = new StringBuilder();

            // Traverse through each pattern set found in rule parameter
            foreach (var pattern in m_MatchPatterns)
            {
                Dictionary<ServiceCallItem, int> matchesFoundDict = new Dictionary<ServiceCallItem, int>();
                
                foreach (ServiceCallItem thisItem in items)
                {
                    Match match = Regex.Match(thisItem.m_uri, pattern.Key);
                    if (match.Success)
                    {
                        try
                        {
                            JObject requestBodyJSON = JObject.Parse(thisItem.m_reqBody);
                            var values = requestBodyJSON.SelectToken(pattern.Value) as JArray;
                            if (values != null)
                            {
                                matchesFoundDict.Add(thisItem, values.Count);
                            }
                        }
                        catch (Exception)
                        {
                            // ignored
                        }
                    }
                }  // finished traversing calls made to endpoint

                m_totalBatchCallCount = (UInt32)matchesFoundDict.Count;

                // For all the matches found, report on batch sets which happened within a specific time window
                int numDictItems = matchesFoundDict.Count;
                if (numDictItems >= 2)
                {
                    int startWindowIdx = 0;
                    List<ServiceCallItem> callsWithinWindow = new List<ServiceCallItem>();
                    int totalXUIDsForWindow = 0; 
                    totalXUIDsForWindow += matchesFoundDict.Values.ElementAt(startWindowIdx);
                    callsWithinWindow.Add(matchesFoundDict.Keys.ElementAt(startWindowIdx));
                    for (int endWindowIdx = 1; endWindowIdx < matchesFoundDict.Count(); ++endWindowIdx)
                    {
                        UInt64 timeElapsed = (UInt64)Math.Abs((float)
                            (matchesFoundDict.Keys.ElementAt(endWindowIdx).m_reqTimeUTC - matchesFoundDict.Keys.ElementAt(startWindowIdx).m_reqTimeUTC) / TimeSpan.TicksPerMillisecond);
                        if (timeElapsed <= m_BatchSetDetectionWindowsMs)
                        {
                            callsWithinWindow.Add(matchesFoundDict.Keys.ElementAt(endWindowIdx));
                            totalXUIDsForWindow += matchesFoundDict.Values.ElementAt(endWindowIdx);
                        }
                        else //exceeded window
                        {
                            if (callsWithinWindow.Count >= 2)
                            {
                                result.AddViolation(ViolationLevel.Warning, $"A set of {callsWithinWindow.Count} Batch Calls was found within a time window of ({m_BatchSetDetectionWindowsMs}ms) to endpoint. Total XUID count ({totalXUIDsForWindow}). Consider combining into one call.", callsWithinWindow);
                            }

                            startWindowIdx = endWindowIdx; // shift window
                            //reset figures
                            totalXUIDsForWindow = 0;
                            callsWithinWindow.Clear();
                        }
                    }
                    // in case we exited the last for early because we never exceeded the time window, then call
                    // the following function once more to handle any dangling reports.
                    if (callsWithinWindow.Count >= 2)
                    {
                        result.AddViolation(ViolationLevel.Warning, $"A set of {callsWithinWindow.Count} Batch Calls was found within a time window of ({m_BatchSetDetectionWindowsMs}ms) to endpoint. Total XUID count ({totalXUIDsForWindow}). Consider combining into one call.", callsWithinWindow);
                    }
                }
            } // end of foreach pattern in patterns

             
            result.Results.Add("Total Batch Calls", m_totalBatchCallCount);
            result.Results.Add("Allowed Time Between Calls in ms", m_BatchSetDetectionWindowsMs);
            result.Results.Add("Times Exceeded", result.ViolationCount);
            result.Results.Add("Potential Reduced Call Count", m_totalBatchCallCount - result.ViolationCount);

            return result;
        }