This version is still in development and is not considered stable yet. For the latest stable version, please use Spring Integration 7.0.2!

CloudEvents Support

Spring Integration provides support for the CloudEvents specification.

Add the following dependency to your project:

  • Maven

  • Gradle

<dependency>
    <groupId>org.springframework.integration</groupId>
    <artifactId>spring-integration-cloudevents</artifactId>
    <version>7.1.0-M1</version>
</dependency>
implementation "org.springframework.integration:spring-integration-cloudevents:7.1.0-M1"

ToCloudEventTransformer

Use the ToCloudEventTransformer to convert Spring Integration messages into CloudEvents-compliant messages. This transformer supports the CloudEvents specification v1.0 and serializes CloudEvents if an EventFormat or eventFormatContentTypeExpression is specified. When you specify an EventFormat or eventFormatContentTypeExpression, the transformer uses the EventFormat to generate the CloudEvent in the payload. If neither is specified, the transformer writes the event data message payload as-is and adds attributes as well as extensions to the message headers. The transformer supports defining attributes using expressions and identifies extensions in the message headers via patterns.

Attribute Expressions

Set the CloudEvents' attributes of id, source, type, dataSchema, and subject through SpEL expressions.

The transformer sets the time attribute to the time when it creates the CloudEvent instance.

The following table lists the attribute names and the values the default expressions return.

Attribute Name Default Value

id

The id of the message.

source

A prefix of "/spring/" followed by the appName, a period, and then the name of the transformer’s bean, e.g., /spring/myapp.toCloudEventTransformerBean.

type

"spring.message"

dataContentType

The contentType of the message, defaults to application/octet-stream. Some other examples include, but are not limited to: application/json, application/x-avro, and application/xml.

dataSchema

The URI to the specified schema. The default for dataSchema is null.

subject

This attribute identifies the subject of the event in the context of the event producer. The default for subject is null.

time

The time the CloudEvent message is created. Set internally to the current time. Note that you cannot configure this value.

Extension Patterns

Use the extensionPatterns constructor parameter (a vararg of strings) to specify pattern matching with wildcards (*). The transformer includes message headers with keys matching any pattern as CloudEvent extensions. Use a ! prefix to explicitly exclude headers through negation. Note that the first matching pattern wins (whether positive or negative).

For example, configure patterns "trace*", "span-id", "user-id" to: - Include headers starting with trace (e.g., trace-id, traceparent) - Include headers with exact keys span-id and user-id - Add all matching headers as extensions to the CloudEvent

To exclude specific headers, use negated patterns: "custom-*", "!custom-internal" includes all headers starting with custom- except custom-internal.

Configuration with DSL

Add the CloudEvent transformer to flows using the DSL:

@Bean
public ToCloudEventTransformer cloudEventTransformer() {
    return new ToCloudEventTransformer("trace*", "correlation-id");
}

@Bean
public IntegrationFlow cloudEventTransformFlow(ToCloudEventTransformer toCloudEventTransformer) {
    return IntegrationFlows
        .from("inputChannel")
        .transform(toCloudEventTransformer)
        .channel("outputChannel")
        .get();
}

CloudEvent Transformer Process

Understand the transformation process:

  1. CloudEvent Building: Build the CloudEvent attributes.

  2. Extension Extraction: Build the CloudEvent extensions using the array of extensionPatterns passed into the constructor.

  3. Format Conversion: Apply the specified EventFormat or, if not set, handle the conversion via Binary Format Mode.

A basic transformation may have the following pattern:

// Input message with headers
Message<byte[]> inputMessage = MessageBuilder
    .withPayload("Hello CloudEvents".getBytes(StandardCharsets.UTF_8))
    .withHeader(MessageHeaders.CONTENT_TYPE, "text/plain")
    .build();

ToCloudEventTransformer transformer = new ToCloudEventTransformer();

// Transform to CloudEvent
Object cloudEventMessage = transformer.transform(inputMessage);

EventFormats

The ToCloudEventTransformer will use formatting to serialize the CloudEvent into the message’s payload when the EventFormat is available, or use Binary Format Mode otherwise. Set the EventFormat in one of two ways:

  1. Set the desired EventFormat.

  2. Set the eventFormatContentTypeExpression with an expression that resolves to a content type that EventFormatProvider can use to provide the required EventFormat. When the eventFormatContentTypeExpression is set and the EventFormatProvider returns null because it cannot find the EventFormat for the content type, the transformer throws a MessageTransformationException. Examples of content types that the eventFormatContentTypeExpression can resolve to that are accepted by the EventFormatProvider are:

    • application/cloudevents+json

    • application/cloudevents+xml

If the EventFormat and the eventFormatContentTypeExpression are not set, the transformer adds cloud event attributes and extensions to the message headers with the cloud event prefix (default is ce-) and leaves the payload unchanged (Binary Format Mode).

To utilize a specific EventFormat, add the associated dependency. For example, to add the XML EventFormat, add the following dependency: io.cloudevents:cloudevents-xml. See the CloudEvents Java Reference Documentation for information on the event formats that are available.

Ensure messages to be transformed to CloudEvents have a payload of type byte[]. The transformer throws an IllegalArgumentException if the payload is not a byte array.