How prevent execution command received from client which may be send from Process Manager only

110 views
Skip to first unread message

Andrey Ladniy

unread,
Dec 13, 2016, 11:55:44 AM12/13/16
to DDD/CQRS
I try implement scheduling microservice.
In this microservice used Calendar, Booking agragates and FreeTime process manager. 
Every Booking instance include list of Calendar and time interval which must be booked for every list entry (Calendar). 
FreeTime process manager used as cache of booked interval for concrete Calendar and send AcceptCalendarBooking/DeclineCalendarBooking command to Booking aggregate as a reaction to Booking.CalendarBookingRequested event when Calendar added to list of Booking entity.

So I get a problem: AcceptCalendarBooking/DeclineCalendarBooking command can be received only from FreeTime process manager, and can not be send manualy from client. I think may be problem is in the design? If I have command then I must receive it from every sender?

Andrey Ladniy

unread,
Dec 14, 2016, 2:06:46 AM12/14/16
to DDD/CQRS
May be right way is:
If some automatic command and manual command may accur, then it must aggregate with command + some external "helper" module (saga for example)
If aggregate should not receive "command" from clients and this is only inner logic, then this is not a command! Aggregate must use some service for deciding about inner state changes.

вторник, 13 декабря 2016 г., 19:55:44 UTC+3 пользователь Andrey Ladniy написал:

Stan Shillis

unread,
Dec 14, 2016, 10:16:43 AM12/14/16
to DDD/CQRS
Perhaps remodel flow between booking and free time. I am thinking something along the lines of bookingPlaced -> through process manager invokes command ReserveTime on freeTime -> emits timeReserved -> through proc manager invokes command AcceptBooking on the booking using reservation id. There can always guard against invalid/nonreserved ids by using freeTime aggregate.

I can't say i went through all cases here but perhaps something like that can work.

Andrey Ladniy

unread,
Dec 14, 2016, 11:17:36 AM12/14/16
to DDD/CQRS
Problem is in invoking AcceptBooking without process manager (in this scenario it can be) and as result there is no guard. I think in aggregate should not be any command which can modify state, if state depends on other state/calculation only. So some shared service/cache must be used and aggregate may change his state on that service shared data.

среда, 14 декабря 2016 г., 18:16:43 UTC+3 пользователь Stan Shillis написал:

Stan Shillis

unread,
Dec 14, 2016, 12:48:30 PM12/14/16
to DDD/CQRS
When processing acceptbooking on booking aggregate how about using freetime aggregate as a guard by giving it reservation id. Freetime is not chaning its state so nothing to emit or persist there. Only aggregate being affected is booking so you are good on that front.

Danil Suits

unread,
Dec 14, 2016, 5:23:41 PM12/14/16
to DDD/CQRS

On Tuesday, December 13, 2016 at 10:55:44 AM UTC-6, Andrey Ladniy wrote:

So I get a problem: AcceptCalendarBooking/DeclineCalendarBooking command can be received only from FreeTime process manager, and can not be send manualy from client. I think may be problem is in the design? If I have command then I must receive it from every sender?

I'm puzzled at why you think that the command can only be sent from the process model, not the client: I'm really fond of Rinat's description of a process manager as a human being with a view and a client
https://abdullin.com/post/ddd-evolving-business-processes-a-la-lokad/

In that line of thinking, it's all just clients sending messages, it doesn't really matter if the "client" is a human driven app or a bit of automation.

So if you want the model to respond to commands from administrator Alice and process manager Bob, but not from Eve, that sounds to me like an authorization check at the command handler, to ensure that the authority currently has the appropriate permissions.

Regardless of where the command comes from, the aggregate still has responsibility for maintaining the invariant.

</endOfGuess>

 

Andrey Ladniy

unread,
Dec 16, 2016, 12:59:19 AM12/16/16
to DDD/CQRS
Now I think so too. 
If model responds to command, it MUST respond for EVERY command independently from source. If model must have some specific behavoir depended from some state, it must be inner calculation beetwen command and event. 
So right way is command -> some service request -> event depended from service response

четверг, 15 декабря 2016 г., 1:23:41 UTC+3 пользователь Danil Suits написал:
Reply all
Reply to author
Forward
0 new messages