【问题标题】:Referencing an Avro type from another Avro type fails in Quarkus with The type of the "id" field must be a defined name or a {"type": ...} expression在 Quarkus 中从另一个 Avro 类型引用 Avro 类型失败,“id”字段的类型必须是定义的名称或 {"type": ...} 表达式
【发布时间】:2021-12-21 18:15:07
【问题描述】:

我正在将 Spring Boot 应用程序迁移到 Quarkus。它是一个发布使用 Avro 序列化的 Kafka 消息的应用程序。

这些是架构:

id.avsc

{
  "namespace" : "xxx",
             "type": "record",
             "name": "Id",
             "fields" : [
                 {"name": "prefix", "type": "string"},
                 {"name": "name", "type": "string"}
             ]
}

event.avsc

{
  "namespace" : "yyy",
  "type" : "record",
  "name" : "EventReceived",
  "fields" : [
    {"name":"id", "type": "xxx.Id"},
  ...

Spring 版本能够为这些 Avro 类型生成必要的源代码。

Quarkus 应用程序失败:

Caused by: org.apache.avro.SchemaParseException: "xxx.Id" is not a defined name. The type of the "id" field must be a defined name or a {"type": ...} expression.

如何在 Quarkus 中引用另一个 Avro 类型?

build.gradle.kts

plugins {
    kotlin("jvm") version "1.5.31"
    kotlin("plugin.allopen") version "1.5.31"
    id("io.quarkus")
}

repositories {
    mavenCentral()
    maven { url = uri("https://packages.confluent.io/maven") }
    mavenLocal()
}

val quarkusPlatformGroupId: String by project
val quarkusPlatformArtifactId: String by project
val quarkusPlatformVersion: String by project

extra["confluentVersion"] = "7.0.1"

dependencies {
    implementation(enforcedPlatform("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}"))
    implementation("io.quarkus:quarkus-resteasy-reactive-jackson")
    implementation("io.quarkus:quarkus-smallrye-opentracing")
    implementation("io.quarkus:quarkus-rest-client-reactive")
    implementation("io.quarkus:quarkus-resteasy-reactive")
    implementation("io.quarkus:quarkus-smallrye-reactive-messaging-kafka")
    implementation("io.quarkus:quarkus-kotlin")
    implementation("io.quarkus:quarkus-avro")
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
    implementation("io.quarkus:quarkus-arc")
    implementation("io.confluent:kafka-avro-serializer:${property("confluentVersion")}")
    testImplementation("io.quarkus:quarkus-junit5")
    testImplementation("io.rest-assured:rest-assured")
}

group = "mygroupid"
version = "1.0-SNAPSHOT"

java {
    sourceCompatibility = JavaVersion.VERSION_11
    targetCompatibility = JavaVersion.VERSION_11
}

allOpen {
    annotation("javax.ws.rs.Path")
    annotation("javax.enterprise.context.ApplicationScoped")
    annotation("io.quarkus.test.junit.QuarkusTest")
}

tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
    kotlinOptions.jvmTarget = JavaVersion.VERSION_11.toString()
    kotlinOptions.javaParameters = true
}

【问题讨论】:

    标签: avro quarkus quarkus-avro quarkus-kafka


    【解决方案1】:

    AVSC 文件不能相互引用。我对这种方法的一般建议是改用 AVDL 文件,您可以在其中定义类似 Java 类的记录定义,而不是 JSON,它们可以相互引用,甚至可以导入和使用外部 AVSC文件。

    如果您包含将架构编译为类的 Gradle 插件,它还可以为每条记录生成一个类。

    否则,你需要像这样完全嵌入记录

    "fields": [
      {"type": {
        "type": "record",
        "namespace": "some.package",
        "name": "Id",
        fields: []
      }
    ]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-17
      • 2020-02-25
      • 2015-07-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多