как сериализовать класс .Net в Avro.Generic.GenericRecord для публикации в теме кафки? - PullRequest
0 голосов
/ 04 декабря 2018

Я пытаюсь найти способ / помощника для преобразования .Net Class в 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 голосов
/ 06 декабря 2018

Ниже приведены шаги, которые я предпринял для решения проблемы, используя предложение @cricket_007.

  1. Чтобы избежать сложности написания схемы avro, сначала создайте классы c #, а затем используйте AvroSerializer для генерации схемы,

AvroSerializer.Create (). WriterSchema.ToString ()

Это сгенерирует схему json для класса.Переместите его в файл схемы и Сделайте так, чтобы все типы имели нулевые значения, как требуется Затем использовали инструмент avro_gen.exe для восстановления файлов классов, который реализует ISpecific Record.

Добавьте используемый ниже код для публикации в очередь

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

0 голосов
/ 05 декабря 2018

Предполагая, что вы используете 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 , а не сериализацию туда-сюда между Avro и классом .NET через GenericRecord.См. Раздел README в инструменте AvroGen для примеров этого

1.Мне неизвестна альтернативная библиотека .NET

...