WIP #667 - Webhook activity project (#718)

* Webhook activity project

* Webhook definition with InMemoryStore

* Add Webhook activity provider

* Prevent part assembly generation. See https://github.com/dotnet/aspnetcore/issues/24171

Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
This commit is contained in:
Konstantin Mikhailyuk 2021-03-19 22:15:50 +02:00 committed by GitHub
parent 58648339c8
commit caf15ecc70
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
28 changed files with 561 additions and 7 deletions

View file

@ -241,7 +241,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Samples.InvokeWorkflow
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Persistence.EntityFramework.PostgreSql", "src\persistence\Elsa.Persistence.EntityFramework\Elsa.Persistence.EntityFramework.PostgreSql\Elsa.Persistence.EntityFramework.PostgreSql.csproj", "{E3EA6449-28EC-48E4-91C4-E82DE08A7DD9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Elsa.Activities.Telnyx", "src\activities\Elsa.Activities.Telnyx\Elsa.Activities.Telnyx.csproj", "{93878BAD-855D-48D1-97ED-C776EC54E19E}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Activities.Telnyx", "src\activities\Elsa.Activities.Telnyx\Elsa.Activities.Telnyx.csproj", "{93878BAD-855D-48D1-97ED-C776EC54E19E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Elsa.Activities.Webhooks", "src\activities\Elsa.Activities.Webhooks\Elsa.Activities.Webhooks.csproj", "{2B67E954-3B04-402D-A9A7-AAAB1D6C3215}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -585,6 +587,10 @@ Global
{93878BAD-855D-48D1-97ED-C776EC54E19E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{93878BAD-855D-48D1-97ED-C776EC54E19E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{93878BAD-855D-48D1-97ED-C776EC54E19E}.Release|Any CPU.Build.0 = Release|Any CPU
{2B67E954-3B04-402D-A9A7-AAAB1D6C3215}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2B67E954-3B04-402D-A9A7-AAAB1D6C3215}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2B67E954-3B04-402D-A9A7-AAAB1D6C3215}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2B67E954-3B04-402D-A9A7-AAAB1D6C3215}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -701,6 +707,7 @@ Global
{346A3A87-A839-499A-A143-3D267A951905} = {22E75696-6FE9-436A-9097-EE21C603F818}
{E3EA6449-28EC-48E4-91C4-E82DE08A7DD9} = {C865B0FD-E505-48F0-BFAF-0D4D7C1B5CA1}
{93878BAD-855D-48D1-97ED-C776EC54E19E} = {B43B546E-23F3-46E8-ACB7-D04F05CDA180}
{2B67E954-3B04-402D-A9A7-AAAB1D6C3215} = {B43B546E-23F3-46E8-ACB7-D04F05CDA180}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {8B0975FD-7050-48B0-88C5-48C33378E158}

View file

@ -0,0 +1,92 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Elsa.Activities.Http;
using Elsa.Activities.Webhooks.Models;
using Elsa.Activities.Webhooks.Persistence;
using Elsa.ActivityProviders;
using Elsa.Design;
using Elsa.Metadata;
using Elsa.Persistence.Specifications;
using Elsa.Services;
using Elsa.Services.Models;
using Newtonsoft.Json.Linq;
namespace Elsa.Activities.Webhooks.ActivityTypes
{
public class WebhookActivityTypeProvider : IActivityTypeProvider
{
private const string WebhookActivityCategory = "Webhooks";
private readonly IWebhookDefinitionStore _webhookDefinitionStore;
private readonly IActivityActivator _activityActivator;
public WebhookActivityTypeProvider(
IWebhookDefinitionStore webhookDefinitionStore,
IActivityActivator activityActivator)
{
_webhookDefinitionStore = webhookDefinitionStore;
_activityActivator = activityActivator;
}
public async ValueTask<IEnumerable<ActivityType>> GetActivityTypesAsync(CancellationToken cancellationToken = default)
{
var specification = Specification<WebhookDefinition>.All;
var definitions = await _webhookDefinitionStore.FindManyAsync(specification, cancellationToken: cancellationToken);
var activityTypes = new List<ActivityType>();
foreach (var definition in definitions)
{
var activity = CreateWebhookActivityType(definition);
activityTypes.Add(activity);
}
return activityTypes;
}
private ActivityType CreateWebhookActivityType(WebhookDefinition webhook)
{
var typeName = webhook.Name;
var displayName = webhook.Name;
var descriptor = new ActivityDescriptor
{
Type = typeName,
DisplayName = displayName,
Category = WebhookActivityCategory,
Outcomes = new[] { OutcomeNames.Done },
Traits = ActivityTraits.Trigger,
Properties = new[]
{
new ActivityPropertyDescriptor(
"RequestMethod",
ActivityPropertyUIHints.Dropdown,
"Request Method",
"Specify what request method this webhook should handle. Leave empty to handle both GET and POST requests",
new[] { "", "GET", "POST" })
}
};
async ValueTask<IActivity> ActivateActivityAsync(ActivityExecutionContext context)
{
var activity = await _activityActivator.ActivateActivityAsync<HttpEndpoint>(context);
activity.Path = webhook.Path;
activity.ReadContent = true;
activity.TargetType = webhook.PayloadTypeName is not null and not "" ? Type.GetType(webhook.PayloadTypeName) : throw new Exception($"Type {webhook.PayloadTypeName} not found");
return activity;
}
return new ActivityType
{
TypeName = webhook.Name,
Type = typeof(HttpEndpoint),
Description = webhook.Description is not null and not "" ? webhook.Description : $"A webhook at {webhook.Path}",
DisplayName = webhook.Name,
ActivateAsync = ActivateActivityAsync,
Describe = () => descriptor
};
}
}
}

View file

@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\common.props" />
<Import Project="..\..\..\configureawait.props" />
<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<Description>
Elsa is a set of workflow libraries and tools that enable lean and mean workflowing capabilities in any .NET Core application.
This package provides the Webhooks activities.
</Description>
<PackageTags>elsa, workflows</PackageTags>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Refit" Version="5.2.4" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\core\Elsa.Core\Elsa.Core.csproj" />
<ProjectReference Include="..\Elsa.Activities.Http\Elsa.Activities.Http.csproj" />
</ItemGroup>
</Project>

View file

@ -0,0 +1,34 @@
using System;
using Elsa;
using Elsa.Activities.Webhooks;
using Elsa.Activities.Webhooks.ActivityTypes;
using Elsa.Activities.Webhooks.Options;
using Elsa.Activities.Webhooks.Persistence;
using Elsa.Activities.Webhooks.Persistence.Decorators;
// ReSharper disable once CheckNamespace
namespace Microsoft.Extensions.DependencyInjection
{
public static class ElsaOptionsExtensions
{
public static ElsaOptions AddWebhooks(
this ElsaOptions elsaOptions,
Action<WebhookOptions>? configure = default)
{
var services = elsaOptions.Services;
// Configure Webhooks.
var options = new WebhookOptions();
configure?.Invoke(options);
// Services.
services
.AddActivityTypeProvider<WebhookActivityTypeProvider>()
.AddScoped(options.WebhookDefinitionStoreFactory);
services.Decorate<IWebhookDefinitionStore, InitializingWebhookDefinitionStore>();
return elsaOptions;
}
}
}

View file

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait ContinueOnCapturedContext="false" />
</Weavers>

View file

@ -0,0 +1,19 @@
using System;
using Elsa.Models;
using Microsoft.AspNetCore.Http;
namespace Elsa.Activities.Webhooks.Models
{
public class WebhookDefinition : Entity, ITenantScope
{
public string Name { get; set; } = default!;
public PathString Path { get; set; }
public string? Description { get; set; }
public string? PayloadTypeName { get; set; }
public string? TenantId { get; set; }
}
}

View file

@ -0,0 +1,23 @@
using System;
using Elsa.Activities.Webhooks.Persistence;
using Elsa.Activities.Webhooks.Persistence.InMemory;
using Microsoft.Extensions.DependencyInjection;
namespace Elsa.Activities.Webhooks.Options
{
public class WebhookOptions
{
public WebhookOptions()
{
WebhookDefinitionStoreFactory = provider => ActivatorUtilities.CreateInstance<InMemoryWebhookStore>(provider);
}
internal Func<IServiceProvider, IWebhookDefinitionStore> WebhookDefinitionStoreFactory { get; set; }
public WebhookOptions UseWebhookDefinitionStore(Func<IServiceProvider, IWebhookDefinitionStore> factory)
{
WebhookDefinitionStoreFactory = factory;
return this;
}
}
}

View file

@ -0,0 +1,69 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Elsa.Models;
using Elsa.Persistence;
using Elsa.Persistence.Specifications;
using Elsa.Services;
namespace Elsa.Activities.Webhooks.Persistence.Decorators
{
public abstract class InitializingStoreBase<T> : IStore<T>
where T : IEntity
{
private readonly IStore<T> _store;
protected InitializingStoreBase(IStore<T> store, IIdGenerator idGenerator)
{
_store = store;
IdGenerator = idGenerator;
}
protected IIdGenerator IdGenerator { get; }
public async Task SaveAsync(T entity, CancellationToken cancellationToken)
{
entity = Initialize(entity);
await _store.SaveAsync(entity, cancellationToken);
}
public async Task UpdateAsync(T entity, CancellationToken cancellationToken)
{
entity = Initialize(entity);
await _store.UpdateAsync(entity, cancellationToken);
}
public async Task AddAsync(T entity, CancellationToken cancellationToken = default)
{
entity = Initialize(entity);
await _store.AddAsync(entity, cancellationToken);
}
public async Task AddManyAsync(IEnumerable<T> entities, CancellationToken cancellationToken = default)
{
var list = entities.ToList();
foreach (var entity in list)
Initialize(entity);
await _store.AddManyAsync(list, cancellationToken);
}
public Task DeleteAsync(T entity, CancellationToken cancellationToken) => _store.DeleteAsync(entity, cancellationToken);
public Task<int> DeleteManyAsync(ISpecification<T> specification, CancellationToken cancellationToken) => _store.DeleteManyAsync(specification, cancellationToken);
public Task<IEnumerable<T>> FindManyAsync(
ISpecification<T> specification,
IOrderBy<T>? orderBy,
IPaging? paging,
CancellationToken cancellationToken) =>
_store.FindManyAsync(specification, orderBy, paging, cancellationToken);
public Task<int> CountAsync(ISpecification<T> specification, CancellationToken cancellationToken) => _store.CountAsync(specification, cancellationToken);
public Task<T?> FindAsync(ISpecification<T> specification, CancellationToken cancellationToken) => _store.FindAsync(specification, cancellationToken);
protected abstract T Initialize(T entity);
}
}

View file

@ -0,0 +1,21 @@
using Elsa.Activities.Webhooks.Models;
using Elsa.Services;
namespace Elsa.Activities.Webhooks.Persistence.Decorators
{
public class InitializingWebhookDefinitionStore : InitializingStoreBase<WebhookDefinition>, IWebhookDefinitionStore
{
public InitializingWebhookDefinitionStore(IWebhookDefinitionStore store, IIdGenerator idGenerator)
: base(store, idGenerator)
{
}
protected override WebhookDefinition Initialize(WebhookDefinition webhookDefinition)
{
if (string.IsNullOrWhiteSpace(webhookDefinition.Id))
webhookDefinition.Id = IdGenerator.Generate();
return webhookDefinition;
}
}
}

View file

@ -0,0 +1,10 @@
using System;
using Elsa.Activities.Webhooks.Models;
using Elsa.Persistence;
namespace Elsa.Activities.Webhooks.Persistence
{
public interface IWebhookDefinitionStore : IStore<WebhookDefinition>
{
}
}

View file

@ -0,0 +1,14 @@
using Elsa.Activities.Webhooks.Models;
using Elsa.Persistence.InMemory;
using Elsa.Services;
using Microsoft.Extensions.Caching.Memory;
namespace Elsa.Activities.Webhooks.Persistence.InMemory
{
public class InMemoryWebhookStore : InMemoryStore<WebhookDefinition>, IWebhookDefinitionStore
{
public InMemoryWebhookStore(IMemoryCache memoryCache, IIdGenerator idGenerator) : base(memoryCache, idGenerator)
{
}
}
}

View file

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Elsa.Activities.Webhooks.Models;
using Refit;
namespace Elsa.Activities.Webhooks.Services
{
public interface IWebhookDefinitionsApi
{
[Get("/v1/webhook-definitions/{webhookDefinitionId}")]
Task<WebhookDefinition> GetByIdAsync(string webhookDefinitionId, CancellationToken cancellationToken = default);
[Get("/v1/webhook-definitions")]
Task<IEnumerable<WebhookDefinition>> ListAsync(CancellationToken cancellationToken = default);
}
}

View file

@ -20,4 +20,8 @@
<PackageReference Include="Refit.Newtonsoft.Json" Version="6.0.24" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\activities\Elsa.Activities.Webhooks\Elsa.Activities.Webhooks.csproj" />
</ItemGroup>
</Project>

View file

@ -1,20 +1,28 @@
using Elsa.Client.Services;
using Elsa.Activities.Webhooks.Services;
using Elsa.Client.Services;
namespace Elsa.Client
{
public class ElsaClient : IElsaClient
{
public ElsaClient(IActivitiesApi activities, IWorkflowDefinitionsApi workflowDefinitions, IWorkflowRegistryApi workflowRegistry, IWorkflowInstancesApi workflowInstances)
public ElsaClient(
IActivitiesApi activities,
IWorkflowDefinitionsApi workflowDefinitions,
IWorkflowRegistryApi workflowRegistry,
IWorkflowInstancesApi workflowInstances,
IWebhookDefinitionsApi webhookDefinitions)
{
Activities = activities;
WorkflowDefinitions = workflowDefinitions;
WorkflowRegistry = workflowRegistry;
WorkflowInstances = workflowInstances;
WebhookDefinitions = webhookDefinitions;
}
public IActivitiesApi Activities { get; }
public IWorkflowDefinitionsApi WorkflowDefinitions { get; }
public IWorkflowRegistryApi WorkflowRegistry { get; }
public IWorkflowInstancesApi WorkflowInstances { get; }
public IWebhookDefinitionsApi WebhookDefinitions { get; }
}
}

View file

@ -1,4 +1,5 @@
using Elsa.Client.Services;
using Elsa.Activities.Webhooks.Services;
using Elsa.Client.Services;
namespace Elsa.Client
{
@ -8,5 +9,6 @@ namespace Elsa.Client
IWorkflowDefinitionsApi WorkflowDefinitions { get; }
IWorkflowRegistryApi WorkflowRegistry { get; }
IWorkflowInstancesApi WorkflowInstances { get; }
IWebhookDefinitionsApi WebhookDefinitions { get; }
}
}

