Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CompletableFuture - Run multiple rest calls in parallel and get different result

I have a rather common or unique requirement. For example, I have the following AccountDetails list:

List<AccountDetails>

class AccountDetails {
    String bankAccountId;
    String mortgageAccountId;
    Integer noOfTrans;
    String addressLine;
    String externalLink;   
}

All the above fields, except bankAccountId are pulled from external REST service call. I want to call all the REST services in parallel and update each object in the list:

So, it looks like below:

For each accountDetails

  • Call mortgage REST service and update martgageAccountIdfield (REST returns MortgageInfo object)
  • Call transaction REST service and update noOfTrans field (REST returns Transactions object)
  • Call address REST service and update addressLine field (REST returns Address object)
  • Call link REST service and update externalLink field. (REST returns Links object)

I want all the above calls in parallel, and for each AcccountDetails object in the list. If there is an exception, I want do gracefully handle it. Note that each of the above REST service returns different custom object

I am confused about how to achieve this with CompletableFuture chaining. Not sure allOf or thenCombine (which only takes two), or thenCompose should use and how to put all of these together.

Any examples/ideas?

like image 580
Kevin Rave Avatar asked Dec 13 '22 08:12

Kevin Rave


1 Answers

AccountDetails accountDetails = new AccountDetails();

CompletableFuture.allOf(
                        CompletableFuture.
                                supplyAsync(() -> //CALL MORTAGE INFO REST, executor).
                                thenAccept(x -> {
                                    accountDetails.setMortgageAccountId(x.getReqdField())
                                }).
                                handle(//HANDLE GRACEFULLY),
                        CompletableFuture.
                                supplyAsync(() -> //CALL SOME OTHER REST, executor).
                                thenAccept(x -> {
                                    accountDetails.setNoOfTrans(x.getReqdField())
                                }).
                                handle(//HANDLE GRACEFULLY),
                        CompletableFuture.
                                supplyAsync(() -> //CALL SOME INFO REST, executor).
                                thenAccept(x -> {
                                    accountDetails.setAddressLine(x.getReqdField())
                                }).
                                handle(//HANDLE GRACEFULLY),
                        CompletableFuture.
                                supplyAsync(() -> //CALL SOME OTHER REST, executor).
                                thenAccept(x -> {
                                    accountDetails.setExternalLink(x.getReqdField())
                                }).
                                handle(//HANDLE GRACEFULLY),
                ).join();
like image 190
The-Proton-Resurgence Avatar answered May 18 '23 13:05

The-Proton-Resurgence