Avro模式GenericRecord缺少密钥

时间:2019-11-21 07:37:01

标签: c# apache-kafka schema avro confluent

我正在使用 Avro模式,使用Confluent Kafka客户端从C#应用程序动态向Kafka群集生成消息。数据类型在编译时是未知的,因此我正在使用Avro.Generic命名空间中的 GenericRecord 类,如此处所述:https://www.confluent.io/blog/decoupling-systems-with-apache-kafka-schema-registry-and-avro/

但是,我有一个问题-如果架构中的字段可以包含空值,则仍然需要使用Add方法将该字段添加到GenericRecord中,并以null作为值。我的应用程序不知道可以为null的字段,我也不认为应该为null-因为这会违背架构中可为空字段的目的。

Avro模式:

{
  "namespace": "Test",
  "type": "record",
  "doc": "Test bool type",
  "name": "BoolType",
  "version": "1",
  "fields": [
    {
      "name": "Data",
      "type": [ "null", "boolean" ],
      "default": null
    },
    {
      "name": "Source",
      "type": "string"
    }
  ]
}

C#代码:

var valueRecord = new GenericRecord( valueAvroSchema );
valueRecord.Add( "Data", null );
valueRecord.Add( "Source", "Test app .NET" );

var messageToSend = new Message<GenericRecord, GenericRecord>
{
   Key = keyRecord,
   Value = valueRecord
};

await _producer.ProduceAsync( _topicName, messageToSend );

如果该行:

valueRecord.Add( "Data", null );

不存在,ProduceAsync方法将抛出Confluent.Kafka.ProduceException,如下面的屏幕截图所示。

enter image description here

有什么方法可以自动填充GenericRecord中可以为null的字段?如果必须使用默认值填充字段,则同样适用。

是否有任何以标准方式执行此操作的方法,或者我需要编写自己的代码以读取模式,并且如果我的应用程序尚未设置任何可为空的字段,则最后添加它们,发布?

谢谢!

1 个答案:

答案 0 :(得分:1)

Avro默认值仅与使用者相关。生产者必须始终设置每个字段