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

@@ -62,6 +62,14 @@ builder.Services.AddSingleton<IOrchestratorControlService>(sp =>
sp.GetRequiredService<IOrchestratorControlRepository>(),
SbomMetrics.Meter));
builder.Services.AddSingleton<IWatermarkService, InMemoryWatermarkService>();
builder.Services.AddOptions<SbomLedgerOptions>()
.Bind(builder.Configuration.GetSection("SbomService:Ledger"));
builder.Services.AddSingleton<ISbomLedgerRepository, InMemorySbomLedgerRepository>();
builder.Services.AddSingleton<ISbomNormalizationService, SbomNormalizationService>();
builder.Services.AddSingleton<ISbomQualityScorer, SbomQualityScorer>();
builder.Services.AddSingleton<ISbomLedgerService, SbomLedgerService>();
builder.Services.AddSingleton<ISbomAnalysisTrigger, InMemorySbomAnalysisTrigger>();
builder.Services.AddSingleton<ISbomUploadService, SbomUploadService>();
builder.Services.AddSingleton<IProjectionRepository>(sp =>
{
@@ -454,6 +462,162 @@ app.MapGet("/sbom/versions", async Task<IResult> (
return Results.Ok(result.Result);
});
var sbomUploadHandler = async Task<IResult> (
[FromBody] SbomUploadRequest request,
[FromServices] ISbomUploadService uploadService,
CancellationToken cancellationToken) =>
{
var (response, validation) = await uploadService.UploadAsync(request, cancellationToken);
if (!validation.Valid)
{
return Results.BadRequest(new
{
error = "sbom_upload_validation_failed",
validation
});
}
SbomMetrics.LedgerUploadsTotal.Add(1);
return Results.Accepted($"/sbom/ledger/history?artifact={Uri.EscapeDataString(response.ArtifactRef)}", response);
};
app.MapPost("/sbom/upload", sbomUploadHandler);
app.MapPost("/api/v1/sbom/upload", sbomUploadHandler);
app.MapGet("/sbom/ledger/history", async Task<IResult> (
[FromServices] ISbomLedgerService ledgerService,
[FromQuery] string? artifact,
[FromQuery] string? cursor,
[FromQuery] int? limit,
CancellationToken cancellationToken) =>
{
if (string.IsNullOrWhiteSpace(artifact))
{
return Results.BadRequest(new { error = "artifact is required" });
}
if (cursor is { Length: > 0 } && !int.TryParse(cursor, NumberStyles.Integer, CultureInfo.InvariantCulture, out _))
{
return Results.BadRequest(new { error = "cursor must be an integer offset" });
}
var offset = cursor is null ? 0 : int.Parse(cursor, CultureInfo.InvariantCulture);
var pageSize = NormalizeLimit(limit, 50, 200);
var history = await ledgerService.GetHistoryAsync(artifact.Trim(), pageSize, offset, cancellationToken);
if (history is null)
{
return Results.NotFound(new { error = "ledger history not found" });
}
return Results.Ok(history);
});
app.MapGet("/sbom/ledger/point", async Task<IResult> (
[FromServices] ISbomLedgerService ledgerService,
[FromQuery] string? artifact,
[FromQuery] string? at,
CancellationToken cancellationToken) =>
{
if (string.IsNullOrWhiteSpace(artifact))
{
return Results.BadRequest(new { error = "artifact is required" });
}
if (string.IsNullOrWhiteSpace(at) || !DateTimeOffset.TryParse(at, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out var atUtc))
{
return Results.BadRequest(new { error = "at must be an ISO-8601 timestamp" });
}
var result = await ledgerService.GetAtTimeAsync(artifact.Trim(), atUtc, cancellationToken);
if (result is null)
{
return Results.NotFound(new { error = "ledger point not found" });
}
return Results.Ok(result);
});
app.MapGet("/sbom/ledger/range", async Task<IResult> (
[FromServices] ISbomLedgerService ledgerService,
[FromQuery] string? artifact,
[FromQuery] string? start,
[FromQuery] string? end,
[FromQuery] string? cursor,
[FromQuery] int? limit,
CancellationToken cancellationToken) =>
{
if (string.IsNullOrWhiteSpace(artifact))
{
return Results.BadRequest(new { error = "artifact is required" });
}
if (string.IsNullOrWhiteSpace(start) || !DateTimeOffset.TryParse(start, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out var startUtc))
{
return Results.BadRequest(new { error = "start must be an ISO-8601 timestamp" });
}
if (string.IsNullOrWhiteSpace(end) || !DateTimeOffset.TryParse(end, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal, out var endUtc))
{
return Results.BadRequest(new { error = "end must be an ISO-8601 timestamp" });
}
if (cursor is { Length: > 0 } && !int.TryParse(cursor, NumberStyles.Integer, CultureInfo.InvariantCulture, out _))
{
return Results.BadRequest(new { error = "cursor must be an integer offset" });
}
var offset = cursor is null ? 0 : int.Parse(cursor, CultureInfo.InvariantCulture);
var pageSize = NormalizeLimit(limit, 50, 200);
var history = await ledgerService.GetRangeAsync(artifact.Trim(), startUtc, endUtc, pageSize, offset, cancellationToken);
if (history is null)
{
return Results.NotFound(new { error = "ledger range not found" });
}
return Results.Ok(history);
});
app.MapGet("/sbom/ledger/diff", async Task<IResult> (
[FromServices] ISbomLedgerService ledgerService,
[FromQuery] string? before,
[FromQuery] string? after,
CancellationToken cancellationToken) =>
{
if (!Guid.TryParse(before, out var beforeId) || !Guid.TryParse(after, out var afterId))
{
return Results.BadRequest(new { error = "before and after must be GUIDs" });
}
var diff = await ledgerService.DiffAsync(beforeId, afterId, cancellationToken);
if (diff is null)
{
return Results.NotFound(new { error = "diff not found" });
}
SbomMetrics.LedgerDiffsTotal.Add(1);
return Results.Ok(diff);
});
app.MapGet("/sbom/ledger/lineage", async Task<IResult> (
[FromServices] ISbomLedgerService ledgerService,
[FromQuery] string? artifact,
CancellationToken cancellationToken) =>
{
if (string.IsNullOrWhiteSpace(artifact))
{
return Results.BadRequest(new { error = "artifact is required" });
}
var lineage = await ledgerService.GetLineageAsync(artifact.Trim(), cancellationToken);
if (lineage is null)
{
return Results.NotFound(new { error = "lineage not found" });
}
return Results.Ok(lineage);
});
app.MapGet("/sboms/{snapshotId}/projection", async Task<IResult> (
[FromServices] ISbomQueryService service,
[FromRoute] string? snapshotId,
@@ -543,6 +707,34 @@ app.MapGet("/internal/sbom/asset-events", async Task<IResult> (
return Results.Ok(events);
});
app.MapGet("/internal/sbom/ledger/audit", async Task<IResult> (
[FromServices] ISbomLedgerService ledgerService,
[FromQuery] string? artifact,
CancellationToken cancellationToken) =>
{
if (string.IsNullOrWhiteSpace(artifact))
{
return Results.BadRequest(new { error = "artifact is required" });
}
var audit = await ledgerService.GetAuditAsync(artifact.Trim(), cancellationToken);
return Results.Ok(audit.OrderBy(a => a.TimestampUtc).ToList());
});
app.MapGet("/internal/sbom/analysis/jobs", async Task<IResult> (
[FromServices] ISbomLedgerService ledgerService,
[FromQuery] string? artifact,
CancellationToken cancellationToken) =>
{
if (string.IsNullOrWhiteSpace(artifact))
{
return Results.BadRequest(new { error = "artifact is required" });
}
var jobs = await ledgerService.ListAnalysisJobsAsync(artifact.Trim(), cancellationToken);
return Results.Ok(jobs.OrderBy(j => j.CreatedAtUtc).ToList());
});
app.MapPost("/internal/sbom/events/backfill", async Task<IResult> (
[FromServices] IProjectionRepository repository,
[FromServices] ISbomEventPublisher publisher,
@@ -632,6 +824,19 @@ app.MapGet("/internal/sbom/resolver-feed/export", async Task<IResult> (
return Results.Text(ndjson, "application/x-ndjson");
});
app.MapPost("/internal/sbom/retention/prune", async Task<IResult> (
[FromServices] ISbomLedgerService ledgerService,
CancellationToken cancellationToken) =>
{
var result = await ledgerService.ApplyRetentionAsync(cancellationToken);
if (result.VersionsPruned > 0)
{
SbomMetrics.LedgerRetentionPrunedTotal.Add(result.VersionsPruned);
}
return Results.Ok(result);
});
app.MapGet("/internal/orchestrator/sources", async Task<IResult> (
[FromQuery] string? tenant,
[FromServices] IOrchestratorRepository repository,