Exemple #1
0
        public async Task UpdateGroupAsync(GroupMemberDiff memberDiff, bool ignoreChangeLimit = false)
        {
            if (memberDiff is null)
            {
                throw new ArgumentNullException(nameof(memberDiff));
            }
            if (!ignoreChangeLimit && memberDiff.ChangeRatio < _changeRatioLowerLimit)
            {
                throw new ChangeRatioException();
            }
            IGroupStore store = GetGroupStore(memberDiff.Document);

            foreach (GroupMember member in memberDiff.Remove)
            {
                await store.RemoveGroupMemberAsync(member, memberDiff.Document.GroupId);

                await _logger?.StoreOperationalLogItemAsync(new OperationalLogItem(memberDiff.Document, GroupMemberOperations.Remove, member));
            }
            foreach (GroupMember member in memberDiff.Add)
            {
                await store.AddGroupMemberAsync(member, memberDiff.Document.GroupId);

                await _logger?.StoreOperationalLogItemAsync(new OperationalLogItem(memberDiff.Document, GroupMemberOperations.Add, member));
            }
        }
Exemple #2
0
        public async Task <IActionResult> GetDiffAsync(bool unchanged)
        {
            Grouper         backend = GetGrouperBackend();
            GroupMemberDiff diff    = await backend.GetMemberDiffAsync(await Helper.MakeDocumentAsync(Request), unchanged);

            return(Ok(diff));
        }
        public async Task <IActionResult> GetDiffForStoredDocumentAsync(Guid id, bool unchanged)
        {
            GrouperDocumentEntry entry = (await GetDocumentDb().GetEntriesByDocumentIdAsync(id)).FirstOrDefault();

            if (entry == null)
            {
                return(BadRequest());
            }
            // Grouper backend = GetGrouperBackend();
            GroupMemberDiff diff = await _grouperBackend.GetMemberDiffAsync(entry.Document, unchanged);

            return(Ok(diff));
        }
Exemple #4
0
        public void TestSerializedPropertyNames()
        {
            GroupMemberDiff diff = new GroupMemberDiff(
                document: TestHelpers.MakeDocument(),
                addMemberCollection: new GroupMemberCollection(),
                removeMemberCollection: new GroupMemberCollection(),
                unchangedMemberCollection: new GroupMemberCollection(),
                changeRatio: 0
                );
            string  serializedDiff = JsonConvert.SerializeObject(diff);
            JObject obj            = JObject.Parse(serializedDiff);

            Assert.True(obj.ContainsKey("document"));
            Assert.True(obj.ContainsKey("add"));
            Assert.True(obj.ContainsKey("remove"));
            Assert.True(obj.ContainsKey("unchanged"));
            Assert.True(obj.ContainsKey("ratio"));
        }
Exemple #5
0
        public async Task <IActionResult> InvokeGrouper(bool ignoreChangelimit)
        {
            GrouperDocument document = await Helper.MakeDocumentAsync(Request);

            Grouper         grouper = GetGrouperBackend();
            GroupMemberDiff diff    = await grouper.GetMemberDiffAsync(document);

            // await grouper.UpdateGroupAsync(diff, ignoreChangelimit);
            var changes = new List <OperationalLogItem>();

            foreach (GroupMember member in diff.Add)
            {
                changes.Add(new OperationalLogItem(document, GroupMemberOperations.Add, member));
            }
            foreach (GroupMember member in diff.Remove)
            {
                changes.Add(new OperationalLogItem(document, GroupMemberOperations.Remove, member));
            }
            return(Ok(changes));
        }
