Class MigrateAggregateDeadlineHandler
- All Implemented Interfaces:
Cloneable
@DeadlineHandler of an aggregate with the Axon Framework 4
@CommandHandler that receives the deadline once it fires.
On the Axoniq Framework legacy module, a deadline scheduled for an aggregate scope fires as a command named
<aggregateType>.<deadlineName>, carrying the deadline's payload, or the deadline name when it has none. The
aggregate type is the one Axon Framework 4 stored with the deadline: the type of the aggregate's
@AggregateRoot or @Aggregate annotation, or its simple class name otherwise. The recipe replaces
a handler with a deadlineName with @CommandHandler(commandName = "<aggregateType>.<deadlineName>"),
keeping its parameters and any payloadType. A handler without a payload keeps receiving the deadline
without one, whether or not the deadline carries a payload, as the command name alone routes it. A deadline name
given as a constant is resolved over all sources.
A handler without a deadlineName received every deadline with its payload type in Axon Framework 4. The
recipe replaces it with a @CommandHandler without a commandName, which receives the command named
after that payload type. The legacy module dispatches a deadline under that name when no handler receives the
command named after the deadline, logging a warning, so the handler keeps receiving every deadline with its payload
type. A // TODO(axon4to5): marker asks to name the command after the deadline instead.
The recipe uses the Axon Framework 4 @CommandHandler on purpose: the Axon Framework 5 upgrade that runs
afterwards moves it to the Axon Framework 5 package and migrates the handler like any other aggregate command
handler. The deadline payload class is left untouched, since the target entity is resolved from the deadline's
aggregate scope.
Where the recipe cannot name the command, it leaves a // TODO(axon4to5): marker and keeps the
@DeadlineHandler:
- a handler that names neither a deadline nor a payload type handled every deadline of the aggregate, and a
handler without a deadline name whose payload type is
Object, an interface or an abstract class handled every deadline with a payload of that type; - a handler without a deadline name whose payload type another
@CommandHandlerof the class handles, which a deadline dispatched under that payload type would reach instead; - a deadline name or aggregate type given as an expression that is no literal or resolvable constant;
- a handler in a subclass of an annotated aggregate class: Axon Framework 4 stored the type of the polymorphic aggregate's root, which the subclass does not declare;
- a handler in an unannotated class that is abstract or extended by another class of the sources: Axon Framework 4 stored the type of the aggregate extending it;
- a handler of a member entity: Axon Framework 4 delivered a fired deadline to the aggregate root and to every member entity, while a command reaches an entity in a collection only through a routing key.
DeadlineMessage parameter, which does not match the command message that now arrives.
The recipe rewrites Java and Kotlin aggregates. Saga classes, which keep their @DeadlineHandler on the
legacy module, are left alone. The recipe is idempotent.
- Since:
- 5.4.0
- Author:
- Mateusz Nowak
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic classWhat the scanning phase learns about the source classes.Nested classes/interfaces inherited from class org.openrewrite.Recipe
org.openrewrite.Recipe.Builder, org.openrewrite.Recipe.DelegatingRecipe -
Field Summary
Fields inherited from class org.openrewrite.Recipe
contributors, examples, PANIC -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptiongetInitialValue(org.openrewrite.ExecutionContext ctx) org.openrewrite.TreeVisitor<?, org.openrewrite.ExecutionContext> org.openrewrite.TreeVisitor<?, org.openrewrite.ExecutionContext> Methods inherited from class org.openrewrite.ScanningRecipe
clone, generate, generate, getAccumulator, getVisitorMethods inherited from class org.openrewrite.Recipe
addDataTable, aggregateDataTableDescriptors, builder, buildRecipeList, causesAnotherCycle, createRecipeDescriptor, equals, getContributors, getDataTableDescriptors, getDescriptor, getEstimatedEffortPerOccurrence, getExamples, getInstanceName, getInstanceNameSuffix, getJacksonPolymorphicTypeTag, getMaintainers, getName, getRecipeList, getTags, hashCode, maxCycles, noop, onComplete, run, run, run, setContributors, setExamples, validate, validate, validateAll, validateAll, withOptions
-
Constructor Details
-
MigrateAggregateDeadlineHandler
public MigrateAggregateDeadlineHandler()
-
-
Method Details
-
getDisplayName
- Specified by:
getDisplayNamein classorg.openrewrite.Recipe
-
getDescription
- Specified by:
getDescriptionin classorg.openrewrite.Recipe
-
getInitialValue
public MigrateAggregateDeadlineHandler.Accumulator getInitialValue(org.openrewrite.ExecutionContext ctx) - Specified by:
getInitialValuein classorg.openrewrite.ScanningRecipe<MigrateAggregateDeadlineHandler.Accumulator>
-
getScanner
public org.openrewrite.TreeVisitor<?,org.openrewrite.ExecutionContext> getScanner(MigrateAggregateDeadlineHandler.Accumulator acc) - Specified by:
getScannerin classorg.openrewrite.ScanningRecipe<MigrateAggregateDeadlineHandler.Accumulator>
-
getVisitor
public org.openrewrite.TreeVisitor<?,org.openrewrite.ExecutionContext> getVisitor(MigrateAggregateDeadlineHandler.Accumulator acc) - Overrides:
getVisitorin classorg.openrewrite.ScanningRecipe<MigrateAggregateDeadlineHandler.Accumulator>
-