Skip to content

ZenWave360/spring-modulith-events-spring-cloud-stream

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Spring-Modulith Events Externalizer for Spring Cloud Stream

Maven Central build coverage branches coverage GitHub

Spring-Modulith Events Externalizer that uses Spring Cloud Stream supporting both JSON and Avro serialization formats.

Check out the blog post here: https://www.zenwave360.io/posts/Spring-Modulith-Events-Spring-Cloud-Stream-Externalizer/ Companion sample project: https://github.com/EDALearn/EDA-TransactionalOutbox-Modulith-JPA

Getting Started

Dependency

Add the following Maven dependency to your project:

<dependency>
    <groupId>io.zenwave360.sdk</groupId>
    <artifactId>spring-modulith-events-scs</artifactId>
    <version>${spring-modulith-events-scs.version}</version>
</dependency>

Versions

This project was built and tested with the following versions:

spring-modulith-events-scs Spring Modulith Spring Boot Spring Cloud SCSt Schema
1.0.x 1.4.x 3.4.x 2024.0.0 2.2.1.RELEASE
1.1.x 2.0.x 4.0.x 2025.1.0 2.2.1.RELEASE

Configuration

Use @EnableSpringCloudStreamEventExternalization annotation to enable Spring Cloud Stream event externalization in your Spring configuration:

@Configuration
@EnableSpringCloudStreamEventExternalization
public class SpringCloudStreamEventsConfig {
    // Additional configurations (if needed)
}

This configuration ensures that, in addition to events annotated with @Externalized, all events of type org.springframework.messaging.Message with a header named SpringCloudStreamEventExternalizer.SPRING_CLOUD_STREAM_EVENT_HEADER will be externalized and routed to their specified destination using the value of this header as the routing target.

If using Spring-Boot 4, you need to either provide a com.fasterxml.jackson.databind.ObjectMapper bean or add org.springframework.boot:spring-boot-jackson2 as dependency.


Event Serialization

Using the transactional event publication log requires serializing events to a format that can be stored in a database. Since the generic type of Message<?> payload is lost when using the default JacksonEventSerializer, this library adds an extra _class field to preserve payload type information, allowing for complete deserialization to its original type.

This library provides support for POJO (JSON) and Avro serialization formats for Message<?> payloads.

Avro Serialization

Avro serialization needs com.fasterxml.jackson.dataformat.avro.AvroMapper class present in the classpath. In order to use Avro serialization, you need to add the following dependency to your project:

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-avro</artifactId>
</dependency>

Routing Events

Programmatic Routing for Message<?> events

You can define routing targets programmatically using a Message header:

public class CustomerEventsProducer implements ICustomerEventsProducer {

    private final ApplicationEventPublisher applicationEventPublisher;

    public void onCustomerCreated(CustomerCreated event) {
        Message<CustomerCreated> message = MessageBuilder.withPayload(event)
                .setHeader(
                        SpringCloudStreamEventExternalizer.SPRING_CLOUD_STREAM_SENDTO_DESTINATION_HEADER, 
                        "customer-created") // <- target binding name
                .build();
        applicationEventPublisher.publishEvent(message);
    }
}

Annotation-Based Routing for POJO Events

Leverage the @Externalized annotation to define the target binding name and routing key:

@Externalized("customer-created::#{#this.getLastname()}")
class CustomerCreated {

    public String getLastname() {
        // Return the customer's last name
    }
}

Configure Spring Cloud Stream destination

Configure Spring Cloud Stream destination for your bindings as usual in application.yml:

spring:
  cloud:
    stream:
      bindings:
        customer-created:
          destination: customer-created-topic

Routing Key

SpringCloudStreamEventExternalizer dynamically sets the appropriate Message header (e.g., kafka_messageKey or rabbit_routingKey) from your routing key based on the channel binder type, if the routing header is not already present.

  • KafkaMessageChannelBinder: kafka_messageKey
  • RabbitMessageChannelBinder: rabbit_routingKey
  • KinesisMessageChannelBinder: partitionKey
  • PubSubMessageChannelBinder: pubsub_orderingKey
  • EventHubsMessageChannelBinder: partitionKey
  • SolaceMessageChannelBinder: solace_messageKey
  • PulsarMessageChannelBinder: pulsar_key

Using Snapshot Versions

In order to test snapshot versions of this library, add the following repository to your Maven configuration:

<repository>
    <id>maven-snapshots</id>
    <url>https://central.sonatype.com/repository/maven-snapshots</url>
    <snapshots>
        <enabled>true</enabled>
    </snapshots>
</repository>

Packages

No packages published

Contributors 2

  •  
  •  

Languages