public bool ReplicateAssociation(IAssociationAdaptor masterAdaptor, params MailboxAssociation[] associations) { ArgumentValidator.ThrowIfNull("associations", associations); ArgumentValidator.ThrowIfZeroOrNegative("associations.Length", associations.Length); PriorityReplicator.Tracer.TraceDebug((long)this.GetHashCode(), "PriorityReplicator::ReplicateAssociations"); bool flag = true; MailboxAssociation priorityAssociation = this.GetAssociationWithPriority(masterAdaptor, associations); if (priorityAssociation != null) { PriorityReplicator.Tracer.TraceDebug((long)this.GetHashCode(), "PriorityReplicator::ReplicateAssociations. Found priority association"); flag &= this.priorityReplicator.ReplicateAssociation(masterAdaptor, new MailboxAssociation[] { priorityAssociation }); MailboxAssociation[] array = (from association in associations where !association.Equals(priorityAssociation) select association).ToArray <MailboxAssociation>(); PriorityReplicator.Tracer.TraceDebug <int>((long)this.GetHashCode(), "PriorityReplicator::ReplicateAssociations. Found {0} association to replicate via RPC", array.Length); if (array.Length > 0) { flag &= this.defaultReplicator.ReplicateAssociation(masterAdaptor, array); } } else { PriorityReplicator.Tracer.TraceDebug <int>((long)this.GetHashCode(), "PriorityReplicator::ReplicateAssociations. Priority association not found. Found {0} association to replicate via RPC", associations.Length); flag &= this.defaultReplicator.ReplicateAssociation(masterAdaptor, associations); } return(flag); }
private void ProcessFailure(MailboxAssociation association, string failureDescription) { association.LastSyncError = failureDescription; association.SyncAttempts++; if (InProcessAssociationReplicator.ShouldStopReplicatingAssociation(association)) { this.Logger.LogEvent(new SchemaBasedLogEvent <MailboxAssociationLogSchema.CommandExecution> { { MailboxAssociationLogSchema.CommandExecution.Command, "InProcessAssociationReplicator.Poison" }, { MailboxAssociationLogSchema.CommandExecution.GroupMailbox, association.Group }, { MailboxAssociationLogSchema.CommandExecution.UserMailboxes, association.User } }); association.SyncedVersion = int.MaxValue; } this.PerformanceTracker.IncrementFailedAssociationReplications(); this.LogError(failureDescription); }
public void ReplicateQueuedAssociations() { QueuedInProcessAssociationReplicator.Tracer.TraceDebug((long)this.GetHashCode(), "MailboxTaskProcessor.ReplicateQueuedAssociations: Processing associations."); ADUser mailboxAdUser = this.mailbox.FindAdUser(); IDiagnosticsFrameFactory <IExtensibleLogger, IMailboxAssociationPerformanceTracker> diagnosticsFrameFactory = this.diagnosticsFrameFactoryCreator(); IMailboxAssociationPerformanceTracker performanceTracker = diagnosticsFrameFactory.CreatePerformanceTracker(null); IExtensibleLogger logger = diagnosticsFrameFactory.CreateLogger(mailboxAdUser.ExchangeGuid, mailboxAdUser.OrganizationId); IAssociationReplicator replicator = this.immediateReplicatorCreator(logger, performanceTracker); using (MailboxAssociationDiagnosticsFrameFactory.Default.CreateDiagnosticsFrame("QueuedInProcessAssociationReplicator", "ReplicateAssociations", logger, performanceTracker)) { bool inProcessReplicationSucceeded = true; GroupMailboxAccessLayerHelper.ExecuteOperationWithRetry(logger, "QueuedInProcessAssociationReplicator.ReplicateAssociations", delegate { IStoreBuilder storeBuilder = this.storeBuilderCreator(logger, this.clientInfoString); using (IAssociationStore associationStore = storeBuilder.Create(this.mailbox, performanceTracker)) { QueuedInProcessAssociationReplicator.Tracer.TraceDebug <string>((long)this.GetHashCode(), "QueuedInProcessAssociationReplicator.ReplicateAssociationsImplementation: Created store provider. Mailbox={0}.", mailboxAdUser.ExternalDirectoryObjectId); UserAssociationAdaptor masterAdaptor = new UserAssociationAdaptor(associationStore, this.adSession, this.mailbox); while (this.pendingAssociations.Count > 0) { MailboxAssociation association = this.pendingAssociations.Dequeue(); inProcessReplicationSucceeded &= this.ReplicateSingleAssociation(replicator, masterAdaptor, association); } if (!inProcessReplicationSucceeded) { IReplicationAssistantInvoker replicationAssistantInvoker = this.replicationAssistantInvokerCreator(logger, this.replicationServerFqdn); replicationAssistantInvoker.Invoke("QueuedInProcessAssociationReplicatorRpcReplication", masterAdaptor, new MailboxAssociation[0]); } } }, new Predicate <Exception>(GrayException.IsGrayException)); } QueuedInProcessAssociationReplicator.Tracer.TraceDebug((long)this.GetHashCode(), "MailboxTaskProcessor.SendNotificationImplementation: Task completed."); }
private bool IsUserMemberOfGroup(MailboxAssociation association) { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); bool result; try { IAadClient aadclient = this.GetAADClient(association); if (aadclient != null) { result = aadclient.IsUserMemberOfGroup(association.User.ExternalId, association.Group.ExternalId); } else { result = false; } } finally { stopwatch.Stop(); if (this.performanceTracker != null) { this.performanceTracker.SetAADQueryLatency(stopwatch.ElapsedMilliseconds); } } return(result); }
private void SaveAssociationInternal(MailboxAssociation association, bool incrementReplicationVersion, Action <MailboxAssociation, IMailboxAssociationBaseItem> updateFunction) { ArgumentValidator.ThrowIfNull("association", association); ArgumentValidator.ThrowIfNull("updateFunction", updateFunction); using (IMailboxAssociationBaseItem mailboxAssociationBaseItem = this.ReadOrCreateMailboxItem(association)) { bool isMember = mailboxAssociationBaseItem.IsMember; updateFunction(association, mailboxAssociationBaseItem); if (incrementReplicationVersion) { this.Tracer.TraceDebug <MailboxAssociation>((long)this.GetHashCode(), "BaseAssociationAdaptor.SaveAssociationInternal. Incrementing CurrentVersion of the association item. Association = {0}", association); mailboxAssociationBaseItem.CurrentVersion++; association.CurrentVersion++; } else { this.Tracer.TraceDebug <MailboxAssociation>((long)this.GetHashCode(), "BaseAssociationAdaptor.SaveAssociationInternal. Saving association without affecting CurrentVersion of the item. Association = {0}", association); } this.associationStore.SaveAssociation(mailboxAssociationBaseItem); if (!isMember && association.IsMember && this.OnAfterJoin != null) { this.OnAfterJoin(this.GetSlaveMailboxLocator(association)); } } }
private bool VerifyMembershipState(MailboxAssociation association) { if (association.IsPin && !association.IsMember && (ExEnvironment.IsTest || this.isModernGroupsNewArchitecture)) { UpdateAssociationCommand.Tracer.TraceDebug <UserMailboxLocator, GroupMailboxLocator>((long)this.GetHashCode(), "User {0} is trying to pin, but membership for {1} is not updated. Trying to fix it", association.User, association.Group); if (!this.IsUserMemberOfGroup(association)) { UpdateAssociationCommand.Tracer.TraceDebug <UserMailboxLocator, string>((long)this.GetHashCode(), "User {0} is not a member for {1} in AAD, ignoring it", association.User, association.Group.ExternalId); throw new NotAMemberException(Strings.CannotPinGroupForNonMember); } UpdateAssociationCommand.Tracer.TraceDebug <UserMailboxLocator, string>((long)this.GetHashCode(), "User {0} is a member for {1} but not marked in EXO. Fixing it", association.User, association.Group.ExternalId); association.IsMember = true; association.JoinDate = ExDateTime.UtcNow; this.Logger.LogEvent(new SchemaBasedLogEvent <MailboxAssociationLogSchema.Warning> { { MailboxAssociationLogSchema.Warning.Context, "SetGroupPinState" }, { MailboxAssociationLogSchema.Warning.Message, string.Format("User {0} is a member for {1} but not marked in EXO. Fixing it", association.User.ExternalId, association.Group.ExternalId) } }); } return(true); }
private static bool ShouldStopReplicatingAssociation(MailboxAssociation association) { bool flag = association.SyncAttempts > 30 && association.JoinDate.Add(InProcessAssociationReplicator.TimeRequiredAfterJoinToStopAssociationReplicationAttempts) < ExDateTime.UtcNow; InProcessAssociationReplicator.Tracer.TraceDebug <bool, MailboxAssociation>(0L, "InProcessAssociationReplicator.ShouldStopReplicatingAssociation. Stop replicating = {0}. Association = {1}.", flag, association); return(flag); }
public void Execute() { List <MailboxAssociation> list = new List <MailboxAssociation>(this.ItemLocators.Length); foreach (IMailboxLocator mailboxLocator in this.ItemLocators) { MailboxAssociation mailboxAssociation = this.LoadAssociation(mailboxLocator); if (this.UpdateAssociation(mailboxAssociation)) { this.SaveAssociation(mailboxAssociation); list.Add(mailboxAssociation); UpdateAssociationCommand.Tracer.TraceDebug <UserMailboxLocator>((long)this.GetHashCode(), "Saved association for user {0}", mailboxAssociation.User); } else if (mailboxAssociation.IsOutOfSync(this.MasterAdaptor.MasterLocator.IdentityHash)) { list.Add(mailboxAssociation); UpdateAssociationCommand.Tracer.TraceDebug <UserMailboxLocator>((long)this.GetHashCode(), "Ignored saving association for user {0}, but association is out of sync, so replication will be attempted.", mailboxAssociation.User); } else { UpdateAssociationCommand.Tracer.TraceDebug <UserMailboxLocator>((long)this.GetHashCode(), "Ignored saving association for user {0}", mailboxAssociation.User); } } IAssociationReplicator associationReplicator = this.GetAssociationReplicator(); if (list.Count > 0 && associationReplicator != null) { associationReplicator.ReplicateAssociation(this.MasterAdaptor, list.ToArray()); } this.OnPostExecute(); }
internal GroupMailbox GetGroupMailbox(GroupMailboxLocator group, UserMailboxLocator user, bool loadAllDetails = false) { GroupMailbox mailbox; using (IAssociationStore associationStore = this.storeProviderBuilder.Create(group, this.PerformanceTracker)) { UserAssociationAdaptor userAssociationAdaptor = new UserAssociationAdaptor(associationStore, this.adSession, group); MailboxAssociation association = userAssociationAdaptor.GetAssociation(user); GroupMailboxBuilder groupMailboxBuilder = new GroupMailboxBuilder(group); groupMailboxBuilder.BuildFromAssociation(association); if (loadAllDetails) { ADUser aduser = group.FindAdUser(); if (aduser == null) { GroupMailboxAccessLayer.Tracer.TraceWarning <string>((long)this.GetHashCode(), "GroupMailboxAccessLayer::GetGroupMailbox. Unable to find group. LegacyDN={0}", group.LegacyDn); throw new MailboxNotFoundException(ServerStrings.ADUserNotFoundId(group.LegacyDn)); } GroupMailboxAccessLayer.Tracer.TraceDebug <string, bool, string>((long)this.GetHashCode(), "GroupMailboxAccessLayer::GetGroupMailbox. Found ADUser for group. LegacyDN={0}, IsCached={1}, OriginatingServer={2}", group.LegacyDn, aduser.IsCached, aduser.OriginatingServer); groupMailboxBuilder.BuildFromDirectory(aduser); } mailbox = groupMailboxBuilder.Mailbox; } return(mailbox); }
protected MailboxAssociation LoadAssociation(IMailboxLocator mailboxLocator) { ArgumentValidator.ThrowIfNull("mailboxLocator", mailboxLocator); MailboxAssociation association = this.MasterAdaptor.GetAssociation(mailboxLocator); UpdateAssociationCommand.Tracer.TraceDebug <IMailboxLocator, MailboxAssociation>((long)this.GetHashCode(), "LoadAssociation: mailboxLocator={0}, association={1}", mailboxLocator, association); return(association); }
protected void SaveAssociation(MailboxAssociation association) { UpdateAssociationCommand.Tracer.TraceDebug <MailboxAssociation>((long)this.GetHashCode(), "SaveAssociation: {0}", association); ArgumentValidator.ThrowIfNull("association", association); bool markForReplication = this.GetAssociationReplicator() != null; this.MasterAdaptor.SaveAssociation(association, markForReplication); }
protected override void UpdateStoreAssociationMasterData(MailboxAssociation association, IMailboxAssociationBaseItem item) { IMailboxAssociationGroup mailboxAssociationGroup = (IMailboxAssociationGroup)item; BaseAssociationAdaptor.UpdateLocatorDataInStoreItem(association.Group, mailboxAssociationGroup); mailboxAssociationGroup.IsPin = association.IsPin; mailboxAssociationGroup.PinDate = association.PinDate; }
private void ProcessSuccess(MailboxAssociation association, string slaveMailboxVersion, IMailboxLocator mailboxLocator) { association.SyncedIdentityHash = mailboxLocator.IdentityHash; association.SyncedVersion = association.CurrentVersion; association.SyncedSchemaVersion = slaveMailboxVersion; association.SyncAttempts = 0; association.LastSyncError = string.Empty; }
protected override void UpdateStoreAssociationSlaveData(MailboxAssociation association, IMailboxAssociationBaseItem item) { IMailboxAssociationUser mailboxAssociationUser = (IMailboxAssociationUser)item; BaseAssociationAdaptor.UpdateLocatorDataInStoreItem(association.User, mailboxAssociationUser); mailboxAssociationUser.SyncedIdentityHash = association.Group.IdentityHash; mailboxAssociationUser.IsPin = association.IsPin; }
private IAadClient GetAADClient(MailboxAssociation association) { if (AADClientTestHooks.GraphApi_GetAadClient != null) { return(AADClientTestHooks.GraphApi_GetAadClient()); } ADUser user = association.User.FindAdUser(); return(AADClientFactory.Create(user)); }
private MailboxAssociation GetAssociationWithPriority(IAssociationAdaptor masterAdaptor, params MailboxAssociation[] associations) { MailboxAssociation result = null; if (this.priorityLocator != null) { result = associations.FirstOrDefault((MailboxAssociation association) => this.ShouldPrioritize(masterAdaptor.GetSlaveMailboxLocator(association))); } return(result); }
public IMailboxBuilder <GroupMailbox> BuildFromAssociation(MailboxAssociation association) { ArgumentValidator.ThrowIfNull("association", association); this.Mailbox.IsPinned = association.IsPin; this.Mailbox.IsMember = association.IsMember; this.Mailbox.JoinedBy = association.JoinedBy; this.Mailbox.JoinDate = association.JoinDate; this.Mailbox.PinDate = association.PinDate; return(this); }
private static void UpdateStoreAssociationSyncState(MailboxAssociation association, IMailboxAssociationBaseItem item) { item.SyncedVersion = association.SyncedVersion; item.LastSyncError = (association.LastSyncError ?? string.Empty); item.SyncAttempts = association.SyncAttempts; item.SyncedSchemaVersion = (association.SyncedSchemaVersion ?? string.Empty); if (association.SyncedIdentityHash != null) { item.SyncedIdentityHash = association.SyncedIdentityHash; } }
protected override bool UpdateAssociation(MailboxAssociation association) { if (this.pin == association.IsPin) { UpdateAssociationCommand.Tracer.TraceDebug <UserMailboxLocator, bool>((long)this.GetHashCode(), "User {0} pin state is already same {1}", association.User, this.pin); return(false); } association.IsPin = this.pin; association.PinDate = (this.pin ? ExDateTime.UtcNow : default(ExDateTime)); return(this.VerifyMembershipState(association)); }
public IMailboxBuilder <UserMailbox> BuildFromAssociation(MailboxAssociation association) { ArgumentValidator.ThrowIfNull("association", association); this.Mailbox.IsMember = association.IsMember; this.Mailbox.JoinDate = association.JoinDate; this.Mailbox.LastVisitedDate = association.LastVisitedDate; this.Mailbox.ShouldEscalate = association.ShouldEscalate; this.Mailbox.IsAutoSubscribed = association.IsAutoSubscribed; this.Mailbox.IsPin = association.IsPin; return(this); }
public IEnumerable <MailboxAssociation> GetPinAssociations() { IEnumerable <IPropertyBag> foundItems = this.associationStore.GetAssociationsByType(this.ItemClass, MailboxAssociationBaseSchema.IsPin, this.PropertiesToLoad); foreach (IPropertyBag item in foundItems) { MailboxAssociation association = this.CreateMailboxAssociationFromItem(item, false); this.Tracer.TraceDebug <MailboxAssociation>((long)this.GetHashCode(), "BaseAssociationAdaptor.GetPinAssociations: Returning association: {0}", association); yield return(association); } yield break; }
public IEnumerable <MailboxAssociation> GetAssociationsWithMembershipChangedAfter(ExDateTime date) { IEnumerable <IPropertyBag> foundItems = this.associationStore.GetAssociationsWithMembershipChangedAfter(date, this.PropertiesToLoad); foreach (IPropertyBag item in foundItems) { MailboxAssociation association = this.CreateMailboxAssociationFromItem(item, false); this.Tracer.TraceDebug <MailboxAssociation>((long)this.GetHashCode(), "BaseAssociationAdaptor.GetMembershipChangedAfterAssociations: Returning association: {0}", association); yield return(association); } yield break; }
private bool DeleteMailboxNotFoundAssociation(MailboxAssociation association, IAssociationAdaptor masterAdaptor, MailboxNotFoundException exception) { bool flag = association.JoinDate.Add(InProcessAssociationReplicator.TimeRequiredAfterJoinToStopAssociationReplicationAttempts) < ExDateTime.UtcNow; InProcessAssociationReplicator.Tracer.TraceDebug <bool, MailboxNotFoundException, MailboxAssociation>((long)this.GetHashCode(), "InProcessAssociationReplicator.DeleteMailboxNotFoundAssociation. Should delete = {0}. Exception = {1}. Association = {2}", flag, exception, association); if (flag) { this.LogWarning("InProcessAssociationReplicator.DeleteMailboxNotFoundAssociation", string.Format("Deleting association given that target mailbox was not found and it is not a recently joined group. Association='{0}'. Exception='{1}'", association, exception)); masterAdaptor.DeleteAssociation(association); return(true); } return(false); }
protected override void UpdateStoreAssociationSlaveData(MailboxAssociation association, IMailboxAssociationBaseItem item) { IMailboxAssociationGroup mailboxAssociationGroup = (IMailboxAssociationGroup)item; BaseAssociationAdaptor.UpdateLocatorDataInStoreItem(association.Group, mailboxAssociationGroup); mailboxAssociationGroup.SyncedIdentityHash = association.User.IdentityHash; mailboxAssociationGroup.IsMember = association.IsMember; mailboxAssociationGroup.JoinDate = association.JoinDate; if (!association.IsMember) { mailboxAssociationGroup.IsPin = false; } }
public override MailboxAssociation GetAssociation(VersionedId itemId) { ArgumentValidator.ThrowIfNull("itemId", itemId); MailboxAssociation result = null; using (IMailboxAssociationBaseItem associationByItemId = this.GetAssociationByItemId(itemId)) { if (associationByItemId != null) { this.Tracer.TraceDebug <VersionedId>((long)this.GetHashCode(), "GroupAssociationAdaptor.GetAssociation: Creating association from store item. itemId={0}", itemId); result = this.CreateMailboxAssociationFromItem(associationByItemId, true); } } return(result); }
public UserMailbox GetMember(GroupMailboxLocator group, UserMailboxLocator user, bool loadAllDetails = false) { UserMailbox result; using (IAssociationStore associationStore = this.storeProviderBuilder.Create(group, this.PerformanceTracker)) { UserAssociationAdaptor adaptor = new UserAssociationAdaptor(associationStore, this.adSession, group); GetMemberAssociation getMemberAssociation = new GetMemberAssociation(adaptor, user); MailboxAssociation item = getMemberAssociation.Execute(); result = this.mailboxCollectionBuilder.BuildUserMailboxes(group, new List <MailboxAssociation>(1) { item }, loadAllDetails).FirstOrDefault <UserMailbox>(); } return(result); }
protected override MailboxAssociation CreateMailboxAssociationWithDefaultValues(IMailboxLocator group) { this.ValidateTargetLocatorType(group); MailboxAssociation mailboxAssociation = new MailboxAssociation { User = (base.MasterLocator as UserMailboxLocator), Group = (group as GroupMailboxLocator), IsPin = false, IsMember = false, JoinDate = default(ExDateTime), PinDate = default(ExDateTime) }; this.Tracer.TraceDebug <MailboxAssociation>((long)this.GetHashCode(), "GroupAssociationAdaptor.CreateMailboxAssociationWithDefaultValues: Creating new association with default values. Association={0}", mailboxAssociation); return(mailboxAssociation); }
protected IMailboxAssociationBaseItem ReadOrCreateMailboxItem(MailboxAssociation mailboxAssociation) { MailboxAssociationFromStore mailboxAssociationFromStore = mailboxAssociation as MailboxAssociationFromStore; if (mailboxAssociationFromStore != null) { this.Tracer.TraceDebug <VersionedId>((long)this.GetHashCode(), "BaseAssociationAdaptor.ReadOrCreateMailboxItem. Binding item using entry id found in property bag. Id = {0}", mailboxAssociationFromStore.ItemId); IMailboxAssociationBaseItem associationByItemId = this.GetAssociationByItemId(mailboxAssociationFromStore.ItemId); this.associationStore.OpenAssociationAsReadWrite(associationByItemId); return(associationByItemId); } this.Tracer.TraceDebug((long)this.GetHashCode(), "BaseAssociationAdaptor.ReadOrCreateMailboxItem. MailboxAssociation was not instantiated from store item, querying store"); MailboxLocator slaveMailboxLocator = this.GetSlaveMailboxLocator(mailboxAssociation); return(this.ReadOrCreateMailboxItem(slaveMailboxLocator)); }
internal static MailboxAssociationType Convert(MailboxAssociation association) { ArgumentValidator.ThrowIfNull("association", association); return(new MailboxAssociationType { User = EwsAssociationDataConverter.Convert(association.User), Group = EwsAssociationDataConverter.Convert(association.Group), IsMember = association.IsMember, IsMemberSpecified = true, IsPin = association.IsPin, IsPinSpecified = true, JoinDate = (DateTime)association.JoinDate, JoinDateSpecified = true, JoinedBy = association.JoinedBy }); }
protected override void UpdateStoreAssociationMasterData(MailboxAssociation association, IMailboxAssociationBaseItem item) { IMailboxAssociationUser mailboxAssociationUser = (IMailboxAssociationUser)item; BaseAssociationAdaptor.UpdateLocatorDataInStoreItem(association.User, mailboxAssociationUser); mailboxAssociationUser.SmtpAddress = association.UserSmtpAddress; mailboxAssociationUser.IsMember = association.IsMember; mailboxAssociationUser.ShouldEscalate = association.ShouldEscalate; mailboxAssociationUser.IsAutoSubscribed = association.IsAutoSubscribed; mailboxAssociationUser.JoinedBy = association.JoinedBy; mailboxAssociationUser.JoinDate = association.JoinDate; mailboxAssociationUser.LastVisitedDate = association.LastVisitedDate; if (!association.IsMember && mailboxAssociationUser.IsPin) { mailboxAssociationUser.IsPin = false; } }