public async Task <HttpResponseMessage> ScheduleLegacyRequest(LegacySchedulerRequestDTO dto)
        {
            if (dto.IsNull() || dto.ScheduleJSON.IsNullOrEmpty())
            {
                throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, "The Request Schedule is not defined."));
            }
            try
            {
                //Delete the recurring job, if it exists
                Hangfire.RecurringJob.RemoveIfExists(dto.RequestID.ToString());

                //Check if any additional schedule jobs exist
                if (DataContext.RequestSchedules.Any(p => p.RequestID == dto.RequestID))
                {
                    var schedules = await DataContext.RequestSchedules.Where(p => p.RequestID == dto.RequestID).ToListAsync();

                    foreach (var item in schedules)
                    {
                        if (item.ScheduleType == RequestScheduleTypes.Recurring)
                        {
                            Hangfire.RecurringJob.RemoveIfExists(item.ScheduleID);
                        }
                        else
                        {
                            Hangfire.BackgroundJob.Delete(item.ScheduleID);
                        }
                    }

                    DataContext.RequestSchedules.RemoveRange(schedules);
                    await DataContext.SaveChangesAsync();
                }

                RequestScheduleModel scheduleModel = Newtonsoft.Json.JsonConvert.DeserializeObject <RequestScheduleModel>(dto.ScheduleJSON);

                if (scheduleModel.PauseJob)
                {
                    //Do not schedule anything if the user has paused the schedule.
                    return(new HttpResponseMessage(HttpStatusCode.OK));
                }

                string cronExpression = ScheduleManager.GetCronExpression(scheduleModel);
                var    schedule       = NCrontab.CrontabSchedule.Parse(cronExpression);

                if (scheduleModel.StartDate <= DateTime.Now)
                {
                    Hangfire.RecurringJob.AddOrUpdate <LegacyRequestsController>(dto.RequestID.ToString(), (x) => x.OnSubmitSchedulerRequest(Identity.ID, dto.RequestID.Value), cronExpression); //LegacyRequests.ActivateLegacyRequestSchedule(Identity.ID, requestID, cronExpression);

                    RequestSchedule requestSchedule = new RequestSchedule();
                    requestSchedule.RequestID    = dto.RequestID.Value;
                    requestSchedule.ID           = Guid.NewGuid();
                    requestSchedule.ScheduleID   = dto.RequestID.ToString();
                    requestSchedule.ScheduleType = RequestScheduleTypes.Recurring;
                    DataContext.RequestSchedules.Add(requestSchedule);
                }
                else
                {
                    var jobID = Hangfire.BackgroundJob.Schedule <LegacyRequestsController>((x) => x.ActivateLegacyRequestSchedule(Identity.ID, dto.RequestID.Value, cronExpression), scheduleModel.StartDate);

                    RequestSchedule requestSchedule = new RequestSchedule();
                    requestSchedule.RequestID    = dto.RequestID.Value;
                    requestSchedule.ID           = Guid.NewGuid();
                    requestSchedule.ScheduleID   = jobID;
                    requestSchedule.ScheduleType = RequestScheduleTypes.Activate;
                    DataContext.RequestSchedules.Add(requestSchedule);
                }

                if (scheduleModel.EndDate.HasValue)
                {
                    var jobID = Hangfire.BackgroundJob.Schedule <LegacyRequestsController>((x) => x.DeactivateLegacyRequestSchedule(dto.RequestID.Value), scheduleModel.EndDate.Value);

                    RequestSchedule requestSchedule = new RequestSchedule();
                    requestSchedule.RequestID    = dto.RequestID.Value;
                    requestSchedule.ID           = Guid.NewGuid();
                    requestSchedule.ScheduleID   = jobID;
                    requestSchedule.ScheduleType = RequestScheduleTypes.Deactivate;
                    DataContext.RequestSchedules.Add(requestSchedule);
                }

                await DataContext.SaveChangesAsync();

                return(new HttpResponseMessage(HttpStatusCode.OK));
            }
            catch (Exception ex)
            {
                throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, "Could not schedule request. Details: " + ex.Message));
            }
        }
