< 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: 42
Uncovered lines: 3
Coverable lines: 45
Total lines: 90
Line coverage: 93.3%
Branch coverage
68%
Covered branches: 11
Total branches: 16
Branch coverage: 68.7%
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()60%101090%

File(s)

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

#LineLine coverage
 1using Elsa.WorkflowProviders.BlobStorage.Contracts;
 2using Elsa.Workflows.Runtime;
 3using FluentStorage.Blobs;
 4using JetBrains.Annotations;
 5
 6namespace Elsa.WorkflowProviders.BlobStorage.Providers;
 7
 8/// <summary>
 9/// A workflow definition provider that loads workflow definitions from a storage using FluentStorage (See https://githu
 10/// </summary>
 11[PublicAPI]
 12public class BlobStorageWorkflowsProvider : IWorkflowsProvider
 13{
 14    private readonly IBlobStorageProvider _blobStorageProvider;
 15    private readonly IEnumerable<IBlobWorkflowFormatHandler> _handlers;
 16
 17    /// <summary>
 18    /// Initializes a new instance of the <see cref="BlobStorageWorkflowsProvider"/> class.
 19    /// </summary>
 26620    public BlobStorageWorkflowsProvider(
 26621        IBlobStorageProvider blobStorageProvider,
 26622        IEnumerable<IBlobWorkflowFormatHandler> handlers)
 23    {
 26624        _blobStorageProvider = blobStorageProvider;
 26625        _handlers = handlers;
 26626    }
 27
 28    /// <inheritdoc />
 029    public string Name => "FluentStorage";
 30
 31    /// <inheritdoc />
 32    public async ValueTask<IEnumerable<MaterializedWorkflow>> GetWorkflowsAsync(CancellationToken cancellationToken = de
 33    {
 34        // Aggregate supported extensions from all handlers
 835        var supportedExtensions = _handlers
 1636            .SelectMany(h => h.SupportedExtensions)
 1637            .Where(ext => !string.IsNullOrEmpty(ext))
 1638            .Select(ext => ext.ToLowerInvariant())
 839            .ToHashSet();
 40
 841        var options = new ListOptions
 842        {
 843            Recurse = true,
 844            BrowseFilter = blob =>
 845            {
 846                // If no handlers declare extensions, accept all files
 30447                if (supportedExtensions.Count == 0)
 048                    return true;
 849
 850                // Only accept files with supported extensions
 30451                var extension = Path.GetExtension(blob.Name).TrimStart('.').ToLowerInvariant();
 30452                return supportedExtensions.Contains(extension);
 853            }
 854        };
 55
 856        var blobStorage = _blobStorageProvider.GetBlobStorage();
 857        var blobs = await blobStorage.ListFilesAsync(options, cancellationToken);
 858        var results = new List<MaterializedWorkflow>();
 59
 35260        foreach (var blob in blobs)
 61        {
 16862            var workflow = await TryReadWorkflowAsync(blob, cancellationToken);
 16863            if (workflow != null)
 16864                results.Add(workflow);
 65        }
 66
 867        return results;
 868    }
 69
 70    private async Task<MaterializedWorkflow?> TryReadWorkflowAsync(Blob blob, CancellationToken cancellationToken)
 71    {
 16872        var blobStorage = _blobStorageProvider.GetBlobStorage();
 16873        var content = await blobStorage.ReadTextAsync(blob.FullPath, cancellationToken: cancellationToken);
 74
 16875        var contentType = blob.Properties.TryGetValue("ContentType", out var ct) ? ct?.ToString() : null;
 76
 50477        foreach (var handler in _handlers)
 78        {
 16879            if (!handler.CanHandle(blob, contentType))
 80                continue;
 81
 16882            var result = await handler.TryParseAsync(blob, content, cancellationToken);
 16883            if (result != null)
 16884                return result;
 85        }
 86
 87        // No handler accepted this blob; ignore it
 088        return null;
 16889    }
 90}