Beispiel #1
0
 private static void RefreshContactLinkingDefaultFolderIds(MailboxSession mailboxSession)
 {
     foreach (DefaultFolderType folderType in ContactsSearchFolderCriteria.MyContactsExtended.ScopeDefaultFolderTypes)
     {
         AutomaticLink.RefreshDefaultFolderWithRetry(mailboxSession, folderType);
     }
 }
        public void ItemOperation(COWSettings settings, IDumpsterItemOperations dumpster, COWTriggerAction operation, COWTriggerActionState state, StoreSession session, StoreObjectId itemId, CoreItem item, CoreFolder folder, bool onBeforeNotification, OperationResult result, CallbackContext callbackContext)
        {
            Util.ThrowOnNullArgument(session, "session");
            Util.ThrowOnNullArgument(item, "item");
            EnumValidator.ThrowIfInvalid <COWTriggerAction>(operation, "operation");
            EnumValidator.ThrowIfInvalid <COWTriggerActionState>(state, "state");
            EnumValidator.ThrowIfInvalid <OperationResult>(result, "result");
            COWContactLinking.Tracer.TraceDebug <StoreObjectId>((long)this.GetHashCode(), "COWContactLinking.ItemOperation: processing contact linking for item {0}.", itemId);
            MailboxSession                   mailboxSession                = (MailboxSession)session;
            MailboxInfoForLinking            mailboxInfo                   = MailboxInfoForLinking.CreateFromMailboxSession(mailboxSession);
            ContactLinkingPerformanceTracker performanceTracker            = new ContactLinkingPerformanceTracker(mailboxSession);
            DirectoryPersonSearcher          directoryPersonSearcher       = new DirectoryPersonSearcher(mailboxSession.MailboxOwner);
            ContactStoreForContactLinking    contactStoreForContactLinking = new ContactStoreForCowContactLinking(mailboxSession, performanceTracker);
            ContactLinkingLogger             logger = new ContactLinkingLogger("COWContactLinking", mailboxInfo);
            AutomaticLink automaticLink             = new AutomaticLink(mailboxInfo, logger, performanceTracker, directoryPersonSearcher, contactStoreForContactLinking);

            automaticLink.LinkNewOrUpdatedContactBeforeSave(item, new Func <ContactInfoForLinking, IContactStoreForContactLinking, IEnumerable <ContactInfoForLinking> >(this.GetOtherContactsEnumeratorForCOW));
            if (!onBeforeNotification)
            {
                item.SaveFlags |= PropertyBagSaveFlags.ForceNotificationPublish;
                try
                {
                    item.Save(SaveMode.NoConflictResolution);
                }
                finally
                {
                    item.SaveFlags &= ~PropertyBagSaveFlags.ForceNotificationPublish;
                }
            }
            callbackContext.ContactLinkingProcessingState = ContactLinkingProcessingState.Processed;
        }
Beispiel #3
0
 protected override void UpdateContact(IExtensibleLogger logger, IContactLinkingPerformanceTracker performanceTracker)
 {
     ContactInfoForLinking.Tracer.TraceDebug <VersionedId, string>((long)this.GetHashCode(), "ContactInfoForLinkingFromPropertyBag.UpdateContact: setting link properties AND saving contact with id = {0}; given-name: {1}", base.ItemId, base.GivenName);
     base.RetryOnTransientExceptionCatchObjectNotFoundException(logger, "update of contact Id=" + base.ItemId, delegate
     {
         using (Contact contact = Contact.Bind(this.mailboxSession, base.ItemId, new PropertyDefinition[]
         {
             ContactSchema.PersonId
         }))
         {
             base.SetLinkingProperties(PropertyBagAdaptor.Create(contact));
             AutomaticLink.DisableAutomaticLinkingForItem(contact);
             contact.Save(SaveMode.NoConflictResolution);
         }
     });
     performanceTracker.IncrementContactsUpdated();
 }
Beispiel #4
0
 private void LinkTwoContacts(ContactLinkingOperation operation, ContactInfoForLinking contact1, ContactInfoForLinking contact2)
 {
     if (!contact1.Linked && contact2.Linked)
     {
         this.LogLinkOperation(operation, contact1, contact2);
         this.UpdatePersonaId(contact1, contact2.PersonId);
         contact1.Linked = true;
     }
     else if (contact1.Linked && !contact2.Linked)
     {
         this.LogLinkOperation(operation, contact2, contact1);
         this.UpdatePersonaId(contact2, contact1.PersonId);
         contact2.Linked = true;
     }
     else if (contact1.Linked && contact2.Linked)
     {
         this.LogLinkOperation(operation, contact2, contact1);
         this.UpdatePersonaId(contact2, contact1.PersonId);
     }
     else
     {
         if (!contact2.IsNew && contact1.IsNew)
         {
             this.LogLinkOperation(operation, contact1, contact2);
             this.UpdatePersonaId(contact1, contact2.PersonId);
         }
         else
         {
             this.LogLinkOperation(operation, contact2, contact1);
             this.UpdatePersonaId(contact2, contact1.PersonId);
         }
         contact1.Linked = true;
         contact2.Linked = true;
     }
     contact1.LinkRejectHistory.UnionWith(contact2.LinkRejectHistory);
     contact2.LinkRejectHistory = contact1.LinkRejectHistory;
     AutomaticLink.MergeGALLinkState(contact1, contact2);
 }
