private IEnumerable <NonConnectedMailbox> GetDisconnectedMailboxesForDatabaseInternal(DirectoryDatabase database, IPhysicalDatabase physicalDatabase) { this.logger.LogVerbose("Getting soft deleted mailboxes for database '{0}'", new object[] { database.Name }); IOperationRetryManager retryManager = LoadBalanceOperationRetryManager.Create(this.logger); foreach (IPhysicalMailbox disconnectedMailbox in physicalDatabase.GetNonConnectedMailboxes()) { NonConnectedMailbox nonConnectedMailbox = null; IPhysicalMailbox mailbox = disconnectedMailbox; retryManager.TryRun(delegate { nonConnectedMailbox = new NonConnectedMailbox(this, DirectoryIdentity.CreateNonConnectedMailboxIdentity(mailbox.Guid, mailbox.OrganizationId), new IPhysicalMailbox[] { mailbox }); nonConnectedMailbox.Parent = database; this.NotifyObjectLoaded(nonConnectedMailbox); }); if (disconnectedMailbox != null) { yield return(nonConnectedMailbox); } } yield break; }
public IEnumerable <DirectoryDatabase> GetDatabasesOwnedByServer(DirectoryServer server) { IOperationRetryManager retryManager = LoadBalanceOperationRetryManager.Create(this.logger); foreach (MailboxDatabase database in this.ConfigurationSession.GetDatabasesOnServer(server.Identity)) { DirectoryDatabase result = null; MailboxDatabase databaseCopy = database; OperationRetryManagerResult operationResult = retryManager.TryRun(delegate { result = this.DirectoryDatabaseFromDatabase(databaseCopy); }); if (!operationResult.Succeeded) { this.logger.LogError(operationResult.Exception, "Could not retrieve database {0} for server {1}.", new object[] { databaseCopy.Name, server.Name }); } else if (result != null) { yield return(result); } } yield break; }
protected override LoadContainer BuildTopology(TopologyExtractorFactoryContext topologyExtractorContext) { TopologyExtractorFactory loadBalancingLocalFactory = topologyExtractorContext.GetLoadBalancingLocalFactory(false); DirectoryServer localServer = base.ServiceContext.Directory.GetLocalServer(); TopologyExtractor extractor = loadBalancingLocalFactory.GetExtractor(localServer); LoadContainer loadContainer = extractor.ExtractTopology(); ExAssert.RetailAssert(loadContainer != null, "Extracted toplogy for server '{0}' should never be null.", new object[] { localServer }); DatabaseCollector databaseCollector = new DatabaseCollector(); loadContainer.Accept(databaseCollector); IOperationRetryManager operationRetryManager = LoadBalanceOperationRetryManager.Create(1, TimeSpan.Zero, base.ServiceContext.Logger); foreach (LoadContainer loadContainer2 in databaseCollector.Databases) { DirectoryDatabase directoryDatabase = loadContainer2.DirectoryObject as DirectoryDatabase; if (directoryDatabase != null) { DatabaseProcessor @object = new DatabaseProcessor(base.ServiceContext.Settings, base.ServiceContext.DrainControl, base.ServiceContext.Logger, directoryDatabase); operationRetryManager.TryRun(new Action(@object.ProcessDatabase)); } } return(loadContainer); }
protected virtual void InjectMoves(LoadContainer database, BatchName batchName, IEnumerable <LoadEntity> mailboxes, bool throwIfNotValid) { IRequestQueue injectorQueue = this.queueManager.GetInjectionQueue((DirectoryDatabase)database.DirectoryObject); IOperationRetryManager operationRetryManager = LoadBalanceOperationRetryManager.Create(this.logger); using (IEnumerator <LoadEntity> enumerator = mailboxes.GetEnumerator()) { while (enumerator.MoveNext()) { LoadEntity mailbox = enumerator.Current; if (mailbox.DirectoryObject == null) { this.logger.Log(MigrationEventType.Warning, "Not injecting move for {0} because its DirectoryObject is null", new object[] { mailbox }); } else { OperationRetryManagerResult operationRetryManagerResult = operationRetryManager.TryRun(delegate { DirectoryObject directoryObject = mailbox.DirectoryObject; ConstraintValidationResult constraintValidationResult = database.Constraint.Accept(mailbox); if (constraintValidationResult.Accepted) { database.CommittedLoad += mailbox.ConsumedLoad; if (directoryObject.SupportsMoving) { DirectoryObject directoryObject2 = database.DirectoryObject; IRequest request = directoryObject.CreateRequestToMove(directoryObject2.Identity, batchName.ToString(), this.logger); injectorQueue.EnqueueRequest(request); return; } if (throwIfNotValid) { throw new ObjectCannotBeMovedException(mailbox.DirectoryObjectIdentity.ObjectType.ToString(), mailbox.DirectoryObjectIdentity.ToString()); } } else { this.logger.Log(MigrationEventType.Warning, "Not injecting move for {0} because it violates the target database constraints: {1}", new object[] { mailbox, constraintValidationResult }); if (throwIfNotValid) { constraintValidationResult.Constraint.ValidateAccepted(mailbox); } } }); if (!operationRetryManagerResult.Succeeded && throwIfNotValid) { throw operationRetryManagerResult.Exception; } } } } }
protected override void ProcessRequest() { using (OperationTracker.Create(this.logger, "Rebalancing {0} from {1} to {2}.", new object[] { this.rebalanceData.RebalanceInformation, this.rebalanceData.SourceDatabase, this.rebalanceData.TargetDatabase })) { this.logger.Log(MigrationEventType.Information, "MOVE: Moving {0} from {1} to {2}.", new object[] { this.rebalanceData.RebalanceInformation, this.rebalanceData.SourceDatabase, this.rebalanceData.TargetDatabase }); Band[] bands = this.rebalanceData.RebalanceInformation.Metrics.OfType <Band>().ToArray <Band>(); TopologyExtractorFactory entitySelectorFactory = this.serviceContext.TopologyExtractorFactoryContextPool.GetContext(this.clientFactory, bands, this.nonMovableOrgs, this.logger).GetEntitySelectorFactory(); DirectoryDatabase database = this.directoryProvider.GetDatabase(this.rebalanceData.SourceDatabase.Guid); LoadContainer container = entitySelectorFactory.GetExtractor(database).ExtractTopology(); IOperationRetryManager operationRetryManager = LoadBalanceOperationRetryManager.Create(this.logger); foreach (LoadMetric loadMetric in this.rebalanceData.RebalanceInformation.Metrics) { EntitySelector selector = loadMetric.GetSelector(container, this.rebalanceData.ConstraintSetIdentity, this.rebalanceData.RebalanceInformation[loadMetric]); if (selector.IsEmpty) { this.logger.Log(MigrationEventType.Information, "Could not find any mailbox for metric {0} in database {1}.", new object[] { loadMetric, this.rebalanceData.SourceDatabase }); } else { this.logger.Log(MigrationEventType.Information, "Found mailboxes matching the metric {0} in database {1}. Requesting the injections.", new object[] { loadMetric, this.rebalanceData.SourceDatabase }); operationRetryManager.TryRun(delegate { DirectoryDatabase database2 = (DirectoryDatabase)this.directoryProvider.GetDirectoryObject(this.rebalanceData.TargetDatabase.DirectoryObjectIdentity); using (IInjectorService injectorClientForDatabase = this.clientFactory.GetInjectorClientForDatabase(database2)) { injectorClientForDatabase.InjectMoves(this.rebalanceData.TargetDatabase.Guid, this.rebalanceData.RebalanceBatchName, selector.GetEntities(this.rebalanceData.TargetDatabase)); } }); } } } }
protected override void ProcessRequest() { this.logger.LogInformation("Starting load balancing moves for request {0}", new object[] { this.rebalanceRequest }); try { BandRebalanceLog.Write(this.rebalanceRequest); IOperationRetryManager operationRetryManager = LoadBalanceOperationRetryManager.Create(this.logger); operationRetryManager.Run(new Action(this.RequestRebalancingOnRemoteServer)); } finally { this.logger.LogInformation("Done creating rebalancing request.", new object[0]); } }
protected override void ProcessRequest() { this.logger.LogInformation("Starting to drain database {0} with batch name {1}.", new object[] { this.directoryDatabase.Identity, this.batchName }); IOperationRetryManager operationRetryManager = LoadBalanceOperationRetryManager.Create(this.logger); using (OperationTracker.Create(this.logger, "Moving mailboxes out of {0}.", new object[] { this.directoryDatabase.Identity })) { foreach (DirectoryMailbox mailboxToMove2 in this.directoryDatabase.GetMailboxes()) { DirectoryMailbox mailboxToMove = mailboxToMove2; operationRetryManager.TryRun(delegate { this.moveInjector.InjectMoveForMailbox(mailboxToMove, this.batchName); }); } } this.logger.LogInformation("Draining database {0}: Cleaning soft deleted mailboxes.", new object[] { this.directoryDatabase.Identity }); using (OperationTracker.Create(this.logger, "Starting soft deleted cleanup for {0}.", new object[] { this.directoryDatabase.Identity })) { this.serviceContext.CleanupSoftDeletedMailboxesOnDatabase(this.directoryDatabase.Identity, ByteQuantifiedSize.Zero); } this.logger.LogInformation("Finished processing the draining of database {0}.", new object[] { this.directoryDatabase.Identity }); if (this.OnDrainFinished != null) { this.OnDrainFinished(this.directoryDatabase); } }
public IEnumerable <DirectoryMailbox> GetMailboxesForDatabase(DirectoryDatabase database) { this.logger.LogVerbose("Getting mailboxes for database '{0}'", new object[] { database.Name }); DirectoryIdentity databaseIdentity = database.Identity; using (IPhysicalDatabase physicalDatabase = this.clientFactory.GetPhysicalDatabaseConnection(database)) { physicalDatabase.LoadMailboxes(); IOperationRetryManager retryManager = LoadBalanceOperationRetryManager.Create(this.logger); foreach (LoadBalancingMiniRecipient recipient in this.RecipientSession.FindAllUsersLinkedToDatabase(databaseIdentity.ADObjectId)) { DirectoryMailbox mailbox = null; LoadBalancingMiniRecipient miniRecipient = recipient; retryManager.TryRun(delegate { mailbox = this.GetMailboxFromMiniRecipient(miniRecipient, this.RecipientSession.GetExternalDirectoryOrganizationId(miniRecipient), physicalDatabase); mailbox.Parent = database; this.NotifyObjectLoaded(mailbox); }); if (mailbox != null) { yield return(mailbox); } } foreach (IPhysicalMailbox consumerMailbox in physicalDatabase.GetConsumerMailboxes()) { DirectoryIdentity consumerIdentity = DirectoryIdentity.CreateConsumerMailboxIdentity(consumerMailbox.Guid, physicalDatabase.DatabaseGuid, consumerMailbox.OrganizationId); yield return(new DirectoryMailbox(this, consumerIdentity, new IPhysicalMailbox[] { consumerMailbox }, DirectoryMailboxType.Consumer)); } foreach (NonConnectedMailbox disconnectedMailbox in this.GetDisconnectedMailboxesForDatabaseInternal(database, physicalDatabase)) { yield return(disconnectedMailbox); } } yield break; }
public void RemoveFromDatabase() { ByteQuantifiedSize currentSize = this.database.GetSize().CurrentPhysicalSize; ByteQuantifiedSize currentSize2 = currentSize; List <NonConnectedMailbox> source = this.database.GetDisconnectedMailboxes().ToList <NonConnectedMailbox>(); this.context.Logger.LogInformation("Beginning soft-deleted mailbox cleanup on database '{0}'", new object[] { this.database.Name }); this.context.Logger.LogInformation("Current size of database '{0}' is {1}, with a target size of {2}", new object[] { this.database.Name, currentSize, this.targetDatabaseSize }); int totalCountRemoved = 0; ByteQuantifiedSize totalSizeRemoved = default(ByteQuantifiedSize); IOperationRetryManager operationRetryManager = LoadBalanceOperationRetryManager.Create(1, TimeSpan.Zero, this.context.Logger); using (IEnumerator <NonConnectedMailbox> enumerator = (from o in source orderby o.DisconnectDate select o).GetEnumerator()) { while (enumerator.MoveNext()) { NonConnectedMailbox softDeletedMailbox = enumerator.Current; if (currentSize < this.targetDatabaseSize) { this.context.Logger.LogInformation("Current size of database '{0}' is below max size allowed by soft deleted threshold. Done deleting soft deleted mailboxes", new object[] { this.database.Name }); break; } if (softDeletedMailbox.IsSoftDeleted) { Exception exception = null; bool success = false; SoftDeletedMailboxRemovalLogEntry entry = new SoftDeletedMailboxRemovalLogEntry(); entry[SoftDeletedMailboxRemovalLogEntrySchema.MailboxGuid] = softDeletedMailbox.Guid; entry[SoftDeletedMailboxRemovalLogEntrySchema.DatabaseName] = this.database.Name; entry[SoftDeletedMailboxRemovalLogEntrySchema.TargetDatabaseSize] = this.targetDatabaseSize; entry[SoftDeletedMailboxRemovalLogEntrySchema.CurrentDatabaseSize] = currentSize; entry[SoftDeletedMailboxRemovalLogEntrySchema.OriginalDatabaseSize] = currentSize2; entry[SoftDeletedMailboxRemovalLogEntrySchema.MailboxSize] = softDeletedMailbox.PhysicalSize; OperationRetryManagerResult operationRetryManagerResult = operationRetryManager.TryRun(delegate { this.context.Logger.LogVerbose("Removing SoftDeleted Mailbox from database '{0}'. MailboxGuid: {1} MailboxSize: {2}", new object[] { this.database.Name, softDeletedMailbox.Guid, softDeletedMailbox.PhysicalSize }); SoftDeleteMailboxRemovalCheckRemoval mailboxRemovalReadiness = this.GetMailboxRemovalReadiness(softDeletedMailbox); entry[SoftDeletedMailboxRemovalLogEntrySchema.RemovalAllowed] = mailboxRemovalReadiness.CanRemove; entry[SoftDeletedMailboxRemovalLogEntrySchema.RemovalDisallowedReason] = mailboxRemovalReadiness.Reason; if (mailboxRemovalReadiness.CanRemove) { success = this.context.TryRemoveSoftDeletedMailbox(softDeletedMailbox.Guid, this.database.Guid, out exception); if (success) { currentSize -= softDeletedMailbox.PhysicalSize; totalCountRemoved++; totalSizeRemoved += softDeletedMailbox.PhysicalSize; this.context.Logger.LogVerbose("Mailbox '{0}' removed", new object[] { softDeletedMailbox.Guid }); } } }); if (!operationRetryManagerResult.Succeeded) { exception = operationRetryManagerResult.Exception; } entry[SoftDeletedMailboxRemovalLogEntrySchema.Removed] = success; entry[SoftDeletedMailboxRemovalLogEntrySchema.Error] = exception; this.logCollector.LogObject <SoftDeletedMailboxRemovalLogEntry>(entry); } } } this.context.Logger.LogInformation("Approximate final size of database '{0}' is {1}. Target size was {2}. {3} total mailboxes with total size of {4} deleted.", new object[] { this.database.Name, currentSize, this.targetDatabaseSize, totalCountRemoved, totalSizeRemoved }); this.context.Logger.LogInformation("Finished soft-deleted mailbox cleanup on database '{0}'", new object[] { this.database.Name }); }
public void ExtractContainer() { IOperationRetryManager operationRetryManager = LoadBalanceOperationRetryManager.Create(this.logger); operationRetryManager.TryRun(new Action(this.ExtractContainerAndAddToParent)); }