Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add DomainEvent activity #5994

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions src/modules/Elsa.Webhooks/Handlers/DomainEventHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using Elsa.Mediator.Contracts;
using Elsa.Webhooks.Models;
using Elsa.Workflows.Runtime.Notifications;
using JetBrains.Annotations;
using WebhooksCore;

namespace Elsa.Webhooks.Handlers;

/// Handles the <see cref="DomainEventNotification"/> notification and asynchronously invokes all registered webhook endpoints.
[UsedImplicitly]
public class DomainEventHandler(IWebhookEventBroadcaster webhookDispatcher) : INotificationHandler<DomainEventNotification>
{
/// <inheritdoc />
public async Task HandleAsync(DomainEventNotification notification, CancellationToken cancellationToken)
{
var activityExecutionContext = notification.ActivityExecutionContext;
var workflowExecutionContext = activityExecutionContext.WorkflowExecutionContext;
var workflowInstanceId = workflowExecutionContext.Id;
var correlationId = workflowExecutionContext.CorrelationId;
var workflow = workflowExecutionContext.Workflow;
var workflowDefinitionId = workflow.Identity.DefinitionId;
var workflowName = workflow.WorkflowMetadata.Name;

var payload = new DomainEventWebhookPayload(
workflowInstanceId,
workflowDefinitionId,
workflowName,
correlationId,
notification.DomainEventId,
notification.DomainEventName,
notification.DomainEventPayload
);

var webhookEvent = new NewWebhookEvent("Elsa.DomainEvent", payload);
await webhookDispatcher.BroadcastAsync(webhookEvent, cancellationToken);
}
}
13 changes: 13 additions & 0 deletions src/modules/Elsa.Webhooks/Models/DomainEventWebhookPayload.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace Elsa.Webhooks.Models;

/// <summary>
/// Stores payload information about the DomainEvent webhook event type.
/// </summary>
public record DomainEventWebhookPayload(
string WorkflowInstanceId,
string WorkflowDefinitionId,
string? WorkflowName,
string? CorrelationId,
string DomainEventId,
string DomainEventName,
object? DomainEventPayload);
44 changes: 44 additions & 0 deletions src/modules/Elsa.Workflows.Runtime/Activities/DomainEvent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using Elsa.Extensions;
using Elsa.Mediator.Contracts;
using Elsa.Workflows.Attributes;
using Elsa.Workflows.Contracts;
using Elsa.Workflows.Models;
using Elsa.Workflows.Runtime.Notifications;
using JetBrains.Annotations;

namespace Elsa.Workflows.Runtime.Activities;

/// <summary>
/// Notifies the application that a domain event with a given name is requested to be published.
/// </summary>
[Activity("Elsa", "Primitives", "Requests a given domain event to be published. ", Kind = ActivityKind.Action)]
[UsedImplicitly]
public class DomainEvent: Activity
{
/// <summary>
/// The name of the domain event being published.
/// </summary>
[Input(Description = "The name of the domain event being published.")]
public Input<string> DomainEventName { get; set; } = default!;

/// <summary>
/// The payload of the domain event being published.
/// </summary>
[Input(Description = "Any additional parameters to send to the domain event.")]
public Input<object?> Payload { get; set; } = default!;

protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
{
var domainEventName = DomainEventName.Get(context);
var identityGenerator = context.GetRequiredService<IIdentityGenerator>();
var domainEventId = identityGenerator.GenerateId();

// Publish the domain event
var domainEventPayload = Payload.GetOrDefault(context);
var domainEventNotification = new DomainEventNotification(context, domainEventId, domainEventName, domainEventPayload);
var dispatcher = context.GetRequiredService<INotificationSender>();

await dispatcher.SendAsync(domainEventNotification, context.CancellationToken);
await context.CompleteActivityAsync();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using Elsa.Mediator.Contracts;

namespace Elsa.Workflows.Runtime.Notifications;

/// <summary>
/// A domain event that applications can subscribe to.
/// </summary>
/// <param name="ActivityExecutionContext">The context of the activity that requested the domain event to be published.</param>
/// <param name="DomainEventId">A unique identifier for an individual domain event notification.</param>
/// <param name="DomainEventName">The name of the domain event requested to be published.</param>
/// <param name="DomainEventPayload">Any additional parameters to send to the domain event.</param>
public record DomainEventNotification(ActivityExecutionContext ActivityExecutionContext, string DomainEventId, string DomainEventName, object? DomainEventPayload) : INotification;
Loading