67 lines
2.3 KiB
C#
67 lines
2.3 KiB
C#
// -----------------------------------------------------------------------------
|
|
// S3UnifiedArtifactStore.Read.cs
|
|
// Sprint: SPRINT_20260118_017_Evidence_artifact_store_unification
|
|
// Task: AS-002 - Implement S3-backed ArtifactStore
|
|
// Description: Read operations for the unified artifact store
|
|
// -----------------------------------------------------------------------------
|
|
using Microsoft.Extensions.Logging;
|
|
using StellaOps.Artifact.Core;
|
|
|
|
namespace StellaOps.Artifact.Infrastructure;
|
|
|
|
public sealed partial class S3UnifiedArtifactStore
|
|
{
|
|
/// <inheritdoc />
|
|
public async Task<ArtifactReadResult> ReadAsync(
|
|
string bomRef,
|
|
string? serialNumber,
|
|
string? artifactId,
|
|
CancellationToken ct = default)
|
|
{
|
|
try
|
|
{
|
|
var entry = await ResolveEntryAsync(bomRef, serialNumber, artifactId, ct).ConfigureAwait(false);
|
|
if (entry == null)
|
|
{
|
|
return ArtifactReadResult.NotFound($"No artifact found for bom-ref: {bomRef}");
|
|
}
|
|
|
|
var stream = await _client.GetObjectAsync(_options.BucketName, entry.StorageKey, ct)
|
|
.ConfigureAwait(false);
|
|
if (stream == null)
|
|
{
|
|
return ArtifactReadResult.NotFound($"Object not found in S3: {entry.StorageKey}");
|
|
}
|
|
|
|
return ArtifactReadResult.Succeeded(stream, CreateMetadata(entry));
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_logger.LogError(ex, "Failed to read artifact for bom-ref {BomRef}", bomRef);
|
|
return ArtifactReadResult.NotFound(ex.Message);
|
|
}
|
|
}
|
|
|
|
private async Task<ArtifactIndexEntry?> ResolveEntryAsync(
|
|
string bomRef,
|
|
string? serialNumber,
|
|
string? artifactId,
|
|
CancellationToken ct)
|
|
{
|
|
if (serialNumber != null && artifactId != null)
|
|
{
|
|
return await _indexRepository.GetAsync(bomRef, serialNumber, artifactId, ct).ConfigureAwait(false);
|
|
}
|
|
|
|
if (serialNumber != null)
|
|
{
|
|
var entries = await _indexRepository.FindByBomRefAndSerialAsync(bomRef, serialNumber, ct)
|
|
.ConfigureAwait(false);
|
|
return entries.FirstOrDefault();
|
|
}
|
|
|
|
var candidates = await _indexRepository.FindByBomRefAsync(bomRef, ct).ConfigureAwait(false);
|
|
return candidates.FirstOrDefault();
|
|
}
|
|
}
|