Hi all.
As I mentioned before I’m writing a POC with Axon, that is now close to the end. But looking at what is done, I can’t help but to see too much complexity and code…
I read in one of my past posts replies [1]
Sometimes it makes more sense to have an external component, such as a saga, register information with the aggregate.
and also this use case that is somewhat similar to what I want [2]. So to put things in perspective, the POC simulates a Process with this stages:
Create-Start-{Finish/Cancel}-Close
All but the Finish are being handled in a Aggregate by making calls to a injected service bean inside the CommandHandlers and then raising some Event.
`
@CommandHandler
public Object doSomething(SomeCommand command) {
Object something = service.getSomething(something.else());
apply(new SomethingHappened(command.getId(), something ));
return something ;
}
@EventSourcingHandler
public void on(SomethingHappened event) {
this.thing = event.getSomething();
}
`
However Finish has to interact with other services and repositories, etc… so it’s modeled as a Saga.
`
@CommandHandler
public void finishSomethig(FinishCommand command){
FinishEvent event = new FinishEvent (command);
event .setData(this.thing);
eventTemplate.publishEvent(event );
}
`
In the Saga, the FinishEvent handler does lots of things, invokes other things, but in the end in ends on one of two places:
`
@SagaEventHandler(associationProperty = “id”)
public void on(SomethingSucceeded event) throws Exception {
end();
// NOTIFY AGGREGATE OF SUCCESS
}
@SagaEventHandler(associationProperty = “id”)
public void on(SomethingFailed event) throws Exception {
end();
// NOTIFY AGGREGATE OF FAILURE
}
`
So now the question: How to do those Notifications? I tried several ways:
- passing the Aggregate in the event and invoking the corresponding CommandHandler method
- passing the Aggregate in the event and invoking the corresponding EventSourcingdHandler method
- loading the Aggregate from the store and invoking the corresponding CommandHandler method
- loading the Aggregate from the store and invoking the corresponding EventSourcingdHandler method
- creating some more commands and events and commandHandlers and eventHandlers and send those commands to the commandGateway
Using the Aggregate directly dis kind of work, but then I noticed that the events triggered did not get stored in the EventStore, so I ended up adding this to the Aggregate (that seems to be a big ugly hack)
`
// BIG UGLY HACK???
@CommandHandler
public void publish(SuperCommand command) {
apply(event.getEvent());
}
`
This way I use the commandGateway in the Saga in a kind of “abstract” way to notify the Aggregate of a multitude of events without having to multiply the number of Commands and Events.
Even like this, just to follow this Create-Start-{Finish/Cancel}-Close pattern I have now:
6 Commands and CommandHandlers
9 Events and EventHandlers
And that is what feels like too much for such a simple use-case. I imagine what it will be in a real-world scenario with dozens of business processes to model…
Am i doing things wrong like this? Are there better good practices?
Any help appreciated.
Cheers.
[1] https://groups.google.com/d/msg/axonframework/-bTpzy0gI6M/ctwvZujXHDMJ
[2] https://groups.google.com/d/topic/axonframework/mikwKBdeRVI/discussion