- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在构建我的第一个事件源系统。它将有多个域,使用以发布生命周期为核心的项目。如何有效地将两个域的事件重放或重新应用到第三个域内的新聚合?
更具体一点。想象 4 个领域,每个领域都有自己的限界上下文和目的。这些上下文的简短描述:
项目
是系统核心的复杂对象,几乎每个领域都需要项目数据来运行。一个项目有一个或多个 ProductTypes,其中包含有限的产品供应。发布状态遵循生命周期:概念(尚未发布)> 宣布(可选)> 销售 > 售罄(发布结束)。在我的描述中,我专注于已宣布的状态。对于出版领域来说,概念实际上并不是一个薄薄的东西,因为如果出版还不知道一个项目,它总是处于概念中。
我的第一次尝试是设置一个处理传入事件 AnnouncementPublishedEvent
的普通聚合。这需要一个项目满足一些基本要求,例如“它有一个名称”、“它有一个描述”、“它至少有一个图像”等等。这意味着我需要在应用事件之前验证此信息,因此我需要以某种方式在命令中提供一个 project
实例。
在执行此操作时,我怀疑此方法破坏了 CQRS 的目的,我应该查看真正的数据源:事件。我的下一次尝试是创建一个在事件 AnnouncementPublicationRequestedEvent
时开始的 Saga。此 saga 需要审查在给定 projectId 周围发生了哪些事件,并将这些事件应用于这个新的“已发布项目”投影,以便(至少)验证请求是否可以被接受。
我对跟踪处理器进行了研究和试验,但无法找到在 Axon 版本 4 中如何完成此操作的良好示例。我还开始阅读有关 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 代码是对其实际工作的假设,因为我还没有接近那部分。我的媒体上下文使用文件 ID 作为聚合标识符,因为并非每个事件都绑定(bind)到项目。但是这个传奇需要重播的所有媒体事件都将有一个 projectId 作为其中的字段。欢迎对此提出任何反馈,但这不是我现在的主要问题。
最终的结果应该是:发布记录或尝试记录以及失败原因。
出版物的记录包含与出版物相关的 project
或 media
事件的所有数据。这主要是潜在买家需要做出决定的信息。
出于这个问题的目的,我不希望上述问题得到完全解决。我只想知道我在思考事件时是否走在正确的轨道上,我重播相关事件的方法是否正确,如果是这样,如何在 Axon4 中完成。
最佳答案
根据 Martin 的问题描述,我假设您有几个不同的限界上下文。按照限界上下文的定义:
Explicitly define the context within which a model applies.
Explicitly set boundaries in terms of team organization,usage within specific parts of the application,and physical manifestations such as code bases and database schemas.
Keep the model strictly consistent within these bounds,but don’t be distracted or confused by issues outside.
由此我想强调的是,在给定的限界上下文中,您对任何组件都使用相同的语言/API。然而,在上下文之间,您将非常有意识地共享,使用专用的上下文映射(例如反腐败层)来确保另一个域不会进入您的域。
综上所述,事件是特定限界上下文的一部分。因此,理想情况下,使用来自其他上下文的多个事件流在另一个上下文中重新创建/重放聚合应该是不可能的。
除此之外,在 Axon 中,聚合只能根据它自己发布的事件重新创建。
要仍然得出一个解决方案,即给定应用程序从其他应用程序中摄取事件以重新聚合聚合,我将采取以下步骤:
最后,我想指出,Axon 提供的与 TrackingEventProcessor
相关的重放的任何细节都用于 CQRS 应用程序查询端的事件处理。
希望这能为您澄清一切,马丁!如果没有,请随时在此答案下发表评论,我会相应地更新我的回复。
关于java - 如何将 Axon4 中的事件重播/转换到不同的上下文中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58136910/
我想在 vim 中从光标到缓冲区末尾的打开缓冲区的每一行上运行我刚刚在寄存器“x”中记录的宏。我该怎么做? 我知道我可以重播宏 n 次: 15@x ...或者只需按住 @ 直到到达最后一行,但我只想按
因此,我最近尝试学习html5知识,并获得了音频标签。在PC的浏览器Chrome上似乎可以正常工作,但在Android(4.0,同时使用常规浏览器和海豚)上却不能正常工作。它将播放一次音频,但不会再播
我有兴趣使用 PHP 构建一个解析器来享受我的乐趣。我需要知道什么?你对我有什么建议?我什至如何使用 PHP 打开星际争霸 2 重播? 最佳答案 SC 回放文件实际上是一个 MPQ 存档文件。此 MP
我有一个使用 Animate.CSS 的动画如果用户愿意,我想重播,但我尝试的方法不起作用。这是代码: HTML:
在 ASP.NET MVC 中防止一个有效 cookie 一次被多个客户端使用的“最佳实践”是什么? 在这种情况下,我们使用了所有 OWASP 技巧。 严格的 HSTS:每个页面都使用 HTTPS/S
我有一个 AVPlayer 类,全部设置为流式传输音频文件。它有点长,所以我不能在这里发布整个内容。我坚持的是如何让用户在听完一次音频文件后重播。当它第一次完成时,我正确地收到通知 AVPlayerI
我正在尝试用 sipp 重播捕获的 pcap 文件。我的设置有 2 台电脑和一个代理。接收电脑有 linphone,应该能够接听来自另一台发送带有 sipp 的 pcap 文件的电脑的调用。我已经用
我有一个网页,如果应用了某些样式,滚动时可能会出现卡顿。我的问题是如何系统地测试个人风格的效果。我不想每次都手动向下滚动页面,我想执行一些可复制的操作,以便轻松比较两个不同样式表的效果。是否可以录制和
我想从 Clojurescript 建立一个 Om session ,它可以在另一台机器上回复整个 GUI。我如何才能将原子从客户端传递到服务器,以便只发送更改,以便可以在其他地方重播更改历史? 更新
我一直在使用 React Native Video 模块并且它工作得很好,但是我需要播放结束时的视频自动倒回到开头。视频实例可以选择使用: onEnd={this.onEnd} 视频播放结束后调用一个
我的计算机上有一些虚拟机,它们通过主机专用网络相互通信。 我想模拟这些机器之间的中间人攻击。我发现的所有运行 MITM 的工具都只是监视数据包,但我没有找到任何可以真正重放或更改它们的工具。 我发现了
我是 FreeGLUT 的当前维护者之一sourceforge 上的项目。此代码存储在 SVN 存储库中,但为了激发其他人的贡献,我想提供一个 git 存储库。我已经在 github 上有一个 svn
我正在开发一个有很多命令行交互的系统。有时甚至通过 SSH。命令有时可能需要长达 30 分钟才能完成。 目前,我正在停止对执行该系统调用的对象的大部分 system 调用。例如: class Back
我们如何在delve session 中轻松查看decimal.Decimal值的浮点值。尤其是在 mozilla rr 录制的 dlv replay session 中。 (dlv) args un
我是一名优秀的程序员,十分优秀!