@@ -0,0 +1,95 @@ | |||
using System; | |||
using System.Collections.Generic; | |||
using System.Linq; | |||
using System.Text; | |||
using Cap.Consistency.Infrastructure; | |||
using Confluent.Kafka; | |||
using Confluent.Kafka.Serialization; | |||
namespace Cap.Consistency.Consumer.Kafka | |||
{ | |||
public class KafkaTopicPartition | |||
{ | |||
public string Topic { get; set; } | |||
public int Partition { get; set; } | |||
} | |||
public class KafkaConsumerClient : IDisposable | |||
{ | |||
private readonly string _groupId; | |||
private readonly string _bootstrapServers; | |||
private Consumer<Null, string> _consumerClient; | |||
public event EventHandler<DeliverMessage> MessageReceieved; | |||
public IDeserializer<string> StringDeserializer { get; set; } | |||
public KafkaConsumerClient(string groupId, string bootstrapServers) { | |||
_groupId = groupId; | |||
_bootstrapServers = bootstrapServers; | |||
StringDeserializer = new StringDeserializer(Encoding.UTF8); | |||
} | |||
public void Subscribe(string topicName, int partition) { | |||
if (_consumerClient == null) { | |||
InitKafkaClient(); | |||
} | |||
_consumerClient.Assignment.Add(new TopicPartition(topicName, partition)); | |||
} | |||
public void Subscribe(IEnumerable<KafkaTopicPartition> topicList) { | |||
if (_consumerClient == null) { | |||
InitKafkaClient(); | |||
} | |||
if (topicList == null || topicList.Count() == 0) { | |||
throw new ArgumentNullException(nameof(topicList)); | |||
} | |||
foreach (var item in topicList) { | |||
Subscribe(item.Topic, item.Partition); | |||
} | |||
} | |||
public void Listening(TimeSpan timeout) { | |||
while (true) { | |||
_consumerClient.Poll(timeout); | |||
} | |||
} | |||
public void Dispose() { | |||
_consumerClient.Dispose(); | |||
} | |||
#region private methods | |||
private void InitKafkaClient() { | |||
var config = new Dictionary<string, object>{ | |||
{ "group.id", "simple-csharp-consumer" }, | |||
{ "bootstrap.servers", _bootstrapServers } | |||
}; | |||
_consumerClient = new Consumer<Null, string>(config, null, StringDeserializer); | |||
_consumerClient.OnMessage += ConsumerClient_OnMessage; | |||
} | |||
private void ConsumerClient_OnMessage(object sender, Message<Null, string> e) { | |||
var message = new DeliverMessage { | |||
MessageKey = e.Topic, | |||
Value = e.Value | |||
}; | |||
MessageReceieved?.Invoke(sender, message); | |||
} | |||
#endregion | |||
//public void | |||
} | |||
} |
@@ -0,0 +1,75 @@ | |||
//using System; | |||
//using System.Collections.Generic; | |||
//using System.Text; | |||
//using System.Linq; | |||
//using System.Threading.Tasks; | |||
//using Cap.Consistency.Abstractions; | |||
//using Cap.Consistency.Infrastructure; | |||
//using Cap.Consistency.Routing; | |||
//using Confluent.Kafka; | |||
//using Confluent.Kafka.Serialization; | |||
//using Microsoft.AspNetCore.Builder; | |||
//using Microsoft.Extensions.Logging; | |||
//using Microsoft.Extensions.Options; | |||
//namespace Cap.Consistency.Consumer.Kafka | |||
//{ | |||
// public class KafkaConsumerHandler<T> : ConsumerHandler<T> where T : ConsistencyMessage, new() | |||
// { | |||
// protected override void OnMessageReceieved(T message) { | |||
// } | |||
// public Task RouteAsync(TopicRouteContext context) { | |||
// if (context == null) { | |||
// throw new ArgumentNullException(nameof(context)); | |||
// } | |||
// context.ServiceProvider = _serviceProvider; | |||
// var matchs = _selector.SelectCandidates(context); | |||
// var config = new Dictionary<string, object> | |||
// { | |||
// { "group.id", "simple-csharp-consumer" }, | |||
// { "bootstrap.servers", _options.BrokerUrlList } | |||
// }; | |||
// using (var consumer = new Consumer<Null, string>(config, null, new StringDeserializer(Encoding.UTF8))) { | |||
// var topicList = matchs.Select(item => new TopicPartitionOffset(item.Topic.Name, item.Topic.Partition, new Offset(item.Topic.Offset))); | |||
// consumer.Assign(topicList); | |||
// while (true) { | |||
// if (consumer.Consume(out Message<Null, string> msg)) { | |||
// T consistencyMessage = new T(); | |||
// var message = new DeliverMessage() { | |||
// MessageKey = msg.Topic, | |||
// Body = Encoding.UTF8.GetBytes(msg.Value) | |||
// }; | |||
// var routeContext = new TopicRouteContext(message); | |||
// var executeDescriptor = _selector.SelectBestCandidate(routeContext, matchs); | |||
// if (executeDescriptor == null) { | |||
// _logger.LogInformation("can not be fond topic execute"); | |||
// return Task.CompletedTask; | |||
// } | |||
// var consumerContext = new ConsumerContext(executeDescriptor, message); | |||
// var invoker = _consumerInvokerFactory.CreateInvoker(consumerContext); | |||
// _logger.LogInformation("consumer starting"); | |||
// return invoker.InvokeAsync(); | |||
// } | |||
// } | |||
// } | |||
// } | |||
// } | |||
//} |