コード例 #1
0
        /// <inheritdoc/>
        protected override async Task ProcessAsync(CancellationToken cancellationToken)
        {
            if (!this.Activity.Metadata.TryGetValue(V1WorkflowActivityMetadata.Subflow, out var workflowInstanceId))
            {
                workflowInstanceId = await this.Context.Workflow.StartSubflowAsync($"{this.Subflow.WorkflowId}:{this.Subflow.Version}", this.Activity.Input, cancellationToken);

                this.Activity.Metadata.Add(V1WorkflowActivityMetadata.Subflow, workflowInstanceId);
                await this.Context.Workflow.SetActivityMetadataAsync(this.Activity, cancellationToken);
            }
            switch (this.Subflow.InvocationMode)
            {
            case InvocationMode.Asynchronous:
                await this.OnNextAsync(new V1WorkflowActivityCompletedIntegrationEvent(this.Activity.Id, this.Activity.Input), this.CancellationTokenSource.Token);

                await this.OnCompletedAsync(this.CancellationTokenSource.Token);

                break;

            case InvocationMode.Synchronous:
                var eventDefinition = new EventDefinition()
                {
                    Kind         = EventKind.Consumed,
                    Name         = "onSubflowExecuted",
                    Source       = CloudEvents.Source.ToString(),
                    Type         = CloudEvents.TypeOf(typeof(V1WorkflowInstanceExecutedIntegrationEvent), typeof(V1WorkflowInstance)),
                    Correlations = new()
                    {
                        new() { ContextAttributeName = nameof(CloudEvent.Subject).ToLower(), ContextAttributeValue = workflowInstanceId }
                    }
                };
                var e = await this.Context.Workflow.ConsumeOrBeginCorrelateEventAsync(eventDefinition, cancellationToken);

                if (e != null)
                {
                    await this.OnEventAsync(e);

                    return;
                }
                this.Subscription = this.IntegrationEventBus.InboundStream
                                    .Where(e => e.Subject == workflowInstanceId && e.Source?.ToString() == eventDefinition.Source && e.Type == eventDefinition.Type)
                                    .SubscribeAsync(this.OnEventAsync);
                if (this.Options.Correlation.Timeout.HasValue)
                {
                    this.IdleTimer = new Timer(async state => await this.OnIdleTimerExpiredAsync(state, cancellationToken), null, this.Options.Correlation.Timeout.Value, this.Options.Correlation.Timeout.Value);
                }
                break;

            default:
                throw new NotSupportedException($"The specified {nameof(InvocationMode)} '{this.Subflow.InvocationMode}' is not supported");
            }
        }
コード例 #2
0
        /// <summary>
        /// Publishes a <see cref="CloudEvent"/> for the specified <see cref="IDomainEvent"/>
        /// </summary>
        /// <param name="e">The <see cref="IDomainEvent"/> to publish a new <see cref="CloudEvent"/> for</param>
        /// <param name="cancellationToken">A <see cref="CancellationToken"/></param>
        /// <returns>A new awaitable <see cref="Task"/></returns>
        protected virtual async Task PublishIntegrationEventAsync <TEvent>(TEvent e, CancellationToken cancellationToken)
            where TEvent : class, IDomainEvent
        {
            if (!e.GetType().TryGetCustomAttribute(out DataTransferObjectTypeAttribute dataTransferObjectTypeAttribute))
            {
                return;
            }
            var integrationEvent = (V1IntegrationEvent)this.Mapper.Map(e, e.GetType(), dataTransferObjectTypeAttribute.Type);
            var aggregateType    = e.GetType().GetGenericType(typeof(DomainEvent <,>)).GetGenericArguments()[0];
            var cloudEvent       = new CloudEvent()
            {
                Id              = Guid.NewGuid().ToString(),
                Source          = CloudEvents.Source,
                Type            = CloudEvents.TypeOf(typeof(TEvent), aggregateType),
                Time            = e.CreatedAt,
                Subject         = e.AggregateId.ToString(),
                DataSchema      = CloudEvents.SchemaOf(typeof(TEvent), aggregateType),
                DataContentType = MediaTypeNames.Application.Json,
                Data            = integrationEvent
            };

            await this.IntegrationEventBus.PublishAsync(cloudEvent, cancellationToken);
        }