Java Quarkus上的文件REST客户端块

Java Quarkus上的文件REST客户端块,java,quarkus,microprofile,mutiny,Java,Quarkus,Microprofile,Mutiny,在Quarkus上,我尝试使用动态baseUrl构建一个反应式文件REST客户端,但到目前为止,在所有实现变体中,REST调用在订阅后被阻塞。有趣的是,非反应性的实现工作起来很有魅力。让我们看看一些代码 REST客户端接口: package ...; import io.smallrye.mutiny.Uni; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax

在Quarkus上,我尝试使用动态baseUrl构建一个反应式文件REST客户端,但到目前为止,在所有实现变体中,REST调用在订阅后被阻塞。有趣的是,非反应性的实现工作起来很有魅力。让我们看看一些代码

REST客户端接口:

package ...;

import io.smallrye.mutiny.Uni;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;
import java.io.InputStream;
import java.util.concurrent.CompletionStage;

import static javax.ws.rs.core.MediaType.APPLICATION_OCTET_STREAM;

@Path("")
public interface RetrievalRestApi {

  @GET
  @Produces(APPLICATION_OCTET_STREAM)
  Uni<InputStream> retrieve();

  @GET
  @Produces(APPLICATION_OCTET_STREAM)
  InputStream retrieve2(); // non-reactive, the only one that works...

  @GET
  @Produces(APPLICATION_OCTET_STREAM)
  Uni<Response> retrieve3();

  @GET
  @Produces(APPLICATION_OCTET_STREAM)
  CompletionStage<InputStream> retrieve4();
}

包。。。;
输入io.smallrye.mutiny.Uni;
导入javax.ws.rs.GET;
导入javax.ws.rs.Path;
导入javax.ws.rs.PathParam;
导入javax.ws.rs.products;
导入javax.ws.rs.core.Response;
导入java.io.InputStream;
导入java.util.concurrent.CompletionStage;
导入静态javax.ws.rs.core.MediaType.APPLICATION\u OCTET\u流;
@路径(“”)
公共接口检索{
@得到
@生成(应用程序\u八位字节\u流)
Uni检索();
@得到
@生成(应用程序\u八位字节\u流)
InputStream retrieve2();//非反应性,唯一有效的。。。
@得到
@生成(应用程序\u八位字节\u流)
uniretrieve3();
@得到
@生成(应用程序\u八位字节\u流)
CompletionStage retrieve4();
}
Quarkus测试:

package ...;

import io.quarkus.test.junit.QuarkusTest;
import io.smallrye.mutiny.Uni;
import org.apache.commons.io.IOUtils;
import org.eclipse.microprofile.rest.client.RestClientBuilder;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import javax.inject.Inject;
import javax.ws.rs.core.Response;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.function.Consumer;

import static org.junit.jupiter.api.Assertions.assertNotNull;

@QuarkusTest
class RetrievalRestApiTest {
  private URL restUrl;

  @BeforeEach
  void setUp() throws MalformedURLException {
    restUrl = new URL("https://some-valid-url");
  }

  @Test
  void testRetrieve() {
    Uni<InputStream> uni = RestClientBuilder.newBuilder()
                                            .baseUrl(restUrl)
                                            .build(RetrievalRestApi.class)
                                            .retrieve()
                                            .onFailure().invoke((Consumer<Throwable>) System.out::println);
    InputStream inputStream = uni.subscribe()
                                 .withSubscriber(UniAssertSubscriber.create())
                                 .await()
                                 .assertCompleted()
                                 .getItem();
    assertNotNull(inputStream);
  }

  @Test
  void testRetrieve2() throws IOException {
    InputStream inputStream = RestClientBuilder.newBuilder()
                                               .baseUrl(restUrl)
                                               .build(RetrievalRestApi.class)
                                               .retrieve2();
    assertNotNull(inputStream);
    String content = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
    assertNotNull(content);
  }

