diff --git a/src/activities/webhooks/Elsa.Activities.Webhooks/Elsa.Activities.Webhooks.csproj b/src/activities/webhooks/Elsa.Activities.Webhooks/Elsa.Activities.Webhooks.csproj index daef3103f..5c2078042 100644 --- a/src/activities/webhooks/Elsa.Activities.Webhooks/Elsa.Activities.Webhooks.csproj +++ b/src/activities/webhooks/Elsa.Activities.Webhooks/Elsa.Activities.Webhooks.csproj @@ -1,4 +1,4 @@ - + @@ -18,6 +18,10 @@ + + + + diff --git a/src/activities/webhooks/Elsa.Activities.Webhooks/Extensions/WebhookOptionsBuilderExtensions.cs b/src/activities/webhooks/Elsa.Activities.Webhooks/Extensions/WebhookOptionsBuilderExtensions.cs index 0bf37c55e..e37da0dbf 100644 --- a/src/activities/webhooks/Elsa.Activities.Webhooks/Extensions/WebhookOptionsBuilderExtensions.cs +++ b/src/activities/webhooks/Elsa.Activities.Webhooks/Extensions/WebhookOptionsBuilderExtensions.cs @@ -21,11 +21,17 @@ namespace Elsa.Activities.Webhooks.Extensions configure?.Invoke(webhookOptionsBuilder); // Services. + services .AddScoped() - .AddScoped(webhookOptionsBuilder.WebhookOptions.WebhookDefinitionStoreFactory); + .AddScoped(sp => + { + var x = webhookOptionsBuilder.WebhookOptions.WebhookDefinitionStoreFactory(sp); + return x; + }); services.Decorate(); + services.Decorate(); return elsaOptions; } diff --git a/src/activities/webhooks/Elsa.Activities.Webhooks/Persistence/Decorators/EventPublishingWebhookDefinitionStore.cs b/src/activities/webhooks/Elsa.Activities.Webhooks/Persistence/Decorators/EventPublishingWebhookDefinitionStore.cs new file mode 100644 index 000000000..f9f99f7cc --- /dev/null +++ b/src/activities/webhooks/Elsa.Activities.Webhooks/Persistence/Decorators/EventPublishingWebhookDefinitionStore.cs @@ -0,0 +1,95 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Elsa.Persistence.Specifications; +using Elsa.Webhooks.Abstractions.Events; +using Elsa.Webhooks.Abstractions.Models; +using Elsa.Webhooks.Abstractions.Persistence; +using MediatR; +using Open.Linq.AsyncExtensions; + +namespace Elsa.Activities.Webhooks.Persistence.Decorators +{ + public class EventPublishingWebhookDefinitionStore : IWebhookDefinitionStore + { + private readonly IWebhookDefinitionStore _store; + private readonly IMediator _mediator; + + public EventPublishingWebhookDefinitionStore(IWebhookDefinitionStore store, IMediator mediator) + { + _store = store; + _mediator = mediator; + } + + public Task CountAsync(ISpecification specification, CancellationToken cancellationToken = default) => _store.CountAsync(specification, cancellationToken); + + public async Task DeleteAsync(WebhookDefinition entity, CancellationToken cancellationToken = default) + { + await _mediator.Publish(new WebhookDefinitionDeleting(entity), cancellationToken); + await _store.DeleteAsync(entity, cancellationToken); + await _mediator.Publish(new WebhookDefinitionDeleted(entity), cancellationToken); + } + + public async Task DeleteManyAsync(ISpecification specification, CancellationToken cancellationToken = default) + { + var webhookDefinitions = await FindManyAsync(specification, cancellationToken: cancellationToken).ToList(); + + if (!webhookDefinitions.Any()) + return 0; + + foreach (var webhookDefinition in webhookDefinitions) + await _mediator.Publish(new WebhookDefinitionDeleting(webhookDefinition), cancellationToken); + + await _mediator.Publish(new ManyWebhookDefinitionsDeleting(webhookDefinitions), cancellationToken); + + var count = await _store.DeleteManyAsync(specification, cancellationToken); + + foreach (var instance in webhookDefinitions) + await _mediator.Publish(new WebhookDefinitionDeleted(instance), cancellationToken); + + await _mediator.Publish(new ManyWebhookDefinitionsDeleted(webhookDefinitions), cancellationToken); + + return count; + } + + public Task FindAsync(ISpecification specification, CancellationToken cancellationToken = default) => _store.FindAsync(specification, cancellationToken); + + public Task> FindManyAsync(ISpecification specification, IOrderBy? orderBy = null, IPaging? paging = null, CancellationToken cancellationToken = default) + => _store.FindManyAsync(specification, orderBy, paging, cancellationToken); + + public async Task SaveAsync(WebhookDefinition entity, CancellationToken cancellationToken = default) + { + await _mediator.Publish(new WebhookDefinitionSaving(entity), cancellationToken); + await _store.SaveAsync(entity, cancellationToken); + await _mediator.Publish(new WebhookDefinitionSaved(entity), cancellationToken); + } + + public async Task AddAsync(WebhookDefinition entity, CancellationToken cancellationToken = default) + { + await _mediator.Publish(new WebhookDefinitionSaving(entity), cancellationToken); + await _store.AddAsync(entity, cancellationToken); + await _mediator.Publish(new WebhookDefinitionSaved(entity), cancellationToken); + } + + public async Task AddManyAsync(IEnumerable entities, CancellationToken cancellationToken = default) + { + var list = entities.ToList(); + + foreach (var entity in list) + await _mediator.Publish(new WebhookDefinitionSaving(entity), cancellationToken); + + await _store.AddManyAsync(list, cancellationToken); + + foreach (var entity in list) + await _mediator.Publish(new WebhookDefinitionSaved(entity), cancellationToken); + } + + public async Task UpdateAsync(WebhookDefinition entity, CancellationToken cancellationToken = default) + { + await _mediator.Publish(new WebhookDefinitionSaving(entity), cancellationToken); + await _store.UpdateAsync(entity, cancellationToken); + await _mediator.Publish(new WebhookDefinitionSaved(entity), cancellationToken); + } + } +} \ No newline at end of file diff --git a/src/activities/webhooks/Elsa.Webhooks.Abstractions/Events/ManyWebhookDefinitionsDeleted.cs b/src/activities/webhooks/Elsa.Webhooks.Abstractions/Events/ManyWebhookDefinitionsDeleted.cs new file mode 100644 index 000000000..b3b1acef9 --- /dev/null +++ b/src/activities/webhooks/Elsa.Webhooks.Abstractions/Events/ManyWebhookDefinitionsDeleted.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; +using Elsa.Webhooks.Abstractions.Models; +using MediatR; + +namespace Elsa.Webhooks.Abstractions.Events +{ + public class ManyWebhookDefinitionsDeleted : INotification + { + public ManyWebhookDefinitionsDeleted(IEnumerable webhookDefinitions) => WebhookDefinitions = webhookDefinitions; + public IEnumerable WebhookDefinitions { get; } + } +} \ No newline at end of file diff --git a/src/activities/webhooks/Elsa.Webhooks.Abstractions/Events/ManyWebhookDefinitionsDeleting.cs b/src/activities/webhooks/Elsa.Webhooks.Abstractions/Events/ManyWebhookDefinitionsDeleting.cs new file mode 100644 index 000000000..e1d8259e0 --- /dev/null +++ b/src/activities/webhooks/Elsa.Webhooks.Abstractions/Events/ManyWebhookDefinitionsDeleting.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; +using Elsa.Webhooks.Abstractions.Models; +using MediatR; + +namespace Elsa.Webhooks.Abstractions.Events +{ + public class ManyWebhookDefinitionsDeleting : INotification + { + public ManyWebhookDefinitionsDeleting(IEnumerable webhookDefinitions) => WebhookDefinitions = webhookDefinitions; + public IEnumerable WebhookDefinitions { get; } + } +} \ No newline at end of file diff --git a/src/activities/webhooks/Elsa.Webhooks.Abstractions/Events/WebhookDefinitionDeleted.cs b/src/activities/webhooks/Elsa.Webhooks.Abstractions/Events/WebhookDefinitionDeleted.cs new file mode 100644 index 000000000..ed0e20343 --- /dev/null +++ b/src/activities/webhooks/Elsa.Webhooks.Abstractions/Events/WebhookDefinitionDeleted.cs @@ -0,0 +1,11 @@ +using Elsa.Webhooks.Abstractions.Models; + +namespace Elsa.Webhooks.Abstractions.Events +{ + public class WebhookDefinitionDeleted : WebhookDefinitionNotification + { + public WebhookDefinitionDeleted(WebhookDefinition webhookDefinition) : base(webhookDefinition) + { + } + } +} \ No newline at end of file diff --git a/src/activities/webhooks/Elsa.Webhooks.Abstractions/Events/WebhookDefinitionDeleting.cs b/src/activities/webhooks/Elsa.Webhooks.Abstractions/Events/WebhookDefinitionDeleting.cs new file mode 100644 index 000000000..c292b43b5 --- /dev/null +++ b/src/activities/webhooks/Elsa.Webhooks.Abstractions/Events/WebhookDefinitionDeleting.cs @@ -0,0 +1,11 @@ +using Elsa.Webhooks.Abstractions.Models; + +namespace Elsa.Webhooks.Abstractions.Events +{ + public class WebhookDefinitionDeleting : WebhookDefinitionNotification + { + public WebhookDefinitionDeleting(WebhookDefinition webhookDefinition) : base(webhookDefinition) + { + } + } +} \ No newline at end of file diff --git a/src/activities/webhooks/Elsa.Webhooks.Abstractions/Events/WebhookDefinitionNotification.cs b/src/activities/webhooks/Elsa.Webhooks.Abstractions/Events/WebhookDefinitionNotification.cs new file mode 100644 index 000000000..efa6d3589 --- /dev/null +++ b/src/activities/webhooks/Elsa.Webhooks.Abstractions/Events/WebhookDefinitionNotification.cs @@ -0,0 +1,11 @@ +using Elsa.Webhooks.Abstractions.Models; +using MediatR; + +namespace Elsa.Webhooks.Abstractions.Events +{ + public abstract class WebhookDefinitionNotification : INotification + { + public WebhookDefinitionNotification(WebhookDefinition webhookDefinition) => WebhookDefinition = webhookDefinition; + public WebhookDefinition WebhookDefinition { get; } + } +} \ No newline at end of file diff --git a/src/activities/webhooks/Elsa.Webhooks.Abstractions/Events/WebhookDefinitionSaved.cs b/src/activities/webhooks/Elsa.Webhooks.Abstractions/Events/WebhookDefinitionSaved.cs new file mode 100644 index 000000000..aadea061d --- /dev/null +++ b/src/activities/webhooks/Elsa.Webhooks.Abstractions/Events/WebhookDefinitionSaved.cs @@ -0,0 +1,11 @@ +using Elsa.Webhooks.Abstractions.Models; + +namespace Elsa.Webhooks.Abstractions.Events +{ + public class WebhookDefinitionSaved : WebhookDefinitionNotification + { + public WebhookDefinitionSaved(WebhookDefinition webhookDefinition) : base(webhookDefinition) + { + } + } +} \ No newline at end of file diff --git a/src/activities/webhooks/Elsa.Webhooks.Abstractions/Events/WebhookDefinitionSaving.cs b/src/activities/webhooks/Elsa.Webhooks.Abstractions/Events/WebhookDefinitionSaving.cs new file mode 100644 index 000000000..7bcbda64a --- /dev/null +++ b/src/activities/webhooks/Elsa.Webhooks.Abstractions/Events/WebhookDefinitionSaving.cs @@ -0,0 +1,11 @@ +using Elsa.Webhooks.Abstractions.Models; + +namespace Elsa.Webhooks.Abstractions.Events +{ + public class WebhookDefinitionSaving : WebhookDefinitionNotification + { + public WebhookDefinitionSaving(WebhookDefinition webhookDefinition) : base(webhookDefinition) + { + } + } +} \ No newline at end of file diff --git a/src/activities/webhooks/Elsa.Webhooks.Persistence.EntityFramework.Core/Configuration/WebhookDefinitionConfiguration.cs b/src/activities/webhooks/Elsa.Webhooks.Persistence.EntityFramework.Core/Configuration/WebhookDefinitionConfiguration.cs index 13c06d462..7bb663eea 100644 --- a/src/activities/webhooks/Elsa.Webhooks.Persistence.EntityFramework.Core/Configuration/WebhookDefinitionConfiguration.cs +++ b/src/activities/webhooks/Elsa.Webhooks.Persistence.EntityFramework.Core/Configuration/WebhookDefinitionConfiguration.cs @@ -8,7 +8,6 @@ namespace Elsa.Webhooks.Persistence.EntityFramework.Core.Configuration { public void Configure(EntityTypeBuilder builder) { - builder.Property("Data"); builder.HasIndex(x => x.TenantId).HasDatabaseName($"IX_{nameof(WebhookDefinition)}_{nameof(WebhookDefinition.TenantId)}"); builder.HasIndex(x => x.Path).HasDatabaseName($"IX_{nameof(WebhookDefinition)}_{nameof(WebhookDefinition.Path)}"); builder.HasIndex(x => x.Name).HasDatabaseName($"IX_{nameof(WebhookDefinition)}_{nameof(WebhookDefinition.Name)}"); diff --git a/src/activities/webhooks/Elsa.Webhooks.Persistence.EntityFramework.Core/Extensions/WebhookServiceCollectionExtensions.cs b/src/activities/webhooks/Elsa.Webhooks.Persistence.EntityFramework.Core/Extensions/WebhookServiceCollectionExtensions.cs index 4c7e9a5cc..a1feea8fa 100644 --- a/src/activities/webhooks/Elsa.Webhooks.Persistence.EntityFramework.Core/Extensions/WebhookServiceCollectionExtensions.cs +++ b/src/activities/webhooks/Elsa.Webhooks.Persistence.EntityFramework.Core/Extensions/WebhookServiceCollectionExtensions.cs @@ -220,9 +220,11 @@ namespace Elsa.Webhooks.Persistence.EntityFramework.Core.Extensions if (autoRunMigrations) webhookOptions.Services.AddStartupTask(); - var webhookOptionsBuilder = new WebhookOptionsBuilder(webhookOptions.Services); - - webhookOptionsBuilder.UseWebhookDefinitionStore(sp => sp.GetRequiredService()); + webhookOptions.UseWebhookDefinitionStore(sp => + { + var x = sp.GetRequiredService(); + return x; + }); return webhookOptions; } diff --git a/src/samples/server/Elsa.Samples.Server.Host/Startup.cs b/src/samples/server/Elsa.Samples.Server.Host/Startup.cs index b469b0107..bd1a3a061 100644 --- a/src/samples/server/Elsa.Samples.Server.Host/Startup.cs +++ b/src/samples/server/Elsa.Samples.Server.Host/Startup.cs @@ -63,7 +63,10 @@ namespace Elsa.Samples.Server.Host .AddConductorActivities(options => elsaSection.GetSection("Conductor").Bind(options)) .AddActivitiesFrom() .AddWorkflowsFrom() - .AddWebhooks(webhooks => webhooks.UseEntityFrameworkPersistence(ef => ef.UseWebhookSqlite())) + .AddWebhooks(webhooks => + { + webhooks.UseEntityFrameworkPersistence(ef => ef.UseWebhookSqlite()); + }) ); // Elsa API endpoints.