【问题标题】:Joining unis in Quarkus/Mutiny/Hibernate-Reactive在 Quarkus/Mutiny/Hibernate-Reactive 中加入 unis
【发布时间】:2022-06-22 00:56:20
【问题描述】:

我对以下 quarkus/hibernate-reactive/mutiny 有一个非常令人困惑的问题。我将首先描述我在 Quarkus 中使用 hibernate-reactive 和 mutiny 实现的功能。

一个。任务是从数据库中检索一条记录,

  Uni<MyRecord> getAuthenticationRecord(String id);

b.然后使用对象中的 refresh_token 字段并构建一个请求对象并将其传递给返回 CallableFuture 的第三方 API。

  CompletableFuture<TokenResponse> refreshToken(final TokenRequest tokenRequest);

最后从tokenRequest中检索值并更新在步骤a中检索到的记录。

我尝试了以下方法:

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();
      }
    );
  }
}

在测试用例中使用它:

@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();

}

有什么建议吗?

【问题讨论】:

  • 您遇到了什么问题?
  • 所以,再看一遍。问题是您的应用程序代码不在事务上运行,而且您还从非 i/o 线程调用它。我建议将您的方法暴露在使用 @ReactiveTransactional 注释的 RESTEasy REactive 端点后面,并让您的测试直接调用端点。
  • 感谢您的回复。首先,我看到的问题是第三方 Future 从未被调用过。现在至于@ReactiveTransactional,我想我会尝试这种方法。目前我正在单独测试业务逻辑方面,因此我面临的问题

标签: java hibernate quarkus mutiny hibernate-reactive


【解决方案1】:

authRecord 和 refreshToke 区域已经一个接一个地链接起来。我认为您不需要 combine.all:

class MyApi {
  public Uni<AuthRecord> refreshToken(String owner) {
    return getAuthenticationRecord(owner)
              .chain(authRecord -> authRecord
                  .map(MyRecord::refreshToken)
                  .chain(refreshToken -> {
                      TokenRequest request = new TokenRequest(refreshToken); //create the request object
                      return Uni.createFrom().completionStage(refreshToken(request)); //convert the CallableFuture to Uni 
                  })
                  .chain( refreshToken -> {
                      record.setCode(refresh.getToken());
                      return record.persistAndFlush();
                  });
  }
}

你可以test reactive applications using quarkus-test-vertx:

  1. 添加quarkus-test-vertx 依赖:
    <dependency>
       <groupId>io.quarkus</groupId>
       <artifactId>quarkus-test-vertx</artifactId>
       <scope>test</scope>
    </dependency>
    
  2. 现在您可以访问UniAsserter
    @Inject
    MyApi api;
    
    @Test 
    @TestReactiveTransaction
    public void test1(UniAsserter asserter) {
     asserter.assertThat(
         () -> api.refreshToken("owner"),
         result -> Asserttions.assertThat(result).isNotNull();
     ); 
    }
    

【讨论】:

    猜你喜欢
    • 2021-09-12
    • 2022-12-01
    • 2021-12-17
    • 1970-01-01
    • 2022-12-20
    • 1970-01-01
    • 2022-06-14
    • 2021-07-31
    • 2021-12-18
    相关资源
    最近更新 更多