132 lines
4.7 KiB
C#
132 lines
4.7 KiB
C#
using StellaOps.Determinism;
|
|
|
|
namespace StellaOps.Provcache.Events;
|
|
|
|
/// <summary>
|
|
/// Event published when an advisory feed advances to a new epoch.
|
|
/// Provcache subscribers use this to invalidate cache entries
|
|
/// that were computed against older feed epochs.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Stream name: <c>stellaops:events:feed-epoch-advanced</c>
|
|
/// </remarks>
|
|
public sealed record FeedEpochAdvancedEvent
|
|
{
|
|
/// <summary>
|
|
/// Stream name for feed epoch events.
|
|
/// </summary>
|
|
public const string StreamName = "stellaops:events:feed-epoch-advanced";
|
|
|
|
/// <summary>
|
|
/// Event type identifier for serialization.
|
|
/// </summary>
|
|
public const string EventType = "feed.epoch.advanced.v1";
|
|
|
|
/// <summary>
|
|
/// Unique identifier for this event instance.
|
|
/// </summary>
|
|
public required Guid EventId { get; init; }
|
|
|
|
/// <summary>
|
|
/// Timestamp when the event occurred (UTC).
|
|
/// </summary>
|
|
public required DateTimeOffset Timestamp { get; init; }
|
|
|
|
/// <summary>
|
|
/// The feed identifier (e.g., "cve", "ghsa", "osv", "redhat-oval").
|
|
/// </summary>
|
|
public required string FeedId { get; init; }
|
|
|
|
/// <summary>
|
|
/// The previous epoch identifier.
|
|
/// Format varies by feed (e.g., "2024-12-24T12:00:00Z", "v2024.52").
|
|
/// </summary>
|
|
public required string PreviousEpoch { get; init; }
|
|
|
|
/// <summary>
|
|
/// The new epoch identifier.
|
|
/// </summary>
|
|
public required string NewEpoch { get; init; }
|
|
|
|
/// <summary>
|
|
/// When the new epoch became effective.
|
|
/// Cache entries with feed_epoch older than this should be invalidated.
|
|
/// </summary>
|
|
public required DateTimeOffset EffectiveAt { get; init; }
|
|
|
|
/// <summary>
|
|
/// Number of advisories added in this epoch (for metrics).
|
|
/// </summary>
|
|
public int? AdvisoriesAdded { get; init; }
|
|
|
|
/// <summary>
|
|
/// Number of advisories modified in this epoch (for metrics).
|
|
/// </summary>
|
|
public int? AdvisoriesModified { get; init; }
|
|
|
|
/// <summary>
|
|
/// Number of advisories withdrawn in this epoch (for metrics).
|
|
/// </summary>
|
|
public int? AdvisoriesWithdrawn { get; init; }
|
|
|
|
/// <summary>
|
|
/// Tenant ID if multi-tenant (null for global feeds).
|
|
/// </summary>
|
|
public string? TenantId { get; init; }
|
|
|
|
/// <summary>
|
|
/// Correlation ID for distributed tracing.
|
|
/// </summary>
|
|
public string? CorrelationId { get; init; }
|
|
|
|
/// <summary>
|
|
/// Creates a new FeedEpochAdvancedEvent.
|
|
/// </summary>
|
|
/// <param name="feedId">The feed identifier.</param>
|
|
/// <param name="previousEpoch">The previous epoch identifier.</param>
|
|
/// <param name="newEpoch">The new epoch identifier.</param>
|
|
/// <param name="effectiveAt">When the new epoch became effective.</param>
|
|
/// <param name="advisoriesAdded">Number of advisories added (for metrics).</param>
|
|
/// <param name="advisoriesModified">Number of advisories modified (for metrics).</param>
|
|
/// <param name="advisoriesWithdrawn">Number of advisories withdrawn (for metrics).</param>
|
|
/// <param name="tenantId">Tenant ID if multi-tenant.</param>
|
|
/// <param name="correlationId">Correlation ID for tracing.</param>
|
|
/// <param name="eventId">Optional event ID (defaults to new GUID).</param>
|
|
/// <param name="timestamp">Optional timestamp (defaults to current UTC time).</param>
|
|
/// <param name="guidProvider">Optional GUID provider for deterministic IDs.</param>
|
|
/// <param name="timeProvider">Optional time provider for deterministic timestamps.</param>
|
|
public static FeedEpochAdvancedEvent Create(
|
|
string feedId,
|
|
string previousEpoch,
|
|
string newEpoch,
|
|
DateTimeOffset effectiveAt,
|
|
int? advisoriesAdded = null,
|
|
int? advisoriesModified = null,
|
|
int? advisoriesWithdrawn = null,
|
|
string? tenantId = null,
|
|
string? correlationId = null,
|
|
Guid? eventId = null,
|
|
DateTimeOffset? timestamp = null,
|
|
IGuidProvider? guidProvider = null,
|
|
TimeProvider? timeProvider = null)
|
|
{
|
|
var guidSource = guidProvider ?? SystemGuidProvider.Instance;
|
|
var timeSource = timeProvider ?? TimeProvider.System;
|
|
|
|
return new FeedEpochAdvancedEvent
|
|
{
|
|
EventId = eventId ?? guidSource.NewGuid(),
|
|
Timestamp = timestamp ?? timeSource.GetUtcNow(),
|
|
FeedId = feedId,
|
|
PreviousEpoch = previousEpoch,
|
|
NewEpoch = newEpoch,
|
|
EffectiveAt = effectiveAt,
|
|
AdvisoriesAdded = advisoriesAdded,
|
|
AdvisoriesModified = advisoriesModified,
|
|
AdvisoriesWithdrawn = advisoriesWithdrawn,
|
|
TenantId = tenantId,
|
|
CorrelationId = correlationId
|
|
};
|
|
}
|
|
}
|