  @Test
  void testRetrieve3() {
    Uni<Response> uni = RestClientBuilder.newBuilder()
                                         .baseUrl(restUrl)
                                         .build(RetrievalRestApi.class)
                                         .retrieve3()
                                         .onFailure().invoke((Consumer<Throwable>) System.out::println);
    Response response = uni.subscribe()
                                 .withSubscriber(UniAssertSubscriber.create())
                                 .await()
                                 .assertCompleted()
                                 .getItem();
    assertNotNull(response);
  }

  @Test
  void testRetrieve4() {
    Uni<InputStream> uni = Uni.createFrom().completionStage(RestClientBuilder.newBuilder()
                                         .baseUrl(restUrl)
                                         .build(RetrievalRestApi.class)
                                         .retrieve4())
                                         .onFailure().invoke((Consumer<Throwable>) System.out::println);
    InputStream inputStream = uni.subscribe()
                                 .withSubscriber(UniAssertSubscriber.create())
                                 .await()
                                 .assertCompleted()
                                 .getItem();
    assertNotNull(inputStream);
  }
}

包。。。;
导入io.quarkus.test.junit.QuarkusTest;
输入io.smallrye.mutiny.Uni;
导入org.apache.commons.io.IOUtils;
导入org.eclipse.microfile.rest.client.RestClientBuilder;
导入org.junit.jupiter.api.beforeach;
导入org.junit.jupiter.api.Test;
导入javax.inject.inject;
导入javax.ws.rs.core.Response;
导入java.io.IOException;
导入java.io.InputStream;
导入java.net.MalformedURLException;
导入java.net.URL;
导入java.nio.charset.StandardCharset;
导入java.util.List;
导入java.util.function.Consumer;
导入静态org.junit.jupiter.api.Assertions.assertNotNull;
@夸克斯特
类检索restapitest{
私有URL restUrl;
@之前
void setUp()引发错误的DurException{
restUrl=新URL(“https://some-valid-url");
}
@试验
void testRetrieve(){
Uni Uni=RestClientBuilder.newBuilder()
.baseUrl(restUrl)
.build(RetrievalRestApi.class)
.retrieve()
.onFailure().invoke((使用者)System.out::println);
InputStream InputStream=uni.subscribe()
.withSubscriber(UniAssertSubscriber.create())
.等待
.assertCompleted()
.getItem();
assertNotNull(inputStream);
}
@试验
void testRetrieve2()引发IOException{
InputStream InputStream=RestClientBuilder.newBuilder()
.baseUrl(restUrl)
.build(RetrievalRestApi.class)
.retrieve2();
assertNotNull(inputStream);
字符串内容=IOUtils.toString(inputStream,StandardCharsets.UTF_8);
assertNotNull(内容);
}
@试验
void testRetrieve3(){
Uni Uni=RestClientBuilder.newBuilder()
.baseUrl(restUrl)
.build(RetrievalRestApi.class)
.retrieve3()
.onFailure().invoke((使用者)System.out::println);
Response-Response=uni.subscribe()
.withSubscriber(UniAssertSubscriber.create())
.等待
.assertCompleted()
.getItem();
assertNotNull(响应);
}
@试验
void testRetrieve4(){
Uni Uni=Uni.createFrom().completionStage(RestClientBuilder.newBuilder())
.baseUrl(restUrl)
.build(RetrievalRestApi.class)
.retrieve4())
.onFailure().invoke((使用者)System.out::println);
InputStream InputStream=uni.subscribe()
.withSubscriber(UniAssertSubscriber.create())
.等待
.assertCompleted()
.getItem();
assertNotNull(inputStream);
}
}
运行4个测试时,只有使用非反应性API的testRetrieve2成功。所有其他文件都挂在AssertSubscriber.await()中


有什么想法吗?

这个问题确实与我有关。将Quarkus升级到1.12.0.Final后,该问题消失。

该问题似乎与Quarkus Jaeger跟踪有关。只要我使用
quarkus.jaeger.enabled=false禁用跟踪,就不再有阻塞。可能与有关,因为我看到几乎相同的堆栈跟踪(差异可能是由于不同的Quarkus版本)。