public static string GetOtherRequests(ADUser user, Guid?requestGuid) { IEnumerable <IRequestIndexEntry> requestIndexEntries = MailboxRequestIndexEntryHandler.GetRequestIndexEntries(user, null); IEnumerable <IRequestIndexEntry> source = from r in requestIndexEntries where !MailboxRelocationRequestStatistics.IsTerminalState(r.Status) && (requestGuid == null || r.RequestGuid != requestGuid) select r; List <IRequestIndexEntry> list = new List <IRequestIndexEntry>(); foreach (IGrouping <ADObjectId, IRequestIndexEntry> grouping in from r in source group r by r.StorageMDB) { using (RequestJobProvider requestJobProvider = new RequestJobProvider(grouping.Key.ObjectGuid)) { foreach (IRequestIndexEntry requestIndexEntry in grouping) { TransactionalRequestJob transactionalRequestJob = (TransactionalRequestJob)requestJobProvider.Read <TransactionalRequestJob>(requestIndexEntry.GetRequestJobId(), ReadJobFlags.SkipValidation | ReadJobFlags.SkipReadingMailboxRequestIndexEntries); if (transactionalRequestJob != null && !MailboxRelocationRequestStatistics.IsTerminalState(transactionalRequestJob)) { list.Add(requestIndexEntry); } } } } return(string.Join <Guid>(", ", from r in list select r.RequestGuid)); }
private void CleanupCompletedJob(TransactionalRequestJob requestJob, RequestJobProvider rjProvider) { DateTime t = requestJob.TimeTracker.GetTimestamp(RequestJobTimestamp.DoNotPickUntil) ?? DateTime.MaxValue; if (DateTime.UtcNow < t) { return; } MrsTracer.Service.Debug("Cleaning up expired completed job '{0}' on queue '{1}'", new object[] { requestJob, this.RequestQueueGuid }); rjProvider.Delete(requestJob); CommonUtils.CatchKnownExceptions(delegate { ReportData reportData = new ReportData(requestJob.IdentifyingGuid, requestJob.ReportVersion); reportData.Delete(rjProvider.SystemMailbox); }, null); CommonUtils.CatchKnownExceptions(delegate { rjProvider.DeleteIndexEntries(requestJob); }, null); requestJob.RemoveAsyncNotification(); MailboxReplicationService.LogEvent(MRSEventLogConstants.Tuple_RemovedCompletedRequest, new object[] { requestJob.ToString(), this.RequestGuid.ToString(), requestJob.WorkItemQueueMdbName }); }
protected void RelinquishRequest() { using (RequestJobProvider rjProvider = new RequestJobProvider(this.RequestQueueGuid, this.SystemMailbox)) { MapiUtils.RetryOnObjectChanged(delegate { using (TransactionalRequestJob transactionalRequestJob = (TransactionalRequestJob)rjProvider.Read <TransactionalRequestJob>(new RequestJobObjectId(this.RequestGuid, this.RequestQueueGuid, this.MessageId))) { if (transactionalRequestJob != null) { ReportData report = new ReportData(transactionalRequestJob.IdentifyingGuid, transactionalRequestJob.ReportVersion); transactionalRequestJob.RequestJobState = JobProcessingState.Ready; transactionalRequestJob.MRSServerName = null; transactionalRequestJob.TimeTracker.CurrentState = this.RelinquishAction(transactionalRequestJob, report); report.Append(MrsStrings.ReportRelinquishingJob); rjProvider.Save(transactionalRequestJob); CommonUtils.CatchKnownExceptions(delegate { report.Flush(rjProvider.SystemMailbox); }, null); transactionalRequestJob.UpdateAsyncNotification(report); this.AfterRelinquishAction(); } } }); } }
internal static RequestStatisticsBase CreateRequestStatistics(Type t, RequestJobXML rj, bool acceptBase) { RequestStatisticsBase requestStatisticsBase = null; if (t.Equals(typeof(MoveRequestStatistics))) { requestStatisticsBase = new MoveRequestStatistics(rj); } else if (t.Equals(typeof(MergeRequestStatistics))) { requestStatisticsBase = new MergeRequestStatistics(rj); } else if (t.Equals(typeof(MailboxImportRequestStatistics))) { requestStatisticsBase = new MailboxImportRequestStatistics(rj); } else if (t.Equals(typeof(MailboxExportRequestStatistics))) { requestStatisticsBase = new MailboxExportRequestStatistics(rj); } else if (t.Equals(typeof(MailboxRelocationRequestStatistics))) { requestStatisticsBase = new MailboxRelocationRequestStatistics(rj); } else if (t.Equals(typeof(MailboxRestoreRequestStatistics))) { requestStatisticsBase = new MailboxRestoreRequestStatistics(rj); } else if (t.Equals(typeof(PublicFolderMoveRequestStatistics))) { requestStatisticsBase = new PublicFolderMoveRequestStatistics(rj); } else if (t.Equals(typeof(PublicFolderMigrationRequestStatistics))) { requestStatisticsBase = new PublicFolderMigrationRequestStatistics(rj); } else if (t.Equals(typeof(PublicFolderMailboxMigrationRequestStatistics))) { requestStatisticsBase = new PublicFolderMailboxMigrationRequestStatistics(rj); } else if (t.Equals(typeof(SyncRequestStatistics))) { requestStatisticsBase = new SyncRequestStatistics(rj); } else if (t.Equals(typeof(FolderMoveRequestStatistics))) { requestStatisticsBase = new FolderMoveRequestStatistics(rj); } else if (acceptBase && t.Equals(typeof(RequestStatisticsBase))) { return(RequestJobProvider.CreateRequestStatistics(rj)); } if (requestStatisticsBase != null) { rj.Retire(); } return(requestStatisticsBase); }
public static void ProcessMoveRequestCreatedNotification(Guid requestGuid, Guid mdbGuid) { using (RequestJobProvider requestJobProvider = new RequestJobProvider(mdbGuid)) { RequestStatisticsBase moveRequest = (RequestStatisticsBase)requestJobProvider.Read <RequestStatisticsBase>(new RequestJobObjectId(requestGuid, mdbGuid, null)); if (moveRequest != null && !(moveRequest.ValidationResult != RequestJobBase.ValidationResultEnum.Valid)) { if (moveRequest.RequestStyle == RequestStyle.CrossOrg && moveRequest.RequestType == MRSRequestType.Move) { CommonUtils.CatchKnownExceptions(delegate { Guid physicalMailboxGuid = moveRequest.ArchiveOnly ? (moveRequest.ArchiveGuid ?? Guid.Empty) : moveRequest.ExchangeGuid; ProxyControlFlags proxyControlFlags = ProxyControlFlags.DoNotApplyProxyThrottling | moveRequest.GetProxyControlFlags(); IMailbox mailbox; MailboxType mbxType; Guid mdbGuid2; if (moveRequest.Direction == RequestDirection.Pull) { if ((moveRequest.Flags & RequestFlags.RemoteLegacy) != RequestFlags.None) { mailbox = new MapiSourceMailbox(LocalMailboxFlags.None); mailbox.ConfigADConnection(moveRequest.SourceDCName, moveRequest.SourceDCName, moveRequest.SourceCredential); } else { mailbox = new RemoteSourceMailbox(moveRequest.RemoteHostName, moveRequest.RemoteOrgName, moveRequest.RemoteCredential, proxyControlFlags, null, true, LocalMailboxFlags.None); } mbxType = MailboxType.SourceMailbox; mdbGuid2 = Guid.Empty; } else { if ((moveRequest.Flags & RequestFlags.RemoteLegacy) != RequestFlags.None) { mailbox = new MapiDestinationMailbox(LocalMailboxFlags.None); mailbox.ConfigADConnection(moveRequest.TargetDCName, moveRequest.TargetDCName, moveRequest.TargetCredential); } else { mailbox = new RemoteDestinationMailbox(moveRequest.RemoteHostName, moveRequest.RemoteOrgName, moveRequest.RemoteCredential, proxyControlFlags, null, true, LocalMailboxFlags.None); } mbxType = MailboxType.DestMailboxCrossOrg; mdbGuid2 = ((moveRequest.ArchiveOnly ? moveRequest.RemoteArchiveDatabaseGuid : moveRequest.RemoteDatabaseGuid) ?? Guid.Empty); } using (mailbox) { mailbox.Config(null, moveRequest.ExchangeGuid, physicalMailboxGuid, null, mdbGuid2, mbxType, null); mailbox.Connect(MailboxConnectFlags.None); mailbox.UpdateRemoteHostName(moveRequest.UserOrgName); mailbox.Disconnect(); } }, null); } } } }
private static void CleanADOrphanAndInconsistencyForRequests(IRecipientSession recipientSession, IConfigurationSession configSession, Guid dbGuid) { MrsTracer.Service.Debug("Try to CleanADOrphanAndInconsistencyForRequests for Database {0} name is {1}", new object[] { dbGuid, dbGuid }); using (RequestJobProvider rjProvider = new RequestJobProvider(dbGuid)) { rjProvider.LoadReport = false; rjProvider.AllowInvalid = true; foreach (object obj in Enum.GetValues(typeof(MRSRequestType))) { MRSRequestType requestType = (MRSRequestType)obj; MrsTracer.Service.Debug("Try to CleanADOrphanAndInconsistencyForRequests for request type {0}", new object[] { requestType }); CommonUtils.CatchKnownExceptions(delegate { if (requestType == MRSRequestType.Move) { ADInconsistencyCheck.CleanADOrphanAndInconsistencyForMoves(recipientSession, rjProvider, dbGuid); return; } ADInconsistencyCheck.CleanADOrphanAndInconsistencyForNonMoves(configSession, requestType, rjProvider, dbGuid); }, delegate(Exception f) { MrsTracer.Service.Error("CleanADOrphanAndInconsistencyForRequests() failed for DB {0}. Request type {1} Error: {2}", new object[] { dbGuid, requestType.ToString(), CommonUtils.FullExceptionMessage(f, true) }); MRSService.LogEvent(MRSEventLogConstants.Tuple_ScanADInconsistencyRequestFailEvent, new object[] { dbGuid, requestType.ToString(), string.Empty, CommonUtils.FullExceptionMessage(f, true) }); }); } } }
public override void Run() { Guid currentQueueGuid = this.CurrentRequestQueue.ObjectGuid; Guid newQueueGuid = this.NewRequestQueue.ObjectGuid; RequestJobObjectId currentId = new RequestJobObjectId(base.RequestGuid, currentQueueGuid, this.MessageId); RequestJobObjectId newId = new RequestJobObjectId(base.RequestGuid, newQueueGuid, null); CommonUtils.CatchKnownExceptions(delegate { DatabaseInformation databaseInformation = MapiUtils.FindServerForMdb(this.NewRequestQueue, null, null, FindServerFlags.None); if (databaseInformation.ServerVersion < Server.E15MinVersion) { throw new UnsupportedRehomeTargetVersionPermanentException(newQueueGuid.ToString(), new ServerVersion(databaseInformation.ServerVersion).ToString()); } this.NewSystemMailbox = MapiUtils.GetSystemMailbox(newQueueGuid); using (RequestJobProvider currentQueueProvider = new RequestJobProvider(currentQueueGuid, this.CurrentSystemMailbox)) { using (RequestJobProvider newQueueProvider = new RequestJobProvider(newQueueGuid, this.NewSystemMailbox)) { using (TransactionalRequestJob requestJob = (TransactionalRequestJob)currentQueueProvider.Read <TransactionalRequestJob>(currentId)) { if (requestJob != null) { RequestJobProvider origProvider = requestJob.Provider; MoveObjectInfo <RequestJobXML> origMO = requestJob.MoveObject; ReportData currentReport = new ReportData(requestJob.IdentifyingGuid, requestJob.ReportVersion); currentReport.Load(currentQueueProvider.SystemMailbox); ReportData newReport = new ReportData(currentReport.IdentifyingGuid, requestJob.ReportVersion); newReport.Append(currentReport.Entries); try { requestJob.Provider = null; requestJob.MoveObject = null; requestJob.RequestQueue = this.NewRequestQueue; requestJob.Identity = newId; requestJob.OriginatingMDBGuid = Guid.Empty; requestJob.RehomeRequest = false; if (requestJob.IndexEntries != null) { foreach (IRequestIndexEntry requestIndexEntry in requestJob.IndexEntries) { requestIndexEntry.StorageMDB = this.NewRequestQueue; } } newQueueProvider.Save(requestJob); CommonUtils.CatchKnownExceptions(delegate { newReport.Append(MrsStrings.ReportJobRehomed(currentQueueGuid.ToString(), newQueueGuid.ToString())); newReport.Flush(newQueueProvider.SystemMailbox); }, null); CommonUtils.CatchKnownExceptions(delegate { requestJob.Provider = origProvider; requestJob.MoveObject = origMO; requestJob.RequestQueue = this.CurrentRequestQueue; requestJob.Identity = currentId; requestJob.OriginatingMDBGuid = currentQueueGuid; requestJob.RehomeRequest = true; MapiUtils.RetryOnObjectChanged(delegate { currentQueueProvider.Delete(requestJob); }); currentReport.Delete(currentQueueProvider.SystemMailbox); }, null); } catch { requestJob.Provider = origProvider; requestJob.MoveObject = origMO; requestJob.RequestQueue = this.CurrentRequestQueue; requestJob.Identity = currentId; requestJob.OriginatingMDBGuid = currentQueueGuid; requestJob.RehomeRequest = true; throw; } } } } } }, delegate(Exception failure) { MrsTracer.Service.Warning("Failed to rehome request.", new object[0]); this.RehomeFailure = failure; }); base.Run(); }
private static void CleanADOrphanAndInconsistencyForMoves(IRecipientSession recipientSession, RequestJobProvider rjProvider, Guid dbGuid) { ADObjectId propertyValue = new ADObjectId(dbGuid); QueryFilter queryFilter = new AndFilter(new QueryFilter[] { new ComparisonFilter(ComparisonOperator.NotEqual, ADUserSchema.MailboxMoveStatus, RequestStatus.None), new ExistsFilter(ADUserSchema.MailboxMoveStatus) }); QueryFilter queryFilter2 = QueryFilter.OrTogether(new QueryFilter[] { QueryFilter.AndTogether(new QueryFilter[] { new ComparisonFilter(ComparisonOperator.Equal, ADUserSchema.MailboxMoveSourceMDB, propertyValue), new BitMaskAndFilter(ADUserSchema.MailboxMoveFlags, 4UL) }), QueryFilter.AndTogether(new QueryFilter[] { new ComparisonFilter(ComparisonOperator.Equal, ADUserSchema.MailboxMoveTargetMDB, propertyValue), new BitMaskAndFilter(ADUserSchema.MailboxMoveFlags, 8UL) }) }); QueryFilter filter = new AndFilter(new QueryFilter[] { queryFilter, queryFilter2 }); ADRecipient[] array = recipientSession.Find(null, QueryScope.SubTree, filter, null, 1000); if (array == null || array.Length == 0) { MrsTracer.Service.Debug("CleanADOrphanAndInconsistencyForMoves(): No move requests found for DB {0}", new object[] { dbGuid }); return; } bool needUpdateAD = false; ADRecipient[] array2 = array; for (int i = 0; i < array2.Length; i++) { ADRecipient request = array2[i]; CommonUtils.CatchKnownExceptions(delegate { needUpdateAD = false; ADUser aduser = request as ADUser; MoveRequestStatistics moveRequestStatistics = (MoveRequestStatistics)rjProvider.Read <MoveRequestStatistics>(new RequestJobObjectId(aduser.ExchangeGuid, dbGuid, null)); if (moveRequestStatistics == null || (!moveRequestStatistics.IsFake && moveRequestStatistics.Status == RequestStatus.None)) { MrsTracer.Service.Debug("CleanADOrphanAndInconsistencyForMoves():AD orphan {0} found for DB {1}", new object[] { aduser.ExchangeGuid, dbGuid }); CommonUtils.CleanupMoveRequestInAD(recipientSession, null, aduser); return; } if (moveRequestStatistics.IsFake) { MrsTracer.Service.Debug("CleanADOrphanAndInconsistencyForMoves():request {0} is uplevel/Fake, ignore it", new object[] { aduser.ExchangeGuid }); return; } if (moveRequestStatistics.User == null) { MrsTracer.Service.Debug("CleanADOrphanAndInconsistencyForMoves():request {0} has been deleted from AD, ignore it", new object[] { aduser.ExchangeGuid }); return; } if (moveRequestStatistics.TimeTracker.GetCurrentDurationChunk() > ADInconsistencyCheck.updateLatencyThreshhold) { RequestStatus versionAppropriateStatus = RequestJobBase.GetVersionAppropriateStatus(moveRequestStatistics.Status, aduser.ExchangeVersion); if (versionAppropriateStatus != moveRequestStatistics.User.MailboxMoveStatus) { MrsTracer.Service.Debug("CleanADOrphanAndInconsistencyForMoves():AD inconsistency {0} found for DB {1}, AD status is {2} but store status is {3} ({4})", new object[] { aduser.ExchangeGuid, dbGuid, aduser.MailboxMoveStatus, moveRequestStatistics.Status, versionAppropriateStatus }); aduser.MailboxMoveStatus = versionAppropriateStatus; needUpdateAD = true; } RequestFlags versionAppropriateFlags = RequestJobBase.GetVersionAppropriateFlags(moveRequestStatistics.Flags, aduser.ExchangeVersion); if (versionAppropriateFlags != moveRequestStatistics.User.MailboxMoveFlags) { MrsTracer.Service.Debug("CleanADOrphanAndInconsistencyForMoves():AD inconsistency {0} found for DB {1}, AD flags is {2} but store flags is {3} ({4})", new object[] { aduser.ExchangeGuid, dbGuid, aduser.MailboxMoveFlags, moveRequestStatistics.Flags, versionAppropriateFlags }); aduser.MailboxMoveFlags = versionAppropriateFlags; needUpdateAD = true; } if (needUpdateAD) { recipientSession.Save(request); } } }, delegate(Exception f) { MrsTracer.Service.Error("CleanADOrphanAndInconsistencyForMoves() failed for DB {0}. move request {1} Error: {2}", new object[] { dbGuid, ((ADUser)request).ExchangeGuid, CommonUtils.FullExceptionMessage(f, true) }); MRSService.LogEvent(MRSEventLogConstants.Tuple_ScanADInconsistencyRequestFailEvent, new object[] { dbGuid, MRSRequestType.Move.ToString(), ((ADUser)request).ExchangeGuid, CommonUtils.FullExceptionMessage(f, true) }); }); } }
private static void CleanADOrphanAndInconsistencyForNonMoves(IConfigurationSession configSession, MRSRequestType requestType, RequestJobProvider rjProvider, Guid dbGuid) { ADObjectId requestQueueId = new ADObjectId(dbGuid); RequestIndexEntryQueryFilter requestIndexEntryQueryFilter = new RequestIndexEntryQueryFilter(); requestIndexEntryQueryFilter.IndexId = new RequestIndexId(RequestIndexLocation.AD); requestIndexEntryQueryFilter.RequestType = requestType; requestIndexEntryQueryFilter.RequestQueueId = requestQueueId; MRSRequestWrapper[] array = ADHandler.Find(configSession, requestIndexEntryQueryFilter, null, true, null); if (array != null && array.Length > 0) { bool needUpdateAD = false; MRSRequestWrapper[] array2 = array; for (int i = 0; i < array2.Length; i++) { MRSRequestWrapper request = array2[i]; CommonUtils.CatchKnownExceptions(delegate { needUpdateAD = false; if (request.Status != RequestStatus.None) { RequestStatisticsBase requestStatisticsBase = (RequestStatisticsBase)rjProvider.Read <RequestStatisticsBase>(new RequestJobObjectId(request.RequestGuid, dbGuid, null)); if (requestStatisticsBase == null || (!requestStatisticsBase.IsFake && requestStatisticsBase.Status == RequestStatus.None)) { MrsTracer.Service.Debug("CleanADOrphanAndInconsistencyForRequests():AD orphan {0} found for DB {1}", new object[] { request.RequestGuid, dbGuid }); ADHandler.Delete(configSession, request); return; } if (requestStatisticsBase.IsFake) { MrsTracer.Service.Debug("CleanADOrphanAndInconsistencyForRequests():request {0} is uplevel/Fake, ignoring it", new object[] { request.RequestGuid }); return; } if (requestStatisticsBase.IndexEntries == null || requestStatisticsBase.IndexEntries.Count == 0) { MrsTracer.Service.Debug("CleanADOrphanAndInconsistencyForRequests():request {0} has been removed from AD, ignoring it", new object[] { request.RequestGuid }); return; } if (requestStatisticsBase.TimeTracker.GetCurrentDurationChunk() > ADInconsistencyCheck.updateLatencyThreshhold) { if (requestStatisticsBase.Status != requestStatisticsBase.IndexEntries[0].Status) { MrsTracer.Service.Debug("CleanADOrphanAndInconsistencyForRequests():AD inconsistency {0} found for DB {1}, AD status is {2} but store status is {3}", new object[] { request.RequestGuid, dbGuid, request.Status, requestStatisticsBase.Status }); request.Status = requestStatisticsBase.Status; needUpdateAD = true; } if (requestStatisticsBase.Flags != requestStatisticsBase.IndexEntries[0].Flags) { MrsTracer.Service.Debug("CleanADOrphanAndInconsistencyForRequests():AD inconsistency {0} found for DB {1}, AD flags is {2} but store flags is {3}", new object[] { request.RequestGuid, dbGuid, request.Flags, requestStatisticsBase.Flags }); request.Flags = requestStatisticsBase.Flags; needUpdateAD = true; } if (needUpdateAD) { ADHandler.Save(configSession, request); return; } } } else { MrsTracer.Service.Debug("CleanADOrphanAndInconsistencyForRequests():request {0} for {1} has been removed from AD, store orphan will be handled by MRS pick up job logic", new object[] { request.RequestGuid, dbGuid }); } }, delegate(Exception f) { MrsTracer.Service.Error("CleanADOrphanAndInconsistencyForRequests() failed for DB {0}. Request type {1} Request guid {2} Error: {3}", new object[] { dbGuid, requestType.ToString(), request.RequestGuid, CommonUtils.FullExceptionMessage(f, true) }); MRSService.LogEvent(MRSEventLogConstants.Tuple_ScanADInconsistencyRequestFailEvent, new object[] { dbGuid, requestType.ToString(), request.RequestGuid, CommonUtils.FullExceptionMessage(f, true) }); }); } return; } MrsTracer.Service.Debug("CleanADOrphanAndInconsistencyForRequests(): No {0} requests found for DB {1}", new object[] { requestType, dbGuid }); }
private void ProcessInvalidJob(TransactionalRequestJob requestJob, RequestJobProvider rjProvider) { MrsTracer.Service.Warning("MoveJob '{0}' on queue '{1}' failed validation: {2}.", new object[] { requestJob, this.RequestQueueGuid, requestJob.ValidationMessage }); if (requestJob.IdleTime < MoveJob.MaxADReplicationWaitTime) { MrsTracer.Service.Warning("MoveJob '{0}' on queue '{1}' appears invalid. Waiting for {2} for AD Replication. Already have waited {3}...", new object[] { requestJob, this.RequestQueueGuid, MoveJob.MaxADReplicationWaitTime, requestJob.IdleTime }); return; } if (requestJob.ValidationResult == RequestJobBase.ValidationResultEnum.Orphaned) { MrsTracer.Service.Warning("MoveJob '{0}' on queue '{1}' is orphaned, removing it.", new object[] { requestJob, this.RequestQueueGuid }); rjProvider.Delete(requestJob); CommonUtils.CatchKnownExceptions(delegate { ReportData reportData2 = new ReportData(requestJob.IdentifyingGuid, requestJob.ReportVersion); reportData2.Delete(rjProvider.SystemMailbox); }, null); requestJob.RemoveAsyncNotification(); MailboxReplicationService.LogEvent(MRSEventLogConstants.Tuple_RemovedOrphanedMoveRequest, new object[] { this.RequestQueueGuid.ToString(), this.RequestGuid.ToString(), requestJob.ToString(), requestJob.ValidationMessage }); return; } ReportData reportData = new ReportData(requestJob.IdentifyingGuid, requestJob.ReportVersion); reportData.Append(MrsStrings.ReportFailingInvalidMoveRequest(requestJob.ValidationMessage)); reportData.Flush(rjProvider.SystemMailbox); requestJob.Status = RequestStatus.Failed; requestJob.FailureCode = new int?(-2147024809); requestJob.FailureType = "InvalidRequest"; requestJob.FailureSide = new ExceptionSide?(ExceptionSide.None); requestJob.Message = MrsStrings.MoveRequestMessageError(MrsStrings.MoveRequestDataIsCorrupt(requestJob.ValidationMessage)); requestJob.TimeTracker.SetTimestamp(RequestJobTimestamp.Failure, new DateTime?(DateTime.UtcNow)); requestJob.TimeTracker.CurrentState = RequestState.Failed; rjProvider.Save(requestJob); requestJob.UpdateAsyncNotification(reportData); MailboxReplicationService.LogEvent(MRSEventLogConstants.Tuple_FailedInvalidRequest, new object[] { this.RequestQueueGuid.ToString(), this.RequestGuid.ToString(), requestJob.ToString(), requestJob.ValidationMessage }); }
public JobPickupRec AttemptToPick(MapiStore systemMailbox) { if (!RequestJobXML.IsKnownRequestType(this.RequestType)) { return(new JobPickupRec(this, JobPickupResult.UnknownJobType, DateTime.MaxValue, MrsStrings.PickupStatusRequestTypeNotSupported(this.RequestType.ToString()), null)); } if (!RequestJobXML.IsKnownJobType(this.JobType)) { return(new JobPickupRec(this, JobPickupResult.UnknownJobType, DateTime.MaxValue, MrsStrings.PickupStatusJobTypeNotSupported(this.JobType.ToString()), null)); } if (this.PoisonCount >= ConfigBase <MRSConfigSchema> .GetConfig <int>("HardPoisonLimit")) { return(new JobPickupRec(this, JobPickupResult.PoisonedJob, DateTime.MaxValue, MrsStrings.PickupStatusJobPoisoned(this.PoisonCount), null)); } if (this.IsActiveOnThisMRSInstance) { return(new JobPickupRec(this, JobPickupResult.JobAlreadyActive, DateTime.MaxValue, LocalizedString.Empty, null)); } DateTime utcNow = DateTime.UtcNow; if (this.Status == RequestStatus.Completed && (!this.DoNotPickUntilHasElapsed || this.DoNotPickUntilTimestamp == DateTime.MinValue) && !this.RehomeRequest) { return(new JobPickupRec(this, JobPickupResult.CompletedJobSkipped, (this.DoNotPickUntilTimestamp == DateTime.MinValue) ? DateTime.MaxValue : this.DoNotPickUntilTimestamp, LocalizedString.Empty, null)); } if (this.CancelRequest && !this.DoNotPickUntilHasElapsed) { return(new JobPickupRec(this, JobPickupResult.PostponeCancel, this.DoNotPickUntilTimestamp, LocalizedString.Empty, null)); } if (!this.isInteractive && !this.IsLightRequest && !this.DoNotPickUntilHasElapsed) { MrsTracer.Service.Debug("Ignoring MoveJob '{0}' on queue '{1}' having DoNotPickUntilTimestamp of {2}.", new object[] { this.RequestGuid, this.RequestQueueGuid, this.DoNotPickUntilTimestamp.ToLocalTime() }); return(new JobPickupRec(this, JobPickupResult.JobIsPostponed, this.DoNotPickUntilTimestamp, LocalizedString.Empty, null)); } if (this.InternalFlags.HasFlag(RequestJobInternalFlags.ExecutedByTransportSync)) { MrsTracer.Service.Debug("Ignoring MoveJob '{0}' since Tranport Sync Owns Execution of the job.", new object[] { this.RequestGuid }); return(new JobPickupRec(this, JobPickupResult.JobOwnedByTransportSync, DateTime.MaxValue, LocalizedString.Empty, null)); } JobPickupRec result; using (DisposeGuard disposeGuard = default(DisposeGuard)) { using (RequestJobProvider requestJobProvider = new RequestJobProvider(this.RequestQueueGuid, systemMailbox)) { using (TransactionalRequestJob transactionalRequestJob = (TransactionalRequestJob)requestJobProvider.Read <TransactionalRequestJob>(new RequestJobObjectId(this.RequestGuid, this.RequestQueueGuid, this.MessageID))) { if (transactionalRequestJob == null) { result = new JobPickupRec(this, JobPickupResult.InvalidJob, DateTime.MaxValue, MrsStrings.PickupStatusCorruptJob, null); } else if (!transactionalRequestJob.IsSupported()) { result = new JobPickupRec(this, JobPickupResult.UnknownJobType, DateTime.MaxValue, MrsStrings.PickupStatusSubTypeNotSupported(transactionalRequestJob.RequestType.ToString()), null); } else if (transactionalRequestJob.ValidationResult != RequestJobBase.ValidationResultEnum.Valid) { this.ProcessInvalidJob(transactionalRequestJob, requestJobProvider); result = new JobPickupRec(this, JobPickupResult.InvalidJob, DateTime.MaxValue, MrsStrings.PickupStatusInvalidJob(transactionalRequestJob.ValidationResult.ToString(), transactionalRequestJob.ValidationMessage), null); } else if (transactionalRequestJob.Status == RequestStatus.Completed && !transactionalRequestJob.RehomeRequest) { this.CleanupCompletedJob(transactionalRequestJob, requestJobProvider); result = new JobPickupRec(this, JobPickupResult.CompletedJobCleanedUp, DateTime.MaxValue, MrsStrings.PickupStatusCompletedJob, null); } else if (!transactionalRequestJob.ShouldProcessJob()) { result = new JobPickupRec(this, JobPickupResult.DisabledJobPickup, DateTime.MaxValue, MrsStrings.PickupStatusDisabled, null); } else { ReservationContext reservationContext = null; if (!this.IsLightRequest && !MoveJob.CacheJobQueues) { reservationContext = new ReservationContext(); disposeGuard.Add <ReservationContext>(reservationContext); try { this.ReserveLocalForestResources(reservationContext, transactionalRequestJob); } catch (LocalizedException ex) { if (CommonUtils.ExceptionIs(ex, new WellKnownException[] { WellKnownException.ResourceReservation })) { return(new JobPickupRec(this, JobPickupResult.ReservationFailure, utcNow + MoveJob.JobPickupRetryInterval, MrsStrings.PickupStatusReservationFailure(CommonUtils.FullExceptionMessage(ex)), ex as ResourceReservationException)); } throw; } } if (!TestIntegration.Instance.DisableRemoteHostNameBlacklisting && transactionalRequestJob.RequestType == MRSRequestType.Move && (transactionalRequestJob.Flags & RequestFlags.CrossOrg) != RequestFlags.None && (transactionalRequestJob.Flags & RequestFlags.RemoteLegacy) == RequestFlags.None && !string.IsNullOrEmpty(transactionalRequestJob.RemoteHostName)) { string key = transactionalRequestJob.RemoteHostName.ToLowerInvariant(); DateTime nextRecommendedPickup; if (MoveJob.RemoteHostsInProxyBackoff.TryGetValue(key, out nextRecommendedPickup)) { return(new JobPickupRec(this, JobPickupResult.ProxyBackoff, nextRecommendedPickup, MrsStrings.PickupStatusProxyBackoff(transactionalRequestJob.RemoteHostName), null)); } } MrsTracer.Service.Debug("Attempting to take over MoveJob '{0}' on queue '{1}', priority={2}", new object[] { transactionalRequestJob, this.RequestQueueGuid, transactionalRequestJob.Priority }); transactionalRequestJob.RequestJobState = JobProcessingState.InProgress; transactionalRequestJob.MRSServerName = CommonUtils.LocalComputerName; if (!this.IsLightRequest) { transactionalRequestJob.PoisonCount++; transactionalRequestJob.LastPickupTime = new DateTime?(DateTime.UtcNow); } if (!transactionalRequestJob.Suspend && !transactionalRequestJob.RehomeRequest && transactionalRequestJob.Status != RequestStatus.Suspended && transactionalRequestJob.Status != RequestStatus.AutoSuspended && transactionalRequestJob.Status != RequestStatus.Failed && transactionalRequestJob.Status != RequestStatus.Completed && transactionalRequestJob.Status != RequestStatus.CompletedWithWarning) { transactionalRequestJob.Status = ((reservationContext == null) ? RequestStatus.Queued : RequestStatus.InProgress); } requestJobProvider.Save(transactionalRequestJob); this.Status = transactionalRequestJob.Status; JobPickupRec jobPickupRec; if (this.IsLightRequest) { jobPickupRec = new JobPickupRec(this, JobPickupResult.JobPickedUp, DateTime.MaxValue, MrsStrings.PickupStatusLightJob(transactionalRequestJob.Suspend, transactionalRequestJob.RehomeRequest, transactionalRequestJob.Priority.ToString()), null); MoveJob.PerformLightJobAction(requestJobProvider.SystemMailbox, RequestJobProvider.CreateRequestStatistics(transactionalRequestJob)); } else { MailboxSyncerJobs.CreateJob(transactionalRequestJob, reservationContext); jobPickupRec = new JobPickupRec(this, JobPickupResult.JobPickedUp, DateTime.MaxValue, MrsStrings.PickupStatusCreateJob(transactionalRequestJob.SyncStage.ToString(), transactionalRequestJob.CancelRequest, transactionalRequestJob.Priority.ToString()), null); } disposeGuard.Success(); result = jobPickupRec; } } } } return(result); }
private List <T> InternalFind <T>(QueryFilter filter, ObjectId rootId, bool deepSearch, SortBy sortBy, int pageSize) where T : IConfigurable, new() { if (!RequestJobProvider.IsRequestStatistics(typeof(T), false)) { throw new ArgumentException("RequestJobProvider can only find *RequestStatistics objects."); } List <T> list = new List <T>(); RequestJobQueryFilter requestJobQueryFilter = filter as RequestJobQueryFilter; if (requestJobQueryFilter != null) { MRSRequestType?requestType = requestJobQueryFilter.RequestType; Guid mdbGuid = requestJobQueryFilter.MdbGuid; Guid requestGuid = requestJobQueryFilter.RequestGuid; this.EnsureStoreConnectionExists(mdbGuid); Restriction restriction = null; if (requestType != null) { RequestJobNamedPropertySet requestJobNamedPropertySet = RequestJobNamedPropertySet.Get(this.SystemMailbox); restriction = Restriction.EQ(requestJobNamedPropertySet.PropTags[14], requestType.Value); if (requestType.Value == MRSRequestType.Move) { restriction = Restriction.Or(new Restriction[] { Restriction.Not(Restriction.Exist(requestJobNamedPropertySet.PropTags[14])), restriction }); } } byte[] searchKey = null; if (requestGuid != Guid.Empty) { searchKey = RequestJobXML.CreateMessageSearchKey(requestGuid); } List <RequestJobXML> list2 = MoveObjectInfo <RequestJobXML> .LoadAll(searchKey, restriction, mdbGuid, this.store, RequestJobXML.RequestJobsFolderName, new MoveObjectInfo <RequestJobXML> .IsSupportedObjectTypeDelegate(RequestJobXML.IsMessageTypeSupported), new MoveObjectInfo <RequestJobXML> .EmptyTDelegate(this.CreateDummyFromSearchKey)); if (list2 == null || list2.Count == 0) { MrsTracer.Common.Debug("No RequestJob messages found.", new object[0]); } else { foreach (RequestJobXML requestJobXML in list2) { RequestJobProvider.FixTenantInfo(requestJobXML); RequestStatisticsBase requestStatisticsBase = RequestJobProvider.CreateRequestStatistics(typeof(T), requestJobXML, true); requestStatisticsBase.OriginatingMDBGuid = mdbGuid; if (requestStatisticsBase.Identity == null) { requestStatisticsBase.Identity = new RequestJobObjectId(requestStatisticsBase.IdentifyingGuid, mdbGuid, null); } if (!requestStatisticsBase.IsFake) { using (this.IndexProvider.RescopeTo(requestStatisticsBase.DomainControllerToUpdate, requestStatisticsBase.OrganizationId)) { if (requestStatisticsBase.UserId != null) { requestStatisticsBase.User = this.IndexProvider.ReadADUser(requestStatisticsBase.UserId, requestStatisticsBase.ExchangeGuid); } if (requestStatisticsBase.SourceUserId != null) { requestStatisticsBase.SourceUser = this.IndexProvider.ReadADUser(requestStatisticsBase.SourceUserId, requestStatisticsBase.SourceExchangeGuid); } if (requestStatisticsBase.TargetUserId != null) { requestStatisticsBase.TargetUser = this.IndexProvider.ReadADUser(requestStatisticsBase.TargetUserId, requestStatisticsBase.TargetExchangeGuid); } if (!typeof(T).Equals(typeof(MoveRequestStatistics)) && requestStatisticsBase.RequestType != MRSRequestType.Move) { List <IRequestIndexEntry> list3 = new List <IRequestIndexEntry>(); if (requestStatisticsBase.IndexIds != null && requestStatisticsBase.IndexIds.Count > 0) { foreach (RequestIndexId indexId in requestStatisticsBase.IndexIds) { IRequestIndexEntry requestIndexEntry; try { requestIndexEntry = this.IndexProvider.Read(new RequestIndexEntryObjectId(requestStatisticsBase.RequestGuid, requestStatisticsBase.TargetExchangeGuid, requestStatisticsBase.RequestType, requestStatisticsBase.OrganizationId, indexId, null)); } catch (TenantOrgContainerNotFoundException) { requestIndexEntry = null; } if (requestIndexEntry != null) { list3.Add(requestIndexEntry); } } } requestStatisticsBase.IndexEntries = list3; } if (this.IndexProvider.DomainController == null && !string.IsNullOrEmpty(requestStatisticsBase.DomainControllerToUpdate)) { requestStatisticsBase.DomainControllerToUpdate = null; } } } requestStatisticsBase.ValidateRequestJob(); if (this.LoadReport) { ReportData reportData = new ReportData(requestStatisticsBase.IdentifyingGuid, requestStatisticsBase.ReportVersion); reportData.Load(this.SystemMailbox); requestStatisticsBase.Report = reportData.ToReport(); } if (requestStatisticsBase != null && requestStatisticsBase.GetType().Equals(typeof(T))) { list.Add((T)((object)requestStatisticsBase)); } } } } return(list); }
private void SaveOrDelete(TransactionalRequestJob requestJob, bool save) { if (!save && (requestJob.MoveObject == null || requestJob.Provider == null || requestJob.Provider != this)) { throw new ArgumentException("RequestJobProvider can only Delete TransactionalRequestJob objects created by this RequestJobProvider.", "instance"); } if (requestJob.Provider != null && requestJob.Provider != this) { throw new ArgumentException("RequestJobProvider can only work on TransactionalRequestJob objects created by this RequestJobProvider.", "instance"); } Guid guid = Guid.Empty; Guid guid2 = Guid.Empty; byte[] messageId = null; ADUser aduser = null; List <IRequestIndexEntry> list = null; RequestJobObjectId requestJobObjectId = requestJob.Identity; if (requestJobObjectId != null) { messageId = requestJobObjectId.MessageId; guid = requestJobObjectId.RequestGuid; guid2 = requestJobObjectId.MdbGuid; } else { if (requestJob.RequestType == MRSRequestType.Move) { guid = requestJob.ExchangeGuid; } else { guid = requestJob.RequestGuid; } guid2 = requestJob.WorkItemQueueMdb.ObjectGuid; } if (requestJob.RequestQueue == null) { requestJob.RequestQueue = requestJob.WorkItemQueueMdb; } if (!(guid == Guid.Empty) && !(guid2 == Guid.Empty)) { if (requestJobObjectId == null) { requestJobObjectId = new RequestJobObjectId(guid, guid2, messageId); requestJob.Identity = requestJobObjectId; } requestJob.ValidateRequestJob(); if (requestJob.IsValid) { aduser = requestJob.User; list = requestJob.IndexEntries; } bool flag = false; MoveObjectInfo <RequestJobXML> moveObjectInfo = null; try { MoveObjectInfo <RequestJobXML> moveObjectInfo2; if (requestJob.MoveObject != null) { moveObjectInfo2 = requestJob.MoveObject; } else { this.EnsureStoreConnectionExists(guid2); moveObjectInfo = new MoveObjectInfo <RequestJobXML>(guid2, this.store, messageId, RequestJobXML.RequestJobsFolderName, RequestJobXML.RequestJobsMessageClass, RequestJobXML.CreateMessageSubject(guid), RequestJobXML.CreateMessageSearchKey(guid)); moveObjectInfo2 = moveObjectInfo; } flag = (moveObjectInfo2.MessageFound || moveObjectInfo2.OpenMessage()); if (save) { RequestJobXML requestJobXML = new RequestJobXML(requestJob); requestJobXML.TimeTracker.SetTimestamp(RequestJobTimestamp.LastUpdate, new DateTime?(DateTime.UtcNow)); if (!flag) { moveObjectInfo2.DeleteOldMessages(); } moveObjectInfo2.SaveObject(requestJobXML, new MoveObjectInfo <RequestJobXML> .GetAdditionalProperties(requestJobXML.GetPropertiesWrittenOnRequestJob)); requestJobXML.Retire(); } else if (flag) { moveObjectInfo2.DeleteMessage(); requestJob.TimeTracker.CurrentState = RequestState.Removed; } else { MrsTracer.Common.Warning("Request job message could not be removed for Request '{0}'. AD data will still be removed", new object[] { requestJobObjectId }); } } finally { if (moveObjectInfo != null) { moveObjectInfo.Dispose(); moveObjectInfo = null; } } if ((aduser != null && requestJob.RequestType == MRSRequestType.Move) || (list != null && requestJob.RequestType != MRSRequestType.Move)) { if (save && !requestJob.CancelRequest) { using (this.IndexProvider.RescopeTo(requestJob.DomainControllerToUpdate, requestJob.OrganizationId)) { MrsTracer.Common.Debug("Updating Index/ADUser data for RequestJob '{0}'.", new object[] { requestJobObjectId }); bool flag2 = false; for (;;) { try { if (requestJob.RequestType == MRSRequestType.Move) { this.IndexProvider.UpdateADData(aduser, requestJob, save); this.IndexProvider.RecipientSession.Save(aduser); } else { foreach (IRequestIndexEntry requestIndexEntry in list) { RequestJobProvider.UpdateIndexEntryData(requestIndexEntry, requestJob); this.IndexProvider.Save(requestIndexEntry); } } } catch (ADTransientException ex) { if (!flag2 && this.IndexProvider.OwnsSessions) { this.IndexProvider.DomainController = null; flag2 = true; continue; } CommonUtils.LogEvent(MRSEventLogConstants.Tuple_ADWriteFailed, new object[] { requestJob.Identity, requestJob.RequestType, requestJob.RequestGuid.ToString(), (requestJob.RequestQueue != null) ? requestJob.RequestQueue.ToString() : "null", requestJob.Status, requestJob.StatusDetail, requestJob.Flags, CommonUtils.FullExceptionMessage(ex) }); throw; } break; } return; } } MrsTracer.Common.Warning("Not updating Index/ADUser data for RequestJob '{0}'.", new object[] { requestJobObjectId }); return; } MrsTracer.Common.Warning("Not updating Index/ADUser data for orphaned RequestJob '{0}'.", new object[] { requestJobObjectId }); if (!flag && !save) { throw new UnableToDeleteMoveRequestMessagePermanentException(); } return; } if (save) { throw new MoveRequestMissingInfoSavePermanentException(); } throw new MoveRequestMissingInfoDeletePermanentException(); }
public IConfigurable Read <T>(ObjectId identity, ReadJobFlags readJobFlags) where T : IConfigurable, new() { if (identity == null) { throw new ArgumentNullException("identity", "The identity of the object to be read must be specified."); } if (!(identity is RequestJobObjectId)) { throw new ArgumentException("RequestJobProvider can only identify RequestJobs based on RequestJobObjectIds.", "identity"); } if (!typeof(T).Equals(typeof(TransactionalRequestJob)) && !RequestJobProvider.IsRequestStatistics(typeof(T), true)) { throw new ArgumentException("RequestJobProvider can only Read *RequestStatistics or TransactionalRequestJob objects."); } bool flag = false; if (typeof(T).Equals(typeof(TransactionalRequestJob))) { flag = true; } RequestJobObjectId requestJobObjectId = (RequestJobObjectId)identity; Guid requestGuid = requestJobObjectId.RequestGuid; Guid mdbGuid = requestJobObjectId.MdbGuid; byte[] messageId = requestJobObjectId.MessageId; ADUser aduser = requestJobObjectId.User; ADUser aduser2 = requestJobObjectId.SourceUser; ADUser aduser3 = requestJobObjectId.TargetUser; IRequestIndexEntry indexEntry = requestJobObjectId.IndexEntry; List <IRequestIndexEntry> list = new List <IRequestIndexEntry>(); if (requestGuid == Guid.Empty || mdbGuid == Guid.Empty) { throw new NotEnoughInformationToFindMoveRequestPermanentException(); } this.EnsureStoreConnectionExists(mdbGuid); MoveObjectInfo <RequestJobXML> moveObjectInfo = null; IConfigurable result; try { moveObjectInfo = new MoveObjectInfo <RequestJobXML>(mdbGuid, this.store, messageId, RequestJobXML.RequestJobsFolderName, RequestJobXML.RequestJobsMessageClass, RequestJobXML.CreateMessageSubject(requestGuid), RequestJobXML.CreateMessageSearchKey(requestGuid)); RequestJobXML requestJobXML = null; if (moveObjectInfo.OpenMessage()) { if (moveObjectInfo.CheckObjectType(new MoveObjectInfo <RequestJobXML> .IsSupportedObjectTypeDelegate(RequestJobXML.IsMessageTypeSupported))) { requestJobXML = moveObjectInfo.ReadObject(ReadObjectFlags.DontThrowOnCorruptData); } else { MrsTracer.Common.Warning("Found unexpected JobType for move job {0}", new object[] { requestJobObjectId.ToString() }); } if (requestJobXML == null) { if (!this.AllowInvalid) { return(null); } requestJobXML = RequestJobBase.CreateDummyObject <RequestJobXML>(); requestJobXML.RequestGuid = requestGuid; requestJobXML.ExchangeGuid = requestGuid; } requestJobXML.OriginatingMDBGuid = mdbGuid; if (requestJobXML.Identity == null) { requestJobXML.Identity = requestJobObjectId; } requestJobXML.Identity.MessageId = moveObjectInfo.MessageId; RequestJobProvider.FixTenantInfo(requestJobXML); if (!requestJobXML.IsFake) { using (this.IndexProvider.RescopeTo(requestJobXML.DomainControllerToUpdate, requestJobXML.OrganizationId)) { if (aduser == null && requestJobXML.UserId != null) { aduser = this.IndexProvider.ReadADUser(requestJobXML.UserId, requestJobXML.ExchangeGuid); } if (aduser2 == null && requestJobXML.SourceUserId != null) { aduser2 = this.IndexProvider.ReadADUser(requestJobXML.SourceUserId, requestJobXML.SourceExchangeGuid); } if (aduser3 == null && requestJobXML.TargetUserId != null) { aduser3 = this.IndexProvider.ReadADUser(requestJobXML.TargetUserId, requestJobXML.TargetExchangeGuid); } if (!typeof(T).Equals(typeof(MoveRequestStatistics)) && requestJobXML.RequestType != MRSRequestType.Move && requestJobXML.IndexIds != null && requestJobXML.IndexIds.Count > 0) { int capacity = requestJobXML.IndexIds.Count - 1; bool flag2 = false; List <RequestIndexEntryObjectId> list2 = new List <RequestIndexEntryObjectId>(capacity); foreach (RequestIndexId requestIndexId in requestJobXML.IndexIds) { if (indexEntry != null && requestIndexId.Equals(indexEntry.RequestIndexId)) { if (!flag2) { list.Add(indexEntry); } flag2 = true; } else if (readJobFlags.HasFlag(ReadJobFlags.SkipReadingMailboxRequestIndexEntries) && requestIndexId.Location == RequestIndexLocation.Mailbox) { MrsTracer.Common.Debug("Skipping loading of an IRequestIndexEntry found in a mailbox.", new object[0]); } else { list2.Add(new RequestIndexEntryObjectId(requestJobXML.RequestGuid, requestJobXML.TargetExchangeGuid, requestJobXML.RequestType, requestJobXML.OrganizationId, requestIndexId, null)); } } foreach (RequestIndexEntryObjectId objectId in list2) { IRequestIndexEntry requestIndexEntry = this.IndexProvider.Read(objectId); if (requestIndexEntry != null) { list.Add(requestIndexEntry); } } } if (this.IndexProvider.DomainController == null && !string.IsNullOrEmpty(requestJobXML.DomainControllerToUpdate)) { requestJobXML.DomainControllerToUpdate = null; } } } requestJobXML.User = aduser; requestJobXML.SourceUser = aduser2; requestJobXML.TargetUser = aduser3; requestJobXML.IndexEntries = list; if (!readJobFlags.HasFlag(ReadJobFlags.SkipValidation)) { requestJobXML.ValidateRequestJob(); } if (this.AllowInvalid) { ValidationError[] array = requestJobXML.Validate(); if (array != null && array.Length > 0) { requestJobXML.IsFake = true; } } if (flag) { TransactionalRequestJob transactionalRequestJob = new TransactionalRequestJob(requestJobXML); requestJobXML.Retire(); transactionalRequestJob.Provider = this; transactionalRequestJob.MoveObject = moveObjectInfo; moveObjectInfo = null; result = transactionalRequestJob; } else { RequestStatisticsBase requestStatisticsBase = RequestJobProvider.CreateRequestStatistics(typeof(T), requestJobXML, true); if (requestStatisticsBase == null) { requestStatisticsBase = new MoveRequestStatistics(requestJobXML); requestJobXML.Retire(); } if (this.LoadReport) { ReportData reportData = new ReportData(requestStatisticsBase.IdentifyingGuid, requestStatisticsBase.ReportVersion); reportData.Load(this.SystemMailbox); requestStatisticsBase.Report = reportData.ToReport(); } result = requestStatisticsBase; } } else { result = null; } } finally { if (moveObjectInfo != null) { moveObjectInfo.Dispose(); moveObjectInfo = null; } } return(result); }