/// <summary>
    /// Sets data to database.
    /// </summary>
    protected void btnOK_Click(object sender, EventArgs e)
    {
        // Check "modify" permission
        if (!MembershipContext.AuthenticatedUser.IsAuthorizedPerResource("CMS.ScheduledTasks", "Modify"))
        {
            RedirectToAccessDenied("CMS.ScheduledTasks", "Modify");
        }

        // Check required fields format
        string errorMessage = new Validator()
                              .NotEmpty(txtTaskDisplayName.Text, rfvDisplayName.ErrorMessage)
                              .NotEmpty(txtTaskName.Text, rfvName.ErrorMessage)
                              .IsCodeName(txtTaskName.Text, GetString("Task_Edit.InvalidTaskName"))
                              .MatchesCondition(schedInterval.StartTime.SelectedDateTime, DataTypeManager.IsValidDate, String.Format("{0} {1}.", GetString("BasicForm.ErrorInvalidDateTime"), DateTime.Now))
                              .Result;

        if ((errorMessage == String.Empty) && !schedInterval.CheckIntervalPreceedings())
        {
            errorMessage = GetString("Task_Edit.BetweenIntervalPreceedingsError");
        }

        if ((errorMessage == String.Empty) && !schedInterval.CheckOneDayMinimum())
        {
            errorMessage = GetString("Task_Edit.AtLeastOneDayError");
        }

        // Validate assembly, but only if task is enabled (so tasks for not-installed modules can be disabled)
        if ((errorMessage == String.Empty) && chkTaskEnabled.Checked && !assemblyElem.IsValid())
        {
            errorMessage = assemblyElem.ErrorMessage;
        }

        // Checking date/time limit (SQL limit)
        if (errorMessage == String.Empty)
        {
            TaskInterval ti = SchedulingHelper.DecodeInterval(schedInterval.ScheduleInterval);
            if ((ti != null) && ((ti.StartTime < DataTypeManager.MIN_DATETIME) || (ti.StartTime > DataTypeManager.MAX_DATETIME)))
            {
                ti.StartTime = DateTime.Now;
                schedInterval.ScheduleInterval = SchedulingHelper.EncodeInterval(ti);
            }
        }

        // Check macro condition length
        if ((errorMessage == String.Empty) && (ucMacroEditor.Text.Length > 400))
        {
            errorMessage = String.Format(GetString("task_edit.invalidlength"), 400);
        }

        if (!String.IsNullOrEmpty(errorMessage))
        {
            ShowError(errorMessage);
        }
        else
        {
            // Check existing task name
            TaskInfo existingTask = TaskInfoProvider.GetTaskInfo(txtTaskName.Text.Trim(), SiteInfo != null ? SiteInfo.SiteName : null);

            if ((existingTask != null) && ((TaskInfo == null) || (existingTask.TaskID != TaskInfo.TaskID)))
            {
                ShowError(GetString("Task_Edit.TaskNameExists").Replace("%%name%%", existingTask.TaskName));
                return;
            }

            if (TaskInfo == null)
            {
                // create new item -> insert
                TaskInfo = new TaskInfo {
                    TaskSiteID = SiteID
                };
                if (!developmentMode)
                {
                    TaskInfo.TaskAllowExternalService = true;
                }
            }

            TaskInfo.TaskAssemblyName               = assemblyElem.AssemblyName.Trim();
            TaskInfo.TaskClass                      = assemblyElem.ClassName.Trim();
            TaskInfo.TaskData                       = txtTaskData.Text.Trim();
            TaskInfo.TaskName                       = txtTaskName.Text.Trim();
            TaskInfo.TaskEnabled                    = chkTaskEnabled.Checked;
            TaskInfo.TaskDeleteAfterLastRun         = chkTaskDeleteAfterLastRun.Checked;
            TaskInfo.TaskInterval                   = schedInterval.ScheduleInterval;
            TaskInfo.TaskDisplayName                = txtTaskDisplayName.Text.Trim();
            TaskInfo.TaskServerName                 = txtServerName.Text.Trim();
            TaskInfo.TaskRunInSeparateThread        = chkRunTaskInSeparateThread.Checked;
            TaskInfo.TaskUseExternalService         = chkTaskUseExternalService.Checked;
            TaskInfo.TaskCondition                  = ucMacroEditor.Text;
            TaskInfo.TaskRunIndividuallyForEachSite = chkRunIndividually.Checked;

            if (plcAllowExternalService.Visible)
            {
                TaskInfo.TaskAllowExternalService = chkTaskAllowExternalService.Checked;
            }
            if (plcUseExternalService.Visible)
            {
                TaskInfo.TaskUseExternalService = chkTaskUseExternalService.Checked;
            }

            TaskInfo.TaskNextRunTime = SchedulingHelper.GetFirstRunTime(SchedulingHelper.DecodeInterval(TaskInfo.TaskInterval));

            if (drpModule.Visible)
            {
                TaskInfo.TaskResourceID = ValidationHelper.GetInteger(drpModule.Value, 0);
            }

            TaskInfo.TaskUserID = ValidationHelper.GetInteger(ucUser.Value, 0);

            // Set synchronization to true (default is false for Scheduled task)
            TaskInfo.Generalized.StoreSettings();
            TaskInfo.Generalized.LogSynchronization = SynchronizationTypeEnum.LogSynchronization;
            TaskInfo.Generalized.LogIntegration     = true;
            TaskInfo.Generalized.LogEvents          = true;

            // If web farm support, create the tasks for all servers
            if (chkAllServers.Checked)
            {
                TaskInfoProvider.CreateWebFarmTasks(TaskInfo);
            }
            else
            {
                TaskInfoProvider.SetTaskInfo(TaskInfo);
            }

            // Restore original settings
            TaskInfo.Generalized.RestoreSettings();

            bool   notSystem = (TaskInfo == null) || (TaskInfo.TaskType != ScheduledTaskTypeEnum.System);
            string url       = UIContextHelper.GetElementUrl("CMS.ScheduledTasks", GetElementName(notSystem ? "EditTask" : "EditSystemTask"), true);

            // Add task ID and saved="1" query parameters
            url = URLHelper.AddParameterToUrl(String.Format(url, TaskInfo.TaskID), "saved", "1");

            // Add site ID query parameter and redirect to the finished URL
            URLHelper.Redirect(URLHelper.AddParameterToUrl(url, "siteid", SiteID.ToString()));
        }
    }
