我正在尝试使用TopologyTestDriver
使用KStream到KStream加入来测试KStream实现。
Key
和Value
都使用Avro
模式,因此我正在使用SpecificAvroSerde
创建的MockSchemaRegistryClient
。
使用testDriver.pipeInput
,我可以将数据发送到两个不同的流。一旦在拓扑中包含Join
,则在发送第二条消息后就会收到ClassCastException
。它似乎以某种方式混淆了Key
和Value
类型。
我将代码分离在一个单独的项目中,并且依赖性最小。我调试到TopologyTestDriver
,在我看来消息已正确序列化,但不知何故导致了Join
中的问题。
// Create Topology
StreamsBuilder builder = new StreamsBuilder();
KStream<TestKey, TestCtrl> ctrlStream = builder.stream(INPUT_CTRL_TOPIC, Consumed.with(keySerde, ctrlSerde));
KStream<TestKey, TestPayload> payloadStream = builder.stream(INPUT_PAYLOAD_TOPIC, Consumed.with(keySerde, payloadSerde));
KStream<TestKey, TestPayload> transformStream = ctrlStream
.join(payloadStream,
(ctrlValue, payloadValue) -> payloadValue,
JoinWindows.of(Duration.ofMinutes(5)),
Joined.with(keySerde, ctrlSerde, payloadSerde)
);
...
// create Avro objects
TestCtrl ctrl = TestCtrl.newBuilder().setId("id1").setPayloadMessageCount(1).build();
TestPayload payload = TestPayload.newBuilder().setId("id1").setDescription("My payload message").build();
TestKey key = TestKey.newBuilder().setKey("k1").build();
// send the objects
testDriver.pipeInput(ctrlFactory.create(INPUT_CTRL_TOPIC, key, ctrl));
testDriver.pipeInput(payloadFactory.create(INPUT_PAYLOAD_TOPIC, key, payload));
...
// creation of Serde
private static <T extends SpecificRecord> SpecificAvroTestSerde<T> createSpecificAvroTestSerde(
boolean isSerdeForRecordKeys) {
Map<String, Object> serdeConfig = new HashMap<>();
serdeConfig.put(KafkaAvroDeserializerConfig.SPECIFIC_AVRO_READER_CONFIG, true);
serdeConfig.put(KafkaAvroDeserializerConfig.SCHEMA_REGISTRY_URL_CONFIG, "http://localhost:8081");
serdeConfig.put(KafkaAvroSerializerConfig.SCHEMA_REGISTRY_URL_CONFIG, "http://localhost:8081");
SpecificAvroTestSerde<T> specificAvroTestSerde = new SpecificAvroTestSerde<>();
specificAvroTestSerde.configure(serdeConfig, isSerdeForRecordKeys);
return specificAvroTestSerde;
}
...
mockSchemaRegistryClient.register(JoinTest.INPUT_CTRL_TOPIC + "-key", TestKey.getClassSchema());
mockSchemaRegistryClient.register(JoinTest.INPUT_CTRL_TOPIC + "-value", TestCtrl.getClassSchema());
mockSchemaRegistryClient.register(JoinTest.INPUT_PAYLOAD_TOPIC + "-key", TestKey.getClassSchema());
mockSchemaRegistryClient.register(JoinTest.INPUT_PAYLOAD_TOPIC + "-value", TestPayload.getClassSchema());
请参阅下面的完整堆栈跟踪记录:
java.lang.ClassCastException: test.testdriver.join.TestKey incompatible with test.testdriver.join.TestCtrl
at test.testdriver.join.JoinTest$$Lambda$424.0000000012EB14E0.apply(Unknown Source)
at org.apache.kafka.streams.kstream.internals.AbstractStream.lambda$reverseJoiner$0(AbstractStream.java:98)
at org.apache.kafka.streams.kstream.internals.AbstractStream$$Lambda$428.0000000012E908F0.apply(Unknown Source)
at org.apache.kafka.streams.kstream.internals.KStreamKStreamJoin$KStreamKStreamJoinProcessor.process(KStreamKStreamJoin.java:94)
at org.apache.kafka.streams.processor.internals.ProcessorNode.process(ProcessorNode.java:117)
at org.apache.kafka.streams.processor.internals.ProcessorContextImpl.forward(ProcessorContextImpl.java:183)
at org.apache.kafka.streams.processor.internals.ProcessorContextImpl.forward(ProcessorContextImpl.java:162)
at org.apache.kafka.streams.processor.internals.ProcessorContextImpl.forward(ProcessorContextImpl.java:122)
at org.apache.kafka.streams.kstream.internals.KStreamJoinWindow$KStreamJoinWindowProcessor.process(KStreamJoinWindow.java:55)
at org.apache.kafka.streams.processor.internals.ProcessorNode.process(ProcessorNode.java:117)
at org.apache.kafka.streams.processor.internals.ProcessorContextImpl.forward(ProcessorContextImpl.java:183)
at org.apache.kafka.streams.processor.internals.ProcessorContextImpl.forward(ProcessorContextImpl.java:162)
at org.apache.kafka.streams.processor.internals.ProcessorContextImpl.forward(ProcessorContextImpl.java:122)
at org.apache.kafka.streams.processor.internals.SourceNode.process(SourceNode.java:87)
at org.apache.kafka.streams.processor.internals.StreamTask.process(StreamTask.java:364)
at org.apache.kafka.streams.TopologyTestDriver.pipeInput(TopologyTestDriver.java:406)
at org.apache.kafka.streams.TopologyTestDriver.captureOutputRecords(TopologyTestDriver.java:472)
at org.apache.kafka.streams.TopologyTestDriver.pipeInput(TopologyTestDriver.java:409)
at test.testdriver.join.JoinTest.testJoin(JoinTest.java:68)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:90)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55)
at java.lang.reflect.Method.invoke(Method.java:508)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:532)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:115)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:171)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor$$Lambda$421.0000000012FA2660.execute(Unknown Source)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:72)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:167)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:114)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:59)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$4(NodeTestTask.java:108)
at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$137.000000000F9064E0.execute(Unknown Source)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:72)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:98)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:74)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService$$Lambda$141.00000000122D1F50.accept(Unknown Source)
at java.util.ArrayList.forEach(ArrayList.java:1268)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$4(NodeTestTask.java:112)
at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$137.000000000F9064E0.execute(Unknown Source)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:72)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:98)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:74)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService$$Lambda$141.00000000122D1F50.accept(Unknown Source)
at java.util.ArrayList.forEach(ArrayList.java:1268)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$4(NodeTestTask.java:112)
at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$137.000000000F9064E0.execute(Unknown Source)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:72)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:98)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:74)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:220)
at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:188)
at org.junit.platform.launcher.core.DefaultLauncher$$Lambda$116.00000000122A2870.accept(Unknown Source)
at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:202)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:181)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:128)
at org.eclipse.jdt.internal.junit5.runner.JUnit5TestReference.run(JUnit5TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)