private async Task DoWork(CancellationToken stoppingToken) { var config = new ConsumerConfig { GroupId = ConsumerGroup, BootstrapServers = KafkaServers, AutoOffsetReset = AutoOffsetReset.Earliest }; _logger.Information($"{GetType().Name}: Creating consumer for '{ConsumerGroup}' pointed at '{KafkaServers}'."); using var consumer = new ConsumerBuilder <Ignore, string>(config).Build(); _logger.Information($"{GetType().Name}: Subscribing the consumer to topic '{KafkaTopic}'."); consumer.Subscribe(KafkaTopic); try { while (!stoppingToken.IsCancellationRequested) { try { _logger.Information($"{GetType().Name}: Consuming next message."); var result = consumer.Consume(stoppingToken); _logger.Information($"{GetType().Name}: Consumed message '{result.Message.Value}' at offset '{result.TopicPartitionOffset}'."); if (_messageDeserializer.TryDeserializeEvent(result.Message.Value, out BookingCreated bookingCreated)) { _logger.Information($"{GetType().Name}: Message {result.Message.Value} is recognized by {GetType().Name} as {nameof(BookingCreated)} event and will be processed."); await _busControl.Send <IBookingCreated>( new { bookingCreated.BookingId, DateTime.UtcNow }, stoppingToken); _logger.Information($"{GetType().Name}: Message {result.Message.Value} was processed."); continue; } _logger.Information($"{GetType().Name}: Message {result.Message.Value} is not recognized by {GetType().Name} and will be skipped."); } catch (ConsumeException e) { _logger.Error($"{GetType().Name}: Error occurred: {e.Error.Reason}."); } } } catch (OperationCanceledException) { // Ensure the consumer leaves the group cleanly and final offsets are committed. consumer.Close(); } }