我的问题是关于在收到触发消息时转储值符合特定条件的KTable。
以下是此问题的一个示例:
KTable-CurrentAccountBalance
John +10,
Joe -1,
Alice -2,
Jill +5,
我的要求是获取所有传入事件中余额为负的记录:FETCH_NEGATIVE_BALANCE_ENTRIES
在不同的命令流上。
我的想法是: 如果使用命令流在CurrentAccountBalance KTable上执行 leftJoin ,我们可以转储CurrentAccountBalance的所有条目(可用于过滤器),但是不会发生。
leftJoin的ValueJoiner仅在右侧接收命令,在左侧接收null(而不是全部) CurrentAccountBalance条目)。我想念什么吗?
谢谢
答案 0 :(得分:0)
由于KTable联接基于主键,因此KTable联接中的单个输入消息将在Kafka Stream中产生一个(或零个)输出消息。
您可以做的是创建一个自定义transformer
,它接收命令并连接到KTable状态(如果指定KTable存储名称,则可以轻松地将该状态连接到转换器)。收到命令后,您可以获取一个state.all()
迭代器,并搜索与您的条件匹配的所有条目,并通过context.forward()
以及在转换器下游的接收器发出它们。
答案 1 :(得分:0)
这是我实现的转储符合特定条件的KTable条目的解决方案。在这里将其描述给以后寻求类似解决方案的其他人。
我将flatmapper的输出写入接收器流。
/ *这是Flatmapper的代码,上面的步骤是Step1 * /
公共类NegativeBalanceMapper实现KeyValueMapper >> { 私有最终BusinessRuleValidator businessRuleValidator; 私人最终StoreHolder storeHolder;
public NegativeBalanceMapper(StoreHolder storeHolder, BusinessRuleValidator businessRuleValidator)
{
this.storeHolder = storeHolder;
this.businessRuleValidator = businessRuleValidator;
}
public Iterable<KeyValue<String, BalanceEntry>> apply(String key, CommandEntry value)
{
List<KeyValue<String, BalanceEntry>> result = new ArrayList<>();
if (value == null)
{
return result;
}
final ReadOnlyKeyValueStore<String, BalanceEntry> ledgerStore = storeHolder.getLedgerStore();
if (ledgerStore != null)
{
KeyValueIterator<String, BalanceEntry> range = ledgerStore.all();
while (range.hasNext())
{
KeyValue<String, BalanceEntry> next = range.next();
if (businessRuleValidator.isNegativeBalance(next.value))
{
result.add(new KeyValue<>(next.key, next.value));
}
}
}
return result;
}
}
/ 这里是接收到FLUSH命令时如何调用它的步骤-上面的step2 / 最终的KStream negativeBalances = filteredCommandStream.flatMap(negativeBalanceMapper);
/ 在这里,我将其推到上方的下沉步骤 /
negativeBalances.to(KafkaConstants.TOPIC_NEGATIVE_BALANCES,Produced.with(Serdes.String(),serdeRegistry.getBalanceEntrySerde()));
感谢Matthias的指导。