Skip to content

Commit

Permalink
Properly determine return type in RESTEasy Reactive methods
Browse files Browse the repository at this point in the history
This is done in order to support complex return types like
`Uni<RestResponse<AsyncFile>>`

Fixes: #23489
  • Loading branch information
geoand committed Feb 8, 2022
1 parent b4f7fc0 commit d8a0ca2
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import org.jboss.resteasy.reactive.FilePart;
import org.jboss.resteasy.reactive.PathPart;
import org.jboss.resteasy.reactive.RestResponse;

import io.smallrye.mutiny.Uni;
import io.vertx.core.file.AsyncFile;
Expand Down Expand Up @@ -56,6 +57,19 @@ public Uni<AsyncFile> getAsyncFile(RoutingContext vertxRequest) {
});
}

@Path("rest-response-async-file")
@GET
public Uni<RestResponse<AsyncFile>> getRestResponseAsyncFile(RoutingContext vertxRequest) {
return Uni.createFrom().emitter(emitter -> {
vertxRequest.vertx().fileSystem().open(FILE, new OpenOptions(), result -> {
if (result.succeeded())
emitter.complete(RestResponse.ResponseBuilder.ok(result.result()).header("foo", "bar").build());
else
emitter.fail(result.cause());
});
});
}

@Path("mutiny-async-file")
@GET
public Uni<io.vertx.mutiny.core.file.AsyncFile> getMutinyAsyncFile(RoutingContext vertxRequest) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@ public void testFiles() throws Exception {
.header(HttpHeaders.CONTENT_LENGTH, Matchers.nullValue())
.statusCode(200)
.body(Matchers.equalTo(content));
RestAssured.get("/providers/file/rest-response-async-file")
.then()
.header("foo", "bar")
.statusCode(200)
.body(Matchers.equalTo(content));
RestAssured.get("/providers/file/mutiny-async-file")
.then()
.header(HttpHeaders.CONTENT_LENGTH, Matchers.nullValue())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ public RuntimeResource buildResourceMethod(ResourceClass clazz,
}

Type returnType = TypeSignatureParser.parse(method.getReturnType());
Type nonAsyncReturnType = getNonAsyncReturnType(returnType);
Type nonAsyncReturnType = getEffectiveReturnType(returnType);
Class<?> rawNonAsyncReturnType = getRawType(nonAsyncReturnType);

ServerMediaType serverMediaType = null;
Expand Down Expand Up @@ -626,23 +626,22 @@ private Class<?> getRawType(Type type) {
throw new UnsupportedOperationException("Endpoint return type not supported yet: " + type);
}

private Type getNonAsyncReturnType(Type returnType) {
private Type getEffectiveReturnType(Type returnType) {
if (returnType instanceof Class)
return returnType;
if (returnType instanceof ParameterizedType) {
// NOTE: same code in EndpointIndexer.getNonAsyncReturnType
ParameterizedType type = (ParameterizedType) returnType;
if (type.getRawType() == CompletionStage.class) {
return type.getActualTypeArguments()[0];
return getEffectiveReturnType(type.getActualTypeArguments()[0]);
}
if (type.getRawType() == Uni.class) {
return type.getActualTypeArguments()[0];
return getEffectiveReturnType(type.getActualTypeArguments()[0]);
}
if (type.getRawType() == Multi.class) {
return type.getActualTypeArguments()[0];
return getEffectiveReturnType(type.getActualTypeArguments()[0]);
}
if (type.getRawType() == RestResponse.class) {
return type.getActualTypeArguments()[0];
return getEffectiveReturnType(type.getActualTypeArguments()[0]);
}
return returnType;
}
Expand Down

0 comments on commit d8a0ca2

Please sign in to comment.