Skip to content

Commit e7c787e

Browse files
geoandgsmet
authored andcommitted
Properly support Optional as a header param for REST Client subresources
(cherry picked from commit 3ad6e97)
1 parent 6453bd0 commit e7c787e

File tree

2 files changed

+72
-10
lines changed

2 files changed

+72
-10
lines changed

extensions/resteasy-reactive/rest-client-jaxrs/deployment/src/main/java/io/quarkus/jaxrs/client/reactive/deployment/JaxrsClientReactiveProcessor.java

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1548,10 +1548,10 @@ private void handleSubResourceMethod(List<JaxrsClientReactiveEnricherBuildItem>
15481548
for (int i = 0; i < method.getParameters().length; i++) {
15491549
MethodParameter param = method.getParameters()[i];
15501550
if (param.parameterType != ParameterType.PATH) {
1551-
FieldDescriptor paramField = subContext.classCreator.getFieldCreator("param" + i, param.type)
1551+
FieldDescriptor paramField = subContext.classCreator.getFieldCreator("param" + i, param.declaredType)
15521552
.setModifiers(Modifier.PUBLIC)
15531553
.getFieldDescriptor();
1554-
subParamFields.add(new SubResourceParameter(method.getParameters()[i], param.type,
1554+
subParamFields.add(new SubResourceParameter(method.getParameters()[i], param.declaredType,
15551555
jandexMethod.parameterType(i), paramField, methodParamAnnotationsField,
15561556
methodGenericParametersField,
15571557
i));
@@ -1690,6 +1690,19 @@ private void handleSubResourceMethod(List<JaxrsClientReactiveEnricherBuildItem>
16901690
// just store the index of parameter used to create the body, we'll use it later
16911691
bodyParameterValue = paramValue;
16921692
} else if (param.parameterType == ParameterType.HEADER) {
1693+
Type paramType = jandexSubMethod.parameterType(subParamField.paramIndex);
1694+
String effectiveParamTypeStr = paramType.name().toString();
1695+
boolean isOptional = isOptional(paramType, index);
1696+
if (isOptional) {
1697+
effectiveParamTypeStr = DotNames.OBJECT.toString();
1698+
if (paramType.kind() == PARAMETERIZED_TYPE) {
1699+
Type objectType = paramType.asParameterizedType().arguments().get(0);
1700+
if ((objectType.kind() == CLASS) || (objectType.kind() == PARAMETERIZED_TYPE)) {
1701+
effectiveParamTypeStr = objectType.name().toString();
1702+
}
1703+
}
1704+
}
1705+
16931706
// headers are added at the invocation builder level
16941707
MethodDescriptor handleHeaderDescriptor = MethodDescriptor.ofMethod(subName,
16951708
subMethod.getName() + "$$" + subMethodIndex + "$$handleHeader$$param"
@@ -1702,9 +1715,15 @@ private void handleSubResourceMethod(List<JaxrsClientReactiveEnricherBuildItem>
17021715
AssignableResultHandle invocationBuilderRef = handleHeaderMethod
17031716
.createVariable(Invocation.Builder.class);
17041717
handleHeaderMethod.assign(invocationBuilderRef, handleHeaderMethod.getMethodParam(0));
1718+
ResultHandle headerValue = handleHeaderMethod.getMethodParam(1);
17051719
addHeaderParam(handleHeaderMethod, invocationBuilderRef, param.name,
1706-
handleHeaderMethod.getMethodParam(1),
1707-
param.type,
1720+
isOptional
1721+
? handleHeaderMethod.invokeVirtualMethod(
1722+
MethodDescriptor.ofMethod(Optional.class, "orElse", Object.class,
1723+
Object.class),
1724+
headerValue, handleHeaderMethod.loadNull())
1725+
: headerValue,
1726+
effectiveParamTypeStr,
17081727
handleHeaderMethod.readInstanceField(clientField, handleHeaderMethod.getThis()),
17091728
getGenericTypeFromArray(handleHeaderMethod, subParamField.genericsParametersField,
17101729
subParamField.paramIndex),
@@ -1816,6 +1835,19 @@ private void handleSubResourceMethod(List<JaxrsClientReactiveEnricherBuildItem>
18161835
// just store the index of parameter used to create the body, we'll use it later
18171836
bodyParameterValue = subMethodCreator.getMethodParam(paramIdx);
18181837
} else if (param.parameterType == ParameterType.HEADER) {
1838+
Type paramType = jandexSubMethod.parameterType(paramIdx);
1839+
String effectiveParamTypeStr = paramType.name().toString();
1840+
boolean isOptional = isOptional(paramType, index);
1841+
if (isOptional) {
1842+
effectiveParamTypeStr = DotNames.OBJECT.toString();
1843+
if (paramType.kind() == PARAMETERIZED_TYPE) {
1844+
Type objectType = paramType.asParameterizedType().arguments().get(0);
1845+
if ((objectType.kind() == CLASS) || (objectType.kind() == PARAMETERIZED_TYPE)) {
1846+
effectiveParamTypeStr = objectType.name().toString();
1847+
}
1848+
}
1849+
}
1850+
18191851
// headers are added at the invocation builder level
18201852
MethodDescriptor handleHeaderDescriptor = MethodDescriptor.ofMethod(subName,
18211853
subMethod.getName() + "$$" + subMethodIndex + "$$handleHeader$$" + paramIdx,
@@ -1826,9 +1858,16 @@ private void handleSubResourceMethod(List<JaxrsClientReactiveEnricherBuildItem>
18261858

18271859
AssignableResultHandle invocationBuilderRef = handleHeaderMethod
18281860
.createVariable(Invocation.Builder.class);
1861+
ResultHandle headerValue = handleHeaderMethod.getMethodParam(1);
18291862
handleHeaderMethod.assign(invocationBuilderRef, handleHeaderMethod.getMethodParam(0));
18301863
addHeaderParam(handleHeaderMethod, invocationBuilderRef, param.name,
1831-
handleHeaderMethod.getMethodParam(1), param.type,
1864+
isOptional
1865+
? handleHeaderMethod.invokeVirtualMethod(
1866+
MethodDescriptor.ofMethod(Optional.class, "orElse", Object.class,
1867+
Object.class),
1868+
headerValue, handleHeaderMethod.loadNull())
1869+
: headerValue,
1870+
effectiveParamTypeStr,
18321871
handleHeaderMethod.readInstanceField(clientField, handleHeaderMethod.getThis()),
18331872
getGenericTypeFromArray(handleHeaderMethod, subMethodGenericParametersField, paramIdx),
18341873
getAnnotationsFromArray(handleHeaderMethod, subMethodParamAnnotationsField, paramIdx));
@@ -2018,7 +2057,7 @@ private void generateSubResourceLocatorOwnerMethod(String name, ClassRestClientC
20182057
for (int i = 0; i < method.getParameters().length; i++) {
20192058
MethodParameter param = method.getParameters()[i];
20202059
if (param.parameterType != ParameterType.PATH) {
2021-
FieldDescriptor paramField = FieldDescriptor.of(subName, "param" + i, param.type);
2060+
FieldDescriptor paramField = FieldDescriptor.of(subName, "param" + i, param.declaredType);
20222061
ownerMethod.writeInstanceField(paramField, subInstance, ownerMethod.getMethodParam(i));
20232062
}
20242063

extensions/resteasy-reactive/rest-client/deployment/src/test/java/io/quarkus/rest/client/reactive/headers/OptionalHeaderTest.java

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,29 +22,52 @@ public class OptionalHeaderTest {
2222

2323
@RegisterExtension
2424
static final QuarkusUnitTest config = new QuarkusUnitTest()
25-
.withApplicationRoot((jar) -> jar.addClasses(Resource.class, Client.class));
25+
.withApplicationRoot((jar) -> jar.addClasses(Resource.class,
26+
Client.class, OtherClient.class, OtherSubClient.class));
2627

2728
@TestHTTPResource
2829
URI baseUri;
2930

3031
@Test
31-
void test() {
32+
void normalClient() {
3233
Client client = QuarkusRestClientBuilder.newBuilder().baseUri(baseUri).build(Client.class);
3334
String result = client.send(Optional.empty(), "q", Optional.of("h2"), Optional.of(3));
3435
assertThat(result).isEqualTo("query=q/Header2=h2,Header3=3");
3536
}
3637

37-
@Path("test")
38+
@Test
39+
void subresourceClient() {
40+
OtherClient client = QuarkusRestClientBuilder.newBuilder().baseUri(baseUri).build(OtherClient.class);
41+
String result = client.send(Optional.empty(), "q").send(Optional.of("h2"), Optional.of(3));
42+
assertThat(result).isEqualTo("query=q/Header2=h2,Header3=3");
43+
}
44+
45+
@Path("resource")
3846
public interface Client {
3947

48+
@Path("test")
4049
@GET
4150
String send(@HeaderParam("header1") Optional<String> header1, @RestQuery String query,
4251
@RestHeader Optional<String> header2, @RestHeader Optional<Integer> header3);
4352
}
4453

45-
@Path("test")
54+
@Path("resource")
55+
public interface OtherClient {
56+
57+
@Path("test")
58+
OtherSubClient send(@HeaderParam("header1") Optional<String> header1, @RestQuery String query);
59+
}
60+
61+
public interface OtherSubClient {
62+
63+
@GET
64+
String send(@RestHeader Optional<String> header2, @RestHeader Optional<Integer> header3);
65+
}
66+
67+
@Path("resource")
4668
public static class Resource {
4769

70+
@Path("test")
4871
@GET
4972
public String test(@RestQuery String query, @RestHeader String header1,
5073
@RestHeader String header2,

0 commit comments

Comments
 (0)