65 lines
3.3 KiB
C#
65 lines
3.3 KiB
C#
using static StellaOps.Localization.T;
|
|
|
|
namespace StellaOps.Evidence.Bundle;
|
|
|
|
/// <summary>Builder for constructing evidence bundles.</summary>
|
|
public sealed class EvidenceBundleBuilder
|
|
{
|
|
private readonly TimeProvider _timeProvider;
|
|
private string? _alertId;
|
|
private string? _artifactId;
|
|
private ReachabilityEvidence? _reachability;
|
|
private CallStackEvidence? _callStack;
|
|
private ProvenanceEvidence? _provenance;
|
|
private VexStatusEvidence? _vexStatus;
|
|
private DiffEvidence? _diff;
|
|
private GraphRevisionEvidence? _graphRevision;
|
|
// Sprint: SPRINT_20260112_008_LB_binary_diff_evidence_models (BINDIFF-LB-002)
|
|
private BinaryDiffEvidence? _binaryDiff;
|
|
|
|
public EvidenceBundleBuilder(TimeProvider timeProvider) => _timeProvider = timeProvider ?? throw new ArgumentNullException(nameof(timeProvider));
|
|
public EvidenceBundleBuilder() : this(TimeProvider.System) { }
|
|
|
|
public EvidenceBundleBuilder WithAlertId(string alertId) { _alertId = alertId; return this; }
|
|
public EvidenceBundleBuilder WithArtifactId(string artifactId) { _artifactId = artifactId; return this; }
|
|
public EvidenceBundleBuilder WithReachability(ReachabilityEvidence e) { _reachability = e; return this; }
|
|
public EvidenceBundleBuilder WithCallStack(CallStackEvidence e) { _callStack = e; return this; }
|
|
public EvidenceBundleBuilder WithProvenance(ProvenanceEvidence e) { _provenance = e; return this; }
|
|
public EvidenceBundleBuilder WithVexStatus(VexStatusEvidence e) { _vexStatus = e; return this; }
|
|
public EvidenceBundleBuilder WithDiff(DiffEvidence e) { _diff = e; return this; }
|
|
public EvidenceBundleBuilder WithGraphRevision(GraphRevisionEvidence e) { _graphRevision = e; return this; }
|
|
// BINDIFF-LB-002: Add binary diff builder method
|
|
public EvidenceBundleBuilder WithBinaryDiff(BinaryDiffEvidence e) { _binaryDiff = e; return this; }
|
|
|
|
public EvidenceBundle Build()
|
|
{
|
|
if (string.IsNullOrWhiteSpace(_alertId)) throw new InvalidOperationException(_t("common.evidence.bundle_alert_id_required"));
|
|
if (string.IsNullOrWhiteSpace(_artifactId)) throw new InvalidOperationException(_t("common.evidence.bundle_artifact_id_required"));
|
|
|
|
var hashes = new Dictionary<string, string>();
|
|
if (_reachability?.Hash is not null) hashes["reachability"] = _reachability.Hash;
|
|
if (_callStack?.Hash is not null) hashes["callstack"] = _callStack.Hash;
|
|
if (_provenance?.Hash is not null) hashes["provenance"] = _provenance.Hash;
|
|
if (_vexStatus?.Hash is not null) hashes["vex"] = _vexStatus.Hash;
|
|
if (_diff?.Hash is not null) hashes["diff"] = _diff.Hash;
|
|
if (_graphRevision?.Hash is not null) hashes["graph"] = _graphRevision.Hash;
|
|
// BINDIFF-LB-002: Include binary diff hash
|
|
if (_binaryDiff?.Hash is not null) hashes["binaryDiff"] = _binaryDiff.Hash;
|
|
|
|
return new EvidenceBundle
|
|
{
|
|
AlertId = _alertId,
|
|
ArtifactId = _artifactId,
|
|
Reachability = _reachability,
|
|
CallStack = _callStack,
|
|
Provenance = _provenance,
|
|
VexStatus = _vexStatus,
|
|
Diff = _diff,
|
|
GraphRevision = _graphRevision,
|
|
BinaryDiff = _binaryDiff,
|
|
Hashes = hashes.Count > 0 ? EvidenceHashSet.Compute(hashes) : EvidenceHashSet.Empty(),
|
|
CreatedAt = _timeProvider.GetUtcNow()
|
|
};
|
|
}
|
|
}
|