/// <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))); }
/// <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))); }