Exemple #2
0
    /// <summary>
    /// Handles the UniGrid's OnAction event.
    /// </summary>
    /// <param name="actionName">Name of item (button) that threw event</param>
    /// <param name="actionArgument">ID (value of Primary key) of corresponding data row</param>
    protected void gridElem_OnAction(string actionName, object actionArgument)
    {
        switch (actionName.ToLowerCSafe())
        {
        case "edit":
            if (!String.IsNullOrEmpty(EditURL))
            {
                URLHelper.Redirect(String.Format(EditURL, actionArgument));
            }
            break;

        case "delete":
        {
            // Check "modify" permission
            if (!MembershipContext.AuthenticatedUser.IsAuthorizedPerResource("CMS.ScheduledTasks", "Modify"))
            {
                RedirectToAccessDenied("CMS.ScheduledTasks", "Modify");
            }

            // Delete the task
            try
            {
                int taskId = Convert.ToInt32(actionArgument);

                TaskInfo ti = TaskInfoProvider.GetTaskInfo(taskId);
                if (ti != null)
                {
                    ti.Generalized.LogSynchronization = SynchronizationTypeEnum.LogSynchronization;
                    ti.Generalized.LogIntegration     = true;
                    ti.Generalized.LogEvents          = true;
                    TaskInfoProvider.DeleteTaskInfo(ti);
                }
            }
            catch (Exception ex)
            {
                ShowError(GetString("Task_List.DeleteError"), ex.Message);
            }
        }
        break;

        case "execute":
        {
            // Check "modify" permission
            if (!MembershipContext.AuthenticatedUser.IsAuthorizedPerResource("CMS.ScheduledTasks", "Modify"))
            {
                RedirectToAccessDenied("CMS.ScheduledTasks", "Modify");
            }

            TaskInfo ti = TaskInfoProvider.GetTaskInfo(Convert.ToInt32(actionArgument));
            if (ti != null)
            {
                SiteInfo si = SiteInfoProvider.GetSiteInfo(SiteID);
                if (!ti.TaskEnabled)
                {
                    // Task is not enabled (won't be executed at the end of request), run it now
                    SchedulingExecutor.ExecuteTask(ti.TaskID, (si != null) ? si.SiteName : SiteContext.CurrentSiteName);
                }
                else
                {
                    TaskInterval interval = SchedulingHelper.DecodeInterval(ti.TaskInterval);

                    if ((ti.TaskNextRunTime != DateTimeHelper.ZERO_TIME) || (interval.Period == SchedulingHelper.PERIOD_ONCE))
                    {
                        ti.TaskNextRunTime = DateTime.Now;

                        // Update the task
                        TaskInfoProvider.SetTaskInfo(ti);

                        // Run the task
                        SchedulingTimer.RunSchedulerImmediately = true;
                        if (si != null)
                        {
                            SchedulingTimer.SchedulerRunImmediatelySiteName = si.SiteName;
                        }
                    }
                    else
                    {
                        ShowWarning(GetString("ScheduledTask.TaskAlreadyrunning"));
                        return;
                    }
                }

                ShowConfirmation(GetString("ScheduledTask.WasExecuted"));
            }
        }
        break;
        }
    }
Exemple #3
0
    /// <summary>
    /// Saves the control. Returns false, if error occurred.
    /// </summary>
    public bool Save()
    {
        // Validates input data
        String error = ValidateData();

        if (!String.IsNullOrEmpty(error))
        {
            ShowError(error);
            return(false);
        }

        if (Report != null)
        {
            bool isNew = false;
            if (mReportSubscriptionInfo.ReportSubscriptionID <= 0)
            {
                // Insert mode - initialize reportSubscriptionID
                mReportSubscriptionInfo.ReportSubscriptionUserID = MembershipContext.AuthenticatedUser.UserID;
                mReportSubscriptionInfo.ReportSubscriptionSiteID = SiteContext.CurrentSiteID;
                mReportSubscriptionInfo.ReportSubscriptionSettings["ReportInterval"] = mIntervalStr;
                isNew = true;
            }

            if (!SimpleMode)
            {
                // Save basic form & validates basic form data
                if (!formElem.SaveData(null))
                {
                    return(false);
                }

                // Store all parameters in basic form to string XML representation
                mParameters = formElem.DataRow;
                mReportSubscriptionInfo.ReportSubscriptionValueID = 0;
                mReportSubscriptionInfo.ReportSubscriptionTableID = 0;
                mReportSubscriptionInfo.ReportSubscriptionGraphID = 0;

                // If subscription is not for whole report, store item ID
                string drpValue = drpItems.SelectedValue;
                if (drpValue != "all")
                {
                    int id = ValidationHelper.GetInteger(drpValue.Substring(1), 0);
                    if (drpValue.Contains('g'))
                    {
                        mReportSubscriptionInfo.ReportSubscriptionGraphID = id;
                    }
                    if (drpValue.Contains('t'))
                    {
                        mReportSubscriptionInfo.ReportSubscriptionTableID = id;
                    }
                    if (drpValue.Contains('v'))
                    {
                        mReportSubscriptionInfo.ReportSubscriptionValueID = id;
                    }
                }
            }
            else
            {
                mReportSubscriptionInfo.ReportSubscriptionGraphID = mGraphID;
                mReportSubscriptionInfo.ReportSubscriptionTableID = mTableID;
                mReportSubscriptionInfo.ReportSubscriptionValueID = mValueID;
            }

            if (mParameters != null)
            {
                // Find special 'from' and 'to' parameters.
                DataColumn dcFrom = mParameters.Table.Columns["fromdate"];
                DataColumn dcTo   = mParameters.Table.Columns["todate"];

                if (rbTime.Checked)
                {
                    if (dcTo != null)
                    {
                        // Convert column from datetime to string to enable store macros
                        mParameters.Table.Columns.Remove(dcTo.ColumnName);
                        mParameters.Table.Columns.Add(dcTo.ColumnName, typeof(String));

                        // Add current date time macro
                        mParameters[dcTo.ColumnName] = "{%CurrentDateTime%}";
                    }

                    // Create right macro datetime command based on given interval.
                    String command = String.Empty;
                    switch (drpLast.SelectedValue)
                    {
                    case "hour":
                        command = "AddHours";
                        break;

                    case "day":
                        command = "AddDays";
                        break;

                    case "week":
                        command = "AddWeeks";
                        break;

                    case "month":
                        command = "AddMonths";
                        break;

                    case "year":
                        command = "AddYears";
                        break;
                    }

                    // Create todate macro
                    int    last        = ValidationHelper.GetInteger(txtLast.Text.Trim(), 0);
                    String dateCommand = String.Format("{{%CurrentDateTime.{0}({1})%}}", command, last * (-1));

                    // Convert fromdate to string
                    if (dcFrom != null)
                    {
                        mParameters.Table.Columns.Remove(dcFrom.ColumnName);
                        mParameters.Table.Columns.Add(dcFrom.ColumnName, typeof(String));
                        mParameters[dcFrom.ColumnName] = dateCommand;
                    }
                }
                else
                {
                    // Empty fromdate and todate for uncheck limit date
                    if (dcFrom != null)
                    {
                        mParameters[dcFrom.ColumnName] = DBNull.Value;
                    }

                    if (dcTo != null)
                    {
                        mParameters[dcTo.ColumnName] = DBNull.Value;
                    }
                }

                // Write parameters to XML string representation
                mReportSubscriptionInfo.ReportSubscriptionParameters = ReportHelper.WriteParametersToXml(mParameters);
            }

            String email        = txtEmail.Text.Trim();
            bool   emailChanged = mReportSubscriptionInfo.ReportSubscriptionEmail != email;

            mReportSubscriptionInfo.ReportSubscriptionEnabled      = chkEnabled.Checked;
            mReportSubscriptionInfo.ReportSubscriptionReportID     = Report.ReportID;
            mReportSubscriptionInfo.ReportSubscriptionInterval     = ucInterval.ScheduleInterval;
            mReportSubscriptionInfo.ReportSubscriptionEmail        = email;
            mReportSubscriptionInfo.ReportSubscriptionSubject      = txtSubject.Text;
            mReportSubscriptionInfo.ReportSubscriptionCondition    = ucMacroEditor.Text;
            mReportSubscriptionInfo.ReportSubscriptionOnlyNonEmpty = chkNonEmpty.Checked;
            mReportSubscriptionInfo.ReportSubscriptionNextPostDate = SchedulingHelper.GetFirstRunTime(ucInterval.TaskInterval);

            ReportSubscriptionInfoProvider.SetReportSubscriptionInfo(mReportSubscriptionInfo);

            // Check whether email changed (applies for new subscription also)
            if (emailChanged)
            {
                String siteName = SiteContext.CurrentSiteName;

                EmailTemplateInfo eti = EmailTemplateProvider.GetEmailTemplate("Reporting_Subscription_information", siteName);
                if (eti != null)
                {
                    // Send information email
                    EmailMessage em = new EmailMessage();
                    em.EmailFormat   = EmailFormatEnum.Default;
                    em.From          = String.IsNullOrEmpty(eti.TemplateFrom) ? EmailHelper.Settings.NotificationsSenderAddress(siteName) : eti.TemplateFrom;
                    em.Recipients    = email;
                    em.Subject       = eti.TemplateSubject;
                    em.BccRecipients = eti.TemplateBcc;
                    em.CcRecipients  = eti.TemplateCc;

                    MacroResolver resolver = ReportSubscriptionSender.CreateSubscriptionMacroResolver(Report, mReportSubscriptionInfo, SiteContext.CurrentSite, em.Recipients);
                    em.Body          = resolver.ResolveMacros(eti.TemplateText);
                    em.PlainTextBody = resolver.ResolveMacros(eti.TemplatePlainText);

                    EmailHelper.ResolveMetaFileImages(em, eti.TemplateID, EmailTemplateInfo.OBJECT_TYPE, ObjectAttachmentsCategories.TEMPLATE);

                    EmailSender.SendEmail(siteName, em);
                }
            }

            // For new item and advanced mode redirect to store ID in query string
            if ((isNew) && (!SimpleMode))
            {
                URLHelper.Redirect(RequestContext.CurrentURL + "&saved=1&subscriptionid=" + mReportSubscriptionInfo.ReportSubscriptionID);
            }

            ShowChangesSaved();
            return(true);
        }

        return(false);
    }
