/// <inheritdoc/> public virtual async Task <IOperationResult <Integration.Models.V1Correlation> > HandleAsync(V1CreateCorrelationCommand command, CancellationToken cancellationToken = default) { var correlation = new V1Correlation(command.Lifetime, command.ConditionType, command.Conditions, command.Outcome, command.Context); correlation = await this.Correlations.AddAsync(correlation, cancellationToken); await this.Correlations.SaveChangesAsync(cancellationToken); return(this.Ok(this.Mapper.Map <Integration.Models.V1Correlation>(correlation))); }
/// <summary> /// Performs a correlation on a <see cref="V1Event"/>, in a given <see cref="V1CorrelationContext"/> and using the specified <see cref="V1EventFilter"/> /// </summary> /// <param name="correlation">The <see cref="V1Correlation"/> to perform</param> /// <param name="correlationContext">The <see cref="V1CorrelationContext"/> in which to perform the <see cref="V1Correlation"/></param> /// <param name="e">The <see cref="V1Event"/> to correlate</param> /// <param name="filter">The <see cref="V1EventFilter"/> used to correlate the <see cref="V1Event"/></param> /// <param name="cancellationToken">A <see cref="CancellationToken"/></param> /// <returns>A new awaitable <see cref="Task"/></returns> protected virtual async Task CorrelateAsync(V1Correlation correlation, V1CorrelationContext correlationContext, V1Event e, V1EventFilter filter, CancellationToken cancellationToken = default) { this.Logger.LogInformation("Correlating event to context with id '{contextId}'...", correlationContext.Id); correlationContext.Correlate(e, filter.CorrelationMappings.Keys, true); correlation = await this.Correlations.UpdateAsync(correlation, cancellationToken); await this.Correlations.SaveChangesAsync(cancellationToken); this.Logger.LogInformation("Event successfully correlated to context with id '{contextId}'", correlationContext.Id); this.Logger.LogInformation("Attempting to complete the correlation with id '{correlationId}' in context with id '{contextId}'...", correlation.Id, correlationContext.Id); if (!correlation.TryComplete(correlationContext)) { this.Logger.LogInformation("Correlations conditions are not met in the specified correlation context"); return; } this.Logger.LogInformation("Correlation with id '{correlationId}' has been completed in context with id '{contextId}. Computing outcome...", correlation.Id, correlationContext.Id); switch (correlation.Outcome.Type) { case V1CorrelationOutcomeType.Start: await this.Mediator.ExecuteAndUnwrapAsync(new V1CreateWorkflowInstanceCommand(correlation.Outcome.Target, V1WorkflowInstanceActivationType.Trigger, new(), correlationContext, true, null), cancellationToken); break; case V1CorrelationOutcomeType.Correlate: await this.Mediator.ExecuteAndUnwrapAsync(new V1CorrelateWorkflowInstanceCommand(correlation.Outcome.Target, correlationContext), cancellationToken); break; default: throw new NotSupportedException($"The specified {nameof(V1CorrelationOutcomeType)} '{correlation.Outcome.Type}' is not supported"); } correlation.ReleaseContext(correlationContext); correlation = await this.Correlations.UpdateAsync(correlation, cancellationToken); await this.Correlations.SaveChangesAsync(cancellationToken); if (correlation.Lifetime == V1CorrelationLifetime.Singleton) { this.Logger.LogInformation("The correlation with id '{correlationId}' is a singleton and its context has been released. Disposing of it...", correlation.Id); await this.Mediator.ExecuteAndUnwrapAsync(new V1DeleteCorrelationCommand(correlation.Id), cancellationToken); this.Logger.LogInformation("The correlation with id '{correlationId}' has been successfully disposed of", correlation.Id); } this.Logger.LogInformation("Correlation outcome successfully computed"); }