我的场景是我使用了很多共享前缀的Kafka话题(例如house.door,house.room) 并使用Kafka流正则表达式主题模式API消耗所有主题。 一切看起来都不错,我得到数据的关键和信息。
为了处理数据我需要主题名称,所以我可以根据主题名称进行连接, 但我不知道如何在Kafka流DSL中获取主题名称。
解决我的问题的一种可能方法是使用我的消息保存主题名称。 但如果我能直接获得主题名称会更好。
那么,如何在Kafka流中获取当前的Kafka主题?
答案 0 :(得分:1)
可通过Processor API访问记录元数据。由于其处理器API集成,它也可通过DSL间接访问。
使用Processor API,您可以通过ProcessorContext访问记录元数据。您可以在Processor#init()期间在处理器的实例字段中存储对上下文的引用,然后在Processor#process()中查询处理器上下文(例如,对于Transformer)。自动更新上下文以匹配当前正在处理的记录,这意味着诸如ProcessorContext#partition()之类的方法始终返回当前记录的元数据。在调度的punctuate()函数中调用处理器上下文时会有一些注意事项,请参阅Javadocs了解详细信息。
例如,如果您将DSL与自定义Transformer结合使用,则可以将输入记录的值转换为还包括分区和偏移元数据,然后可以利用此信息来执行后续DSL操作(如map或filter)。
答案 1 :(得分:1)
要添加到Matthias J. Sax点,我已经附加了示例代码来演示如何实现。
public static void main(final String[] args) {
try {
final Properties props = new Properties();
props.put(StreamsConfig.APPLICATION_ID_CONFIG, "streamProcessor");
props.put(StreamsConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
props.put(StreamsConfig.STATE_DIR_CONFIG, "state-store");
props.put(StreamsConfig.DEFAULT_KEY_SERDE_CLASS_CONFIG, Serdes.String().getClass().getName());
props.put(StreamsConfig.DEFAULT_VALUE_SERDE_CLASS_CONFIG, Serdes.String().getClass().getName());
props.put(StreamsConfig.COMMIT_INTERVAL_MS_CONFIG, 10 * 1000);
props.put(StreamsConfig.CACHE_MAX_BYTES_BUFFERING_CONFIG, 0);
StreamsBuilder streamsBuilder = new StreamsBuilder();
final KStream<String, String> textLines = streamsBuilder.stream(inputTopicList);
final KStream<String, String> textLines = builder.stream(inputTopiclist);
textLines.transform(getTopicDetailsTransformer::new)
.foreach(new ForeachAction<String, String>() {
public void apply(String key, String value) {
System.out.println(key + ": " + value);
}
});
textLines.to(outputTopic);
} catch (Exception e) {
System.out.println(e);
}
}
private static class getTopicDetailsTransformer implements Transformer<String, String, KeyValue<String, String>> {
private ProcessorContext context;
@Override
public void init(final ProcessorContext context) {
this.context = context;
}
public KeyValue<String, String> transform(final String recordKey, final String recordValue) {
//here i am returning key as topic name.
return KeyValue.pair(context.topic(), recordValue);
}
@Override
public void close() {
// Not needed.
}
}