Skip to content

Commit 89a5650

Browse files
committed
feat: enhance Kerberos support and streamline configuration
- Improved Kerberos integration for Kafka and other services, reducing redundancy across components. - Removed Schema Registry-specific Kerberos configuration, leveraging Kafka Kerberos setup instead. - Added programmatic support for configuring Kerberos principals, keytabs, and krb5.conf. - Introduced dynamic Kafka port mapping and improved advertised listener handling for host-side clients. - Updated Spark example and extensions to support Kerberos-secured Kafka communication. - Enhanced documentation with revised Kerberos setup and usage instructions.
1 parent ce4feb6 commit 89a5650

17 files changed

Lines changed: 260 additions & 82 deletions

File tree

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ class MyIntegrationTest {
155155
}
156156
```
157157

158-
Kerberos can be enabled per service. Hadoop/HDFS, Hive Metastore, Kafka, Schema Registry, and Kafka UI expose dedicated Kerberos switches; set `kerberos = true` to start the shared KDC and then enable auth for the services that should use it.
158+
Kerberos can be enabled per service. Hadoop/HDFS, Hive Metastore, Kafka, and Kafka UI expose dedicated Kerberos switches. Set `kerberos = true` to start the shared KDC and then enable auth for the services that should use it. Schema Registry can still be enabled with Kafka Kerberos; it uses Kafka's internal plaintext listener while host clients keep using Kerberos.
159159

160160
```kotlin
161161
@BigDataTest(
@@ -166,12 +166,13 @@ Kerberos can be enabled per service. Hadoop/HDFS, Hive Metastore, Kafka, Schema
166166
hiveMetastoreKerberos = true,
167167
kafka = true,
168168
kafkaKerberos = true,
169-
schemaRegistry = true,
170-
schemaRegistryKerberos = true,
169+
kafkaPort = 19092,
171170
)
172171
class MyKerberosIntegrationTest
173172
```
174173

174+
For host-side Kafka Kerberos clients, configure a fixed `kafkaPort` so the broker can advertise the same host port that clients use.
175+
175176
JUnit tests can also route container logs to the main test process console or to files:
176177

177178
```kotlin

