Spring Batch Itemwriter Rest API post call - spring

what are your thoughts on firing rest post calls as part of ItemWriter ? Also what is the best approach to track failures so that when we restart it picks only those failures/start from where it left off in the previous run

Related

How can i return response before job is'nt done in spring

I would make a simple restful api in spring boot.
This api trigger a hard job that takes about 20 min.
Request is performed by another spring boot project.
And request's wanted is only to trigger, not return data.
I can't wait end of this job. So I have to separated api call and 20 minute job.
I think that async is not way...
How can i do this?
Only way is to use a message broker?

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.

Quarkus Reactive SQL clients how to make sure my api is reactive

I have a question, I am just starting on reactive programing and I am using quarkus. I made a demo with Panache hibernate reactive and one with SQL clients.
I want each of my rest apis to run on a different non blocking thread. With panache hibernate whenever I did a a blocking action I got a message about it and in the logs it showed me that the api was running o vertex event loop thread so everything was fine.
In Reactive clients everything runs on executor thread 0 does that mean my apis aren’t asynchonus(reactive) from input to output and when I run a blocking action non erros is showing.
Quarkus tries in a lot of places to put the proper guard-rails when it comes to the threads that can be used - however it can't catch all mistakes.
If you are seeing your code executed on a thread that has executor in the name, then the request is being serviced by the wrong thread pool.
If you are using quarkus-resteasy for example, this is the only way that RESTEasy can handle requests - it doesn't matter what your code is, the request is always handled on an executor thread.
For this reason, Quarkus provides RESTEasy Reactive (which is the prefered REST API layer) which allows you to choose whether you want a request to be serviced on an executor thread or an event-loop thread.
See this for more details.

Best approach to run a Spring Batch job

I have a requirement where I have to call a spring batch job from a rest endpoint. We are using an API which has all the boilerplate code for running a job and it also adds an endpoint to our service and upon calling that endpoint it will run the requested job. I have attached a snip of that endpoint.
Please suggest a best approach to run the job from another rest endpoint within the same service should I call /Jobs endpoint or should I implement the logic of running the required job? TIA.
There is no best approaches, it depends on the use case. I would not make REST endpoints call each others, I think it would be simpler to inject the JobLauncher in your controller and call your job accordingly. You can find more details and a code example in the reference documentation here: Running Jobs from within a Web Container.

Transaction management of JPA and external API calls

I'm new to spring, started using spring boot for the project. We have an use case of implementing database changes and few external API calls as one transaction. Please suggest, is this possible with the spring #transactional?
Do the API calls need to be part of the transaction?
If the answer is no, I would advise to use TransactionTemplate.doInTransaction() leaving the API requests outside of the Tx.
If you need to make the API requests inside a Tx, I would advise against it, you would be locking DB resources for the duration of those requests.
You can also search and find out more about the eventual consistency model.
Using #Transactional for multiple database changes as one transaction is of course doable with the annotation but not so much for the external API calls. You would have to implement some custom logic for that - there would have to be endpoints to undo your last actions and you would have to implement calling them manually in try-catch block for example. For example, if the external API call creates an item there would also have to be an endpoint to delete an item and so on.
So to summarise - using #Transactional annotation for implementing database changes as one transaction is fine, but not enough for external API calls.

Resources