0

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

这些是模式:

id.avsc

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

事件.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 类型?

构建.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
}

4

1 回答 1

0

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

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

否则,您需要完全嵌入记录,例如

"fields": [
  {"type": {
    "type": "record",
    "namespace": "some.package",
    "name": "Id",
    fields: []
  }
]
于 2022-01-04T20:10:54.593 回答