* 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:
parent
58648339c8
commit
caf15ecc70
9
Elsa.sln
9
Elsa.sln
|
|
@ -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}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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>
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
3
src/activities/Elsa.Activities.Webhooks/FodyWeavers.xml
Normal file
3
src/activities/Elsa.Activities.Webhooks/FodyWeavers.xml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
|
||||
<ConfigureAwait ContinueOnCapturedContext="false" />
|
||||
</Weavers>
|
||||
|
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
using System;
|
||||
using Elsa.Activities.Webhooks.Models;
|
||||
using Elsa.Persistence;
|
||||
|
||||
namespace Elsa.Activities.Webhooks.Persistence
|
||||
{
|
||||
public interface IWebhookDefinitionStore : IStore<WebhookDefinition>
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
@ -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>()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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!;
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@
|
|||
<Import Project="..\..\..\..\configureawait.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<GenerateMvcApplicationPartsAssemblyAttributes>false</GenerateMvcApplicationPartsAssemblyAttributes>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\activities\Elsa.Activities.Webhooks\Elsa.Activities.Webhooks.csproj" />
|
||||
<ProjectReference Include="..\..\core\Elsa\Elsa.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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",
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue