Rename Feedser to Concelier
This commit is contained in:
@@ -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);
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -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() };
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user