Example #1
0
        protected List <CustomJobFailedTarget> DeleteSuccessfulFailed(ExecutionFailures failures = null)
        {
            var failedTargets = failures?.Exceptions
                                .Select(failure =>
                                        new CustomJobFailedTarget
            {
                ID = failure.Key.ToString()
            }).ToList();
            var retryTargets           = GetRetryTargets();
            var successfulRetryTargets =
                failedTargets == null
                                        ? retryTargets
                                        : retryTargets.Except(failedTargets, new CustomFailedJobComparer()).ToList();

            foreach (var successfulTarget in successfulRetryTargets)
            {
                log.Log($"Deleting successful target record '{successfulTarget.ID}' ...", LogLevel.Debug);
                Service.Delete(CustomJobFailedTarget.EntityLogicalName, successfulTarget.Id);
                log.Log($"Deleted successful target record '{successfulTarget.ID}'.");
            }

            var remainingFailures = failedTargets?.Except(successfulRetryTargets).ToList();

            if (remainingFailures == null)
            {
                return(null);
            }

            // set the ID for the remaining failed targets' records
            // it was built on the fly without retrieve from CRM, so the IDs are empty
            foreach (var failure in remainingFailures)
            {
                var id = retryTargets.FirstOrDefault(retry => retry.ID == failure.ID)?.Id;

                if (id == null)
                {
                    continue;
                }

                failure.Id = id.Value;
            }

            return(remainingFailures);
        }
