< Summary

Information
Class: Elsa.WorkflowProviders.BlobStorage.Providers.BlobStorageWorkflowsProvider
Assembly: Elsa.WorkflowProviders.BlobStorage
File(s): /home/runner/work/elsa-core/elsa-core/src/modules/Elsa.WorkflowProviders.BlobStorage/Providers/BlobStorageWorkflowsProvider.cs
Line coverage
93%
Covered lines: 43
Uncovered lines: 3
Coverable lines: 46
Total lines: 93
Line coverage: 93.4%
Branch coverage
72%
Covered branches: 13
Total branches: 18
Branch coverage: 72.2%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
get_Name()100%210%
GetWorkflowsAsync()100%44100%
TryReadWorkflowAsync()66.66%121290.9%

File(s)

/home/runner/work/elsa-core/elsa-core/src/modules/Elsa.WorkflowProviders.BlobStorage/Providers/BlobStorageWorkflowsProvider.cs

#LineLine coverage
 1using Elsa.Extensions;
 2using Elsa.WorkflowProviders.BlobStorage.Contracts;
 3using Elsa.Workflows.Runtime;
 4using FluentStorage.Blobs;
 5using JetBrains.Annotations;
 6
 7namespace Elsa.WorkflowProviders.BlobStorage.Providers;
 8
 9/// <summary>
 10/// A workflow definition provider that loads workflow definitions from a storage using FluentStorage (See https://githu
 11/// </summary>
 12[PublicAPI]
 13public class BlobStorageWorkflowsProvider : IWorkflowsProvider
 14{
 15    private readonly IBlobStorageProvider _blobStorageProvider;
 16    private readonly IEnumerable<IBlobWorkflowFormatHandler> _handlers;
 17
 18    /// <summary>
 19    /// Initializes a new instance of the <see cref="BlobStorageWorkflowsProvider"/> class.
 20    /// </summary>
 26221    public BlobStorageWorkflowsProvider(
 26222        IBlobStorageProvider blobStorageProvider,
 26223        IEnumerable<IBlobWorkflowFormatHandler> handlers)
 24    {
 26225        _blobStorageProvider = blobStorageProvider;
 26226        _handlers = handlers;
 26227    }
 28
 29    /// <inheritdoc />
 030    public string Name => "FluentStorage";
 31
 32    /// <inheritdoc />
 33    public async ValueTask<IEnumerable<MaterializedWorkflow>> GetWorkflowsAsync(CancellationToken cancellationToken = de
 34    {
 35        // Aggregate supported extensions from all handlers
 2036        var supportedExtensions = _handlers
 4037            .SelectMany(h => h.SupportedExtensions)
 4038            .Where(ext => !string.IsNullOrEmpty(ext))
 4039            .Select(ext => ext.ToLowerInvariant())
 2040            .ToHashSet();
 41
 2042        var options = new ListOptions
 2043        {
 2044            Recurse = true,
 2045            BrowseFilter = blob =>
 2046            {
 2047                // If no handlers declare extensions, accept all files
 76048                if (supportedExtensions.Count == 0)
 049                    return true;
 2050
 2051                // Only accept files with supported extensions
 76052                var extension = Path.GetExtension(blob.Name).TrimStart('.').ToLowerInvariant();
 76053                return supportedExtensions.Contains(extension);
 2054            }
 2055        };
 56
 2057        var blobStorage = _blobStorageProvider.GetBlobStorage();
 2058        var blobs = await blobStorage.ListFilesAsync(options, cancellationToken);
 2059        var results = new List<MaterializedWorkflow>();
 60
 88061        foreach (var blob in blobs)
 62        {
 42063            var workflow = await TryReadWorkflowAsync(blob, cancellationToken);
 42064            if (workflow != null)
 42065                results.Add(workflow);
 66        }
 67
 2068        return results;
 2069    }
 70
 71    private async Task<MaterializedWorkflow?> TryReadWorkflowAsync(Blob blob, CancellationToken cancellationToken)
 72    {
 42073        var blobStorage = _blobStorageProvider.GetBlobStorage();
 42074        var content = await blobStorage.ReadTextAsync(blob.FullPath, cancellationToken: cancellationToken);
 42075        var contentType = blob.Properties.TryGetValue("ContentType", out var ct) ? ct?.ToString() : null;
 76
 126077        foreach (var handler in _handlers)
 78        {
 42079            if (!handler.SupportsExtension(blob.GetExtension()))
 80                continue;
 81
 42082            if (!handler.CanHandle(blob, contentType))
 83                continue;
 84
 42085            var result = await handler.TryParseAsync(blob, content, cancellationToken);
 42086            if (result != null)
 42087                return result;
 88        }
 89
 90        // No handler accepted this blob; ignore it
 091        return null;
 42092    }
 93}