Как воспроизвести события из базы данных перед запуском приложения?
Я студент, который является новичком в структуре Axon для событийного поиска, поэтому терпите меня, пожалуйста. В настоящее время у меня возникают проблемы, когда моему QueryHandler требуется доступ к событиям, которые были созданы до запуска весеннего приложения, они не включаются в них.
Например, создается следующее событие:
- Интернет-магазин создан
(Событие создает новый интернет-магазин и устанавливает для него баланс 100). Это событие сохраняется в моей базе данных. Когда я запрашиваю текущий баланс в интернет-магазине, я могу вернуть, что текущий баланс равен 100. (Код события и запроса показан ниже)
Однако, если я перезапускаю приложение и пытаюсь запросить текущий баланс еще раз, предыдущие события не воспроизводятся, поэтому я не могу получить текущий баланс (после перезапуска события все еще находятся в базе данных, поэтому я думаю, что это это просто проблема с фреймворком, не извлекающим все предыдущие события).
В настоящее время я использую конфигурацию по умолчанию, Axon 4.0.3 для Spring и базу данных H2, в которой события хранятся в файле локально (я знаю, что H2 не лучший выбор, но это все для небольшого подтверждения концепции, показывающей Event Sourcing и CQRS в действии, поэтому не нужно больших и масштабируемых).
@Service
@NoArgsConstructor
public class WebshopsEventHandler {
private final Map<String, Webshop> webshops = new HashMap<>();
// ... some other unrelated code
@EventSourcingHandler
public void on(ShopCreatedEvent shopCreatedEvent) {
this.webshops.put(
shopCreatedEvent.getId(),
new Webshop(
shopCreatedEvent.getId(),
shopCreatedEvent.getName(),
shopCreatedEvent.getBalance() // Balance is 100 as default
)
);
}
// ... some more unrelated code
@QueryHandler
protected Optional handle(GetCurrentBalanceQuery getCurrentBalanceQuery) {
System.out.println("Balance query");
if (webshops.containsKey(getCurrentBalanceQuery.getShopId())) {
return Optional.of(webshops.get(getCurrentBalanceQuery.getShopId()).getBalance());
} else {
return Optional.empty();
}
}
}
Как я могу настроить Axon 4 для получения всех предыдущих событий после перезагрузки?
1 ответ
Я думаю, что могу помочь вам в этом сценарии. Позвольте мне сначала дать вам небольшую информацию о том, почему ваш "магазин моделей запросов", private final Map<String, Webshop>
, не заполняется при каждом запуске.
Технический механизм, который обеспечивает события для вашего @EventHandler
аннотированные функции, называется обработчиком событий. Начиная с версии 4.0 Axon Framework по умолчанию TrackingEventProcessor
,
TrackingEventProcessor
Как и предполагает название, он отслеживает собственную обработку событий. Это делается путем хранения TrackingToken
- в вашей настройке это означает, что он будет храниться в файле базы данных H2. это TrackingToken
хранит (среди прочего) последнее событие данного TrackingEventProcessor
обработал.
TrackingToken
это то, что позволяет вам воспроизводить события, так как вы можете указать это на другой момент времени в потоке событий. Таким образом, настройка положения токена является ключевой в этом сценарии.
Вы можете сделать это, начав воспроизведение на TrackingEventProcessor
, что объясняется более подробно здесь. Однако, поскольку вы просто показываете, как это работает, а не создаете постоянную систему, я бы предложил что-то более прагматичное.
Если вы отрегулируете TokenStore
(компонент, отвечающий за хранение ваших токенов), чтобы быть InMemoryTokenStore
, вы будете уверены, что ваше приложение не отслеживает процесс отслеживания событий между отключениями вашего приложения. Чтобы сделать это, вы можете сделать следующее в файле конфигурации или @SpringBootApplication
аннотированный класс (при условии, что вы используете Spring Boot):
@Autowired
public void configureInMemoryTokenStore(EventProcessingConfigurer configurer) {
configurer.registerTokenStore(configuration -> new InMemoryTokenStore());
}
Надеюсь это поможет!