I'm new to reactive programming and WebClient. I would like to repeatedly call an API until I get a specific value from the API (the API I am calling is a regular API that's configured for event streaming). Once I get the desired value, I would take an action.
I attempted to solve this with Flux interval, but haven't had much luck. I'm not sure if there is something wrong with my code, or if I am taking the wrong approach.
public Flux<TransactionStatus> watchAndTransact(Duration intervalDuration, Duration watchDuration,
String toAddress, String fromAddress) {
return Flux.interval(intervalDuration)
.take(watchDuration)
.flatMap(aFloat -> getBalance(fromAddress))
//.retryWhen(getBalance(fromAddress).block() < 0)
.flatMap(balance -> {
log.info("Checking balance {}", Instant.now());
//If we find that an amount was deposited into the deposit account
if (balance > 0) {
log.info("Balance Present {}", balance.toString());
//Build a transaction
Transaction transaction = new Transaction(fromAddress, toAddress, balance);
//Post the transaction
return postTransactionService.postTransaction(transaction);
}
return Mono.empty();
}).switchIfEmpty(s -> s.onError(new RuntimeException()));
}
I am getting the balance from the API using the code below:
public Mono<AddressInfo> getAddressInfo(String address) {
log.info("Pulling information on the address {}", address);
return webConfig.api
.get()
.uri("/addresses/{address}", address)
.retrieve()
.onStatus(HttpStatus::is4xxClientError,
error -> Mono.error(new NotFoundResourceException("Couldn't find a record")))
.onStatus(HttpStatus::is5xxServerError,
error -> Mono.error(new BadRequestException("Server isn't responding")))
.bodyToMono(AddressInfo.class)
.onErrorReturn(new AddressInfo(0f, EMPTY_LIST));
}
public Mono<Float> getBalance(String address) {
return getAddressInfo(address).map(AddressInfo::getBalance);
}
This is how I setup my webclient:
@Bean
@LoadBalanced
public WebClient.Builder loadBalancedWebClientBuilder() {
return WebClient.builder();
}
public WebClient dbClient = loadBalancedWebClientBuilder()
.baseUrl(gatewayUrl+"/api/v2/data")
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.build();
public WebClient apiClient = loadBalancedWebClientBuilder()
.baseUrl(url)
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.build();
How Can I call a regular API repeatedly using Spring Boot Reactive?