I am running same API multiple times for a List in parallel to save time. I have input List of ProductIds and API returns an Output ProductResponse with successFlag and TransactionId.
1 I am trying to run them all, the other API calls should continue even if one fails.
2 And then collect all ProductId Number Requests which fail. How would I collect the original request list that failed? Trying to modify code below.
public runAllAPIs() {
List<Integer> productIds = Arrays.asList(2,5,7);
List<CompletableFuture<ProductResponse>> productFutures =
productIds.stream()
.map(productIdItems -> createProduct(productId)
.collect(Collectors.toList());
List<ProductResponse> productResponses =
productFutures.stream()
.map(CompletableFuture::join)
.collect(Collectors.toList());
// how to print which productIds requests failed here
}
private CompletableFuture<ProductResponse> createProduct(int productId){
return CompletableFuture.supplyAsync(() -> productAPI.createProduct(productId);
}
@Data
public class ProductResponse {
private boolean isSuccessAPI;
private int transactionId;
}
Note: the Response Object does not contain ProductId in request.
CodePudding user response:
@Test
public void test() {
List<Integer> productIds = Arrays.asList(2, 5, 7);
List<CompletableFuture<MyCustomProductResponse>> productFutures =
productIds.stream()
.map(productId -> createProduct(productId))
.collect(Collectors.toList());
List<MyCustomProductResponse> productResponses =
productFutures.stream()
.map(CompletableFuture::join)
.collect(Collectors.toList());
// how to print which productIds requests failed here
productResponses.forEach(pr -> {
if (!pr.apiResponse.isSuccessAPI) {
System.out.println(pr.productId);
}
});
}
private CompletableFuture<MyCustomProductResponse> createProduct(int productId) {
return CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(1000);
// This is what you get from API
ProductResponseFromAPI apiResponse = new ProductResponseFromAPI(new Random().nextBoolean(), new Random().nextInt());
//You wrap that in your own object
return new MyCustomProductResponse(productId, apiResponse);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
});
}
@Value
static class ProductResponseFromAPI {
private boolean isSuccessAPI;
private int productTransactionId;
}
@Value
static class MyCustomProductResponse {
private int productId;
private ProductResponseFromAPI apiResponse;
}