View file

@ -6,7 +6,7 @@ namespace Elsa.Metadata
{
}
public ActivityPropertyDescriptor(string name, string uiHint, string label, string? hint, object? options, string? category, object? defaultValue)
public ActivityPropertyDescriptor(string name, string uiHint, string label, string? hint = default, object? options = default, string? category = default, object? defaultValue = default)
{
Name = name;
UIHint = uiHint;

View file

@ -8,4 +8,9 @@ namespace Elsa.Services
{
Task<IActivity> ActivateActivityAsync(ActivityExecutionContext context, Type type);
}
public static class ActivityActivatorExtensions
{
public static async Task<T> ActivateActivityAsync<T>(this IActivityActivator activityActivator, ActivityExecutionContext context) where T : IActivity => (T) await activityActivator.ActivateActivityAsync(context, typeof(T));
}
}

View file

@ -1,4 +1,4 @@
using ElsaDashboard.Shared.Rpc;
using ElsaDashboard.Shared.Rpc;
using Microsoft.AspNetCore.Builder;
namespace ElsaDashboard.Backend.Extensions
@ -15,6 +15,7 @@ namespace ElsaDashboard.Backend.Extensions
.MapGrpcEndpoint<IWorkflowDefinitionService>()
.MapGrpcEndpoint<IWorkflowRegistryService>()
.MapGrpcEndpoint<IWorkflowInstanceService>()
.MapGrpcEndpoint<IWebhookDefinitionService>()
);
}
}

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.IO.Compression;
using Elsa.Client.Extensions;
using Elsa.Client.Options;
@ -24,6 +24,7 @@ namespace ElsaDashboard.Backend.Extensions
services.AddScoped<IWorkflowDefinitionService, WorkflowDefinitionService>();
services.AddScoped<IWorkflowRegistryService, WorkflowRegistryService>();
services.AddScoped<IWorkflowInstanceService, WorkflowInstanceService>();
services.AddScoped<IWebhookDefinitionService, WebhookDefinitionService>();
return services;
}