Exemple #4
0
    /// <summary>
    /// Creates schedule interval string.
    /// </summary>
    protected override string EncodeInterval()
    {
        if (!TimeoutEnabled)
        {
            return(String.Empty);
        }

        TaskInterval ti     = new TaskInterval();
        string       result = string.Empty;

        try
        {
            ti.Period = Mode;

            if (Mode != SchedulingHelper.PERIOD_ONCE)
            {
                result = new Validator().NotEmpty(txtQuantity.Text, GetString("timeoutselector.quantity.errorempty")).IsInteger(txtQuantity.Text, String.Format(GetString("timeoutselector.quantity.wrongformat"), QUANTITYMAXIMUM)).Result;
                if (String.IsNullOrEmpty(result))
                {
                    int quantity = ValidationHelper.GetInteger(txtQuantity.Text, -1);
                    if ((quantity >= QuantityLowerBound) && (quantity <= QUANTITYMAXIMUM))
                    {
                        ti.Every = quantity;
                    }
                    else
                    {
                        txtQuantity.ForeColor = Color.Red;
                    }
                }
            }
            if (String.IsNullOrEmpty(result))
            {
                switch (Mode)
                {
                case SchedulingHelper.PERIOD_MINUTE:
                case SchedulingHelper.PERIOD_HOUR:
                case SchedulingHelper.PERIOD_DAY:
                    ti.BetweenStart = DateTime.MinValue;
                    ti.BetweenEnd   = DateTime.MaxValue;

                    // Add all days to match the format
                    AddWeekDays(ti);
                    AddWeekEnd(ti);
                    break;

                case SchedulingHelper.PERIOD_WEEK:
                    if (rbNextDay.Checked)
                    {
                        ti.Order = drpNextOrder.SelectedValue;
                        ti.Day   = drpNextDay.SelectedValue;
                    }
                    break;

                case SchedulingHelper.PERIOD_MONTH:
                    if (rbNextDate.Checked)
                    {
                        ti.Order = drpNextDate.SelectedValue;
                    }
                    else if (rbNextDay.Checked)
                    {
                        ti.Order = drpNextOrder.SelectedValue;
                        ti.Day   = drpNextDay.SelectedValue;
                    }
                    break;

                case SchedulingHelper.PERIOD_YEAR:
                    if (rbNextDate.Checked)
                    {
                        ti.Order = drpNextDateMonth.SelectedValue;
                        ti.Day   = drpNextDate.SelectedValue;
                    }
                    break;

                case SchedulingHelper.PERIOD_ONCE:
                    if (dateTimePicker.SelectedDateTime != DateTime.MinValue)
                    {
                        ti.StartTime = dateTimePicker.SelectedDateTime;
                    }
                    else
                    {
                        result = GetString("timeoutselector.errorinvaliddate");
                    }
                    break;
                }

                // Add specific time to start date
                if (String.IsNullOrEmpty(result) && cbSpecificTime.Visible && cbSpecificTime.Checked)
                {
                    //result = new Validator().NotEmpty(txtSpecificTimeHour.Text, GetString("timeoutselector.specifichour.errorempty")).IsInteger(txtSpecificTimeHour.Text, GetString("timeoutselector.specifichour.wrongformat")).NotEmpty(txtSpecificTimeMinute.Text, GetString("timeoutselector.specificminute.errorempty")).IsInteger(txtSpecificTimeMinute.Text, GetString("timeoutselector.specificminute.wrongformat")).Result;
                    if (timePicker.IsValid())
                    {
                        ti.StartTime = ti.StartTime.AddHours(timePicker.Time.Hour);
                        ti.StartTime = ti.StartTime.AddMinutes(timePicker.Time.Minute);

                        ti.UseSpecificTime = true;
                    }
                    else
                    {
                        result = timePicker.ErrorMessage;
                    }
                }
                else
                {
                    ti.UseSpecificTime = false;
                }
            }
        }
        catch (Exception ex)
        {
            ShowError(ex.Message);
            result = ex.Message;
            dateTimePicker.DateTimeTextBox.ForeColor = Color.Red;
        }

        if (!String.IsNullOrEmpty(result))
        {
            AddError(result);
            return(null);
        }

        WeekListChecked = true;

        return(SchedulingHelper.EncodeInterval(ti));
    }
    /// <summary>
    /// Saves configuration changes.
    /// </summary>
    protected void SaveData()
    {
        // Check "configure" permission
        if (!CMSContext.CurrentUser.IsAuthorizedPerResource("cms.newsletter", "configure"))
        {
            RedirectToCMSDeskAccessDenied("cms.newsletter", "configure");
        }

        string scheduledInterval = null;

        if (isDynamic && chkSchedule.Checked)
        {
            // Get scheduled interval for dynamic newsletter
            scheduledInterval = schedulerInterval.ScheduleInterval;
        }

        string errorMessage = ValidateNewsletterValues();

        if (!string.IsNullOrEmpty(errorMessage))
        {
            ShowError(errorMessage);
            return;
        }

        NewsletterInfo newsletterObj = NewsletterInfoProvider.GetNewsletterInfo(txtNewsletterName.Text.Trim(), CMSContext.CurrentSiteID);

        // Newsletter's code name must be unique
        if (newsletterObj != null && newsletterObj.NewsletterID != newsletterId)
        {
            ShowError(GetString("Newsletter_Edit.NewsletterNameExists"));
            return;
        }

        if (newsletterObj == null)
        {
            newsletterObj = NewsletterInfoProvider.GetNewsletterInfo(newsletterId);
        }

        SetNewsletterValues(newsletterObj);

        // Check if subscription template was selected
        int subscriptionTemplateValue = ValidationHelper.GetInteger(subscriptionTemplate.Value, 0);

        if (subscriptionTemplateValue == 0)
        {
            ShowError(GetString("Newsletter_Edit.NoSubscriptionTemplateSelected"));
            return;
        }
        newsletterObj.NewsletterSubscriptionTemplateID = subscriptionTemplateValue;

        // Check if double opt-in template was selected
        int optInTemplateValue = ValidationHelper.GetInteger(optInSelector.Value, 0);

        if (newsletterObj.NewsletterEnableOptIn && optInTemplateValue == 0)
        {
            ShowError(GetString("Newsletter_Edit.NoOptInTemplateSelected"));
            return;
        }
        newsletterObj.NewsletterOptInTemplateID = optInTemplateValue;

        // Check if unsubscription template was selected
        int unsubscriptionTemplateValue = ValidationHelper.GetInteger(unsubscriptionTemplate.Value, 0);

        if (unsubscriptionTemplateValue == 0)
        {
            ShowError(GetString("Newsletter_Edit.NoUnsubscriptionTemplateSelected"));
            return;
        }
        newsletterObj.NewsletterUnsubscriptionTemplateID = unsubscriptionTemplateValue;

        // ID of scheduled task which should be deleted
        int deleteScheduledTaskId = 0;

        if (isDynamic)
        {
            newsletterObj.NewsletterType           = NewsletterType.Dynamic;
            newsletterObj.NewsletterDynamicURL     = txtNewsletterDynamicURL.Text.Trim();
            newsletterObj.NewsletterDynamicSubject = radFollowing.Checked ? txtSubject.Text : string.Empty;

            if (chkSchedule.Checked)
            {
                // Set info for scheduled task
                TaskInfo task = GetDynamicNewsletterTask(newsletterObj);

                if (!schedulerInterval.CheckOneDayMinimum())
                {
                    // If problem occurred while setting schedule interval
                    ShowError(GetString("Newsletter_Edit.NoDaySelected"));
                    return;
                }

                if (!IsValidDate(SchedulingHelper.DecodeInterval(scheduledInterval).StartTime))
                {
                    ShowError(GetString("Newsletter.IncorrectDate"));
                    return;
                }

                task.TaskInterval = scheduledInterval;

                task.TaskNextRunTime = SchedulingHelper.GetNextTime(task.TaskInterval, new DateTime(), new DateTime());
                task.TaskDisplayName = GetString("DynamicNewsletter.TaskName") + newsletterObj.NewsletterDisplayName;
                task.TaskName        = "DynamicNewsletter_" + newsletterObj.NewsletterName;
                // Set task for processing in external service
                task.TaskAllowExternalService = true;
                task.TaskUseExternalService   = (SchedulingHelper.UseExternalService && NewsletterHelper.UseExternalServiceForDynamicNewsletters(CMSContext.CurrentSiteName));
                TaskInfoProvider.SetTaskInfo(task);
                newsletterObj.NewsletterDynamicScheduledTaskID = task.TaskID;
            }
            else
            {
                if (newsletterObj.NewsletterDynamicScheduledTaskID > 0)
                {
                    // Store task ID for deletion
                    deleteScheduledTaskId = newsletterObj.NewsletterDynamicScheduledTaskID;
                }
                newsletterObj.NewsletterDynamicScheduledTaskID = 0;
                schedulerInterval.Visible = false;
            }
        }
        else
        {
            newsletterObj.NewsletterType = NewsletterType.TemplateBased;

            // Check if issue template was selected
            int issueTemplateValue = ValidationHelper.GetInteger(issueTemplate.Value, 0);
            if (issueTemplateValue == 0)
            {
                ShowError(GetString("Newsletter_Edit.NoEmailTemplateSelected"));
                return;
            }
            newsletterObj.NewsletterTemplateID = issueTemplateValue;
        }

        // Save changes to DB
        NewsletterInfoProvider.SetNewsletterInfo(newsletterObj);
        if (deleteScheduledTaskId > 0)
        {
            // Delete scheduled task if schedule mail-outs were unchecked
            TaskInfoProvider.DeleteTaskInfo(deleteScheduledTaskId);
        }

        ShowChangesSaved();

        // Refresh header with display name
        ScriptHelper.RefreshTabHeader(Page, GetString("Newsletter_Header.Configuration"));
    }
        public async Task ActivationSched_Task_Run_Delay()
        {
            using var workItemGroup = SchedulingHelper.CreateWorkItemGroupForTesting(context, loggerFactory);
            TaskScheduler scheduler = workItemGroup.TaskScheduler;

            ManualResetEvent pause1 = new ManualResetEvent(false);
            ManualResetEvent pause2 = new ManualResetEvent(false);
            var        finish       = new TaskCompletionSource <bool>();
            Task <int> task1        = null;
            Task <int> task2        = null;
            Task       join         = null;
            Task       wrapper      = new Task(() =>
            {
                task1 = Task.Run(() =>
                {
                    this.output.WriteLine("Task-1 Started");
                    Assert.NotEqual(scheduler, TaskScheduler.Current);
                    Task.Delay(1);
                    Assert.NotEqual(scheduler, TaskScheduler.Current);
                    pause1.WaitOne();
                    this.output.WriteLine("Task-1 Done");
                    return(1);
                });
                task2 = Task.Run(() =>
                {
                    this.output.WriteLine("Task-2 Started");
                    Assert.NotEqual(scheduler, TaskScheduler.Current);
                    Task.Delay(1);
                    Assert.NotEqual(scheduler, TaskScheduler.Current);
                    pause2.WaitOne();
                    this.output.WriteLine("Task-2 Done");
                    return(2);
                });

                join = Task.WhenAll(task1, task2).ContinueWith(t =>
                {
                    this.output.WriteLine("Join Started");
                    if (t.IsFaulted)
                    {
                        throw t.Exception;
                    }
                    Assert.Equal(scheduler, TaskScheduler.Current);
                    this.output.WriteLine("Join Done");
                });

                finish.SetResult(true);
            });

            wrapper.Start(scheduler);

            var timeoutLimit = TimeSpan.FromSeconds(1);

            try
            {
                await finish.Task.WithTimeout(timeoutLimit);
            }
            catch (TimeoutException)
            {
                Assert.True(false, "Result did not arrive before timeout " + timeoutLimit);
            }

            pause1.Set();
            pause2.Set();
            Assert.NotNull(join); // Joined promise assigned
            await join;

            Assert.True(join.IsCompleted && !join.IsFaulted, "Join Status " + join);
            Assert.True(task1.IsCompleted && !task1.IsFaulted, "Task-1 Status " + task1);
            Assert.True(task2.IsCompleted && !task2.IsFaulted, "Task-2 Status " + task2);
        }
        public async Task ActivationSched_Turn_Execution_Order_Loop()
        {
            using var workItemGroup = SchedulingHelper.CreateWorkItemGroupForTesting(context, loggerFactory);
            TaskScheduler scheduler = workItemGroup.TaskScheduler;

            const int NumChains   = 100;
            const int ChainLength = 3;
            // Can we add a unit test that basicaly checks that any turn is indeed run till completion before any other turn?
            // For example, you have a long running main turn and in the middle it spawns a lot of short CWs (on Done promise) and StartNew.
            // You test that no CW/StartNew runs until the main turn is fully done. And run in stress.

            var resultHandles = new TaskCompletionSource <bool> [NumChains];

            Task[] taskChains      = new Task[NumChains];
            Task[] taskChainEnds   = new Task[NumChains];
            bool[] executingChain  = new bool[NumChains];
            int[]  stageComplete   = new int[NumChains];
            int    executingGlobal = -1;

            for (int i = 0; i < NumChains; i++)
            {
                int chainNum  = i; // Capture
                int sleepTime = ThreadSafeRandom.Next(100);
                resultHandles[i] = new TaskCompletionSource <bool>();
                taskChains[i]    = new Task(() =>
                {
                    const int taskNum = 0;
                    try
                    {
                        Assert.Equal(-1, executingGlobal);  // "Detected unexpected other execution in chain " + chainNum + " Task " + taskNum
                        Assert.False(executingChain[chainNum], "Detected unexpected other execution on chain " + chainNum + " Task " + taskNum);

                        executingGlobal          = chainNum;
                        executingChain[chainNum] = true;

                        Thread.Sleep(sleepTime);
                    }
                    finally
                    {
                        stageComplete[chainNum]  = taskNum;
                        executingChain[chainNum] = false;
                        executingGlobal          = -1;
                    }
                });
                Task task = taskChains[i];
                for (int j = 1; j < ChainLength; j++)
                {
                    int taskNum = j; // Capture
                    task = task.ContinueWith(t =>
                    {
                        if (t.IsFaulted)
                        {
                            throw t.Exception;
                        }
                        this.output.WriteLine("Inside Chain {0} Task {1}", chainNum, taskNum);
                        try
                        {
                            Assert.Equal(-1, executingGlobal);                  // "Detected unexpected other execution in chain " + chainNum + " Task " + taskNum
                            Assert.False(executingChain[chainNum], "Detected unexpected other execution on chain " + chainNum + " Task " + taskNum);
                            Assert.Equal(taskNum - 1, stageComplete[chainNum]); // "Detected unexpected execution stage on chain " + chainNum + " Task " + taskNum

                            executingGlobal          = chainNum;
                            executingChain[chainNum] = true;

                            Thread.Sleep(sleepTime);
                        }
                        finally
                        {
                            stageComplete[chainNum]  = taskNum;
                            executingChain[chainNum] = false;
                            executingGlobal          = -1;
                        }
                    }, scheduler);
                }
                taskChainEnds[chainNum] = task.ContinueWith(t =>
                {
                    if (t.IsFaulted)
                    {
                        throw t.Exception;
                    }
                    this.output.WriteLine("Inside Chain {0} Final Task", chainNum);
                    resultHandles[chainNum].SetResult(true);
                }, scheduler);
            }

            for (int i = 0; i < NumChains; i++)
            {
                taskChains[i].Start(scheduler);
            }

            for (int i = 0; i < NumChains; i++)
            {
                TimeSpan waitCheckTime = TimeSpan.FromMilliseconds(150 * ChainLength * NumChains * WaitFactor);

                try
                {
                    await resultHandles[i].Task.WithTimeout(waitCheckTime);
                }
                catch (TimeoutException)
                {
                    Assert.True(false, "Result did not arrive before timeout " + waitCheckTime);
                }

                bool ok = resultHandles[i].Task.Result;

                try
                {
                    // since resultHandle being complete doesn't directly imply that the final chain was completed (there's a chance for a race condition), give a small chance for it to complete.
                    await taskChainEnds[i].WithTimeout(TimeSpan.FromMilliseconds(10));
                }
                catch (TimeoutException)
                {
                    Assert.True(false, $"Task chain end {i} should complete very shortly after after its resultHandle");
                }

                Assert.True(taskChainEnds[i].IsCompleted, "Task chain " + i + " should be completed");
                Assert.False(taskChainEnds[i].IsFaulted, "Task chain " + i + " should not be Faulted: " + taskChainEnds[i].Exception);
                Assert.Equal(ChainLength - 1, stageComplete[i]);  // "Task chain " + i + " should have completed all stages"
                Assert.True(ok, "Successfully waited for ResultHandle for Task chain " + i);
            }
        }
    /// <summary>
    /// Saves configuration changes.
    /// </summary>
    protected void SaveData()
    {
        // Check "configure" permission
        if (!MembershipContext.AuthenticatedUser.IsAuthorizedPerResource("cms.newsletter", "configure"))
        {
            RedirectToAccessDenied("cms.newsletter", "configure");
        }

        string scheduledInterval = null;

        if (isDynamic && chkSchedule.Checked)
        {
            // Get scheduled interval for dynamic newsletter
            scheduledInterval = schedulerInterval.ScheduleInterval;
        }

        string errorMessage = ValidateNewsletterValues();

        if (!string.IsNullOrEmpty(errorMessage))
        {
            ShowError(errorMessage);
            return;
        }

        NewsletterInfo newsletterObj = NewsletterInfoProvider.GetNewsletterInfo(txtNewsletterName.Text.Trim(), SiteContext.CurrentSiteID);

        // Newsletter's code name must be unique
        if (newsletterObj != null && newsletterObj.NewsletterID != EditedNewsletter.NewsletterID)
        {
            ShowError(GetString("Newsletter_Edit.NewsletterNameExists"));
            return;
        }

        if (newsletterObj == null)
        {
            newsletterObj = NewsletterInfoProvider.GetNewsletterInfo(EditedNewsletter.NewsletterID);
        }

        SetNewsletterValues(newsletterObj);

        // Check if subscription template was selected
        int subscriptionTemplateValue = ValidationHelper.GetInteger(subscriptionTemplate.Value, 0);

        if (EditedFeedIsNewsletter() && subscriptionTemplateValue == 0)
        {
            ShowError(GetString("Newsletter_Edit.NoSubscriptionTemplateSelected"));
            return;
        }
        newsletterObj.NewsletterSubscriptionTemplateID = subscriptionTemplateValue;

        // Check if double opt-in template was selected
        if (chkEnableOptIn.Checked)
        {
            int optInTemplateValue = ValidationHelper.GetInteger(optInSelector.Value, 0);
            if (optInTemplateValue == 0)
            {
                ShowError(GetString("Newsletter_Edit.NoOptInTemplateSelected"));
                return;
            }
            newsletterObj.NewsletterOptInTemplateID = optInTemplateValue;
        }
        else
        {
            newsletterObj.NewsletterOptInTemplateID = 0;
        }

        // Check if unsubscription template was selected
        int unsubscriptionTemplateValue = ValidationHelper.GetInteger(unsubscriptionTemplate.Value, 0);

        if (unsubscriptionTemplateValue == 0)
        {
            ShowError(GetString("Newsletter_Edit.NoUnsubscriptionTemplateSelected"));
            return;
        }
        newsletterObj.NewsletterUnsubscriptionTemplateID = unsubscriptionTemplateValue;

        // ID of scheduled task which should be deleted
        int deleteScheduledTaskId = 0;

        if (isDynamic)
        {
            newsletterObj.NewsletterSource         = NewsletterSource.Dynamic;
            newsletterObj.NewsletterDynamicURL     = txtNewsletterDynamicURL.Value.ToString();
            newsletterObj.NewsletterDynamicSubject = radFollowing.Checked ? txtSubject.Text : string.Empty;

            if ((String.IsNullOrEmpty(txtNewsletterDynamicURL.Value.ToString())))
            {
                // Dynamic URL cannot be empty
                ShowError(GetString("newsletter_edit.sourcepageurlempty"));
                return;
            }

            if (chkSchedule.Checked)
            {
                if (!schedulerInterval.CheckOneDayMinimum())
                {
                    // If problem occurred while setting schedule interval
                    ShowError(GetString("Newsletter_Edit.NoDaySelected"));
                    return;
                }

                TaskInterval taskInterval = SchedulingHelper.DecodeInterval(scheduledInterval);
                if (!DataTypeManager.IsValidDate(taskInterval.StartTime))
                {
                    ShowError(GetString("Newsletter.IncorrectDate"));
                    return;
                }

                UpdateDynamicNewsletterTask(newsletterObj, taskInterval);
            }
            else
            {
                if (newsletterObj.NewsletterDynamicScheduledTaskID > 0)
                {
                    // Store task ID for deletion
                    deleteScheduledTaskId = newsletterObj.NewsletterDynamicScheduledTaskID;
                }
                newsletterObj.NewsletterDynamicScheduledTaskID = 0;
                schedulerInterval.Visible = false;
            }
        }
        else
        {
            newsletterObj.NewsletterSource = NewsletterSource.TemplateBased;

            // Check if at least one template is selected
            if (string.IsNullOrEmpty(ValidationHelper.GetString(usTemplates.Value, null)))
            {
                ShowError(GetString("Newsletter_Edit.NoEmailTemplateSelected"));
                usTemplates.Value = mCurrentTemplates;
                return;
            }
            SaveTemplates();
        }

        // Save changes to DB
        NewsletterInfoProvider.SetNewsletterInfo(newsletterObj);
        if (deleteScheduledTaskId > 0)
        {
            // Delete scheduled task if schedule mail-outs were unchecked
            TaskInfoProvider.DeleteTaskInfo(deleteScheduledTaskId);
        }

        ShowChangesSaved();

        // Update breadcrumbs
        ScriptHelper.RefreshTabHeader(Page, newsletterObj.NewsletterDisplayName);
    }
        public async Task ActivationSched_WhenAny_Busy_Timeout()
        {
            using var workItemGroup = SchedulingHelper.CreateWorkItemGroupForTesting(context, loggerFactory);
            TaskScheduler scheduler = workItemGroup.TaskScheduler;

            var        pause1  = new TaskCompletionSource <bool>();
            var        pause2  = new TaskCompletionSource <bool>();
            var        finish  = new TaskCompletionSource <bool>();
            Task <int> task1   = null;
            Task <int> task2   = null;
            Task       join    = null;
            Task       wrapper = new Task(() =>
            {
                task1 = Task <int> .Factory.StartNew(() =>
                {
                    this.output.WriteLine("Task-1 Started");
                    Assert.Equal(scheduler, TaskScheduler.Current);
                    int num1 = 1;
                    while (!pause1.Task.Result) // Infinite busy loop
                    {
                        num1 = ThreadSafeRandom.Next();
                    }
                    this.output.WriteLine("Task-1 Done");
                    return(num1);
                });
                task2 = Task <int> .Factory.StartNew(() =>
                {
                    this.output.WriteLine("Task-2 Started");
                    Assert.Equal(scheduler, TaskScheduler.Current);
                    int num2 = 2;
                    while (!pause2.Task.Result) // Infinite busy loop
                    {
                        num2 = ThreadSafeRandom.Next();
                    }
                    this.output.WriteLine("Task-2 Done");
                    return(num2);
                });

                join = Task.WhenAny(task1, task2, Task.Delay(TimeSpan.FromSeconds(2)));

                finish.SetResult(true);
            });

            wrapper.Start(scheduler);

            var timeoutLimit = TimeSpan.FromSeconds(1);

            try
            {
                await finish.Task.WithTimeout(timeoutLimit);
            }
            catch (TimeoutException)
            {
                Assert.True(false, "Result did not arrive before timeout " + timeoutLimit);
            }

            Assert.NotNull(join); // Joined promise assigned
            await join;

            Assert.True(join.IsCompleted && !join.IsFaulted, "Join Status " + join.Status);
            Assert.False(task1.IsFaulted, "Task-1 Faulted " + task1.Exception);
            Assert.False(task1.IsCompleted, "Task-1 Status " + task1.Status);
            Assert.False(task2.IsFaulted, "Task-2 Faulted " + task2.Exception);
            Assert.False(task2.IsCompleted, "Task-2 Status " + task2.Status);
        }
