up
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Findings Ledger CI / build-test (push) Has been cancelled
Findings Ledger CI / migration-validation (push) Has been cancelled
Scanner Analyzers / Discover Analyzers (push) Has been cancelled
Signals Reachability Scoring & Events / reachability-smoke (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
cryptopro-linux-csp / build-and-test (push) Has been cancelled
Scanner Analyzers / Validate Test Fixtures (push) Has been cancelled
Signals CI & Image / signals-ci (push) Has been cancelled
sm-remote-ci / build-and-test (push) Has been cancelled
Findings Ledger CI / generate-manifest (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Scanner Analyzers / Build Analyzers (push) Has been cancelled
Scanner Analyzers / Test Language Analyzers (push) Has been cancelled
Scanner Analyzers / Verify Deterministic Output (push) Has been cancelled
Signals Reachability Scoring & Events / sign-and-upload (push) Has been cancelled

This commit is contained in:
StellaOps Bot
2025-12-09 09:38:09 +02:00
parent bc0762e97d
commit 108d1c64b3
193 changed files with 7265 additions and 13029 deletions

View File

@@ -11,6 +11,7 @@ using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using MongoDB.Bson;
using MongoContracts = StellaOps.Concelier.Storage.Mongo;
using StorageContracts = StellaOps.Concelier.Storage.Contracts;
using StellaOps.Concelier.Connector.Common.Http;
using StellaOps.Concelier.Connector.Common.Telemetry;
using StellaOps.Concelier.Core.Aoc;
@@ -32,6 +33,7 @@ public sealed class SourceFetchService
private readonly IHttpClientFactory _httpClientFactory;
private readonly RawDocumentStorage _rawDocumentStorage;
private readonly MongoContracts.IDocumentStore _documentStore;
private readonly StorageContracts.IStorageDocumentStore _storageDocumentStore;
private readonly ILogger<SourceFetchService> _logger;
private readonly TimeProvider _timeProvider;
private readonly IOptionsMonitor<SourceHttpClientOptions> _httpClientOptions;
@@ -46,6 +48,7 @@ public sealed class SourceFetchService
IHttpClientFactory httpClientFactory,
RawDocumentStorage rawDocumentStorage,
MongoContracts.IDocumentStore documentStore,
StorageContracts.IStorageDocumentStore storageDocumentStore,
ILogger<SourceFetchService> logger,
IJitterSource jitterSource,
IAdvisoryRawWriteGuard guard,
@@ -58,6 +61,7 @@ public sealed class SourceFetchService
_httpClientFactory = httpClientFactory ?? throw new ArgumentNullException(nameof(httpClientFactory));
_rawDocumentStorage = rawDocumentStorage ?? throw new ArgumentNullException(nameof(rawDocumentStorage));
_documentStore = documentStore ?? throw new ArgumentNullException(nameof(documentStore));
_storageDocumentStore = storageDocumentStore ?? throw new ArgumentNullException(nameof(storageDocumentStore));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_jitterSource = jitterSource ?? throw new ArgumentNullException(nameof(jitterSource));
_guard = guard ?? throw new ArgumentNullException(nameof(guard));
@@ -69,6 +73,36 @@ public sealed class SourceFetchService
_connectorVersion = typeof(SourceFetchService).Assembly.GetName().Version?.ToString() ?? "0.0.0";
}
// Backward-compatible constructor until all callers provide the storage document contract explicitly.
public SourceFetchService(
IHttpClientFactory httpClientFactory,
RawDocumentStorage rawDocumentStorage,
MongoContracts.IDocumentStore documentStore,
ILogger<SourceFetchService> logger,
IJitterSource jitterSource,
IAdvisoryRawWriteGuard guard,
IAdvisoryLinksetMapper linksetMapper,
ICryptoHash hash,
TimeProvider? timeProvider = null,
IOptionsMonitor<SourceHttpClientOptions>? httpClientOptions = null,
IOptions<MongoContracts.MongoStorageOptions>? storageOptions = null)
: this(
httpClientFactory,
rawDocumentStorage,
documentStore,
documentStore as StorageContracts.IStorageDocumentStore
?? throw new ArgumentNullException(nameof(documentStore), "Document store must implement IStorageDocumentStore"),
logger,
jitterSource,
guard,
linksetMapper,
hash,
timeProvider,
httpClientOptions,
storageOptions)
{
}
public async Task<SourceFetchResult> FetchAsync(SourceFetchRequest request, CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(request);
@@ -147,7 +181,7 @@ public sealed class SourceFetchService
}
}
var existing = await _documentStore.FindBySourceAndUriAsync(request.SourceName, request.RequestUri.ToString(), cancellationToken).ConfigureAwait(false);
var existing = await _storageDocumentStore.FindBySourceAndUriAsync(request.SourceName, request.RequestUri.ToString(), cancellationToken).ConfigureAwait(false);
var recordId = existing?.Id ?? Guid.NewGuid();
var payloadId = await _rawDocumentStorage.UploadAsync(
@@ -159,7 +193,7 @@ public sealed class SourceFetchService
cancellationToken,
recordId).ConfigureAwait(false);
var record = new MongoContracts.DocumentRecord(
var record = new StorageContracts.StorageDocument(
recordId,
request.SourceName,
request.RequestUri.ToString(),
@@ -173,9 +207,10 @@ public sealed class SourceFetchService
response.Content.Headers.LastModified,
payloadId,
expiresAt,
Payload: contentBytes);
Payload: contentBytes,
FetchedAt: fetchedAt);
var upserted = await _documentStore.UpsertAsync(record, cancellationToken).ConfigureAwait(false);
var upserted = await _storageDocumentStore.UpsertAsync(record, cancellationToken).ConfigureAwait(false);
SourceDiagnostics.RecordHttpRequest(request.SourceName, request.ClientName, response.StatusCode, sendResult.Attempts, duration, contentBytes.LongLength, rateLimitRemaining);
activity?.SetStatus(ActivityStatusCode.Ok);
_logger.LogInformation("Fetched {Source} document {Uri} (sha256={Sha})", request.SourceName, request.RequestUri, contentHash);