Example #2
0
        protected List <CustomJobFailedTarget> AssociateFailedTargets(ExecutionFailures failures, Guid jobId)
        {
            var failedTargets = failures.Exceptions
                                .Select(failure =>
                                        new CustomJobFailedTarget
            {
                ID             = jobId == failure.Key ? "No Target" : failure.Key.ToString(),
                CustomJob      = jobId,
                FailureMessage = BuildNoTraceExceptionMessage(failure.Value),
            });
            var retryTargets     = GetRetryTargets();
            var newFailedTargets = failedTargets.Except(retryTargets, new CustomFailedJobComparer()).ToList();

            foreach (var failedTarget in newFailedTargets)
            {
                log.Log($"Creating failed target record for '{failedTarget.ID}' ...", LogLevel.Debug);
                failedTarget.CustomJob = jobId;
                Service.Create(failedTarget);
                log.Log($"Created failed target record for '{failedTarget.ID}'.");
            }

            return(newFailedTargets);
        }
        protected ExecutionFailures Execute(JobPagingInfo pagingInfo)
        {
            var result = new ExecutionFailures();

            var  contextService = GetServiceInContext();
            var  targets        = pagingInfo.Targets;
            Guid workflowId;

            if (Guid.TryParse(Job.ActionName, out workflowId) ||
                ((workflowId = Job.Workflow.GetValueOrDefault()) != Guid.Empty))
            {
                log.Log($"Running workflow '{workflowId}' ...", LogLevel.Debug);

                if (targets?.Any() == true)
                {
                    foreach (var target in targets)
                    {
                        try
                        {
                            log.Log($"Running workflow on '{target}'.");
                            contextService.Execute(
                                new ExecuteWorkflowRequest
                            {
                                EntityId   = target,
                                WorkflowId = workflowId
                            });
                        }
                        catch (Exception ex)
                        {
                            log.Log($"Failed at '{target}':'{ex.Message}'.");
                            result.Exceptions[target] = ex;

                            if (Job.ContinueOnError == false)
                            {
                                break;
                            }
                        }
                    }
                }
                else
                {
                    log.Log("No targets to run workflow on.");
                }

                log.Log($"Finished running workflow '{workflowId}'.");
            }
            else
            {
                var action = new OrganizationRequest(Job.ActionName);

                if (!string.IsNullOrEmpty(Job.SerialisedInputParams))
                {
                    log.Log($"Inputs: '{Job.SerialisedInputParams}'.");
                    action.Parameters.AddRange(GetInputs());
                }

                log.Log($"Executing action '{Job.ActionName}' ...", LogLevel.Debug);

                if (targets?.Any() == true)
                {
                    foreach (var target in targets)
                    {
                        try
                        {
                            log.Log($"Executing action on '{target}' ...", LogLevel.Debug);
                            action["Target"] = new EntityReference(Job.TargetLogicalName, target);
                            contextService.Execute(action);
                        }
                        catch (Exception ex)
                        {
                            log.Log($"Failed at '{target}':'{ex.Message}'.");
                            result.Exceptions[target] = ex;

                            if (Job.ContinueOnError == false)
                            {
                                break;
                            }
                        }
                    }
                }
                else if (string.IsNullOrEmpty(Job.TargetLogicalName))
                {
                    try
                    {
                        log.Log($"Executing global action ...", LogLevel.Debug);
                        contextService.Execute(action);
                    }
                    catch (Exception ex)
                    {
                        log.Log($"Failed: '{ex.Message}'.");
                        result.Exceptions[Job.Id] = ex;
                    }
                }

                log.Log($"Executed action '{Job.ActionName}'.");
            }

            return(result);
        }
        protected virtual JobRunStatus ProcessFailure(ExecutionFailures executionResult)
        {
            var status = new JobRunStatus();

            if (IsNoRetry())
            {
                if (IsSubJob())
                {
                    var parentId = Job.ParentJob.Value;

                    if (IsWaitingOnSubJobs(Service, parentId))
                    {
                        if (Job.IgnoreFailure == true)
                        {
                            log.Log($"Setting status of parent '{parentId}' to 'waiting' ...", LogLevel.Debug);
                            SetStatus(Service, CustomJob.StatusReasonEnum.Waiting, parentId, IsParentRecurrentJob());
                            log.Log($"Set status of parent '{parentId}' to 'waiting'.");
                        }
                        else
                        {
                            log.Log($"Setting status of parent '{parentId}' to 'failed' ...", LogLevel.Debug);
                            Close(Service, CustomJob.StatusReasonEnum.Failure, parentId, true);
                            log.Log($"Set status of parent '{parentId}' to 'failed'.");
                        }
                    }

                    status.ParentId = parentId;
                }

                if (Job.FailureAction != null)
                {
                    log.Log("Running failure action ...");

                    try
                    {
                        Service.Execute(
                            new ExecuteWorkflowRequest
                        {
                            EntityId   = Job.Id,
                            WorkflowId = Job.FailureAction.Value
                        });
                    }
                    catch (Exception exception)
                    {
                        log.Log(exception);
                    }

                    log.Log("Finished running failure action.");
                }

                status.IsClose = true;
            }
            else
            {
                if (Job.RetrySchedule != null)
                {
                    UpdateRetryTargetDate(Service, Job, log);
                }

                IncrementRetry(Job.CurrentRetryRun ?? 0);
                log.Log($"Setting status of job to 'retry' ...", LogLevel.Debug);
                SetStatus(Service, CustomJob.StatusReasonEnum.Retry, Job.Id, false);
                log.Log($"Set status of job to 'retry'.");
            }

            var failures = executionResult.Exceptions
                           .Select(failure =>
                                   new CustomJobFailedTarget
            {
                ID             = failure.Key.ToString(),
                FailureMessage = BuildNoTraceExceptionMessage(failure.Value)
            });

            status.IsSuccess         = false;
            status.RunTargetFailures = failures.ToList();

            return(status);
        }
 protected override JobRunStatus ProcessFailure(ExecutionFailures executionResult)
 {
     AssociateFailedTargets(executionResult, Job.Id);
     DeleteSuccessfulFailed(executionResult);
     return(base.ProcessFailure(executionResult));
 }
Example #6
0
 protected abstract JobRunStatus ProcessFailurePaging(ExecutionFailures failures, JobPagingInfo pagingInfo);