使用相同的界面创建多个HTTP客户端

时间:2019-07-15 15:10:37

标签: micronaut

我们需要能够连接到多个Elasticsearch服务器。我们有一个简单的Elasticsearch客户,使用Micronaut的声明性方法定义。

但是,作为多租户环境,我们需要能够定义许多这样的客户端。这些客户端中的每个客户端显然都有不同的URL,并且需要使用不同的HTTPFilter进行身份验证。

Micronaut是一个面向编译时的框架,我如何动态创建许多由配置选项定义的此类bean?

更新: 我看到将@Factory@EachBean注释结合起来可能是一种有前途的方法,但是声明性HTTP客户端是一个接口,而不是一个具体的类。我如何仅基于接口实例化这样的客户端?

请参见https://docs.micronaut.io/latest/guide/index.html#eachBean

2 个答案:

答案 0 :(得分:2)

正常创建声明性@Client 接口,除了 2 个细节:

  1. 使其指向本地“/proxy-elastic”的网址
  2. 向每个声明的方法添加一个@Header("X-Elastic-Cluster") 字符串簇
@Client("/proxy-elastic")
public interface DeclarativeHttpClient {
    @Get("/connectors/{name}")
    void diplay(@Header(value = "X-Elastic-Cluster") String cluster, String name);
}

然后,创建一个 ProxyFilter 并根据 Header 值对 HttpRequest 进行变异 (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"));
    }
}

答案 1 :(得分:0)

答案似乎是:不能。

您需要使用低级HttpClient并动态实例化它。您不能使用声明性客户端。

笨蛋