Beispiel #5
0
        internal static void PerformContactLinkingAfterMigration(StoreSession storeSession)
        {
            MailboxSession mailboxSession = storeSession as MailboxSession;

            if (mailboxSession == null)
            {
                ContactLink.Tracer.TraceDebug(0L, "AutomaticLink::PerformContactLinkingAfterMigration. Skiping session as it is not a MailboxSession.");
                return;
            }
            ContactLink.Tracer.TraceDebug <MailboxSession>(0L, "StoreSession::PerformContactLinking. Starting linking for {0}.", mailboxSession);
            ExDateTime                        exDateTime                        = ExDateTime.Now.Add(AutomaticLink.AllocatedTimeSlotForLinkingOnMigration.Value);
            MailboxInfoForLinking             mailboxInfoForLinking             = MailboxInfoForLinking.CreateFromMailboxSession(mailboxSession);
            ContactLinkingPerformanceTracker  performanceTracker                = new ContactLinkingPerformanceTracker(mailboxSession);
            DirectoryPersonSearcher           directoryPersonSearcher           = new DirectoryPersonSearcher(mailboxSession.MailboxOwner);
            ContactStoreForBulkContactLinking contactStoreForBulkContactLinking = new ContactStoreForBulkContactLinking(mailboxSession, performanceTracker);
            ContactLinkingLogger              contactLinkingLogger              = new ContactLinkingLogger("PerformContactLinkingAfterMigration", mailboxInfoForLinking);
            bool flag = false;

            contactLinkingLogger.LogEvent(new SchemaBasedLogEvent <ContactLinkingLogSchema.MigrationStart>
            {
                {
                    ContactLinkingLogSchema.MigrationStart.DueTime,
                    (DateTime)exDateTime
                }
            });
            try
            {
                AutomaticLink.RefreshContactLinkingDefaultFolderIds(mailboxSession);
                AutomaticLink automaticLink = new AutomaticLink(mailboxInfoForLinking, contactLinkingLogger, performanceTracker, directoryPersonSearcher, contactStoreForBulkContactLinking);
                automaticLink.LinkAllExistingContactsTimeBound(exDateTime);
                flag = true;
            }
            catch (DefaultFolderNameClashException e)
            {
                AutomaticLink.TraceAndLogExceptionDuringLinkingPostMigration(mailboxInfoForLinking, contactLinkingLogger, e);
            }
            catch (AccessDeniedException e2)
            {
                AutomaticLink.TraceAndLogExceptionDuringLinkingPostMigration(mailboxInfoForLinking, contactLinkingLogger, e2);
            }
            catch (ConnectionFailedTransientException e3)
            {
                AutomaticLink.TraceAndLogExceptionDuringLinkingPostMigration(mailboxInfoForLinking, contactLinkingLogger, e3);
            }
            catch (FolderSaveTransientException e4)
            {
                AutomaticLink.TraceAndLogExceptionDuringLinkingPostMigration(mailboxInfoForLinking, contactLinkingLogger, e4);
            }
            catch (MailboxUnavailableException e5)
            {
                AutomaticLink.TraceAndLogExceptionDuringLinkingPostMigration(mailboxInfoForLinking, contactLinkingLogger, e5);
            }
            catch (ObjectNotFoundException e6)
            {
                AutomaticLink.TraceAndLogExceptionDuringLinkingPostMigration(mailboxInfoForLinking, contactLinkingLogger, e6);
            }
            catch (StorageTransientException e7)
            {
                AutomaticLink.TraceAndLogExceptionDuringLinkingPostMigration(mailboxInfoForLinking, contactLinkingLogger, e7);
            }
            catch (StoragePermanentException e8)
            {
                AutomaticLink.TraceAndLogExceptionDuringLinkingPostMigration(mailboxInfoForLinking, contactLinkingLogger, e8);
            }
            catch (Exception e9)
            {
                AutomaticLink.TraceAndLogExceptionDuringLinkingPostMigration(mailboxInfoForLinking, contactLinkingLogger, e9);
                throw;
            }
            finally
            {
                contactLinkingLogger.LogEvent(new SchemaBasedLogEvent <ContactLinkingLogSchema.MigrationEnd>
                {
                    {
                        ContactLinkingLogSchema.MigrationEnd.Success,
                        flag
                    }
                });
                ContactLink.Tracer.TraceDebug <MailboxInfoForLinking, bool>(0L, "AutomaticLink::PerformContactLinkingAfterMigration. Done processing {0}. Contact linking completed successfully: {1}", mailboxInfoForLinking, flag);
            }
        }
