0

I am implementing a Routing Datasource, where the datasource is picked based on the @Destination dbRoutingKey. For multiple rest endpoints we can inject it into the publisher context in a WebFilter and later use it to determine the lookup key. With Spring RSocket @MessageMapping how to write this dbRoutingKey to the request publish context for multiple endpoints?

/*
This works for Rest endpoints.
*/

@Component
@Order(-2)
public class TenancyContextFilter implements WebFilter {

  @Override
  public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
    String tenant = extractTenantFromRequestPath(exchange.getRequest());
    if (tenant != null) {
      return chain.filter(exchange).subscriberContext(context -> context.put(DB_ROUTING_KEY, tenant));
    }
    return Mono.error(new TenantExtractionException());
  }

  private String extractTenantFromRequestPath(ServerHttpRequest request) {
    String applicationPath = request.getPath().pathWithinApplication().value();
    AntPathMatcher matcher = new AntPathMatcher();
    matcher.setCaseSensitive(false);
    if (matcher.match("/{tenant}/api/**", applicationPath)) {
      Map<String, String> templateVariables = matcher.extractUriTemplateVariables("/{tenant}/api/**", applicationPath);
      return templateVariables.get("tenant");
    }
    return null;
  }

}

/*
Sample code
With Rocket we can inject the key in every @MessageMapping method
*/

@MessageMapping("test.request.{dbRoutingKey}")
public Mono<String> getData(@Destination String dbRoutingKey) {
  
 return dbDataService.getData().contextWrite(ctx -> ctx.put(DB_ROUTING_KEY, dbRoutingKey));

}
Zeno
  • 1
  • 1

0 Answers0