-
-
Notifications
You must be signed in to change notification settings - Fork 10
/
saga.go
108 lines (85 loc) · 3.73 KB
/
saga.go
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package internal
import (
"context"
"github.com/LordMoMA/Intelli-Mall/cosec/internal/models"
"github.com/LordMoMA/Intelli-Mall/customers/customerspb"
"github.com/LordMoMA/Intelli-Mall/depot/depotpb"
"github.com/LordMoMA/Intelli-Mall/internal/ddd"
"github.com/LordMoMA/Intelli-Mall/internal/sec"
"github.com/LordMoMA/Intelli-Mall/ordering/orderingpb"
"github.com/LordMoMA/Intelli-Mall/payments/paymentspb"
)
const CreateOrderSagaName = "cosec.CreateOrder"
const CreateOrderReplyChannel = "intellimall.cosec.replies.CreateOrder"
type createOrderSaga struct {
sec.Saga[*models.CreateOrderData]
}
func NewCreateOrderSaga() sec.Saga[*models.CreateOrderData] {
saga := createOrderSaga{
Saga: sec.NewSaga[*models.CreateOrderData](CreateOrderSagaName, CreateOrderReplyChannel),
}
// 0. -RejectOrder
saga.AddStep().
Compensation(saga.rejectOrder)
// 1. AuthorizeCustomer
saga.AddStep().
Action(saga.authorizeCustomer)
// 2. CreateShoppingList, -CancelShoppingList
saga.AddStep().
Action(saga.createShoppingList).
OnActionReply(depotpb.CreatedShoppingListReply, saga.onCreatedShoppingListReply).
Compensation(saga.cancelShoppingList)
// 3. ConfirmPayment
saga.AddStep().
Action(saga.confirmPayment)
// 4. InitiateShopping
saga.AddStep().
Action(saga.initiateShopping)
// 5. ApproveOrder
saga.AddStep().
Action(saga.approveOrder)
return saga
}
func (s createOrderSaga) rejectOrder(ctx context.Context, data *models.CreateOrderData) (string, ddd.Command, error) {
return orderingpb.CommandChannel, ddd.NewCommand(orderingpb.RejectOrderCommand, &orderingpb.RejectOrder{Id: data.OrderID}), nil
}
func (s createOrderSaga) authorizeCustomer(ctx context.Context, data *models.CreateOrderData) (string, ddd.Command, error) {
return customerspb.CommandChannel, ddd.NewCommand(customerspb.AuthorizeCustomerCommand, &customerspb.AuthorizeCustomer{Id: data.CustomerID}), nil
}
func (s createOrderSaga) createShoppingList(ctx context.Context, data *models.CreateOrderData) (string, ddd.Command, error) {
items := make([]*depotpb.CreateShoppingList_Item, len(data.Items))
for i, item := range data.Items {
items[i] = &depotpb.CreateShoppingList_Item{
ProductId: item.ProductID,
StoreId: item.StoreID,
Quantity: int32(item.Quantity),
}
}
return depotpb.CommandChannel, ddd.NewCommand(depotpb.CreateShoppingListCommand, &depotpb.CreateShoppingList{
OrderId: data.OrderID,
Items: items,
}), nil
}
func (s createOrderSaga) onCreatedShoppingListReply(ctx context.Context, data *models.CreateOrderData, reply ddd.Reply) error {
payload := reply.Payload().(*depotpb.CreatedShoppingList)
data.ShoppingID = payload.GetId()
return nil
}
func (s createOrderSaga) cancelShoppingList(ctx context.Context, data *models.CreateOrderData) (string, ddd.Command, error) {
return depotpb.CommandChannel, ddd.NewCommand(depotpb.CancelShoppingListCommand, &depotpb.CancelShoppingList{Id: data.ShoppingID}), nil
}
func (s createOrderSaga) confirmPayment(ctx context.Context, data *models.CreateOrderData) (string, ddd.Command, error) {
return paymentspb.CommandChannel, ddd.NewCommand(paymentspb.ConfirmPaymentCommand, &paymentspb.ConfirmPayment{
Id: data.PaymentID,
Amount: data.Total,
}), nil
}
func (s createOrderSaga) initiateShopping(ctx context.Context, data *models.CreateOrderData) (string, ddd.Command, error) {
return depotpb.CommandChannel, ddd.NewCommand(depotpb.InitiateShoppingCommand, &depotpb.InitiateShopping{Id: data.ShoppingID}), nil
}
func (s createOrderSaga) approveOrder(ctx context.Context, data *models.CreateOrderData) (string, ddd.Command, error) {
return orderingpb.CommandChannel, ddd.NewCommand(orderingpb.ApproveOrderCommand, &orderingpb.ApproveOrder{
Id: data.OrderID,
ShoppingId: data.ShoppingID,
}), nil
}