Add tests and implement timeline ingestion options with NATS and Redis subscribers

- Introduced `BinaryReachabilityLifterTests` to validate binary lifting functionality.
- Created `PackRunWorkerOptions` for configuring worker paths and execution persistence.
- Added `TimelineIngestionOptions` for configuring NATS and Redis ingestion transports.
- Implemented `NatsTimelineEventSubscriber` for subscribing to NATS events.
- Developed `RedisTimelineEventSubscriber` for reading from Redis Streams.
- Added `TimelineEnvelopeParser` to normalize incoming event envelopes.
- Created unit tests for `TimelineEnvelopeParser` to ensure correct field mapping.
- Implemented `TimelineAuthorizationAuditSink` for logging authorization outcomes.
This commit is contained in:
StellaOps Bot
2025-12-03 09:46:48 +02:00
parent e923880694
commit 35c8f9216f
520 changed files with 4416 additions and 31492 deletions

View File

@@ -17,8 +17,38 @@ builder.Configuration
builder.Services.AddOptions();
builder.Services.AddLogging();
// Register SBOM query services (InMemory seed; replace with Mongo-backed repository later).
builder.Services.AddSingleton<IComponentLookupRepository>(_ => new InMemoryComponentLookupRepository());
// Register SBOM query services (file-backed fixtures when present; fallback to in-memory seeds).
builder.Services.AddSingleton<IComponentLookupRepository>(sp =>
{
var config = sp.GetRequiredService<IConfiguration>();
var env = sp.GetRequiredService<IHostEnvironment>();
var configured = config.GetValue<string>("SbomService:ComponentLookupPath");
if (!string.IsNullOrWhiteSpace(configured) && File.Exists(configured))
{
return new FileComponentLookupRepository(configured!);
}
var candidate = FindFixture(env, "component_lookup.json");
return candidate is not null
? new FileComponentLookupRepository(candidate)
: new InMemoryComponentLookupRepository();
});
builder.Services.AddSingleton<ICatalogRepository>(sp =>
{
var config = sp.GetRequiredService<IConfiguration>();
var env = sp.GetRequiredService<IHostEnvironment>();
var configured = config.GetValue<string>("SbomService:CatalogPath");
if (!string.IsNullOrWhiteSpace(configured) && File.Exists(configured))
{
return new FileCatalogRepository(configured!);
}
var candidate = FindFixture(env, "catalog.json");
return candidate is not null
? new FileCatalogRepository(candidate)
: new InMemoryCatalogRepository();
});
builder.Services.AddSingleton<IClock, SystemClock>();
builder.Services.AddSingleton<ISbomEventStore, InMemorySbomEventStore>();
builder.Services.AddSingleton<ISbomEventPublisher>(sp => sp.GetRequiredService<ISbomEventStore>());
@@ -63,6 +93,28 @@ builder.Services.AddSingleton<IProjectionRepository>(sp =>
return new FileProjectionRepository(string.Empty);
});
static string? FindFixture(IHostEnvironment env, string fileName)
{
var candidateRoots = new[]
{
env.ContentRootPath,
Path.GetFullPath(Path.Combine(env.ContentRootPath, "..")),
Path.GetFullPath(Path.Combine(env.ContentRootPath, "..", "..")),
Path.GetFullPath(Path.Combine(env.ContentRootPath, "..", "..", ".."))
};
foreach (var root in candidateRoots)
{
var candidate = Path.Combine(root, "docs", "modules", "sbomservice", "fixtures", "lnm-v1", fileName);
if (File.Exists(candidate))
{
return candidate;
}
}
return null;
}
var app = builder.Build();
if (app.Environment.IsDevelopment())