简体   繁体   中英

Setting Dapr @Topic fields at runtime

Stack: Java Jakarta EE10 Wildfly27 Docker Dapr

The issue is configuration of Topics, dynamically. I have several environments TEST/DEV/PROD and i want to use different topics for the different environments, but the same image. Ideally i would like to set the topic via Environment variables.

So why not do this declarative? Well as i run Dapr on Azure Container Service (ACA) and it does NOT(!) support declarative config(!)

So the way to do this in my subscriber is via the Annotation @Topic

Like this @Topic(name = "cache_update", pubsubName = "${myAppProperty:messagebus}")

In the sample above "messagebus" is the default value and "myAppProperty" is the name of the application Property.

Had i used Spring this would have worked but we are using Jakarta EE10 running on Wildfly 27

How on earth can i get this to work?

Dapr Java SDK only provides a native integration for Spring Boot; where Dapr-specific annotations such as Topic gets processed and their configuration synthesized into the respective action taking into consideration property resolution, which in your case, would be the topic subscription creation.

To have the a subscription created dynamically toward the config-wired topic values, you can use the Dapr SDK programmatically to create subscription topics by exposing a route over the /dapr/subscribe endpoint:

@Path("/dapr")
public class DaprController {

   private static final DefaultObjectSerializer SERIALIZER = new DefaultObjectSerializer();

   @GET
   @Produces(MediaType.APPLICATION_JSON)
   @Path("/subscribe")
   public Response subscribeTopics() {
       String topic = "TOPIC_NAME"; // you can resolve this value out of environment variables, system properties or MicroProfile config is you are using Wildfly-extras
       String pubsub = "PUBSUB"; // resolve this values as well through any external meaning
       TopicConfig config = new TopicConfig(pubsub, topic, "/handleTopicRoute", Collections.emptyList());
       return Response.ok(SERIALIZER.serialize(Collections.singleton(config))).build();
   }
}

Here is the Topic configuration template (Inspired from Spring Boot integration DaprTopicConfiguration):

public class TopicConfig {
  private final String pubsubName;
  private final String topic;
  private final String route;
  private final Map<String, String> metadata;

  public TopicConfig(String pubsubName, String topic, String route, Map<String, String> metadata) {
    this.pubsubName = pubsubName;
    this.topic = topic;
    this.route = route;
    this.metadata = Collections.unmodifiableMap(metadata);
  }

  public String getPubsubName() {
    return pubsubName;
  }

  public String getTopic() {
    return topic;
  }

  public String getRoute() {
    return route;
  }

  public Map<String, String> getMetadata() {
    return metadata;
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM