spring-cloud / spring-cloud-schema-registry

A schema registry implementation for Spring Cloud Stream
47 stars 28 forks source link

Incompatible Content-type for Schema Registry client, when RestTemplate XML support is (implicitly) enabled [2.2.x] #19

Closed dlehammer closed 4 years ago

dlehammer commented 4 years ago

Error

Utilizing @EnableSchemaRegistryClient while jackson-dataformat-xml is present on classpath when performing requests to the @EnableSchemaRegistryServer results in HTTP response:

415 : [{"timestamp":"2020-01-07T16:10:35.469+0000","status":415,"error":"Unsupported Media Type","message":"Content type 'application/xml;charset=UTF-8' not supported","path":"/schema-registry/"}]

Stacktrace:

Caused by: org.springframework.web.client.HttpClientErrorException$UnsupportedMediaType: 415 : [{"timestamp":"2020-01-07T16:10:35.469+0000","status":415,"error":"Unsupported Media Type","message":"Content type 'application/xml;charset=UTF-8' not supported","path":"/schema-registry/"}]
    at org.springframework.web.client.HttpClientErrorException.create(HttpClientErrorException.java:133)
    at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:170)
    at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:112)
    at org.springframework.web.client.ResponseErrorHandler.handleError(ResponseErrorHandler.java:63)
    at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:785)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:743)
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:677)
    at org.springframework.web.client.RestTemplate.postForEntity(RestTemplate.java:452)
    at org.springframework.cloud.stream.schema.client.DefaultSchemaRegistryClient.register(DefaultSchemaRegistryClient.java:69)
    at org.springframework.cloud.stream.schema.avro.AvroSchemaRegistryClientMessageConverter.resolveSchemaForWriting(AvroSchemaRegistryClientMessageConverter.java:308)
    at org.springframework.cloud.stream.schema.avro.AbstractAvroMessageConverter.convertToInternal(AbstractAvroMessageConverter.java:125)
    at org.springframework.messaging.converter.AbstractMessageConverter.toMessage(AbstractMessageConverter.java:217)
    at org.springframework.messaging.converter.AbstractMessageConverter.toMessage(AbstractMessageConverter.java:207)
    at org.springframework.messaging.converter.CompositeMessageConverter.toMessage(CompositeMessageConverter.java:83)
    at org.springframework.cloud.stream.binding.MessageConverterConfigurer$OutboundContentTypeConvertingInterceptor.doPreSend(MessageConverterConfigurer.java:324)
    at org.springframework.cloud.stream.binding.MessageConverterConfigurer$AbstractContentTypeInterceptor.preSend(MessageConverterConfigurer.java:356)
    at org.springframework.integration.channel.AbstractMessageChannel$ChannelInterceptorList.preSend(AbstractMessageChannel.java:613)
    at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:443)
    ... 153 more

Symptom discovered in 2.2.1.RELEASE, still present in 2.2.2.RELEASE.

Cause

SchemaRegistryClientConfiguration.schemaRegistryClient() initializes new DefaultSchemaRegistryClient(), this client implicitly utilizes new RestTemplate().

Unfortunately in this case RestTemplate behaviour is dictated by the classpath, and when jackson-dataformat-xml is present, XML takes precedence over JSON and Content-type is set to application/xml.

Proposed solution

Utilize RestTemplateBuilder to generate a JSON compatible RestTemplate regardless of classpath configuration.

Known work-around

"Duplicate" SchemaRegistryClientConfiguration logic and remove @EnableSchemaRegistryClient, changing the client to utilize the DefaultSchemaRegistryClient(RestTemplate restTemplate) constructor instead with a JSON compliant RestTemplate instance.

olegz commented 4 years ago

@dlehammer We are now in 3.0.1 (Horsham.SR1) version and schema-registry has moved to it's own project outside of spring-cloud-stream. So I am going to move this issue there.

dlehammer commented 4 years ago

Thanks @olegz,

I was wondering where the code had moved, seems my google-fu didn't reveal the new location :)

FYI: seems the symptom is still present in master SchemaRegistryClientConfiguration.