Files
spring-modulith/spring-modulith-examples/spring-modulith-example-kafka
Oliver Drotbohm 84e9f38b07 GH-855 - Support to add headers in event externalization.
EventExternalizationConfiguration now exposes a ….headers(Class<T>, Function<T, Map<String, Object>) to allow to define a function that extracts headers from the event that are supposed to added to the message to be sent out. The Kafka and AMQP implementations have been augmented to consider those configurations.

Furthermore, if the mapping step prior to the externalization creates a Spring Message<?>, we add routing information as fallback and send it out as is.
2024-10-13 20:17:12 +02:00
..

= Spring Modulith -- Kafka event externalization example

This examples how domain events can automatically be externalized to Kafka.
The two fundamentally required steps are:

1. Add the `spring-modulith-events-kafka` dependency to the project (`runtime` scope is sufficient).
2. Add the `spring-modulith-events-api` dependency to annotate the event types to be externalized automatically with `@Externalized` (see `OrderCompleted`).

`TestApplication` (in `src/test/java`) declares a `KafkaOperations` instance so that we do not need an actual Kafka instance running for the sample.
The bean declared simply triggers some log output simulating the actual interaction with Kafka.
Running the test application using `./mvnw spring-boot:test-run` should show the following output.

[source]
----
22:20:20.398 D -     main : Registering domain event externalization to Kafka… <1>
…
22:20:21.267 I -     main : Triggering order completion… <2>
22:20:21.277 D -     main : Registering publication of example.order.OrderCompleted for org.springframework.modulith.events.support.DelegatingEventExternalizer.externalize(java.lang.Object). <3>
22:20:21.325 D -   task-1 : Externalizing event of type class example.order.OrderCompleted to RoutingTarget[value=order.OrderCompleted]. <4>
22:20:21.327 I -   task-1 : Sending message {"orderId":{"id":"ef3521e8-d498-4539-8745-3a1c74bbe90d"}} to RoutingTarget[value=order.OrderCompleted]. <5>
22:20:21.376 D -   task-1 : Marking publication of event example.order.OrderCompleted to listener org.springframework.modulith.events.support.DelegatingEventExternalizer.externalize(java.lang.Object) completed. <6>
----
<1> On application bootstrap, the `spring-modulith-events-kafka` module registers an `ApplicationModuleListener` that will listen to domain events to be externalized.
<2> Once started, the application's `main` method invokes a business method on the `OrderManagement` that ultimately results in the publication of an `OrderCompleted` event.
That in turn is annotated with Spring Modulith's `@Externalized` and thus qualifies for externalization.
<3> The event publication infrastructure detects an `@ApplicationModuleListener` interested in the event, it creates an entry in the Event Publication Registry to track the processing of the event.
<4> The externalizing `@ApplicationModuleListener` gets triggered (note how it runs asynchronously, indicated by the `task-1` thread).
<5> Our mock `KafkaOperations` is invoked and triggers the log message simulating the actual sending.
<6> The Event Publication Registry eventually marks the publication completed as the sending has completed successfully.