We need to be able to connect to multiple Elasticsearch servers. We have a simple Elasticsearch client, defined with the declarative approach of Micronaut.
However, being a multi-tenant environment, we need to be able to define many such clients. Each of these clients has obviously a different URL and needs to use a different HTTPFilter for authentication.
Micronaut being a compile-time focused framework, how can I dynamically create many such beans, defined by configuration options?
UPDATE:
I see that the @Factory
combined with @EachBean
annotation might be a promising way to do it, but the declarative HTTP client is an interface, not a concrete class. How can I instantiate such a client, based on the interface alone?
See https://docs.micronaut.io/latest/guide/index.html#eachBean
Create your declarative @Client interface normally except for 2 details :
@Client("/proxy-elastic")
public interface DeclarativeHttpClient {
@Get("/connectors/{name}")
void diplay(@Header(value = "X-Elastic-Cluster") String cluster, String name);
}
Then, create a ProxyFilter and mutate the HttpRequest based on the Header value (https://docs.micronaut.io/latest/guide/index.html#proxyClient)
@Filter("/proxy-elastic/**")
public class KafkaConnectClientProxy extends OncePerRequestHttpServerFilter {
@Inject
ProxyHttpClient client;
@Override
protected Publisher<MutableHttpResponse<?>> doFilterOnce(HttpRequest<?> request, ServerFilterChain chain) {
// retrieve the config for this cluster
String cluster = request.getHeaders().get("X-Elastic-Cluster");
var config = getConfigForCluster(cluster);
URI newURI = URI.create(config.url);
// call kafka connect with proper URL and Auth
return Publishers.map(client.proxy(
request.mutate()
.uri(b -> b
.scheme(newURI.getScheme())
.host(newURI.getHost())
.port(newURI.getPort())
.replacePath(StringUtils.prependUri(
newURI.getPath(),
request.getPath().substring("/proxy-elastic".length())
))
)
.basicAuth(config.basicAuthUsername, config.basicAuthPassword)
), response -> response.header("X-My-Response-Header", "YYY"));
}
}