This commit is contained in:
StellaOps Bot
2025-12-09 00:20:52 +02:00
parent 3d01bf9edc
commit bc0762e97d
261 changed files with 14033 additions and 4427 deletions

View File

@@ -0,0 +1,105 @@
using System;
namespace StellaOps.Signals.Options;
/// <summary>
/// Configuration for reachability fact events (SIGNALS-24-005).
/// </summary>
public sealed class SignalsEventsOptions
{
/// <summary>
/// Enables event emission. When false, events are dropped.
/// </summary>
public bool Enabled { get; set; } = true;
/// <summary>
/// Transport driver: "inmemory" or "redis".
/// </summary>
public string Driver { get; set; } = "inmemory";
/// <summary>
/// Primary topic/stream name for fact updates.
/// </summary>
public string Stream { get; set; } = "signals.fact.updated.v1";
/// <summary>
/// Dead-letter topic/stream used when publishing fails.
/// </summary>
public string DeadLetterStream { get; set; } = "signals.fact.updated.dlq";
/// <summary>
/// Connection string for Redis streams (when Driver=redis).
/// </summary>
public string? ConnectionString { get; set; }
/// <summary>
/// Optional publish timeout (seconds). Set to 0 to disable.
/// </summary>
public int PublishTimeoutSeconds { get; set; } = 5;
/// <summary>
/// Approximate maximum stream length (capped by Redis trimming).
/// </summary>
public long MaxStreamLength { get; set; } = 10_000;
/// <summary>
/// Producer identifier for observability payloads.
/// </summary>
public string Producer { get; set; } = "StellaOps.Signals";
/// <summary>
/// Pipeline name attached to event metadata.
/// </summary>
public string Pipeline { get; set; } = "signals";
/// <summary>
/// Optional release string to stamp events with build provenance.
/// </summary>
public string? Release { get; set; }
/// <summary>
/// Default tenant when none is supplied in metadata.
/// </summary>
public string DefaultTenant { get; set; } = "tenant-default";
public void Validate()
{
var normalizedDriver = Driver?.Trim();
if (string.IsNullOrWhiteSpace(normalizedDriver))
{
throw new InvalidOperationException("Signals events driver is required.");
}
if (!string.Equals(normalizedDriver, "redis", StringComparison.OrdinalIgnoreCase)
&& !string.Equals(normalizedDriver, "inmemory", StringComparison.OrdinalIgnoreCase))
{
throw new InvalidOperationException("Signals events driver must be 'redis' or 'inmemory'.");
}
if (string.IsNullOrWhiteSpace(Stream))
{
throw new InvalidOperationException("Signals events stream/topic is required.");
}
if (PublishTimeoutSeconds < 0)
{
throw new InvalidOperationException("Signals events publish timeout must be >= 0 seconds.");
}
if (MaxStreamLength < 0)
{
throw new InvalidOperationException("Signals events max stream length must be >= 0.");
}
if (string.IsNullOrWhiteSpace(DefaultTenant))
{
throw new InvalidOperationException("Signals events default tenant is required.");
}
if (string.Equals(normalizedDriver, "redis", StringComparison.OrdinalIgnoreCase)
&& string.IsNullOrWhiteSpace(ConnectionString))
{
throw new InvalidOperationException("Signals events Redis driver requires ConnectionString.");
}
}
}

View File

@@ -1,26 +1,26 @@
namespace StellaOps.Signals.Options;
/// <summary>
/// Root configuration for the Signals service.
/// </summary>
public sealed class SignalsOptions
{
/// <summary>
/// Configuration section name.
/// </summary>
public const string SectionName = "Signals";
/// <summary>
/// Authority integration settings.
/// </summary>
public SignalsAuthorityOptions Authority { get; } = new();
/// <summary>
/// MongoDB configuration.
/// </summary>
public SignalsMongoOptions Mongo { get; } = new();
/// <summary>
namespace StellaOps.Signals.Options;
/// <summary>
/// Root configuration for the Signals service.
/// </summary>
public sealed class SignalsOptions
{
/// <summary>
/// Configuration section name.
/// </summary>
public const string SectionName = "Signals";
/// <summary>
/// Authority integration settings.
/// </summary>
public SignalsAuthorityOptions Authority { get; } = new();
/// <summary>
/// MongoDB configuration.
/// </summary>
public SignalsMongoOptions Mongo { get; } = new();
/// <summary>
/// Artifact storage configuration.
/// </summary>
public SignalsArtifactStorageOptions Storage { get; } = new();
@@ -40,22 +40,28 @@ public sealed class SignalsOptions
/// </summary>
public SignalsCacheOptions Cache { get; } = new();
/// <summary>
/// Event transport configuration.
/// </summary>
public SignalsEventsOptions Events { get; } = new();
/// <summary>
/// OpenAPI exposure (if enabled).
/// </summary>
public SignalsOpenApiOptions OpenApi { get; } = new();
/// <summary>
/// Validates configured options.
/// </summary>
public void Validate()
{
/// <summary>
/// Validates configured options.
/// </summary>
public void Validate()
{
Authority.Validate();
Mongo.Validate();
Storage.Validate();
AirGap.Validate();
Scoring.Validate();
Cache.Validate();
Events.Validate();
OpenApi.Validate();
}
}