Ejemplo n.º 1
0
        /// <inheritdoc/>
        public virtual async Task <IOperationResult <Integration.Models.V1Event?> > HandleAsync(V1ConsumeOrBeginCorrelateEventCommand command, CancellationToken cancellationToken = default)
        {
            var workflowInstance = await this.WorkflowInstances.FindAsync(command.WorkflowInstanceId, cancellationToken);

            if (workflowInstance == null)
            {
                throw DomainException.NullReference(typeof(V1WorkflowInstance), command.WorkflowInstanceId);
            }
            var e = workflowInstance.CorrelationContext.PendingEvents
                    .FirstOrDefault(e => e.Matches(command.EventDefinition));

            if (e == null)
            {
                var conditions = new List <V1CorrelationCondition>()
                {
                    V1CorrelationCondition.Match(command.EventDefinition)
                };
                var outcome = new V1CorrelationOutcome(V1CorrelationOutcomeType.Correlate, command.WorkflowInstanceId);
                await this.Mediator.ExecuteAndUnwrapAsync(new V1CreateCorrelationCommand(V1CorrelationLifetime.Singleton, V1CorrelationConditionType.AnyOf, conditions, outcome, workflowInstance.CorrelationContext), cancellationToken);
            }
            else
            {
                workflowInstance.CorrelationContext.RemoveEvent(e);
                await this.WorkflowInstances.UpdateAsync(workflowInstance, cancellationToken);

                await this.WorkflowInstances.SaveChangesAsync(cancellationToken);
            }
            return(this.Ok(e == null ? null : this.Mapper.Map <Integration.Models.V1Event>(e)));
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Initializes a new <see cref="V1CreateWorkflowInstanceCommand"/>
 /// </summary>
 /// <param name="lifetime">The lifetime of the <see cref="V1Correlation"/> to create</param>
 /// <param name="conditionType">The type of <see cref="V1CorrelationCondition"/> evaluation the <see cref="V1Correlation"/> should use</param>
 /// <param name="conditions">An <see cref="IEnumerable{T}"/> containing all <see cref="V1CorrelationCondition"/>s the <see cref="V1Correlation"/> to create is made out of</param>
 /// <param name="outcome">The <see cref="V1CorrelationOutcome"/> of the <see cref="V1Correlation"/> to create</param>
 /// <param name="context">The initial <see cref="V1CorrelationContext"/> of the <see cref="V1Correlation"/> to create</param>
 public V1CreateCorrelationCommand(V1CorrelationLifetime lifetime, V1CorrelationConditionType conditionType,
                                   IEnumerable <V1CorrelationCondition> conditions, V1CorrelationOutcome outcome, V1CorrelationContext?context)
 {
     this.Lifetime      = lifetime;
     this.ConditionType = conditionType;
     this.Conditions    = conditions;
     this.Outcome       = outcome;
     this.Context       = context;
 }
        /// <inheritdoc/>
        public virtual async Task <IOperationResult <Integration.Models.V1Workflow> > HandleAsync(V1CreateWorkflowCommand command, CancellationToken cancellationToken = default)
        {
            var validationResult = await this.WorkflowValidator.ValidateAsync(command.Definition, true, true, cancellationToken);

            if (!validationResult.IsValid)
            {
                return(this.Invalid(validationResult.AsErrors().ToArray()));
            }
            foreach (var subflowRef in command.Definition.GetSubflowReferences())
            {
                var reference = subflowRef.WorkflowId;
                if (!string.IsNullOrWhiteSpace(subflowRef.Version))
                {
                    reference += $":{subflowRef.Version}";
                }
                var subflow = await this.Mediator.ExecuteAndUnwrapAsync(new V1GetWorkflowByIdQuery(subflowRef.WorkflowId, subflowRef.Version), cancellationToken);

                if (subflow == null)
                {
                    throw DomainException.NullReference(typeof(V1Workflow), $"Failed to find the referenced workflow '{reference}'");
                }
            }
            if (command.IfNotExists &&
                await this.Workflows.ContainsAsync(command.Definition.GetUniqueIdentifier(), cancellationToken))
            {
                return(this.NotModified());
            }
            else
            {
                while (await this.Workflows.ContainsAsync(command.Definition.GetUniqueIdentifier(), cancellationToken))
                {
                    var version = Version.Parse(command.Definition.Version);
                    version = new Version(version.Major, version.Minor, version.Build == -1 ? 1 : version.Build + 1);
                    command.Definition.Version = version.ToString(3);
                }
            }
            var workflow = await this.Workflows.AddAsync(new(command.Definition), cancellationToken);

            await this.Workflows.SaveChangesAsync(cancellationToken);

            var startState = workflow.Definition.GetStartState();

            if (startState is EventStateDefinition eventState)
            {
                var lifetime      = V1CorrelationLifetime.Transient;
                var conditionType = eventState.Exclusive ? V1CorrelationConditionType.AnyOf : V1CorrelationConditionType.AllOf;
                var conditions    = new List <V1CorrelationCondition>();
                foreach (var trigger in eventState.Triggers)
                {
                    var filters = new List <V1EventFilter>(trigger.Events.Count);
                    foreach (var eventRef in trigger.Events)
                    {
                        if (!workflow.Definition.TryGetEvent(eventRef, out var e))
                        {
                            throw DomainException.NullReference(typeof(EventDefinition), eventRef, nameof(EventDefinition.Name));
                        }
                        filters.Add(V1EventFilter.Match(e));
                    }
                    conditions.Add(new(filters.ToArray()));
                }
                var outcome = new V1CorrelationOutcome(V1CorrelationOutcomeType.Start, workflow.Id);
                await this.Mediator.ExecuteAndUnwrapAsync(new V1CreateCorrelationCommand(lifetime, conditionType, conditions, outcome, null));
            }
            else if (!string.IsNullOrWhiteSpace(workflow.Definition.Start?.Schedule?.Cron?.Expression))
            {
                await this.Mediator.ExecuteAndUnwrapAsync(new V1ScheduleWorkflowCommand(workflow.Id, false), cancellationToken);
            }
            return(this.Ok(this.Mapper.Map <Integration.Models.V1Workflow>(workflow)));
        }