Exemplo n.º 1
0
        private async Task AddJobsAsync(List <JobResult> jobs, Envelope <IEvent> @event, RuleContext context,
                                        CancellationToken ct)
        {
            try
            {
                var skipReason = SkipReason.None;

                var rule = context.Rule;

                if (!rule.IsEnabled)
                {
                    // For the simulation we want to proceed as much as possible.
                    if (context.IncludeSkipped)
                    {
                        skipReason |= SkipReason.Disabled;
                    }
                    else
                    {
                        jobs.Add(JobResult.Disabled);
                        return;
                    }
                }

                if (@event.Payload is not AppEvent)
                {
                    jobs.Add(JobResult.WrongEvent);
                    return;
                }

                var typed = @event.To <AppEvent>();

                if (typed.Payload.FromRule)
                {
                    // For the simulation we want to proceed as much as possible.
                    if (context.IncludeSkipped)
                    {
                        skipReason |= SkipReason.FromRule;
                    }
                    else
                    {
                        jobs.Add(JobResult.FromRule);
                        return;
                    }
                }

                var actionType = rule.Action.GetType();

                if (!ruleTriggerHandlers.TryGetValue(rule.Trigger.GetType(), out var triggerHandler))
                {
                    jobs.Add(JobResult.NoTrigger);
                    return;
                }

                if (!triggerHandler.Handles(typed.Payload))
                {
                    jobs.Add(JobResult.WrongEventForTrigger);
                    return;
                }

                if (!ruleActionHandlers.TryGetValue(actionType, out var actionHandler))
                {
                    jobs.Add(JobResult.NoAction);
                    return;
                }

                var now = clock.GetCurrentInstant();

                var eventTime =
                    @event.Headers.ContainsKey(CommonHeaders.Timestamp) ?
                    @event.Headers.Timestamp() :
                    now;

                if (!context.IncludeStale && eventTime.Plus(Constants.StaleTime) < now)
                {
                    // For the simulation we want to proceed as much as possible.
                    if (context.IncludeSkipped)
                    {
                        skipReason |= SkipReason.TooOld;
                    }
                    else
                    {
                        jobs.Add(JobResult.TooOld);
                        return;
                    }
                }

                if (!triggerHandler.Trigger(typed, context))
                {
                    // For the simulation we want to proceed as much as possible.
                    if (context.IncludeSkipped)
                    {
                        skipReason |= SkipReason.ConditionPrecheckDoesNotMatch;
                    }
                    else
                    {
                        jobs.Add(JobResult.ConditionPrecheckDoesNotMatch);
                        return;
                    }
                }

                await foreach (var enrichedEvent in triggerHandler.CreateEnrichedEventsAsync(typed, context, ct))
                {
                    if (string.IsNullOrWhiteSpace(enrichedEvent.Name))
                    {
                        enrichedEvent.Name = GetName(typed.Payload);
                    }

                    try
                    {
                        await eventEnricher.EnrichAsync(enrichedEvent, typed);

                        if (!triggerHandler.Trigger(enrichedEvent, context))
                        {
                            // For the simulation we want to proceed as much as possible.
                            if (context.IncludeSkipped)
                            {
                                skipReason |= SkipReason.ConditionDoesNotMatch;
                            }
                            else
                            {
                                jobs.Add(JobResult.ConditionDoesNotMatch);
                                return;
                            }
                        }

                        var job = await CreateJobAsync(actionHandler, enrichedEvent, context, now);

                        // If the conditions matchs, we can skip creating a new object and save a few allocation.s
                        if (skipReason != SkipReason.None)
                        {
                            job = job with {
                                SkipReason = skipReason
                            };
                        }

                        jobs.Add(job);
                    }
                    catch (Exception ex)
                    {
                        if (jobs.Count == 0)
                        {
                            jobs.Add(new JobResult
                            {
                                EnrichedEvent   = enrichedEvent,
                                EnrichmentError = ex,
                                SkipReason      = SkipReason.Failed
                            });
                        }

                        log.LogError(ex, w => w
                                     .WriteProperty("action", "createRuleJobFromEvent")
                                     .WriteProperty("status", "Failed"));
                    }
                }
            }
            catch (Exception ex)
            {
                jobs.Add(JobResult.Failed(ex));

                log.LogError(ex, w => w
                             .WriteProperty("action", "createRuleJob")
                             .WriteProperty("status", "Failed"));
            }
        }
Exemplo n.º 2
0
        private async Task <JobResult> CreateJobAsync(IRuleActionHandler actionHandler, EnrichedEvent enrichedEvent, RuleContext context, Instant now)
        {
            var actionName = typeNameRegistry.GetName(context.Rule.Action.GetType());

            var expires = now.Plus(Constants.ExpirationTime);

            var job = new RuleJob
            {
                Id                 = DomainId.NewGuid(),
                ActionData         = string.Empty,
                ActionName         = actionName,
                AppId              = enrichedEvent.AppId.Id,
                Created            = now,
                EventName          = enrichedEvent.Name,
                ExecutionPartition = enrichedEvent.Partition,
                Expires            = expires,
                RuleId             = context.RuleId
            };

            try
            {
                var(description, data) = await actionHandler.CreateJobAsync(enrichedEvent, context.Rule.Action);

                var json = jsonSerializer.Serialize(data);

                job.ActionData  = json;
                job.ActionName  = actionName;
                job.Description = description;

                return(new JobResult {
                    Job = job, EnrichedEvent = enrichedEvent
                });
            }
            catch (Exception ex)
            {
                job.Description = "Failed to create job";

                return(JobResult.Failed(ex, enrichedEvent, job));
            }
        }
Exemplo n.º 3
0
        public async IAsyncEnumerable <JobResult> CreateJobsAsync(Envelope <IEvent> @event, RuleContext context,
                                                                  [EnumeratorCancellation] CancellationToken ct = default)
        {
            Guard.NotNull(@event, nameof(@event));

            var jobs = new List <JobResult>();

            await AddJobsAsync(jobs, @event, context, ct);

            foreach (var job in jobs)
            {
                if (ct.IsCancellationRequested)
                {
                    break;
                }

                yield return(job);
            }
        }