EventSourceHandler вызван неправильным событием? - PullRequest
1 голос
/ 20 января 2020

У меня возникла проблема, при которой происходит событие, которое, я думаю, не должно быть. Я играю с аксоном и моделирую службу отправки писем на основе событий отправки писем. Мой пример довольно тривиален.

Я разработал две команды ввода 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)

1 Ответ

3 голосов
/ 20 января 2020

Что вы заметили @ GoldFi sh, это фреймворк, который получает ваш агрегат на основе опубликованных событий. Итак, коротко говоря, вы видите «Event Sourcing in action».

С аннотацией @EventSourcingHandler в агрегате Letter вы эффективно создали методы, используемые для воссоздания агрегата на основе событий. .

Таким образом, если вы отправите команду для отмены письма этого агрегата, он сначала заново создаст агрегат из событий. Только после того, как это будет решено, команда фактически будет передана аннотированному методу @CommandHandler.

Надеюсь, это прояснит это для вас @ GoldFi sh!

...