0

I Have the following code, i want to provide the "topicName" as paramater or read it dynamically from a property, is the possible

@KafkaListener(offsetReset = OffsetReset.EARLIEST)
public class KafkaConsumer {

    private final String topicName;

    public KafkaConsumer(String topicName) {
        this.topicName = topicName;
    }

    @Topic("topicName")
    public void receive(@KafkaKey String day, String message) {
        System.out.println("Got Message for the  - " + day + " and Message is  " + message);
    }

}
shaydel
  • 589
  • 4
  • 15
  • Does this answer your question? [How do I read application properties in Micronaut?](https://stackoverflow.com/questions/53436144/how-do-i-read-application-properties-in-micronaut) – daniu Aug 31 '22 at 10:44
  • not really ,since it's reading the value from static file ,i need to use a different topic name in every method call, such as getting the topic name from the user and then creating a listener – shaydel Aug 31 '22 at 14:32
  • 1
    Then the answer is "it's not possible". The annotation is used by the framework to easily create a consumer and register it for the topic at compile time. To dynamically read topics, you'll need to manually create a consumer for the given topic. – daniu Aug 31 '22 at 15:38
  • please provide an example for such consumer in micronaut – shaydel Sep 01 '22 at 10:06

2 Answers2

0

You can do:

@Topic("${myTopicFromProperties}")
Denis
  • 603
  • 4
  • 8
0

It's a bit confusing because if the question to be combined with the OP's comment "i need to use a different topic name in every method call, such as getting the topic name from the user and then creating a listener" one might think of the following examples/scenarios based on the official doc:

@Topic({"topic1", "topic2", "topic3}) //multiple topics, see "Specifying Topics" sub-section on the linked page
public void receive(
    @KafkaKey String key,
    String message,
    long offset, 
    int partition, 
    String topic, // topic as a parameter
    long timestamp
) { 
    System.out.println("Got message: " + message + " from topic: " + topic);
}

You can also use ConsumerRecord and get all the necessary information from there:

// "Receiving a ConsumerRecord" sub-section on the linked page
@Topic({"topic1", "topic2", "topic3})
public void receive(ConsumerRecord<String, String> record) { 
    System.out.println("Got message: " + record.value() + " from topic: " + record.topic());
}

You should also be able to specify the topics through the property placeholders as found in another answer like @Topic({"${topic1}", "${topic2}", "${topic3}"}).

P.S. The above examples assume that for each specified topic both the message key and the message body are deserialized to strings.

Dmitry Khamitov
  • 3,061
  • 13
  • 21
  • the param in your comment [ String topic ] is used as metadata when consuming messages, i want to create the consumer using topic name provided in runtime – shaydel Sep 07 '22 at 08:22
  • @shaydel what's the source of your topic name then? Meaning who will pass this name to whatever responsible for consumer creation and when is it supposed to happen? It's quite unclear form the question. It would be great if you provided more details of your use case. – Dmitry Khamitov Sep 07 '22 at 11:50