Class AnnotatedAggregate<T>

java.lang.Object
org.axonframework.messaging.Scope
org.axonframework.modelling.command.AggregateLifecycle
org.axonframework.modelling.command.inspection.AnnotatedAggregate<T>
Type Parameters:
T - The type of the aggregate root object
All Implemented Interfaces:
Aggregate<T>, ApplyMore
Direct Known Subclasses:
EventSourcedAggregate

public class AnnotatedAggregate<T> extends AggregateLifecycle implements Aggregate<T>, ApplyMore
Implementation of the Aggregate interface that allows for an aggregate root to be a POJO with annotations on its Command and Event Handler methods.

This wrapper ensures that aggregate members can use the AggregateLifecycle.apply(Object) method in a static context, as long as access to the instance is done via the execute(Consumer) or invoke(Function) methods.

Since:
3.0
Author:
Allard Buijze
See Also:
  • Field Details

  • Constructor Details

    • AnnotatedAggregate

      protected AnnotatedAggregate(T aggregateRoot, AggregateModel<T> model, EventBus eventBus)
      Initialize an Aggregate instance for the given aggregateRoot, described by the given aggregateModel that will publish events to the given eventBus.
      Parameters:
      aggregateRoot - The aggregate root instance
      model - The model describing the aggregate structure
      eventBus - The Event Bus to publish generated events on
    • AnnotatedAggregate

      protected AnnotatedAggregate(T aggregateRoot, AggregateModel<T> model, EventBus eventBus, RepositoryProvider repositoryProvider)
      Initialize an Aggregate instance for the given aggregateRoot, described by the given aggregateModel that will publish events to the given eventBus.
      Parameters:
      aggregateRoot - The aggregate root instance
      model - The model describing the aggregate structure
      eventBus - The Event Bus to publish generated events on
      repositoryProvider - Provides repositories for specific aggregate types
    • AnnotatedAggregate

      protected AnnotatedAggregate(AggregateModel<T> inspector, EventBus eventBus)
      Initialize an Aggregate instance for the given aggregateRoot, described by the given aggregateModel that will publish events to the given eventBus.
      Parameters:
      inspector - The AggregateModel that describes the aggregate
      eventBus - The Event Bus to publish generated events on
    • AnnotatedAggregate

      protected AnnotatedAggregate(AggregateModel<T> inspector, EventBus eventBus, RepositoryProvider repositoryProvider)
      Initialize an Aggregate instance for the given aggregateRoot, described by the given aggregateModel that will publish events to the given eventBus.
      Parameters:
      inspector - The AggregateModel that describes the aggregate
      eventBus - The Event Bus to publish generated events on
      repositoryProvider - Provides repositories for specific aggregate types
  • Method Details

    • initialize

      public static <T> AnnotatedAggregate<T> initialize(Callable<T> aggregateFactory, AggregateModel<T> aggregateModel, EventBus eventBus) throws Exception
      Initialize an aggregate created by the given aggregateFactory which is described in the given aggregateModel. The given eventBus is used to publish events generated by the aggregate.
      Type Parameters:
      T - The type of the Aggregate root
      Parameters:
      aggregateFactory - The factory to create the aggregate root instance with
      aggregateModel - The model describing the aggregate structure
      eventBus - The EventBus to publish events on
      Returns:
      An Aggregate instance, fully initialized
      Throws:
      Exception - when an error occurs creating the aggregate root instance
    • initialize

      public static <T> AnnotatedAggregate<T> initialize(Callable<T> aggregateFactory, AggregateModel<T> aggregateModel, EventBus eventBus, RepositoryProvider repositoryProvider) throws Exception
      Initialize an aggregate created by the given aggregateFactory which is described in the given aggregateModel. The given eventBus is used to publish events generated by the aggregate.
      Type Parameters:
      T - The type of the Aggregate root
      Parameters:
      aggregateFactory - The factory to create the aggregate root instance with
      aggregateModel - The model describing the aggregate structure
      eventBus - The EventBus to publish events on
      repositoryProvider - Provides repositories for specific aggregate types
      Returns:
      An Aggregate instance, fully initialized
      Throws:
      Exception - when an error occurs creating the aggregate root instance
    • initialize

      public static <T> AnnotatedAggregate<T> initialize(Callable<T> aggregateFactory, AggregateModel<T> aggregateModel, EventBus eventBus, boolean generateSequences) throws Exception
      Initialize an aggregate created by the given aggregateFactory which is described in the given aggregateModel. The given eventBus is used to publish events generated by the aggregate.
      Type Parameters:
      T - The type of the Aggregate root
      Parameters:
      aggregateFactory - The factory to create the aggregate root instance with
      aggregateModel - The model describing the aggregate structure
      eventBus - The EventBus to publish events on
      generateSequences - Whether to generate sequence numbers on events published from this aggregate
      Returns:
      An Aggregate instance, fully initialized
      Throws:
      Exception - when an error occurs creating the aggregate root instance
    • initialize

      public static <T> AnnotatedAggregate<T> initialize(Callable<T> aggregateFactory, AggregateModel<T> aggregateModel, EventBus eventBus, RepositoryProvider repositoryProvider, boolean generateSequences) throws Exception
      Initialize an aggregate created by the given aggregateFactory which is described in the given aggregateModel. The given eventBus is used to publish events generated by the aggregate.
      Type Parameters:
      T - The type of the Aggregate root
      Parameters:
      aggregateFactory - The factory to create the aggregate root instance with
      aggregateModel - The model describing the aggregate structure
      eventBus - The EventBus to publish events on
      repositoryProvider - Provides repositories for specific aggregate types
      generateSequences - Whether to generate sequence numbers on events published from this aggregate
      Returns:
      An Aggregate instance, fully initialized
      Throws:
      Exception - when an error occurs creating the aggregate root instance
    • initialize

      public static <T> AnnotatedAggregate<T> initialize(T aggregateRoot, AggregateModel<T> aggregateModel, EventBus eventBus)
      Initialize an aggregate with the given aggregateRoot which is described in the given aggregateModel. The given eventBus is used to publish events generated by the aggregate.
      Type Parameters:
      T - The type of the Aggregate root
      Parameters:
      aggregateRoot - The aggregate root instance
      aggregateModel - The model describing the aggregate structure
      eventBus - The EventBus to publish events on
      Returns:
      An Aggregate instance, fully initialized
    • initialize

      public static <T> AnnotatedAggregate<T> initialize(T aggregateRoot, AggregateModel<T> aggregateModel, EventBus eventBus, RepositoryProvider repositoryProvider)
      Initialize an aggregate with the given aggregateRoot which is described in the given aggregateModel. The given eventBus is used to publish events generated by the aggregate.
      Type Parameters:
      T - The type of the Aggregate root
      Parameters:
      aggregateRoot - The aggregate root instance
      aggregateModel - The model describing the aggregate structure
      eventBus - The EventBus to publish events on
      repositoryProvider - Provides repositories for specific aggregate types
      Returns:
      An Aggregate instance, fully initialized
    • initSequence

      public void initSequence()
      Enable sequences on this Aggregate, causing it to emit DomainEventMessages, starting at sequence 0. Each Event applied will increase the sequence, allowing to trace each event back to the Aggregate instance that published it, in the order published.
    • initSequence

      public void initSequence(long lastKnownSequenceNumber)
      Enable sequences on this Aggregate, causing it to emit DomainEventMessages based on the given lastKnownSequenceNumber. Each Event applied will increase the sequence, allowing to trace each event back to the Aggregate instance that published it, in the order published.
      Parameters:
      lastKnownSequenceNumber - The sequence number to pass into the next event published
    • registerRoot

      protected void registerRoot(Callable<T> aggregateFactory) throws Exception
      Registers the aggregate root created by the given aggregateFactory with this aggregate. Applies any delayed events that have not been applied to the aggregate yet.

      This is method is commonly called while an aggregate is being initialized.

      Parameters:
      aggregateFactory - the factory to create the aggregate root
      Throws:
      Exception - if the aggregate factory fails to create the aggregate root
    • type

      public String type()
      Description copied from class: AggregateLifecycle
      Retrieve a String denoting the type of this Aggregate.
      Specified by:
      type in interface Aggregate<T>
      Specified by:
      type in class AggregateLifecycle
      Returns:
      a String denoting the type of this Aggregate
    • identifier

      public Object identifier()
      Description copied from class: AggregateLifecycle
      Retrieve a Object denoting the identifier of this Aggregate.
      Specified by:
      identifier in interface Aggregate<T>
      Specified by:
      identifier in class AggregateLifecycle
      Returns:
      a Object denoting the identifier of this Aggregate
    • version

      public Long version()
      Description copied from class: AggregateLifecycle
      Gets the version of the aggregate.
      Specified by:
      version in interface Aggregate<T>
      Specified by:
      version in class AggregateLifecycle
      Returns:
      the current version of the aggregate
    • lastSequence

      public Long lastSequence()
      Returns the last sequence of any event published, or null if no events have been published yet. If sequences aren't enabled for this Aggregate, the this method will also return null;
      Returns:
      the last sequence of any event published, or null if no events have been published yet
    • getIsLive

      protected boolean getIsLive()
      Description copied from class: AggregateLifecycle
      Indicates whether this Aggregate instance is 'live'. This means events currently applied represent events that are currently happening, as opposed to events representing historic decisions.
      Specified by:
      getIsLive in class AggregateLifecycle
      Returns:
      true if the aggregate is 'live', false if the aggregate is initializing state based on historic events
    • doCreateNew

      protected <R> Aggregate<R> doCreateNew(Class<R> aggregateType, Callable<R> factoryMethod) throws Exception
      Description copied from class: AggregateLifecycle
      Creates a new aggregate instance. In order for new aggregate to be created, a Repository should be available to the current aggregate. Repository of an aggregate to be created is exposed to the current aggregate via RepositoryProvider.
      Specified by:
      doCreateNew in class AggregateLifecycle
      Type Parameters:
      R - type of new aggregate to be created
      Parameters:
      aggregateType - type of new aggregate to be created
      factoryMethod - factory method which creates new aggregate
      Returns:
      a new aggregate instance
      Throws:
      Exception - thrown if something goes wrong during instantiation of new aggregate
    • invoke

      public <R> R invoke(Function<T,R> invocation)
      Description copied from interface: Aggregate
      Invoke a method on the underlying aggregate root or one of its instances. Use this over Aggregate.execute(Consumer) to obtain an invocation result, for instance in order to query the aggregate.

      Note that the use of this method is not recommended as aggregates are not meant to be queried. Relying on this method is commonly a sign of design smell.

      Specified by:
      invoke in interface Aggregate<T>
      Type Parameters:
      R - The type of the result produced by the given invocation
      Parameters:
      invocation - The function that performs the actual invocation
      Returns:
      The invocation result
    • execute

      public void execute(Consumer<T> invocation)
      Description copied from interface: Aggregate
      Execute a method on the underlying aggregate or one of its instances.

      Note that the use of this method is not recommended as the wrapped aggregate instance is not meant to be exposed. Relying on this method is commonly a sign of design smell.

      Specified by:
      execute in interface Aggregate<T>
      Parameters:
      invocation - The function that performs the invocation
    • isDeleted

      public boolean isDeleted()
      Description copied from interface: Aggregate
      Check if this aggregate has been deleted. This is checked by aggregate repositories when an aggregate is loaded. In case the repository is asked to load a deleted aggregate the repository will refuse by throwing an AggregateDeletedException.
      Specified by:
      isDeleted in interface Aggregate<T>
      Returns:
      true in case the aggregate was deleted, false otherwise
    • rootType

      public Class<? extends T> rootType()
      Description copied from interface: Aggregate
      Get the class type of the wrapped aggregate root that the Aggregate defers to for command handling.
      Specified by:
      rootType in interface Aggregate<T>
      Returns:
      The aggregate root type
    • doMarkDeleted

      protected void doMarkDeleted()
      Description copied from class: AggregateLifecycle
      Marks this aggregate as deleted. Implementations may react differently to aggregates marked for deletion. Typically, Event Sourced Repositories will ignore the marking and expect deletion to be provided as part of Event information.
      Specified by:
      doMarkDeleted in class AggregateLifecycle
    • publish

      protected void publish(EventMessage<?> msg)
      Publish an event to the aggregate root and its entities first and external event handlers (using the given event bus) later.
      Parameters:
      msg - the event message to publish
    • publishOnEventBus

      protected void publishOnEventBus(EventMessage<?> msg)
      Publish an event to external event handlers using the given event bus.
      Parameters:
      msg - the event message to publish
    • handle

      public Object handle(Message<?> message) throws Exception
      Description copied from interface: Aggregate
      Handle the given message on the aggregate root or one of its child entities.
      Specified by:
      handle in interface Aggregate<T>
      Parameters:
      message - The message to be handled by the aggregate
      Returns:
      The result of message handling. Might returns null if for example handling a CommandMessage yields no results
      Throws:
      Exception - in case one is triggered during message processing
    • doApply

      protected <P> ApplyMore doApply(P payload, MetaData metaData)
      Description copied from class: AggregateLifecycle
      Apply a DomainEventMessage with given payload and metadata (metadata from interceptors will be combined with the provided metadata). The event should be applied to the aggregate immediately and scheduled for publication to other event handlers.

      The event should be applied on all entities part of this aggregate. If the event is applied from an event handler of the aggregate and additional events need to be applied that depends on state changes brought about by the first event the returned ApplyMore instance should allow for additional events to be applied after this event.

      Specified by:
      doApply in class AggregateLifecycle
      Parameters:
      payload - the payload of the event to apply
      metaData - any meta-data that must be registered with the Event
      Returns:
      a gizmo to apply additional events after the given event has been processed by the entire aggregate
      See Also:
    • createMessage

      protected <P> EventMessage<P> createMessage(P payload, MetaData metaData)
      Creates an EventMessage with given payload and metaData.
      Type Parameters:
      P - the payload type
      Parameters:
      payload - payload of the resulting message
      metaData - metadata of the resulting message
      Returns:
      the resulting message
    • getAggregateRoot

      public T getAggregateRoot()
      Get the annotated aggregate instance. Note that this method should probably never be used in normal use. If you need to operate on the aggregate use invoke(Function) or execute(Consumer) instead.
      Returns:
      the aggregate instance
    • andThenApply

      public ApplyMore andThenApply(Supplier<?> payloadOrMessageSupplier)
      Description copied from interface: ApplyMore
      Apply a subsequent event to the aggregate after applying another event. When the given payloadOrMessageSupplier is asked to provide the subsequent event the initial event has been fully processed by the aggregate.

      If the given supplier passes an object that is an instance of a Message the event is applied with the metadata from the message. If the supplied event is not a Message instance it will be applied as an event without additional metadata.

      Specified by:
      andThenApply in interface ApplyMore
      Parameters:
      payloadOrMessageSupplier - The next event message or the payload of the next event
      Returns:
      an instance of ApplyMore to apply any subsequent events
    • andThen

      public ApplyMore andThen(Runnable runnable)
      Description copied from interface: ApplyMore
      Execute the given runnable after applying the previous event. This runnable is guaranteed to be invoked when the previous event has been fully applied to the aggregate.

      The given runnable must not directly alter any state of the aggregate. Instead, it should only decide if more events should be applied based on the state of the aggregate after the previous event

      Specified by:
      andThen in interface ApplyMore
      Parameters:
      runnable - the code to execute when the previous event was applied
      Returns:
      an instance of ApplyMore to apply any subsequent events
    • applyMessageOrPayload

      protected void applyMessageOrPayload(Object payloadOrMessage)
      Apply a new event message to the aggregate and then publish this message to external systems. If the given payloadOrMessage is an instance of a Message an event message is applied with the payload and metadata of the given message, otherwise an event message is applied with given payload and empty metadata.
      Parameters:
      payloadOrMessage - defines the payload and optionally metadata to apply to the aggregate