when spring.main.jackson.property-naming-strategy = KEBAB_CASE with an embedded config server in the same jvm as the spring app and client. seeing Environment contains empty list propertySources
omitting property-naming-strategy and environment deserializes correctly.
not a problem with config server or client, but within RestTemplate - proved with wireshark server is sending property-sources
got to configure the client to use the same property-naming-strategy fore deserialization somehow.
jackson core 2.11.1 spring boot 2.4.0-M1
@Test
public void testRemoteEnvironment() {
ResponseEntity<Environment> response = null;
HttpHeaders headers = new HttpHeaders();
headers.setAccept(
Collections.singletonList(MediaType.parseMediaType(V2_JSON)));
restTemplate = new RestTemplate();
try {
final HttpEntity<Void> entity = new HttpEntity<>((Void) null, headers);
response = restTemplate.exchange("http://localhost:9091/fmcs/dev/master", HttpMethod.GET, entity,
Environment.class, new Object[0]);
} catch (HttpClientErrorException e) {
if (e.getStatusCode() != HttpStatus.NOT_FOUND) {
throw e;
}
} catch (ResourceAccessException e) {
}
if (response == null || response.getStatusCode() != HttpStatus.OK) {
Assert.fail();
}
Environment result = response.getBody();
Assert.assertNotNull(result.getName());
Assert.assertNotNull(result.getProfiles());
Assert.assertFalse(result.getPropertySources().isEmpty());
}
Comment From: warrenc5
ConfigServicePropertySourceLocator getSecureRestTemplate. the BaseSettings propertyNamingStrategy null Because you do a new RestTemplate in getSecureRestTemplate and not using an autowired/builder approach.
https://github.com/spring-cloud/spring-cloud-config/blob/master/spring-cloud-config-client/src/main/java/org/springframework/cloud/config/client/ConfigServicePropertySourceLocator.java line 308
You can configure a RestTemplate's HTTP message converters to take control over what it can deserialise and how. It sounds like you need to configure it with a custom MappingJackson2HttpMessageConverter that's using an appropriately configured ObjectMapper. Alternatively, you could use the auto-configured RestTemplateBuilder to create a RestTemplate rather than calling new RestTemplate(). Using the builder will result in a RestTemplate that uses a Jackson HTTP message converter with the auto-configured ObjectMapper and its custom property naming strategy.
Let me know - I can submit a patch :)
Comment From: spencergibb
You didn't say what version of config server/client you are using.
Also, are you embedding the config server in a config client and using http to call itself?
Comment From: warrenc5
Yes, thanks for your response. I'm embedding a Config Server and we need KEBAB-CASE for other APIs in that same server.
spring-cloud-config-client 2.2.2 & I tried 2.2.3 also.
Thanks again.
Comment From: warrenc5
Basically the Config seems to go into bootstrap. I'm no expert so forgive me as I go on this journey of hacking into the springs.
There is a setRestTemplate on ConfigServicePropertySourceLocator
So I created a BeanPostProcessor and override the postProcessAfterInitialization to inject my RestTemplate.
I had to drag into the bootstrap META-INF/spring-factories
org.springframework.cloud.bootstrap.BootstrapConfiguration=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration, org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration, org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration, org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration, org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration, au.gov.nsw.transport.fmcs.config.web.MyBeanPostProcessor, au.gov.nsw.transport.fmcs.config.web.ClientConfig
public class MyBeanPostProcessor implements BeanPostProcessor {
@Autowired
@Qualifier("restTemplate")
private RestTemplate restTemplate;
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof ConfigServicePropertySourceLocator) {
((ConfigServicePropertySourceLocator) bean).setRestTemplate(restTemplate);
}
return bean;
}
}
Comment From: spencergibb
That is currently an acceptable way of updating the rest template.
Comment From: warrenc5
Thanks Spencer for your response. I honestly was suprised, it wasn't automagic somehow :) But I see that there have been changes to auto building/wiring a resttemplate in later spring versions. So I did some scratching around after sent me in the right direction. It's debatably a sourceforge issue. Thanks for all your help and continued support.