'Joining unis in Quarkus/Mutiny/Hibernate-Reactive

I am having a very confusing issue with the following quarkus/hibernate-reactive/mutiny. I'll start by describing the feature I'm implementing in Quarkus using hibernate-reactive and mutiny.

a. The task is to retrieve a record from the database,

  Uni<MyRecord> getAuthenticationRecord(String id);

b. then use the refresh_token field in the object and build a request object and pass it to a third party API that returns a CallableFuture.

  CompletableFuture<TokenResponse> refreshToken(final TokenRequest tokenRequest);

and finally retieve the the values from tokenRequest and update the record retrieved in the Step a.

I have tried the following:

class MyApi {
  public Uni<AuthRecord> refreshToken(String owner) {

    MyRecord authRecord = getAuthenticationRecord(owner); //get the authentication record

    TokenResponse refreshToken = authRecord.onItem().transform(MyRecord::refreshToken)
    .chain(refreshToken -> {
        TokenRequest request = new TokenRequest(refreshToken); //create the request object
        return Uni.createFrom().completionStage(refreshToken(request)); //convert the CallableFuture to Uni 
    });


    //Join the unis and update the auth record
    return Uni.combine().all().unis(authRecord, refreshToken).asTuple().onItem().transform( 
      tuplle -> {
        var record = tuple.getItem1();
        var refresh = tuple.getItem2();

        record.setCode(refresh.getToken());
        return record.persistAndFlush();
      }
    );
  }
}

Using it in a test case:

@Inject
MyApi api;

@Test 
public void test1() {
  //This produces nothing
  api.refreshToken("owner").subscribe().with(
    item -> { 
      System.out.println(Json.encode(item));
    }
  )
}

@Test 
public void test2() {
  //This won't work because no transaction is active
  var record = api.refreshToken("owner").await().indefinitely();

}

@Test 
@ReactiveTransactional
public void test3() {
  //This won't work either because the thread is blocked @Blocking annotation didn't help either 
  var record = api.refreshToken("owner").await().indefinitely();

}

Any suggestions?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source