Search code examples
spring-pulsar

Defining multiple Pulsar Producers in Spring Boot application


We have a SpringBoot application that sends messages into multiple topics, each with a defined JSON Schema. I would like to reduce the boilerplate code so that we don't have to call setSchema on the PulsarTemplate instance when the defined type already has that information. Also, we could potentially remove the need to call .send with topic name since it is known in advance and is static.

Doing this, we could reduce the code from:

@Autowired PulsarTemplate<Type1> template1;
@Autowired PulsarTemplate<Type2> template2;

void send1(...) {
  template1.setSchema(Schema.JSON(Type1));
  template1.send("topic-1", ...);
}


void send2(...) {
  template2.setSchema(Schema.JSON(Type2));
  template2.send("topic-2", ...);
}

to

@Autowired PulsarTemplate<Type1> template1;
@Autowired PulsarTemplate<Type2> template2;

void send1(...) {
  template1.send(new Type1(...));
}


void send2(...) {
  template2.send(new Type2(...));
}

I'm not finding a good solution and would like to know if there is way to do this or is my thinking is not in the right direction at all.

Thank you


Solution

  • The auto-configuration only configures a single template instance. So even though Spring will autowire your 2 template variables (template1, template2), they ultimately point to the same template instance.

    @Autowired PulsarTemplate<Type1> template1;
    @Autowired PulsarTemplate<Type2> template2;
    

    As such, there is no way for the framework to know when you would want the "topic1/schema1" or "topic2/schema2" to be applied to the instance.

    There is a global property spring.pulsar.producer.topic-name that can be set to specify the default topic when one is not specified (does not help your 2 template case though as you really want 2 defaults).

    It would not be too much work to add the ability for users to configure a mapping of message types to schema and topics to use. Something like:

    spring.pulsar.producer.topic-mappings:
      acme.Type1: "topic1"
      acme.Type2: "topic2"
    
    spring.pulsar.producer.schema-mappings:
      acme.Type1: SchemaType.JSON(acme.Type1)
      acme.Type2: SchemaType.JSON(acme.Type2)
    

    This would solve your use case. I created https://github.com/spring-projects-experimental/spring-pulsar/issues/269.

    However, until the above feature is added I am afraid we are stuck w/ the boilerplate.