private RuleCollectionResult ExecuteRuleCollection()

in src/IdFix/Rules/RulesRunner.cs [308:424]


        private RuleCollectionResult ExecuteRuleCollection(RuleCollection collection, LdapConnection connection)
        {
            // these count all the totals for the connection against which this RuleCollection is being run
            var stopWatch = new Stopwatch();
            long skipCount = 0;
            long entryCount = 0;
            long duplicateCount = 0;
            long errorCount = 0;

            this.OnStatusUpdate?.Invoke(StringLiterals.LdapConnectionEstablishing);
            var searchRequest = collection.CreateSearchRequest();
            this.OnStatusUpdate?.Invoke(StringLiterals.LdapConnectionEstablished);

            var errors = new List<ComposedRuleResult>();

            this.OnStatusUpdate?.Invoke(StringLiterals.BeginningQuery);

            while (true)
            {
                var searchResponse = (SearchResponse)connection.SendRequest(searchRequest);

                // verify support for paged results
                if (searchResponse.Controls.Length != 1 || !(searchResponse.Controls[0] is PageResultResponseControl))
                {
                    this.OnStatusUpdate?.Invoke(StringLiterals.CannotPageResultSet);
                    throw new InvalidOperationException(StringLiterals.CannotPageResultSet);
                }

                foreach (SearchResultEntry entry in searchResponse.Entries)
                {
                    if (this.CancellationPending)
                    {
                        return null;
                    }

                    if (collection.Skip(entry))
                    {
                        skipCount++;
                        continue;
                    }

                    // this tracks the number of entries we have processed and not skipped
                    entryCount++;

                    foreach (var composedRule in collection.Rules)
                    {
                        // run each composed rule which can produce multiple results
                        var results = composedRule.Execute(entry);

                        for (var i = 0; i < results.Length; i++)
                        {
                            var result = results[i];
                            if (!result.Success)
                            {
                                errorCount++;

                                if (result.Results.Any(r => (r.ErrorTypeFlags & ErrorType.Duplicate) != 0))
                                {
                                    duplicateCount++;

                                    if (result.ProposedAction == ActionType.Edit)
                                    {
                                        // Add original LDAP entry with the same value.
                                        var originalEntry = DuplicateStore.GetOriginalSearchResultEntry(result.AttributeName, result.OriginalValue);
                                        var additionalResult = new ComposedRuleResult
                                        {
                                            AttributeName = result.AttributeName,
                                            EntityDistinguishedName = originalEntry.DistinguishedName,
                                            EntityCommonName = originalEntry.Attributes[StringLiterals.Cn][0].ToString(),
                                            ObjectType = ComposedRule.GetObjectType(entry),
                                            OriginalValue = result.OriginalValue,
                                            ProposedAction = result.ProposedAction,
                                            ProposedValue = result.ProposedValue,
                                            Results = new RuleResult[] {
                                                new RuleResult(false)
                                                {
                                                    ErrorTypeFlags = ErrorType.Duplicate,
                                                    ProposedAction = result.ProposedAction,
                                                    UpdatedValue = result.OriginalValue
                                                }
                                            },
                                            Success = result.Success
                                        };
                                        errors.Add(additionalResult);
                                    }
                                }

                                errors.Add(result);
                            }
                        }
                    }
                }

                // handle paging
                var cookie = searchResponse.Controls.OfType<PageResultResponseControl>().First().Cookie;

                // if this is true, there are no more pages to request
                if (cookie.Length == 0)
                    break;

                searchRequest.Controls.OfType<PageResultRequestControl>().First().Cookie = cookie;
            }

            // we are all done, stop tracking time
            stopWatch.Stop();

            return new RuleCollectionResult
            {
                TotalDuplicates = duplicateCount,
                TotalErrors = errorCount,
                TotalFound = skipCount + entryCount,
                TotalSkips = skipCount,
                TotalProcessed = entryCount,
                Elapsed = stopWatch.Elapsed,
                Errors = errors.ToArray()
            };
        }