Unit testing 使用kafka stream binder测试Spring cloud stream:使用TopologyTestDriver,我得到的错误是;该类不在受信任的包中;
我有一个使用kafka streams binder的简单流处理器(不是消费者/生产者)Unit testing 使用kafka stream binder测试Spring cloud stream:使用TopologyTestDriver,我得到的错误是;该类不在受信任的包中;,unit-testing,kotlin,spring-cloud-stream,Unit Testing,Kotlin,Spring Cloud Stream,我有一个使用kafka streams binder的简单流处理器(不是消费者/生产者) @Bean fun processFoo():Function<KStream<FooName, FooAddress>, KStream<FooName, FooAddressPlus>> { return Function { input-> input.map { key, value -> println("\nPAY
@Bean
fun processFoo():Function<KStream<FooName, FooAddress>, KStream<FooName, FooAddressPlus>> {
return Function { input-> input.map { key, value ->
println("\nPAYLOAD KEY: ${key.name}\n");
println("\nPAYLOAD value: ${value.address}\n");
val output = FooAddressPlus()
output.address = value.address
output.name = value.name
output.plus = "$value.name-$value.address"
KeyValue(key, output)
}}
}
@Bean
fun processFoo():函数{
返回函数{input->input.map{key,value->
println(“\n加载项:${KEY.name}\n”);
println(“\n路径值:${value.address}\n”);
val输出=foodAddressPlus()
output.address=value.address
output.name=value.name
output.plus=“$value.name-$value.address”
键值(键,输出)
}}
}
我正在尝试使用TopologyTestDriver进行测试:
@SpringBootTest(
webEnvironment = SpringBootTest.WebEnvironment.NONE,
classes = [Application::class, FooProcessor::class]
)
class FooProcessorTests {
var testDriver: TopologyTestDriver? = null
val INPUT_TOPIC = "input"
val OUTPUT_TOPIC = "output"
val inputKeySerde: Serde<FooName> = JsonSerde<FooName>()
val inputValueSerde: Serde<FooAddress> = JsonSerde<FooAddress>()
val outputKeySerde: Serde<FooName> = JsonSerde<FooName>()
val outputValueSerde: Serde<FooAddressPlus> = JsonSerde<FooAddressPlus>()
fun getStreamsConfiguration(): Properties? {
val streamsConfiguration = Properties()
streamsConfiguration[StreamsConfig.APPLICATION_ID_CONFIG] = "TopologyTestDriver"
streamsConfiguration[StreamsConfig.BOOTSTRAP_SERVERS_CONFIG] = "dummy:1234"
streamsConfiguration[JsonDeserializer.TRUSTED_PACKAGES] = "*"
streamsConfiguration["spring.kafka.consumer.properties.spring.json.trusted.packages"] = "*"
return streamsConfiguration
}
@Before
fun setup() {
val builder = StreamsBuilder()
val input: KStream<FooName, FooAddress> = builder.stream(INPUT_TOPIC, Consumed.with(inputKeySerde, inputValueSerde))
val processor = FooProcessor()
val output: KStream<FooName, FooAddressPlus> = processor.processFoo().apply(input)
output.to(OUTPUT_TOPIC, Produced.with(outputKeySerde, outputValueSerde))
testDriver = TopologyTestDriver(builder.build(), getStreamsConfiguration())
}
@After
fun tearDown() {
try {
testDriver!!.close()
} catch (e: RuntimeException) {
// https://issues.apache.org/jira/browse/KAFKA-6647 causes exception when executed in Windows, ignoring it
// Logged stacktrace cannot be avoided
println("Ignoring exception, test failing in Windows due this exception:" + e.localizedMessage)
}
}
@org.junit.Test
fun testOne() {
val inputTopic: TestInputTopic<FooName, FooAddress> =
testDriver!!.createInputTopic(INPUT_TOPIC, inputKeySerde.serializer(), inputValueSerde.serializer())
val key = FooName()
key.name = "sherlock"
val value = FooAddress()
value.name = "sherlock"
value.address = "Baker street"
inputTopic.pipeInput(key, value)
val outputTopic: TestOutputTopic<FooName, FooAddressPlus> =
testDriver!!.createOutputTopic(OUTPUT_TOPIC, outputKeySerde.deserializer(), outputValueSerde.deserializer())
val message = outputTopic.readValue()
assertThat(message.name).isEqualTo(key.name)
assertThat(message.address).isEqualTo(value.address)
}
}
@SpringBootTest(
webEnvironment=SpringBootTest.webEnvironment.NONE,
classes=[Application::class,FooProcessor::class]
)
类FooProcessorTests{
var testDriver:TopologyTestDriver?=null
val INPUT_TOPIC=“输入”
val输出\u主题=“输出”
val inputKeySerde:Serde=JsonSerde()
val inputValueSerde:Serde=JsonSerde()
val outputKeySerde:Serde=JsonSerde()
val outputValueSerde:Serde=JsonSerde()
fun getStreamsConfiguration():属性{
val streamsConfiguration=属性()
streamsConfiguration[StreamsConfig.APPLICATION\u ID\u CONFIG]=“TopologyTestDriver”
streamsConfiguration[StreamsConfig.BOOTSTRAP\u SERVERS\u CONFIG]=“虚拟:1234”
streamsConfiguration[JsonDeserializer.TRUSTED_PACKAGES]=“*”
streamsConfiguration[“spring.kafka.consumer.properties.spring.json.trusted.packages”]=“*”
回流配置
}
@以前
趣味设置(){
val builder=StreamsBuilder()
val input:KStream=builder.stream(输入主题,已消费.with(inputKeySerde,inputValueSerde))
val processor=FooProcessor()
val输出:KStream=processor.processFoo().apply(输入)
to(output_主题,producted.with(outputKeySerde,outputValueSerde))
testDriver=TopologyTestDriver(builder.build(),getStreamsConfiguration())
}
@之后
有趣的撕裂{
试一试{
testDriver!!.close()
}捕获(e:运行时异常){
// https://issues.apache.org/jira/browse/KAFKA-6647 在Windows中执行时导致异常,忽略它
//无法避免记录堆栈跟踪
println(“忽略异常,由于此异常导致Windows中的测试失败:”+e.localizedMessage)
}
}
@org.junit.Test
趣味测试一{
val:睾丸正位=
testDriver!!.createInputTopic(输入主题,inputKeySerde.serializer(),inputValueSerde.serializer())
val key=FooName()
key.name=“夏洛克”
val value=FooAddress()
value.name=“夏洛克”
value.address=“贝克街”
InputOptic.pipeInput(键、值)
val outputTopic:TestOutputTopic=
testDriver!!.createOutputTopic(输出主题,outputKeySerde.deserializer(),outputValueSerde.deserializer())
val message=outputTopic.readValue()
assertThat(message.name).isEqualTo(key.name)
assertThat(message.address).isEqualTo(value.address)
}
}
运行它时,我在inputOptic.pipeInput(键,值)
类“package.FooAddress”不在受信任的包:[java.util,java.lang]中。如果您认为该类可以安全地反序列化,请提供其名称。如果序列化仅由受信任的源完成,则还可以启用trust all()*
有没有办法解决这个问题?在getStreamsConfiguration()
中设置这些属性没有帮助。请注意,这是一个流处理器,而不是消费者/生产者
非常感谢 当Kafka自己创建Serde时,它通过调用
configure()
应用属性
由于您自己正在实例化Serde,因此需要在传递属性映射时对其调用configure()
这就是trusted packages属性传播到反序列化程序的方式
或者,您可以在反序列化程序上调用
setTrustedPackages()
。因此,为了完整起见,下面是按照@GaryRussell的建议配置serde时代码的外观:
private fun getStreamsConfiguration(): Properties? {
// Don't set the trusted packages here since topology test driver does not know about Spring
val streamsConfiguration = Properties()
streamsConfiguration[StreamsConfig.APPLICATION_ID_CONFIG] = "TopologyTestDriver"
streamsConfiguration[StreamsConfig.BOOTSTRAP_SERVERS_CONFIG] = "dummy:1234"
}
@之前
趣味设置(){
val builder=StreamsBuilder()
//为所有SERDE设置受信任的包
val config=mapOf(jsondesializer.TRUSTED_包到“*”)
配置(配置,true)
inputValueSerde.configure(配置,false)
outputKeySerde.configure(配置,true)
outputValueSerde.configure(配置,false)
}
代码的其余部分仍如问题中所述。感谢@GaryRusell。非常感谢@GaryRussell。我将从我的另一个问题中进行检查。顺便说一句,感谢令人敬畏的spring cloud stream框架不幸的是,我没能让它工作,可能我做错了什么,所以我非常感谢您在我添加的
getStreamsConfiguration
方法中对@GaryRussell的指导:streamsConfiguration[“spring.cloud.streams.kafka.streams.binder.configuration.spring.json.trusted.packages”]=“*”
但测试仍然失败,因为不在受信任的包中:[java.util,java.lang]
。谢谢!我将研究为什么它不能与测试驱动程序一起工作-它对Spring一无所知,添加Spring属性也没有帮助。非常感谢@GaryRussell。如果代码有用,我可以提供git repo。天哪!我真的说不出我有多感激。非常感谢。只是出于好奇:我如何调用setTrust反序列化程序上的dPackages()
?我没有访问权限,是吗?我只有我创建的serdes。非常感谢!有一个构造函数,您可以在其中提供预配置(反)序列化程序public JsonSerde(JsonSerializer JsonSerializer,JsonSerializer JsonSerializer)
@Before
fun setup() {
val builder = StreamsBuilder()
// Set the trusted packages for all serdes
val config = mapOf<String, String>(JsonDeserializer.TRUSTED_PACKAGES to "*")
inputKeySerde.configure(config, true)
inputValueSerde.configure(config, false)
outputKeySerde.configure(config, true)
outputValueSerde.configure(config, false)
}