< Summary

Information
Class: AsiBackbone.Core.Classification.DlpFailurePolicyContext
Assembly: AsiBackbone.Core
File(s): /home/runner/work/AsiBackbone/AsiBackbone/src/AsiBackbone.Core/Classification/DlpFailurePolicyContext.cs
Line coverage
100%
Covered lines: 72
Uncovered lines: 0
Coverable lines: 72
Total lines: 210
Line coverage: 100%
Branch coverage
100%
Covered branches: 26
Total branches: 26
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.cctor()100%11100%
.ctor(...)100%1010100%
get_HasTimeout()100%11100%
get_HasMetadata()100%11100%
Create(...)100%11100%
TimeoutFailure(...)100%11100%
NormalizeOptional(...)100%22100%
NormalizeMetadata(...)100%1414100%

File(s)

/home/runner/work/AsiBackbone/AsiBackbone/src/AsiBackbone.Core/Classification/DlpFailurePolicyContext.cs

#LineLine coverage
 1using System.Collections.ObjectModel;
 2
 3namespace AsiBackbone.Core.Classification;
 4
 5/// <summary>
 6/// Represents provider-neutral context for resolving DLP or classification failure behavior.
 7/// </summary>
 8public sealed class DlpFailurePolicyContext
 9{
 110    private static readonly IReadOnlyDictionary<string, string> EmptyMetadata =
 111        new ReadOnlyDictionary<string, string>(
 112            new Dictionary<string, string>(StringComparer.Ordinal));
 13
 5314    private DlpFailurePolicyContext(
 5315        DlpClassificationFailureKind failureKind,
 5316        DlpIntentRiskLevel riskLevel,
 5317        string? intentCategory,
 5318        string? environment,
 5319        string? correlationId,
 5320        string? traceId,
 5321        string? policyVersion,
 5322        string? policyHash,
 5323        TimeSpan? timeout,
 5324        IReadOnlyDictionary<string, string> metadata)
 25    {
 5326        if (!Enum.IsDefined(failureKind))
 27        {
 128            throw new ArgumentOutOfRangeException(nameof(failureKind), failureKind, "DLP failure kind must be defined.")
 29        }
 30
 5231        if (!Enum.IsDefined(riskLevel))
 32        {
 133            throw new ArgumentOutOfRangeException(nameof(riskLevel), riskLevel, "DLP intent risk level must be defined."
 34        }
 35
 36        // The host assigns the risk tier, and every tier maps to a different failure behavior. An unassigned tier is
 37        // rejected here rather than treated as the lowest one, so a caller that never set it fails closed at the bounda
 38        // instead of resolving to the most permissive policy.
 5139        if (riskLevel == DlpIntentRiskLevel.Unspecified)
 40        {
 141            throw new ArgumentOutOfRangeException(
 142                nameof(riskLevel),
 143                riskLevel,
 144                "DLP intent risk level must be assigned. Supply Low, Medium, or High rather than leaving the risk level 
 45        }
 46
 5047        if (timeout < TimeSpan.Zero)
 48        {
 149            throw new ArgumentOutOfRangeException(nameof(timeout), timeout, "Timeout must be greater than or equal to ze
 50        }
 51
 4952        FailureKind = failureKind;
 4953        RiskLevel = riskLevel;
 4954        IntentCategory = NormalizeOptional(intentCategory);
 4955        Environment = NormalizeOptional(environment);
 4956        CorrelationId = NormalizeOptional(correlationId);
 4957        TraceId = NormalizeOptional(traceId);
 4958        PolicyVersion = NormalizeOptional(policyVersion);
 4959        PolicyHash = NormalizeOptional(policyHash);
 4960        Timeout = timeout;
 4961        Metadata = metadata;
 4962    }
 63
 64    /// <summary>
 65    /// Gets the provider-neutral DLP or classification failure kind.
 66    /// </summary>
 67    public DlpClassificationFailureKind FailureKind { get; }
 68
 69    /// <summary>
 70    /// Gets the host-assigned risk level for the intent.
 71    /// </summary>
 72    public DlpIntentRiskLevel RiskLevel { get; }
 73
 74    /// <summary>
 75    /// Gets the host-defined intent category, when supplied.
 76    /// </summary>
 77    public string? IntentCategory { get; }
 78
 79    /// <summary>
 80    /// Gets the host-defined environment, when supplied.
 81    /// </summary>
 82    public string? Environment { get; }
 83
 84    /// <summary>
 85    /// Gets the correlation identifier associated with the governed flow, when supplied.
 86    /// </summary>
 87    public string? CorrelationId { get; }
 88
 89    /// <summary>
 90    /// Gets the trace identifier associated with the governed flow, when supplied.
 91    /// </summary>
 92    public string? TraceId { get; }
 93
 94    /// <summary>
 95    /// Gets the policy version associated with the governed flow, when supplied.
 96    /// </summary>
 97    public string? PolicyVersion { get; }
 98
 99    /// <summary>
 100    /// Gets the policy hash associated with the governed flow, when supplied.
 101    /// </summary>
 102    public string? PolicyHash { get; }
 103
 104    /// <summary>
 105    /// Gets the timeout value associated with the failure, when applicable.
 106    /// </summary>
 107    public TimeSpan? Timeout { get; }
 108
 109    /// <summary>
 110    /// Gets provider-neutral host metadata associated with the failure.
 111    /// </summary>
 112    public IReadOnlyDictionary<string, string> Metadata { get; }
 113
 114    /// <summary>
 115    /// Gets a value indicating whether timeout context is present.
 116    /// </summary>
 2117    public bool HasTimeout => Timeout.HasValue;
 118
 119    /// <summary>
 120    /// Gets a value indicating whether metadata is present.
 121    /// </summary>
 5122    public bool HasMetadata => Metadata.Count > 0;
 123
 124    /// <summary>
 125    /// Creates a provider-neutral DLP or classification failure policy context.
 126    /// </summary>
 127    public static DlpFailurePolicyContext Create(
 128        DlpClassificationFailureKind failureKind,
 129        DlpIntentRiskLevel riskLevel,
 130        string? intentCategory = null,
 131        string? environment = null,
 132        string? correlationId = null,
 133        string? traceId = null,
 134        string? policyVersion = null,
 135        string? policyHash = null,
 136        TimeSpan? timeout = null,
 137        IReadOnlyDictionary<string, string>? metadata = null)
 138    {
 53139        return new DlpFailurePolicyContext(
 53140            failureKind,
 53141            riskLevel,
 53142            intentCategory,
 53143            environment,
 53144            correlationId,
 53145            traceId,
 53146            policyVersion,
 53147            policyHash,
 53148            timeout,
 53149            NormalizeMetadata(metadata));
 150    }
 151
 152    /// <summary>
 153    /// Creates timeout-specific failure policy context.
 154    /// </summary>
 155    public static DlpFailurePolicyContext TimeoutFailure(
 156        DlpIntentRiskLevel riskLevel,
 157        TimeSpan? timeout = null,
 158        string? intentCategory = null,
 159        string? environment = null,
 160        string? correlationId = null,
 161        string? traceId = null,
 162        string? policyVersion = null,
 163        string? policyHash = null,
 164        IReadOnlyDictionary<string, string>? metadata = null)
 165    {
 6166        return Create(
 6167            DlpClassificationFailureKind.Timeout,
 6168            riskLevel,
 6169            intentCategory,
 6170            environment,
 6171            correlationId,
 6172            traceId,
 6173            policyVersion,
 6174            policyHash,
 6175            timeout,
 6176            metadata);
 177    }
 178
 179    private static string? NormalizeOptional(string? value)
 180    {
 294181        return string.IsNullOrWhiteSpace(value)
 294182            ? null
 294183            : value.Trim();
 184    }
 185
 186    private static IReadOnlyDictionary<string, string> NormalizeMetadata(
 187        IReadOnlyDictionary<string, string>? metadata)
 188    {
 53189        if (metadata is null || metadata.Count == 0)
 190        {
 49191            return EmptyMetadata;
 192        }
 193
 4194        Dictionary<string, string> normalizedMetadata = new(StringComparer.Ordinal);
 195
 24196        foreach (KeyValuePair<string, string> item in metadata)
 197        {
 8198            if (string.IsNullOrWhiteSpace(item.Key))
 199            {
 200                continue;
 201            }
 202
 5203            normalizedMetadata[item.Key.Trim()] = item.Value?.Trim() ?? string.Empty;
 204        }
 205
 4206        return normalizedMetadata.Count == 0
 4207            ? EmptyMetadata
 4208            : new ReadOnlyDictionary<string, string>(normalizedMetadata);
 209    }
 210}