Hi,

I have now made an initial commit of an EventSourcing library in qi4j-libraries. Basically, when making changes to a domain model it is possible to mark entity methods as @DomainEvent, which will then cause a domain event to be created. When the UoW commits all the events in it will be stored as a unit in an EventStore. They can then be consumed either by a listener interface (push) or a direct access interface (poll). There are helpers available that makes it easy to consume events without having to bother with whether to do poll (if you're behind) or push (if you're up to date).

Here's an example from the test code:
Principal administratorPrincipal = ...
UnitOfWork uow = unitOfWorkFactory.newUnitOfWork( UsecaseBuilder.newUsecase( "Change description" ));
uow.metaInfo().set( administratorPrincipal );

TestEntity entity = uow.newEntity( TestEntity.class );
entity.changedDescription( "New description" );
uow.complete();

EventSource source = (EventSource) serviceLocator.findService( EventSource.class ).get();

source.events( 0, Long.MAX_VALUE ).transferTo( Transforms.map( new Function<UnitOfWorkDomainEventsValue, String>()
{
public String map( UnitOfWorkDomainEventsValue unitOfWorkDomainEventsValue )
    {
        return unitOfWorkDomainEventsValue.toJSON();
    }
}, Outputs.systemOut()));
---
which will output:
{"events":[{"entityId":"8de8d219-352e-4a37-a5c8-4f9db8db96b4-0","entityType":"org.qi4j.library.eventsourcing.domain.DomainEventTest$TestEntity","name":"changedDescription","parameters":"{\"param0\":\"New description\"}"}],"timestamp":1295427369412,"usecase":"Change description","user":"administrator","version":"1.0"}

To define the EventSourced method is as simple as:
@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 );
        }
    }
}
---
i.e. annotation is enough.

So that's a start. More to be done on helpers, performance, and an Atom feed for distribution.

Any thoughts/comments?

/Rickard

_______________________________________________
qi4j-dev mailing list
[email protected]
http://lists.ops4j.org/mailman/listinfo/qi4j-dev

Reply via email to