Skip to content

Commit

Permalink
Add Optional BeanParam support for JAXRS2Contract (#1935)
Browse files Browse the repository at this point in the history
* Add Optional BeanParam support for JAXRS2Contract

* Fix Code Style

* Commit Build Code Format Changes

* Roll Back Removal of braces

* Make sure jaxrs1 dependencies not avaiable on jaxrs2

* Update JAXRS2ContractWithBeanParamSupportTest.java

* Always Use Enable BeanParam Support

* Roll Back Test Changes

---------

Co-authored-by: Marvin Froeder <velo@users.noreply.github.com>
  • Loading branch information
JKomoroski and velo committed Feb 18, 2023
1 parent 0cb3a0a commit 4455fc2
Show file tree
Hide file tree
Showing 5 changed files with 174 additions and 10 deletions.
3 changes: 2 additions & 1 deletion jaxrs/src/main/java/feign/jaxrs/JAXRSContract.java
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,8 @@ protected void registerParamAnnotations() {
}

// Not using override as the super-type's method is deprecated and will be removed.
private String addTemplatedParam(String name) {
// Protected so JAXRS2Contract can make use of this
protected String addTemplatedParam(String name) {
return String.format("{%s}", name);
}
}
2 changes: 2 additions & 0 deletions jaxrs2/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,5 @@ Links the value of the corresponding parameter to a query parameter. When invok
Links the value of the corresponding parameter to a header.
#### `@FormParam`
Links the value of the corresponding parameter to a key passed to `Encoder.Text<Map<String, Object>>.encode()`.
#### `@BeanParm`
Aggregates the above supported parameter annotations under a single value object.
18 changes: 12 additions & 6 deletions jaxrs2/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@
<artifactId>feign-core</artifactId>
</dependency>

<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>2.1.1</version>
</dependency>

<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>feign-jaxrs</artifactId>
Expand All @@ -53,12 +59,6 @@
</exclusions>
</dependency>

<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>2.1.1</version>
</dependency>

<!-- for example -->
<dependency>
<groupId>${project.groupId}</groupId>
Expand All @@ -77,6 +77,12 @@
<artifactId>feign-jaxrs</artifactId>
<type>test-jar</type>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
</exclusion>
</exclusions>
</dependency>

<dependency>
Expand Down
69 changes: 66 additions & 3 deletions jaxrs2/src/main/java/feign/jaxrs2/JAXRS2Contract.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,13 @@
*/
package feign.jaxrs2;

import javax.ws.rs.BeanParam;
import feign.jaxrs.JAXRSContract;
import javax.ws.rs.*;
import javax.ws.rs.container.Suspended;
import javax.ws.rs.core.Context;
import feign.jaxrs.JAXRSContract;
import java.lang.reflect.Field;
import static feign.Util.checkState;
import static feign.Util.emptyToNull;

/**
* Please refer to the <a href="https://github.com/Netflix/feign/tree/master/feign-jaxrs2">Feign
Expand All @@ -31,7 +34,67 @@ public JAXRS2Contract() {
// https://github.com/OpenFeign/feign/issues/669
super.registerParameterAnnotation(Suspended.class, (ann, data, i) -> data.ignoreParamater(i));
super.registerParameterAnnotation(Context.class, (ann, data, i) -> data.ignoreParamater(i));
super.registerParameterAnnotation(BeanParam.class, (ann, data, i) -> data.ignoreParamater(i));

}

@Override
protected void registerParamAnnotations() {
super.registerParamAnnotations();

registerParameterAnnotation(BeanParam.class, (param, data, paramIndex) -> {
final Field[] aggregatedParams = data.method()
.getParameters()[paramIndex]
.getType()
.getDeclaredFields();

for (Field aggregatedParam : aggregatedParams) {

if (aggregatedParam.isAnnotationPresent(PathParam.class)) {
final String name = aggregatedParam.getAnnotation(PathParam.class).value();
checkState(
emptyToNull(name) != null,
"BeanParam parameter %s contains PathParam with empty .value() on field %s",
paramIndex,
aggregatedParam.getName());
nameParam(data, name, paramIndex);
}

if (aggregatedParam.isAnnotationPresent(QueryParam.class)) {
final String name = aggregatedParam.getAnnotation(QueryParam.class).value();
checkState(
emptyToNull(name) != null,
"BeanParam parameter %s contains QueryParam with empty .value() on field %s",
paramIndex,
aggregatedParam.getName());
final String query = addTemplatedParam(name);
data.template().query(name, query);
nameParam(data, name, paramIndex);
}

if (aggregatedParam.isAnnotationPresent(HeaderParam.class)) {
final String name = aggregatedParam.getAnnotation(HeaderParam.class).value();
checkState(
emptyToNull(name) != null,
"BeanParam parameter %s contains HeaderParam with empty .value() on field %s",
paramIndex,
aggregatedParam.getName());
final String header = addTemplatedParam(name);
data.template().header(name, header);
nameParam(data, name, paramIndex);
}

if (aggregatedParam.isAnnotationPresent(FormParam.class)) {
final String name = aggregatedParam.getAnnotation(FormParam.class).value();
checkState(
emptyToNull(name) != null,
"BeanParam parameter %s contains FormParam with empty .value() on field %s",
paramIndex,
aggregatedParam.getName());
data.formParams().add(name);
nameParam(data, name, paramIndex);
}
}
});

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
* Copyright 2012-2023 The Feign Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package feign.jaxrs2;

import feign.MethodMetadata;
import feign.jaxrs.JAXRSContract;
import feign.jaxrs.JAXRSContractTest;
import feign.jaxrs2.JAXRS2ContractWithBeanParamSupportTest.Jaxrs2Internals.BeanParamInput;
import org.junit.Test;
import javax.ws.rs.*;
import javax.ws.rs.container.AsyncResponse;
import javax.ws.rs.container.Suspended;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.UriInfo;
import static feign.assertj.FeignAssertions.assertThat;
import static java.util.Arrays.asList;
import static org.assertj.core.data.MapEntry.entry;

/**
* Tests interfaces defined per {@link JAXRS2Contract} are interpreted into expected
* {@link feign .RequestTemplate template} instances.
*/
public class JAXRS2ContractWithBeanParamSupportTest extends JAXRSContractTest {

@Override
protected JAXRSContract createContract() {
return new JAXRS2Contract();
}

@Test
public void injectJaxrsInternals() throws Exception {
final MethodMetadata methodMetadata =
parseAndValidateMetadata(Jaxrs2Internals.class, "inject", AsyncResponse.class,
UriInfo.class);
assertThat(methodMetadata.template())
.noRequestBody();
}

@Test
public void injectBeanParam() throws Exception {
final MethodMetadata methodMetadata =
parseAndValidateMetadata(Jaxrs2Internals.class, "beanParameters", BeanParamInput.class);
assertThat(methodMetadata.template())
.noRequestBody();

assertThat(methodMetadata.template())
.hasHeaders(entry("X-Custom-Header", asList("{X-Custom-Header}")));
assertThat(methodMetadata.template())
.hasQueries(entry("query", asList("{query}")));
assertThat(methodMetadata.formParams())
.isNotEmpty()
.containsExactly("form");

}

public interface Jaxrs2Internals {
@GET
@Path("/")
void inject(@Suspended AsyncResponse ar, @Context UriInfo info);

@Path("/{path}")
@POST
void beanParameters(@BeanParam BeanParamInput beanParam);

public class BeanParamInput {

@PathParam("path")
String path;

@QueryParam("query")
String query;

@FormParam("form")
String form;

@HeaderParam("X-Custom-Header")
String header;
}
}

}

0 comments on commit 4455fc2

Please sign in to comment.