Exemple #10
0
    /// <summary>
    /// OnAfterSave event handler.
    /// </summary>
    protected void EditForm_OnAfterSave(object sender, EventArgs e)
    {
        // Get edited contact group
        ContactGroupInfo cgi = (ContactGroupInfo)EditForm.EditedObject;

        if (chkDynamic.Checked)
        {
            // Set info for scheduled task
            task = GetScheduledTask(cgi);

            // Update scheduled task
            if (chkSchedule.Checked)
            {
                if (!schedulerInterval.CheckOneDayMinimum())
                {
                    // If problem occurred while setting schedule interval
                    EditForm.ErrorLabel.Text    = GetString("Newsletter_Edit.NoDaySelected");
                    EditForm.ErrorLabel.Visible = true;
                    EditForm.StopProcessing     = true;
                    return;
                }

                if (!IsValidDate(SchedulingHelper.DecodeInterval(scheduleInterval).StartTime))
                {
                    // Start date is not in valid format
                    EditForm.ErrorLabel.Text    = GetString("Newsletter.IncorrectDate");
                    EditForm.ErrorLabel.Visible = true;
                    EditForm.StopProcessing     = true;
                    return;
                }

                task.TaskInterval    = scheduleInterval;
                task.TaskNextRunTime = SchedulingHelper.GetNextTime(task.TaskInterval, new DateTime(), new DateTime());
                task.TaskEnabled     = true;
            }
            else
            {
                task.TaskInterval    = scheduleInterval;
                task.TaskNextRunTime = TaskInfoProvider.NO_TIME;
                task.TaskEnabled     = false;
            }
            TaskInfoProvider.SetTaskInfo(task);

            cgi.ContactGroupScheduledTaskID = task.TaskID;
            pnlInfo.Visible = true;
            InitInfoPanel(cgi, true);
        }
        else
        {
            if (cgi.ContactGroupScheduledTaskID > 0)
            {
                // Store task ID for deletion
                deleteScheduledTaskId = cgi.ContactGroupScheduledTaskID;
            }
            cgi.ContactGroupScheduledTaskID = 0;
            cgi.ContactGroupStatus          = ContactGroupStatusEnum.Unspecified;
            schedulerInterval.Visible       = false;
            pnlInfo.Visible = false;
        }

        // Update contact group
        ContactGroupInfoProvider.SetContactGroupInfo(cgi);

        if (deleteScheduledTaskId > 0)
        {
            // Delete scheduled task if schedule evaluation was unchecked
            TaskInfoProvider.DeleteTaskInfo(deleteScheduledTaskId);
        }

        InitHeaderActions(false);
        ((CMSPage)Page).CurrentMaster.HeaderActions.ReloadData();

        // Refresh breadcrumbs after data are loaded
        ScriptHelper.RefreshTabHeader(Page, null);
    }
        public void Sched_Task_SchedulingContext()
        {
            var context = new UnitTestSchedulingContext();

            using var workItemGroup = SchedulingHelper.CreateWorkItemGroupForTesting(context, loggerFactory);
            context.Scheduler       = workItemGroup;

            var  result     = new TaskCompletionSource <bool>();
            Task endOfChain = null;
            int  n          = 0;

            Task wrapper = new Task(() =>
            {
                CheckRuntimeContext(context);

                // ReSharper disable AccessToModifiedClosure
                Task task1 = Task.Factory.StartNew(() =>
                {
                    this.output.WriteLine("===> 1a ");
                    CheckRuntimeContext(context);
                    Thread.Sleep(1000);
                    n = n + 3;
                    this.output.WriteLine("===> 1b");
                    CheckRuntimeContext(context);
                });
                Task task2 = task1.ContinueWith(task =>
                {
                    this.output.WriteLine("===> 2");
                    CheckRuntimeContext(context);
                    n = n * 5;
                });
                Task task3 = task2.ContinueWith(task =>
                {
                    this.output.WriteLine("===> 3");
                    n = n / 5;
                    CheckRuntimeContext(context);
                });
                Task task4 = task3.ContinueWith(task =>
                {
                    this.output.WriteLine("===> 4");
                    n = n - 2;
                    result.SetResult(true);
                    CheckRuntimeContext(context);
                });
                // ReSharper restore AccessToModifiedClosure
                endOfChain = task4.ContinueWith(task =>
                {
                    this.output.WriteLine("Done Faulted={0}", task.IsFaulted);
                    CheckRuntimeContext(context);
                    Assert.False(task.IsFaulted, "Faulted with Exception=" + task.Exception);
                });
            });

            wrapper.Start(workItemGroup.TaskScheduler);
            bool ok = wrapper.Wait(TimeSpan.FromSeconds(1));

            if (!ok)
            {
                throw new TimeoutException();
            }

            Assert.False(wrapper.IsFaulted, "Wrapper Task Faulted with Exception=" + wrapper.Exception);
            Assert.True(wrapper.IsCompleted, "Wrapper Task completed");
            bool finished = result.Task.Wait(TimeSpan.FromSeconds(2));

            Assert.NotNull(endOfChain); // End of chain Task created successfully
            Assert.False(endOfChain.IsFaulted, "Task chain Faulted with Exception=" + endOfChain.Exception);
            Assert.True(finished, "Wrapper Task completed ok");
            Assert.True(n != 0, "Work items did not get executed");
            Assert.Equal(1, n);   // "Work items executed out of order"
        }
        public void Sched_AC_Current_TaskScheduler()
        {
            UnitTestSchedulingContext context = new UnitTestSchedulingContext();
            var workItemGroup = SchedulingHelper.CreateWorkItemGroupForTesting(context, loggerFactory);

            context.Scheduler = workItemGroup;
            ActivationTaskScheduler activationScheduler = workItemGroup.TaskScheduler;

            this.mainDone = false;

            var result = new TaskCompletionSource <bool>();

            Task wrapper      = null;
            Task finalPromise = null;

            context.Scheduler.QueueAction(() =>
            {
                Log(1, "Outer ClosureWorkItem " + Task.CurrentId + " starting");
                Assert.Equal(activationScheduler, TaskScheduler.Current);   // "TaskScheduler.Current #0"

                Log(2, "Starting wrapper Task");
                wrapper = Task.Factory.StartNew(() =>
                {
                    Log(3, "Inside wrapper Task Id=" + Task.CurrentId);
                    Assert.Equal(activationScheduler, TaskScheduler.Current);   // "TaskScheduler.Current #1"

                    Log(4, "Wrapper Task " + Task.CurrentId + " creating AC chain");
                    Task promise1 = Task.Factory.StartNew(() =>
                    {
                        Log(5, "#1 Inside AC Task Id=" + Task.CurrentId);
                        Assert.Equal(activationScheduler, TaskScheduler.Current);   // "TaskScheduler.Current #1"
                        SubProcess1(1);
                    });
                    Task promise2 = promise1.ContinueWith((_) =>
                    {
                        Log(6, "#2 Inside AC Task Id=" + Task.CurrentId);
                        Assert.Equal(activationScheduler, TaskScheduler.Current);   // "TaskScheduler.Current #2"
                        SubProcess1(2);
                    });
                    finalPromise = promise2.ContinueWith((_) =>
                    {
                        Log(7, "#3 Inside final AC Task Id=" + Task.CurrentId);
                        Assert.Equal(activationScheduler, TaskScheduler.Current);   // "TaskScheduler.Current #3"
                        SubProcess1(3);
                        result.SetResult(true);
                    });
                    finalPromise.Ignore();

                    Log(8, "Wrapper Task Id=" + Task.CurrentId + " sleeping");
                    Thread.Sleep(TimeSpan.FromSeconds(1));

                    Log(9, "Wrapper Task Id=" + Task.CurrentId + " finished");
                });

                Log(10, "Outer ClosureWorkItem Task Id=" + Task.CurrentId + " sleeping");
                Thread.Sleep(TimeSpan.FromSeconds(1));
                Log(11, "Outer ClosureWorkItem Task Id=" + Task.CurrentId + " awake");

                Log(12, "Finished Outer TaskWorkItem Task Id=" + wrapper.Id);
                this.mainDone = true;
            });

            Log(13, "Waiting for ClosureWorkItem to spawn wrapper Task");
            for (int i = 0; i < 5 * WaitFactor; i++)
            {
                if (wrapper != null)
                {
                    break;
                }
                Thread.Sleep(TimeSpan.FromSeconds(1).Multiply(WaitFactor));
            }
            Assert.NotNull(wrapper); // Wrapper Task was not created

            Log(14, "Waiting for wrapper Task Id=" + wrapper.Id + " to complete");
            bool finished = wrapper.Wait(TimeSpan.FromSeconds(4 * WaitFactor));

            Log(15, "Done waiting for wrapper Task Id=" + wrapper.Id + " Finished=" + finished);
            if (!finished)
            {
                throw new TimeoutException();
            }
            Assert.False(wrapper.IsFaulted, "Wrapper Task faulted: " + wrapper.Exception);
            Assert.True(wrapper.IsCompleted, "Wrapper Task should be completed");

            Log(16, "Waiting for TaskWorkItem to complete");
            for (int i = 0; i < 15 * WaitFactor; i++)
            {
                if (this.mainDone)
                {
                    break;
                }
                Thread.Sleep(1000 * WaitFactor);
            }
            Log(17, "Done waiting for TaskWorkItem to complete MainDone=" + this.mainDone);
            Assert.True(this.mainDone, "Main Task should be completed");
            Assert.NotNull(finalPromise); // AC chain not created

            Log(18, "Waiting for final AC promise to complete");
            finalPromise.Wait(TimeSpan.FromSeconds(4 * WaitFactor));
            Log(19, "Done waiting for final promise");
            Assert.False(finalPromise.IsFaulted, "Final AC faulted: " + finalPromise.Exception);
            Assert.True(finalPromise.IsCompleted, "Final AC completed");
            Assert.True(result.Task.Result, "Timeout-1");

            Assert.NotEqual(0, this.stageNum1); // "Work items did not get executed-1"
            Assert.Equal(3, this.stageNum1);    // "Work items executed out of order-1"
        }
        public void Sched_Task_Turn_Execution_Order()
        {
            // A unit test that checks that any turn is indeed run till completion before any other turn?
            // For example, you have a long running main turn and in the middle it spawns a lot of short CWs (on Done promise) and StartNew.
            // You test that no CW/StartNew runs until the main turn is fully done. And run in stress.

            UnitTestSchedulingContext context       = new UnitTestSchedulingContext();
            WorkItemGroup             workItemGroup = SchedulingHelper.CreateWorkItemGroupForTesting(context, this.loggerFactory);

            context.Scheduler = workItemGroup;
            ActivationTaskScheduler activationScheduler = workItemGroup.TaskScheduler;

            this.mainDone  = false;
            this.stageNum1 = this.stageNum2 = 0;

            var result1 = new TaskCompletionSource <bool>();
            var result2 = new TaskCompletionSource <bool>();

            Task wrapper       = null;
            Task finalTask1    = null;
            Task finalPromise2 = null;

            context.Scheduler.QueueAction(() =>
            {
                Log(1, "Outer ClosureWorkItem " + Task.CurrentId + " starting");
                Assert.Equal(activationScheduler, TaskScheduler.Current);   // "TaskScheduler.Current #0"

                Log(2, "Starting wrapper Task");
                wrapper = Task.Factory.StartNew(() =>
                {
                    Log(3, "Inside wrapper Task Id=" + Task.CurrentId);
                    Assert.Equal(activationScheduler, TaskScheduler.Current);   // "TaskScheduler.Current #1"

                    // Execution chain #1
                    Log(4, "Wrapper Task Id=" + Task.CurrentId + " creating Task chain");
                    Task task1 = Task.Factory.StartNew(() =>
                    {
                        Log(5, "#11 Inside sub-Task Id=" + Task.CurrentId);
                        Assert.Equal(activationScheduler, TaskScheduler.Current);   // "TaskScheduler.Current #11"
                        SubProcess1(11);
                    });
                    Task task2 = task1.ContinueWith((Task task) =>
                    {
                        Log(6, "#12 Inside continuation Task Id=" + Task.CurrentId);
                        Assert.Equal(activationScheduler, TaskScheduler.Current);   // "TaskScheduler.Current #12"
                        if (task.IsFaulted)
                        {
                            throw task.Exception.Flatten();
                        }
                        SubProcess1(12);
                    });
                    Task task3 = task2.ContinueWith(task =>
                    {
                        Log(7, "#13 Inside continuation Task Id=" + Task.CurrentId);
                        Assert.Equal(activationScheduler, TaskScheduler.Current);   // "TaskScheduler.Current #13"
                        if (task.IsFaulted)
                        {
                            throw task.Exception.Flatten();
                        }
                        SubProcess1(13);
                    });
                    finalTask1 = task3.ContinueWith(task =>
                    {
                        Log(8, "#14 Inside final continuation Task Id=" + Task.CurrentId);
                        Assert.Equal(activationScheduler, TaskScheduler.Current);   // "TaskScheduler.Current #14"
                        if (task.IsFaulted)
                        {
                            throw task.Exception.Flatten();
                        }
                        SubProcess1(14);
                        result1.SetResult(true);
                    });

                    // Execution chain #2
                    Log(9, "Wrapper Task " + Task.CurrentId + " creating AC chain");
                    Task promise2 = Task.Factory.StartNew(() =>
                    {
                        Log(10, "#21 Inside sub-Task Id=" + Task.CurrentId);
                        Assert.Equal(activationScheduler, TaskScheduler.Current);   // "TaskScheduler.Current #21"
                        SubProcess2(21);
                    });
                    finalPromise2 = promise2.ContinueWith((_) =>
                    {
                        Log(11, "#22 Inside final continuation Task Id=" + Task.CurrentId);
                        Assert.Equal(activationScheduler, TaskScheduler.Current);   // "TaskScheduler.Current #22"
                        SubProcess2(22);
                        result2.SetResult(true);
                    });
                    finalPromise2.Ignore();

                    Log(12, "Wrapper Task Id=" + Task.CurrentId + " sleeping #2");
                    Thread.Sleep(TimeSpan.FromSeconds(1));

                    Log(13, "Wrapper Task Id=" + Task.CurrentId + " finished");
                });

                Log(14, "Outer ClosureWorkItem Task Id=" + Task.CurrentId + " sleeping");
                Thread.Sleep(TimeSpan.FromSeconds(1));
                Log(15, "Outer ClosureWorkItem Task Id=" + Task.CurrentId + " awake");

                Log(16, "Finished Outer ClosureWorkItem Task Id=" + wrapper.Id);
                this.mainDone = true;
            });

            Log(17, "Waiting for ClosureWorkItem to spawn wrapper Task");
            for (int i = 0; i < 5 * WaitFactor; i++)
            {
                if (wrapper != null)
                {
                    break;
                }
                Thread.Sleep(TimeSpan.FromSeconds(1).Multiply(WaitFactor));
            }
            Assert.NotNull(wrapper); // Wrapper Task was not created

            Log(18, "Waiting for wrapper Task Id=" + wrapper.Id + " to complete");
            bool finished = wrapper.Wait(TimeSpan.FromSeconds(4 * WaitFactor));

            Log(19, "Done waiting for wrapper Task Id=" + wrapper.Id + " Finished=" + finished);
            if (!finished)
            {
                throw new TimeoutException();
            }
            Assert.False(wrapper.IsFaulted, "Wrapper Task faulted: " + wrapper.Exception);
            Assert.True(wrapper.IsCompleted, "Wrapper Task should be completed");

            Log(20, "Waiting for TaskWorkItem to complete");
            for (int i = 0; i < 15 * WaitFactor; i++)
            {
                if (this.mainDone)
                {
                    break;
                }
                Thread.Sleep(1000 * WaitFactor);
            }
            Log(21, "Done waiting for TaskWorkItem to complete MainDone=" + this.mainDone);
            Assert.True(this.mainDone, "Main Task should be completed");
            Assert.NotNull(finalTask1);    // Task chain #1 not created
            Assert.NotNull(finalPromise2); // Task chain #2 not created

            Log(22, "Waiting for final task #1 to complete");
            bool ok = finalTask1.Wait(TimeSpan.FromSeconds(4 * WaitFactor));

            Log(23, "Done waiting for final task #1 complete Ok=" + ok);
            if (!ok)
            {
                throw new TimeoutException();
            }
            Assert.False(finalTask1.IsFaulted, "Final Task faulted: " + finalTask1.Exception);
            Assert.True(finalTask1.IsCompleted, "Final Task completed");
            Assert.True(result1.Task.Result, "Timeout-1");

            Log(24, "Waiting for final promise #2 to complete");
            finalPromise2.Wait(TimeSpan.FromSeconds(4 * WaitFactor));
            Log(25, "Done waiting for final promise #2");
            Assert.False(finalPromise2.IsFaulted, "Final Task faulted: " + finalPromise2.Exception);
            Assert.True(finalPromise2.IsCompleted, "Final Task completed");
            Assert.True(result2.Task.Result, "Timeout-2");

            Assert.NotEqual(0, this.stageNum1); // "Work items did not get executed-1"
            Assert.Equal(14, this.stageNum1);   // "Work items executed out of order-1"
            Assert.NotEqual(0, this.stageNum2); // "Work items did not get executed-2"
            Assert.Equal(22, this.stageNum2);   // "Work items executed out of order-2"
        }
