### Event Sourcing

code

docs

tests

The Event Sourcing Library supports generating, storing and replaying two types of events: application-events and domain-events.

Application events are bound to Usecase and are produced by execution of specific methods (ones with `ApplicationEvent` as their first parameter). Each application event holds information about Usecase, method name and JSON serialized values of method parameters.

Domain events are bound to entity instances and are produced by execution of annotated (see `@DomainEvent`) methods that belongs to `EntityComposite`. Each domain event (see `DomainEventValue`) holds information about entity type, identity, method name and JSON serialized values of method parameters.

Both application and domain events are captured during `UnitOfWork` lifetime and are stored in `EventStore` after successfully completed `UnitOfWork` as collection together (see `UnitOfWorkDomainEventsValue` and `TransactionApplicationEvents`).

There is support for replaying events. When events are replayed the same code is executed but no new events are generated.

There are helper classes that enables a service to easily track events feed, and for domain events there is `EventRouter` that allow to specify specification→receiver routes.

Table 29. Artifact

Group ID | Artifact ID | Version
--- | --- | ---
org.qi4j.library | org.qi4j.library.eventsourcing | 2.1

JDBM backed store

EventStore supports indexed and streamed access to events feed. There is in-memory and JDBM backed implementations.

code

docs

tests

Table 30. Artifact

Group ID | Artifact ID | Version
--- | --- | ---
org.qi4j.library | org.qi4j.library.eventsourcing-jdbm | 2.1

REST access

For remote access to feed there is `eventsourcing-rest` library that exposes events as Atom feeds.

code

docs

tests

Table 31. Artifact

Group ID | Artifact ID | Version
--- | --- | ---
org.qi4j.library | org.qi4j.library.eventsourcing-rest | 2.1

#### Application Events

Assembly is done as follows:

    new EventsourcingAssembler()
            .withApplicationEvents()
            .withCurrentUserFromUOWPrincipal()
            .assemble(module);

Configure application events store:

    module.services( MemoryApplicationEventStoreService.class );

Actual method on composite which execution emits application event. First parameter is `null` on "normal" execution. If it is not `null`, then the method call is a replay of previously created events.

    @Mixins( Users.Mixin.class )
    public interface Users extends TransientComposite
    {
        void signup( @Optional ApplicationEvent evt, String username, List<String> mailinglists );

To enable execution capturing, you have to configure composite with concern:

    module.transients( Users.class ).withConcerns( ApplicationEventCreationConcern.class );

#### Domain Events

Assembly:

    new EventsourcingAssembler()
            .withDomainEvents()
            .withCurrentUserFromUOWPrincipal()
            .assemble(module);

Configure domain events store:

    module.services( MemoryEventStoreService.class );

Annotate your entity state changing methods. Event methods may only change state. They may not fail or thrown exceptions:

    @Mixins( TestEntity.Mixin.class )
    public interface TestEntity
        extends EntityComposite
    {
        @UseDefaults
        Property<String> description();

        @DomainEvent
        void changedDescription( String newName );

        abstract class Mixin
            implements TestEntity
        {
            public void changedDescription( String newName )
            {
                description().set( newName );
            }
        }
    }

To enable method execution capturing, you have to configure entity with concern:

    module.entities( TestEntity.class ).withConcerns(DomainEventCreationConcern.class);