View file

@ -0,0 +1,25 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Elsa.Activities.Webhooks.Models;
using Elsa.Client;
using ElsaDashboard.Shared.Rpc;
using ProtoBuf.Grpc;
namespace ElsaDashboard.Backend.Rpc
{
public class WebhookDefinitionService : IWebhookDefinitionService
{
private readonly IElsaClient _elsaClient;
public WebhookDefinitionService(IElsaClient elsaClient)
{
_elsaClient = elsaClient;
}
public Task<IEnumerable<WebhookDefinition>> ListAsync(CallContext context = default) =>
_elsaClient.WebhookDefinitions.ListAsync(context.CancellationToken);
public Task<WebhookDefinition> GetByIdAsync(GetWebhookDefinitionByIdRequest request, CallContext context = default) =>
_elsaClient.WebhookDefinitions.GetByIdAsync(request.WebhookDefinitionId, context.CancellationToken);
}
}

View file

@ -0,0 +1,19 @@
using ProtoBuf;
namespace ElsaDashboard.Shared.Rpc
{
[ProtoContract]
public class GetWebhookDefinitionByIdRequest
{
public GetWebhookDefinitionByIdRequest()
{
}
public GetWebhookDefinitionByIdRequest(string webhookDefinitionId)
{
WebhookDefinitionId = webhookDefinitionId;
}
[ProtoMember(1)] public string WebhookDefinitionId { get; set; } = default!;
}
}

