Skip to content

Commit 6453bd0

Browse files
geoandgsmet
authored andcommitted
Properly support Optional as a header param for REST Client
Fixes: #47366 (cherry picked from commit 2422ae6)
1 parent 87d457c commit 6453bd0

File tree

2 files changed

+101
-6
lines changed

2 files changed

+101
-6
lines changed

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

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1138,6 +1138,19 @@ A more full example of generated client (with sub-resource) can is at the bottom
11381138
// just store the index of parameter used to create the body, we'll use it later
11391139
bodyParameterIdx = paramIdx;
11401140
} else if (param.parameterType == ParameterType.HEADER) {
1141+
Type paramType = jandexMethod.parameterType(paramIdx);
1142+
String effectiveParamTypeStr = paramType.name().toString();
1143+
boolean isOptional = isOptional(paramType, index);
1144+
if (isOptional) {
1145+
effectiveParamTypeStr = DotNames.OBJECT.toString();
1146+
if (paramType.kind() == PARAMETERIZED_TYPE) {
1147+
Type objectType = paramType.asParameterizedType().arguments().get(0);
1148+
if ((objectType.kind() == CLASS) || (objectType.kind() == PARAMETERIZED_TYPE)) {
1149+
effectiveParamTypeStr = objectType.name().toString();
1150+
}
1151+
}
1152+
}
1153+
11411154
// headers are added at the invocation builder level
11421155
MethodDescriptor handleHeaderDescriptor = MethodDescriptor.ofMethod(name,
11431156
method.getName() + "$$" + methodIndex + "$$handleHeader$$" + paramIdx,
@@ -1149,8 +1162,15 @@ A more full example of generated client (with sub-resource) can is at the bottom
11491162
AssignableResultHandle invocationBuilderRef = handleHeaderMethod
11501163
.createVariable(Invocation.Builder.class);
11511164
handleHeaderMethod.assign(invocationBuilderRef, handleHeaderMethod.getMethodParam(0));
1165+
ResultHandle headerValue = handleHeaderMethod.getMethodParam(1);
11521166
addHeaderParam(handleHeaderMethod, invocationBuilderRef, param.name,
1153-
handleHeaderMethod.getMethodParam(1), param.type,
1167+
isOptional
1168+
? handleHeaderMethod.invokeVirtualMethod(
1169+
MethodDescriptor.ofMethod(Optional.class, "orElse", Object.class,
1170+
Object.class),
1171+
headerValue, handleHeaderMethod.loadNull())
1172+
: headerValue,
1173+
effectiveParamTypeStr,
11541174
handleHeaderMethod.getThis(),
11551175
getGenericTypeFromArray(handleHeaderMethod, methodGenericParametersField, paramIdx),
11561176
getAnnotationsFromArray(handleHeaderMethod, methodParamAnnotationsField, paramIdx));
@@ -3123,22 +3143,22 @@ private boolean isOptional(Type type, IndexView index) {
31233143
}
31243144

31253145
private void addHeaderParam(BytecodeCreator invoBuilderEnricher, AssignableResultHandle invocationBuilder,
3126-
String paramName, ResultHandle headerParamHandle, String paramType, ResultHandle client,
3146+
String headerName, ResultHandle headerValueHandle, String paramType, ResultHandle client,
31273147
ResultHandle genericType, ResultHandle annotations) {
31283148

3129-
BytecodeCreator notNullValue = invoBuilderEnricher.ifNull(headerParamHandle).falseBranch();
3149+
BytecodeCreator notNullValue = invoBuilderEnricher.ifNull(headerValueHandle).falseBranch();
31303150

3131-
headerParamHandle = notNullValue.invokeVirtualMethod(
3151+
headerValueHandle = notNullValue.invokeVirtualMethod(
31323152
MethodDescriptor.ofMethod(RestClientBase.class, "convertParam", Object.class,
31333153
Object.class, Class.class, java.lang.reflect.Type.class, Annotation[].class),
3134-
client, headerParamHandle,
3154+
client, headerValueHandle,
31353155
notNullValue.loadClassFromTCCL(paramType), genericType, annotations);
31363156

31373157
notNullValue.assign(invocationBuilder,
31383158
notNullValue.invokeInterfaceMethod(
31393159
MethodDescriptor.ofMethod(Invocation.Builder.class, "header", Invocation.Builder.class,
31403160
String.class, Object.class),
3141-
invocationBuilder, notNullValue.load(paramName), headerParamHandle));
3161+
invocationBuilder, notNullValue.load(headerName), headerValueHandle));
31423162
}
31433163

31443164
private void addPathParam(BytecodeCreator methodCreator, AssignableResultHandle methodTarget,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package io.quarkus.rest.client.reactive.headers;
2+
3+
import static org.assertj.core.api.Assertions.assertThat;
4+
5+
import java.net.URI;
6+
import java.util.Optional;
7+
8+
import jakarta.ws.rs.GET;
9+
import jakarta.ws.rs.HeaderParam;
10+
import jakarta.ws.rs.Path;
11+
12+
import org.jboss.resteasy.reactive.RestHeader;
13+
import org.jboss.resteasy.reactive.RestQuery;
14+
import org.junit.jupiter.api.Test;
15+
import org.junit.jupiter.api.extension.RegisterExtension;
16+
17+
import io.quarkus.rest.client.reactive.QuarkusRestClientBuilder;
18+
import io.quarkus.test.QuarkusUnitTest;
19+
import io.quarkus.test.common.http.TestHTTPResource;
20+
21+
public class OptionalHeaderTest {
22+
23+
@RegisterExtension
24+
static final QuarkusUnitTest config = new QuarkusUnitTest()
25+
.withApplicationRoot((jar) -> jar.addClasses(Resource.class, Client.class));
26+
27+
@TestHTTPResource
28+
URI baseUri;
29+
30+
@Test
31+
void test() {
32+
Client client = QuarkusRestClientBuilder.newBuilder().baseUri(baseUri).build(Client.class);
33+
String result = client.send(Optional.empty(), "q", Optional.of("h2"), Optional.of(3));
34+
assertThat(result).isEqualTo("query=q/Header2=h2,Header3=3");
35+
}
36+
37+
@Path("test")
38+
public interface Client {
39+
40+
@GET
41+
String send(@HeaderParam("header1") Optional<String> header1, @RestQuery String query,
42+
@RestHeader Optional<String> header2, @RestHeader Optional<Integer> header3);
43+
}
44+
45+
@Path("test")
46+
public static class Resource {
47+
48+
@GET
49+
public String test(@RestQuery String query, @RestHeader String header1,
50+
@RestHeader String header2,
51+
@RestHeader Integer header3) {
52+
StringBuilder result = new StringBuilder("query=");
53+
result.append(query);
54+
result.append("/");
55+
if (header1 != null) {
56+
result.append("Header1");
57+
result.append("=");
58+
result.append(header1);
59+
result.append(",");
60+
}
61+
if (header2 != null) {
62+
result.append("Header2");
63+
result.append("=");
64+
result.append(header2);
65+
result.append(",");
66+
}
67+
if (header3 != null) {
68+
result.append("Header3");
69+
result.append("=");
70+
result.append(header3);
71+
}
72+
return result.toString();
73+
}
74+
}
75+
}

0 commit comments

Comments
 (0)