Creating the aggregator

You know that the request comes to the order-service at the first (for downstream services), and it tries to handle the entire request by calling to other utility services. To start the execute the request, the order-service should have an Aggregator class that extend from the SagaAggregator class. And as well as to verify the aggregator object is serializable well or not, we should provide a sagaSerializable's implementation.

Read the reference documentation to have a better understanding and best practices regarding the SagaAggregator.

package org.example.aggregator;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Getter;
import lombok.Setter;
import org.example.aggregator.dto.OrderItem;
import org.stacksaga.Aggregator;
import org.stacksaga.SagaSerializable;
import org.stacksaga.core.annotation.SagaAggregator;
import org.stacksaga.core.annotation.SagaAggregatorVersion;

import java.util.List;

@SagaAggregator(
        version = @SagaAggregatorVersion(major = 1, minor = 0, patch = 0),
        name = "PlaceOrderAggregator",
        sagaSerializable = PlaceOrderAggregatorSerializer.class
)
@Getter
@Setter
@ToString
public class PlaceOrderAggregator extends Aggregator {


    /**
     * The relevant user to the order.
     */
    @JsonProperty("user_id")
    private String userId;
    /**
     * The item list that user order.
     */
    @JsonProperty("items")
    private List<OrderItem> items;

    /**
     * The amount to be paid.
     */
    @JsonProperty("amount")
    private Double amount;

    /**
     * Pre-Auth Reference for release or make the payment.
     */
    @JsonProperty("pre_auth_ref")
    private String preAuthRef;

    /**
     * Payment ID after the payment.
     */
    @JsonProperty("payment_id")
    private String paymentId;

    @JsonProperty("executions")
    private List<String> executions = new ArrayList<>();

    @JsonIgnore
    private Boolean hasRevertError = false;

    public PlaceOrderAggregator() {
        super(PlaceOrderAggregator.class);
    }
}


class PlaceOrderAggregatorSerializer extends SagaSerializable<PlaceOrderAggregator> {

    public PlaceOrderAggregatorSerializer() {
        PlaceOrderAggregator placeOrderAggregator = new PlaceOrderAggregator();
        placeOrderAggregator.setUserId("user-1");
        placeOrderAggregator.setAmount(100.00);
        placeOrderAggregator.setItems(new ArrayList<>());
        placeOrderAggregator.getItems()
                .add(OrderItem.builder()
                        .itemId("item-1")
                        .itemPrice(100.00)
                        .build()
                );
        this.put("sample-1", placeOrderAggregator);
    }
}
To make the code more readable and clear, I have used lombok and builder pattern for creating the objects through the demo. It is not required, and you are free to use the traditional way by creating getters and setters manual.

In the PlaceOrderAggregator has the data that we want to access while the entire transaction process. Those data will be updated time to time from each execution.

Now the aggregator is ready to store and carry out the data throughout the entire process.