sliceX
sliceX

Reputation: 81

How is an Event stored in Axon EventStore?

The following example implements event sourcing (and CQRS) with spring using Axon.

https://github.com/dashsaurabh/event-sourcing-cqrs-axon-spring-boot

Article regarding the code:

http://progressivecoder.com/event-sourcing-and-cqrs-with-axon-and-spring-boot-part-2//

In the application:

I'm having a hard time understanding how in the example, an Event is stored inside the EventStore. In AccountQueryServiceImpl, an EventStore is created and used to read the events from. But how is the EventStore populated exactly? (The service class is called by a REST Endpoint)

In regards to the JPA repository accountRepository, a new Account is persisted by using the save() method in AccountQueryEntityManager whenever a BaseEvent is fired, but I can't find a line of code where something is being appended to the EventStore.

AccountQueryServiceimpl

@Service
public class AccountQueryServiceImpl implements AccountQueryService {

private final EventStore eventStore;

private final AccountRepository accountRepository;

public AccountQueryServiceImpl(EventStore eventStore, AccountRepository 
accountRepository) {
    this.eventStore = eventStore;
    this.accountRepository = accountRepository;
}

@Override
public List<Object> listEventsForAccount(String accountNumber) {
    return eventStore.readEvents(accountNumber).asStream().map( s -> 
s.getPayload()).collect(Collectors.toList());
}

@Override
public AccountQueryEntity getAccount(String accountNumber) {
    return accountRepository.findById(accountNumber).get();
}
}

AccountQueryEntityManager

@Component
public class AccountQueryEntityManager {

@Autowired
private AccountRepository accountRepository;

@Autowired
@Qualifier("accountAggregateEventSourcingRepository")
private EventSourcingRepository<AccountAggregate> accountAggregateEventSourcingRepository;

@EventSourcingHandler
void on(BaseEvent event){
persistAccount(buildQueryAccount(getAccountFromEvent(event)));
}


private AccountAggregate getAccountFromEvent(BaseEvent event){
return accountAggregateEventSourcingRepository.load(event.id.toString()).getWrappedAggregate().getAggregateRoot();
}

private AccountQueryEntity findExistingOrCreateQueryAccount(String id){
return accountRepository.findById(id).isPresent() ? accountRepository.findById(id).get() : new AccountQueryEntity();
}

private AccountQueryEntity buildQueryAccount(AccountAggregate accountAggregate){
AccountQueryEntity accountQueryEntity =     findExistingOrCreateQueryAccount(accountAggregate.getId());

accountQueryEntity.setId(accountAggregate.getId());
accountQueryEntity.setAccountBalance(accountAggregate.getAccountBalance());
accountQueryEntity.setCurrency(accountAggregate.getCurrency());
accountQueryEntity.setStatus(accountAggregate.getStatus());

return accountQueryEntity;
}

private void persistAccount(AccountQueryEntity accountQueryEntity){
accountRepository.save(accountQueryEntity);
}
}

Upvotes: 1

Views: 1271

Answers (1)

Steven
Steven

Reputation: 7275

Axon Framework aims to provide you easy building blocks to work with DDD, CQRS and Event Sourcing. Through this, a lot of plumbing is provided out of the box to make your life on that road as easy as possible.

What's good to note to get a grasp how this works, is to assuming the shared sample focuses on all three paradigms. In such a scenario, you'd use Events as the synchronizing means between the Command and Query side of your application (typically in the form of distinct models).

The Command side of the app would deal with business validation by handling commands and validating it's own state. As a result of that, an event will be published. This in a typical Axon application occurs from within the lifecycle of an Aggregate. To not have the framework user require to wire the EventStore or EventBus directly, with all the added complexity of making sure the event is stored with the right sequence, Axon provides the AggregateLifecycle#apply(Object) method.

Under the hood it's through this that the framework will be able to automatically find the EventBus used to publish the event on, which will end up in the EventStore too.

Side notes

  • The sample you're referring to uses Axon 4. This is already pretty old, as 4.4.4 has been released recently. If you try it out, place use more recent samples as a guide line, like this Hotel Demo by AxonIQ.
  • Any other specifics you'd like to know are pretty well documented in the Reference Guide. If you're gonna look into this further, I'd highly recommend to keep a tab open with the guide in place.
  • There are some online videos to get you started with Axon as well. For those who prefer video material over text, check out this YouTube channel. This series is an actual quick start which might be helpful too.

Upvotes: 2

Related Questions