I am using OpenSearchClient which uses the apache https client5 internally to communicate with the opensearch server. I need to intercept the search request that is sent from the application to the opensearch server (i.e. to log the search query). For this, I tried to add a HttpRequestInterceptor that will intercept the request and log the entity. But, the body retrieval from the EntityDetails is not possible in this case. Following code is the config I am using:-
public OpenSearchClient opensearchClient() {
val builder = ApacheHttpClient5TransportBuilder.builder(new HttpHost(protocol, host, port));
builder.setHttpClientConfigCallback(
httpClientBuilder -> {
val connectionManager =
PoolingAsyncClientConnectionManagerBuilder.create()
.setDefaultConnectionConfig(
ConnectionConfig.custom()
.setConnectTimeout(timeout, TimeUnit.MILLISECONDS)
.setSocketTimeout(3000, TimeUnit.MILLISECONDS)
.build())
.build();
return httpClientBuilder
.setConnectionManager(connectionManager)
.addRequestInterceptorFirst(
(request, entity, context) -> {
log.info("Class: {}", entity.getClass());
log.info("Package: {}", entity.getClass().getPackageName());
log.info("Name: {}", entity.getClass().getName());
});
});
return new OpenSearchClient(builder.build());
}
The EntityDetails here is an instance of InternalAbstractHttpAsyncClient that I could see using the debugger. Seems like extraction of the request body from it is not straightforward. The logs are below:
2024-03-20T12:26:04.998+06:00 INFO 382364 --- [ient-dispatch-1] n.n.i.s.api.config.OpenSearchConfig : Class: class org.apache.hc.client5.http.impl.async.InternalAbstractHttpAsyncClient$2
2024-03-20T12:26:04.999+06:00 INFO 382364 --- [ient-dispatch-1] n.n.i.s.api.config.OpenSearchConfig : Package: org.apache.hc.client5.http.impl.async
2024-03-20T12:26:05.000+06:00 INFO 382364 --- [ient-dispatch-1] n.n.i.s.api.config.OpenSearchConfig : Name: org.apache.hc.client5.http.impl.async.InternalAbstractHttpAsyncClient$2
My goal is to retrieve the request body from the entity. The apache http client5 docs suggest to use decorator pattern to achieve such behavior. Any help would be appreciated.
Yes, of course, it is, but one needs to use a request execution interceptor for that end.
In the example below a custom execution interceptor buffers content of the request entity if its not repeatable in order to make it repeatable, so that the request could be automatically redirected or re-authenticated