< 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: 241
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.Options;
 11using Elsa.Http.Parsers;
 12using Elsa.Http.PortResolvers;
 13using Elsa.Http.Resilience;
 14using Elsa.Http.Selectors;
 15using Elsa.Http.Services;
 16using Elsa.Http.Tasks;
 17using Elsa.Http.TriggerPayloadValidators;
 18using Elsa.Http.UIHints;
 19using Elsa.Resilience.Extensions;
 20using Elsa.Workflows;
 21using Elsa.Workflows.Management.Extensions;
 22using FluentStorage;
 23using JetBrains.Annotations;
 24using Microsoft.AspNetCore.Builder;
 25using Microsoft.AspNetCore.Http;
 26using Microsoft.AspNetCore.StaticFiles;
 27using Microsoft.Extensions.DependencyInjection;
 28using Microsoft.Extensions.Hosting;
 29using Microsoft.Extensions.Options;
 30
 31namespace Elsa.Http.ShellFeatures;
 32
 33/// <summary>
 34/// Installs services related to HTTP services and activities.
 35/// </summary>
 36[ShellFeature(
 37    DisplayName = "HTTP",
 38    Description = "Provides HTTP-related activities and services for workflow execution",
 39    DependsOn = ["HttpJavaScript", "Resilience"])]
 40[UsedImplicitly]
 41public class HttpFeature : IMiddlewareShellFeature
 42{
 43    /// <summary>
 44    /// The <see cref="HttpActivityOptions"/> to configure.
 45    /// </summary>
 046    public HttpActivityOptions HttpActivityOptions { get; set; } = new();
 47
 48    /// <summary>
 49    /// A delegate to configure <see cref="HttpFileCacheOptions"/>.
 50    /// </summary>
 051    public Action<HttpFileCacheOptions>? ConfigureHttpFileCacheOptions { get; set; }
 52
 53    /// <summary>
 54    /// A delegate that is invoked when authorizing an inbound HTTP request.
 55    /// </summary>
 056    public Func<IServiceProvider, IHttpEndpointAuthorizationHandler> HttpEndpointAuthorizationHandler { get; set; } = sp
 57
 58    /// <summary>
 59    /// A delegate that is invoked when an HTTP workflow faults.
 60    /// </summary>
 061    public Func<IServiceProvider, IHttpEndpointFaultHandler> HttpEndpointWorkflowFaultHandler { get; set; } = sp => sp.G
 62
 63    /// <summary>
 64    /// A delegate to configure the <see cref="IContentTypeProvider"/>.
 65    /// </summary>
 066    public Func<IServiceProvider, IContentTypeProvider> ContentTypeProvider { get; set; } = _ => new FileExtensionConten
 67
 68    /// <summary>
 69    /// A delegate to configure the <see cref="IFileCacheStorageProvider"/>.
 70    /// </summary>
 071    public Func<IServiceProvider, IFileCacheStorageProvider> FileCache { get; set; } = sp =>
 072    {
 073        var options = sp.GetRequiredService<IOptions<HttpFileCacheOptions>>().Value;
 074        var blobStorage = StorageFactory.Blobs.DirectoryFiles(options.LocalCacheDirectory);
 075        return new BlobFileCacheStorageProvider(blobStorage);
 076    };
 77
 78    /// <summary>
 79    /// A delegate to configure the <see cref="HttpClient"/> used when by the <see cref="FlowSendHttpRequest"/> and <see
 80    /// </summary>
 081    public Action<IServiceProvider, HttpClient> HttpClient { get; set; } = (_, _) => { };
 82
 83    /// <summary>
 84    /// A delegate to configure the <see cref="HttpClientBuilder"/> for <see cref="HttpClient"/>.
 85    /// </summary>
 086    public Action<IHttpClientBuilder> HttpClientBuilder { get; set; } = _ => { };
 87
 88    /// <summary>
 89    /// A list of <see cref="IHttpCorrelationIdSelector"/> types to register with the service collection.
 90    /// </summary>
 091    public ICollection<Type> HttpCorrelationIdSelectorTypes { get; } = new List<Type>
 092    {
 093        typeof(HeaderHttpCorrelationIdSelector),
 094        typeof(QueryStringHttpCorrelationIdSelector)
 095    };
 96
 97    /// <summary>
 98    /// A list of <see cref="IHttpWorkflowInstanceIdSelector"/> types to register with the service collection.
 99    /// </summary>
 0100    public ICollection<Type> HttpWorkflowInstanceIdSelectorTypes { get; } = new List<Type>
 0101    {
 0102        typeof(HeaderHttpWorkflowInstanceIdSelector),
 0103        typeof(QueryStringHttpWorkflowInstanceIdSelector)
 0104    };
 105
 106    public void ConfigureServices(IServiceCollection services)
 107    {
 108        // Register HTTP activities.
 0109        services.AddActivitiesFrom<HttpFeature>();
 110
 111        // Register HTTP variable types.
 0112        services.AddVariableDescriptors([
 0113            new(typeof(HttpRouteData), "HTTP", null),
 0114            new(typeof(HttpRequest), "HTTP", null),
 0115            new(typeof(HttpResponse), "HTTP", null),
 0116            new(typeof(HttpResponseMessage), "HTTP", null),
 0117            new(typeof(HttpHeaders), "HTTP", null),
 0118            new(typeof(IFormFile), "HTTP", null),
 0119            new(typeof(HttpFile), "HTTP", null),
 0120            new(typeof(Downloadable), "HTTP", null),
 0121        ]);
 122
 123        // Register the HTTP resilience strategy.
 0124        services.AddResilienceStrategy<HttpResilienceStrategy>();
 125
 0126        var configureFileCacheOptions = ConfigureHttpFileCacheOptions ?? (options => { options.TimeToLive = TimeSpan.Fro
 127
 0128        services.Configure<HttpActivityOptions>(options =>
 0129        {
 0130            options.BasePath = HttpActivityOptions.BasePath;
 0131            options.BaseUrl = HttpActivityOptions.BaseUrl;
 0132            options.AvailableContentTypes = HttpActivityOptions.AvailableContentTypes;
 0133            options.WriteHttpResponseSynchronously = HttpActivityOptions.WriteHttpResponseSynchronously;
 0134        });
 135
 0136        services.Configure(configureFileCacheOptions);
 137
 0138        var httpClientBuilder = services.AddHttpClient<SendHttpRequestBase>(HttpClient);
 0139        HttpClientBuilder(httpClientBuilder);
 140
 0141        services
 0142            .AddScoped<IRouteMatcher, RouteMatcher>()
 0143            .AddScoped<IRouteTable, RouteTable>()
 0144            .AddScoped<IAbsoluteUrlProvider, DefaultAbsoluteUrlProvider>()
 0145            .AddScoped<IRouteTableUpdater, DefaultRouteTableUpdater>()
 0146            .AddScoped<IHttpWorkflowLookupService, HttpWorkflowLookupService>()
 0147            .AddScoped(ContentTypeProvider)
 0148            .AddHttpContextAccessor()
 0149
 0150            // Handlers.
 0151            .AddNotificationHandler<UpdateRouteTable>()
 0152
 0153            // Content parsers.
 0154            .AddSingleton<IHttpContentParser, JsonHttpContentParser>()
 0155            .AddSingleton<IHttpContentParser, XmlHttpContentParser>()
 0156            .AddSingleton<IHttpContentParser, PlainTextHttpContentParser>()
 0157            .AddSingleton<IHttpContentParser, TextHtmlHttpContentParser>()
 0158            .AddSingleton<IHttpContentParser, FileHttpContentParser>()
 0159
 0160            // HTTP content factories.
 0161            .AddScoped<IHttpContentFactory, TextContentFactory>()
 0162            .AddScoped<IHttpContentFactory, JsonContentFactory>()
 0163            .AddScoped<IHttpContentFactory, XmlContentFactory>()
 0164            .AddScoped<IHttpContentFactory, FormUrlEncodedHttpContentFactory>()
 0165
 0166            // Activity property options providers.
 0167            .AddScoped<IPropertyUIHandler, HttpContentTypeOptionsProvider>()
 0168            .AddScoped<IPropertyUIHandler, HttpEndpointPathUIHandler>()
 0169
 0170            // Default providers.
 0171            .AddScoped<DefaultHttpEndpointBasePathProvider>()
 0172            .AddScoped<IHttpEndpointBasePathProvider>(sp => sp.GetRequiredService<DefaultHttpEndpointBasePathProvider>()
 0173
 0174            // Port resolvers.
 0175            .AddScoped<IActivityResolver, SendHttpRequestActivityResolver>()
 0176
 0177            // HTTP endpoint handlers.
 0178            .AddScoped<AuthenticationBasedHttpEndpointAuthorizationHandler>()
 0179            .AddScoped<AllowAnonymousHttpEndpointAuthorizationHandler>()
 0180            .AddScoped<DefaultHttpEndpointFaultHandler>()
 0181            .AddScoped<DefaultHttpEndpointRoutesProvider>()
 0182            .AddScoped(HttpEndpointWorkflowFaultHandler)
 0183            .AddScoped(HttpEndpointAuthorizationHandler)
 0184            .AddScoped<IHttpEndpointRoutesProvider>(sp => sp.GetRequiredService<DefaultHttpEndpointRoutesProvider>())
 0185
 0186            // Startup tasks.
 0187            .AddStartupTask<UpdateRouteTableStartupTask>()
 0188
 0189            // Downloadable content handlers.
 0190            .AddScoped<IDownloadableManager, DefaultDownloadableManager>()
 0191            .AddScoped<IDownloadableContentHandler, MultiDownloadableContentHandler>()
 0192            .AddScoped<IDownloadableContentHandler, BinaryDownloadableContentHandler>()
 0193            .AddScoped<IDownloadableContentHandler, StreamDownloadableContentHandler>()
 0194            .AddScoped<IDownloadableContentHandler, FormFileDownloadableContentHandler>()
 0195            .AddScoped<IDownloadableContentHandler, DownloadableDownloadableContentHandler>()
 0196            .AddScoped<IDownloadableContentHandler, UrlDownloadableContentHandler>()
 0197            .AddScoped<IDownloadableContentHandler, StringDownloadableContentHandler>()
 0198            .AddScoped<IDownloadableContentHandler, HttpFileDownloadableContentHandler>()
 0199
 0200            //Trigger payload validators.
 0201            .AddTriggerPayloadValidator<HttpEndpointTriggerPayloadValidator, HttpEndpointBookmarkPayload>()
 0202
 0203            // File caches.
 0204            .AddScoped(FileCache)
 0205            .AddScoped<ZipManager>()
 0206
 0207            // AuthenticationBasedHttpEndpointAuthorizationHandler requires Authorization services.
 0208            .AddAuthorization();
 209
 210        // HTTP clients.
 0211        services.AddHttpClient<IFileDownloader, HttpClientFileDownloader>();
 212
 213        // Add selectors.
 0214        foreach (var httpCorrelationIdSelectorType in HttpCorrelationIdSelectorTypes)
 0215            services.AddScoped(typeof(IHttpCorrelationIdSelector), httpCorrelationIdSelectorType);
 216
 0217        foreach (var httpWorkflowInstanceIdSelectorType in HttpWorkflowInstanceIdSelectorTypes)
 0218            services.AddScoped(typeof(IHttpWorkflowInstanceIdSelector), httpWorkflowInstanceIdSelectorType);
 219
 0220        services.Configure<ExpressionOptions>(options =>
 0221        {
 0222            options.AddTypeAlias<HttpRequest>("HttpRequest");
 0223            options.AddTypeAlias<HttpResponse>("HttpResponse");
 0224            options.AddTypeAlias<HttpResponseMessage>("HttpResponseMessage");
 0225            options.AddTypeAlias<HttpHeaders>("HttpHeaders");
 0226            options.AddTypeAlias<HttpRouteData>("RouteData");
 0227            options.AddTypeAlias<IFormFile>("FormFile");
 0228            options.AddTypeAlias<IFormFile[]>("FormFile[]");
 0229            options.AddTypeAlias<HttpFile>("HttpFile");
 0230            options.AddTypeAlias<HttpFile[]>("HttpFile[]");
 0231            options.AddTypeAlias<Downloadable>("Downloadable");
 0232            options.AddTypeAlias<Downloadable[]>("Downloadable[]");
 0233        });
 0234    }
 235
 236    /// <inheritdoc />
 237    public void UseMiddleware(IApplicationBuilder app, IHostEnvironment? environment)
 238    {
 0239        app.UseWorkflows();
 0240    }
 241}