• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

me-viper / OpaDotNet / 13670981829

05 Mar 2025 07:47AM UTC coverage: 82.062% (-0.8%) from 82.832%
13670981829

push

github

me-viper
chore: Freeze public API

2057 of 2664 branches covered (77.21%)

Branch coverage included in aggregate %.

4000 of 4717 relevant lines covered (84.8%)

8028.52 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.72
/src/Extensions.AspNetCore/src/OpaPolicySource.cs
1
using Microsoft.Extensions.Options;
2
using Microsoft.Extensions.Primitives;
3

4
using OpaDotNet.Extensions.AspNetCore.Telemetry;
5
using OpaDotNet.Wasm;
6

7
namespace OpaDotNet.Extensions.AspNetCore;
8

9
/// <summary>
10
/// Compiles policy bundle from source.
11
/// </summary>
12
public abstract class OpaPolicySource : IOpaPolicySource
13
{
14
    // Has nothing to do with cancellation really but used to notify about recompilation.
15
    private CancellationTokenSource _changeTokenSource = new();
28✔
16

17
    private CancellationChangeToken _changeToken;
18

19
    private readonly SemaphoreSlim _lock = new(1, 1);
28✔
20

21
    private readonly IOptionsMonitor<OpaAuthorizationOptions> _options;
22

23
    protected ILogger Logger { get; }
416✔
24

25
    /// <summary>
26
    /// Produces instances of ILogger classes based on the specified providers.
27
    /// </summary>
28
    [PublicAPI]
29
    protected ILoggerFactory LoggerFactory { get; }
28✔
30

31
    /// <summary>
32
    /// Policy evaluator options.
33
    /// </summary>
34
    protected OpaAuthorizationOptions Options => _options.CurrentValue;
288✔
35

36
    private readonly IMutableOpaEvaluatorFactory _factory;
37

38
    /// <inheritdoc />
39
    public IOpaEvaluator CreateEvaluator() => _factory.Create();
162✔
40

41
    protected OpaPolicySource(
28✔
42
        IOptionsMonitor<OpaAuthorizationOptions> options,
28✔
43
        IMutableOpaEvaluatorFactory evaluatorFactory,
28✔
44
        ILoggerFactory loggerFactory)
28✔
45
    {
46
        ArgumentNullException.ThrowIfNull(options);
28✔
47
        ArgumentNullException.ThrowIfNull(evaluatorFactory);
28✔
48
        ArgumentNullException.ThrowIfNull(loggerFactory);
28✔
49

50
        _options = options;
28✔
51
        _factory = evaluatorFactory;
28✔
52
        LoggerFactory = loggerFactory;
28✔
53

54
        Logger = LoggerFactory.CreateLogger<OpaPolicySource>();
28✔
55
        _changeToken = new(_changeTokenSource.Token);
28✔
56
    }
28✔
57

58
    /// <inheritdoc />
59
    public IChangeToken OnPolicyUpdated()
60
    {
61
        if (_changeTokenSource.IsCancellationRequested)
122✔
62
        {
63
            _changeTokenSource = new();
104✔
64
            _changeToken = new(_changeTokenSource.Token);
104✔
65
        }
66

67
        return _changeToken;
122✔
68
    }
69

70
    /// <summary>
71
    /// When overriden produces compiled policy bundle stream.
72
    /// </summary>
73
    /// <param name="recompiling">
74
    /// <c>true</c> if it's first time bundle is compiled; otherwise <c>false</c>
75
    /// </param>
76
    /// <param name="cancellationToken">Cancellation token.</param>
77
    /// <returns>Compiled policy bundle stream.</returns>
78
    [PublicAPI]
79
    protected abstract Task<Stream?> CompileBundleFromSource(bool recompiling, CancellationToken cancellationToken = default);
80

81
    protected internal async Task CompileBundle(bool recompiling, CancellationToken cancellationToken = default)
82
    {
83
        try
84
        {
85
            await _lock.WaitAsync(cancellationToken).ConfigureAwait(false);
137✔
86
            Logger.BundleCompiling();
137✔
87

88
            var policyStream = await CompileBundleFromSource(recompiling, cancellationToken).ConfigureAwait(false);
137✔
89

90
            if (policyStream == null)
136!
91
                return;
×
92

93
            await using (policyStream.ConfigureAwait(false))
136✔
94
            {
95
                _factory.UpdatePolicy(policyStream, _options.CurrentValue.EngineOptions);
136✔
96
            }
97

98
            if (recompiling)
136✔
99
            {
100
                Logger.BundleRecompilationSucceeded();
109✔
101
                await _changeTokenSource.CancelAsync().ConfigureAwait(false);
109✔
102
            }
103
        }
136✔
104
        catch (Exception ex)
1✔
105
        {
106
            Logger.BundleCompilationFailed(ex);
1✔
107
            OpaEventSource.Log.BundleCompilationFailed();
1✔
108
            throw;
1✔
109
        }
110
        finally
111
        {
112
            _lock.Release();
137✔
113
        }
114

115
        Logger.BundleCompilationSucceeded();
134✔
116
        OpaEventSource.Log.BundleCompilationSucceeded();
134✔
117
    }
134✔
118

119
    /// <inheritdoc />
120
    public void Dispose()
121
    {
122
        Dispose(true);
43✔
123
        GC.SuppressFinalize(this);
43✔
124
    }
43✔
125

126
    /// <summary>
127
    /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
128
    /// </summary>
129
    /// <param name="disposing">If <c>true</c> method call comes from a Dispose method; otherwise <c>false</c>.</param>
130
    protected virtual void Dispose(bool disposing)
131
    {
132
        if (disposing)
43✔
133
        {
134
            _factory.Dispose();
43✔
135
            _lock.Dispose();
43✔
136
            _changeTokenSource.Dispose();
43✔
137
        }
138
    }
43✔
139

140
    /// <inheritdoc />
141
    public virtual async Task StartAsync(CancellationToken cancellationToken)
142
    {
143
        await CompileBundle(false, cancellationToken).ConfigureAwait(false);
28✔
144
    }
27✔
145

146
    /// <inheritdoc />
147
    public virtual Task StopAsync(CancellationToken cancellationToken)
148
    {
149
        return Task.CompletedTask;
22✔
150
    }
151
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc