namespace EventBusKafka; public class EventBusKafka : IEventBus, IDisposable { // for now use single topic and event names as keys for messages // such that they always land in same partition and we have ordering guarantee // then the consumers have to ignore events they are not subscribed to // alternatively could have multiple topics (associated with event name) private readonly string _topicName = "eshop_event_bus"; private readonly IKafkaPersistentConnection _persistentConnection; private readonly ILogger _logger; private readonly IEventBusSubscriptionsManager _subsManager; private readonly int _retryCount; private const string INTEGRATION_EVENT_SUFFIX = "IntegrationEvent"; // Object that will be registered as singleton to each service on startup, // which will be used to publish and subscribe to events. public EventBusKafka(IKafkaPersistentConnection persistentConnection, ILogger logger, IEventBusSubscriptionsManager subsManager, int retryCount = 5) { _persistentConnection = persistentConnection ?? throw new ArgumentNullException(nameof(persistentConnection)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); _subsManager = subsManager ?? new InMemoryEventBusSubscriptionsManager(); _retryCount = retryCount; } public void Publish(IntegrationEvent @event) { var eventName = @event.GetType().Name.Replace(INTEGRATION_EVENT_SUFFIX, ""); var jsonMessage = JsonSerializer.Serialize(@event, @event.GetType()); // map Integration event to kafka message // event name something like OrderPaymentSucceededIntegrationEvent var message = new Message { Key = eventName, Value = jsonMessage }; IProducer kafkaHandle = new DependentProducerBuilder(_persistentConnection.Handle).Build(); kafkaHandle.ProduceAsync(_topicName, message); } public void Subscribe() where T : IntegrationEvent where TH : IIntegrationEventHandler { throw new NotImplementedException(); } public void SubscribeDynamic(string eventName) where TH : IDynamicIntegrationEventHandler { throw new NotImplementedException(); } // Taken directly from rabbitMQ implementation public void UnsubscribeDynamic(string eventName) where TH : IDynamicIntegrationEventHandler { _subsManager.RemoveDynamicSubscription(eventName); } // Taken directly from rabbitMQ implementation public void Unsubscribe() where T : IntegrationEvent where TH : IIntegrationEventHandler { var eventName = _subsManager.GetEventKey(); _logger.LogInformation("Unsubscribing from event {EventName}", eventName); _subsManager.RemoveSubscription(); } public void Dispose() { _subsManager.Clear(); } }