Avro 模式中的 Avro 模式文件引用

Avro schema file references in a Avro schema

我有将近 100 个 avsc 文件,其中大多数 avsc 文件通常引用另一个 asvc 文件作为它们的类型。举个例子

Item.avsc 在./com/example/common

{
    "namespace":"com.example.common",
    "name":"Item",
    "type":"record",
    "fields":[
        {
            "name":"itemId",
            "type":"com.example.common.ItemId"
        },
        {
            "name":"features",
            "type":"com.example.common.Features"
        }
    ]
}

ItemId.avsc 在./com/example/common

{
    "namespace":"com.example.common",
    "name":"ItemId",
    "type":"record",
    "fields":[
        {
            "name":"id",
            "type":"int"
        }
    ]
}

Features.avsc 在./com/example/common

{
    "namespace":"com.example.common",
    "name":"Features",
    "type":"record",
    "fields":[
        {
            "name":"Range",
            "type":{
                "type":"array",
                "items":"com.example.common.Range"
            }
        }
    ]
}

当我想解析 Item.avsc 的架构时,它会引发:

Schema schema = new Schema.Parser().parse(new File(".\com\example\common\Item.avsc"));

Exception in thread "main" org.apache.avro.SchemaParseException: "com.example.common.ItemId" is not a defined name. The type of the "itemId" field must be a defined name or a {"type": ...} expression.

我通过使用解析器的单个实例首先解析 ItemId.avsc 和 Features.avsc,然后解析 Item.avsc,找到了解决此问题的方法,如下所示:

Parser parser = new Parser();
parser.parse(new File(".\com\example\common\ItemId.avsc"));
parser.parse(new File(".\com\example\common\Features.avsc"));
parser.parse(new File(".\com\example\common\Range.avsc"));
parser.parse(new File(".\com\example\common\Item.avsc"));

但我有将近 100 个 avsc 文件,其中大多数引用多个 avsc 文件,我需要像这样解析每个文件,同时考虑它们的依赖等级。对此有更好的解决方案吗?

遍历您的包,并通过循环解析它们。

Schema.Parser parser = new Schema.Parser();
URI uri = Test.class.getResource("package/name/here").toURI();
Path myPath = Paths.get(uri);
try (Stream<Path> paths = Files.walk(myPath)) {
     paths.filter(Files::isRegularFile)
          .filter(path -> path.toString().endsWith(".avsc"))
          .map(path -> new File(path.toUri()))
          .forEach(file -> {
              try {
                 parser.parse(file);
              } catch (IOException e) {}
          });
}