Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
September 13, 2021 08:34 am GMT

AWS Step Functions - Simple Order Flow

AWS Step Functions - Simple Order Flow Example (Step by Step Guide)

What is AWS Step Functions?

  • AWS Step Functions is a fully managed service that makes it easy to coordinate the components of distributed applications and microservices using visual workflows.
  • Building applications from individual components that each perform a discrete function lets you scale easily and change applications quickly.
  • Step Functions is a reliable way to coordinate components and step through the functions of your application. Step Functions provides a graphical console to arrange and visualize the components of your application as a series of steps.
  • This makes it simple to build and run multi-step applications. Step Functions automatically triggers and tracks each step, and retries when there are errors, so your application executes in order and as expected.
  • Step Functions logs the state of each step, so when things do go wrong, you can diagnose and debug problems quickly.
  • You can change and add steps without even writing code, so you can easily evolve your application and innovate faster.

Order Flow - Design Details

For this example, I will demo how step functions can help to manage a order flow once user has submitted the order. Here, for this example, I am taking an online bookstore which will ship books based on the order submission. It should perform the below steps as part of Order Handling

  1. On Order Submit, system will check the available inventory of the book.
  2. If inventory available, then proceed further. If not available, then trigger a printOrder and wait for the book to be printed.
  3. Once the book is printed, the system will prepare order for delivery and trigger the send shipment flow.
  4. In parallel, System will
    • Update Loyalty Points for the Customer
    • Check future discount eligibility and send discount code for future order
    • Update Recommendation Engine
    • Send a free eBook for Tips to Better Life

Order Flow - Steps

For creating a Step Function, below are the steps required which I will show in details

  1. Create an IAM Role for the AWS Step function to be able to execute the AWS Services ( eg:- Lambda in this case)
  2. Create Lambda Executor Functions
  3. Create AWS Step Functions with the flow as highlighted above

Order Flow - Step 1 - IAM Roles

1 In the AWS Console, go to Identity and Access Management (IAM), click on Roles in the left hand pane
image

  1. Click on Create Role
    image

  2. On the next screen, keep the default AWS Service option selected and under the list of Services choose Step Functions
    image

  3. Leave the rest as default and click Next on next 3 screens, Give a Role Name and click Create Role
    image

Great! Step 1 has been completed and we are now ready for Step 2 on creation of the required Lambda functions

Order Flow - Step 2 - Create Lambda

Next step is to create below Lambda functions as per the requirement of our code.

  • In the IAM console, search Lambda and click on Create Function
  • Select Author from scratch
  • Give Function name as per below function names
  • Select Runtime as Node.js 14.x
  • Under Permissions, select Use and Existing Role and select the role created at Step 1
  • Copy-Paste the below code for checkInventory (1 below)
  • Click Deploy
  • Now repeat this step for (2-8 lambda code below)

  • 1 - checkInventory

console.log('Loading function checkInventory');exports.handler = async (event, context) => {    var x = {ItemStock: 0};    if (event.bookId == 343222)      x = {ItemStock: 20};    return x;  };
  • 2 - OrderToPrint
console.log('Loading function orderToPrint');exports.handler = async (event, context) => {    console.log('Printing the Order Book');    var retJson = { TotalValue: 500 };    return retJson;  };
  • 3 - checkFurtherDiscountEligibility
console.log('Loading function check Further Discount');exports.handler = async (event, context) => {    var TotalDiscount = { Discount: 10 };    if (event.TotalValue > 400){        TotalDiscount = { Discount: 20 };    }    return TotalDiscount; };
  • 4 - generateDiscountCode
