< Summary

Information
Class: AsiBackbone.Storage.InMemory.Audit.InMemoryAuditLedger
Assembly: AsiBackbone.Storage.InMemory
File(s): /home/runner/work/AsiBackbone/AsiBackbone/src/AsiBackbone.Storage.InMemory/Audit/InMemoryAuditLedger.cs
Line coverage
96%
Covered lines: 27
Uncovered lines: 1
Coverable lines: 28
Total lines: 102
Line coverage: 96.4%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
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_Records()100%11100%
WriteAsync(...)100%11100%
AsiBackbone.Core.Audit.IAsiBackboneAuditSink.WriteAsync(...)100%210%
GetByCorrelationId(...)100%11100%
GetByEventId(...)100%11100%
WriteCore(...)100%11100%

File(s)

/home/runner/work/AsiBackbone/AsiBackbone/src/AsiBackbone.Storage.InMemory/Audit/InMemoryAuditLedger.cs

#LineLine coverage
 1using AsiBackbone.Core.Audit;
 2
 3namespace AsiBackbone.Storage.InMemory.Audit;
 4
 5/// <summary>
 6/// In-memory audit ledger intended for tests, samples, and local validation hosts.
 7/// </summary>
 8/// <remarks>
 9/// This type is not durable storage. It records audit residue in process memory and is suitable only for local developm
 10/// tests, examples, and non-production validation flows.
 11/// </remarks>
 12public sealed class InMemoryAuditLedger : IAsiBackboneAuditSink
 13{
 314    private readonly Lock syncRoot = new();
 315    private readonly List<IAsiBackboneAuditResidue> records = [];
 16
 17    /// <summary>
 18    /// Gets a snapshot of all recorded audit residue values.
 19    /// </summary>
 20    public IReadOnlyList<IAsiBackboneAuditResidue> Records
 21    {
 22        get
 323        {
 24            lock (syncRoot)
 25            {
 326                return Array.AsReadOnly([.. records]);
 27            }
 328        }
 29    }
 30
 31    /// <inheritdoc />
 32    public ValueTask WriteAsync(
 33        IAsiBackboneAuditResidue residue,
 34        CancellationToken cancellationToken = default)
 35    {
 336        return WriteCore(residue, cancellationToken);
 37    }
 38
 39    ValueTask IAsiBackboneAuditSink.WriteAsync(
 40        IAsiBackboneAuditResidue residue,
 41        CancellationToken cancellationToken)
 42    {
 043        return WriteCore(residue, cancellationToken);
 44    }
 45
 46    /// <summary>
 47    /// Gets a snapshot of records matching the supplied correlation identifier.
 48    /// </summary>
 49    /// <param name="correlationId">The correlation identifier to match.</param>
 50    /// <returns>Audit residue values with the supplied correlation identifier.</returns>
 51    public IReadOnlyList<IAsiBackboneAuditResidue> GetByCorrelationId(string correlationId)
 52    {
 153        ArgumentException.ThrowIfNullOrWhiteSpace(correlationId);
 54
 155        string normalizedCorrelationId = correlationId.Trim();
 56
 57        lock (syncRoot)
 58        {
 159            return Array.AsReadOnly([
 160                .. records.Where(record => string.Equals(
 161                    record.CorrelationId,
 162                    normalizedCorrelationId,
 163                    StringComparison.Ordinal))
 164            ]);
 65        }
 166    }
 67
 68    /// <summary>
 69    /// Attempts to get a record by its audit event identifier.
 70    /// </summary>
 71    /// <param name="eventId">The audit event identifier.</param>
 72    /// <returns>The matching audit residue, or <see langword="null"/> when none is found.</returns>
 73    public IAsiBackboneAuditResidue? GetByEventId(string eventId)
 74    {
 175        ArgumentException.ThrowIfNullOrWhiteSpace(eventId);
 76
 177        string normalizedEventId = eventId.Trim();
 78
 79        lock (syncRoot)
 80        {
 281            return records.FirstOrDefault(record => string.Equals(
 282                record.EventId,
 283                normalizedEventId,
 284                StringComparison.Ordinal));
 85        }
 186    }
 87
 88    private ValueTask WriteCore(
 89        IAsiBackboneAuditResidue residue,
 90        CancellationToken cancellationToken)
 91    {
 392        ArgumentNullException.ThrowIfNull(residue);
 393        cancellationToken.ThrowIfCancellationRequested();
 94
 95        lock (syncRoot)
 96        {
 397            records.Add(residue);
 398        }
 99
 3100        return ValueTask.CompletedTask;
 101    }
 102}