Refactor code structure for improved readability and maintainability; optimize performance in key functions.

This commit is contained in:
master
2025-12-22 19:06:31 +02:00
parent dfaa2079aa
commit 4602ccc3a3
1444 changed files with 109919 additions and 8058 deletions

View File

@@ -10,6 +10,9 @@ public sealed class SbomIngestTransformer
private const string DependsOnEdgeKind = "DEPENDS_ON";
private const string DeclaredInEdgeKind = "DECLARED_IN";
private const string BuiltFromEdgeKind = "BUILT_FROM";
private const string SbomNodeKind = "sbom";
private const string SbomVersionOfEdgeKind = "SBOM_VERSION_OF";
private const string SbomLineageEdgePrefix = "SBOM_LINEAGE_";
public GraphBuildBatch Transform(SbomSnapshot snapshot)
{
@@ -19,6 +22,7 @@ public sealed class SbomIngestTransformer
var edges = new List<JsonObject>();
var artifactNodes = new Dictionary<string, JsonObject>(StringComparer.OrdinalIgnoreCase);
var sbomNodes = new Dictionary<string, JsonObject>(StringComparer.OrdinalIgnoreCase);
var componentNodes = new Dictionary<string, JsonObject>(StringComparer.OrdinalIgnoreCase);
var fileNodes = new Dictionary<string, JsonObject>(StringComparer.OrdinalIgnoreCase);
var licenseCandidates = new Dictionary<(string License, string SourceDigest), LicenseCandidate>(LicenseKeyComparer.Instance);
@@ -30,6 +34,16 @@ public sealed class SbomIngestTransformer
nodes.Add(artifactNode);
artifactNodes[GetArtifactKey(snapshot.ArtifactDigest, snapshot.SbomDigest)] = artifactNode;
var sbomNode = CreateSbomNode(snapshot);
if (sbomNode is not null)
{
nodes.Add(sbomNode);
sbomNodes[snapshot.SbomDigest] = sbomNode;
var sbomEdge = CreateSbomVersionOfEdge(snapshot, sbomNode, artifactNode, NextEdgeOffset());
edges.Add(sbomEdge);
}
foreach (var component in snapshot.Components)
{
var componentNode = CreateComponentNode(snapshot, component);
@@ -91,6 +105,27 @@ public sealed class SbomIngestTransformer
edges.Add(edge);
}
if (sbomNode is not null && snapshot.Lineage.Count > 0)
{
foreach (var lineage in snapshot.Lineage)
{
if (string.IsNullOrWhiteSpace(lineage.SbomDigest))
{
continue;
}
if (!sbomNodes.TryGetValue(lineage.SbomDigest, out var relatedNode))
{
relatedNode = CreateLineageSbomNode(snapshot, lineage);
nodes.Add(relatedNode);
sbomNodes[lineage.SbomDigest] = relatedNode;
}
var edge = CreateLineageEdge(snapshot, sbomNode, relatedNode, lineage, NextEdgeOffset());
edges.Add(edge);
}
}
var orderedNodes = nodes
.OrderBy(node => node["kind"]!.GetValue<string>(), StringComparer.Ordinal)
.ThenBy(node => node["id"]!.GetValue<string>(), StringComparer.Ordinal)
@@ -168,6 +203,76 @@ public sealed class SbomIngestTransformer
ValidTo: null));
}
private static JsonObject? CreateSbomNode(SbomSnapshot snapshot)
{
if (string.IsNullOrWhiteSpace(snapshot.SbomDigest))
{
return null;
}
var attributes = new JsonObject
{
["sbom_digest"] = snapshot.SbomDigest,
["artifact_digest"] = snapshot.ArtifactDigest,
["format"] = snapshot.SbomFormat,
["format_version"] = snapshot.SbomFormatVersion
};
if (!string.IsNullOrWhiteSpace(snapshot.SbomVersionId))
{
attributes["version_id"] = snapshot.SbomVersionId;
}
if (snapshot.SbomSequence > 0)
{
attributes["sequence"] = snapshot.SbomSequence;
}
if (!string.IsNullOrWhiteSpace(snapshot.ChainId))
{
attributes["chain_id"] = snapshot.ChainId;
}
return GraphDocumentFactory.CreateNode(new GraphNodeSpec(
Tenant: snapshot.Tenant,
Kind: SbomNodeKind,
CanonicalKey: new Dictionary<string, string>
{
["tenant"] = snapshot.Tenant,
["sbom_digest"] = snapshot.SbomDigest
},
Attributes: attributes,
Provenance: new GraphProvenanceSpec(snapshot.Source, snapshot.CollectedAt, snapshot.SbomDigest, snapshot.EventOffset + 1),
ValidFrom: snapshot.CollectedAt,
ValidTo: null));
}
private static JsonObject CreateLineageSbomNode(SbomSnapshot snapshot, SbomLineageReference lineage)
{
var attributes = new JsonObject
{
["sbom_digest"] = lineage.SbomDigest,
["artifact_digest"] = lineage.ArtifactDigest
};
return GraphDocumentFactory.CreateNode(new GraphNodeSpec(
Tenant: snapshot.Tenant,
Kind: SbomNodeKind,
CanonicalKey: new Dictionary<string, string>
{
["tenant"] = snapshot.Tenant,
["sbom_digest"] = lineage.SbomDigest
},
Attributes: attributes,
Provenance: new GraphProvenanceSpec(
ResolveSource(lineage.Source, snapshot.Source),
lineage.CollectedAt,
lineage.SbomDigest,
lineage.EventOffset),
ValidFrom: lineage.CollectedAt,
ValidTo: null));
}
private static JsonObject CreateComponentNode(SbomSnapshot snapshot, SbomComponent component)
{
var attributes = new JsonObject
@@ -199,6 +304,59 @@ public sealed class SbomIngestTransformer
ValidTo: null));
}
private static JsonObject CreateSbomVersionOfEdge(SbomSnapshot snapshot, JsonObject sbomNode, JsonObject artifactNode, long eventOffset)
{
return GraphDocumentFactory.CreateEdge(new GraphEdgeSpec(
Tenant: snapshot.Tenant,
Kind: SbomVersionOfEdgeKind,
CanonicalKey: new Dictionary<string, string>
{
["tenant"] = snapshot.Tenant,
["sbom_node_id"] = sbomNode["id"]!.GetValue<string>(),
["artifact_node_id"] = artifactNode["id"]!.GetValue<string>()
},
Attributes: new JsonObject
{
["sbom_digest"] = snapshot.SbomDigest,
["artifact_digest"] = snapshot.ArtifactDigest,
["chain_id"] = snapshot.ChainId,
["sequence"] = snapshot.SbomSequence
},
Provenance: new GraphProvenanceSpec(snapshot.Source, snapshot.CollectedAt, snapshot.SbomDigest, eventOffset),
ValidFrom: snapshot.CollectedAt,
ValidTo: null));
}
private static JsonObject CreateLineageEdge(SbomSnapshot snapshot, JsonObject fromNode, JsonObject toNode, SbomLineageReference lineage, long fallbackOffset)
{
var offset = lineage.EventOffset > 0 ? lineage.EventOffset : fallbackOffset;
var kind = NormalizeLineageKind(lineage.Relationship);
return GraphDocumentFactory.CreateEdge(new GraphEdgeSpec(
Tenant: snapshot.Tenant,
Kind: kind,
CanonicalKey: new Dictionary<string, string>
{
["tenant"] = snapshot.Tenant,
["from_sbom_node_id"] = fromNode["id"]!.GetValue<string>(),
["to_sbom_node_id"] = toNode["id"]!.GetValue<string>(),
["relationship"] = lineage.Relationship
},
Attributes: new JsonObject
{
["relationship"] = lineage.Relationship,
["sbom_digest"] = lineage.SbomDigest,
["artifact_digest"] = lineage.ArtifactDigest
},
Provenance: new GraphProvenanceSpec(
ResolveSource(lineage.Source, snapshot.Source),
lineage.CollectedAt,
snapshot.SbomDigest,
offset),
ValidFrom: lineage.CollectedAt,
ValidTo: null));
}
private static JsonObject CreateFileNode(SbomSnapshot snapshot, SbomComponentFile file)
{
var attributes = new JsonObject
@@ -390,6 +548,17 @@ public sealed class SbomIngestTransformer
return array;
}
private static string NormalizeLineageKind(string relationship)
{
if (string.IsNullOrWhiteSpace(relationship))
{
return SbomLineageEdgePrefix + "UNKNOWN";
}
var normalized = relationship.Trim().Replace('-', '_').Replace(' ', '_').ToUpperInvariant();
return SbomLineageEdgePrefix + normalized;
}
private static LicenseCandidate CreateLicenseCandidate(SbomSnapshot snapshot, SbomComponent component)
{
var collectedAt = component.CollectedAt.AddSeconds(2);

View File

@@ -16,6 +16,21 @@ public sealed class SbomSnapshot
[JsonPropertyName("sbomDigest")]
public string SbomDigest { get; init; } = string.Empty;
[JsonPropertyName("sbomVersionId")]
public string SbomVersionId { get; init; } = string.Empty;
[JsonPropertyName("sbomSequence")]
public int SbomSequence { get; init; }
[JsonPropertyName("sbomFormat")]
public string SbomFormat { get; init; } = string.Empty;
[JsonPropertyName("sbomFormatVersion")]
public string SbomFormatVersion { get; init; } = string.Empty;
[JsonPropertyName("chainId")]
public string ChainId { get; init; } = string.Empty;
[JsonPropertyName("collectedAt")]
public DateTimeOffset CollectedAt { get; init; } = DateTimeOffset.UnixEpoch;
@@ -33,6 +48,9 @@ public sealed class SbomSnapshot
[JsonPropertyName("baseArtifacts")]
public IReadOnlyList<SbomBaseArtifact> BaseArtifacts { get; init; } = Array.Empty<SbomBaseArtifact>();
[JsonPropertyName("lineage")]
public IReadOnlyList<SbomLineageReference> Lineage { get; init; } = Array.Empty<SbomLineageReference>();
}
public sealed class SbomArtifactMetadata
@@ -229,3 +247,24 @@ public sealed class SbomBaseArtifact
[JsonPropertyName("source")]
public string Source { get; init; } = string.Empty;
}
public sealed class SbomLineageReference
{
[JsonPropertyName("relationship")]
public string Relationship { get; init; } = string.Empty;
[JsonPropertyName("sbomDigest")]
public string SbomDigest { get; init; } = string.Empty;
[JsonPropertyName("artifactDigest")]
public string ArtifactDigest { get; init; } = string.Empty;
[JsonPropertyName("eventOffset")]
public long EventOffset { get; init; }
[JsonPropertyName("collectedAt")]
public DateTimeOffset CollectedAt { get; init; } = DateTimeOffset.UnixEpoch;
[JsonPropertyName("source")]
public string Source { get; init; } = string.Empty;
}