Class AnnotatedSaga<T>
- All Implemented Interfaces:
DescribableComponent,MessageHandler,EventHandler,EventHandlingComponent,ReplayStatusChangedHandler,ResetHandler,Saga<T>,SagaLifecycle
interface that allows for a POJO instance with annotated message handlers to act
as a Saga. The POJO instance can access SagaLifecycle operations, such as
associateWith and end, by declaring
a SagaLifecycle-typed parameter on its @SagaEventHandler method. This
AnnotatedSaga instance registers itself as the active SagaLifecycle on the ProcessingContext
for the duration of a single event handler invocation, so the parameter always resolves to this instance.
A @SagaEventHandler method must complete on the thread that invoked it. Returning a result
that is not done yet fails handling with a SagaExecutionException, because the Saga is stored in the
invoking thread's transaction and work continuing on another thread would fall outside it. Axon Framework 4 had no
way to express an asynchronous handler at all, so nothing that worked there is refused here.
While a handler method runs, this Saga is the current Scope, as it was in Axon Framework 4. Code reached
from the handler on the same thread, such as a DeadlineManager, can therefore describe the Saga through
Scope.describeCurrentScope() and reach the handler's ProcessingContext through
ContextAwareScope.currentProcessingContext(), without being handed either of them.
- Since:
- 3.0
- Author:
- Allard Buijze
-
Field Summary
Fields inherited from interface org.axonframework.modelling.saga.SagaLifecycle
RESOURCE_KEY -
Constructor Summary
ConstructorsConstructorDescriptionAnnotatedSaga(String sagaId, Set<AssociationValue> associationValues, T annotatedSaga, SagaModel<T> metaModel, MessageHandlerInterceptorMemberChain<T> chainedInterceptor) Creates an AnnotatedSaga instance to wrap the givenannotatedSaga, identifier with the givensagaIdand associated with the givenassociationValues. -
Method Summary
Modifier and TypeMethodDescriptionvoidassociateWith(AssociationValue associationValue) Registers the givenassociationValuewith the current Saga.Retrieves theAssociationValuesthat have been associated with the current Saga so far.booleancanHandle(EventMessage event, ProcessingContext context) Indicates whether this saga instance takes the givenevent, which is the case when it isactiveand holds theAssociationValuethat one of its handlers for this event resolves from it.voiddescribeTo(ComponentDescriptor descriptor) Describe the properties ofthis DescribableComponentwith the givendescriptor.voidend()Marks the saga as ended.voidExecute the giveninvocationagainst the root object of this Saga instance.Returns a view on the Association Values for this saga instance.Returns the unique identifier of this saga.handle(EventMessage event, ProcessingContext context) Handles the giveneventwithin the givencontext.<R> RExecute the giveninvocationagainst the root object of this Saga instance.booleanisActive()Indicates whether or not this saga is active.voidremoveAssociationWith(AssociationValue associationValue) Removes the givenassociationValuefrom the current Saga.root()Returns the (annotated) Saga instance.All supportedevents, referenced through aQualifiedName.Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface org.axonframework.messaging.eventhandling.EventHandlingComponent
handle, supports, unwrapMethods inherited from interface org.axonframework.modelling.saga.Saga
handle, sequenceIdentifierFor, supportsResetMethods inherited from interface org.axonframework.modelling.saga.SagaLifecycle
associateWith, associateWith, removeAssociationWith, removeAssociationWith
-
Constructor Details
-
AnnotatedSaga
public AnnotatedSaga(String sagaId, Set<AssociationValue> associationValues, T annotatedSaga, SagaModel<T> metaModel, MessageHandlerInterceptorMemberChain<T> chainedInterceptor) Creates an AnnotatedSaga instance to wrap the givenannotatedSaga, identifier with the givensagaIdand associated with the givenassociationValues. ThemetaModelprovides the description of the structure of the Saga.- Parameters:
sagaId- The identifier of this Saga instanceassociationValues- The current associations of this SagaannotatedSaga- The object instance representing the SagametaModel- The model describing Saga structurechainedInterceptor- The interceptor to be used for this Saga
-
-
Method Details
-
getSagaIdentifier
Description copied from interface:SagaReturns the unique identifier of this saga.- Specified by:
getSagaIdentifierin interfaceSaga<T>- Returns:
- the unique identifier of this saga
-
getAssociationValues
Description copied from interface:SagaReturns a view on the Association Values for this saga instance. The returned instance is mutable.- Specified by:
getAssociationValuesin interfaceSaga<T>- Returns:
- a view on the Association Values for this saga instance
-
invoke
Description copied from interface:SagaExecute the giveninvocationagainst the root object of this Saga instance. -
execute
Description copied from interface:SagaExecute the giveninvocationagainst the root object of this Saga instance. -
isActive
public boolean isActive()Description copied from interface:SagaIndicates whether or not this saga is active. A Saga is active when its life cycle has not been ended. -
supportedEvents
Description copied from interface:EventHandlingComponentAll supportedevents, referenced through aQualifiedName.- Specified by:
supportedEventsin interfaceEventHandlingComponent- Returns:
- All supported
events, referenced through aQualifiedName.
-
canHandle
Description copied from interface:SagaIndicates whether this saga instance takes the givenevent, which is the case when it isactiveand holds theAssociationValuethat one of its handlers for this event resolves from it.This answers a different question than
EventHandlingComponent.supports(org.axonframework.messaging.core.QualifiedName), which reports the events the saga type declares handlers for. Two saga instances of the same type therefore disagree here whenever they are associated with different values, and the component managing them needs that answer: a Saga that declines the event has not taken it, so aSagaCreationPolicy.IF_NONE_FOUNDpolicy must still start a new instance. The returnedMessageStreamcannot express it, since a Saga that declines and a Saga that handled the event without producing anything both yield an empty stream.In Axon Framework 4 this method was inherited from
MessageHandler, which Axon Framework 5 reduced to a marker interface, so the declaration lives here instead.- Specified by:
canHandlein interfaceSaga<T>- Parameters:
event- the event to check this saga instance againstcontext- theProcessingContextin which the event is being processed- Returns:
truewhen this saga instance takes the givenevent,falseotherwise
-
handle
Description copied from interface:EventHandler- Specified by:
handlein interfaceEventHandler- Parameters:
event- The event to handle.context- The context to the giveneventis handled in.- Returns:
- An
empty streamcontaining nothing.
-
root
Returns the (annotated) Saga instance.- Returns:
- the Saga instance
-
associateWith
Description copied from interface:SagaLifecycleRegisters the givenassociationValuewith the current Saga. When the saga is committed, it can be found using the registered property. If the saga already has the given association, nothing happens.- Specified by:
associateWithin interfaceSagaLifecycle- Parameters:
associationValue- the association to associate this saga with
-
removeAssociationWith
Description copied from interface:SagaLifecycleRemoves the givenassociationValuefrom the current Saga. When the saga is committed, it can no longer be found using the given association value. If the given saga wasn't associated with the given value, nothing happens.- Specified by:
removeAssociationWithin interfaceSagaLifecycle- Parameters:
associationValue- the association value to remove from this saga
-
end
public void end()Description copied from interface:SagaLifecycleMarks the saga as ended. Ended sagas may be cleaned up by the repository when they are committed.- Specified by:
endin interfaceSagaLifecycle
-
associationValues
Description copied from interface:SagaLifecycleRetrieves theAssociationValuesthat have been associated with the current Saga so far. This includes the uncommitted ones, so adding or removing anAssociationValuethroughSagaLifecycle.associateWith(AssociationValue)or any other method will have an immediate effect.- Specified by:
associationValuesin interfaceSagaLifecycle- Returns:
- the
AssociationValuesthat have been associated with the Saga so far
-
describeTo
Description copied from interface:DescribableComponentDescribe the properties ofthis DescribableComponentwith the givendescriptor.Components should call the appropriate
describePropertymethods on the descriptor to register their properties. The descriptor is responsible for determining how these properties are formatted and structured in the final output.Best Practices: As a general rule, all relevant fields of a
DescribableComponentimplementation should be described in this method. However, developers have discretion to include only the fields that make sense in the context. Not every field may be meaningful for description purposes, especially internal implementation details. Furthermore, components might want to expose different information based on their current state. The final decision on what properties to include lies with the person implementing thedescribeTomethod, who should focus on providing information that is useful for understanding the component's configuration and state.Example implementation:
public void describeTo(ComponentDescriptor descriptor) { descriptor.describeProperty("name", this.name); descriptor.describeProperty("enabled", this.enabled); descriptor.describeProperty("configuration", this.configuration); // A nested component descriptor.describeProperty("handlers", this.eventHandlers); // A collection }- Specified by:
describeToin interfaceDescribableComponent- Parameters:
descriptor- The component descriptor to describethis DescribableComponentn its properties in.
-