0

I have a custom dead letter recoverer which I've implemented so that I could override the createProducer method

protected ProducerRecord<Object, Object> createProducerRecord(ConsumerRecord<?, ?> record,
            TopicPartition topicPartition, Headers headers, @Nullable byte[] key, @Nullable byte[] value) 

This is needed because my DLT needs a different schema from the source. I need to inject spring @Values from my application environment specific ( dev, review, test, prod) yamls to get values to create this new schema and produce to the DLT.

 import org.springframework.beans.factory.annotation.Value

public class MyDeadLetterPublishingRecoverer extends DeadLetterPublishingRecoverer
{
   @Value("${spring.kafka.custom.myValue}")
    private String myValue;

   public MyDeadLetterPublishingRecoverer (
    KafkaOperations<?, ?> template,
    BiFunction<ConsumerRecord<?, ?>, Exception, TopicPartition> destinationResolver) {
  super(template, destinationResolver);
}

}

However, myValue is always null because the DeadLetterPublishingRecoverer is not a component or similar stereotype so there is no spring context to enable the resolution of the variable. If one of the stereotypes is added to MyDeadLetterPublishingRecoverer then the constructor complains about needing a bean so that the desitination resolver can be autowired ( which I don't want anyway) "Could not autowire. No beans of 'BiFunction<ConsumerRecord, Exception, TopicPartition>' type found"

So, I'm looking for either a way to get the @value annotation to work in the custom DeadLetterPublishingRecoverer or an alternate way to pull the values from application.yml to use in the custom DeadLetterPublishingRecoverer

Gary Russell
  • 166,535
  • 14
  • 146
  • 179
feenix110998
  • 61
  • 1
  • 7

1 Answers1

0

Just define the recoverer as a @Bean, or annotate it as a @Component, and Spring will take care of all the wiring.

If you are using Spring Boot, just the presence of the bean is enough, Boot will wire it into the container factory (if you are using Boot's auto configured factory).

If you are not using boot, you will have to set in on the container factory yourself.

Correction: Boot will auto configure a CommonErrorHandler that contains the recoverer, not the recoverer itself.

If you don't need a destination resolver, implement the simpler constructor instead (the one that just takes a KafkaOperations - template).

Gary Russell
  • 166,535
  • 14
  • 146
  • 179
  • I'm using Spring Boot , should have mentioned that. When I add '@Bean' to the Custom recoverer "MyDeadLetterPublishingRecoverer " the error is "@Bean' not applicable to type" If I add '@Component' that's when I get "Could not autowire. No beans of 'BiFunction' type found" I do need the destination resolver, I'm using a topic other than the default. Thanks – feenix110998 Feb 15 '23 at 21:55
  • To define it as a bean, don't add it to the class, add a `@Bean` definition factory method to some `@Configuration` class. For `@Component` to work, the destination resolver would have to be declared as a `@Bean` or `@Component` too. – Gary Russell Feb 15 '23 at 22:20
  • I also added a correction; Boot won't auto configure a recoverer bean, but it will auto configure a `DefaultErrorHandler` configured to use your recoverer. – Gary Russell Feb 15 '23 at 22:24
  • Adding the custom recoverer instantiation as a bean factory method was the solution, thanks sir! – feenix110998 Feb 16 '23 at 00:01