Interface EventTransformation
- All Superinterfaces:
MessageTransformation<EventMessage>
MessageTransformation describing how stored events of one MessageType are
rewritten into another when they are read. A transformation is a 1:1 payload mapping, a pure rename, a 1:N split,
or a 1:0 drop.
A mapping is built through one of two from paths, each continuing with to(...) to declare the
resulting identity and transform(...) to supply the payload mapper:
- Concrete (
from(MessageType)): matches a sourceMessageTypeby exact equality. The source type is known up front. Prefer this path whenever the source identities are known, registering one transformation per version step. Exact matches are resolved by a constant-time identity lookup and let the chain widen read criteria to precisely those source types, so they impose no per-event scanning cost. - Predicate-based (
from(Predicate)): matches everyMessageTypefor which the supplied predicate returnstrue. Reach for this only when the source identities cannot be enumerated up front: each predicate is evaluated against non-exact events in registration order, a per-event cost that grows with the number of predicates, and the widened read criteria are necessarily broader than the concrete path's. Both can carry a significant performance penalty.
rename(MessageType, MessageType): it leaves the payload unchanged and, unlike
the mapping paths, may change the QualifiedName rather than only the version. A 1:N split is built with
split(MessageType, Class): a matched event is replaced by the declared outputs, each pairing a produced
identity with the mapper deriving its payload, delivered in declaration order at the input's stream position. A
drop is built with drop(MessageType): matched events are removed from the read stream while their stream
position is still advanced.
// Concrete mapping: rewrite a single, known source type.
EventTransformation.from(new MessageType("com.example.CourseCreated", "1.0.0"))
.to(new MessageType("com.example.CourseCreated", "2.0.0"))
.transform(String.class, (payload, context) -> payload);
// Predicate-based mapping: match many source types, declaring them so reads stay type-filtered.
EventTransformation.from(type -> "1.0.0".equals(type.version()))
.declaringFromTypes(new QualifiedName("com.example.CourseCreated"))
.to(new MessageType("com.example.CourseCreated", "2.0.0"))
.transform(String.class, (payload, context) -> payload);
// Pure rename: same payload, new identity.
EventTransformation.rename(new MessageType("com.example.CourseCreated", "1.0.0"),
new MessageType("com.example.CourseRegistered", "1.0.0"));
// Split: replace one event with several, pairing each produced identity with its payload mapper.
EventTransformation.split(new MessageType("com.example.StudentEnrolledAndCourseUpdated", "1.0.0"), Combined.class)
.producing(new MessageType("com.example.StudentEnrolled", "1.0.0"),
payload -> payload.enrollment())
.producing(new MessageType("com.example.CourseCapacityUpdated", "1.0.0"),
payload -> payload.capacity())
.build();
// Drop: remove matched events from the read stream.
EventTransformation.drop(new MessageType("com.example.CourseCreated", "1.0.0"));
Why the declared from types matter. When entities are sourced, read criteria are widened so a
query for the to type also returns events still stored under the from type(s) this transformation
rewrites. For the concrete path the source type is always known. For the predicate path the matched types cannot
be enumerated, so the source types must be declared explicitly through
EventTransformation.PredicateFromStep.declaringFromTypes(QualifiedName...). Declaring an incomplete set means a read for the
to type is not widened to the omitted types, leaving entities without events they expect to receive.
Omitting declaringFromTypes entirely is the safe fallback: the read's type filter is dropped for that
target, and matching falls back to tags, broader but never missing events.
- Since:
- 5.2.0
- Author:
- Laura Devriendt
-
Nested Class Summary
Nested ClassesModifier and TypeInterfaceDescriptionstatic final classContinuation offrom(Predicate); optionally restricts the predicate match to a set of declaredfromtype names beforeto(...)is supplied.static final classContinuation ofsplit(MessageType, Class)/split(MessageType, TypeReference).static final classstatic final classContinuation offrom(...).to(...); supplies the payload mapper. -
Field Summary
Fields -
Method Summary
Modifier and TypeMethodDescriptionstatic EventTransformationdrop(MessageType source) Drop events of identitysourcefrom the read stream, so no handler receives them.from(Predicate<MessageType> sourcePredicate) Begin a 1:1 transformation matching anyMessageTypefor which the supplied predicate returnstrue.static EventTransformation.ToStepfrom(MessageType source) Begin a 1:1 transformation matching the givenfromidentity by exact equality.matcher()Thefrom-side matcher selecting the events this transformation applies to.static EventTransformationrename(MessageType source, MessageType target) Create a pure rename of events fromsourcetotarget, leaving the payload unchanged.static <T> EventTransformation.SplitStep<T> split(MessageType source, Class<T> inputType) Begin a 1:N split of events matchingsourceby exact equality.static <T> EventTransformation.SplitStep<T> split(MessageType source, TypeReference<T> inputType) Generic-type overload ofsplit(MessageType, Class).Methods inherited from interface io.axoniq.framework.messaging.transformation.MessageTransformation
transform
-
Field Details
-
SOURCE_NOT_NULL
Error message for when the source is null.- See Also:
-
TARGET_NOT_NULL
Error message for when the target is null.- See Also:
-
-
Method Details
-
from
Begin a 1:1 transformation matching the givenfromidentity by exact equality. Continue withto(...)thentransform(...).- Parameters:
source- thefromidentity- Returns:
- a builder awaiting
to(...)
-
from
Begin a 1:1 transformation matching anyMessageTypefor which the supplied predicate returnstrue. Optionally restrict the match to specificfromtype names viaEventTransformation.PredicateFromStep.declaringFromTypes(QualifiedName...), then continue withto(...).- Parameters:
sourcePredicate- the matcher- Returns:
- a builder optionally restricting the match before awaiting
to(...)
-
rename
Create a pure rename of events fromsourcetotarget, leaving the payload unchanged. Unlikefrom(MessageType), a rename may change theQualifiedName, not only the version.- Parameters:
source- thefromidentity to matchtarget- thetoidentity applied to the output- Returns:
- the completed rename
EventTransformation, ready to register without further builder steps - Throws:
IllegalArgumentException- ifsourceandtargetare identical
-
split
Begin a 1:N split of events matchingsourceby exact equality. The stored payload is converted toinputTypeonce, then each output declared viaEventTransformation.SplitStep.producing(MessageType, Function)is derived from that converted payload. Finish withEventTransformation.SplitStep.build().- Type Parameters:
T- input payload type- Parameters:
source- thefromidentity to splitinputType- the type the stored payload is converted to before the output mappers are invoked- Returns:
- a builder awaiting one or more
producing(...)declarations
-
split
Generic-type overload ofsplit(MessageType, Class). Use this wheninputTypecarries type parameters (e.g.Map<String, Object>,List<Foo>).- Type Parameters:
T- input payload type- Parameters:
source- thefromidentity to splitinputType- theTypeReferencethe stored payload is converted to- Returns:
- a builder awaiting one or more
producing(...)declarations
-
drop
Drop events of identitysourcefrom the read stream, so no handler receives them. A dropped event's stream position is still advanced, so a streaming processor resumes after it rather than reprocessing it.- Parameters:
source- the identity to drop- Returns:
- a completed drop
EventTransformation, ready to register without further builder steps
-
matcher
Thefrom-side matcher selecting the events this transformation applies to. The chain's lookup uses this; the declaredtoidentity, if any, is variant-specific and not part of this contract.- Returns:
- the
from-side matcher
-