6565import org .apache .kafka .streams .kstream .internals .suppress .NamedSuppressed ;
6666import org .apache .kafka .streams .kstream .internals .suppress .SuppressedInternal ;
6767import org .apache .kafka .streams .processor .StreamPartitioner ;
68+ import org .apache .kafka .streams .processor .api .FixedKeyProcessorSupplier ;
6869import org .apache .kafka .streams .processor .api .ProcessorSupplier ;
6970import org .apache .kafka .streams .processor .internals .InternalResourcesNaming ;
7071import org .apache .kafka .streams .processor .internals .InternalTopicProperties ;
@@ -126,6 +127,8 @@ public class KTableImpl<K, S, V> extends AbstractStream<K, V> implements KTable<
126127
127128 private static final String TRANSFORMVALUES_NAME = "KTABLE-TRANSFORMVALUES-" ;
128129
130+ private static final String PROCESSFIXEDKEY_NAME = "KTABLE-PROCESSFIXEDKEY-" ;
131+
129132 private static final String FK_JOIN = "KTABLE-FK-JOIN-" ;
130133 private static final String FK_JOIN_STATE_STORE_NAME = FK_JOIN + "SUBSCRIPTION-STATE-STORE-" ;
131134 private static final String SUBSCRIPTION_REGISTRATION = FK_JOIN + "SUBSCRIPTION-REGISTRATION-" ;
@@ -396,12 +399,14 @@ public <VR> KTable<K, VR> mapValues(final ValueMapperWithKey<? super K, ? super
396399 return doMapValues (mapper , named , materializedInternal );
397400 }
398401
402+ @ SuppressWarnings ("deprecation" )
399403 @ Override
400404 public <VR > KTable <K , VR > transformValues (final ValueTransformerWithKeySupplier <? super K , ? super V , ? extends VR > transformerSupplier ,
401405 final String ... stateStoreNames ) {
402406 return doTransformValues (transformerSupplier , null , NamedInternal .empty (), stateStoreNames );
403407 }
404408
409+ @ SuppressWarnings ("deprecation" )
405410 @ Override
406411 public <VR > KTable <K , VR > transformValues (final ValueTransformerWithKeySupplier <? super K , ? super V , ? extends VR > transformerSupplier ,
407412 final Named named ,
@@ -410,13 +415,15 @@ public <VR> KTable<K, VR> transformValues(final ValueTransformerWithKeySupplier<
410415 return doTransformValues (transformerSupplier , null , new NamedInternal (named ), stateStoreNames );
411416 }
412417
418+ @ SuppressWarnings ("deprecation" )
413419 @ Override
414420 public <VR > KTable <K , VR > transformValues (final ValueTransformerWithKeySupplier <? super K , ? super V , ? extends VR > transformerSupplier ,
415421 final Materialized <K , VR , KeyValueStore <Bytes , byte []>> materialized ,
416422 final String ... stateStoreNames ) {
417423 return transformValues (transformerSupplier , materialized , NamedInternal .empty (), stateStoreNames );
418424 }
419425
426+ @ SuppressWarnings ("deprecation" )
420427 @ Override
421428 public <VR > KTable <K , VR > transformValues (final ValueTransformerWithKeySupplier <? super K , ? super V , ? extends VR > transformerSupplier ,
422429 final Materialized <K , VR , KeyValueStore <Bytes , byte []>> materialized ,
@@ -429,7 +436,39 @@ public <VR> KTable<K, VR> transformValues(final ValueTransformerWithKeySupplier<
429436 return doTransformValues (transformerSupplier , materializedInternal , new NamedInternal (named ), stateStoreNames );
430437 }
431438
432- @ SuppressWarnings ("resource" )
439+ @ Override
440+ public <VOut > KTable <K , VOut > processFixedKey (final FixedKeyProcessorSupplier <? super K , ? super V , VOut > processorSupplier ,
441+ final String ... stateStoreNames ) {
442+ return doProcessFixedKey (processorSupplier , null , NamedInternal .empty (), stateStoreNames );
443+ }
444+
445+ @ Override
446+ public <VOut > KTable <K , VOut > processFixedKey (final FixedKeyProcessorSupplier <? super K , ? super V , VOut > processorSupplier ,
447+ final Named named ,
448+ final String ... stateStoreNames ) {
449+ Objects .requireNonNull (named , "named can't be null" );
450+ return doProcessFixedKey (processorSupplier , null , new NamedInternal (named ), stateStoreNames );
451+ }
452+
453+ @ Override
454+ public <VOut > KTable <K , VOut > processFixedKey (final FixedKeyProcessorSupplier <? super K , ? super V , VOut > processorSupplier ,
455+ final Materialized <K , VOut , KeyValueStore <Bytes , byte []>> materialized ,
456+ final String ... stateStoreNames ) {
457+ return processFixedKey (processorSupplier , materialized , NamedInternal .empty (), stateStoreNames );
458+ }
459+
460+ @ Override
461+ public <VOut > KTable <K , VOut > processFixedKey (final FixedKeyProcessorSupplier <? super K , ? super V , VOut > processorSupplier ,
462+ final Materialized <K , VOut , KeyValueStore <Bytes , byte []>> materialized ,
463+ final Named named ,
464+ final String ... stateStoreNames ) {
465+ Objects .requireNonNull (materialized , "materialized can't be null" );
466+ Objects .requireNonNull (named , "named can't be null" );
467+ final MaterializedInternal <K , VOut , KeyValueStore <Bytes , byte []>> materializedInternal = new MaterializedInternal <>(materialized );
468+ return doProcessFixedKey (processorSupplier , materializedInternal , new NamedInternal (named ), stateStoreNames );
469+ }
470+
471+ @ SuppressWarnings ({"resource" , "deprecation" })
433472 private <VR > KTable <K , VR > doTransformValues (final ValueTransformerWithKeySupplier <? super K , ? super V , ? extends VR > transformerSupplier ,
434473 final MaterializedInternal <K , VR , KeyValueStore <Bytes , byte []>> materializedInternal ,
435474 final NamedInternal namedInternal ,
@@ -497,6 +536,74 @@ private <VR> KTable<K, VR> doTransformValues(final ValueTransformerWithKeySuppli
497536 builder );
498537 }
499538
539+ @ SuppressWarnings ("resource" )
540+ private <VOut > KTable <K , VOut > doProcessFixedKey (final FixedKeyProcessorSupplier <? super K , ? super V , VOut > supplier ,
541+ final MaterializedInternal <K , VOut , KeyValueStore <Bytes , byte []>> materializedInternal ,
542+ final NamedInternal namedInternal ,
543+ final String ... stateStoreNames ) {
544+ Objects .requireNonNull (stateStoreNames , "stateStoreNames" );
545+ final Serde <K > keySerde ;
546+ final Serde <VOut > valueSerde ;
547+ final String queryableStoreName ;
548+ final Set <StoreBuilder <?>> storeBuilder ;
549+
550+ if (materializedInternal != null ) {
551+ // don't inherit parent value serde, since this operation may change the value type, more specifically:
552+ // we preserve the key following the order of 1) materialized, 2) parent, 3) null
553+ keySerde = materializedInternal .keySerde () != null ? materializedInternal .keySerde () : this .keySerde ;
554+ // we preserve the value following the order of 1) materialized, 2) null
555+ valueSerde = materializedInternal .valueSerde ();
556+ queryableStoreName = materializedInternal .queryableStoreName ();
557+ // only materialize if materialized is specified and it has queryable name
558+ if (queryableStoreName != null ) {
559+ final StoreFactory storeFactory = new KeyValueStoreMaterializer <>(materializedInternal );
560+ storeBuilder = Set .of (new FactoryWrappingStoreBuilder <>(storeFactory ));
561+ } else {
562+ storeBuilder = null ;
563+ }
564+ } else {
565+ keySerde = this .keySerde ;
566+ valueSerde = null ;
567+ queryableStoreName = null ;
568+ storeBuilder = null ;
569+ }
570+
571+ final String name = namedInternal .orElseGenerateWithPrefix (builder , PROCESSFIXEDKEY_NAME );
572+
573+ final KTableProcessorSupplier <K , V , K , VOut > tableProcessorSupplier = new KTableProcessFixedKey <>(
574+ this ,
575+ supplier ,
576+ queryableStoreName );
577+
578+ final ProcessorParameters <K , VOut , ?, ?> processorParameters =
579+ unsafeCastProcessorParametersToCompletelyDifferentType (
580+ new ProcessorParameters <>(
581+ new StoreDelegatingProcessorSupplier <>(
582+ tableProcessorSupplier ,
583+ storeBuilder ),
584+ name
585+ ));
586+
587+ final GraphNode tableNode = new ProcessorToStateConnectorNode <>(
588+ name ,
589+ processorParameters ,
590+ stateStoreNames
591+ );
592+ maybeSetOutputVersioned (tableNode , materializedInternal );
593+
594+ builder .addGraphNode (this .graphNode , tableNode );
595+
596+ return new KTableImpl <>(
597+ name ,
598+ keySerde ,
599+ valueSerde ,
600+ subTopologySourceNodes ,
601+ queryableStoreName ,
602+ tableProcessorSupplier ,
603+ tableNode ,
604+ builder );
605+ }
606+
500607 @ Override
501608 public KStream <K , V > toStream () {
502609 return toStream (NamedInternal .empty ());
0 commit comments