Spring ResponseEntity - how to return HTTP 100 Continue - spring

Having rest services using Spring-boot 1.5.8.RELEASE some of the services may take time to process.
My idea is to use HTTP 100 Continue so the response will not time out and then return the final response.
I haven't find any way how to do that
Thanks for any hint

Related

Calling Multiple apis synchronously, spring boot webflux

In my project we are using spring boot webflux, and I have this scenario where i have to call multiple api's from within a particular microservice synchronously.
e.g.
for(String api:apiNames){
//call api's
}
As per my understanding, webClient works asynchronously, until and unless someone subscribe to it it wont release the response.
in my current scenario i have to make use of webclient and I have to call each api only after successfull execution of previous api.
Note:- api response can be anything success/failure
Please help me in implementing this synchronous call
You can use the #block() method to make it synchronous.
Example on a mono (https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Mono.html#block--)
For example on the (asynchronous) webflux webclient:
return webClient.get()
.uri(uri)
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.bodyToMono(String.class)
.block();
The above example will wait with executing any next line of code untill it has received a response.
After which you can just make another call to another api in the same way.
Edit: As pointed out in the comments I would like to add a warning that using #block() is not efficient and you should try and chain more reactive calls and try to avoid making your application non reactive.
A nice post with more details can be found here: https://stackoverflow.com/a/57365926/1326867
Although, the question uses the word "synchronously", the description rather seems to suggest that sequentiality is what is needed, meaning executing each request one after the other.
If that's the requirement, it can be implemented the following way with Reactor:
Flux.fromIterable(apiNames)
.concatMap(apiName -> webClient...) // concatMap ensures sequential execution
However, if the application is a blocking Spring application, then Nick Hol's answer is also a correct one.

How to make Spring Boot REST controller asynchronous?

My application is simple 3-tier Spring Boot rest web-service with usual synchronous endpoints.
But since the period of getting response from downstream system where my service sends requests is quite long (kind of 60 seconds), I need to add support of asynchronous REST calls to my service to save upstream systems from a response awaiting. In other words, if a response to a downstream system is going to take more than 60 seconds (timeout), then the upstream system break the connection with my service and keeps its doing...
But when the response come, my service using "reply-to" header from the upstream system will send the response to the upstream system.
All the things above are kind of call back or webhook.
But I didn't find any examples of implementation.
How to implement this mechanism?
How can I find more information?
Does Spring Boot have something to implement it out-of-box?
Thank you for attention!
You can use the #Async annotation from Spring. You will also need to enable in your application this by setting #EnableAsync.
An important note is that your method with the #Async annotation should be on a different class from where it is being called. This will let the Spring proxy intercept the call and effectively do it asynchronous.
Please find here the official tutorial.

How to produce and consume a RabbitMQ message with inside Spring RestController and send it back to the user

Hello Anyone and Everyone. I am working on a Spring Boot application. Here is my problem. I have a Spring RestController with a post-mapping that takes in some data. I am then needing to send that data over RabbitMQ to another application which in return will perform some calculations on that data and then send it back to me which I then want to return back to the user.
I know that RabbitMQ is for async communication. But I need my controller to return the result that comes back from RabbitMQ all in one go. Right now I am using.
#EnableBinding(Sink::class)
class OptimizedScheduleMessageListener {
#StreamListener(Sink.INPUT)
fun handler(incomingMessage: MyDTO) {
println(incomingMessage)
}
}
to retrieve the results from RabbitMQ. Now I just need my Controller to return it.
#PostMapping( produces = ["application/json"])
fun retrieveOptimizedSchedule: Result<MyDTO> {
myUncalculatedDTO: MyDTO()
source.output().send(MessageBuilder.withPayload(myUncalculadeDTO).build())
return ???
}
Any help with this endeavor is much appreciated.
Thanks in Advance.
Spring Cloud Stream is not designed for request/reply processing.
See the Spring AMQP (Spring for RabbitMQ) project.
The RabbitTemplate has sendAndReceive and convertSendAndReceive methods to implement the RPC model.
On the server side, a #RabbitListener method can be used for request/reply.
What you are trying to do is not advised for couple of reasons.
1. The failure of the 'Another application' which consumes the Rabbit
MQ messages will result in Requests being blocked on the controller end.
2. There is a limit on how many requests you can have simultaneously from the server to clients.
What you can do is use any other communication protocol than REST for this specific part. May be Websocket will be an ideal solution. If not you need to have two REST endpoints. One to submit and get back an request-id, another to poll periodically with the request-id and get processed, completed response.

How to consume a Reactive Spring Rest API with WebClient

I need to consume a reactive rest API (built with spring webflux) on a backend job (executable jar).
I've read about Spring WebClient, but I am not understanding some points.
For instance:
WebClient webClient = WebClient.create("http://localhost:8080");
Mono<Person> person = webClient.get()
.uri("/persons/{id}", 42)
.accept(MediaType.APPLICATION_JSON)
.exchange()
.then(response -> response.bodyToMono(Person.class));
On the last line, there is a "bodyToMono". So that's my question:
If the Rest API being called is already a reactive service, do I need to transform the response to a mono? Is there some point I'm missing?
From my perspective, I think could have a way to let explicit in the code that my Rest API is reactive, but probably is something I am not aware about.
Yes it is required.
The whole idea of being reactive is to make sure none of the Thread are blocked for IO.
You may have made your server side service reactive, but when your consuming that what is the benefit you get when your client is blocked untill there is a response from server. Your client thread keeps waiting untill the server responds. Which is not desired.
webClient.get()
.uri("/persons/{id}", 42)
.accept(MediaType.APPLICATION_JSON)
.exchange().block()
will block your current client thread to wait till the server responds. This can block your client thread.
webClient.get()
.uri("/persons/{id}", 42)
.accept(MediaType.APPLICATION_JSON)
.exchange()
.then(response -> response.bodyToMono(Person.class));
Gives you a Mono which is a reference to a publisher that can emit a single value in future. So the client thread is non blocked.
I have blogged explaining this more.
https://dzone.com/articles/spring-5-reactive-web-services

spring actuator increases the metric counter.status.200.{my endpoint} even if the endpoint returns a 500

I've developed my first rest service with Spring Boot, Spring MVC Spring Actuator using embedded tomcat 8.
For some reason, when the endpoint fails due to an exception which is not caught, the returned response from the endpoint has the status 500, but the metric of counter.status.200. was increased.
I debug a bit the code and looks like the status of the response in the class ResponseFacade (from tomcat) is set after the metric is increased on the MetricFilterAutoConfiguration.MetricsFilter.
Does someone has an idea how can I get the right status code counter (counter.status.500.{my endpoint}) increased?
Thanks in advance

Resources