在Kafka Streams应用程序中,是否可以使用输出主题的通配符列表定义拓扑?

时间:2019-06-24 10:01:11

标签: java apache-kafka apache-kafka-streams kafka-producer-api

我有多模式Kafka Streams应用程序,该应用程序通过联接到KTable来丰富记录,然后将经过丰富的记录传递给我们。

输入主题的命名格式目前定义良好,但我将其更改为通配符。我想确定每个记录的输入主题,通过正则表达式替换派生输出主题,然后继续发送。

例如在收听event.raw.*时,event.raw.foo上有一条记录,我希望在event.foo上将其传递出去。

我意识到我可以通过Processor API获得输入主题:

public class EnrichmentProcessor extends AbstractProcessor<String, GenericRecord> {

    @Override
    public void process(String key, GenericRecord value) {
        //Do Join...

        //Determine output topic and forward
        String outputTopic = context().topic().replaceFirst(".raw.", ".");
        context().forward(key, value, To.child(outputTopic));
        context().commit();
    }
}

但是,当我尝试定义拓扑时,这无济于事,因为我无法预先知道输出主题将是什么。

  InternalTopologyBuilder topologyBuilder = new InternalTopologyBuilder();
        topologyBuilder.addSource("SOURCE", stringDeserializer, genericRecordDeserializer, "event.raw.*")
        .addProcessor("ENRICHER", EnrichmentProcessor::new, "SOURCE")
        .addSink("OUTPUT", outputTopic, stringSerializer, genericRecordSerializer, "ENRICHER"); // How can I register all possible output topics here?

有人以前解决过这种情况吗?

我知道,如果我事先有一个可能的输出主题名称列表,则可以在拓扑上定义多个接收器,但我不会。

当我没有预先可能的输出主题名称的硬编码列表时,是否可以定义拓扑以动态分配输出主题名称?

1 个答案:

答案 0 :(得分:0)

这应该可行:您可以使用Topology#addSink(..., new TopicNameExtractor(){...}, ...)动态设置输出主题名称。 TopicNameExtractor可以访问RecordContext,从而可以通过context.topic()获取输入的主题名称。因此,您应该能够基于输入主题名称来计算输出主题名称。