1

Is it possible with Spring Java to read a string-array from a map of named values from a YAML file as a constant (specifically for use with the @KafkaListener annotation from Spring-Kafka)?

   a:
     b:
       topics:
         foo: FooTopic
         bar: BarTopic

Would result in a constant = ['FooTopic','BarTopic'].

I'm assuming it would be something similar to the expression that evaluates to a list as with some of the examples from [ Reading a List from properties file and load with spring annotation @Value ]. I'm just unsure of what the syntax might be, as the only way I've seen is using multiple annotations to construct a POJO like [ Reading a map from yaml in Java getting null ] which doesn't work in the @KafkaListener annotation context.

Note: The topics need to be named as they are extracted individually in a different context.

Edit: spelling

Asmodean
  • 339
  • 3
  • 13

1 Answers1

1

It's not going to work that way without extracting @ConfigurationProperties.

This is what I have in a forehead:

@KafkaListener(topics = {"${kafka.topics.foo}", "${kafka.topics.bar}"})

But at the same time having this:

@ConfigurationProperties("kafka")
public class KafkaAppProperties {

    private Map<String, String> topics  = new HashMap<>();

    public Map<String, String> getTopics() {
        return this.topics;
    }

}

I can do:

 @KafkaListener(topics = "#{@'kafka-org.springframework.integration.samples.kafka.KafkaAppProperties'.topics.values()}")

Right, that bean name for the KafkaAppProperties looks awkward, but we can overcome it with the artificial bean:

@Autowired
private KafkaAppProperties properties;

@Bean
public Map<String, String> kafkaTopic() {
    return this.properties.getTopics();
}

...

@KafkaListener(topics = "#{@kafkaTopic.values()}")
public void handle(Object record) {
    ...
}
Artem Bilan
  • 113,505
  • 11
  • 91
  • 118
  • I keep getting a 'NoSuchBeanDefinitionException` regardless of whether I explicitly create a bean in the configuration or whether I just use the 'awkward' method of having everything in the annotation. It was almost like the `@KafkaListener` was looking for the bean before it was created. Thoughts? – Asmodean Aug 14 '17 at 14:53
  • Yup; looks exactly like the POJO in your example, just with a different string to represent the YAML path. – Asmodean Aug 14 '17 at 14:58
  • OK. Do you have then `@EnableConfigurationProperties(KafkaAppProperties.class)` on one of your `@Configuration`/`@SpringBootApplication` ? – Artem Bilan Aug 14 '17 at 14:59
  • I didn't originally (was trying just using the `@Bean` annotation), but I just tried adding that in below the `@Configuration` and it resulted in the same error. – Asmodean Aug 14 '17 at 15:13
  • Not sure what's going on in your application. Everything I have shared with you I checked on this sample application: https://github.com/spring-projects/spring-integration-samples/tree/master/basic/kafka – Artem Bilan Aug 14 '17 at 15:14
  • Turned out to be a naming thing, and possibly an unneeded annotation that was messing with bean creation; it works now though. Thanks for the help! – Asmodean Aug 15 '17 at 13:27