I have a piece of code completely reactive, i check in database if value exists, if not i call a third api.
The problem i go in switchIfEmpty and then i throw the exception because the data is found in mongo DB, something is going wrong but i dont understand why, any idea?
@Log4j2
@AllArgsConstructor
public class GetTokenizationInformation {
private final ConfigProperties properties;
private final NetworkTokenTmsAdapter service;
private final TokenRepositoryAdapter repository;
public Mono<NetworkTokenInformationResponse> execute(@NonNull Mono<CardRequest> card) {
log.info("Network token creation process starting");
return card.flatMap(c -> {
var hashedPan = Token.hashPan(c.getNumber(), properties.getHashing().getSecretKey());
return repository.findByHashedPan(hashedPan.trim())
.flatMap(_ -> {
log.info("Token already existing for hashed pan {}, throwing exception", hashedPan);
return Mono.<NetworkTokenInformationResponse>error(new TokenizationServiceAlreadyExistsException("Token already existing for hashed pan"));
})
.switchIfEmpty(
service.createToken(Card.builder()
.expirationYear(String.valueOf(c.getExpirationYear()))
.expirationMonth(Token.mapIntegerToString(c.getExpirationMonth()))
.securityCode(String.valueOf(c.getSecurityCode()))
.number(c.getNumber())
.build())
.flatMap(tmsInstrumentidentifier -> {
log.info("Token created, database saving in progress...");
var gatewayToken = ObjectId.get().toString();
var token = Token.builder()
.gatewayToken(gatewayToken)
.tmsInstrumentIdentifier(tmsInstrumentidentifier)
.hashedPan(hashedPan)
.build();
return repository.save(token)
.flatMap(savedToken -> Mono.just(savedToken.networkTokenInformationResponseExtracted()))
.doOnSuccess(_ -> log.info("Token saved in database"));
})
);
});
}
}
repository:
@Repository
public interface TokenRepositoryAdapter extends ReactiveCrudRepository<Token, String> {
Mono<Token> findByGatewayToken(String gatewayToken);
Mono<Token> findByHashedPan(String hashedPan);
@Query(value = "{ 'tmsInstrumentIdentifier.tokenizedCard.expirationYear' : ?0, 'tmsInstrumentIdentifier.tokenizedCard.expirationMonth' : { $lt: ?1 } }")
Flux<Token> findByTokenizedCardExpiredDate(int year, int month);
}
Why i am going in the switchIfEmpty, and then go back in the flatmap after findByHashedPan ?
PS: service.createToken is calling a webclient that go on paid service, but it should not as the token is found in database
what’s wrong ?