public static void CreateJob(TransactionalRequestJob requestJob, ReservationContext reservation)
        {
            BaseJob baseJob;

            lock (MailboxSyncerJobs.syncRoot)
            {
                Guid guid = (requestJob.RequestType == MRSRequestType.Move) ? requestJob.ExchangeGuid : requestJob.RequestGuid;
                baseJob = MailboxSyncerJobs.FindJob(guid, false);
                if (baseJob != null)
                {
                    MrsTracer.Service.Error("Request {0} is already being worked on.", new object[]
                    {
                        guid
                    });
                    return;
                }
                baseJob = MailboxSyncerJobs.ConstructJob(requestJob);
                if (baseJob == null)
                {
                    MrsTracer.Service.Error("Don't know how to process '{0}' request", new object[]
                    {
                        requestJob.RequestType
                    });
                    return;
                }
                baseJob.Initialize(requestJob);
                baseJob.Reservation = reservation;
                MailboxSyncerJobs.activeJobs.Add(guid, baseJob);
                MailboxSyncerJobs.activeJobsIsEmpty.Reset();
            }
            JobScheduler.ScheduleJob(baseJob);
        }
Example #2
0
        public static void ReserveLocalForestResources(ReservationContext reservation, WorkloadType workloadType, MRSRequestType requestType, RequestFlags requestFlags, Guid archiveGuid, Guid exchangeGuid, Guid sourceExchangeGuid, Guid targetExchangeGuid, TenantPartitionHint partitionHint, ADObjectId sourceDatabase, ADObjectId sourceArchiveDatabase, ADObjectId targetDatabase, ADObjectId targetArchiveDatabase, Guid sourceDatabaseGuid, Guid sourceArchiveDatabaseGuid, Guid targetDatabaseGuid, Guid targetArchiveDatabaseGuid)
        {
            ReservationFlags reservationFlags;
            Guid             guid;
            Guid             guid2;

            if (requestType == MRSRequestType.Move || requestType == MRSRequestType.MailboxRelocation)
            {
                reservationFlags = ReservationFlags.Move;
                if (requestFlags.HasFlag(RequestFlags.MoveOnlyArchiveMailbox) && archiveGuid != Guid.Empty)
                {
                    guid = archiveGuid;
                }
                else
                {
                    guid = exchangeGuid;
                }
                guid2 = guid;
            }
            else
            {
                reservationFlags = ReservationFlags.Merge;
                guid             = sourceExchangeGuid;
                guid2            = targetExchangeGuid;
            }
            if (workloadType != Microsoft.Exchange.WorkloadManagement.WorkloadType.MailboxReplicationServiceHighPriority)
            {
                switch (workloadType)
                {
                case Microsoft.Exchange.WorkloadManagement.WorkloadType.MailboxReplicationServiceInternalMaintenance:
                    reservationFlags |= ReservationFlags.InternalMaintenance;
                    break;

                case Microsoft.Exchange.WorkloadManagement.WorkloadType.MailboxReplicationServiceInteractive:
                    reservationFlags |= ReservationFlags.Interactive;
                    break;
                }
            }
            else
            {
                reservationFlags |= ReservationFlags.HighPriority;
            }
            reservation.ReserveResource((guid2 == Guid.Empty) ? guid : guid2, partitionHint, MRSResource.Id, reservationFlags);
            if (targetDatabaseGuid != Guid.Empty)
            {
                reservation.ReserveResource(guid2, partitionHint, targetDatabase, reservationFlags | ReservationFlags.Write);
            }
            if (targetArchiveDatabaseGuid != Guid.Empty && targetArchiveDatabaseGuid != targetDatabaseGuid && archiveGuid != Guid.Empty)
            {
                reservation.ReserveResource(archiveGuid, partitionHint, targetArchiveDatabase, reservationFlags | ReservationFlags.Write | ReservationFlags.Archive);
            }
            if (sourceDatabaseGuid != Guid.Empty)
            {
                reservation.ReserveResource(guid, partitionHint, sourceDatabase, reservationFlags | ReservationFlags.Read);
            }
            if (sourceArchiveDatabaseGuid != Guid.Empty && sourceArchiveDatabaseGuid != sourceDatabaseGuid && archiveGuid != Guid.Empty)
            {
                reservation.ReserveResource(archiveGuid, partitionHint, sourceArchiveDatabase, reservationFlags | ReservationFlags.Read | ReservationFlags.Archive);
            }
        }
Example #3
0
 private void ReserveLocalForestResources(ReservationContext reservation, TransactionalRequestJob requestJob)
 {
     MoveJob.ReserveLocalForestResources(reservation, CommonUtils.ComputeWlmWorkloadType(this.Priority, this.isInteractive, ConfigBase <MRSConfigSchema> .GetConfig <WorkloadType>("WlmWorkloadType")), this.RequestType, this.Flags, this.ArchiveGuid, this.ExchangeGuid, this.SourceExchangeGuid, this.TargetExchangeGuid, this.PartitionHint, requestJob.SourceDatabase, requestJob.SourceArchiveDatabase, requestJob.TargetDatabase, requestJob.TargetArchiveDatabase, this.SourceDatabaseGuid, this.SourceArchiveDatabaseGuid, this.TargetDatabaseGuid, this.TargetArchiveDatabaseGuid);
 }
Example #4
0
        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);
        }