У меня возникла проблема, при которой происходит событие, которое, я думаю, не должно быть. Я играю с аксоном и моделирую службу отправки писем на основе событий отправки писем. Мой пример довольно тривиален.
Я разработал две команды ввода ScheduleLetterCommand
, которые "отправят письмо" через несколько минут ... что позволяет пользователю отменить его, если они отправят другую команду CancelLetterCommand
в течение этого периода времени.
Я запускаю команды через контроллер REST API ...
Я ожидаю увидеть сообщения журнала, в которых говорится, что письмо запланировано и отменено, если я должны были запланировать письмо и немедленно отменить его в течение следующих пяти минут.
Я с любопытством вижу, что письмо успешно запланировано, и я вижу следующие записи в журнале:
Received schedule command for letter id e6e037be-3b6d-4ae3-80cd-12426adcd526
LetterScheduledEvent e6e037be-3b6d-4ae3-80cd-12426adcd526 SCHEDULED
Но когда я отменяю письмо, я вижу следующее:
LetterScheduledEvent e6e037be-3b6d-4ae3-80cd-12426adcd526 SCHEDULED
Received cancel command for letter id e6e037be-3b6d-4ae3-80cd-12426adcd526
Letter e6e037be-3b6d-4ae3-80cd-12426adcd526 cancelled CANCELLED
Что мне здесь не хватает? Почему обработчик LetterScheduledEvent
снова запускается?
Вот мой агрегат -
public class Letter {
@AggregateIdentifier
private String letterId;
private ScheduleToken scheduleToken;
@SuppressWarnings("UnusedDeclaration")
protected Letter() {
// Default constructor required by Axon Framework
}
@CommandHandler
public Letter(ScheduleLetterCommand cmd, EventScheduler scheduler) {
String id = cmd.getLetterId();
log.info("Received schedule command for letter id {}", letterId);
AggregateLifecycle.apply(new LetterScheduledEvent(id, LetterEventType.SCHEDULED));
this.scheduleToken = scheduler.schedule(Duration.ofMinutes(5), new BeginSendLetterEvent(id,LetterEventType.BEGIN_SEND));
}
@CommandHandler
public void handle(CancelLetterCommand cmd, EventScheduler eventScheduler) {
String letterId = cmd.getLetterId();
log.info("Received cancel command for letter id {}", letterId);
AggregateLifecycle.apply(new LetterCancelledEvent(letterId, LetterEventType.CANCELLED));
eventScheduler.cancelSchedule(scheduleToken);
}
@EventSourcingHandler
public void on(LetterScheduledEvent event) {
log.info("LetterScheduledEvent {} {}", event.getLetterId(), event.getEventType());
this.letterId = event.getLetterId();
}
@EventSourcingHandler
public void on(LetterCancelledEvent event) {
log.info("Letter {} cancelled {}", event.getLetterId(), event.getEventType());
scheduleToken = null;
}
@EventSourcingHandler
public void on(BeginSendLetterEvent event) {
log.info("Letter sending process started {} {}", event.getLetterId(), event.getEventType());
//complicated letter sending processes...
AggregateLifecycle.apply(new LetterSentEvent(event.getLetterId(), LetterEventType.SENT));
}
@EventSourcingHandler
public void on(LetterSentEvent event) {
log.info("Letter sent {} {}", event.getLetterId(), event.getEventType());
}
}
А вот мои события ->
abstract class LetterMovementEvent(open val letterId: String, open val eventType: LetterEventType)
enum class LetterEventType {
SCHEDULED,
CANCELLED,
BEGIN_SEND,
SENT
}
data class LetterScheduledEvent(
override val letterId: String,
override val eventType: LetterEventType = LetterEventType.SCHEDULED
) : LetterMovementEvent(letterId, eventType)
data class LetterCancelledEvent(
override val letterId: String,
override val eventType: LetterEventType = LetterEventType.CANCELLED
) : LetterMovementEvent(letterId, eventType)
data class BeginSendLetterEvent(
override val letterId: String,
override val eventType: LetterEventType = LetterEventType.BEGIN_SEND
) : LetterMovementEvent(letterId, eventType)
data class LetterSentEvent(
override val letterId: String,
override val eventType: LetterEventType = LetterEventType.SENT
) : LetterMovementEvent(letterId, eventType)