Beispiel #6
0
        private HashSet <ContactInfoForLinking> LinkWithContacts(ContactInfoForLinking contactBeingSaved, IEnumerable <ContactInfoForLinking> otherContacts, int maxLinkCount, out bool linkedToDirectory)
        {
            linkedToDirectory = false;
            HashSet <ContactInfoForLinking> hashSet = new HashSet <ContactInfoForLinking>(ContactInfoForLinkingComparerByItemId.Instance);
            PersonId           personId             = contactBeingSaved.PersonId;
            HashSet <PersonId> hashSet2             = new HashSet <PersonId>();
            ContactInfoForLinkingFromDirectory contactInfoForLinkingFromDirectory = null;

            if (contactBeingSaved.GALLinkState != GALLinkState.NotAllowed && contactBeingSaved.GALLinkID == null)
            {
                this.TryFindDirectoryMatch(contactBeingSaved, out contactInfoForLinkingFromDirectory);
            }
            foreach (ContactInfoForLinking contactInfoForLinking in otherContacts)
            {
                if (!this.CanContinueProcessingContacts())
                {
                    break;
                }
                if (!contactInfoForLinking.PersonId.Equals(personId) && !ContactInfoForLinkingComparerByItemId.Instance.Equals(contactInfoForLinking, contactBeingSaved) && !hashSet2.Contains(contactInfoForLinking.PersonId))
                {
                    ContactLinkingOperation contactLinkingOperation = AutomaticLinkCriteria.CanLink(contactBeingSaved, contactInfoForLinking);
                    if (contactInfoForLinkingFromDirectory != null && contactInfoForLinking.GALLinkState == GALLinkState.Linked && contactInfoForLinking.GALLinkID == contactInfoForLinkingFromDirectory.GALLinkID)
                    {
                        if (contactLinkingOperation == ContactLinkingOperation.None)
                        {
                            contactLinkingOperation = ContactLinkingOperation.AutoLinkViaGalLinkId;
                        }
                        contactInfoForLinkingFromDirectory = null;
                    }
                    if (AutomaticLink.ShouldLink(contactLinkingOperation))
                    {
                        hashSet2.Add(contactInfoForLinking.PersonId);
                        HashSet <ContactInfoForLinking> hashSet3 = new HashSet <ContactInfoForLinking>(this.contactStoreForContactLinking.GetPersonContacts(contactInfoForLinking.PersonId));
                        if (hashSet3.Count + hashSet.Count <= maxLinkCount)
                        {
                            hashSet.UnionWith(hashSet3);
                            this.LinkTwoContacts(contactLinkingOperation, contactBeingSaved, contactInfoForLinking);
                            if (hashSet.Count == maxLinkCount)
                            {
                                string text = string.Format(CultureInfo.InvariantCulture, "Stopping linking iteration for PersonID {0}  because we have reached maximum number of contacts for the persona.", new object[]
                                {
                                    contactBeingSaved.PersonId
                                });
                                ContactLink.Tracer.TraceDebug <string>((long)this.GetHashCode(), "AutomaticLinking.LinkWithContacts: {0}", text);
                                base.LogEvent(new SchemaBasedLogEvent <ContactLinkingLogSchema.Warning>
                                {
                                    {
                                        ContactLinkingLogSchema.Warning.Context,
                                        text
                                    }
                                });
                                break;
                            }
                        }
                        else
                        {
                            ContactLink.Tracer.TraceDebug <PersonId, VersionedId>((long)this.GetHashCode(), "AutomaticLinking.LinkWithContacts: Skipping link with PersonID {0} for item {1} because we would be over the maximum number of contacts for the persona.", contactInfoForLinking.PersonId, contactBeingSaved.ItemId);
                            this.LogSkippedContactLinking(contactBeingSaved, hashSet.Count, maxLinkCount, contactInfoForLinking, hashSet3.Count);
                        }
                    }
                }
            }
            if (contactInfoForLinkingFromDirectory != null && contactBeingSaved.GALLinkState != GALLinkState.Linked)
            {
                this.LogGALLinkOperation(contactBeingSaved, contactInfoForLinkingFromDirectory);
                contactBeingSaved.SetGALLink(contactInfoForLinkingFromDirectory);
                linkedToDirectory = true;
            }
            return(hashSet);
        }