autoconfigure/src/main/kotlin/org/openprojectx/bigdata/test/autoconfigure/BigDataTestAutoConfiguration.kt

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,11 +94,6 @@ class BigDataTestAutoConfiguration {
9494
servicePrincipal = "kafka/broker1.example.com@${properties.kerberos.realm}",
9595
keytabPath = "/kerby/keytabs/kafka-broker1.keytab",
9696
),
97-
schemaRegistryKerberos = KerberosAuthOptions(
98-
enabled = properties.kafka.schemaRegistryKerberosEnabled,
99-
servicePrincipal = "schema-registry/schema-registry.example.com@${properties.kerberos.realm}",
100-
keytabPath = "/kerby/keytabs/schema-registry.keytab",
101-
),
10297
kafkaUiKerberos = KerberosAuthOptions(
10398
enabled = properties.kafka.kafkaUiKerberosEnabled,
10499
servicePrincipal = "kafbat-ui/kafbat-ui.example.com@${properties.kerberos.realm}",

autoconfigure/src/main/kotlin/org/openprojectx/bigdata/test/autoconfigure/BigDataTestProperties.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@ data class BigDataTestProperties(
5454
var kafkaUiEnabled: Boolean = false,
5555
var kafkaUiImage: String = "ghcr.io/kafbat/kafka-ui:latest",
5656
var kerberosEnabled: Boolean = false,
57-
var schemaRegistryKerberosEnabled: Boolean = false,
5857
var kafkaUiKerberosEnabled: Boolean = false,
5958
)
6059

core/src/main/kotlin/org/openprojectx/bigdata/test/core/BigDataService.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,11 @@ enum class BigDataService(
99
endpointProperties = setOf(
1010
"bigdata.test.kerberos.realm",
1111
"bigdata.test.kerberos.kdc",
12+
"bigdata.test.kerberos.krb5-conf",
1213
"bigdata.test.kerberos.client-principal",
1314
"bigdata.test.kerberos.client-password",
15+
"bigdata.test.kerberos.client-keytab",
16+
"bigdata.test.kerberos.client-keytab.container",
1417
),
1518
),
1619
HDFS(

core/src/main/kotlin/org/openprojectx/bigdata/test/core/BigDataTestKitOptions.kt

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@ data class KerberosOptions(
1919
val domain: String = "example.com",
2020
val clientPrincipal: String = "app_user@EXAMPLE.COM",
2121
val clientPassword: String = "app-user-secret",
22+
val users: List<KerberosUserOptions> = emptyList(),
23+
)
24+
25+
data class KerberosUserOptions(
26+
val principal: String,
27+
val password: String,
28+
val keytabPath: String = "/kerby/keytabs/${principal.substringBefore("@").replace(Regex("[^A-Za-z0-9._-]"), "_")}.keytab",
2229
)
2330

2431
data class KerberosAuthOptions(
@@ -69,13 +76,9 @@ data class KafkaOptions(
6976
val kafkaUiImage: String = "ghcr.io/kafbat/kafka-ui:latest",
7077
val clusterId: String = "MkU3OEVBNTcwNTJENDM2Qk",
7178
val kerberos: KerberosAuthOptions = KerberosAuthOptions(
72-
servicePrincipal = "kafka/broker1.example.com@EXAMPLE.COM",
79+
servicePrincipal = "kafka/localhost@EXAMPLE.COM",
7380
keytabPath = "/kerby/keytabs/kafka-broker1.keytab",
7481
),
75-
val schemaRegistryKerberos: KerberosAuthOptions = KerberosAuthOptions(
76-
servicePrincipal = "schema-registry/schema-registry.example.com@EXAMPLE.COM",
77-
keytabPath = "/kerby/keytabs/schema-registry.keytab",
78-
),
7982
val kafkaUiKerberos: KerberosAuthOptions = KerberosAuthOptions(
8083
servicePrincipal = "kafbat-ui/kafbat-ui.example.com@EXAMPLE.COM",
8184
keytabPath = "/kerby/keytabs/kafbat-ui.keytab",

core/src/main/kotlin/org/openprojectx/bigdata/test/core/container/BigDataContainerFactory.kt

Lines changed: 82 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import org.openprojectx.bigdata.test.core.BigDataTestKitOptions
66
import org.openprojectx.bigdata.test.core.ContainerLogMode
77
import org.openprojectx.bigdata.test.core.KerberosAuthOptions
88
import org.openprojectx.bigdata.test.core.KafkaOptions
9+
import org.openprojectx.bigdata.test.core.KerberosOptions
910
import org.testcontainers.containers.BindMode
1011
import org.testcontainers.containers.GenericContainer
1112
import org.testcontainers.containers.Network
@@ -56,21 +57,20 @@ internal class BigDataContainerFactory(
5657

5758
private fun kerberosRequired(): Boolean =
5859
options.kerberos.enabled ||
59-
options.hdfs.kerberos.enabled ||
60+
options.hdfs.kerberos.enabled ||
6061
options.hiveMetastore.kerberos.enabled ||
6162
options.kafka.kerberos.enabled ||
62-
options.kafka.schemaRegistryKerberos.enabled ||
6363
options.kafka.kafkaUiKerberos.enabled
6464

6565
private fun kerberos(): BigDataServiceContainer {
6666
val kerberos = options.kerberos
6767
val servicePrincipals = buildList {
68+
addUserKeytab(kerberos.clientPrincipal, "/kerby/keytabs/client.keytab")
69+
kerberos.users.forEach { addUserKeytab(it.principal, it.keytabPath) }
6870
addIfEnabled(options.hdfs.kerberos)
6971
addIfEnabled(options.hiveMetastore.kerberos)
7072
addIfEnabled(options.kafka.kerberos)
71-
addIfEnabled(options.kafka.schemaRegistryKerberos)
7273
addIfEnabled(options.kafka.kafkaUiKerberos)
73-
if (options.kafka.kerberos.enabled && options.kafka.schemaRegistryEnabled) addPrincipal(options.kafka.schemaRegistryKerberos)
7474
if (options.kafka.kerberos.enabled && options.kafka.kafkaUiEnabled) addPrincipal(options.kafka.kafkaUiKerberos)
7575
}
7676

@@ -92,17 +92,26 @@ internal class BigDataContainerFactory(
9292
if (servicePrincipals.isNotEmpty()) {
9393
container.withEnv("KERBY_EXTRA_SERVICE_PRINCIPALS", servicePrincipals.joinToString(","))
9494
}
95+
val users = kerberos.users.joinToString(",") { "${it.principal}:${it.password}" }
96+
if (users.isNotEmpty()) {
97+
container.withEnv("KERBY_EXTRA_PRINCIPALS", users)
98+
}
9599

96100
return BigDataServiceContainer(BigDataService.KERBEROS, attachLogs("kerberos", container)) {
101+
val localKrb5Conf = writeLocalKerberosConf(kerberos, container.host, container.getMappedPort(88))
97102
BigDataEndpoint(
98103
service = BigDataService.KERBEROS,
99104
host = container.host,
100105
ports = mapOf("kdc" to container.getMappedPort(88)),
101106
properties = mapOf(
102107
"bigdata.test.kerberos.realm" to kerberos.realm,
103108
"bigdata.test.kerberos.kdc" to "${container.host}:${container.getMappedPort(88)}",
109+
"bigdata.test.kerberos.krb5-conf" to localKrb5Conf,
110+
"bigdata.test.kerberos.krb5-conf.container" to "/kerby/client/krb5.conf",
104111
"bigdata.test.kerberos.client-principal" to kerberos.clientPrincipal,
105112
"bigdata.test.kerberos.client-password" to kerberos.clientPassword,
113+
"bigdata.test.kerberos.client-keytab" to localKerberosPath("/kerby/keytabs/client.keytab"),
114+
"bigdata.test.kerberos.client-keytab.container" to "/kerby/keytabs/client.keytab",
106115
),
107116
)
108117
}
@@ -207,10 +216,16 @@ internal class BigDataContainerFactory(
207216
val kafka = options.kafka
208217
if (!kafka.kerberos.enabled) return plaintextKafka(kafka)
209218

219+
val kafkaHostPort = options.portBindings.hostPort(9092, options.portBindings.kafka)
220+
val advertisedListener = if (kafkaHostPort > 0) {
221+
"SASL_PLAINTEXT://localhost:$kafkaHostPort"
222+
} else {
223+
"SASL_PLAINTEXT://broker1.example.com:9092"
224+
}
210225
val container = GenericBigDataContainer(kafka.image)
211226
.withNetwork(network)
212227
.withNetworkAliases("kafka", "broker1.example.com")
213-
.withServicePort(9092, options.portBindings.hostPort(9092, options.portBindings.kafka))
228+
.withServicePort(9092, kafkaHostPort)
214229
.withEnv("KAFKA_NODE_ID", "1")
215230
.withEnv("KAFKA_PROCESS_ROLES", "broker,controller")
216231
.withEnv("KAFKA_CONTROLLER_QUORUM_VOTERS", "1@kafka:29093")
@@ -226,10 +241,10 @@ internal class BigDataContainerFactory(
226241
.waitingFor(Wait.forListeningPort().withStartupTimeout(Duration.ofMinutes(3)))
227242
mountKerberos(container)
228243
container
229-
.withEnv("KAFKA_LISTENER_SECURITY_PROTOCOL_MAP", "CONTROLLER:PLAINTEXT,SASL_PLAINTEXT:SASL_PLAINTEXT")
230-
.withEnv("KAFKA_ADVERTISED_LISTENERS", "SASL_PLAINTEXT://broker1.example.com:9092")
231-
.withEnv("KAFKA_LISTENERS", "SASL_PLAINTEXT://broker1.example.com:9092,CONTROLLER://broker1.example.com:29093")
232-
.withEnv("KAFKA_CONTROLLER_QUORUM_VOTERS", "1@broker1.example.com:29093")
244+
.withEnv("KAFKA_LISTENER_SECURITY_PROTOCOL_MAP", "CONTROLLER:PLAINTEXT,SASL_PLAINTEXT:SASL_PLAINTEXT,PLAINTEXT:PLAINTEXT")
245+
.withEnv("KAFKA_ADVERTISED_LISTENERS", "$advertisedListener,PLAINTEXT://kafka:19092")
246+
.withEnv("KAFKA_LISTENERS", "SASL_PLAINTEXT://0.0.0.0:9092,PLAINTEXT://0.0.0.0:19092,CONTROLLER://kafka:29093")
247+
.withEnv("KAFKA_CONTROLLER_QUORUM_VOTERS", "1@kafka:29093")
233248
.withEnv("KAFKA_INTER_BROKER_LISTENER_NAME", "SASL_PLAINTEXT")
234249
.withEnv("KAFKA_SASL_ENABLED_MECHANISMS", "GSSAPI")
235250
.withEnv("KAFKA_SASL_MECHANISM_INTER_BROKER_PROTOCOL", "GSSAPI")
@@ -250,7 +265,7 @@ internal class BigDataContainerFactory(
250265
properties = mapOf(
251266
"bootstrap.servers" to bootstrapServers,
252267
"spring.kafka.bootstrap-servers" to bootstrapServers,
253-
) + kafkaClientKerberosProperties(kafka.kerberos),
268+
) + kerberosProperties("kafka", kafka.kerberos) + kafkaClientKerberosProperties(kafka.kerberos, options.kerberos),
254269
)
255270
}
256271
}
@@ -293,20 +308,6 @@ internal class BigDataContainerFactory(
293308
.withEnv("SCHEMA_REGISTRY_LISTENERS", "http://0.0.0.0:8085")
294309
.withEnv("SCHEMA_REGISTRY_KAFKASTORE_BOOTSTRAP_SERVERS", "PLAINTEXT://kafka:19092")
295310
.waitingFor(Wait.forHttp("/subjects").forStatusCode(200).withStartupTimeout(Duration.ofMinutes(3)))
296-
if (kafka.schemaRegistryKerberos.enabled || kafka.kerberos.enabled) {
297-
mountKerberos(container)
298-
val registryPrincipal = kafka.schemaRegistryKerberos
299-
container
300-
.withEnv("SCHEMA_REGISTRY_KAFKASTORE_BOOTSTRAP_SERVERS", "SASL_PLAINTEXT://broker1.example.com:9092")
301-
.withEnv("SCHEMA_REGISTRY_KAFKASTORE_SECURITY_PROTOCOL", "SASL_PLAINTEXT")
302-
.withEnv("SCHEMA_REGISTRY_KAFKASTORE_SASL_MECHANISM", "GSSAPI")
303-
.withEnv("SCHEMA_REGISTRY_KAFKASTORE_SASL_KERBEROS_SERVICE_NAME", "kafka")
304-
.withEnv("SCHEMA_REGISTRY_KAFKASTORE_SASL_JAAS_CONFIG", inlineJaas(registryPrincipal))
305-
.withEnv("KAFKA_OPTS", "-Djava.security.krb5.conf=/kerby/client/krb5.conf")
306-
.withEnv("KRB5_CONFIG", "/kerby/client/krb5.conf")
307-
.withEnv("SCHEMA_REGISTRY_OPTS", "-Djava.security.krb5.conf=/kerby/client/krb5.conf")
308-
}
309-
310311
return BigDataServiceContainer(BigDataService.SCHEMA_REGISTRY, attachLogs("schema-registry", container)) {
311312
val url = "http://${container.host}:${container.getMappedPort(8085)}"
312313
BigDataEndpoint(
@@ -505,6 +506,11 @@ internal class BigDataContainerFactory(
505506
if (!contains(principal)) add(principal)
506507
}
507508

509+
private fun MutableList<String>.addUserKeytab(principal: String, keytabPath: String) {
510+
val entry = "$principal:${keytabPath.replace("/kerby/", "/var/lib/kerby/")}"
511+
if (!contains(entry)) add(entry)
512+
}
513+
508514
private fun mountKerberos(container: GenericBigDataContainer) {
509515
container.withFileSystemBind(kerberosDirectory(), "/kerby", BindMode.READ_ONLY)
510516
}
@@ -517,20 +523,26 @@ internal class BigDataContainerFactory(
517523
mapOf(
518524
"$prefix.security.authentication" to "kerberos",
519525
"$prefix.kerberos.principal" to options.servicePrincipal,
526+
"$prefix.kerberos.service-name" to options.servicePrincipal.substringBefore("/"),
520527
"$prefix.kerberos.keytab" to options.keytabPath,
528+
"$prefix.kerberos.keytab.local" to localKerberosPath(options.keytabPath),
521529
"java.security.krb5.conf" to "/kerby/client/krb5.conf",
530+
"java.security.krb5.conf.local" to localKerberosPath("/kerby/client/krb5.conf"),
522531
)
523532
} else {
524533
emptyMap()
525534
}
526535

527-
private fun kafkaClientKerberosProperties(options: KerberosAuthOptions): Map<String, String> =
528-
if (options.enabled) {
536+
private fun kafkaClientKerberosProperties(service: KerberosAuthOptions, client: KerberosOptions): Map<String, String> =
537+
if (service.enabled) {
538+
val clientKeytab = localKerberosPath("/kerby/keytabs/client.keytab")
529539
mapOf(
530540
"security.protocol" to "SASL_PLAINTEXT",
531541
"sasl.mechanism" to "GSSAPI",
532-
"sasl.kerberos.service.name" to options.servicePrincipal.substringBefore("/"),
533-
"sasl.jaas.config" to inlineJaas(options),
542+
"sasl.kerberos.service.name" to service.servicePrincipal.substringBefore("/"),
543+
"sasl.jaas.config" to inlineJaas(client.clientPrincipal, clientKeytab),
544+
"sasl.jaas.config.container-keytab" to inlineJaas(client.clientPrincipal, "/kerby/keytabs/client.keytab"),
545+
"java.security.krb5.conf.local" to localKerberosPath("/kerby/client/krb5.conf"),
534546
)
535547
} else {
536548
emptyMap()
@@ -549,4 +561,46 @@ internal class BigDataContainerFactory(
549561

550562
private fun inlineJaas(options: KerberosAuthOptions): String =
551563
"""com.sun.security.auth.module.Krb5LoginModule required useKeyTab=true storeKey=true keyTab="${options.keytabPath}" principal="${options.servicePrincipal}";"""
564+
565+
private fun inlineJaas(principal: String, keytabPath: String): String =
566+
"""com.sun.security.auth.module.Krb5LoginModule required useKeyTab=true storeKey=true keyTab="$keytabPath" principal="$principal";"""
567+
568+
private fun localKerberosPath(containerPath: String): String =
569+
when {
570+
containerPath == "/kerby/client/krb5.conf" -> Path.of(kerberosDirectory())
571+
.resolve("krb5-local.conf")
572+
.toString()
573+
containerPath.startsWith("/kerby/") -> Path.of(kerberosDirectory())
574+
.resolve(containerPath.removePrefix("/kerby/"))
575+
.toString()
576+
else -> containerPath
577+
}
578+
579+
private fun writeLocalKerberosConf(options: KerberosOptions, host: String, port: Int): String {
580+
val path = Path.of(localKerberosPath("/kerby/client/krb5.conf"))
581+
Files.createDirectories(path.parent)
582+
Files.writeString(
583+
path,
584+
"""
585+
[libdefaults]
586+
default_realm = ${options.realm}
587+
dns_lookup_realm = false
588+
dns_lookup_kdc = false
589+
rdns = false
590+
udp_preference_limit = 1
591+
592+
[realms]
593+
${options.realm} = {
594+
kdc = $host:$port
595+
admin_server = $host:$port
596+
}
597+
598+
[domain_realm]
599+
.${options.domain} = ${options.realm}
600+
${options.domain} = ${options.realm}
601+
""".trimIndent(),
602+
StandardCharsets.UTF_8,
603+
)
604+
return path.toString()
605+
}
552606
}

doc/user-guide.adoc

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -160,9 +160,6 @@ The JUnit extension starts the kit before all tests in the class and closes it a
160160
|`schemaRegistry`
161161
|Starts Schema Registry.
162162

163-
|`schemaRegistryKerberos`
164-
|Configures Schema Registry for Kerberos/SASL Kafka access.
165-
166163
|`kafkaUi`
167164
|Starts Kafka UI.
168165

@@ -249,7 +246,7 @@ Each started service exposes a `BigDataEndpoint` with named ports and connection
249246
|`BigDataService.KERBEROS`
250247
|`kdc`
251248
|`88`
252-
|`bigdata.test.kerberos.realm`, `bigdata.test.kerberos.kdc`, `bigdata.test.kerberos.client-principal`, `bigdata.test.kerberos.client-password`
249+
|`bigdata.test.kerberos.realm`, `bigdata.test.kerberos.kdc`, `bigdata.test.kerberos.krb5-conf`, `bigdata.test.kerberos.client-principal`, `bigdata.test.kerberos.client-password`, `bigdata.test.kerberos.client-keytab`
253250

254251
|`BigDataService.HDFS`
255252
|`namenode`, `web`
@@ -264,7 +261,7 @@ Each started service exposes a `BigDataEndpoint` with named ports and connection
264261
|`BigDataService.KAFKA`
265262
|`bootstrap`
266263
|`9092`
267-
|`bootstrap.servers`, `spring.kafka.bootstrap-servers`, `bootstrap.servers.internal`
264+
|`bootstrap.servers`, `spring.kafka.bootstrap-servers`, `bootstrap.servers.internal`, `kafka.kerberos.service-name`, `sasl.jaas.config`
268265

269266
|`BigDataService.SCHEMA_REGISTRY`
270267
|`http`
@@ -349,12 +346,12 @@ Kerberos can be enabled globally and per service. Set `kerberos = true` to start
349346
hiveMetastoreKerberos = true,
350347
kafka = true,
351348
kafkaKerberos = true,
352-
schemaRegistry = true,
353-
schemaRegistryKerberos = true,
354349
)
355350
class MyKerberosIntegrationTest
356351
----
357352

353+
For host-side Kafka Kerberos clients, prefer an explicit fixed `kafkaPort`. Kafka must advertise the same host and port that the client uses during the SASL/GSSAPI exchange; with a random host port the framework cannot know that advertised port before the broker starts. When Schema Registry is enabled with Kafka Kerberos, it uses Kafka's internal plaintext listener while host clients keep using the Kerberos listener.
354+
358355
Default principals are defined in `BigDataTestKitOptions`:
359356

360357
[cols="1,2",options="header"]
@@ -371,15 +368,32 @@ Default principals are defined in `BigDataTestKitOptions`:
371368
|`hive/hive-metastore.example.com@EXAMPLE.COM`
372369

373370
|Kafka broker
374-
|`kafka/broker1.example.com@EXAMPLE.COM`
375-
376-
|Schema Registry
377-
|`schema-registry/schema-registry.example.com@EXAMPLE.COM`
371+
|`kafka/localhost@EXAMPLE.COM`
378372

379373
|Kafka UI
380374
|`kafbat-ui/kafbat-ui.example.com@EXAMPLE.COM`
381375
|===
382376

377+
The `KerberosMaterialExtension` publishes reusable client and service material to extension output:
378+
379+
[source,toml]
380+
----
381+
[kerberosMaterial]
382+
enabled = true
383+
----
384+
385+
Common output keys are:
386+
387+
* `kerberos-material.realm`
388+
* `kerberos-material.kdc`
389+
* `kerberos-material.krb5-conf`
390+
* `kerberos-material.client.principal`
391+
* `kerberos-material.client.password`
392+
* `kerberos-material.client.keytab`
393+
* `kerberos-material.kafka.service-name`
394+
* `kerberos-material.kafka.principal`
395+
* `kerberos-material.kafka.keytab`
396+
383397
== Extensions Module
384398

385399
The `extensions` module is for config-driven setup that should not live in `core` or `junit5`. It depends on heavier client libraries where needed and runs lifecycle hooks against a started `BigDataTestKit`.

example/junit/src/test/kotlin/org/openprojectx/bigdata/test/example/junit/KerberosBigDataTestExample.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import org.openprojectx.bigdata.test.junit5.BigDataTest
1313
kafka = true,
1414
kafkaKerberos = true,
1515
schemaRegistry = true,
16-
schemaRegistryKerberos = true,
1716
)
1817
class KerberosBigDataTestExample {
1918
@Test

0 commit comments

Comments
 (0)