View file

@ -0,0 +1,18 @@
using System.Collections.Generic;
using System.Threading.Tasks;
using Elsa.Activities.Webhooks.Models;
using ProtoBuf.Grpc;
using ProtoBuf.Grpc.Configuration;
namespace ElsaDashboard.Shared.Rpc
{
[Service]
public interface IWebhookDefinitionService
{
[Operation]
Task<IEnumerable<WebhookDefinition>> ListAsync(CallContext context = default);
[Operation]
Task<WebhookDefinition> GetByIdAsync(GetWebhookDefinitionByIdRequest request, CallContext context = default);
}
}

View file

@ -4,6 +4,7 @@
<Import Project="..\..\..\..\configureawait.props" />
<PropertyGroup>
<GenerateMvcApplicationPartsAssemblyAttributes>false</GenerateMvcApplicationPartsAssemblyAttributes>
<TargetFramework>net5.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>

View file

@ -25,6 +25,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\activities\Elsa.Activities.Webhooks\Elsa.Activities.Webhooks.csproj" />
<ProjectReference Include="..\..\core\Elsa\Elsa.csproj" />
</ItemGroup>

View file

@ -0,0 +1,48 @@
using System.Net.Mime;
using System.Threading;
using System.Threading.Tasks;
using Elsa.Activities.Webhooks.Models;
using Elsa.Activities.Webhooks.Persistence;
using Elsa.Models;
using Elsa.Persistence.Specifications;
using Elsa.Serialization;
using Elsa.Server.Api.Swagger.Examples;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Swashbuckle.AspNetCore.Annotations;
using Swashbuckle.AspNetCore.Filters;
namespace Elsa.Server.Api.Endpoints.WebhookDefinitions
{
[ApiController]
[ApiVersion("1")]
[Route("v{apiVersion:apiVersion}/webhook-definitions/{webhookDefinitionId}")]
[Produces(MediaTypeNames.Application.Json)]
public class Get : Controller
{
private readonly IWebhookDefinitionStore _webhookDefinitionStore;
private readonly IContentSerializer _serializer;
public Get(IWebhookDefinitionStore webhookDefinitionStore, IContentSerializer serializer)
{
_webhookDefinitionStore = webhookDefinitionStore;
_serializer = serializer;
}
[HttpGet]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(WorkflowDefinition))]
[SwaggerResponseExample(StatusCodes.Status200OK, typeof(WorkflowDefinitionExample))]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[SwaggerOperation(
Summary = "Returns a single webhook definition.",
Description = "Returns a single webhook definition using the specified webhook definition ID.",
OperationId = "WebhookDefinitions.GetByDefinition",
Tags = new[] { "WebhookDefinitions" })
]
public async Task<IActionResult> Handle(string webhookDefinitionId, CancellationToken cancellationToken = default)
{
var webhookDefinition = await _webhookDefinitionStore.FindAsync(new EntityIdSpecification<WebhookDefinition>(webhookDefinitionId), cancellationToken);
return webhookDefinition == null ? (IActionResult) NotFound() : Json(webhookDefinition, _serializer.GetSettings());
}
}
}

