如果 avro 模式包含联合,如何将 json 对象转换为 Avro 对象

Mac*_*Mac 5 api json avro

给定的示例架构包含一个字段,它是 null 和字符串的并集,

架构

    {
  "type":"record",
  "name":"DataFlowEntity",
  "namespace":"org.sdf.manage.commons.server",
  "fields":
  [
    {"name":"dataTypeGroupName","type":["null","string"]},
    {"name":"dataTypeName","type":"string"},
    {"name":"dataSchemaVersion","type":"string"}
  ]
}
Run Code Online (Sandbox Code Playgroud)

我想转换以下 json 对象,

目的

{
  "dataTypeGroupName": "dg_1",
  "dataTypeName": "dt_1",
  "dataSchemaVersion": "1"
}
Run Code Online (Sandbox Code Playgroud)

进入与上述模式对应的 avro 对象。我尝试使用 Avro 的 JsonDecoder 和下面描述的代码 snppet,

    String dataFlowEntity = "{\"dataTypeGroupName\": \"dg_1\", \"dataTypeName\": \"dt_1\", \"dataSchemaVersion\": \"1\"}";
    Schema schema = DataFlowEntity.SCHEMA$;
    InputStream inputStream = new ByteArrayInputStream(dataFlowEntity.getBytes());
    DataInputStream dInputStream = new DataInputStream(inputStream);
    Decoder decoder = DecoderFactory.get().jsonDecoder(schema, dInputStream);
    DatumReader<DataFlowEntity> datumReader = new GenericDatumReader<DataFlowEntity>(schema);
    DataFlowEntity dataFlowEntityObject = DataFlowEntity.newBuilder().build();
    dataFlowEntityObject = datumReader.read(null, decoder);
Run Code Online (Sandbox Code Playgroud)

它无一例外地失败,

threw exception [org.apache.avro.AvroRuntimeException: org.apache.avro.AvroRuntimeException: Field dataTypeGroupName type:UNION pos:0 not set and has no default value] with root cause
org.apache.avro.AvroRuntimeException: Field dataTypeGroupName type:UNION pos:0 not set and has no default value
  at org.apache.avro.generic.GenericData.getDefaultValue(GenericData.java:874)
  at org.apache.avro.data.RecordBuilderBase.defaultValue(RecordBuilderBase.java:135)
Run Code Online (Sandbox Code Playgroud)

ppe*_*rcy 0

有一个新的 JSON 编码器正在开发中,应该可以解决这个常见问题:

https://issues.apache.org/jira/browse/AVRO-1582

https://github.com/zolyfarkas/avro

这似乎是很多人在使用 Avro 时遇到的常见问题。

如果你将你的 JSON 切换到这个,它应该可以工作:

{
  "dataTypeGroupName": {"string" : "dg_1"},
  "dataTypeName": "dt_1",
  "dataSchemaVersion": "1"
}
Run Code Online (Sandbox Code Playgroud)

这是因为 Avro 使用对象类型包装器对联合进行编码,不幸的是,即使是简单的联合来表示不需要 JSON 对象包装器来消除歧义的可选类型。Avro 的意图似乎从来都不是生成友好的 JSON,更重要的是使用 JSON 作为序列化格式。

有关更多详细信息: https://avro.apache.org/docs/1.7.7/spec.html#json_encoding