Skip to content

Avro support#2468

Draft
etrandafir93 wants to merge 3 commits intospring-cloud:mainfrom
etrandafir93:avro_support
Draft

Avro support#2468
etrandafir93 wants to merge 3 commits intospring-cloud:mainfrom
etrandafir93:avro_support

Conversation

@etrandafir93
Copy link
Copy Markdown

  • Bug fix ContractVerifierObjectMapper fails for Avro-generated objects #2402ContractVerifierObjectMapper fails for Avro objects: when the intercepted message is an Avro-generated object, ContractVerifierObjectMapper would fail to serialize it to JSON due to Avro-specific fields (schema,
    specificData, classSchema, conversion). Fixed by configuring the JsonMapper to ignore those fields via a mixin when Avro is on the classpath.

  • Avro support for contract-based messaging: introduced KafkaAvroMessageVerifierSender which builds an Avro GenericRecord from the contract body and sends it via KafkaTemplate, backed by KafkaAvroContractVerifierConfiguration
    (auto-configuration) and AvroMetadata (schema config in contract metadata).

  • Header propagation: KafkaAvroMessageVerifierSender now wraps the payload in a ProducerRecord and copies contract output headers (e.g. X-Correlation-Id) as UTF-8 bytes onto it, so they are actually sent to Kafka.

  • Bug fix StubRunnerExecutor fails for Avro objects #2404StubRunnerExecutor JSON-serializes Avro body: StubRunnerExecutor.sendMessage() was unconditionally calling JsonOutput.toJson() on the message body before passing it to the MessageVerifierSender. This broke
    KafkaAvroMessageVerifierSender which expects a Map, not a JSON string. Fixed by adding an isAvroContract() check that inspects the raw contract metadata and skips JSON serialization for Avro contracts, passing the body as a Map
    directly.

TODO: if this gets accepted, we also need to add the documentation and sthe samples repo

Related issues

closes spring-cloud#2402

Signed-off-by: Emanuel Trandafir <emanueltrandafir1993@gmail.com>
relates to spring-cloud#2402

Signed-off-by: Emanuel Trandafir <emanueltrandafir1993@gmail.com>
relates to spring-cloud#2404

Signed-off-by: Emanuel Trandafir <emanueltrandafir1993@gmail.com>
return body != null && body.getClientValue() instanceof FromFileProperty;
}

private boolean isAvroContract(YamlContract contract) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we make this section kafka / avro agnostic? If we just set asBytes() it should work right? Another option is to verify the contentType in which case if it's not json but explicitly sth else then we just pass through? Wdyt?

I also sense that we could have some extension points here. Like check through spi (we already do it in other parts of scc) some interfaces to verify if this contract has a special way of treating payload. We could have some AvroContractPayloadProceesor that would activate when the metadata has avro and it would provide a function to how convert the payload. That way this core logic stays clean of avro but we can inject the behavior. There would have to be some priority / ordering like we do in other spis here in scc.

Wdyt?

outputMessage:
sentTo: book.returned
headers:
X-Correlation-Id: abc-123-def
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What headers are being sent in case of avro messages? Is there any content type?


private File saveTmpContract(String contractYaml) {
File contractDir = File.createTempDir()
new File(contractDir, "book_returned.yml").text = contractYaml
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a return


@Bean
@ConditionalOnMissingBean(name = "avroKafkaTemplate")
KafkaTemplate<String, Object> avroKafkaTemplate(@Value("${spring.kafka.bootstrap-servers}") String bootstrapServers,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why can't we reuse the users production template?

}

@JsonIgnoreProperties({ "schema", "specificData", "classSchema", "conversion" })
interface IgnoreAvroMixin {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you provide a javadoc why we need this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

StubRunnerExecutor fails for Avro objects ContractVerifierObjectMapper fails for Avro-generated objects

3 participants