From c3766720faca97e1ef6698b33a5169daa19eb241 Mon Sep 17 00:00:00 2001 From: Matt Benson Date: Mon, 15 Feb 2016 13:51:43 -0600 Subject: [PATCH] Parameter name discovery for Feign clients Supports Spring REST parameter annotations considered only #value() members without respecting @AliasFor meta-annotations. Address by passing a Spring-synthesized annotation to individual AnnotatedParameterProcessors. This approach has the benefit of impacting present as well as any future implementations alike. Fixes gh-828 --- .../feign/support/SpringMvcContract.java | 3 +- ...tTest.java => SpringMvcContractTests.java} | 29 +++++++++++++++++-- 2 files changed, 29 insertions(+), 3 deletions(-) rename spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/support/{SpringMvcContractTest.java => SpringMvcContractTests.java} (86%) diff --git a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/support/SpringMvcContract.java b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/support/SpringMvcContract.java index e0e0f38d..327656b9 100644 --- a/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/support/SpringMvcContract.java +++ b/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/feign/support/SpringMvcContract.java @@ -30,6 +30,7 @@ import org.springframework.cloud.netflix.feign.AnnotatedParameterProcessor; import org.springframework.cloud.netflix.feign.annotation.PathVariableParameterProcessor; import org.springframework.cloud.netflix.feign.annotation.RequestHeaderParameterProcessor; import org.springframework.cloud.netflix.feign.annotation.RequestParamParameterProcessor; +import org.springframework.core.annotation.AnnotationUtils; import org.springframework.util.Assert; import org.springframework.web.bind.annotation.RequestMapping; @@ -166,7 +167,7 @@ public class SpringMvcContract extends Contract.BaseContract { .get(parameterAnnotation.annotationType()); if (processor != null) { isHttpAnnotation |= processor.processArgument(context, - parameterAnnotation); + AnnotationUtils.synthesizeAnnotation(parameterAnnotation, null)); } } return isHttpAnnotation; diff --git a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/support/SpringMvcContractTest.java b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/support/SpringMvcContractTests.java similarity index 86% rename from spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/support/SpringMvcContractTest.java rename to spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/support/SpringMvcContractTests.java index 6f87fe54..93936e7e 100644 --- a/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/support/SpringMvcContractTest.java +++ b/spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/feign/support/SpringMvcContractTests.java @@ -26,7 +26,7 @@ import lombok.ToString; /** * @author chadjaros */ -public class SpringMvcContractTest { +public class SpringMvcContractTests { private SpringMvcContract contract; @@ -122,6 +122,27 @@ public class SpringMvcContractTest { data.template().queries().get("amount").iterator().next()); } + @Test + public void testProcessAnnotations_Aliased() throws Exception { + Method method = TestTemplate_Advanced.class.getDeclaredMethod("getTest2", + String.class, Integer.class); + MethodMetadata data = this.contract + .parseAndValidateMetadata(method.getDeclaringClass(), method); + + assertEquals("/advanced/test2", data.template().url()); + assertEquals("PUT", data.template().method()); + assertEquals(MediaType.APPLICATION_JSON_VALUE, + data.template().headers().get("Accept").iterator().next()); + + assertEquals("Authorization", data.indexToName().get(0).iterator().next()); + assertEquals("amount", data.indexToName().get(1).iterator().next()); + + assertEquals("{Authorization}", + data.template().headers().get("Authorization").iterator().next()); + assertEquals("{amount}", + data.template().queries().get("amount").iterator().next()); + } + @Test public void testProcessAnnotations_Advanced2() throws Exception { Method method = TestTemplate_Advanced.class.getDeclaredMethod("getTest"); @@ -166,6 +187,10 @@ public class SpringMvcContractTest { ResponseEntity getTest(@RequestHeader("Authorization") String auth, @PathVariable("id") String id, @RequestParam("amount") Integer amount); + @RequestMapping(path = "/test2", method = RequestMethod.PUT, produces = MediaType.APPLICATION_JSON_VALUE) + ResponseEntity getTest2(@RequestHeader(name = "Authorization") String auth, + @RequestParam(name = "amount") Integer amount); + @RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) TestObject getTest(); } @@ -209,4 +234,4 @@ public class SpringMvcContractTest { return result; } } -} \ No newline at end of file +}