Exemple #6
0
        public void TestConstruction()
        {
            double                ratio = 0.5;
            GrouperDocument       doc   = TestHelpers.MakeDocument();
            GroupMemberCollection add   = new GroupMemberCollection();

            add.Add(new GroupMember(Guid.Empty, "M1", GroupMemberTypes.AzureAd));
            GroupMemberCollection remove = new GroupMemberCollection();

            remove.Add(new GroupMember(Guid.Empty, "M2", GroupMemberTypes.AzureAd));
            GroupMemberCollection unchanged = new GroupMemberCollection();

            unchanged.Add(new GroupMember(Guid.Empty, "M3", GroupMemberTypes.AzureAd));
            GroupMemberDiff diff = new GroupMemberDiff(doc, add, remove, unchanged, ratio);

            Assert.NotNull(diff.Add.FirstOrDefault(m => m.DisplayName == "M1"));
            Assert.NotNull(diff.Remove.FirstOrDefault(m => m.DisplayName == "M2"));
            Assert.NotNull(diff.Unchanged.FirstOrDefault(m => m.DisplayName == "M3"));
            Assert.Equal(ratio, diff.ChangeRatio);
            Assert.Equal(doc, diff.Document);
        }
Exemple #7
0
        private void InvokeGrouper(object source, ElapsedEventArgs e)
        {
            Timer timer = (Timer)source;
            List <GrouperDocumentEntry> entries = new List <GrouperDocumentEntry>();
            bool processAllDocuments            = ShouldProcessAllDocuments();

            if (processAllDocuments)
            {
                _lastFullProcessHour = DateTime.Now.Hour;
                entries.AddRange(_documentDb.GetAllEntriesAsync().GetAwaiter().GetResult());
            }
            else
            {
                // Get documents that changed since the last timer event.
                // It doesn't matter if we miss a document. It will be processed in the next full run
                DateTime start = DateTime.Now.AddMilliseconds(-_workInterval);
                entries.AddRange(_documentDb.GetEntriesByAgeAsync(start).GetAwaiter().GetResult());

                // Get documents that have a processing interval hint and
                // where the interval has passed.
                IEnumerable <GrouperDocumentEntry> entriesWithInterval =
                    _documentDb.GetEntriesByProcessingInterval(min: 1).GetAwaiter().GetResult();
                foreach (GrouperDocumentEntry entry in entriesWithInterval)
                {
                    if (_lastProcessedDictionary.TryGetValue(entry.Document.Id, out DateTime lastProcessed))
                    {
                        if (lastProcessed.AddMinutes(entry.Document.ProcessingInterval) < DateTime.Now)
                        {
                            entries.Add(entry);
                        }
                        // If it's not in the dictionary, process interval was added to the document
                        // after the service started and the document should be picked up by the
                        // document age check above (this includes both new and changed documents)
                    }
                }
            }
            foreach (GrouperDocumentEntry entry in entries)
            {
                DebugPrint("Processing group {0}", entry.GroupName);
                if (_stopRequested)
                {
                    return;
                }
                try
                {
                    GroupMemberDiff diff = _grouper.GetMemberDiffAsync(entry.Document).GetAwaiter().GetResult();
                    _grouper.UpdateGroupAsync(diff).GetAwaiter().GetResult();
                    if (entry.Document.ProcessingInterval > 0)
                    {
                        _lastProcessedDictionary[entry.Document.Id] = DateTime.Now;
                    }
                    DebugPrint("Processed group {0}. {1} added, {2} removed.", entry.GroupName, diff.Add.Count(), diff.Remove.Count());
                }
                catch (Exception ex)
                {
                    string message = ex.Message;
                    if (ex.InnerException != null)
                    {
                        message = ex.InnerException.Message;
                    }
                    WriteToLogDb(entry.Document, message, LogLevels.Error);
                    if (!(ex is GroupNotFoundException || ex is MemberNotFoundException || ex is ChangeRatioException))
                    {
                        WriteToEventLog(message, EventLogEntryType.Error);
                    }
                }
            }
            // There is a memory leak somewhere. Likely in Exo. So we tear down Grouper and build a new one after
            // every full run and see if that helps narrow down the leak.
            if (processAllDocuments)
            {
                SetupGrouper();
            }
            if (!_stopRequested)
            {
                timer.Enabled = true;
            }
        }