dotnet-cqrs/Svrnty.CQRS.Events.Abstractions/Delivery/IExternalEventDeliveryProvider.cs

118 lines
5.1 KiB
C#

using System;
using Svrnty.CQRS.Events.Abstractions.Delivery;
using Svrnty.CQRS.Events.Abstractions.EventStore;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace Svrnty.CQRS.Events.Abstractions.Delivery;
/// <summary>
/// Extended delivery provider interface for cross-service event delivery via external message brokers.
/// </summary>
/// <remarks>
/// <para>
/// This interface extends <see cref="IEventDeliveryProvider"/> with capabilities for publishing
/// events to external services and subscribing to events from external services.
/// </para>
/// <para>
/// <strong>Use Cases:</strong>
/// - Publishing events to RabbitMQ for consumption by other microservices
/// - Publishing events to Kafka for high-throughput scenarios
/// - Publishing events to Azure Service Bus or AWS SNS/SQS
/// - Subscribing to events from other services via message brokers
/// </para>
/// <para>
/// <strong>Phase 4 Implementation:</strong>
/// RabbitMQ provider with automatic topology management.
/// </para>
/// </remarks>
public interface IExternalEventDeliveryProvider : IEventDeliveryProvider
{
/// <summary>
/// Publish an event to an external service via the message broker.
/// </summary>
/// <param name="streamName">The name of the stream (maps to exchange/topic).</param>
/// <param name="event">The event to publish.</param>
/// <param name="metadata">Additional metadata (routing keys, headers, etc.).</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>A task that completes when the event is published.</returns>
/// <remarks>
/// <para>
/// This method is called by the stream store when an event needs to be published
/// externally (when StreamScope = CrossService).
/// </para>
/// <para>
/// The provider is responsible for:
/// - Serializing the event to the wire format
/// - Publishing to the appropriate exchange/topic
/// - Adding routing metadata (correlation ID, event type, etc.)
/// - Handling publish failures (retry, dead letter, etc.)
/// </para>
/// </remarks>
Task PublishExternalAsync(
string streamName,
ICorrelatedEvent @event,
IDictionary<string, string>? metadata = null,
CancellationToken cancellationToken = default);
/// <summary>
/// Subscribe to events from an external service via the message broker.
/// </summary>
/// <param name="streamName">The name of the remote stream (maps to exchange/topic).</param>
/// <param name="subscriptionId">The subscription identifier (maps to queue name).</param>
/// <param name="consumerId">The consumer identifier (for consumer groups).</param>
/// <param name="eventHandler">Handler called when events are received.</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>A task that represents the subscription lifecycle.</returns>
/// <remarks>
/// <para>
/// This method establishes a subscription to an external event stream from another service.
/// The provider is responsible for:
/// - Creating the necessary topology (queue, bindings, etc.)
/// - Deserializing incoming messages
/// - Invoking the event handler
/// - Managing acknowledgments and redelivery
/// </para>
/// <para>
/// The subscription remains active until the cancellation token is triggered or
/// an unrecoverable error occurs.
/// </para>
/// </remarks>
Task SubscribeExternalAsync(
string streamName,
string subscriptionId,
string consumerId,
Func<ICorrelatedEvent, IDictionary<string, string>, CancellationToken, Task> eventHandler,
CancellationToken cancellationToken = default);
/// <summary>
/// Unsubscribe from an external event stream.
/// </summary>
/// <param name="streamName">The name of the remote stream.</param>
/// <param name="subscriptionId">The subscription identifier.</param>
/// <param name="consumerId">The consumer identifier.</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>A task that completes when the unsubscription is finished.</returns>
/// <remarks>
/// This method cleans up resources associated with the subscription.
/// Depending on the provider, this may delete queues or simply disconnect.
/// </remarks>
Task UnsubscribeExternalAsync(
string streamName,
string subscriptionId,
string consumerId,
CancellationToken cancellationToken = default);
/// <summary>
/// Check if this provider supports the specified stream for external delivery.
/// </summary>
/// <param name="streamName">The stream name to check.</param>
/// <returns>True if the provider can handle this stream, false otherwise.</returns>
/// <remarks>
/// This allows routing different streams to different providers based on configuration.
/// For example, "orders.*" might route to RabbitMQ while "analytics.*" routes to Kafka.
/// </remarks>
bool SupportsStream(string streamName);
}