Rename Feedser to Concelier

This commit is contained in:
master
2025-10-18 20:04:15 +03:00
parent dd66f58b00
commit 89ede53cc3
1208 changed files with 4370 additions and 4370 deletions

View File

@@ -0,0 +1,11 @@
using System.Threading;
using System.Threading.Tasks;
namespace StellaOps.Concelier.Storage.Mongo.PsirtFlags;
public interface IPsirtFlagStore
{
Task UpsertAsync(PsirtFlagRecord record, CancellationToken cancellationToken);
Task<PsirtFlagRecord?> FindAsync(string advisoryKey, CancellationToken cancellationToken);
}

View File

@@ -0,0 +1,52 @@
using MongoDB.Bson.Serialization.Attributes;
namespace StellaOps.Concelier.Storage.Mongo.PsirtFlags;
[BsonIgnoreExtraElements]
public sealed class PsirtFlagDocument
{
[BsonId]
[BsonElement("advisoryKey")]
public string AdvisoryKey { get; set; } = string.Empty;
[BsonElement("vendor")]
public string Vendor { get; set; } = string.Empty;
[BsonElement("sourceName")]
public string SourceName { get; set; } = string.Empty;
[BsonElement("advisoryIdText")]
public string AdvisoryIdText { get; set; } = string.Empty;
[BsonElement("flaggedAt")]
public DateTime FlaggedAt { get; set; }
}
internal static class PsirtFlagDocumentExtensions
{
public static PsirtFlagDocument FromRecord(PsirtFlagRecord record)
{
ArgumentNullException.ThrowIfNull(record);
return new PsirtFlagDocument
{
AdvisoryKey = string.IsNullOrWhiteSpace(record.AdvisoryKey) ? record.AdvisoryIdText : record.AdvisoryKey,
Vendor = record.Vendor,
SourceName = record.SourceName,
AdvisoryIdText = record.AdvisoryIdText,
FlaggedAt = record.FlaggedAt.UtcDateTime,
};
}
public static PsirtFlagRecord ToRecord(this PsirtFlagDocument document)
{
ArgumentNullException.ThrowIfNull(document);
return new PsirtFlagRecord(
document.AdvisoryKey,
document.Vendor,
document.SourceName,
document.AdvisoryIdText,
DateTime.SpecifyKind(document.FlaggedAt, DateTimeKind.Utc));
}
}

View File

@@ -0,0 +1,15 @@
namespace StellaOps.Concelier.Storage.Mongo.PsirtFlags;
/// <summary>
/// Describes a PSIRT precedence flag for a canonical advisory.
/// </summary>
public sealed record PsirtFlagRecord(
string AdvisoryKey,
string Vendor,
string SourceName,
string AdvisoryIdText,
DateTimeOffset FlaggedAt)
{
public PsirtFlagRecord WithFlaggedAt(DateTimeOffset flaggedAt)
=> this with { FlaggedAt = flaggedAt.ToUniversalTime() };
}

View File

@@ -0,0 +1,50 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using MongoDB.Driver;
namespace StellaOps.Concelier.Storage.Mongo.PsirtFlags;
public sealed class PsirtFlagStore : IPsirtFlagStore
{
private readonly IMongoCollection<PsirtFlagDocument> _collection;
private readonly ILogger<PsirtFlagStore> _logger;
public PsirtFlagStore(IMongoDatabase database, ILogger<PsirtFlagStore> logger)
{
ArgumentNullException.ThrowIfNull(database);
ArgumentNullException.ThrowIfNull(logger);
_collection = database.GetCollection<PsirtFlagDocument>(MongoStorageDefaults.Collections.PsirtFlags);
_logger = logger;
}
public async Task UpsertAsync(PsirtFlagRecord record, CancellationToken cancellationToken)
{
ArgumentNullException.ThrowIfNull(record);
ArgumentException.ThrowIfNullOrEmpty(record.AdvisoryKey);
var document = PsirtFlagDocumentExtensions.FromRecord(record);
var filter = Builders<PsirtFlagDocument>.Filter.Eq(x => x.AdvisoryKey, record.AdvisoryKey);
var options = new ReplaceOptions { IsUpsert = true };
try
{
await _collection.ReplaceOneAsync(filter, document, options, cancellationToken).ConfigureAwait(false);
_logger.LogDebug("Upserted PSIRT flag for {AdvisoryKey}", record.AdvisoryKey);
}
catch (MongoWriteException ex) when (ex.WriteError?.Category == ServerErrorCategory.DuplicateKey)
{
_logger.LogWarning(ex, "Duplicate PSIRT flag detected for {AdvisoryKey}", record.AdvisoryKey);
}
}
public async Task<PsirtFlagRecord?> FindAsync(string advisoryKey, CancellationToken cancellationToken)
{
ArgumentException.ThrowIfNullOrEmpty(advisoryKey);
var filter = Builders<PsirtFlagDocument>.Filter.Eq(x => x.AdvisoryKey, advisoryKey);
var document = await _collection.Find(filter).FirstOrDefaultAsync(cancellationToken).ConfigureAwait(false);
return document?.ToRecord();
}
}