0

I am unable to configure custom handlers for my stream consumer using StreamsBuilderFactoryBeanCustomizer.

@Bean
    public StreamsBuilderFactoryBeanCustomizer customizer() { 
        return fb -> {          
    fb.getStreamsConfiguration().put(StreamsConfig.DEFAULT_DESERIALIZATION_EXCEPTION_HANDLER_CLASS_CONFIG, CustomDeserializationHandler.class);
            fb.getStreamsConfiguration().put(StreamsConfig.DEFAULT_PRODUCTION_EXCEPTION_HANDLER_CLASS_CONFIG, CustomEventErrorHandler.class);               
            fb.getStreamsConfiguration().forEach((k,v) -> System.err.println("Key , Value "+ k + " , " + v));
        };
    }

After setting the above in my spring boot @Configuration class and starting application, I still see defaults under SteamConfig. According to docs

Blockquote

customizer will be invoked by the binder right before the factory bean is started.

Blockquote

But it seems like binder is not invoking StreamsBuilderFactoryBeanCustomizer Is this a known issue ? I am using spring-cloud-stream-binder-kafka-streams with 2020.0.1 (spring-cloud.version) 2.4.2(spring boot)

021-03-11 11:52:04.386 [main] INFO  o.apache.kafka.streams.StreamsConfig - StreamsConfig values: 
    acceptable.recovery.lag = 10000
    application.id = service-stream
    application.server = 
    bootstrap.servers = [localhost:9092]
    buffered.records.per.partition = 1000
    built.in.metrics.version = latest
    cache.max.bytes.buffering = 10485760
    client.id = 
    commit.interval.ms = 1000
    connections.max.idle.ms = 540000
    default.deserialization.exception.handler = class org.apache.kafka.streams.errors.LogAndContinueExceptionHandler
    default.key.serde = class org.apache.kafka.common.serialization.Serdes$ByteArraySerde
    default.production.exception.handler = class org.apache.kafka.streams.errors.DefaultProductionExceptionHandler
    default.timestamp.extractor = class org.apache.kafka.streams.processor.FailOnInvalidTimestamp
    default.value.serde = class org.apache.kafka.common.serialization.Serdes$ByteArraySerde
    max.task.idle.ms = 0
    max.warmup.replicas = 2
Andy
  • 87
  • 6

2 Answers2

1

Looks like there are two interfaces of the same name: One from Spring Kafka and another in Spring Boot. The binder only takes into consideration the one from Spring Kafka. Please make sure that you are implementing that one. We have filed an issue in Boot to address this inconsistency.

sobychacko
  • 5,099
  • 15
  • 26
  • Thanks @sobychacko that was indeed the case. Using the correct import statement causes the registration as expected. – Andy Mar 11 '21 at 21:13
  • Good to know. Feel free to accept the answer, just in case if anyone else having the same problem and come to this thread. – sobychacko Mar 11 '21 at 22:47
  • But the interface from spring-kafka is deprecated. – Bhavesh Shah Jul 06 '21 at 04:40
  • 1
    Spring Kafka deprecated `StreamsBuilderFactoryBeanCustomizer` and provides a `StreamsBuilderFactoryBeanConfigurer` instead to avoid the name clash with Spring Boot. See this issue for details: https://github.com/spring-projects/spring-kafka/issues/1736 – sobychacko Jul 06 '21 at 15:11
1

This has been updated in spring cloud version 2020.0.3. One can use org.springframework.kafka.config.StreamsBuilderFactoryBeanConfigurer instead.