2020-10-17 10:49:41 +00:00
|
|
|
using System.Linq;
|
2020-10-30 20:55:27 +00:00
|
|
|
using System.Net;
|
2021-01-29 15:16:45 +00:00
|
|
|
using System.Threading;
|
2020-10-17 07:15:46 +00:00
|
|
|
using System.Threading.Tasks;
|
2021-01-29 15:16:45 +00:00
|
|
|
using Elsa.Activities.Http.Bookmarks;
|
2020-10-30 20:55:27 +00:00
|
|
|
using Elsa.Activities.Http.Extensions;
|
2021-01-29 15:16:45 +00:00
|
|
|
using Elsa.Bookmarks;
|
2021-01-30 11:47:50 +00:00
|
|
|
using Elsa.Models;
|
2020-12-11 20:35:22 +00:00
|
|
|
using Elsa.Persistence;
|
2021-01-30 11:47:50 +00:00
|
|
|
using Elsa.Serialization;
|
2020-10-17 10:49:41 +00:00
|
|
|
using Elsa.Services;
|
2021-03-04 10:47:20 +00:00
|
|
|
using Elsa.Triggers;
|
2020-10-17 07:15:46 +00:00
|
|
|
using Microsoft.AspNetCore.Http;
|
2020-10-30 20:55:27 +00:00
|
|
|
using Open.Linq.AsyncExtensions;
|
2020-10-17 07:15:46 +00:00
|
|
|
|
|
|
|
|
namespace Elsa.Activities.Http.Middleware
|
|
|
|
|
{
|
2021-03-04 10:47:20 +00:00
|
|
|
public class HttpEndpointMiddleware
|
2020-10-17 07:15:46 +00:00
|
|
|
{
|
2021-03-30 07:58:00 +00:00
|
|
|
// TODO: Design multi-tenancy.
|
2021-01-29 15:16:45 +00:00
|
|
|
private const string TenantId = default;
|
2020-10-17 07:15:46 +00:00
|
|
|
private readonly RequestDelegate _next;
|
|
|
|
|
|
2021-03-31 12:18:37 +00:00
|
|
|
public HttpEndpointMiddleware(RequestDelegate next) => _next = next;
|
2020-10-17 07:15:46 +00:00
|
|
|
|
2021-03-31 12:18:37 +00:00
|
|
|
public async Task InvokeAsync(HttpContext httpContext, ITriggersWorkflows triggersWorkflows, IContentSerializer contentSerializer)
|
2020-10-17 07:15:46 +00:00
|
|
|
{
|
2021-03-04 10:47:20 +00:00
|
|
|
var path = httpContext.Request.Path.Value.ToLowerInvariant();
|
|
|
|
|
var method = httpContext.Request.Method!.ToLowerInvariant();
|
2020-10-17 11:51:27 +00:00
|
|
|
var cancellationToken = httpContext.RequestAborted;
|
2020-10-30 20:55:27 +00:00
|
|
|
httpContext.Request.TryGetCorrelationId(out var correlationId);
|
2020-10-17 13:38:27 +00:00
|
|
|
|
2021-03-31 12:18:37 +00:00
|
|
|
const string activityType = nameof(HttpEndpoint);
|
|
|
|
|
var trigger = new HttpEndpointBookmark(path, method, null);
|
|
|
|
|
var bookmark = new HttpEndpointBookmark(path, method, correlationId?.ToLowerInvariant());
|
|
|
|
|
var workflowInstances = await triggersWorkflows.TriggerWorkflowsAsync(activityType, bookmark, trigger, correlationId, tenantId: TenantId, cancellationToken: cancellationToken).ToList();
|
2021-01-29 15:16:45 +00:00
|
|
|
|
2021-03-31 12:18:37 +00:00
|
|
|
if (!workflowInstances.Any())
|
2020-10-30 20:55:27 +00:00
|
|
|
{
|
2020-10-17 10:49:41 +00:00
|
|
|
await _next(httpContext);
|
2020-10-30 20:55:27 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2021-03-31 12:18:37 +00:00
|
|
|
|
|
|
|
|
foreach (var workflowInstance in workflowInstances)
|
2021-01-30 11:47:50 +00:00
|
|
|
await HandleWorkflowInstanceResponseAsync(httpContext, workflowInstance, contentSerializer, cancellationToken);
|
|
|
|
|
}
|
2020-10-30 20:55:27 +00:00
|
|
|
|
2021-01-30 11:47:50 +00:00
|
|
|
private async Task HandleWorkflowInstanceResponseAsync(HttpContext httpContext, WorkflowInstance workflowInstance, IContentSerializer contentSerializer, CancellationToken cancellationToken)
|
|
|
|
|
{
|
|
|
|
|
if (workflowInstance.WorkflowStatus == WorkflowStatus.Faulted)
|
|
|
|
|
{
|
2021-04-04 13:17:40 +00:00
|
|
|
if (httpContext.Response.HasStarted)
|
|
|
|
|
return;
|
|
|
|
|
|
2021-01-30 11:47:50 +00:00
|
|
|
httpContext.Response.StatusCode = (int) HttpStatusCode.InternalServerError;
|
|
|
|
|
httpContext.Response.ContentType = "application/json";
|
|
|
|
|
|
|
|
|
|
var model = new
|
|
|
|
|
{
|
|
|
|
|
WorkflowInstanceId = workflowInstance.Id,
|
|
|
|
|
WorkflowStatus = workflowInstance.WorkflowStatus,
|
|
|
|
|
Fault = workflowInstance.Fault
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
await httpContext.Response.WriteAsync(contentSerializer.Serialize(model), cancellationToken);
|
|
|
|
|
}
|
2021-01-29 15:16:45 +00:00
|
|
|
}
|
2020-10-17 07:15:46 +00:00
|
|
|
}
|
|
|
|
|
}
|