-
Notifications
You must be signed in to change notification settings - Fork 0
/
BookTripSagaManager.kt
82 lines (65 loc) · 2.41 KB
/
BookTripSagaManager.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package com.cingaldi.sagapattern.application
import com.cingaldi.commons.flightservice.FlightConfirmedEvent
import com.cingaldi.commons.hotelservice.HotelConfirmedEvent
import com.cingaldi.commons.scheduleDeadline
import com.cingaldi.logger
import com.cingaldi.sagapattern.domain.events.TripCreatedEvt
import com.cingaldi.sagapattern.domain.models.TripBookingStatus
import com.cingaldi.sagapattern.domain.repositories.TripBookingStatusRepository
import org.springframework.context.event.EventListener
import org.springframework.stereotype.Service
@Service
class BookTripSagaManager (
private val repository: TripBookingStatusRepository,
private val commandFacade: BookTripCommandFacade
) {
private val logger = logger<BookTripSagaManager>()
/**
* this event starts the saga. Thus, its responsibility is to initialize saga status, make data association
* and make the first move: flight and hotel booking
*/
@EventListener
fun on(evt: TripCreatedEvt) {
//create saga
val saga = TripBookingStatus(evt.flightReservationCode, evt.hotelReservationCode, evt.tripId)
saga.start()
//persist
logger.debug("trip booking started for tripId=${evt.tripId}")
update(saga)
//set deadline
scheduleDeadline(6000, {
repository.findByHotelCode(evt.hotelReservationCode)
},{ foundSaga ->
logger.debug("trip booking with tripId=${foundSaga.tripId} still ongoing. Wrap it up somehow!!!!")
})
}
@EventListener
fun on(evt: FlightConfirmedEvent) {
//retrieve saga
val saga = repository.findByFlightCode(evt.code).orElseThrow()
//update the progress
saga.bookFlight()
//persist
logger.debug("flight booking with code ${evt.code} was confirmed")
update(saga)
}
@EventListener
fun on(evt: HotelConfirmedEvent) {
//retrieve saga
val saga = repository.findByHotelCode(evt.code).orElseThrow()
//update the progress
saga.bookHotel()
//persist
logger.debug("hotel booking with code ${evt.code} was confirmed")
update(saga)
}
private fun update(saga: TripBookingStatus) {
repository.save(saga)
saga.commands().forEach {
//send command
cmd ->
commandFacade.dispatch(cmd)
}
saga.clearCommands()
}
}