Skip to content

Commit

Permalink
Merge pull request quarkusio#1260 from kenfinnigan/rest-fix
Browse files Browse the repository at this point in the history
Register return types on REST Interface methods for reflection
  • Loading branch information
stuartwdouglas authored Mar 6, 2019
2 parents 32f14a7 + 9335b90 commit f9673b4
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@

import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import javax.ws.rs.client.ClientRequestFilter;
import javax.ws.rs.client.ClientResponseFilter;
Expand All @@ -32,6 +34,8 @@
import org.jboss.jandex.AnnotationTarget;
import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.DotName;
import org.jboss.jandex.MethodInfo;
import org.jboss.jandex.Type;
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
import org.jboss.resteasy.client.jaxrs.internal.proxy.ProxyBuilderImpl;
import org.jboss.resteasy.client.jaxrs.internal.proxy.ResteasyClientProxy;
Expand All @@ -52,6 +56,7 @@
import io.quarkus.deployment.builditem.FeatureBuildItem;
import io.quarkus.deployment.builditem.SslNativeConfigBuildItem;
import io.quarkus.deployment.builditem.substrate.ReflectiveClassBuildItem;
import io.quarkus.deployment.builditem.substrate.ReflectiveHierarchyBuildItem;
import io.quarkus.deployment.builditem.substrate.SubstrateProxyDefinitionBuildItem;
import io.quarkus.deployment.builditem.substrate.SubstrateResourceBuildItem;
import io.quarkus.deployment.util.ServiceUtil;
Expand Down Expand Up @@ -127,11 +132,13 @@ void processInterfaces(CombinedIndexBuildItem combinedIndexBuildItem,
SslNativeConfigBuildItem sslNativeConfig,
BuildProducer<SubstrateProxyDefinitionBuildItem> proxyDefinition,
BuildProducer<ReflectiveClassBuildItem> reflectiveClass,
BuildProducer<ReflectiveHierarchyBuildItem> reflectiveHierarchy,
BuildProducer<BeanRegistrarBuildItem> beanRegistrars,
BuildProducer<ExtensionSslNativeSupportBuildItem> extensionSslNativeSupport) {

// According to the spec only rest client interfaces annotated with RegisterRestClient are registered as beans
Map<DotName, ClassInfo> interfaces = new HashMap<>();
Set<Type> returnTypes = new HashSet<>();

for (AnnotationInstance annotation : combinedIndexBuildItem.getIndex().getAnnotations(REGISTER_REST_CLIENT)) {
AnnotationTarget target = annotation.target();
Expand All @@ -147,6 +154,16 @@ void processInterfaces(CombinedIndexBuildItem combinedIndexBuildItem,
continue;
}
interfaces.put(theInfo.name(), theInfo);

// Find Return types
for (MethodInfo method : theInfo.methods()) {
Type type = method.returnType();
if (!type.name().toString().contains("java.lang")) {
if (!returnTypes.contains(type)) {
returnTypes.add(type);
}
}
}
}

if (interfaces.isEmpty()) {
Expand All @@ -160,6 +177,11 @@ void processInterfaces(CombinedIndexBuildItem combinedIndexBuildItem,
reflectiveClass.produce(new ReflectiveClassBuildItem(true, false, iName));
}

// Register Interface return types for reflection
for (Type returnType : returnTypes) {
reflectiveHierarchy.produce(new ReflectiveHierarchyBuildItem(returnType));
}

beanRegistrars.produce(new BeanRegistrarBuildItem(new BeanRegistrar() {

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@
package io.quarkus.example.rest;

import java.net.URL;
import java.util.List;

import javax.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;

import org.eclipse.microprofile.rest.client.RestClientBuilder;
import org.eclipse.microprofile.rest.client.inject.RestClient;
Expand All @@ -47,4 +49,40 @@ public String cdi() throws Exception {
return restInterface.get();
}

@GET
@Path("manual/jackson")
@Produces("application/json")
public TestResource.MyData getDataManual() throws Exception {
RestInterface iface = RestClientBuilder.newBuilder()
.baseUrl(new URL(System.getProperty("test.url")))
.build(RestInterface.class);
System.out.println(iface.getData());
return iface.getData();
}

@GET
@Path("cdi/jackson")
@Produces("application/json")
public TestResource.MyData getDataCdi() {
return restInterface.getData();
}

@GET
@Path("/manual/complex")
@Produces("application/json")
public List<ComponentType> complexManual() throws Exception {
RestInterface iface = RestClientBuilder.newBuilder()
.baseUrl(new URL(System.getProperty("test.url")))
.build(RestInterface.class);
System.out.println(iface.complex());
return iface.complex();
}

@GET
@Path("/cdi/complex")
@Produces("application/json")
public List<ComponentType> complexCdi() {
return restInterface.complex();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,11 @@

package io.quarkus.example.rest;

import java.util.List;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;

import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;

Expand All @@ -27,4 +30,14 @@ public interface RestInterface {

@GET
String get();

@GET
@Path("/jackson")
@Produces("application/json")
TestResource.MyData getData();

@GET
@Path("/complex")
@Produces("application/json")
List<ComponentType> complex();
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,17 @@
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.is;

import java.util.List;
import java.util.Map;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;

import io.quarkus.example.rest.ComponentType;
import io.quarkus.test.junit.QuarkusTest;
import io.restassured.RestAssured;
import io.restassured.path.json.JsonPath;

@QuarkusTest
public class RestClientTestCase {
Expand All @@ -40,6 +46,38 @@ public void testMicroprofileClientCDIIntegration() {
.body(is("TEST"));
}

@Test
void testMicroprofileClientData() {
JsonPath jsonPath = RestAssured.when().get("/client/manual/jackson").thenReturn().jsonPath();
Assertions.assertEquals(jsonPath.getString("name"), "Stuart");
Assertions.assertEquals(jsonPath.getString("value"), "A Value");
}

@Test
void testMicroprofileClientDataCdi() {
JsonPath jsonPath = RestAssured.when().get("/client/cdi/jackson").thenReturn().jsonPath();
Assertions.assertEquals(jsonPath.getString("name"), "Stuart");
Assertions.assertEquals(jsonPath.getString("value"), "A Value");
}

@Test
void testMicroprofileClientComplex() {
JsonPath jsonPath = RestAssured.when().get("/client/manual/complex").thenReturn().jsonPath();
List<Map<String, String>> components = jsonPath.getList("$");
Assertions.assertEquals(components.size(), 1);
Map<String, String> map = components.get(0);
Assertions.assertEquals(map.get("value"), "component value");
}

@Test
void testMicroprofileClientComplexCdi() {
JsonPath jsonPath = RestAssured.when().get("/client/cdi/complex").thenReturn().jsonPath();
List<Map<String, String>> components = jsonPath.getList("$");
Assertions.assertEquals(components.size(), 1);
Map<String, String> map = components.get(0);
Assertions.assertEquals(map.get("value"), "component value");
}

/**
* Disabled by default as it establishes external connections.
* <p>
Expand Down

0 comments on commit f9673b4

Please sign in to comment.