Aggregator KeyGen
Overview
You already know that every transaction should have a unique id.
to provide your own custom keygen for the aggregator, you have to provide an implementation of AggregatorKeyGenerator
interface.
AggregatorKeyGenerator
does provide a method called generateKey
. and also it provides you helpful metadata for creating your unique id like serviceName,serviceVersion,instanceId,region,zone and sagaAggregator.
providing a custom keygen is not necessary all the time because StackSaga provides an implementation for the KeyGen by default (DefaultKeyGen.class
).
even though it is not necessary, implementing a custom id generator helps some cases.
for instance, it can be helped for proper indexing and as well as the database partition in the datacenter.
The default implementation creates the unique id in this format.
the_initial_letters_of_service_name-currentTimeMillis-randomNanoId.
let’s assume that the service name is order-service then here you can see some of the transaction ids that created by using default keygen.
-
OS-1713809175237-021575259417101
-
OS-1713809468378-117401549843120
-
OS-1713809493499-012220401009440
jnanoid is used for creating the randomNanoId. |
Custom Implementation of AggregatorKeyGenerator
as mentioned above if you want to implement your custom own keygen for generating the aggregator id, you can implement as below.
@Component
public class PlaceOrderAggregatorKeyGenerator implements AggregatorKeyGenerator {
@Override
public String generateKey(String serviceName, String serviceVersion, String instanceId, String region, String zone, SagaAggregator sagaAggregator) {
StringBuilder regionKey = new StringBuilder();
for (char c : region.toCharArray()) {
regionKey.append((int) c);
}
return String.format("%s-%s-%s", serviceName , regionKey , UUID.randomUUID());
}
}
Make sure to mark the implementation class as @Component .
|
After implementing it should be provided as keyGen of the aggregator inside the @SagaAggregator
annotation as below.
@SagaAggregator(
version = @SagaAggregatorVersion(major = 1, minor = 0, patch = 1),
name = "PlaceOrderAggregator",
sagaSerializable = PlaceOrderAggregatorSample.class,
keyGen = PlaceOrderAggregatorKeyGenerator.class
)
public class PlaceOrderAggregator extends Aggregator {
After configuring the custom keygen to the aggregator that will be invoked by framework when start the transaction.
and then the generated ID will be stored to the Aggregator#aggregatorTransactionId
. and then it can be accessed by calling the get method from your aggregator class due to that your aggregator class has been extended by the Aggregator
.
Accessing the generated ID;
@RequestMapping("/order-place")
@RestController
public class PlaceOrderController {
private final SagaTemplate<PlaceOrderAggregator> placeOrderAggregatorSagaTemplate;
public PlaceOrderController(SagaTemplate<PlaceOrderAggregator> placeOrderAggregatorSagaTemplate) {
this.placeOrderAggregatorSagaTemplate = placeOrderAggregatorSagaTemplate;
}
@PostMapping
public Object placeOrder() {
PlaceOrderAggregator placeOrderAggregator = new PlaceOrderAggregator();
//initialize your aggregator data
placeOrderAggregator.setUserName("mafei");
...
...
//calling the getAggregatorTransactionId() method but still the id is null.
String aggregatorTransactionIdBefore = placeOrderAggregator.getAggregatorTransactionId();
System.out.println("aggregatorTransactionIdBefore = " + aggregatorTransactionIdBefore);
//calling the process() method and then the aggregatorTransactionId will be added internally by the framework.
placeOrderAggregatorSagaTemplate.process(
placeOrderAggregator,
InitializeOrderExecutor.class
);
//after calling the process() method, the aggregatorTransactionId is no longer null.
String aggregatorTransactionIdAfter = placeOrderAggregator.getAggregatorTransactionId();
System.out.println("aggregatorTransactionIdAfter = " + aggregatorTransactionIdAfter);
return Collections.singletonMap("aggregator_id", aggregatorTransactionIdAfter);
}
}
The output wil be like below.
aggregatorTransactionIdBefore = null
aggregatorTransactionIdAfter = ORDER-SERVICE-117115-71230b5c-79b5-418b-990b-058fba747869