private void SpawnOrTurnOffRecurrance() { if (IsMessage(PluginMessage.Create, PluginMessage.Update) && IsStage(PluginStage.PostEvent) && IsMode(PluginMode.Synchronous)) { if (GetOptionSet(Fields.jmcg_workflowtask_.jmcg_workflowexecutiontype) != OptionSets.WorkflowTask.WorkflowExecutionType.MonitorOnly) { if (BooleanChangingToTrue(Fields.jmcg_workflowtask_.jmcg_on)) { if (!GetDateTimeField(Fields.jmcg_workflowtask_.jmcg_nextexecutiontime).HasValue) { SetField(Fields.jmcg_workflowtask_.jmcg_nextexecutiontime, DateTime.UtcNow); } var workflows = WorkflowSchedulerService.GetRecurringInstances(TargetId); if (!workflows.Any()) { WorkflowSchedulerService.StartNewContinuousWorkflowFor(TargetId); } } if (BooleanChangingToFalse(Fields.jmcg_workflowtask_.jmcg_on)) { WorkflowSchedulerService.StopContinuousWorkflowFor(TargetId); } } } }
public void WorkflowTaskMonitorScheduleTest() { DeleteAll(Entities.account); var workflowName = "Test Account Target Schedule Failure"; DeleteWorkflowTasks(workflowName); var account = CreateAccount(); var scheduleFailWorkflow = GetWorkflow(workflowName); var initialThreshold = DateTime.UtcNow.AddDays(-3); var workflowTask = InitialiseValidWorkflowTask(); workflowTask.SetLookupField(Fields.jmcg_workflowtask_.jmcg_targetworkflow, scheduleFailWorkflow); workflowTask.SetField(Fields.jmcg_workflowtask_.jmcg_nextexecutiontime, DateTime.UtcNow.AddDays(1)); workflowTask.SetField(Fields.jmcg_workflowtask_.jmcg_name, workflowName); workflowTask.SetField(Fields.jmcg_workflowtask_.jmcg_sendnotificationfortargetfailures, true); workflowTask.SetField(Fields.jmcg_workflowtask_.jmcg_sendnotificationforschedulefailures, true); workflowTask.SetLookupField(Fields.jmcg_workflowtask_.jmcg_sendfailurenotificationsfrom, TestQueue); workflowTask.SetLookupField(Fields.jmcg_workflowtask_.jmcg_sendfailurenotificationsto, TestQueue); workflowTask.SetField(Fields.jmcg_workflowtask_.jmcg_minimumschedulefailuredatetime, initialThreshold); workflowTask = CreateAndRetrieve(workflowTask); //wait until the monitor completed its first check - will respawn another the check it Thread.Sleep(10000); workflowTask.SetField(Fields.jmcg_workflowtask_.jmcg_nextexecutiontime, DateTime.UtcNow.AddDays(-2)); workflowTask = UpdateFieldsAndRetreive(workflowTask, Fields.jmcg_workflowtask_.jmcg_nextexecutiontime); WaitTillTrue(() => WorkflowSchedulerService.GetRecurringInstancesFailed(workflowTask.Id).Any(), 60); WorkflowSchedulerService.StartNewMonitorWorkflowFor(workflowTask.Id); WaitTillTrue(() => GetRegardingEmails(workflowTask).Count() == 1, 60); WaitTillTrue(() => initialThreshold < Refresh(workflowTask).GetDateTimeField(Fields.jmcg_workflowtask_.jmcg_minimumschedulefailuredatetime), 60); workflowTask = Refresh(workflowTask); Thread.Sleep(1000); workflowTask.SetField(Fields.jmcg_workflowtask_.jmcg_nextexecutiontime, DateTime.UtcNow.AddDays(-1)); workflowTask.SetField(Fields.jmcg_workflowtask_.jmcg_minimumschedulefailuredatetime, DateTime.UtcNow.AddDays(-2)); workflowTask = UpdateFieldsAndRetreive(workflowTask, Fields.jmcg_workflowtask_.jmcg_nextexecutiontime, Fields.jmcg_workflowtask_.jmcg_minimumschedulefailuredatetime); WorkflowSchedulerService.StartNewContinuousWorkflowFor(workflowTask.Id); WaitTillTrue(() => WorkflowSchedulerService.GetRecurringInstancesFailed(workflowTask.Id).Count() > 1, 60); WorkflowSchedulerService.StartNewMonitorWorkflowFor(workflowTask.Id); WaitTillTrue(() => GetRegardingEmails(workflowTask).Count() == 2, 60); WorkflowSchedulerService.StartNewMonitorWorkflowFor(workflowTask.Id); Thread.Sleep(60000); Assert.AreEqual(2, GetRegardingEmails(workflowTask).Count()); XrmService.Delete(workflowTask); XrmService.Delete(account); }
protected override void Execute() { var behindSchedule = IsBehindSchedule(); ActivityThisType.IsBehindSchedule.Set(ExecutionContext, behindSchedule); if (behindSchedule) { //if there is recurring instance, but we are behind schedule //then probably went into an error waiting state //so lets stop it try { WorkflowSchedulerService.StopContinuousWorkflowFor(TargetId); } catch (Exception ex) { Trace(string.Format("Error stopping continuous workflows: {0}", ex.XrmDisplayString())); } //and start a fresh continuous one try { WorkflowSchedulerService.StartNewContinuousWorkflowFor(TargetId); } catch (Exception ex) { Trace(string.Format("Error starting continuous workflow: {0}", ex.XrmDisplayString())); } } if (behindSchedule && Target.GetBoolean(Fields.jmcg_workflowtask_.jmcg_sendnotificationforschedulefailures)) { var recipientQueue = Target.GetLookupGuid(Fields.jmcg_workflowtask_.jmcg_sendfailurenotificationsto); if (!recipientQueue.HasValue) { throw new NullReferenceException(string.Format("Error required field {0} is empty on the target {1}", XrmService.GetFieldLabel(Fields.jmcg_workflowtask_.jmcg_sendfailurenotificationsto, TargetType), XrmService.GetEntityLabel(TargetType))); } var crmUrl = GetCrmURL(); var email = new HtmlEmailGenerator(XrmService, crmUrl, null); email.AppendParagraph(string.Format("This is an automated notification that the {0} named '{1}' fell behind schedule. The system has attempted to restart the continuous workflow but any failed instance should be reviewed" , XrmService.GetEntityLabel(TargetType) , Target.GetStringField(Fields.jmcg_workflowtask_.jmcg_name))); if (!string.IsNullOrWhiteSpace(crmUrl)) { email.AppendParagraph(email.CreateHyperlink(email.CreateUrl(Target), "Open " + XrmService.GetEntityLabel(TargetType))); } var subject = XrmService.GetEntityLabel(TargetType) + " Schedule Failure: " + Target.GetStringField(Fields.jmcg_workflowtask_.jmcg_name); SendNotificationEmail(Entities.queue, recipientQueue.Value, subject, email.GetContent()); Target.SetField(Fields.jmcg_workflowtask_.jmcg_minimumschedulefailuredatetime, DateTime.UtcNow); XrmService.Update(Target, new[] { Fields.jmcg_workflowtask_.jmcg_minimumschedulefailuredatetime }); } }
private void DoIt() { WorkflowSchedulerService.StartNewContinuousWorkflowFor(TargetId); }