protected override RequestState RelinquishAction(TransactionalRequestJob requestJob, ReportData report) { requestJob.Status = RequestStatus.Suspended; requestJob.TimeTracker.SetTimestamp(RequestJobTimestamp.Suspended, new DateTime?(DateTime.UtcNow)); report.Append(MrsStrings.ReportSuspendingJob); return(RequestState.Suspended); }
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(); } } }); } }
protected override RequestState RelinquishAction(TransactionalRequestJob requestJob, ReportData report) { FailureRec failureRec = QuarantinedJobs.Get(base.RequestGuid); if (failureRec == null) { return(RequestState.Relinquished); } report.Append(MrsStrings.JobIsQuarantined, failureRec, ReportEntryFlags.Fatal); requestJob.Suspend = true; requestJob.Status = RequestStatus.Failed; requestJob.TimeTracker.SetTimestamp(RequestJobTimestamp.Failure, new DateTime?(DateTime.UtcNow)); QuarantinedJobs.Remove(base.RequestGuid); RequestJobLog.Write(requestJob); return(RequestState.Failed); }
protected override RequestState RelinquishAction(TransactionalRequestJob requestJob, ReportData report) { requestJob.TimeTracker.SetTimestamp(RequestJobTimestamp.Failure, null); requestJob.TimeTracker.SetTimestamp(RequestJobTimestamp.Suspended, null); requestJob.FailureCode = null; requestJob.FailureType = null; requestJob.FailureSide = null; requestJob.Message = LocalizedString.Empty; if (requestJob.SyncStage <= SyncStage.None) { requestJob.Status = RequestStatus.Queued; requestJob.TimeTracker.CurrentState = RequestState.Queued; } else { requestJob.Status = RequestStatus.InProgress; requestJob.TimeTracker.CurrentState = RequestState.InitialSeeding; } report.Append(MrsStrings.ReportJobResumed(requestJob.Status.ToString())); return(RequestState.Relinquished); }
public SyncStateError LoadSyncState(Guid expectedRequestGuid, ReportData report, SyncStateFlags flags) { MrsTracer.Service.Debug("Attempting to load saved synchronization state.", new object[0]); string text = this.DestinationMailbox.LoadSyncState(this.syncStateKey); if (new TestIntegration(false).InjectCorruptSyncState) { text = "Some corrupt sync state"; } PersistedSyncData persistedSyncData; try { persistedSyncData = PersistedSyncData.Deserialize(text); } catch (UnableToDeserializeXMLException failure) { DestinationMailboxWrapper.StringSummary stringSummary = new DestinationMailboxWrapper.StringSummary(text); report.Append(MrsStrings.ReportSyncStateCorrupt(expectedRequestGuid, stringSummary.Length, stringSummary.Start, stringSummary.End), failure, ReportEntryFlags.Target); return(SyncStateError.CorruptSyncState); } if (persistedSyncData == null) { MrsTracer.Service.Debug("Saved sync state does not exist.", new object[0]); report.Append(MrsStrings.ReportSyncStateNull(expectedRequestGuid)); return(SyncStateError.NullSyncState); } if (persistedSyncData.MoveRequestGuid != expectedRequestGuid) { MrsTracer.Service.Warning("Saved state message contains invalid data (move request guid does not match). Discarding saved state.", new object[0]); report.Append(MrsStrings.ReportSyncStateWrongRequestGuid(expectedRequestGuid, persistedSyncData.MoveRequestGuid)); return(SyncStateError.WrongRequestGuid); } MrsTracer.Service.Debug("Successfully parsed saved state: stage={0}", new object[] { persistedSyncData.SyncStage }); this.SyncState = persistedSyncData; string text2 = this.DestinationMailbox.LoadSyncState(this.icsSyncStateKey); try { this.ICSSyncState = MailboxMapiSyncState.Deserialize(text2); } catch (UnableToDeserializeXMLException failure2) { DestinationMailboxWrapper.StringSummary stringSummary2 = new DestinationMailboxWrapper.StringSummary(text2); report.Append(MrsStrings.ReportIcsSyncStateCorrupt(expectedRequestGuid, stringSummary2.Length, stringSummary2.Start, stringSummary2.End), failure2, ReportEntryFlags.Target); return(SyncStateError.CorruptIcsSyncState); } if (this.ICSSyncState == null) { report.Append(MrsStrings.ReportIcsSyncStateNull(expectedRequestGuid)); return(SyncStateError.NullIcsSyncState); } if (flags.HasFlag(SyncStateFlags.Replay)) { string text3 = this.DestinationMailbox.LoadSyncState(this.replaySyncStateKey); try { this.ReplaySyncState = ReplaySyncState.Deserialize(text3); } catch (UnableToDeserializeXMLException failure3) { DestinationMailboxWrapper.StringSummary stringSummary3 = new DestinationMailboxWrapper.StringSummary(text3); report.Append(MrsStrings.ReportReplaySyncStateCorrupt(expectedRequestGuid, stringSummary3.Length, stringSummary3.Start, stringSummary3.End), failure3, ReportEntryFlags.Target); return(SyncStateError.CorruptReplaySyncState); } if (this.ReplaySyncState == null) { report.Append(MrsStrings.ReportReplaySyncStateNull(expectedRequestGuid)); return(SyncStateError.NullReplaySyncState); } report.AppendDebug(MrsStrings.ReportSyncStateLoaded2(expectedRequestGuid, text.Length, text2.Length, text3.Length)); } else { report.AppendDebug(MrsStrings.ReportSyncStateLoaded(expectedRequestGuid, text.Length, text2.Length)); } return(SyncStateError.None); }
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(); }
protected override RequestState RelinquishAction(TransactionalRequestJob requestJob, ReportData report) { if (this.RehomeFailure == null) { return(requestJob.TimeTracker.CurrentState); } string stackTrace = this.RehomeFailure.StackTrace; if (CommonUtils.IsTransientException(this.RehomeFailure)) { this.RehomeFailure = new RehomeRequestTransientException(this.RehomeFailure); report.Append(MrsStrings.ReportTransientException(CommonUtils.GetFailureType(this.RehomeFailure), 0, 0), this.RehomeFailure, ReportEntryFlags.None); if (requestJob.Status == RequestStatus.Completed || requestJob.Status == RequestStatus.CompletedWithWarning) { requestJob.RehomeRequest = false; return(requestJob.TimeTracker.CurrentState); } requestJob.TimeTracker.SetTimestamp(RequestJobTimestamp.DoNotPickUntil, new DateTime?(DateTime.UtcNow + TimeSpan.FromMinutes(5.0))); if (CommonUtils.ExceptionIs(this.RehomeFailure, new WellKnownException[] { WellKnownException.MapiMdbOffline })) { return(RequestState.MDBOffline); } if (CommonUtils.ExceptionIs(this.RehomeFailure, new WellKnownException[] { WellKnownException.MapiNetworkError })) { return(RequestState.NetworkFailure); } if (CommonUtils.ExceptionIs(this.RehomeFailure, new WellKnownException[] { WellKnownException.Mapi })) { return(RequestState.TransientFailure); } return(RequestState.TransientFailure); } else { if (!(this.RehomeFailure is UnsupportedRehomeTargetVersionPermanentException)) { this.RehomeFailure = new RehomeRequestPermanentException(this.RehomeFailure); } requestJob.RehomeRequest = false; report.Append(MrsStrings.ReportFatalException(CommonUtils.GetFailureType(this.RehomeFailure)), this.RehomeFailure, ReportEntryFlags.Fatal); if (requestJob.Status == RequestStatus.Completed || requestJob.Status == RequestStatus.CompletedWithWarning) { return(requestJob.TimeTracker.CurrentState); } requestJob.Suspend = true; requestJob.Status = RequestStatus.Failed; requestJob.TimeTracker.SetTimestamp(RequestJobTimestamp.Failure, new DateTime?(DateTime.UtcNow)); requestJob.FailureCode = new int?(CommonUtils.HrFromException(this.RehomeFailure)); requestJob.FailureType = CommonUtils.GetFailureType(this.RehomeFailure); requestJob.FailureSide = new ExceptionSide?((requestJob.Direction == RequestDirection.Push) ? ExceptionSide.Source : ExceptionSide.Target); requestJob.Message = MrsStrings.MoveRequestMessageError(CommonUtils.FullExceptionMessage(this.RehomeFailure)); if (CommonUtils.ExceptionIs(this.RehomeFailure, new WellKnownException[] { WellKnownException.MapiMdbOffline })) { return(RequestState.FailedOther); } if (CommonUtils.ExceptionIs(this.RehomeFailure, new WellKnownException[] { WellKnownException.MapiNetworkError })) { return(RequestState.FailedNetwork); } if (CommonUtils.ExceptionIs(this.RehomeFailure, new WellKnownException[] { WellKnownException.Mapi })) { return(RequestState.FailedMAPI); } return(RequestState.FailedOther); } }
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 }); }