Как воспроизвести / спроецировать события в Axon4 на другой контекст? - PullRequest
2 голосов
/ 27 сентября 2019

Я создаю свою первую систему источников событий.Он будет иметь несколько доменов, использующих проекты с жизненным циклом публикации в своей основе.Как эффективно воспроизвести или повторно применить события двух доменов к новому агрегату внутри третьего домена?

Чтобы быть более конкретным.Представьте себе 4 домена, каждый со своим ограниченным контекстом и целью.Краткое описание этих контекстов:

  • Проект - A project является сложным объектом в ядре системы, почти для каждого домена требуются данные проекта для работы.У проекта есть один или несколько типов продуктов, которые содержат ограниченное количество продуктов.
  • Мультимедиа - домен мультимедиа охватывает операции с изображениями, документами и сгенерированными отчетами, а также выполняет функции файлового сервера.
  • Доставка -Доставка позволяет настроить, в каких каналах контента можно публиковать все публикации.
  • Публикация - домен публикации выполняет сложные задачи проверки возможности публикации проекта в запрошенном состоянии в его текущем состоянии.

Состояния публикации соответствуют жизненному циклу: концепция (еще не опубликована)> объявлено (необязательно)> продажа> распродано (публикация окончена).В моем описании я остановлюсь на объявленном статусе.На самом деле концепция не является тонкой для области публикации, поскольку проект всегда находится в концепции, если публикация еще не знает об этом.

Моей первой попыткой была установка обычного агрегата, который обрабатывал входящее событие AnnouncementPublishedEvent.Для этого требуется, чтобы проект отвечал некоторым базовым требованиям, таким как «у него есть имя», «у него есть описание», «у него есть хотя бы одно изображение» и так далее.Это означает, что мне нужно проверить эту информацию до того, как событие будет применено, и поэтому мне как-то нужно предоставить экземпляр project в команде.

При этом я подозревал, что этот метод нарушает цель CQRS, и я долженсмотреть на реальный источник данных: события.Моей следующей попыткой было создание саги, которая начинается, когда происходит событие AnnouncementPublicationRequestedEvent.Эта сага должна проверить, какие события произошли вокруг заданного идентификатора проекта, и применить их к этой новой проекции «опубликованного проекта», чтобы (как минимум) проверить, можно ли принять запрос.

Я исследовал и экспериментировал с отслеживаниемпроцессоры, но не смогли получить хороший пример того, как это делается в версии 4 Axon.Я также начал читать несколько других вопросов о Stackoverflow, которые заставили меня подумать, что мне, возможно, придется пересмотреть мой подход.

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

@Saga
@ProcessingGroup("AnnouncementPublication")
public class AnnouncementPublicationSaga {

   private static int NUMBER_OF_ALLOWED_IMAGES

   private PublicationId publicationId;
   private ProjectId projectId;
   private int numberOfImages = 0;
   //...other fields

   @StartSaga
   @SagaEventHandler(associationProperty = "projectId")
   public void handle(AnnouncementPublicationRequestedEvent event) {
      publicationId = generatePublicationId();

      //set parameters from event for saga to use
      projectId = event.getProjectId();
      targetPublicationStatus = event.getPublicationStatus();
      date = event.getDate();

      //initialize the 'publicated project' aggregate
      //start a replay of associated events for this @ProcessingGroup
   }

   ...

   @SagaEventHandler(associationProperty = "projectId")
   public void handle(ProjectCreatedEvent event) {
      //Verify the project exists and has a valid name
   }

   ...

   /* Assumption* on how AssociationResolver works: */
   @SagaEventHandler(AssociationResolver=MediaProjectAssociator.class )
   public void handle(ProjectImageAdded event) {
      numberOfImages += 1;
   }

   /* Assumption* on how AssociationResolver works: */
   @SagaEventHandler(AssociationResolver=MediaProjectAssociator.class )
   public void handle(ProjectImageRemoved event) {
      numberOfImages -= 1;
   }

   ...

   /* In my head this should trigger if all events have been played
      up to the PublicationRequestedEvent. Or maybe 
   */
   @SagaEventHandler(associationProperty = "publicationId")
   public void handle(ValidationRequestCompleted event) {
      //ValidationResult result = ValidationResult.builder();
      ...
      if (numberOfImages > NUMBER_OF_ALLOWED_IMAGES) {
         //reason to trigger PublicationRequestDeniedEvent
         //update validationResult
      }
      ...
      if (validationResult.isAcceptable()) {
         //Trigger AnnouncementPublicationAcceptedEvent
      } else {
         //Trigger AnnouncementPublicationDeniedEvent
      }
   }

   ...

   @EndSaga
   @SagaEventHandler(associationProperty = "publicationId")
   public void handle(AnnouncementPublicationDeniedEvent event) {
      //do stuff to inform why the publication failed
   }

   @EndSaga
   @SagaEventHandler(associationProperty = "publicationId")
   public void handle(AnnouncementPublicationAcceptedEvent event){
      //do stuff to notify success to user
      //choice: delegate to delivery for actual sharing of data
      //    or  delivery itselfs listens for these events
   }
}

* Код associationResolver - это предположение, что он действительно работает, так как я еще даже не близок к этой части.Мой медиа-контекст использует идентификатор файла в качестве совокупного идентификатора, так как не каждое событие связано с проектом.Но все медиа-события, которые необходимо воспроизвести в этой саге, будут содержать поле projectId в качестве поля.Любые отзывы по этому поводу приветствуются, но это не моя главная проблема.

В конце должен быть результат: запись публикации или запись попытки и причины ее неудачи.

Запись публикации содержит все данные событий project или media.которые имеют отношение к публикации.В основном это информация, которую потенциальные покупатели должны принять решение.

Для целей этого вопроса я не ожидаю, что вышеупомянутое будет решено полностью.Я просто хочу знать, нахожусь ли я на правильном пути, думая о событиях, правильный ли мой подход к воспроизведению соответствующих событий, и если да, то как это можно сделать в Axon4.

...