Skip to content

Commit

Permalink
Rest-Client-Reactive: Allow FormParams to be used in BeanParams
Browse files Browse the repository at this point in the history
  • Loading branch information
fwippe committed Jan 23, 2022
1 parent 20cae8f commit db94e76
Show file tree
Hide file tree
Showing 7 changed files with 350 additions and 102 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
import org.jboss.resteasy.reactive.client.processor.beanparam.BeanParamItem;
import org.jboss.resteasy.reactive.client.processor.beanparam.ClientBeanParamInfo;
import org.jboss.resteasy.reactive.client.processor.beanparam.CookieParamItem;
import org.jboss.resteasy.reactive.client.processor.beanparam.FormParamItem;
import org.jboss.resteasy.reactive.client.processor.beanparam.HeaderParamItem;
import org.jboss.resteasy.reactive.client.processor.beanparam.Item;
import org.jboss.resteasy.reactive.client.processor.beanparam.PathParamItem;
Expand Down Expand Up @@ -849,11 +850,12 @@ A more full example of generated client (with sub-resource) can is at the bottom
AssignableResultHandle invocationBuilderRef = handleBeanParamMethod
.createVariable(Invocation.Builder.class);
handleBeanParamMethod.assign(invocationBuilderRef, handleBeanParamMethod.getMethodParam(0));
addBeanParamData(methodCreator, handleBeanParamMethod,
formParams = addBeanParamData(methodCreator, handleBeanParamMethod,
invocationBuilderRef, beanParam.getItems(),
methodCreator.getMethodParam(paramIdx), methodTarget, index,
methodCreator.getThis(),
handleBeanParamMethod.getThis());
handleBeanParamMethod.getThis(),
formParams);

handleBeanParamMethod.returnValue(invocationBuilderRef);
invocationBuilderEnrichers.put(handleBeanParamDescriptor, methodCreator.getMethodParam(paramIdx));
Expand Down Expand Up @@ -1126,12 +1128,13 @@ private void handleSubResourceMethod(List<JaxrsClientReactiveEnricherBuildItem>
AssignableResultHandle invocationBuilderRef = handleBeanParamMethod
.createVariable(Invocation.Builder.class);
handleBeanParamMethod.assign(invocationBuilderRef, handleBeanParamMethod.getMethodParam(0));
addBeanParamData(subMethodCreator, handleBeanParamMethod,
formParams = addBeanParamData(subMethodCreator, handleBeanParamMethod,
invocationBuilderRef, beanParam.getItems(),
paramValue, methodTarget, index,
subMethodCreator.readInstanceField(clientField, subMethodCreator.getThis()),
handleBeanParamMethod.readInstanceField(clientField,
handleBeanParamMethod.getThis()));
handleBeanParamMethod.getThis()),
formParams);

handleBeanParamMethod.returnValue(invocationBuilderRef);
invocationBuilderEnrichers.put(handleBeanParamDescriptor, paramValue);
Expand Down Expand Up @@ -1219,12 +1222,13 @@ private void handleSubResourceMethod(List<JaxrsClientReactiveEnricherBuildItem>
AssignableResultHandle invocationBuilderRef = handleBeanParamMethod
.createVariable(Invocation.Builder.class);
handleBeanParamMethod.assign(invocationBuilderRef, handleBeanParamMethod.getMethodParam(0));
addBeanParamData(subMethodCreator, handleBeanParamMethod,
formParams = addBeanParamData(subMethodCreator, handleBeanParamMethod,
invocationBuilderRef, beanParam.getItems(),
subMethodCreator.getMethodParam(paramIdx), methodTarget, index,
subMethodCreator.readInstanceField(clientField, subMethodCreator.getThis()),
handleBeanParamMethod.readInstanceField(clientField,
handleBeanParamMethod.getThis()));
handleBeanParamMethod.getThis()),
formParams);