Exemple #14
0
    /// <summary>
    /// Handles the UniGrid's OnAction event.
    /// </summary>
    /// <param name="actionName">Name of item (button) that threw event</param>
    /// <param name="actionArgument">ID (value of Primary key) of corresponding data row</param>
    protected void gridElem_OnAction(string actionName, object actionArgument)
    {
        switch (actionName.ToLowerInvariant())
        {
        case "edit":
            if (!String.IsNullOrEmpty(EditURL))
            {
                URLHelper.Redirect(UrlResolver.ResolveUrl(String.Format(EditURL, actionArgument)));
            }
            break;

        case "delete":
        {
            // Check "modify" permission
            if (!MembershipContext.AuthenticatedUser.IsAuthorizedPerResource("CMS.ScheduledTasks", "Modify"))
            {
                RedirectToAccessDenied("CMS.ScheduledTasks", "Modify");
            }

            // Delete the task
            try
            {
                int taskId = Convert.ToInt32(actionArgument);

                TaskInfo task = TaskInfo.Provider.Get(taskId);
                if (task != null)
                {
                    task.Generalized.LogSynchronization = SynchronizationTypeEnum.LogSynchronization;
                    task.Generalized.LogIntegration     = true;
                    task.Generalized.LogEvents          = true;
                    TaskInfo.Provider.Delete(task);

                    if (task.TaskType == ScheduledTaskTypeEnum.System)
                    {
                        Service.Resolve <IEventLogService>().LogWarning("ScheduledTasks", "DELETE", $"System scheduled task '{task.TaskName}' has been deleted.");
                    }
                }
            }
            catch (Exception ex)
            {
                ShowError(GetString("Task_List.DeleteError"), ex.Message);
            }
        }
        break;

        case "execute":
        {
            // Check "modify" permission
            if (!MembershipContext.AuthenticatedUser.IsAuthorizedPerResource("CMS.ScheduledTasks", "Modify"))
            {
                RedirectToAccessDenied("CMS.ScheduledTasks", "Modify");
            }

            TaskInfo taskInfo = TaskInfo.Provider.Get(Convert.ToInt32(actionArgument));
            if (taskInfo != null)
            {
                if (taskInfo.TaskIsRunning)
                {
                    ShowWarning(GetString("ScheduledTask.TaskAlreadyrunning"));
                    return;
                }

                var site   = SiteInfo.Provider.Get(SiteID);
                var siteId = site?.SiteID ?? SiteContext.CurrentSiteID;
                var url    = SchedulingUrlFactory.GetSchedulerUrl(siteId, taskInfo.TaskAvailability, taskInfo.TaskID);

                SchedulingHelper.RunSchedulerRequest(url);

                ShowConfirmation(GetString("ScheduledTask.WasExecuted"));
            }
        }
        break;
        }
    }