DUE TO SPAM, SIGN-UP IS DISABLED. Goto Selfserve wiki signup and request an account.
...
For stream-table joins, the join key is the stream record's key, so the processor works correctly. For stream-globalTable joins, the join key is computed from the stream record via a user-supplied KeyValueMapper and is generally different from the stream record's key. However, the current KStreamKTableJoinProcessor#doJoin implementation passes the stream record's key into ValueJoinerWithKey.apply(), not the mapped join key.
The g lThe discrepancy is not surfaced at runtime: the DSL signature pins the joiner's first type parameter to the stream key type K, and the implementation passes record.key() (also K), so types align, and no error or warning is raised. The join still matches records correctly because matching is done by the KeyValueMapper, not the joiner. However, KIP-149 specified readOnlyKey would be the join key, which for stream–globalKTable joins stream–globalTable joins is the mapped key, not the stream key. Any joiner that uses readOnlyKey will silently produce output values that encode the stream key where it is expected to be the join key, with no error or warning surfaced.
Public Interfaces
KStream
Four new methods are added to KStream. They mirror the four existing stream-globalTable join overloads that take a ValueJoinerWithKey.
...
The existing KStream.join(GlobalKTable, KeyValueMapper, ValueJoinerWithKey) and KStream.leftJoin(GlobalKTable, KeyValueMapper, ValueJoinerWithKey) overloads are retained for backwards compatibility. They continue to pass the stream record's key into the joiner, but are marked as @Deprecated, and are targeted to be removed at in a future major release.
| Code Block |
|---|
@Deprecated
<GlobalKey, GlobalValue, VOut> KStream<K, VOut> join(
final GlobalKTable<GlobalKey, GlobalValue> globalTable,
final KeyValueMapper<? super K, ? super V, ? extends GlobalKey> keySelector,
final ValueJoinerWithKey<? super K, ? super V, ? super GlobalValue, ? extends VOut> joiner
)
@Deprecated
<GlobalKey, GlobalValue, VOut> KStream<K, VOut> join(
final GlobalKTable<GlobalKey, GlobalValue> globalTable,
final KeyValueMapper<? super K, ? super V, ? extends GlobalKey> keySelector,
final ValueJoinerWithKey<? super K, ? super V, ? super GlobalValue, ? extends VOut> joiner,
final Named named
)
@Deprecated
<GlobalKey, GlobalValue, VOut> KStream<K, VOut> leftJoin(
final GlobalKTable<GlobalKey, GlobalValue> globalTable,
final KeyValueMapper<? super K, ? super V, ? extends GlobalKey> keySelector,
final ValueJoinerWithKey<? super K, ? super V, ? super GlobalValue, ? extends VOut> joiner
)
@Deprecated
<GlobalKey, GlobalValue, VOut> KStream<K, VOut> leftJoin(
final GlobalKTable<GlobalKey, GlobalValue> globalTable,
final KeyValueMapper<? super K, ? super V, ? extends GlobalKey> keySelector,
final ValueJoinerWithKey<? super K, ? super V, ? super GlobalValue, ? extends VOut> joiner,
final Named named
) |
...
The existing join/leftJoin stream-globalTable overloads taking ValueJoinerWithKey are deprecated. Existing applications continue to compile and run unchanged, but the compiler will emit deprecation warnings, and the methods will be removed in a future major release.
The new
joinOnMappedKeyandleftJoinOnMappedKeymethods are additive. Existing code compiles and runs unchanged; migration is required only before the deprecated overloads are removed.Stream-globalTable overloads taking
ValueJoiner(no key access) are unaffected.Migration guidance for the new join methods will be added to the Streams upgrade guide.
...
Unit tests in KStreamGlobalKTableJoinTest, KStreamGlobalKTableLeftJoinTest and other related tests covering the new join methods.
Rejected Alternatives
Change KStreamKTableJoinProcessor#doJoin in place
...
Even if worked around with an unsafe cast, this would silently change the observable value of readOnlyKey for every existing application using ValueJoinerWithKey with a stream-globalKTable globalTable join, with no migration path.
...