CQRS - 新しいレポート テーブルを処理する方法 (または:イベント ストアからすべての履歴をインポートする方法)
-
23-09-2019 - |
質問
イベント ストアとしてイベント ソーシングを使用し、「レポート ストア」として単純な (いいえ) SQL ストアを使用する、いくつかの CQRS サンプル実装 (Java / .Net) を研究しました。
すべて問題ないようですが、すべてのサンプル実装に何かが欠けているようです。
アプリケーションが運用に入った後、新しいレポート ストア/画面の追加を処理するにはどうすればよいですか?また、既存の (最新の) データをイベント ストアから新しいレポート ストアにインポートするにはどうすればよいでしょうか?
つまり:
基本的な DDD/CQRS 主導の CRM アプリケーションを想像してください。すべての画面 (実際にはビュー) には、独自の構造化レポート ストア (SQL テーブル) があります。これらすべてのビューは、ドメイン イベント (CustomerCreated / CustomerHasMoved など) をリッスンするハンドラーを使用して更新されます。
CRM の機能の 1 つは、通話を記録できることです (PhoneCallLogged イベント)。時間の制約のため、CRM の V1 には通話の記録のみを実装しました (誰がどの通話に対応したかの表示とレポートは V2 で実装されます)。
実稼働環境で一定の時間が経過した後、顧客および営業担当者ごとに記録された通話の「レポート」を実装したいと考えています。
したがって、いくつかの画面 (ビュー) とサポートするレポート テーブル (レポート ストア内) を追加し、イベント ストアですでに収集されているデータをそれに入力する必要があります。
私が研究したサンプルを見ているときに、ここで行き詰まってしまいます。イベント ストアから (新しい) レポート ストアへの既存の (履歴) データのインポートは処理しません。
EventRepository (DomainRepository) のすべてのサンプルにはメソッド「GetById」と「Add」のみがあり、新しいレポート テーブルに記入するためにすべての集約ルートを一度に取得することはサポートされていません。
この初期データのインポートがないと、新しい画面は新しく発生したイベントに対してのみ更新されます。すでに記録されている通話については対象外です (PhoneCallLogged イベントのレポート リスナーがなかったため)
何か提案、推奨事項はありますか?
前もって感謝します、
レムコ
解決
あなたを再実行し、既存のイベントログのハンドラ(例えば、新しいイベントハンドラを介して古いイベントをプレイ)
あなたの例を考えてみましょう...あなたはあなたのイベントログにPhoneCallLoggedEventsのトンを持っています。あなたの新しいハンドルを取り、それを介してすべての古いイベントを果たしています。それは常に実行されていて、ちょうど到着した任意の新しいイベントを処理していきますようにそれはそれからです。
乾杯、
グレッグ
他のヒント
たとえば、Axon Framework では、これは次のように実行できます。
JdbcEventStore eventStore = ...;
ReplayingCluster replayingCluster = new ReplayingCluster(
new SimpleCluster("replaying"),
eventStore,
new NoTransactionManager(),
0,
new BackloggingIncomingMessageHandler());
replayingCluster.startReplay();
イベントのリプレイは完全に文書化されておらず、成熟したツールが不足している領域ですが、開始点をいくつか示します。
これらのメソッドは運用環境でのみ必要となるため、「EventRepository」にはこれらのメソッドのみが含まれています。
レポート用に新しい非正規化を追加する場合、最初からすべてのイベントをハンドラーに送信できます。
開発サイトで次の方法でこれを行うことができます。
- イベント ログを開発サイトにロードします
- すべてのイベントを非正規化ハンドラーに送信します
- 新しいビューとハンドラーを運用サイトに移動します。
- その間に発生したイベントを実行する
- これで準備は完了です