View file

@ -0,0 +1,51 @@
using System.Collections.Generic;
using System.Net.Mime;
using System.Threading;
using System.Threading.Tasks;
using Elsa.Activities.Webhooks.Models;
using Elsa.Activities.Webhooks.Persistence;
using Elsa.Models;
using Elsa.Persistence.Specifications;
using Elsa.Serialization;
using Elsa.Server.Api.Models;
using Elsa.Server.Api.Swagger.Examples;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Swashbuckle.AspNetCore.Annotations;
using Swashbuckle.AspNetCore.Filters;
namespace Elsa.Server.Api.Endpoints.WebhookDefinitions
{
[ApiController]
[ApiVersion("1")]
[Route("v{apiVersion:apiVersion}/webhook-definitions")]
[Produces(MediaTypeNames.Application.Json)]
public class List : Controller
{
private readonly IWebhookDefinitionStore _webhookDefinitionStore;
private readonly IContentSerializer _serializer;
public List(IWebhookDefinitionStore webhookDefinitionStore, IContentSerializer serializer)
{
_webhookDefinitionStore = webhookDefinitionStore;
_serializer = serializer;
}
[HttpGet]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(IEnumerable<WebhookDefinition>))]
[SwaggerResponseExample(StatusCodes.Status200OK, typeof(WebhookDefinitionListExample))]
[SwaggerOperation(
Summary = "Returns a list of webhook definitions.",
Description = "Returns a list of webhook definitions.",
OperationId = "WebhookDefinitions.List",
Tags = new[] { "WebhookDefinitions" })
]
public async Task<ActionResult<PagedList<WorkflowDefinition>>> Handle(CancellationToken cancellationToken = default)
{
var specification = Specification<WebhookDefinition>.All;
var items = await _webhookDefinitionStore.FindManyAsync(specification, cancellationToken: cancellationToken);
return Json(items, _serializer.GetSettings());
}
}
}

View file

@ -0,0 +1,21 @@
using System;
using Elsa.Activities.Webhooks.Models;
using Swashbuckle.AspNetCore.Filters;
namespace Elsa.Server.Api.Swagger.Examples
{
public class WebhookDefinitionExample : IExamplesProvider<WebhookDefinition>
{
public WebhookDefinition GetExamples()
{
return new()
{
Id = Guid.NewGuid().ToString("N"),
Path = "/sample-path",
Description = "Sample description",
PayloadTypeName = "PayloadType",
TenantId = "tenant",
};
}
}
}

View file

@ -0,0 +1,16 @@
using System.Collections.Generic;
using System.Linq;
using Elsa.Activities.Webhooks.Models;
using Swashbuckle.AspNetCore.Filters;
namespace Elsa.Server.Api.Swagger.Examples
{
public class WebhookDefinitionListExample : IExamplesProvider<IEnumerable<WebhookDefinition>>
{
public IEnumerable<WebhookDefinition> GetExamples()
{
var result = Enumerable.Range(1, 3).Select(_ => new WebhookDefinitionExample().GetExamples()).ToList();
return result;
}
}
}