Skip to content

Commit f7a4faf

Browse files
authored
Merge pull request #53 from fraktalio/feature/event_sourced_orchestrating_aggregate
Identifier trait added - domain
2 parents 33613d7 + 1f22bc7 commit f7a4faf

File tree

8 files changed

+88
-63
lines changed

8 files changed

+88
-63
lines changed

src/aggregate.rs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::marker::PhantomData;
33

44
use crate::decider::{Decider, EventComputation, StateComputation};
55
use crate::saga::{ActionComputation, Saga};
6+
use crate::Identifier;
67

78
/// Event Repository trait
89
///
@@ -316,7 +317,11 @@ where
316317
}
317318
}
318319
/// Handles the command by fetching the events from the repository, computing new events based on the current events and the command, and saving the new events to the repository.
319-
pub async fn handle(&self, command: &C) -> Result<Vec<(E, Version)>, Error> {
320+
pub async fn handle(&self, command: &C) -> Result<Vec<(E, Version)>, Error>
321+
where
322+
E: Identifier,
323+
C: Identifier,
324+
{
320325
let events: Vec<(E, Version)> = self.fetch_events(command).await?;
321326
let mut current_events: Vec<E> = vec![];
322327
for (event, _) in events {
@@ -336,7 +341,11 @@ where
336341
&self,
337342
current_events: &[E],
338343
command: &C,
339-
) -> Result<Vec<E>, Error> {
344+
) -> Result<Vec<E>, Error>
345+
where
346+
E: Identifier,
347+
C: Identifier,
348+
{
340349
let current_state: S = current_events
341350
.iter()
342351
.fold((self.decider.initial_state)(), |state, event| {
@@ -361,7 +370,11 @@ where
361370
.iter()
362371
.map(|(e, _)| e.clone())
363372
.collect::<Vec<E>>(),
364-
initial_events.clone(),
373+
initial_events
374+
.clone()
375+
.into_iter()
376+
.filter(|e| e.identifier() == command.identifier())
377+
.collect::<Vec<E>>(),
365378
]
366379
.concat();
367380

src/lib.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,3 +340,10 @@ pub enum Sum<A, B> {
340340
/// Second variant
341341
Second(B),
342342
}
343+
344+
/// Identify the state/command/event.
345+
/// It is used to identify the concept to what the state/command/event belongs to. For example, the `order_id` or `restaurant_id`.
346+
pub trait Identifier {
347+
/// Returns the identifier of the state/command/event
348+
fn identifier(&self) -> String;
349+
}

tests/aggregate_combined_test.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use fmodel_rust::aggregate::{
88
};
99
use fmodel_rust::decider::Decider;
1010
use fmodel_rust::saga::Saga;
11+
use fmodel_rust::Identifier;
1112

1213
use crate::api::{
1314
CancelOrderCommand, CreateOrderCommand, CreateShipmentCommand, OrderCancelledEvent,
@@ -16,7 +17,6 @@ use crate::api::{
1617
};
1718
use crate::application::{
1819
command_from_sum, event_from_sum, sum_to_command, sum_to_event, AggregateError, Command, Event,
19-
Id,
2020
};
2121

2222
mod api;
@@ -44,7 +44,7 @@ impl EventRepository<Command, Event, i32, AggregateError> for InMemoryEventRepos
4444
.unwrap()
4545
.clone()
4646
.into_iter()
47-
.filter(|(event, _)| event.id() == command.id())
47+
.filter(|(event, _)| event.identifier() == command.identifier())
4848
.collect())
4949
}
5050

@@ -75,7 +75,7 @@ impl EventRepository<Command, Event, i32, AggregateError> for InMemoryEventRepos
7575
.unwrap()
7676
.clone()
7777
.into_iter()
78-
.filter(|(e, _)| e.id() == event.id())
78+
.filter(|(e, _)| e.identifier() == event.identifier())
7979
.map(|(_, version)| version)
8080
.last())
8181
}
@@ -102,7 +102,12 @@ impl StateRepository<Command, (OrderState, ShipmentState), i32, AggregateError>
102102
&self,
103103
command: &Command,
104104
) -> Result<Option<((OrderState, ShipmentState), i32)>, AggregateError> {
105-
Ok(self.states.lock().unwrap().get(&command.id()).cloned())
105+
Ok(self
106+
.states
107+
.lock()
108+
.unwrap()
109+
.get(&command.identifier().parse::<u32>().unwrap())
110+
.cloned())
106111
}
107112

108113
async fn save(
@@ -114,7 +119,7 @@ impl StateRepository<Command, (OrderState, ShipmentState), i32, AggregateError>
114119
self.states
115120
.lock()
116121
.unwrap()
117-
.insert(state.id(), (state.clone(), version + 1));
122+
.insert(state.0.order_id, (state.clone(), version + 1));
118123
Ok((state.clone(), version))
119124
}
120125
}

tests/aggregate_test.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use fmodel_rust::aggregate::{
66
EventRepository, EventSourcedAggregate, StateRepository, StateStoredAggregate,
77
};
88
use fmodel_rust::decider::Decider;
9+
use fmodel_rust::Identifier;
910