handleBeanParamMethod.returnValue(invocationBuilderRef);
invocationBuilderEnrichers.put(handleBeanParamDescriptor,
Expand Down Expand Up @@ -2098,15 +2102,37 @@ private Optional<MethodInfo> getJavaMethod(ClassInfo interfaceClass, ResourceMet
return maybeMethod;
}

private void addBeanParamData(BytecodeCreator methodCreator,
private AssignableResultHandle addBeanParamData(MethodCreator methodCreator,
BytecodeCreator invocationBuilderEnricher, // Invocation.Builder executePut$$enrichInvocationBuilder${noOfBeanParam}(Invocation.Builder)
AssignableResultHandle invocationBuilder,
List<Item> beanParamItems,
ResultHandle param,
AssignableResultHandle target, // can only be used in the current method, not in `invocationBuilderEnricher`
IndexView index,
ResultHandle client,
ResultHandle invocationEnricherClient) { // this client or containing client if this is a sub-client
ResultHandle invocationEnricherClient, // this client or containing client if this is a sub-client
AssignableResultHandle formParams) {
// Form params collector must be initialized at method root level before any inner blocks that may use it
if (areFormParamsDefinedIn(beanParamItems)) {
formParams = createIfAbsent(methodCreator, formParams);
}

addSubBeanParamData(methodCreator, invocationBuilderEnricher, invocationBuilder, beanParamItems, param, target,
index, client, invocationEnricherClient, formParams);

return formParams;
}

private void addSubBeanParamData(BytecodeCreator methodCreator,
BytecodeCreator invocationBuilderEnricher, // Invocation.Builder executePut$$enrichInvocationBuilder${noOfBeanParam}(Invocation.Builder)
AssignableResultHandle invocationBuilder,
List<Item> beanParamItems,
ResultHandle param,
AssignableResultHandle target, // can only be used in the current method, not in `invocationBuilderEnricher`
IndexView index,
ResultHandle client,
ResultHandle invocationEnricherClient, // this client or containing client if this is a sub-client
AssignableResultHandle formParams) {
BytecodeCreator creator = methodCreator.ifNotNull(param).trueBranch();
BytecodeCreator invoEnricher = invocationBuilderEnricher.ifNotNull(invocationBuilderEnricher.getMethodParam(1))
.trueBranch();
Expand All @@ -2115,8 +2141,8 @@ private void addBeanParamData(BytecodeCreator methodCreator,
case BEAN_PARAM:
BeanParamItem beanParamItem = (BeanParamItem) item;
ResultHandle beanParamElementHandle = beanParamItem.extract(creator, param);
addBeanParamData(creator, invoEnricher, invocationBuilder, beanParamItem.items(),
beanParamElementHandle, target, index, client, invocationEnricherClient);
addSubBeanParamData(creator, invoEnricher, invocationBuilder, beanParamItem.items(),
beanParamElementHandle, target, index, client, invocationEnricherClient, formParams);
break;
case QUERY_PARAM:
QueryParamItem queryParam = (QueryParamItem) item;
Expand Down Expand Up @@ -2146,12 +2172,33 @@ private void addBeanParamData(BytecodeCreator methodCreator,
pathParam.getPathParamName(),
pathParam.extract(creator, param), pathParam.getParamType(), client);
break;
case FORM_PARAM:
FormParamItem formParam = (FormParamItem) item;
addFormParam(creator, formParam.getFormParamName(), formParam.extract(creator, param),
formParam.getParamType(), client, formParams);
break;
default:
throw new IllegalStateException("Unimplemented"); // TODO form params, etc
throw new IllegalStateException("Unimplemented");
}
}
}

private boolean areFormParamsDefinedIn(List<Item> beanParamItems) {
for (Item item : beanParamItems) {
switch (item.type()) {
case FORM_PARAM:
return true;
case BEAN_PARAM:
if (areFormParamsDefinedIn(((BeanParamItem) item).items())) {
return true;
}
break;
}
}

return false;
}

// takes a result handle to target as one of the parameters, returns a result handle to a modified target
private ResultHandle addQueryParam(BytecodeCreator methodCreator,
ResultHandle target,
Expand Down Expand Up @@ -2234,6 +2281,17 @@ private void addPathParam(BytecodeCreator methodCreator, AssignableResultHandle
methodCreator.load(paramName), handle));
}

private void addFormParam(BytecodeCreator methodCreator, String paramName, ResultHandle formParamHandle,
String parameterType,
ResultHandle client, AssignableResultHandle formParams) {
ResultHandle convertedHandle = methodCreator.invokeVirtualMethod(
MethodDescriptor.ofMethod(RestClientBase.class, "convertParam", Object.class, Object.class, Class.class),
client, formParamHandle,
methodCreator.loadClass(parameterType));
methodCreator.invokeInterfaceMethod(MULTIVALUED_MAP_ADD, formParams,
methodCreator.load(paramName), convertedHandle);
}

private void addCookieParam(BytecodeCreator invoBuilderEnricher, AssignableResultHandle invocationBuilder,
String paramName, ResultHandle cookieParamHandle, String paramType, ResultHandle client) {
cookieParamHandle = invoBuilderEnricher.invokeVirtualMethod(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package io.quarkus.rest.client.reactive.beanparam;

import static org.assertj.core.api.Assertions.assertThat;

import java.net.URI;

import javax.ws.rs.BeanParam;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.MediaType;

import org.eclipse.microprofile.rest.client.RestClientBuilder;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.test.QuarkusUnitTest;
import io.quarkus.test.common.http.TestHTTPResource;

public class BeanFormParamTest {
@RegisterExtension
static final QuarkusUnitTest TEST = new QuarkusUnitTest();

@TestHTTPResource
URI baseUri;

@Test
void shouldPassFormParamsFromBeanParam() {
assertThat(clientBuilder().build(FormTestClient.class).postFormParams(new BeanWithFormParams("value1", "value2")))
.isEqualTo(
"received value1-value2");
}

private RestClientBuilder clientBuilder() {
return RestClientBuilder.newBuilder().baseUri(baseUri);
}

@Path("/form")
public interface FormTestClient {
@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
String postFormParams(@BeanParam BeanWithFormParams beanParam);
}

public static class BeanWithFormParams {
private final String param1;
private final String param2;

public BeanWithFormParams(String param1, String param2) {
this.param1 = param1;
this.param2 = param2;
}

@FormParam("param1")
public String getParam1() {
return param1;
}

@FormParam("param2")
public String getParam2() {
return param2;
}
}

@Path("/form")
public static class FormTestResource {
@POST
public String post(@FormParam("param1") String param1, @FormParam("param2") String param2) {
return String.format("received %s-%s", param1, param2);
}
}
}
13 changes: 8 additions & 5 deletions independent-projects/resteasy-reactive/client/processor/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,23 +38,26 @@
<groupId>jakarta.enterprise</groupId>
<artifactId>jakarta.enterprise.cdi-api</artifactId>
</dependency>

<dependency>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
</dependency>

<!-- Test -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.jboss.logging</groupId>
<artifactId>jboss-logging</artifactId>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>

</dependencies>

</project>
Loading

0 comments on commit db94e76

Please sign in to comment.