< 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: 139
Coverable lines: 139
Total lines: 250
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 System.Net;
 2using CShells.AspNetCore.Features;
 3using CShells.Features;
 4using Elsa.Common.Serialization;
 5using Elsa.Extensions;
 6using Elsa.Http.Bookmarks;
 7using Elsa.Http.ContentWriters;
 8using Elsa.Http.DownloadableContentHandlers;
 9using Elsa.Http.FileCaches;
 10using Elsa.Http.Handlers;
 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.Resilience.ShellFeatures;
 22using Elsa.Workflows.Management.Extensions;
 23using Elsa.Workflows.Options;
 24using Elsa.Workflows;
 25using Elsa.Platform.PackageManifest.Generator.Hints;
 26using FluentStorage;
 27using JetBrains.Annotations;
 28using Microsoft.AspNetCore.Builder;
 29using Microsoft.AspNetCore.Http;
 30using Microsoft.AspNetCore.StaticFiles;
 31using Microsoft.Extensions.DependencyInjection;
 32using Microsoft.Extensions.Hosting;
 33using Microsoft.Extensions.Options;
 34
 35namespace Elsa.Http.ShellFeatures;
 36
 37/// <summary>
 38/// Installs services related to HTTP services and activities.
 39/// </summary>
 40[ManifestFeatureCategory("HTTP")]
 41[ManifestFeatureCategory("Workflows")]
 42[ShellFeature(
 43    DisplayName = "HTTP",
 44    Description = "Provides HTTP-related activities and services for workflow execution",
 45    DependsOn = [typeof(HttpJavaScriptFeature), typeof(ResilienceFeature)])]
 46[UsedImplicitly]
 47public class HttpFeature : IMiddlewareShellFeature
 48{
 49    /// <summary>
 50    /// The <see cref="HttpActivityOptions"/> to configure.
 51    /// </summary>
 052    public HttpActivityOptions HttpActivityOptions { get; set; } = new();
 53
 54    /// <summary>
 55    /// A delegate to configure <see cref="HttpFileCacheOptions"/>.
 56    /// </summary>
 057    public Action<HttpFileCacheOptions>? ConfigureHttpFileCacheOptions { get; set; }
 58
 59    /// <summary>
 60    /// A delegate that is invoked when authorizing an inbound HTTP request.
 61    /// </summary>
 062    public Func<IServiceProvider, IHttpEndpointAuthorizationHandler> HttpEndpointAuthorizationHandler { get; set; } = sp
 63
 64    /// <summary>
 65    /// A delegate that is invoked when an HTTP workflow faults.
 66    /// </summary>
 067    public Func<IServiceProvider, IHttpEndpointFaultHandler> HttpEndpointWorkflowFaultHandler { get; set; } = sp => sp.G
 68
 69    /// <summary>
 70    /// A delegate to configure the <see cref="IContentTypeProvider"/>.
 71    /// </summary>
 072    public Func<IServiceProvider, IContentTypeProvider> ContentTypeProvider { get; set; } = _ => new FileExtensionConten
 73
 74    /// <summary>
 75    /// A delegate to configure the <see cref="IFileCacheStorageProvider"/>.
 76    /// </summary>
 077    public Func<IServiceProvider, IFileCacheStorageProvider> FileCache { get; set; } = sp =>
 078    {
 079        var options = sp.GetRequiredService<IOptions<HttpFileCacheOptions>>().Value;
 080        var blobStorage = StorageFactory.Blobs.DirectoryFiles(options.LocalCacheDirectory);
 081        return new BlobFileCacheStorageProvider(blobStorage);
 082    };
 83
 84    /// <summary>
 85    /// A delegate to configure the <see cref="HttpClient"/> used when by the <see cref="FlowSendHttpRequest"/> and <see
 86    /// </summary>
 087    public Action<IServiceProvider, HttpClient> HttpClient { get; set; } = (_, _) => { };
 88
 89    /// <summary>
 90    /// A delegate to configure the <see cref="HttpClientBuilder"/> for <see cref="HttpClient"/>.
 91    /// </summary>
 092    public Action<IHttpClientBuilder> HttpClientBuilder { get; set; } = _ => { };
 93
 94    /// <summary>
 95    /// A list of <see cref="IHttpCorrelationIdSelector"/> types to register with the service collection.
 96    /// </summary>
 097    public ICollection<Type> HttpCorrelationIdSelectorTypes { get; } = new List<Type>
 098    {
 099        typeof(HeaderHttpCorrelationIdSelector),
 0100        typeof(QueryStringHttpCorrelationIdSelector)
 0101    };
 102
 103    /// <summary>
 104    /// A list of <see cref="IHttpWorkflowInstanceIdSelector"/> types to register with the service collection.
 105    /// </summary>
 0106    public ICollection<Type> HttpWorkflowInstanceIdSelectorTypes { get; } = new List<Type>
 0107    {
 0108        typeof(HeaderHttpWorkflowInstanceIdSelector),
 0109        typeof(QueryStringHttpWorkflowInstanceIdSelector)
 0110    };
 111
 112    public void ConfigureServices(IServiceCollection services)
 113    {
 114        // Register HTTP activities.
 0115        services.AddActivitiesFrom<HttpFeature>();
 116
 117        // Register HTTP variable types.
 0118        services.AddVariableDescriptors([
 0119            new(typeof(HttpRouteData), "HTTP", null),
 0120            new(typeof(HttpRequest), "HTTP", null),
 0121            new(typeof(HttpResponse), "HTTP", null),
 0122            new(typeof(HttpResponseMessage), "HTTP", null),
 0123            new(typeof(HttpHeaders), "HTTP", null),
 0124            new(typeof(IFormFile), "HTTP", null),
 0125            new(typeof(HttpFile), "HTTP", null),
 0126            new(typeof(Downloadable), "HTTP", null),
 0127        ]);
 128
 129        // Register the HTTP resilience strategy.
 0130        services.AddResilienceStrategy<HttpResilienceStrategy>();
 131
 0132        var configureFileCacheOptions = ConfigureHttpFileCacheOptions ?? (options => { options.TimeToLive = TimeSpan.Fro
 133
 0134        services.Configure<HttpActivityOptions>(options =>
 0135        {
 0136            options.BasePath = HttpActivityOptions.BasePath;
 0137            options.BaseUrl = HttpActivityOptions.BaseUrl;
 0138            options.AvailableContentTypes = HttpActivityOptions.AvailableContentTypes;
 0139            options.WriteHttpResponseSynchronously = HttpActivityOptions.WriteHttpResponseSynchronously;
 0140        });
 141
 0142        services.Configure(configureFileCacheOptions);
 143
 0144        var httpClientBuilder = services.AddHttpClient<SendHttpRequestBase>(HttpClient);
 0145        HttpClientBuilder(httpClientBuilder);
 146
 0147        services
 0148            .AddScoped<IRouteMatcher, RouteMatcher>()
 0149            .AddScoped<IRouteTable, RouteTable>()
 0150            .AddScoped<IAbsoluteUrlProvider, DefaultAbsoluteUrlProvider>()
 0151            .AddScoped<IRouteTableUpdater, DefaultRouteTableUpdater>()
 0152            .AddScoped<IHttpWorkflowLookupService, HttpWorkflowLookupService>()
 0153            .AddScoped(ContentTypeProvider)
 0154            .AddHttpContextAccessor()
 0155
 0156            // Handlers.
 0157            .AddNotificationHandler<UpdateRouteTable>()
 0158
 0159            // Content parsers.
 0160            .AddSingleton<IHttpContentParser, JsonHttpContentParser>()
 0161            .AddSingleton<IHttpContentParser, XmlHttpContentParser>()
 0162            .AddSingleton<IHttpContentParser, PlainTextHttpContentParser>()
 0163            .AddSingleton<IHttpContentParser, TextHtmlHttpContentParser>()
 0164            .AddSingleton<IHttpContentParser, FileHttpContentParser>()
 0165
 0166            // HTTP content factories.
 0167            .AddScoped<IHttpContentFactory, TextContentFactory>()
 0168            .AddScoped<IHttpContentFactory, JsonContentFactory>()
 0169            .AddScoped<IHttpContentFactory, XmlContentFactory>()
 0170            .AddScoped<IHttpContentFactory, FormUrlEncodedHttpContentFactory>()
 0171
 0172            // Activity property options providers.
 0173            .AddScoped<IPropertyUIHandler, HttpContentTypeOptionsProvider>()
 0174            .AddScoped<IPropertyUIHandler, HttpEndpointPathUIHandler>()
 0175
 0176            // Default providers.
 0177            .AddScoped<DefaultHttpEndpointBasePathProvider>()
 0178            .AddScoped<IHttpEndpointBasePathProvider>(sp => sp.GetRequiredService<DefaultHttpEndpointBasePathProvider>()
 0179
 0180            // Port resolvers.
 0181            .AddScoped<IActivityResolver, SendHttpRequestActivityResolver>()
 0182
 0183            // HTTP endpoint handlers.
 0184            .AddScoped<AuthenticationBasedHttpEndpointAuthorizationHandler>()
 0185            .AddScoped<AllowAnonymousHttpEndpointAuthorizationHandler>()
 0186            .AddScoped<DefaultHttpEndpointFaultHandler>()
 0187            .AddScoped<DefaultHttpEndpointRoutesProvider>()
 0188            .AddScoped(HttpEndpointWorkflowFaultHandler)
 0189            .AddScoped(HttpEndpointAuthorizationHandler)
 0190            .AddScoped<IHttpEndpointRoutesProvider>(sp => sp.GetRequiredService<DefaultHttpEndpointRoutesProvider>())
 0191
 0192            // Startup tasks.
 0193            .AddStartupTask<UpdateRouteTableStartupTask>()
 0194
 0195            // Downloadable content handlers.
 0196            .AddScoped<IDownloadableManager, DefaultDownloadableManager>()
 0197            .AddScoped<IDownloadableContentHandler, MultiDownloadableContentHandler>()
 0198            .AddScoped<IDownloadableContentHandler, BinaryDownloadableContentHandler>()
 0199            .AddScoped<IDownloadableContentHandler, StreamDownloadableContentHandler>()
 0200            .AddScoped<IDownloadableContentHandler, FormFileDownloadableContentHandler>()
 0201            .AddScoped<IDownloadableContentHandler, DownloadableDownloadableContentHandler>()
 0202            .AddScoped<IDownloadableContentHandler, UrlDownloadableContentHandler>()
 0203            .AddScoped<IDownloadableContentHandler, StringDownloadableContentHandler>()
 0204            .AddScoped<IDownloadableContentHandler, HttpFileDownloadableContentHandler>()
 0205
 0206            //Trigger payload validators.
 0207            .AddTriggerPayloadValidator<HttpEndpointTriggerPayloadValidator, HttpEndpointBookmarkPayload>()
 0208
 0209            // File caches.
 0210            .AddScoped(FileCache)
 0211            .AddScoped<ZipManager>()
 0212
 0213            // AuthenticationBasedHttpEndpointAuthorizationHandler requires Authorization services.
 0214            .AddAuthorization();
 215
 216        // HTTP clients.
 0217        services.AddHttpClient<IFileDownloader, HttpClientFileDownloader>();
 218
 219        // Add selectors.
 0220        foreach (var httpCorrelationIdSelectorType in HttpCorrelationIdSelectorTypes)
 0221            services.AddScoped(typeof(IHttpCorrelationIdSelector), httpCorrelationIdSelectorType);
 222
 0223        foreach (var httpWorkflowInstanceIdSelectorType in HttpWorkflowInstanceIdSelectorTypes)
 0224            services.AddScoped(typeof(IHttpWorkflowInstanceIdSelector), httpWorkflowInstanceIdSelectorType);
 225
 0226        services.Configure<SerializationTypeOptions>(options =>
 0227        {
 0228            options.RegisterTypeAlias(typeof(HttpRequest), "HttpRequest");
 0229            options.RegisterTypeAlias(typeof(HttpResponse), "HttpResponse");
 0230            options.RegisterTypeAlias(typeof(HttpResponseMessage), "HttpResponseMessage");
 0231            options.RegisterTypeAlias(typeof(HttpHeaders), "HttpHeaders");
 0232            options.RegisterTypeAlias(typeof(HttpRouteData), "RouteData");
 0233            options.RegisterTypeAlias(typeof(IFormFile), "FormFile");
 0234            options.RegisterTypeAlias(typeof(IFormFile[]), "FormFile[]");
 0235            options.RegisterTypeAlias(typeof(HttpFile), "HttpFile");
 0236            options.RegisterTypeAlias(typeof(HttpFile[]), "HttpFile[]");
 0237            options.RegisterTypeAlias(typeof(Downloadable), "Downloadable");
 0238            options.RegisterTypeAlias(typeof(Downloadable[]), "Downloadable[]");
 0239            options.RegisterTypeAlias(typeof(HttpStatusCode), nameof(HttpStatusCode));
 0240            options.RegisterTypeAlias(typeof(HttpRequestException), nameof(HttpRequestException));
 0241            options.RegisterTypeAlias(typeof(HttpEndpointBookmarkPayload), nameof(HttpEndpointBookmarkPayload));
 0242        });
 0243    }
 244
 245    /// <inheritdoc />
 246    public void UseMiddleware(IApplicationBuilder app, IHostEnvironment? environment)
 247    {
 0248        app.UseWorkflows();
 0249    }
 250}