Пример #2
0
        /// <summary>
        /// Hangfire uses NCronTab expressions.
        /// A crontab expression are a very compact way to express a recurring schedule. A single expression is composed of 5 space-delimited fields:
        /// MINUTES HOURS DAYS MONTHS DAYS-OF-WEEK
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        internal static string GetCronExpression(RequestScheduleModel model)
        {
            int hour = model.RunTime.Hour;
            int mins = model.RunTime.Minute;

            // MINS HOURS DAYS MONTHS DAYS-WEEK
            string cronPattern = "{0} {1} {2} {3} {4}";
            string cronExpr    = null;

            switch (model.RecurrenceType)
            {
            case "Daily":
                switch (model.DailyType)
                {
                case "EveryNDays":
                    if (model.NDays == 1)
                    {
                        cronExpr = string.Format(cronPattern, mins, hour, "*", "*", "*");
                    }
                    else
                    {
                        cronExpr = string.Format(cronPattern, mins, hour, "*/" + model.NDays, "*", "*");
                    }
                    break;

                case "EveryWeekDay":
                    cronExpr = string.Format(cronPattern, mins, hour, "*", "*", "0-6");
                    break;
                }
                break;

            case "Weekly":
                string dow = "";
                if (model.Sunday)
                {
                    dow += "0,";
                }
                if (model.Monday)
                {
                    dow += "1,";
                }
                if (model.Tuesday)
                {
                    dow += "2,";
                }
                if (model.Wednesday)
                {
                    dow += "3,";
                }
                if (model.Thursday)
                {
                    dow += "4,";
                }
                if (model.Friday)
                {
                    dow += "5,";
                }
                if (model.Saturday)
                {
                    dow += "6,";
                }
                dow      = dow.Length > 0 ? dow.Substring(0, dow.Length - 1) : "*";
                cronExpr = string.Format(cronPattern, mins, hour, "*", "*", dow);
                break;

            case "Monthly":
                switch (model.MonthlyType)
                {
                case "DayOfMonth":
                    if (model.NMonthsForMonthDay == 1)
                    {
                        cronExpr = string.Format(cronPattern, mins, hour, model.MonthDay, "*", "*");
                    }
                    else
                    {
                        cronExpr = string.Format(cronPattern, mins, hour, model.MonthDay + "/" + model.NMonthsForMonthDay, "*", "*");
                    }
                    break;

                case "WeekDayOfMonth":
                    if (model.NMonthsForWeekDay == 1)
                    {
                        cronExpr = string.Format(cronPattern, mins, hour, "*", "*", GetWeekDayNumber(model.WeekDay));
                    }
                    else
                    {
                        cronExpr = string.Format(cronPattern, mins, hour, "*", "*/" + model.NMonthsForWeekDay, GetWeekDayNumber(model.WeekDay) + GetWeekDayPattern(model.NthWeekDay));
                    }
                    break;
                }
                break;

            case "Yearly":
                switch (model.YearlyType)
                {
                case "YearlyDayOfMonth":
                    cronExpr = string.Format(cronPattern, mins, hour, model.DayOfMonth, GetMonthNumber(model.Month), "*");
                    break;

                case "YearlyWeekDayOfMonth":
                    cronExpr = string.Format(cronPattern, mins, hour, "*", GetMonthNumber(model.Month), GetWeekDayNumber(model.WeekDay) + GetWeekDayPattern(model.NthWeekDay));
                    break;
                }
                break;
            }
            return(cronExpr);
        }
        public void OnSubmitSchedulerRequest(Guid userID, Guid requestID)
        {
            //Ensure the request exists and is not deleted, otherwise clear the schedule
            if (DataContext.Requests.Any(p => p.ID == requestID) == false || DataContext.Requests.Any(p => p.ID == requestID && p.Deleted == true))
            {
                DeleteRequestSchedules(requestID);
                return;
            }

            var user = (from u in DataContext.Users where u.ID == userID select u).AsNoTracking().FirstOrDefault();

            Lpp.Utilities.Security.ApiIdentity identity = new Utilities.Security.ApiIdentity(user.ID, user.UserName, user.FullName, user.OrganizationID);

            try
            {
                if (!DataContext.Requests.Any(p => p.ID == requestID))
                {
                    throw new Exception("Cannot find scheduled request ID = " + requestID.ToString());
                }

                var request = DataContext.Requests
                              .Include("Activity")
                              .Include("Activity.ParentActivity")
                              .Include("Activity.ParentActivity.ParentActivity")
                              .Include("SourceActivity")
                              .Include("SourceActivityProject")
                              .Include("SourceTaskOrder")
                              .Include("Organization")
                              .Include("Project")
                              .Include("RequestType")
                              .Include("RequesterCenter")
                              .Include("WorkplanType")
                              .Include("CreatedBy")
                              .Include("UpdatedBy")
                              .Include("SubmittedBy")
                              .Include("DataMarts")
                              .Include("Folders")
                              .Include("SearchTerms")
                              //.AsNoTracking()
                              .SingleOrDefault(r => r.ID == requestID);

                if (request == null)
                {
                    throw new Exception("Cannot find scheduled request ID = " + requestID.ToString());
                }

                var newRequest = CopyRequest(request, identity);
                //db.Entry(ctx.Request).Reload();
                DataContext.Entry(request).Reload();
                DataContext.Entry(newRequest).Reload();

                // Suffix the request name by its recurrence type and instance count.
                XmlSerializer        serializer    = new XmlSerializer(typeof(DTO.Schedule.RequestScheduleModel));
                RequestScheduleModel scheduleModel = serializer.Deserialize(new StringReader(request.Schedule ?? "")) as RequestScheduleModel;

                string schedName = string.IsNullOrEmpty(request.Name) ? "" : request.Name.Substring(0, (request.Name.Length > 100) ? 100 : request.Name.Length);
                schedName = schedName + " (" + scheduleModel.RecurrenceType + " " + (++request.ScheduleCount) + ")";

                newRequest.Name = schedName;
                // If there is a request due date and there is a schedule start date and request due date > schedule start date,
                // then slide the due date forward by the same amount from the current date.
                if (request.DueDate != null && scheduleModel.StartDate != null)
                {
                    DateTime newDueDate = DateTime.Now.Add(((DateTime)request.DueDate).Subtract(scheduleModel.StartDate.DateTime));
                    TimeSpan delta      = newDueDate.Subtract((DateTime)request.DueDate);
                    newRequest.DueDate = newDueDate;
                    //RequestService.TimeShift(newCtx, delta);
                }

                //var res = RequestService.TimeShift(newCtx, newCtx.Request.CreatedOn - ctx.Request.CreatedOn);
                DataContext.SaveChanges();
                if (!SubmitRequest(newRequest.ID, identity))
                {
                    throw new Exception("Failed to submit request.");
                }
            }
            catch (Exception ex)
            {
                //Log.Error(ex);
                throw;
            }
        }