I have multiple httpClient instances in one app. I want to collect metrics by each httpClient with specific label or name. Is it possible with vert.x? I saw in documentation block of collecting httpClient metrics and I want to enrich each metric with specification for client.
You can provide a metrics name when creating the client:
HttpClientOptions options = new HttpClientOptions().setMetricsName("foo");
Related
I am new to spring webflux. I am trying to implement the ThreadLocal using spring webflux.
I have a requirement where I need to pass the header from one microservice to another microservice in webclient.
I do not want to pass the header from on service to another service carrying it manually and assigning it in each request.
So thought of using ThreadLocal when I can set it and can access that in webclient call.
I am try to find a sample application where I can refer ThreadLocal with in spring webflux.
You should not use ThreadLocal in reactive environment. Webflux (which based on Reactor) is a non blocking framework. It reuses threads so the steps of one reactive pipeline can run in different threads and also multiple requests can use the same thread concurrently - until one waits, another operation will be picked and executed. Imagine if your request puts something into threadlocal and waits - for example - on a db select, another request can override this value and the next pipeline stage of the original request will see that new value belongs to another request. Threadlocal is good for request-per-thread model.
For webflux, you can use contexts. For example put the value into the pipeline in a WebFilter, then you can retrieve it in any point of the reactive pipeline:
chain.filter(exchange).contextWrite(<your data>)
In the pipeline (in map/flatmap...)
Mono.deferContextual(...)
Here is the link for documentation.
Alternatively you can lift ThreadLocal's value on every operation using Hooks, but this is not a nice and bulletproof solution.
I am new to Kafka and We are using Spring Web Flux in the application. We have a requirement to push two different messages to two different Topics say T1 and T2. Kafka Broker is the same.
We are using ReactiveKafkaProducerTemplate and it working fine.
#Bean
public ReactiveKafkaProducerTemplate<String, Object> reactiveKafkaProducerTemplate(
KafkaProperties properties) {
final Map<String, Object> props = properties.buildProducerProperties();
return new ReactiveKafkaProducerTemplate<String, Object>(SenderOptions.create(props));
}
Now we have requirement to compress only one Topic[T1] content alone as the message size is more on the Topic T1.
Do we have something like RoutingKafkaTemplate support in Reactive Kafka or Project Reactor where we can modify the Producer Config as per Topic needs?
No; there is no equivalent; you need to configure two templates with different producer configs.
I need to calculate some kind of digest of the request body using the WebClient of Webflux and this digest must be set into a HTTP header. Using the good old Spring MVC ClientHttpRequestInterceptor is easy because the request body is provided as an array of bytes.
The ExchangeFilterFunction does not provide access to the request body.
The body is sent as JSon and Spring uses Jackson in order to serialize Java objects, so an option could be serialize my Object into Json and calculate the digest on it, but this strategy has two drawbacks:
my code would repeat what Spring will do when the request is actually sent
there's no guarantee that the acutal bytes sent by Spring as a request are equal to what I've passed to the digest function
I suppose that I should use some low level API of Netty, but I can't find any example.
I implemented the solution proposed by #rewolf and it worked, but I encountered an issue because of the multi-threading nature of WebFlux.
In fact, it's possible that the client request is saved into the thread-local map by one thread, but a different thread tries to get it, so a null value is returned.
For example, it happens if the request to be signed is created inside a Rest controller method which has a Mono as a request body parameter:
#PostMapping
public String execute(#RequestBody Mono<MyBody> body){
Mono<OtherBody> otherBody = body.map(this::transformBodyIntoOtherBody);
...
webClient.post()
.body(otherBody)
.exchange();
...
}
According to Reactor specs, the Reactor Context should be used instead of Thread Local.
I forked #rewolf project and implemented a solution based on Reactor Context: https://github.com/taxone/blog-hmac-auth-webclient
This is not currently easy to do with WebClient. But there are ways to do so by intercepting the body post-serialization. This can be done by registering a custom encoder that intercepts the data after encoding, and the passes it to a custom HttpConnector to inject it as a header.
This blog post explains one way to achieve it: https://andrew-flower.com/blog/Custom-HMAC-Auth-with-Spring-WebClient
Edit: Currently this blog post doesn't take into account concurrent requests. See the accepted answer by Claodio for the modified approach.
The new WSO2 API MicroGateway 3.0 states as new feature Support for composing multiple microservices.I cannot find an example of how to do that.
We are trying a use case with just this type of processing:
An API that queries a back-end database using OData and if not found queries another (non OData) API.
In both cases the result must be transformed (reformatted).
Idea of composing microservices, is to expose set of microservices as a single API using microgateway. Basically you can define define set of REST resources and then point them to different microservices. For ex:
/list . -> micro service1
/add -> micro service2.
You can define per resource back ends using swagger (open API) extensions as below
https://github.com/wso2/product-microgateway/blob/master/samples/per_resource_endpoint.yaml
As of now microgateway does not have out of the box capability to call subsequent endpoints based on the response from the previous endpoint.
But you can transform the response using the response interceptors as explained below link
https://docs.wso2.com/display/MG300/Adding+Interceptors
I'm wondering whether sleuth has reactive WebClient instrumentation supported.
I did't find it from the document:
Instruments common ingress and egress points from Spring applications (servlet filter, async endpoints, rest template, scheduled actions, message channels, Zuul filters, and Feign client).
My case:
I may use WebClient in either a WebFilter or my rest resource to produce Mono.
And I want:
A sub span auto created as child of root span
trace info propagated via headers
If the instrumentation is not supported at the moment, Am I supposed to manually get the span from context and do it by myself like this:
OpenTracing instrumentation on reactive WebClient
Thanks
Leon
Even though this is an old question this would help others...
WebClient instrumentation will only work if new instance is created via Spring as a Bean. Check Spring Cloud Sleuth reference guide.
You have to register WebClient as a bean so that the tracing instrumentation gets applied. If you create a WebClient instance with a new keyword, the instrumentation does NOT work.
If you go to Sleuth's documentation for the Finchley release train, and you do find and you search for WebClient you'll find it - https://cloud.spring.io/spring-cloud-static/Finchley.RC2/single/spring-cloud.html#__literal_webclient_literal . In other words we do support it out of the box.
UPDATE:
New link - https://docs.spring.io/spring-cloud-sleuth/docs/current/reference/html/integrations.html#sleuth-http-client-webclient-integration
let me paste the contents
3.2.2. WebClient
This feature is available for all tracer implementations.
We inject a ExchangeFilterFunction implementation that creates a span
and, through on-success and on-error callbacks, takes care of closing
client-side spans.
To block this feature, set spring.sleuth.web.client.enabled to false.
You have to register WebClient as a bean so that the tracing
instrumentation gets applied. If you create a WebClient instance with
a new keyword, the instrumentation does NOT work.