In a stream processing application using Spring Cloud Stream I am taking an input stream (keyed on an integer) and calling selectKey
on it to create a new topic with the same values, but with a different key (a string). The input topic has records in it in proper JSON format, e.g.:
"key": {
"id": 1
},
"value": {
"id": 1,
"public_id": "4273b60f-6fe6-40be-8602-d0b3ed2ecf2a", ...
The problem is that the topic created by the stream processing application has the value
as a string containing JSON rather than as proper JSON, i.e.:
"key": "4273b60f-6fe6-40be-8602-d0b3ed2ecf2a",
"value": "{\"id\":1,\"publicId\":\"4273b60f-6fe6-40be-8602-d0b3ed2ecf2a\"}"
The code is as follows:
@StreamListener
@SendTo("output")
fun process(@Input("input") stream: KStream<Int, MyObj>): KStream<String, MyObj> =
stream.selectKey { _, value -> value.publicId }
What the function above does is consume the input stream, and generate an output stream (being sent to output
). That output stream has the same values as the input stream, but simply a different key. (In this case the key comes from the value's publicId
property.)
The application.yml
is as follows:
spring.cloud.stream:
bindings:
input:
destination: input-topic
output:
destination: output-output
kafka:
streams:
binder:
application-id: test-app-id-1
bindings:
input:
consumer:
keySerde: org.apache.kafka.common.serialization.Serdes$IntegerSerde
output:
producer:
keySerde: org.apache.kafka.common.serialization.Serdes$StringSerde
Is there something I'm missing? Is this actually a problem, or is it OK for the JSON to be stored as a string in the messages produced by Spring Cloud Stream?
Other things I've tried which haven't made a difference:
- Using native decoding/encoding
- Setting
spring.cloud.stream.bindings.output.content-type
toapplication/json
- Using
map
instead ofselectKey