< Summary

Information
Class: Elsa.Http.ShellFeatures.HttpFeature
Assembly: Elsa.Http
File(s): /home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Http/ShellFeatures/HttpFeature.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 136
Coverable lines: 136
Total lines: 243
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 6
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

File(s)

/home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Http/ShellFeatures/HttpFeature.cs

#LineLine coverage
 1using CShells.AspNetCore.Features;
 2using CShells.Features;
 3using Elsa.Expressions.Options;
 4using Elsa.Extensions;
 5using Elsa.Http.Bookmarks;
 6using Elsa.Http.ContentWriters;
 7using Elsa.Http.DownloadableContentHandlers;
 8using Elsa.Http.FileCaches;
 9using Elsa.Http.Handlers;
 10using Elsa.Http.Middleware;
 11using Elsa.Http.Options;
 12using Elsa.Http.Parsers;
 13using Elsa.Http.PortResolvers;
 14using Elsa.Http.Resilience;
 15using Elsa.Http.Selectors;
 16using Elsa.Http.Services;
 17using Elsa.Http.Tasks;
 18using Elsa.Http.TriggerPayloadValidators;
 19using Elsa.Http.UIHints;
 20using Elsa.Resilience.Extensions;
 21using Elsa.Workflows;
 22using Elsa.Workflows.Management.Extensions;
 23using FluentStorage;
 24using JetBrains.Annotations;
 25using Microsoft.AspNetCore.Builder;
 26using Microsoft.AspNetCore.Http;
 27using Microsoft.AspNetCore.Routing;
 28using Microsoft.AspNetCore.StaticFiles;
 29using Microsoft.Extensions.DependencyInjection;
 30using Microsoft.Extensions.Hosting;
 31using Microsoft.Extensions.Options;
 32
 33namespace Elsa.Http.ShellFeatures;
 34
 35/// <summary>
 36/// Installs services related to HTTP services and activities.
 37/// </summary>
 38[ShellFeature(
 39    DisplayName = "HTTP",
 40    Description = "Provides HTTP-related activities and services for workflow execution",
 41    DependsOn = ["HttpJavaScript", "Resilience"])]
 42[UsedImplicitly]
 43public class HttpFeature : IMiddlewareShellFeature
 44{
 45    /// <summary>
 46    /// The <see cref="HttpActivityOptions"/> to configure.
 47    /// </summary>
 048    public HttpActivityOptions HttpActivityOptions { get; set; } = new();
 49
 50    /// <summary>
 51    /// A delegate to configure <see cref="HttpFileCacheOptions"/>.
 52    /// </summary>
 053    public Action<HttpFileCacheOptions>? ConfigureHttpFileCacheOptions { get; set; }
 54
 55    /// <summary>
 56    /// A delegate that is invoked when authorizing an inbound HTTP request.
 57    /// </summary>
 058    public Func<IServiceProvider, IHttpEndpointAuthorizationHandler> HttpEndpointAuthorizationHandler { get; set; } = sp
 59
 60    /// <summary>
 61    /// A delegate that is invoked when an HTTP workflow faults.
 62    /// </summary>
 063    public Func<IServiceProvider, IHttpEndpointFaultHandler> HttpEndpointWorkflowFaultHandler { get; set; } = sp => sp.G
 64
 65    /// <summary>
 66    /// A delegate to configure the <see cref="IContentTypeProvider"/>.
 67    /// </summary>
 068    public Func<IServiceProvider, IContentTypeProvider> ContentTypeProvider { get; set; } = _ => new FileExtensionConten
 69
 70    /// <summary>
 71    /// A delegate to configure the <see cref="IFileCacheStorageProvider"/>.
 72    /// </summary>
 073    public Func<IServiceProvider, IFileCacheStorageProvider> FileCache { get; set; } = sp =>
 074    {
 075        var options = sp.GetRequiredService<IOptions<HttpFileCacheOptions>>().Value;
 076        var blobStorage = StorageFactory.Blobs.DirectoryFiles(options.LocalCacheDirectory);
 077        return new BlobFileCacheStorageProvider(blobStorage);
 078    };
 79
 80    /// <summary>
 81    /// A delegate to configure the <see cref="HttpClient"/> used when by the <see cref="FlowSendHttpRequest"/> and <see
 82    /// </summary>
 083    public Action<IServiceProvider, HttpClient> HttpClient { get; set; } = (_, _) => { };
 84
 85    /// <summary>
 86    /// A delegate to configure the <see cref="HttpClientBuilder"/> for <see cref="HttpClient"/>.
 87    /// </summary>
 088    public Action<IHttpClientBuilder> HttpClientBuilder { get; set; } = _ => { };
 89
 90    /// <summary>
 91    /// A list of <see cref="IHttpCorrelationIdSelector"/> types to register with the service collection.
 92    /// </summary>
 093    public ICollection<Type> HttpCorrelationIdSelectorTypes { get; } = new List<Type>
 094    {
 095        typeof(HeaderHttpCorrelationIdSelector),
 096        typeof(QueryStringHttpCorrelationIdSelector)
 097    };
 98
 99    /// <summary>
 100    /// A list of <see cref="IHttpWorkflowInstanceIdSelector"/> types to register with the service collection.
 101    /// </summary>
 0102    public ICollection<Type> HttpWorkflowInstanceIdSelectorTypes { get; } = new List<Type>
 0103    {
 0104        typeof(HeaderHttpWorkflowInstanceIdSelector),
 0105        typeof(QueryStringHttpWorkflowInstanceIdSelector)
 0106    };
 107
 108    public void ConfigureServices(IServiceCollection services)
 109    {
 110        // Register HTTP activities.
 0111        services.AddActivitiesFrom<HttpFeature>();
 112
 113        // Register HTTP variable types.
 0114        services.AddVariableDescriptors([
 0115            new(typeof(HttpRouteData), "HTTP", null),
 0116            new(typeof(HttpRequest), "HTTP", null),
 0117            new(typeof(HttpResponse), "HTTP", null),
 0118            new(typeof(HttpResponseMessage), "HTTP", null),
 0119            new(typeof(HttpHeaders), "HTTP", null),
 0120            new(typeof(IFormFile), "HTTP", null),
 0121            new(typeof(HttpFile), "HTTP", null),
 0122            new(typeof(Downloadable), "HTTP", null),
 0123        ]);
 124
 125        // Register the HTTP resilience strategy.
 0126        services.AddResilienceStrategy<HttpResilienceStrategy>();
 127
 0128        var configureFileCacheOptions = ConfigureHttpFileCacheOptions ?? (options => { options.TimeToLive = TimeSpan.Fro
 129
 0130        services.Configure<HttpActivityOptions>(options =>
 0131        {
 0132            options.BasePath = HttpActivityOptions.BasePath;
 0133            options.BaseUrl = HttpActivityOptions.BaseUrl;
 0134            options.AvailableContentTypes = HttpActivityOptions.AvailableContentTypes;
 0135            options.WriteHttpResponseSynchronously = HttpActivityOptions.WriteHttpResponseSynchronously;
 0136        });
 137
 0138        services.Configure(configureFileCacheOptions);
 139
 0140        var httpClientBuilder = services.AddHttpClient<SendHttpRequestBase>(HttpClient);
 0141        HttpClientBuilder(httpClientBuilder);
 142
 0143        services
 0144            .AddScoped<IRouteMatcher, RouteMatcher>()
 0145            .AddScoped<IRouteTable, RouteTable>()
 0146            .AddScoped<IAbsoluteUrlProvider, DefaultAbsoluteUrlProvider>()
 0147            .AddScoped<IRouteTableUpdater, DefaultRouteTableUpdater>()
 0148            .AddScoped<IHttpWorkflowLookupService, HttpWorkflowLookupService>()
 0149            .AddScoped(ContentTypeProvider)
 0150            .AddHttpContextAccessor()
 0151
 0152            // Handlers.
 0153            .AddNotificationHandler<UpdateRouteTable>()
 0154
 0155            // Content parsers.
 0156            .AddSingleton<IHttpContentParser, JsonHttpContentParser>()
 0157            .AddSingleton<IHttpContentParser, XmlHttpContentParser>()
 0158            .AddSingleton<IHttpContentParser, PlainTextHttpContentParser>()
 0159            .AddSingleton<IHttpContentParser, TextHtmlHttpContentParser>()
 0160            .AddSingleton<IHttpContentParser, FileHttpContentParser>()
 0161
 0162            // HTTP content factories.
 0163            .AddScoped<IHttpContentFactory, TextContentFactory>()
 0164            .AddScoped<IHttpContentFactory, JsonContentFactory>()
 0165            .AddScoped<IHttpContentFactory, XmlContentFactory>()
 0166            .AddScoped<IHttpContentFactory, FormUrlEncodedHttpContentFactory>()
 0167
 0168            // Activity property options providers.
 0169            .AddScoped<IPropertyUIHandler, HttpContentTypeOptionsProvider>()
 0170            .AddScoped<IPropertyUIHandler, HttpEndpointPathUIHandler>()
 0171
 0172            // Default providers.
 0173            .AddScoped<DefaultHttpEndpointBasePathProvider>()
 0174            .AddScoped<IHttpEndpointBasePathProvider>(sp => sp.GetRequiredService<DefaultHttpEndpointBasePathProvider>()
 0175
 0176            // Port resolvers.
 0177            .AddScoped<IActivityResolver, SendHttpRequestActivityResolver>()
 0178
 0179            // HTTP endpoint handlers.
 0180            .AddScoped<AuthenticationBasedHttpEndpointAuthorizationHandler>()
 0181            .AddScoped<AllowAnonymousHttpEndpointAuthorizationHandler>()
 0182            .AddScoped<DefaultHttpEndpointFaultHandler>()
 0183            .AddScoped<DefaultHttpEndpointRoutesProvider>()
 0184            .AddScoped(HttpEndpointWorkflowFaultHandler)
 0185            .AddScoped(HttpEndpointAuthorizationHandler)
 0186            .AddScoped<IHttpEndpointRoutesProvider>(sp => sp.GetRequiredService<DefaultHttpEndpointRoutesProvider>())
 0187
 0188            // Startup tasks.
 0189            .AddStartupTask<UpdateRouteTableStartupTask>()
 0190
 0191            // Downloadable content handlers.
 0192            .AddScoped<IDownloadableManager, DefaultDownloadableManager>()
 0193            .AddScoped<IDownloadableContentHandler, MultiDownloadableContentHandler>()
 0194            .AddScoped<IDownloadableContentHandler, BinaryDownloadableContentHandler>()
 0195            .AddScoped<IDownloadableContentHandler, StreamDownloadableContentHandler>()
 0196            .AddScoped<IDownloadableContentHandler, FormFileDownloadableContentHandler>()
 0197            .AddScoped<IDownloadableContentHandler, DownloadableDownloadableContentHandler>()
 0198            .AddScoped<IDownloadableContentHandler, UrlDownloadableContentHandler>()
 0199            .AddScoped<IDownloadableContentHandler, StringDownloadableContentHandler>()
 0200            .AddScoped<IDownloadableContentHandler, HttpFileDownloadableContentHandler>()
 0201
 0202            //Trigger payload validators.
 0203            .AddTriggerPayloadValidator<HttpEndpointTriggerPayloadValidator, HttpEndpointBookmarkPayload>()
 0204
 0205            // File caches.
 0206            .AddScoped(FileCache)
 0207            .AddScoped<ZipManager>()
 0208
 0209            // AuthenticationBasedHttpEndpointAuthorizationHandler requires Authorization services.
 0210            .AddAuthorization();
 211
 212        // HTTP clients.
 0213        services.AddHttpClient<IFileDownloader, HttpClientFileDownloader>();
 214
 215        // Add selectors.
 0216        foreach (var httpCorrelationIdSelectorType in HttpCorrelationIdSelectorTypes)
 0217            services.AddScoped(typeof(IHttpCorrelationIdSelector), httpCorrelationIdSelectorType);
 218
 0219        foreach (var httpWorkflowInstanceIdSelectorType in HttpWorkflowInstanceIdSelectorTypes)
 0220            services.AddScoped(typeof(IHttpWorkflowInstanceIdSelector), httpWorkflowInstanceIdSelectorType);
 221
 0222        services.Configure<ExpressionOptions>(options =>
 0223        {
 0224            options.AddTypeAlias<HttpRequest>("HttpRequest");
 0225            options.AddTypeAlias<HttpResponse>("HttpResponse");
 0226            options.AddTypeAlias<HttpResponseMessage>("HttpResponseMessage");
 0227            options.AddTypeAlias<HttpHeaders>("HttpHeaders");
 0228            options.AddTypeAlias<HttpRouteData>("RouteData");
 0229            options.AddTypeAlias<IFormFile>("FormFile");
 0230            options.AddTypeAlias<IFormFile[]>("FormFile[]");
 0231            options.AddTypeAlias<HttpFile>("HttpFile");
 0232            options.AddTypeAlias<HttpFile[]>("HttpFile[]");
 0233            options.AddTypeAlias<Downloadable>("Downloadable");
 0234            options.AddTypeAlias<Downloadable[]>("Downloadable[]");
 0235        });
 0236    }
 237
 238    /// <inheritdoc />
 239    public void UseMiddleware(IApplicationBuilder app, IHostEnvironment? environment)
 240    {
 0241        app.UseWorkflows();
 0242    }
 243}