Description
We recently inherited a Porject with a lot of Kafka. Standing on the shoulder of the Spring Giants and with the recent updates we removed as much boilerplate as possible and tried to solve whats possible via configuration.
Delegating Serializer and Deserializer
Delegating Serializer and Deserializer
It took us quite a while to figure why our config was not picked up.
Obiously a beginners fail, solution is here
If you use spring.kafka.value.serialization.bytopic.config
(kafka property) you must set value-deserializer
to org.springframework.kafka.support.serializer.DelegatingByTopicDeserializer
A Working Config:
spring:
kafka:
...
consumer:
...
key-deserializer: "org.springframework.kafka.support.serializer.DelegatingByTopicDeserializer"
value-deserializer: "org.springframework.kafka.support.serializer.DelegatingByTopicDeserializer"
properties:
...
spring.kafka.key.serialization.bytopic.config: "${kafka.consumer.topic_one}:org.apache.kafka.common.serialization.StringDeserializer"
spring.kafka.value.serialization.bytopic.config: "${kafka.consumer.topic_one}:com.example.custom.KafkaSomethiungDeserializer"
-
Any chance that spring boot can warn about this or make those propeties its own so they can be autoconfigured?
-
On the same Topic the value of the
spring.kafka.value.serialization.bytopic.config
is a comma separted list of"topicregex:some.com.package.hard.to.read.and.maintain.if.there.is.more.than.one.serializer"
this list becomes hard to read/maintain.
Beeing able to provide this list as "list" or even as map via yaml would be nice. -
To add some typesafety a Bean of ConsumerTopicToDeserializer or something similiar which autoconfiguration picks up to do it right and save us fools some time :-)
we used the customizer to add it before we found the solution up top
@Bean
fun customizeKafkaConsumerFactory(): DefaultKafkaConsumerFactoryCustomizer {
return DefaultKafkaConsumerFactoryCustomizer {
@Suppress("UNCHECKED_CAST")
val factory = it as DefaultKafkaConsumerFactory<String, Any>
run {
factory.setKeyDeserializer(ErrorHandlingDeserializer(StringDeserializer()))
factory.setValueDeserializer(
ErrorHandlingDeserializer(
DelegatingByTopicDeserializer(
mapOf(
Pattern.compile("SomeTopic") to SomerDeserializer(),
),
JsonDeserializer<Any>(),
)
)
)
};
}
}
- How about some configured
ErrorHandlingDeserializer
spring:
kafka:
...
consumer:
...
key-deserializer: org.springframework.kafka.support.serializer.ErrorHandlingDeserializer
value-deserializer: org.springframework.kafka.support.serializer.ErrorHandlingDeserializer
properties:
...
spring.deserializer.key.delegate.class: org.springframework.kafka.support.serializer.DelegatingByTopicDeserializer
spring.deserializer.value.delegate.class: org.springframework.kafka.support.serializer.DelegatingByTopicDeserializer
spring.kafka.key.serialization.bytopic.config: "${kafka.consumer.topic_one}:org.apache.kafka.common.serialization.StringDeserializer"
spring.kafka.value.serialization.bytopic.config: "${kafka.consumer.topic_one}:com.example.custom.KafkaSomethiungDeserializer"
Maybe you see some things which can be adressed in the Documentation and/or autoconfig.
Thanks for the great work!