使用avro-protobuf将protobuf转换成avro
avro-protobuf项目提供ProtobufDatumReader类,可以用于从protobuf定义生成的java class中获得avro schema
使用方法如下:
1.引入依赖
<dependency> <groupId>org.apache.avro</groupId> <artifactId>avro-protobuf</artifactId> <version>1.11.1</version> </dependency> <dependency> <groupId>com.google.protobuf</groupId> <artifactId>protobuf-java</artifactId> <version>3.21.7</version> </dependency>
2.定义protobuf schema,名为other.proto,schema如下
syntax = "proto3"; package com.acme; message MyRecord { string f1 = 1; OtherRecord f2 = 2; } message OtherRecord { int32 other_id = 1; }
从使用protobuf定义生成java class
protoc -I=./ --java_out=./src/main/java ./src/main/proto/other.proto
3.编写java代码
package com.example.demo; import com.acme.Other; import java.util.*; import org.apache.avro.protobuf.ProtobufDatumReader; public class Demo { public static void main(String[] args) throws Exception { ProtobufDatumReader<Other.MyRecord> datumReader = new ProtobufDatumReader<Other.MyRecord>(Other.MyRecord.class); System.out.println(datumReader.getSchema().toString(true)); } }
输出如下
{ "type" : "record", "name" : "MyRecord", "namespace" : "com.acme.Other", "fields" : [ { "name" : "f1", "type" : { "type" : "string", "avro.java.string" : "String" }, "default" : "" }, { "name" : "f2", "type" : [ "null", { "type" : "record", "name" : "OtherRecord", "fields" : [ { "name" : "other_id", "type" : "int", "default" : 0 } ] } ], "default" : null } ] }
注意:该工具在把protobuf schema转换成avro schema的时候,可能会出现不严谨的时候,比如在转换protobuf的uint32(0 到 2^32 -1)的时候,会统一转换成int(-2^31 ~ 2^31-1),这可能会产生问题,解决方法是使用confluent schema registry提供的工具,参考:使用confluent schema registry将protobuf schema转换成avro schema
本文只发表于博客园和tonglin0325的博客,作者:tonglin0325,转载请注明原文链接:https://www.cnblogs.com/tonglin0325/p/4714993.html