1011
use crate::api::{
1112
CancelOrderCommand, CreateOrderCommand, OrderCancelledEvent, OrderCommand, OrderCreatedEvent,
@@ -43,7 +44,7 @@ impl EventRepository<OrderCommand, OrderEvent, i32, AggregateError>
4344
.unwrap()
4445
.clone()
4546
.into_iter()
46-
.filter(|(event, _)| event.id() == command.id())
47+
.filter(|(event, _)| event.identifier() == command.identifier())
4748
.collect())
4849
}
4950

@@ -74,7 +75,7 @@ impl EventRepository<OrderCommand, OrderEvent, i32, AggregateError>
7475
.unwrap()
7576
.clone()
7677
.into_iter()
77-
.filter(|(e, _)| e.id() == event.id())
78+
.filter(|(e, _)| e.identifier() == event.identifier())
7879
.map(|(_, version)| version)
7980
.last())
8081
}
@@ -100,7 +101,12 @@ impl StateRepository<OrderCommand, OrderState, i32, AggregateError>
100101
&self,
101102
command: &OrderCommand,
102103
) -> Result<Option<(OrderState, i32)>, AggregateError> {
103-
Ok(self.states.lock().unwrap().get(&command.id()).cloned())
104+
Ok(self
105+
.states
106+
.lock()
107+
.unwrap()
108+
.get(&command.identifier().parse::<u32>().unwrap())
109+
.cloned())
104110
}
105111

