This commit is contained in:
StellaOps Bot
2025-12-13 02:22:15 +02:00
parent 564df71bfb
commit 999e26a48e
395 changed files with 25045 additions and 2224 deletions

View File

@@ -0,0 +1,80 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using StellaOps.Messaging;
using StellaOps.Messaging.Abstractions;
using StellaOps.Scanner.WebService.Contracts;
using StellaOps.Scanner.WebService.Options;
namespace StellaOps.Scanner.WebService.Services;
/// <summary>
/// Transport-agnostic implementation of <see cref="IPlatformEventPublisher"/> using StellaOps.Messaging abstractions.
/// Works with any configured transport (Valkey, PostgreSQL, InMemory).
/// </summary>
internal sealed class MessagingPlatformEventPublisher : IPlatformEventPublisher
{
private readonly IEventStream<OrchestratorEvent> _eventStream;
private readonly ILogger<MessagingPlatformEventPublisher> _logger;
private readonly TimeSpan _publishTimeout;
private readonly long? _maxStreamLength;
public MessagingPlatformEventPublisher(
IEventStreamFactory eventStreamFactory,
IOptions<ScannerWebServiceOptions> options,
ILogger<MessagingPlatformEventPublisher> logger)
{
ArgumentNullException.ThrowIfNull(eventStreamFactory);
ArgumentNullException.ThrowIfNull(options);
var eventsOptions = options.Value.Events ?? throw new InvalidOperationException("Events options are required when messaging publisher is registered.");
if (!eventsOptions.Enabled)
{
throw new InvalidOperationException("MessagingPlatformEventPublisher requires events emission to be enabled.");
}
var streamName = string.IsNullOrWhiteSpace(eventsOptions.Stream) ? "stella.events" : eventsOptions.Stream;
_maxStreamLength = eventsOptions.MaxStreamLength > 0 ? eventsOptions.MaxStreamLength : null;
_publishTimeout = TimeSpan.FromSeconds(eventsOptions.PublishTimeoutSeconds <= 0 ? 5 : eventsOptions.PublishTimeoutSeconds);
_eventStream = eventStreamFactory.Create<OrchestratorEvent>(new EventStreamOptions
{
StreamName = streamName,
MaxLength = _maxStreamLength,
ApproximateTrimming = true,
});
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_logger.LogInformation("Initialized messaging platform event publisher for stream {Stream}.", streamName);
}
public async Task PublishAsync(OrchestratorEvent @event, CancellationToken cancellationToken = default)
{
ArgumentNullException.ThrowIfNull(@event);
cancellationToken.ThrowIfCancellationRequested();
var publishOptions = new EventPublishOptions
{
IdempotencyKey = @event.IdempotencyKey,
TenantId = @event.Tenant,
CorrelationId = @event.CorrelationId,
MaxStreamLength = _maxStreamLength,
Headers = new Dictionary<string, string>
{
["kind"] = @event.Kind,
["occurredAt"] = @event.OccurredAt.ToString("O")
}
};
var publishTask = _eventStream.PublishAsync(@event, publishOptions, cancellationToken);
if (_publishTimeout > TimeSpan.Zero)
{
await publishTask.AsTask().WaitAsync(_publishTimeout, cancellationToken).ConfigureAwait(false);
}
else
{
await publishTask.ConfigureAwait(false);
}
}
}