On Quarkus I try to build a reactive microprofile REST client with a dynamic baseUrl, but so far in all implementation variants the REST call blocks after subscription. Interestingly the non-reactive implementation works like a charm. Let's see some code...
The REST client interface:
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();
}
The Quarkus-Test:
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);
}
}
When running the 4 tests only testRetrieve2, which uses the non-reactive API, is successful. All others hang in AssertSubscriber.await().
Any ideas?
question from:
https://stackoverflow.com/questions/66059664/reactive-microprofile-rest-client-blocks-on-quarkus 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…