console.log('Loading function generate Discount Code');exports.handler = async (event, context) => {    //console.log('Received event:', JSON.stringify(event, null, 2));    var Disc = { DiscountCode: "Hello10" };    if (event.Discount >20 )       Disc = { DiscountCode: "Hello20" };    return Disc; };
  • 5 - updateLoyaltyPoints
console.log('Loading function update Loyalty Points');exports.handler = async (event, context) => {    var LoyaltyPoints = { LoyaltyPoints: event.TotalValue };    return LoyaltyPoints;  };
  • 6 - prepareOrder
console.log('Loading function prepare Order');exports.handler = async (event, context) => {    var shipmsg = { Shipmsg: "Order Prepared - Ready for Shipment"};    console.log(' Order Prepared - Ready for Shipment');    return shipmsg;  };
  • 7 - sendToShipment
console.log('Loading function send to shipment');exports.handler = async (event, context) => {    //console.log('Received event:', JSON.stringify(event, null, 2));    var shipment = { ShipmentSent : "True" };    return shipment; };
  • 8 - updateRecoEngine
console.log('Loading function update Reco Engine');exports.handler = async (event, context) => {    var Reco = { RecoengineUpdated : "True"};    return Reco;};

Order Flow - Step 3 - Create Step Functions

  1. In the AWS Console, search Step Functions, click on State Machines in the left hand pane
    image

  2. Click on 'Create State Machine' Button
    image

  3. Choose Authoring method as Design you workflow visually and select Type as Standard, Click Next
    image

  4. On the Next Screen, you can choose to design the workflow by using the Lambda Actions and decision making Flow as per our example statement or you can use the code below

{  "Comment": "An Order Flow example of the Amazon States Language using Lambda",  "StartAt": "Order Handling",  "States": {    "Order Handling": {      "Type": "Pass",      "Next": "CheckInventory"    },    "CheckInventory": {      "Type": "Task",      "Resource": "arn:aws:states:::lambda:invoke",      "OutputPath": "$.Payload",      "Parameters": {        "Payload.$": "$"      },      "Retry": [        {          "ErrorEquals": [            "Lambda.ServiceException",            "Lambda.AWSLambdaException",            "Lambda.SdkClientException"          ],          "IntervalSeconds": 2,          "MaxAttempts": 6,          "BackoffRate": 2        }      ],      "Next": "Choice"    },    "Choice": {      "Type": "Choice",      "Choices": [        {          "Variable": "$.ItemStock",          "NumericGreaterThan": 0,          "Next": "Pass"        }      ],      "Default": "OrderPrint"    },    "Pass": {      "Type": "Pass",      "Next": "Parallel"    },    "OrderPrint": {      "Type": "Task",      "Resource": "arn:aws:states:::lambda:invoke",      "OutputPath": "$.Payload",      "Parameters": {        "Payload.$": "$"      },      "Retry": [        {          "ErrorEquals": [            "Lambda.ServiceException",            "Lambda.AWSLambdaException",            "Lambda.SdkClientException"          ],          "IntervalSeconds": 2,          "MaxAttempts": 6,          "BackoffRate": 2        }      ],      "Next": "Parallel"    },    "Parallel": {      "Type": "Parallel",      "Branches": [        {          "StartAt": "CheckFurtherDiscountEligibility",          "States": {            "CheckFurtherDiscountEligibility": {              "Type": "Task",              "Resource": "arn:aws:states:::lambda:invoke",              "OutputPath": "$.Payload",              "Parameters": {                "Payload.$": "$"              },              "Retry": [                {                  "ErrorEquals": [                    "Lambda.ServiceException",                    "Lambda.AWSLambdaException",                    "Lambda.SdkClientException"                  ],                  "IntervalSeconds": 2,                  "MaxAttempts": 6,                  "BackoffRate": 2                }              ],              "Next": "GenerateDiscountCode"            },            "GenerateDiscountCode": {              "Type": "Task",              "Resource": "arn:aws:states:::lambda:invoke",              "OutputPath": "$.Payload",              "Parameters": {                "Payload.$": "$"              },              "Retry": [                {                  "ErrorEquals": [                    "Lambda.ServiceException",                    "Lambda.AWSLambdaException",                    "Lambda.SdkClientException"                  ],                  "IntervalSeconds": 2,                  "MaxAttempts": 6,                  "BackoffRate": 2                }              ],              "End": true            }          }        },        {          "StartAt": "UpdateLoyaltyPoints",          "States": {            "UpdateLoyaltyPoints": {              "Type": "Task",              "Resource": "arn:aws:states:::lambda:invoke",              "OutputPath": "$.Payload",              "Parameters": {                "Payload.$": "$"              },              "Retry": [                {                  "ErrorEquals": [                    "Lambda.ServiceException",                    "Lambda.AWSLambdaException",                    "Lambda.SdkClientException"                  ],                  "IntervalSeconds": 2,                  "MaxAttempts": 6,                  "BackoffRate": 2                }              ],              "End": true            }          }        },        {          "StartAt": "PrepareOrder",          "States": {            "PrepareOrder": {              "Type": "Task",              "Resource": "arn:aws:states:::lambda:invoke",              "OutputPath": "$.Payload",              "Parameters": {                "Payload.$": "$"              },              "Retry": [                {                  "ErrorEquals": [                    "Lambda.ServiceException",                    "Lambda.AWSLambdaException",                    "Lambda.SdkClientException"                  ],                  "IntervalSeconds": 2,                  "MaxAttempts": 6,                  "BackoffRate": 2                }              ],              "Next": "SendToShipment"            },            "SendToShipment": {              "Type": "Task",              "Resource": "arn:aws:states:::lambda:invoke",              "OutputPath": "$.Payload",              "Parameters": {                "Payload.$": "$"              },              "Retry": [                {                  "ErrorEquals": [                    "Lambda.ServiceException",                    "Lambda.AWSLambdaException",                    "Lambda.SdkClientException"                  ],                  "IntervalSeconds": 2,                  "MaxAttempts": 6,                  "BackoffRate": 2                }              ],              "End": true            }          }        },        {          "StartAt": "UpdateRecoEngine",          "States": {            "UpdateRecoEngine": {              "Type": "Task",              "Resource": "arn:aws:states:::lambda:invoke",              "OutputPath": "$.Payload",              "Parameters": {                "Payload.$": "$"              },              "Retry": [                {                  "ErrorEquals": [                    "Lambda.ServiceException",                    "Lambda.AWSLambdaException",                    "Lambda.SdkClientException"                  ],                  "IntervalSeconds": 2,                  "MaxAttempts": 6,                  "BackoffRate": 2                }              ],              "End": true            }          }        }      ],      "Next": "Order Handled"    },    "Order Handled": {      "Type": "Pass",      "End": true    }  }}
  1. Replace the arn:aws:states:::lambda:invoke with lambda that you specifically created in Step 2.

  2. Click Next, review generated code

  3. Click Next and Specify state name, under permissions, select the existing role that you had created earlier, keep the rest setting as default and click create state machine
    image

Order Flow - Final Testing.

So now you are ready with a working state machine and it's time to test.

  1. Go to State Machine and click on View Details
  2. Click on Start Execution
  3. For the test, i have created two types of inputs, book id = 343222 which has inventory and any other number which will not have inventory, lets try it out now.
  4. Enter the below input: (With Inventory)
{  "orderId": "123",  "bookId": "343222"} 

Result is:
** Note it goes to inventory Available flow **
image

  1. Now lets try another input without inventory
{  "orderId": "124",  "bookId": "343122"} 

Result is:
** Note it goes to the book printing flow**
image

Thanks a lot. Hope this helps you with more learning on Step functions. Would love to hear your comments.


Original Link: https://dev.to/aws-builders/aws-step-functions-simple-order-flow-6gn

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To