elsa-workflows / elsa-core

A .NET workflows library
https://v3.elsaworkflows.io/
MIT License
6.51k stars 1.2k forks source link

[DOC] MassTransit Azure Service Bus examples (V3) #5887

Open sturlath opened 3 months ago

sturlath commented 3 months ago

I´m trying to use UseMassTransit().UseAzureServiceBus() to start my workflow but am totally unable to get it working. The only other thing I found was this discussion but that is version 2.

This here is what I currently have working in my normal MassTransit setup

using MassTransit;
public class AssignmentCreatedHandler(
    : IConsumer<SubscriptionAssignmentCreated>
{
    public async Task Consume(ConsumeContext<SubscriptionAssignmentCreated> context)
    {  
        // handle code omitted 
    }
}

public class SubscriptionAssignmentCreated
{
    public Subscription Subscription { get; }
    public Guid CustomerId { get; }

    public SubscriptionAssignmentCreated(Subscription Subscription, Guid CustomerId)
    {
        this.Subscription = Subscription;
        if (!(CustomerId != Guid.Empty))
        {
            throw new ArgumentException("Customer id must contain a valid value");
        }

        this.CustomerId = CustomerId;
    }
}

and then in my Program.cs

builder.Services.AddMassTransit(options =>
{
    options.AddConsumer<AssignmentCreatedHandler>();

    options.UsingAzureServiceBus((context, cfg) =>
    {
            cfg.Host(
                new Uri($"sb://..."),
                bus =>
                {
                    bus.ConnectionString = "Endpoint=sb://....";
                }
            );
        cfg.SubscriptionEndpoint<SubscriptionAssignmentCreated>("SubscriptionAssignmentCreated",
            configurator => configurator.ConfigureConsumer<AssignmentCreatedHandler>(context));

        cfg.ConfigureEndpoints(context);
    });
});

But this here is as far as I have been able to get with Elsa version 3.2.0-rc4.

builder.Services.AddElsa(elsa =>
{
    elsa.UseWorkflowManagement(management => management.UseEntityFrameworkCore());
    elsa.UseWorkflowRuntime(runtime => runtime.UseEntityFrameworkCore());
    elsa.UseIdentity(identity =>
    {
        identity.TokenOptions = options => options.SigningKey = "sufficiently-large-secret-signing-key";
        identity.UseAdminUserProvider();
    });
    elsa.UseDefaultAuthentication(auth => auth.UseAdminApiKey());
    elsa.UseWorkflowsApi();
    elsa.UseRealTimeWorkflows();
    elsa.UseCSharp();
    elsa.UseHttp();
    elsa.UseScheduling();

    elsa.UseMassTransit(massTransit =>
    {
       massTransit.AddConsumer<AssignmentCreatedHandler>("AssignmentCreatedHandler", isTemporary: false);
        massTransit.UseAzureServiceBus(
            "Endpoint=sb://...",
            serviceBusFeature => serviceBusFeature.ConfigureServiceBus = bus =>
            {
                            bus.PrefetchCount = 4;
                            bus.LockDuration = TimeSpan.FromMinutes(5);
                            bus.MaxConcurrentCalls = 32;
                            bus.MaxDeliveryCount = 8;

                // I'm guessing I don´t need to setup SubscriptionEndpoint as above to setup a "handler"
               // since the AssignmentConsumedWorkflow should be picking up the event.. 🤷‍♂️
            }
        );
    });
    elsa.AddActivitiesFrom<Program>();
    elsa.AddWorkflowsFrom<Program>();
});

Here is the workflow that should be the starting point when a message hits. I followed MessageReceivedTriggerWorkflow

public class AssignmentConsumedWorkflow() : WorkflowBase
{
    public static readonly string DefinitionId = Guid.NewGuid().ToString();
    public static readonly string Topic = "my_azure_service_bus_topic_name";
    public static readonly object Signal1 = new();
    public static readonly object Signal2 = new();

    protected override void Build(IWorkflowBuilder builder)
    {
        builder.WithDefinitionId(DefinitionId);
        var message = builder.WithVariable<SubscriptionAssignmentCreated>();
        builder.Root = new Sequence
        {
            Activities =
            {
                new MessageReceived(Topic, nameof(SubscriptionAssignmentCreated))
                {
                    CanStartWorkflow = true,
                    TransportMessage = new(message)
                },
                new If
                {
                    Condition = new Input<bool>(context =>
                    {
                        var msg = message.Get(context);
                        return msg?.Subscription?.Features != null &&
                               msg.Subscription.Features.Any(f => f.Code == FeatureCodes.SomeCode);
                    }),
                    Then = new Sequence
                    {
                        Activities =
                        {
                            new TheClassThatShouldDoSomethingActivity(),
                        }
                    },
                    Else = new Sequence
                    {
                        Activities =
                        {
                            new WriteLine("Subscription or Features is null or does not contain the required feature."),
                            new WriteLine("False!")
                        }
                    }

                }
            }
        };
    }
}

But what ever I try I just can´t get the AssignmentConsumedWorkflow to fire.

Hope you can assist me in the right direction before I give up 😅

sturlath commented 2 months ago

@sfmskywalker any change to get some feedback here? I just can´t get this to work 🤷‍♂️

sfmskywalker commented 2 months ago

Hey there! I suspect that the way you’re using the MT activities may not be fully tested. I only ever tested this for use in the designer where the activities are generated for each registered message. However, when you’re using a code first approach, either you would need to use some dynamic activity to be able to provide the right activity type, or we should revise or add activities that let you use it the way you’re trying to.

sturlath commented 2 months ago

🤷‍♂️ I think I will just wait with further exploring Elsa 3.x until it has matured further with the documentation and examples 😉 I really like what I see but at the moment its way to hard and time consuming for me.

sfmskywalker commented 2 months ago

Sounds fair. Thank you for the feedback.