Hi,
I'm having the following 2 FeignClient configurations
@Configuration
public class ServiceAClientConfiguration {
@FeignClient(name = "serviceA", url = "${service.a.url}", configuration = ServiceAClientFeignConfiguration.class)
public interface ServiceAClient extends ServiceAResource {
}
@Configuration
public static class ServiceAClientFeignConfiguration {
@Bean
public Decoder feignDecoder(@Qualifier("_halObjectMapper") ObjectMapper objectMapper) {
ObjectMapper kebabObjectMapper = objectMapper.copy().setPropertyNamingStrategy(KEBAB_CASE);
HttpMessageConverter jacksonConverter = new MappingJackson2HttpMessageConverter(kebabObjectMapper);
ObjectFactory<HttpMessageConverters> objectFactory = () -> new HttpMessageConverters(jacksonConverter);
return new ResponseEntityDecoder(new SpringDecoder(objectFactory));
}
}
}
@Configuration
public class ServiceBClientConfiguration {
@FeignClient(name = "serviceB", url = "${service.b.url}", configuration = ServiceBClientFeignConfiguration.class)
public interface ServiceBClient extends ServiceBResource {
}
@Configuration
public static class ServiceBClientFeignConfiguration {
@Bean
public Decoder feignDecoder(@Qualifier("_halObjectMapper") ObjectMapper objectMapper) {
ObjectMapper snakeObjectMapper = objectMapper.copy().setPropertyNamingStrategy(SNAKE_CASE);
HttpMessageConverter jacksonConverter = new MappingJackson2HttpMessageConverter(snakeObjectMapper);
ObjectFactory<HttpMessageConverters> objectFactory = () -> new HttpMessageConverters(jacksonConverter);
return new ResponseEntityDecoder(new SpringDecoder(objectFactory));
}
}
}
Both of these services talk in a different JSON format. Service A is using KEBAB casing, service B is using SNAKE casing. By tweaking the object mapper, I was hoping to talk with the different services.
However, what I now see is that the FeignClient for service A is using the same converter as of service B, and so using the same object mapper of service B. It's unable to talk with a KEBAB casing service as the object mapper is expecting SNAKE casing.
I read this issue (#1211) which is kind of similar of what I'm facing, but I'm using different names for the FeignClients, so it should not be the root cause.
Is it possible my problem is actually the same as #1211? And the only solution is to create the feign clients manually?
Comment From: ryanjbaxter
Remove the @Configuration annotation from the configuration classes.
See the note in http://cloud.spring.io/spring-cloud-static/Finchley.RELEASE/single/spring-cloud.html#_logging_configuration
Comment From: jochenhebbrecht
Hi @ryanjbaxter ,
Thanks for your fast feedback! Are you talking about the @Configuration on the ServiceAClientConfiguration class or on the ServiceAClientFeignConfiguration class.
I also see your posting a link to logging configuration. I was wondering what the link is between my problem and the logging configuration?
Thnx! Jochen
Comment From: ryanjbaxter
Yes that is what I am talking about.
Sorry I posted the wrong link http://cloud.spring.io/spring-cloud-static/Finchley.RELEASE/single/spring-cloud.html#spring-cloud-feign-overriding-defaults
Comment From: jochenhebbrecht
Ok, this bring me in the following situation:
@Configuration
public class ServiceAClientConfiguration {
@FeignClient(name = "serviceA", url = "${service.a.url}", configuration = ServiceAClientFeignConfiguration.class)
public interface ServiceAClient extends ServiceAResource {
}
public static class ServiceAClientFeignConfiguration {
@Bean
public Decoder feignDecoder(@Qualifier("_halObjectMapper") ObjectMapper objectMapper) {
ObjectMapper kebabObjectMapper = objectMapper.copy().setPropertyNamingStrategy(KEBAB_CASE);
HttpMessageConverter jacksonConverter = new MappingJackson2HttpMessageConverter(kebabObjectMapper);
ObjectFactory<HttpMessageConverters> objectFactory = () -> new HttpMessageConverters(jacksonConverter);
return new ResponseEntityDecoder(new SpringDecoder(objectFactory));
}
}
}
@Configuration
public class ServiceBClientConfiguration {
@FeignClient(name = "serviceB", url = "${service.b.url}", configuration = ServiceBClientFeignConfiguration.class)
public interface ServiceBClient extends ServiceBResource {
}
public static class ServiceBClientFeignConfiguration {
@Bean
public Decoder feignDecoder(@Qualifier("_halObjectMapper") ObjectMapper objectMapper) {
ObjectMapper snakeObjectMapper = objectMapper.copy().setPropertyNamingStrategy(SNAKE_CASE);
HttpMessageConverter jacksonConverter = new MappingJackson2HttpMessageConverter(snakeObjectMapper);
ObjectFactory<HttpMessageConverters> objectFactory = () -> new HttpMessageConverters(jacksonConverter);
return new ResponseEntityDecoder(new SpringDecoder(objectFactory));
}
}
}
When booting the application, the custom feign configurations are still being loaded (I added a breakpoint to be sure they would still be loaded ) but I still see the converter of service B ending up in the configuration of service A :-( ...
Comment From: ryanjbaxter
Maybe also try removing the @Bean annotations?
Comment From: jochenhebbrecht
Already tried that as well - the configurations still get loaded, but the converters are still being mixed up
Comment From: ryanjbaxter
Please provide a sample that reproduces the problem.
Comment From: jochenhebbrecht
Yes, I understand that it's hard now to understand what exactly the problem is. I do appreciate your very fast feedback!
I was successful in isolating the problem by creating a small project which only initializes the feign clients and talks to existing services. But you would still not be able to run that application as you need my services. I guess that won't be enough for you? And you would like me to deliver 2 small REST services as well? 1 speaking KEBAB casing, 1 speaking SNAKE casing?
Comment From: ryanjbaxter
doesnt necessarily need to be using the KEBAB and SNAKE casing just something that demonstrates the configuration not be applied correctly to the services
Comment From: jochenhebbrecht
Ok, I'll see what I can do. I'll probably come back to you after the weekend. You can, for now, mark this issue as 'Waiting for feedback'
Comment From: jochenhebbrecht
Hi @ryanjbaxter,
I was able to create a small 'test' project which you could easily use to reproduce the problem. However, by creating those 'dummy' services, it seems like that I can't reproduce the problem anymore.
This actually proved to me that the feign client library works like it should work, and there's a big chance there's something wrong in my project which breaks the stability of the feign clients.
This is no longer an issue for spring-cloud-netflix, so I'm closing this issue.
I do want to thank you for your feedback! The tip on the removal of the @Configuration was very valuable to me!
Jochen
Comment From: educostadev
Remove the @Configuration saved my day!
Comment From: paulkeogh
Not just configuration... any Spring annotation.
Comment From: arvinxian
Remove the @configuration also saved my day!