Skip to content

Instantly share code, notes, and snippets.

@saikarthik952
Last active March 20, 2022 12:20
Show Gist options
  • Save saikarthik952/bb747573cd6cb74d26b639f22958eac3 to your computer and use it in GitHub Desktop.
Save saikarthik952/bb747573cd6cb74d26b639f22958eac3 to your computer and use it in GitHub Desktop.
package com.food.saga.myfood.temporal.workflows;
import com.food.saga.myfood.temporal.activities.FoodOrderActivity;
import io.temporal.activity.ActivityOptions;
import io.temporal.common.RetryOptions;
import io.temporal.workflow.Saga;
import io.temporal.workflow.Workflow;
import lombok.extern.slf4j.Slf4j;
import java.time.Duration;
import java.util.Objects;
@Slf4j
public class FoodDeliveryWorkFlowImpl implements FoodDeliveryWorkFlow{
private final ActivityOptions options =
ActivityOptions.newBuilder()
.setStartToCloseTimeout(Duration.ofHours(1))
.setRetryOptions(RetryOptions.newBuilder().setMaximumAttempts(1).build())
.build();
private final FoodOrderActivity foodOrderActivity = Workflow.newActivityStub(FoodOrderActivity.class, options);
@Override
public String orderFood(String food, String amount) {
final Saga saga = new Saga(new Saga.Options.Builder().setParallelCompensation(false).build());
try {
final String orderId = Workflow.randomUUID().toString();
final boolean isPaymentDone = foodOrderActivity.makePayment(amount, orderId);
saga.addCompensation(() -> foodOrderActivity.revert(amount, orderId));
if (!isPaymentDone) {
throw new RuntimeException("Payment Failed");
}
final boolean isCustomerNotified = foodOrderActivity.acknowledgeCustomer(orderId);
saga.addCompensation(() -> foodOrderActivity.acknowledgeCustomerForFailure(orderId));
if (!isCustomerNotified) {
throw new RuntimeException("Order creation Failed");
}
final boolean isRestaurantAcknowledged = foodOrderActivity.notifyRestuarantAndFetchAck(food, orderId, "1");
saga.addCompensation(() -> foodOrderActivity.notifyRestuarantAndSendFailAck(food, orderId, "1"));
if (!isRestaurantAcknowledged) {
throw new RuntimeException("Ack Failed");
}
final boolean amountSentToRes = foodOrderActivity.sendPaymentToRestaurant(amount, orderId, "1");
saga.addCompensation(() -> foodOrderActivity.revertPaymentToRestaurant(amount, orderId, "1"));
if (!amountSentToRes) {
throw new RuntimeException("Payment to Res Failed");
}
final String deliveryPartnerAssigned = foodOrderActivity.searchAndAssignDeliveryPartner(orderId, "1");
saga.addCompensation(() -> foodOrderActivity.noDeliveryPersonsFound(orderId, "1"));
if (Objects.isNull(deliveryPartnerAssigned)) {
throw new RuntimeException("No Delivery Partner Found");
}
return orderId;
}
catch (final RuntimeException activityFailure) {
log.error(activityFailure.toString());
saga.compensate();
return "FAILED";
}
}
}
package com.food.saga.myfood.temporal.activities;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class FoodOrderActivityImpl implements FoodOrderActivity{
@Override
public boolean makePayment(String amount, String orderId) {
log.info(" Transferring to FoodDelivery Global AC of Amount : {} from customer acc by payment Provider for Order Id : " + orderId, amount);
return true;
//return false;
}
@Override
public boolean acknowledgeCustomer(String orderId) {
log.info(" Payment Done for $ 10 and your order is placed order Id : " + orderId);
return true;
//return false;
}
@Override
public boolean notifyRestuarantAndFetchAck(String food, String orderId, String restaurantId) {
log.info("Notifying Restaurant with Id : {} on Food : {} for OrderId : " + orderId, restaurantId, food);
return true;
//return false;
}
@Override
public boolean sendPaymentToRestaurant(String amount, String orderId, String restaurantId) {
log.info("Sending Amount : {} to restaurant : {} for the Food with orderId : " + orderId, amount, restaurantId);
return true;
//return false;
}
@Override
public String searchAndAssignDeliveryPartner(String orderId, String restaurantId) {
log.info("Searching Delivery Genie near to restaurant : {} for the Food Delivering with orderId : " + orderId);
return "ABC_DEL_GENIE_ID";
// Failure Scenario roll back above transactions
//return null;
}
@Override
public boolean revert(String amount, String orderId) {
log.info(" Reverting Transferred to FoodDelivery Global AC of Amount : {} from customer acc by payment Provider for Order Id : " + orderId, amount);
return true;
}
@Override
public boolean acknowledgeCustomerForFailure(String orderId) {
log.info(" Reverted your payment for $ 10 for your order due to technical Issues : " + orderId);
return true;
}
@Override
public boolean notifyRestuarantAndSendFailAck(String food, String orderId, String restaurantId) {
log.info("Notifying Failure that customer has cancelled the order Restaurant with Id : {} on Food : {} for OrderId : " + orderId, restaurantId, food);
return true;
}
@Override
public boolean revertPaymentToRestaurant(String amount, String orderId, String restaurantId) {
log.info("Reverting Amount : {} to restaurant : {} for the Food with orderId : " + orderId, amount, restaurantId);
return true;
}
@Override
public String noDeliveryPersonsFound(String orderId, String restaurantId) {
log.info("No Delivery Genie near to restaurant : {} for the Food Delivering with orderId : " + orderId);
return "FAILURE";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment