将 Json 转换为 Avro 模式

Convert Json to Avro schema

问题

我想将如下所示的普通 Json 文件转换为 avro 模式,使其在具有融合模式注册表的 apache kafka 中工作。

例子

输入(Json)

[
  {
    "name": "Robin Hood",
    "department": "",
    "manager": "",
    "salary": 200
  },
  {
    "name": "Arsene Wenger",
    "department": "Bar",
    "manager": "Friar Tuck",
    "salary": 50
  },
  {
    "name": "Friar Tuck",
    "department": "Foo",
    "manager": "Robin Hood",
    "salary": 100
  },
  {
    "name": "Little John",
    "department": "Foo",
    "manager": "Robin Hood",
    "salary": 100
  },
  {
    "name": "Sam Allardyce",
    "department": "",
    "manager": "",
    "salary": 250
  },
  {
    "name": "Dimi Berbatov",
    "department": "Foo",
    "manager": "Little John",
    "salary": 50
  }
]

输出(Avro 模式)

{
  "name": "MyClass",
  "type": "array",
  "namespace": "com.acme.avro",
  "items": {
    "name": "MyClass_record",
    "type": "record",
    "fields": [
      {
        "name": "name",
        "type": "string"
      },
      {
        "name": "department",
        "type": "string"
      },
      {
        "name": "manager",
        "type": "string"
      },
      {
        "name": "salary",
        "type": "int"
      }
    ]
  }
}

A Json 架构作为输入也很好。

这个问题was asked a while ago但是没有很好的答案。

有一个 website 可以执行此操作,但我想要一个库或 cli。

谢谢!

事实证明,avro4s 可以做到这一点。它是一个 Scala 库,我在 java 中没有找到任何东西。

这里有一个简单的例子来说明如何使用它。我有包含属性的事件。

package example

import com.sksamuel.avro4s.AvroSchema
import com.sksamuel.avro4s.json.JsonToAvroConverter

object Main extends App {

  case class Propertie(name: String, value: String)
  case class Event(name: String, properties: Seq[Propertie])

  val schema = AvroSchema[Event]

  val converter = new JsonToAvroConverter("com.example.kafkaorch")
  val string =
    """{
      |  "AvroEvent": {
      |    "name": "order-created",
      |    "AvroPropertie": {
      |      "name": "",
      |      "type": "",
      |      "value":""
      |    }
      |  }
      |}""".stripMargin

  print(converter.convert("test", string).toString(true))

}

结果应该是这样的:

{
  "type" : "record",
  "name" : "test",
  "namespace" : "com.example.kafkaorch",
  "fields" : [ {
    "name" : "AvroEvent",
    "type" : {
      "type" : "record",
      "name" : "AvroEvent",
      "fields" : [ {
        "name" : "name",
        "type" : "string"
      }, {
        "name" : "AvroPropertie",
        "type" : {
          "type" : "record",
          "name" : "AvroPropertie",
          "fields" : [ {
            "name" : "name",
            "type" : "string"
          }, {
            "name" : "type",
            "type" : "string"
          }, {
            "name" : "value",
            "type" : "string"
          } ]
        }
      } ]
    }
  } ]
}