106112
async fn save(

tests/api/mod.rs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// ############################ Order API ############################
33
// ###################################################################
44

5+
use fmodel_rust::Identifier;
6+
57
/// The state of the Order entity
68
#[derive(Debug, Clone, PartialEq)]
79
pub struct OrderState {
@@ -47,14 +49,13 @@ pub struct CancelOrderCommand {
4749
pub order_id: u32,
4850
}
4951

50-
/// Provides a way to get the id of the Order commands
51-
impl OrderCommand {
52+
impl Identifier for OrderCommand {
5253
#[allow(dead_code)]
53-
pub fn id(&self) -> u32 {
54+
fn identifier(&self) -> String {
5455
match self {
55-
OrderCommand::Create(c) => c.order_id.to_owned(),
56-
OrderCommand::Update(c) => c.order_id.to_owned(),
57-
OrderCommand::Cancel(c) => c.order_id.to_owned(),
56+
OrderCommand::Create(c) => c.order_id.to_string(),
57+
OrderCommand::Update(c) => c.order_id.to_string(),
58+
OrderCommand::Cancel(c) => c.order_id.to_string(),
5859
}
5960
}
6061
}
@@ -87,13 +88,13 @@ pub struct OrderCancelledEvent {
8788
}
8889

8990
/// Provides a way to get the id of the Order events
90-
impl OrderEvent {
91+
impl Identifier for OrderEvent {
9192
#[allow(dead_code)]
92-
pub fn id(&self) -> u32 {
93+
fn identifier(&self) -> String {
9394
match self {
94-
OrderEvent::Created(c) => c.order_id.to_owned(),
95-
OrderEvent::Updated(c) => c.order_id.to_owned(),
96-
OrderEvent::Cancelled(c) => c.order_id.to_owned(),
95+
OrderEvent::Created(c) => c.order_id.to_string(),
96+
OrderEvent::Updated(c) => c.order_id.to_string(),
97+
OrderEvent::Cancelled(c) => c.order_id.to_string(),
9798
}
9899
}
99100
}
@@ -136,11 +137,11 @@ pub struct CreateShipmentCommand {
136137
}
137138

138139
/// Provides a way to get the id of the Shipment commands
139-
impl ShipmentCommand {
140+
impl Identifier for ShipmentCommand {
140141
#[allow(dead_code)]
141-
pub fn id(&self) -> u32 {
142+
fn identifier(&self) -> String {
142143
match self {
143-
ShipmentCommand::Create(c) => c.shipment_id.to_owned(),
144+
ShipmentCommand::Create(c) => c.shipment_id.to_string(),
144145
}
145146
}
146147
}

tests/application/mod.rs

Lines changed: 15 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
use derive_more::Display;
2-
use fmodel_rust::Sum;
2+
use fmodel_rust::{Identifier, Sum};
33
use std::error::Error;
44

55
use crate::api::{
66
CancelOrderCommand, CreateOrderCommand, CreateShipmentCommand, OrderCancelledEvent,
7-
OrderCommand, OrderCreatedEvent, OrderEvent, OrderState, OrderUpdatedEvent, OrderViewState,
8-
ShipmentCommand, ShipmentCreatedEvent, ShipmentEvent, ShipmentState, ShipmentViewState,
9-
UpdateOrderCommand,
7+
OrderCommand, OrderCreatedEvent, OrderEvent, OrderUpdatedEvent, ShipmentCommand,
8+
ShipmentCreatedEvent, ShipmentEvent, UpdateOrderCommand,
109
};
1110

1211
/// The command enum for all the domain commands (shipment and order)
@@ -105,46 +104,28 @@ pub fn sum_to_event(event: &Sum<OrderEvent, ShipmentEvent>) -> Event {
105104
}
106105
}
107106

108-
/// A trait to provide a way to get the id of the messages/entities
109-
#[allow(dead_code)]
110-
pub trait Id {
111-
fn id(&self) -> u32;
112-
}
113-
114-
impl Id for Event {
115-
fn id(&self) -> u32 {
107+
impl Identifier for Event {
108+
fn identifier(&self) -> String {
116109
match self {
117-
Event::OrderCreated(event) => event.order_id,
118-
Event::OrderCancelled(event) => event.order_id,
119-
Event::OrderUpdated(event) => event.order_id,
120-
Event::ShipmentCreated(event) => event.shipment_id,
110+
Event::ShipmentCreated(evt) => evt.shipment_id.to_string(),
111+
Event::OrderCreated(evt) => evt.order_id.to_string(),
112+
Event::OrderUpdated(evt) => evt.order_id.to_string(),
113+
Event::OrderCancelled(evt) => evt.order_id.to_string(),
121114
}
122115
}
123116
}
124117

125-
impl Id for Command {
126-
fn id(&self) -> u32 {
118+
impl Identifier for Command {
119+
fn identifier(&self) -> String {
127120
match self {
128-
Command::OrderCreate(cmd) => cmd.order_id,
129-
Command::OrderUpdate(cmd) => cmd.order_id,
130-
Command::OrderCancel(cmd) => cmd.order_id,
131-
Command::ShipmentCreate(cmd) => cmd.shipment_id,
121+
Command::OrderCreate(cmd) => cmd.order_id.to_string(),
122+
Command::OrderUpdate(cmd) => cmd.order_id.to_string(),
123+
Command::OrderCancel(cmd) => cmd.order_id.to_string(),
124+
Command::ShipmentCreate(cmd) => cmd.shipment_id.to_string(),
132125
}
133126
}
134127
}
135128

136-
impl Id for (OrderState, ShipmentState) {
137-
fn id(&self) -> u32 {
138-
self.0.order_id
139-
}
140-
}
141-
142-
impl Id for (OrderViewState, ShipmentViewState) {
143-
fn id(&self) -> u32 {
144-
self.0.order_id
145-
}
146-
}
147-
148129
/// Error type for the application/aggregate
149130
#[derive(Debug, Display)]
150131
#[allow(dead_code)]

tests/materialized_view_combined_test.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@ use std::thread;
44

55
use fmodel_rust::materialized_view::{MaterializedView, ViewStateRepository};
66
use fmodel_rust::view::View;
7+
use fmodel_rust::Identifier;
78

89
use crate::api::{
910
OrderCancelledEvent, OrderCreatedEvent, OrderEvent, OrderUpdatedEvent, OrderViewState,
1011
ShipmentEvent, ShipmentViewState,
1112
};
12-
use crate::application::{event_from_sum, Event, Id, MaterializedViewError};
13+
use crate::application::{event_from_sum, Event, MaterializedViewError};
1314

1415
mod api;
1516
mod application;
@@ -85,7 +86,12 @@ impl ViewStateRepository<Event, (OrderViewState, ShipmentViewState), Materialize
8586
&self,
8687
event: &Event,
8788
) -> Result<Option<(OrderViewState, ShipmentViewState)>, MaterializedViewError> {
88-
Ok(self.states.lock().unwrap().get(&event.id()).cloned())
89+
Ok(self
90+
.states
91+
.lock()
92+
.unwrap()
93+
.get(&event.identifier().parse::<u32>().unwrap())
94+
.cloned())
8995
}
9096

9197
async fn save(
@@ -95,7 +101,7 @@ impl ViewStateRepository<Event, (OrderViewState, ShipmentViewState), Materialize
95101
self.states
96102
.lock()
97103
.unwrap()
98-
.insert(state.id(), state.clone());
104+
.insert(state.0.order_id, state.clone());
99105
Ok(state.clone())
100106
}
101107
}

tests/materialized_view_test.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use std::thread;
44

55
use fmodel_rust::materialized_view::{MaterializedView, ViewStateRepository};
66
use fmodel_rust::view::View;
7+
use fmodel_rust::Identifier;
78

89
use crate::api::{
910
OrderCancelledEvent, OrderCreatedEvent, OrderEvent, OrderUpdatedEvent, OrderViewState,
@@ -61,7 +62,12 @@ impl ViewStateRepository<OrderEvent, OrderViewState, MaterializedViewError>
6162
&self,
6263
event: &OrderEvent,
6364
) -> Result<Option<OrderViewState>, MaterializedViewError> {
64-
Ok(self.states.lock().unwrap().get(&event.id()).cloned())
65+
Ok(self
66+
.states
67+
.lock()
68+
.unwrap()
69+
.get(&event.identifier().parse::<u32>().unwrap())
70+
.cloned())
6571
}
6672

6773
async fn save(&self, state: &OrderViewState) -> Result<OrderViewState, MaterializedViewError> {

0 commit comments

Comments
 (0)