@@ -36,12 +36,10 @@ public class CheckoutOrchestrator {
3636
3737 @ Transactional
3838 public UUID startCheckout (StartCheckoutRequest request ) {
39- // Create saga in STARTED state
4039 Saga saga = sagaStateService .createSaga (request .getCustomerId (), maxRetries );
4140 log .info (
4241 "[saga={}] Checkout started for customer={}" , saga .getSagaId (), request .getCustomerId ());
4342
44- // Store original request payload as JSON for future steps
4543 try {
4644 String requestJson = objectMapper .writeValueAsString (request );
4745 saga .setRequestPayload (requestJson );
@@ -54,22 +52,16 @@ public UUID startCheckout(StartCheckoutRequest request) {
5452 "Failed to serialize request payload for saga=" + saga .getSagaId (), e );
5553 }
5654
57- // Publish RESERVE_INVENTORY command
5855 publishCommand (saga .getSagaId (), CommandType .RESERVE_INVENTORY , request );
5956
6057 return saga .getSagaId ();
6158 }
6259
63- /** Get the current state of a saga. */
6460 @ Transactional (readOnly = true )
6561 public Saga getStatus (UUID sagaId ) {
6662 return sagaRepository .findById (sagaId ).orElseThrow (() -> new SagaNotFoundException (sagaId ));
6763 }
6864
69- /**
70- * Handle InventoryReservedEvent from inventory.events topic. Advance saga to AUTHORIZE_PAYMENT
71- * and publish payment command.
72- */
7365 @ Transactional
7466 public void handleInventoryReserved (UUID sagaId , UUID reservationId ) {
7567 log .info (
@@ -80,7 +72,6 @@ public void handleInventoryReserved(UUID sagaId, UUID reservationId) {
8072 Saga saga =
8173 sagaRepository .findById (sagaId ).orElseThrow (() -> new SagaNotFoundException (sagaId ));
8274
83- // Idempotency check: only process if still on RESERVE_INVENTORY step
8475 if (saga .getCurrentStep () != SagaStep .RESERVE_INVENTORY ) {
8576 log .info (
8677 "[saga={}] Already past step {}, skipping (idempotency)" ,
@@ -89,18 +80,12 @@ public void handleInventoryReserved(UUID sagaId, UUID reservationId) {
8980 return ;
9081 }
9182
92- // Advance saga state
9383 sagaStateService .advanceStep (sagaId , SagaStep .AUTHORIZE_PAYMENT );
9484
95- // Publish AUTHORIZE_PAYMENT command (need to reconstruct request - stored in saga or outbox)
9685 StartCheckoutRequest request = buildRequestFromSaga (saga );
9786 publishCommand (sagaId , CommandType .AUTHORIZE_PAYMENT , request );
9887 }
9988
100- /**
101- * Handle PaymentAuthorizedEvent from payment.events topic. Advance saga to CREATE_ORDER and
102- * publish order command.
103- */
10489 @ Transactional
10590 public void handlePaymentAuthorized (UUID sagaId , UUID paymentId ) {
10691 log .info (
@@ -109,7 +94,6 @@ public void handlePaymentAuthorized(UUID sagaId, UUID paymentId) {
10994 Saga saga =
11095 sagaRepository .findById (sagaId ).orElseThrow (() -> new SagaNotFoundException (sagaId ));
11196
112- // Idempotency check: only process if still on AUTHORIZE_PAYMENT step
11397 if (saga .getCurrentStep () != SagaStep .AUTHORIZE_PAYMENT ) {
11498 log .info (
11599 "[saga={}] Already past step {}, skipping (idempotency)" ,
@@ -118,35 +102,29 @@ public void handlePaymentAuthorized(UUID sagaId, UUID paymentId) {
118102 return ;
119103 }
120104
121- // Record payment ID
122105 sagaStateService .recordPayment (sagaId , paymentId );
123106 sagaStateService .advanceStep (sagaId , SagaStep .CREATE_ORDER );
124107
125- // Publish CREATE_ORDER command
126108 StartCheckoutRequest request = buildRequestFromSaga (saga );
127109 publishCommand (sagaId , CommandType .CREATE_ORDER , request );
128110 }
129111
130- /** Handle OrderCreatedEvent from order.events topic. Mark saga as COMPLETED. */
131112 @ Transactional
132113 public void handleOrderCreated (UUID sagaId , UUID orderId ) {
133114 log .info ("[saga={}] Order created orderId={}, marking COMPLETED" , sagaId , orderId );
134115
135116 Saga saga =
136117 sagaRepository .findById (sagaId ).orElseThrow (() -> new SagaNotFoundException (sagaId ));
137118
138- // Idempotency check: only process if still on CREATE_ORDER step
139119 if (saga .getCurrentStep () != SagaStep .CREATE_ORDER ) {
140120 log .info (
141121 "[saga={}] Already past step {}, skipping (idempotency)" , sagaId , SagaStep .CREATE_ORDER );
142122 return ;
143123 }
144124
145- // Mark saga completed
146125 sagaStateService .completeSaga (sagaId , orderId );
147126 }
148127
149- /** Publish a command to checkout.commands topic with sagaId as partition key. */
150128 private void publishCommand (UUID sagaId , CommandType commandType , StartCheckoutRequest request ) {
151129 CheckoutCommand command = new CheckoutCommand ();
152130 command .setSagaId (sagaId );
@@ -171,12 +149,6 @@ private void publishCommand(UUID sagaId, CommandType commandType, StartCheckoutR
171149 }
172150 }
173151
174- /**
175- * Reconstruct StartCheckoutRequest from saga state.
176- *
177- * <p>Deserializes the original request from saga.requestPayload. Falls back to hardcoded test
178- * data if payload is missing (for backwards compatibility with old sagas).
179- */
180152 private StartCheckoutRequest buildRequestFromSaga (Saga saga ) {
181153 // Try to deserialize from stored payload
182154 if (saga .getRequestPayload () != null ) {
@@ -194,7 +166,6 @@ private StartCheckoutRequest buildRequestFromSaga(Saga saga) {
194166 saga .getSagaId ());
195167 }
196168
197- // FALLBACK: Use hardcoded test data (for backwards compatibility)
198169 StartCheckoutRequest request = new StartCheckoutRequest ();
199170 request .setCustomerId (saga .getCustomerId ());
200171
0 commit comments