GenericRecord для объекта SpecificRecord с использованием Avro
Я использую Confluent.Kafka.Avro
для сериализации между производителем и потребителем для Apache Kafka. От производителя я использую конкретную запись, но на стороне потребителя я хочу использовать все записи как общие, а затем преобразовать их в конкретные записи. Есть ли способ сделать это автоматически? Или нужно реализовать все это преобразование?
1 ответ
Если у вас есть конкретная запись и вы знаете, что можете преобразовать в нее, вам следует использовать Kafka's SpecificRecord
десериализатор. Я считаю, что единственные ситуации, в которых преобразование вGenericRecord
в вашем потребителе Kafka имеет смысл, когда вы знаете, что контент Avro не может быть десериализован с использованием ваших текущих конкретных классов данных, потому что либо у вас нет каких-либо конкретных классов данных для этих данных (схема / сообщение заранее не известны), или схема изменилась несовместимым образом, и поэтому данные не могут быть десериализованы в ваш текущий SpecificRecord
классы. Ни одна из этих ситуаций не может относиться к вам, поскольку вы прямо заявляете, что у вас естьSpecificRecord
занятия необходимы.
При этом, согласно моему ответу здесь /questions/4380175/mozhno-li-preobrazovat-obschuyu-zapis-v-konkretnuyu-zapis-s-toj-zhe-shemoj/55461591#55461591, вы можете преобразовать AvroGenericRecord
к SpecificRecord
с помощью deepCopy
:
SpecificData.get().deepCopy(genericRecord.schema, genericRecord)
Вы должны реализовать его самостоятельно, однако решение на самом деле не связано с Kafka, потому что, как только вы используете и десериализуете данные, вы можете манипулировать этой информацией так, как можете.
Однако в Определенном десериализаторе Avro он не примет тип GenericRecord, потому что Generics не реализует ISpecificRecord
или подклассы SpecificFixed
else
{
throw new ArgumentException(
$"{nameof(AvroDeserializer<T>)} " +
"only accepts type parameters of int, bool, double, string, float, " +
"long, byte[], instances of ISpecificRecord and subclasses of SpecificFixed."
);
}
Если вы все равно собираетесь конвертировать в SpecificRecord, то вам просто нужно использовать десериализатор SpecificRecord