如何将.Net类序列化为Avro.Generic.GenericRecord以发布到kafka主题中?

时间:2018-12-04 19:50:14

标签: c# serialization apache-kafka avro kafka-producer-api

我试图找到一种方法/帮助程序,以将.Net类转换为Avro.Generic.GenericRecord。目前,我正在手动将字段名称和字段值添加到通用记录。是否有一个序列化器/转换器,可以用来将对象转换为通用记录并发布到kafka主题上。

class Plant
{
 public long Id { get; set; }
 public string Name { get; set; }
 public List<PlantProperties> PlantProperties{ get; set; }
}
class PlantProperties
{
 public long Leaves{ get; set; }
 public string Color{ get; set; }
}

请提出建议。

2 个答案:

答案 0 :(得分:0)

假设您正在使用Confluent Schema Regsitry,则可以使用其.NET客户端 1

https://github.com/confluentinc/confluent-kafka-dotnet

从示例文件夹中复制

    using (var serdeProvider = new AvroSerdeProvider(avroConfig))
    using (var producer = new Producer<string, GenericRecord>(producerConfig, serdeProvider.GetSerializerGenerator<string>(), serdeProvider.GetSerializerGenerator<GenericRecord>()))
    {
        Console.WriteLine($"{producer.Name} producing on {topicName}. Enter user names, q to exit.");

        int i = 0;
        string text;
        while ((text = Console.ReadLine()) != "q")
        {
            var record = new GenericRecord(s);
            record.Add("name", text);
            record.Add("favorite_number", i++);
            record.Add("favorite_color", "blue");

            producer
                .ProduceAsync(topicName, new Message<string, GenericRecord> { Key = text, Value = record })
                .ContinueWith(task => task.IsFaulted
                    ? $"error producing message: {task.Exception.Message}"
                    : $"produced to: {task.Result.TopicPartitionOffset}");
        }
    }

    cts.Cancel();
}

根据您的情况,相应地更新record.Add的使用方式


但是,由于您拥有一个类,因此,您应该尝试使用 SpecificRecord ,而不是通过GenericRecord在Avro和.NET类之间来回序列化。有关此示例

的信息,请参阅AvroGen工具上的README部分。

1。我不知道其他的.NET库

答案 1 :(得分:0)

下面是我使用@ cricket_007的建议来解决问题的步骤。

  1. 为避免编写avro模式的复杂性,请先创建c#类,然后使用AvroSerializer生成模式。
  

AvroSerializer.Create()。WriterSchema.ToString()

  1. 这将为该类生成模式json。 将其移至架构文件,然后
  2. 使所有类型的空值都为必填项
  3. 然后使用avro_gen.exe工具重新生成实现ISpecific Record的类文件。
  4. 添加使用下面的代码发布到队列中

    using (var serdeProvider = new AvroSerdeProvider(avroConfig))
            using (var producer = new Producer<string, MYClass>(producerConfig, 
      serdeProvider.GetSerializerGenerator<string>(), 
      serdeProvider.GetSerializerGenerator<MYClass>()))
            {
                Console.WriteLine($"{producer.Name} producing on 
           {_appSettings.PullListKafka.Topic}.");  
    
                producer.ProduceAsync(_appSettings.PullListKafka.Topic, new 
    Message<string, MYClass> { Key = Guid.NewGuid().ToString(), Value = MYClassObject})
                        .ContinueWith(task => task.IsFaulted
                            ? $"error producing message: {task.Exception.Message}"
                            : $"produced to: {task.Result.TopicPartitionOffset}");
    
            }
    

一些帮助实现此目的的链接。

https://shanidgafur.github.io/blog/apache-avro-on-dotnet https://github.com/SidShetye/HelloAvro/tree/master/Avro