├── saga-orchestration ├── README.md ├── MakePaymentLambda │ ├── global.json │ ├── src │ │ └── MakePaymentLambda │ │ │ ├── MakePaymentLambda.csproj │ │ │ ├── aws-lambda-tools-defaults.json │ │ │ ├── Function.cs │ │ │ └── Readme.md │ ├── test │ │ └── MakePaymentLambda.Tests │ │ │ ├── MakePaymentLambda.Tests.csproj │ │ │ └── FunctionTest.cs │ ├── MakePaymentLambda.sln │ └── buildspec.yml ├── PlaceOrderLambda │ ├── global.json │ ├── src │ │ └── PlaceOrderLambda │ │ │ ├── PlaceOrderLambda.csproj │ │ │ ├── aws-lambda-tools-defaults.json │ │ │ ├── Readme.md │ │ │ └── Function.cs │ ├── test │ │ └── PlaceOrderLambda.Tests │ │ │ ├── PlaceOrderLambda.Tests.csproj │ │ │ └── FunctionTest.cs │ ├── PlaceOrderLambda.sln │ └── buildspec.yml ├── RemoveOrderLambda │ ├── global.json │ ├── src │ │ └── RemoveOrderLambda │ │ │ ├── RemoveOrderLambda │ │ │ └── src │ │ │ │ └── RemoveOrderLambda.zip │ │ │ ├── RemoveOrderLambda.csproj │ │ │ ├── aws-lambda-tools-defaults.json │ │ │ ├── Readme.md │ │ │ └── Function.cs │ ├── test │ │ └── RemoveOrderLambda.Tests │ │ │ ├── FunctionTest.cs │ │ │ └── RemoveOrderLambda.Tests.csproj │ ├── RemoveOrderLambda.sln │ └── buildspec.yml ├── RevertInventoryLambda │ ├── global.json │ ├── src │ │ └── RevertInventoryLambda │ │ │ ├── RevertInventoryLambda.csproj │ │ │ ├── aws-lambda-tools-defaults.json │ │ │ ├── Readme.md │ │ │ └── Function.cs │ ├── test │ │ └── RevertInventoryLambda.Tests │ │ │ ├── FunctionTest.cs │ │ │ └── RevertInventoryLambda.Tests.csproj │ ├── RevertInventoryLambda.sln │ └── buildspec.yml ├── RevertPaymentLambda │ ├── global.json │ ├── src │ │ └── RevertPaymentLambda │ │ │ ├── RevertPaymentLambda.csproj │ │ │ ├── aws-lambda-tools-defaults.json │ │ │ ├── Function.cs │ │ │ └── Readme.md │ ├── test │ │ └── RevertPaymentLambda.Tests │ │ │ ├── FunctionTest.cs │ │ │ └── RevertPaymentLambda.Tests.csproj │ ├── RevertPaymentLambda.sln │ └── buildspec.yml ├── SendNotificationLambda │ ├── global.json │ ├── src │ │ └── SendNotificationLambda │ │ │ ├── SendNotificationLambda.csproj │ │ │ ├── aws-lambda-tools-defaults.json │ │ │ ├── Function.cs │ │ │ └── Readme.md │ ├── test │ │ └── SendNotificationLambda.Tests │ │ │ ├── FunctionTest.cs │ │ │ └── SendNotificationLambda.Tests.csproj │ ├── SendNotificationLambda.sln │ └── buildspec.yml ├── UpdateInventoryLambda │ ├── global.json │ ├── src │ │ └── UpdateInventoryLambda │ │ │ ├── UpdateInventoryLambda.csproj │ │ │ ├── aws-lambda-tools-defaults.json │ │ │ ├── Readme.md │ │ │ └── Function.cs │ ├── test │ │ └── UpdateInventoryLambda.Tests │ │ │ ├── UpdateInventoryLambda.Tests.csproj │ │ │ └── FunctionTest.cs │ ├── UpdateInventoryLambda.sln │ └── buildspec.yml ├── InvokeOrchestratorLambda │ ├── global.json │ ├── src │ │ └── InvokeOrchestratorLambda │ │ │ ├── aws-lambda-tools-defaults.json │ │ │ ├── InvokeOrchestratorLambda.csproj │ │ │ ├── Readme.md │ │ │ └── Function.cs │ ├── test │ │ └── InvokeOrchestratorLambda.Tests │ │ │ ├── FunctionTest.cs │ │ │ └── InvokeOrchestratorLambda.Tests.csproj │ ├── buildspec.yml │ └── InvokeOrchestratorLambda.sln └── LICENSE ├── images ├── orders.png ├── cfn_stack.png ├── inventory.png ├── step_output.png ├── dynamodb_console.png ├── postman_output.png ├── postman_settings.png ├── apigateway_endpoint.png ├── directory_structure.png ├── dynamodb_createitem.png ├── statemachine_success.png ├── stepfunctions_graph.png ├── orders_aftercompensation.png ├── orders_beforecompensation.png ├── statemachine_compensation.png ├── inventory_aftercompensation.png └── inventory_beforecompensation.png ├── cdk-saga-orchestration ├── src │ ├── global.json │ ├── CdkSagaOrchestration │ │ ├── GlobalSuppressions.cs │ │ ├── Program.cs │ │ ├── CdkSagaOrchestration.csproj │ │ └── CdkSagaOrchestrationStack.cs │ └── CdkSagaOrchestration.sln ├── cdk.json ├── LICENSE └── README.md ├── CODE_OF_CONDUCT.md ├── LICENSE ├── .gitignore ├── CONTRIBUTING.md └── README.md /saga-orchestration/README.md: -------------------------------------------------------------------------------- 1 | # saga-orchestration 2 | 3 | -------------------------------------------------------------------------------- /images/orders.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/saga-orchestration-netcore-blog/HEAD/images/orders.png -------------------------------------------------------------------------------- /images/cfn_stack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/saga-orchestration-netcore-blog/HEAD/images/cfn_stack.png -------------------------------------------------------------------------------- /images/inventory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/saga-orchestration-netcore-blog/HEAD/images/inventory.png -------------------------------------------------------------------------------- /images/step_output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/saga-orchestration-netcore-blog/HEAD/images/step_output.png -------------------------------------------------------------------------------- /images/dynamodb_console.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/saga-orchestration-netcore-blog/HEAD/images/dynamodb_console.png -------------------------------------------------------------------------------- /images/postman_output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/saga-orchestration-netcore-blog/HEAD/images/postman_output.png -------------------------------------------------------------------------------- /images/postman_settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/saga-orchestration-netcore-blog/HEAD/images/postman_settings.png -------------------------------------------------------------------------------- /images/apigateway_endpoint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/saga-orchestration-netcore-blog/HEAD/images/apigateway_endpoint.png -------------------------------------------------------------------------------- /images/directory_structure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/saga-orchestration-netcore-blog/HEAD/images/directory_structure.png -------------------------------------------------------------------------------- /images/dynamodb_createitem.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/saga-orchestration-netcore-blog/HEAD/images/dynamodb_createitem.png -------------------------------------------------------------------------------- /images/statemachine_success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/saga-orchestration-netcore-blog/HEAD/images/statemachine_success.png -------------------------------------------------------------------------------- /images/stepfunctions_graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/saga-orchestration-netcore-blog/HEAD/images/stepfunctions_graph.png -------------------------------------------------------------------------------- /images/orders_aftercompensation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/saga-orchestration-netcore-blog/HEAD/images/orders_aftercompensation.png -------------------------------------------------------------------------------- /images/orders_beforecompensation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/saga-orchestration-netcore-blog/HEAD/images/orders_beforecompensation.png -------------------------------------------------------------------------------- /images/statemachine_compensation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/saga-orchestration-netcore-blog/HEAD/images/statemachine_compensation.png -------------------------------------------------------------------------------- /images/inventory_aftercompensation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/saga-orchestration-netcore-blog/HEAD/images/inventory_aftercompensation.png -------------------------------------------------------------------------------- /images/inventory_beforecompensation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/saga-orchestration-netcore-blog/HEAD/images/inventory_beforecompensation.png -------------------------------------------------------------------------------- /cdk-saga-orchestration/src/global.json: -------------------------------------------------------------------------------- 1 | { 2 | "sdk": { 3 | "version": "6.0.0", 4 | "rollForward": "latestMajor", 5 | "allowPrerelease": false 6 | } 7 | } -------------------------------------------------------------------------------- /saga-orchestration/MakePaymentLambda/global.json: -------------------------------------------------------------------------------- 1 | { 2 | "sdk": { 3 | "version": "6.0.0", 4 | "rollForward": "latestMajor", 5 | "allowPrerelease": false 6 | } 7 | } -------------------------------------------------------------------------------- /saga-orchestration/PlaceOrderLambda/global.json: -------------------------------------------------------------------------------- 1 | { 2 | "sdk": { 3 | "version": "6.0.0", 4 | "rollForward": "latestMajor", 5 | "allowPrerelease": false 6 | } 7 | } -------------------------------------------------------------------------------- /saga-orchestration/RemoveOrderLambda/global.json: -------------------------------------------------------------------------------- 1 | { 2 | "sdk": { 3 | "version": "6.0.0", 4 | "rollForward": "latestMajor", 5 | "allowPrerelease": false 6 | } 7 | } -------------------------------------------------------------------------------- /saga-orchestration/RevertInventoryLambda/global.json: -------------------------------------------------------------------------------- 1 | { 2 | "sdk": { 3 | "version": "6.0.0", 4 | "rollForward": "latestMajor", 5 | "allowPrerelease": false 6 | } 7 | } -------------------------------------------------------------------------------- /saga-orchestration/RevertPaymentLambda/global.json: -------------------------------------------------------------------------------- 1 | { 2 | "sdk": { 3 | "version": "6.0.0", 4 | "rollForward": "latestMajor", 5 | "allowPrerelease": false 6 | } 7 | } -------------------------------------------------------------------------------- /saga-orchestration/SendNotificationLambda/global.json: -------------------------------------------------------------------------------- 1 | { 2 | "sdk": { 3 | "version": "6.0.0", 4 | "rollForward": "latestMajor", 5 | "allowPrerelease": false 6 | } 7 | } -------------------------------------------------------------------------------- /saga-orchestration/UpdateInventoryLambda/global.json: -------------------------------------------------------------------------------- 1 | { 2 | "sdk": { 3 | "version": "6.0.0", 4 | "rollForward": "latestMajor", 5 | "allowPrerelease": true 6 | } 7 | } -------------------------------------------------------------------------------- /saga-orchestration/InvokeOrchestratorLambda/global.json: -------------------------------------------------------------------------------- 1 | { 2 | "sdk": { 3 | "version": "6.0.0", 4 | "rollForward": "latestMajor", 5 | "allowPrerelease": false 6 | } 7 | } -------------------------------------------------------------------------------- /saga-orchestration/RemoveOrderLambda/src/RemoveOrderLambda/RemoveOrderLambda/src/RemoveOrderLambda.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aws-samples/saga-orchestration-netcore-blog/HEAD/saga-orchestration/RemoveOrderLambda/src/RemoveOrderLambda/RemoveOrderLambda/src/RemoveOrderLambda.zip -------------------------------------------------------------------------------- /cdk-saga-orchestration/src/CdkSagaOrchestration/GlobalSuppressions.cs: -------------------------------------------------------------------------------- 1 | [assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Potential Code Quality Issues", "RECS0026:Possible unassigned object created by 'new'", Justification = "Constructs add themselves to the scope in which they are created")] 2 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | ## Code of Conduct 2 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 3 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 4 | opensource-codeofconduct@amazon.com with any additional questions or comments. 5 | -------------------------------------------------------------------------------- /cdk-saga-orchestration/src/CdkSagaOrchestration/Program.cs: -------------------------------------------------------------------------------- 1 | using Amazon.CDK; 2 | 3 | namespace CdkSagaOrchestration 4 | { 5 | sealed class Program 6 | { 7 | public static void Main(string[] args) 8 | { 9 | var app = new App(); 10 | new CdkSagaOrchestrationStack(app, "CdkSagaOrchestrationStack"); 11 | 12 | app.Synth(); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /cdk-saga-orchestration/src/CdkSagaOrchestration/CdkSagaOrchestration.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net6.0 6 | 7 | Major 8 | default 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /saga-orchestration/UpdateInventoryLambda/src/UpdateInventoryLambda/UpdateInventoryLambda.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net6.0 4 | true 5 | Lambda 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /saga-orchestration/MakePaymentLambda/src/MakePaymentLambda/MakePaymentLambda.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net6.0 4 | true 5 | Lambda 6 | default 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /saga-orchestration/RevertPaymentLambda/src/RevertPaymentLambda/RevertPaymentLambda.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net6.0 4 | true 5 | Lambda 6 | default 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /saga-orchestration/SendNotificationLambda/src/SendNotificationLambda/SendNotificationLambda.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net6.0 4 | true 5 | Lambda 6 | default 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /saga-orchestration/PlaceOrderLambda/src/PlaceOrderLambda/PlaceOrderLambda.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net6.0 4 | true 5 | Lambda 6 | default 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /saga-orchestration/RevertInventoryLambda/src/RevertInventoryLambda/RevertInventoryLambda.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net6.0 4 | true 5 | Lambda 6 | default 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /cdk-saga-orchestration/cdk.json: -------------------------------------------------------------------------------- 1 | { 2 | "app": "dotnet run -p src/CdkSagaOrchestration/CdkSagaOrchestration.csproj", 3 | "context": { 4 | "@aws-cdk/aws-apigateway:usagePlanKeyOrderInsensitiveId": true, 5 | "aws-cdk:enableDiffNoFail": "true", 6 | "@aws-cdk/core:stackRelativeExports": "true", 7 | "@aws-cdk/aws-ecr-assets:dockerIgnoreSupport": true, 8 | "@aws-cdk/aws-secretsmanager:parseOwnedSecretName": true, 9 | "@aws-cdk/aws-kms:defaultKeyPolicies": true, 10 | "@aws-cdk/aws-s3:grantWriteWithoutAcl": true, 11 | "@aws-cdk/aws-ecs-patterns:removeDefaultDesiredCount": true, 12 | "@aws-cdk/aws-rds:lowercaseDbIdentifier": true, 13 | "@aws-cdk/aws-efs:defaultEncryptionAtRest": true 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /saga-orchestration/RemoveOrderLambda/src/RemoveOrderLambda/RemoveOrderLambda.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net6.0 4 | true 5 | Lambda 6 | default 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /saga-orchestration/RemoveOrderLambda/src/RemoveOrderLambda/aws-lambda-tools-defaults.json: -------------------------------------------------------------------------------- 1 | { 2 | "Information": [ 3 | "This file provides default values for the deployment wizard inside Visual Studio and the AWS Lambda commands added to the .NET Core CLI.", 4 | "To learn more about the Lambda commands with the .NET Core CLI execute the following command at the command line in the project root directory.", 5 | "dotnet lambda help", 6 | "All the command line options for the Lambda command can be specified in this file." 7 | ], 8 | "profile": "", 9 | "region": "", 10 | "configuration": "Release", 11 | "framework": "net6.0", 12 | "function-runtime": "dotnet6", 13 | "function-memory-size": 256, 14 | "function-timeout": 30, 15 | "function-handler": "RemoveOrderLambda::RemoveOrderLambda.RemoveOrder::FunctionHandler" 16 | } -------------------------------------------------------------------------------- /saga-orchestration/SendNotificationLambda/test/SendNotificationLambda.Tests/FunctionTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Xunit; 6 | using Amazon.Lambda.Core; 7 | using Amazon.Lambda.TestUtilities; 8 | using SendNotificationLambda; 9 | 10 | namespace SendNotificationLambda.Tests 11 | { 12 | public class FunctionTest 13 | { 14 | [Fact] 15 | public void TestToUpperFunction() 16 | { 17 | // Invoke the lambda function and confirm the string was upper cased. 18 | var function = new SendNotification(); 19 | var context = new TestLambdaContext(); 20 | var result = function.FunctionHandler(context); 21 | 22 | Assert.Equal("SUCCESS", result.Status); 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /saga-orchestration/RevertPaymentLambda/src/RevertPaymentLambda/aws-lambda-tools-defaults.json: -------------------------------------------------------------------------------- 1 | { 2 | "Information": [ 3 | "This file provides default values for the deployment wizard inside Visual Studio and the AWS Lambda commands added to the .NET Core CLI.", 4 | "To learn more about the Lambda commands with the .NET Core CLI execute the following command at the command line in the project root directory.", 5 | "dotnet lambda help", 6 | "All the command line options for the Lambda command can be specified in this file." 7 | ], 8 | "profile": "", 9 | "region": "", 10 | "configuration": "Release", 11 | "framework": "net6.0", 12 | "function-runtime": "dotnet6", 13 | "function-memory-size": 256, 14 | "function-timeout": 30, 15 | "function-handler": "RevertPaymentLambda::RevertPaymentLambda.RevertPayment::FunctionHandler" 16 | } -------------------------------------------------------------------------------- /saga-orchestration/PlaceOrderLambda/src/PlaceOrderLambda/aws-lambda-tools-defaults.json: -------------------------------------------------------------------------------- 1 | { 2 | "Information": [ 3 | "This file provides default values for the deployment wizard inside Visual Studio and the AWS Lambda commands added to the .NET Core CLI.", 4 | "To learn more about the Lambda commands with the .NET Core CLI execute the following command at the command line in the project root directory.", 5 | "dotnet lambda help", 6 | "All the command line options for the Lambda command can be specified in this file." 7 | ], 8 | "profile": "default", 9 | "region": "ap-southeast-2", 10 | "configuration": "Release", 11 | "framework": "net6.0", 12 | "function-runtime": "dotnet6", 13 | "function-memory-size": 256, 14 | "function-timeout": 90, 15 | "function-handler": "PlaceOrderLambda::PlaceOrderLambda.PlaceOrder::FunctionHandler" 16 | } -------------------------------------------------------------------------------- /saga-orchestration/MakePaymentLambda/src/MakePaymentLambda/aws-lambda-tools-defaults.json: -------------------------------------------------------------------------------- 1 | { 2 | "Information": [ 3 | "This file provides default values for the deployment wizard inside Visual Studio and the AWS Lambda commands added to the .NET Core CLI.", 4 | "To learn more about the Lambda commands with the .NET Core CLI execute the following command at the command line in the project root directory.", 5 | "dotnet lambda help", 6 | "All the command line options for the Lambda command can be specified in this file." 7 | ], 8 | "profile": "default", 9 | "region": "ap-southeast-2", 10 | "configuration": "Release", 11 | "framework": "net6.0", 12 | "function-runtime": "dotnet6", 13 | "function-memory-size": 256, 14 | "function-timeout": 30, 15 | "function-handler": "MakePaymentLambda::MakePaymentLambda.MakePayment::FunctionHandler" 16 | } -------------------------------------------------------------------------------- /saga-orchestration/RevertInventoryLambda/src/RevertInventoryLambda/aws-lambda-tools-defaults.json: -------------------------------------------------------------------------------- 1 | { 2 | "Information": [ 3 | "This file provides default values for the deployment wizard inside Visual Studio and the AWS Lambda commands added to the .NET Core CLI.", 4 | "To learn more about the Lambda commands with the .NET Core CLI execute the following command at the command line in the project root directory.", 5 | "dotnet lambda help", 6 | "All the command line options for the Lambda command can be specified in this file." 7 | ], 8 | "profile": "", 9 | "region": "", 10 | "configuration": "Release", 11 | "framework": "net6.0", 12 | "function-runtime": "dotnet6", 13 | "function-memory-size": 256, 14 | "function-timeout": 30, 15 | "function-handler": "RevertInventoryLambda::RevertInventoryLambda.RevertInventory::FunctionHandler" 16 | } -------------------------------------------------------------------------------- /saga-orchestration/InvokeOrchestratorLambda/src/InvokeOrchestratorLambda/aws-lambda-tools-defaults.json: -------------------------------------------------------------------------------- 1 | { 2 | "Information": [ 3 | "This file provides default values for the deployment wizard inside Visual Studio and the AWS Lambda commands added to the .NET Core CLI.", 4 | "To learn more about the Lambda commands with the .NET Core CLI execute the following command at the command line in the project root directory.", 5 | "dotnet lambda help", 6 | "All the command line options for the Lambda command can be specified in this file." 7 | ], 8 | "profile": "", 9 | "region": "", 10 | "configuration": "Release", 11 | "framework": "net6.0", 12 | "function-runtime": "dotnet6", 13 | "function-memory-size": 256, 14 | "function-timeout": 30, 15 | "function-handler": "InvokeOrchestratorLambda::InvokeOrchestratorLambda.InvokeOrchestrator::FunctionHandler" 16 | } -------------------------------------------------------------------------------- /saga-orchestration/UpdateInventoryLambda/src/UpdateInventoryLambda/aws-lambda-tools-defaults.json: -------------------------------------------------------------------------------- 1 | { 2 | "Information": [ 3 | "This file provides default values for the deployment wizard inside Visual Studio and the AWS Lambda commands added to the .NET Core CLI.", 4 | "To learn more about the Lambda commands with the .NET Core CLI execute the following command at the command line in the project root directory.", 5 | "dotnet lambda help", 6 | "All the command line options for the Lambda command can be specified in this file." 7 | ], 8 | "profile": "default", 9 | "region": "ap-southeast-2", 10 | "configuration": "Release", 11 | "framework": "net6.0", 12 | "function-runtime": "dotnet6", 13 | "function-memory-size": 256, 14 | "function-timeout": 60, 15 | "function-handler": "UpdateInventoryLambda::UpdateInventoryLambda.UpdateInventory::FunctionHandler" 16 | } -------------------------------------------------------------------------------- /saga-orchestration/RemoveOrderLambda/test/RemoveOrderLambda.Tests/FunctionTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Xunit; 6 | using Amazon.Lambda.Core; 7 | using Amazon.Lambda.TestUtilities; 8 | using RemoveOrderLambda; 9 | 10 | namespace RemoveOrderLambda.Tests 11 | { 12 | public class RemoveOrderLambdaShould 13 | { 14 | [Fact] 15 | public void RemovePlacedOrder() 16 | { 17 | var function = new RemoveOrder(); 18 | var context = new TestLambdaContext(); 19 | var orderDetails = new OrderDetails {ItemId = "ABC/001", FailAtStage = "RevertInventory", Status = "ERROR"}; 20 | var outputObj = function.FunctionHandler(orderDetails, context); 21 | 22 | Assert.Equal("ORDER_REMOVED", outputObj); 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /saga-orchestration/SendNotificationLambda/src/SendNotificationLambda/aws-lambda-tools-defaults.json: -------------------------------------------------------------------------------- 1 | { 2 | "Information": [ 3 | "This file provides default values for the deployment wizard inside Visual Studio and the AWS Lambda commands added to the .NET Core CLI.", 4 | "To learn more about the Lambda commands with the .NET Core CLI execute the following command at the command line in the project root directory.", 5 | "dotnet lambda help", 6 | "All the command line options for the Lambda command can be specified in this file." 7 | ], 8 | "profile": "default", 9 | "region": "ap-southeast-2", 10 | "configuration": "Release", 11 | "framework": "net6.0", 12 | "function-runtime": "dotnet6", 13 | "function-memory-size": 256, 14 | "function-timeout": 30, 15 | "function-handler": "SendNotificationLambda::SendNotificationLambda.SendNotification::FunctionHandler" 16 | } -------------------------------------------------------------------------------- /saga-orchestration/InvokeOrchestratorLambda/test/InvokeOrchestratorLambda.Tests/FunctionTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Xunit; 6 | using Amazon.Lambda.Core; 7 | using Amazon.Lambda.TestUtilities; 8 | using InvokeOrchestratorLambda; 9 | 10 | namespace InvokeOrchestratorLambda.Tests 11 | { 12 | public class InvokeOrchestratorShould 13 | { 14 | // [Fact] 15 | // public void TestToUpperFunction() 16 | // { 17 | // // Invoke the lambda function and confirm the string was upper cased. 18 | // var function = new InvokeOrchestrator(); 19 | // var context = new TestLambdaContext(); 20 | // var retValue = function.FunctionHandler("hello world", context); 21 | // 22 | // Assert.True(retValue.Result); 23 | // } 24 | } 25 | } -------------------------------------------------------------------------------- /saga-orchestration/RevertInventoryLambda/test/RevertInventoryLambda.Tests/FunctionTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Xunit; 6 | using Amazon.Lambda.Core; 7 | using Amazon.Lambda.TestUtilities; 8 | using RevertInventoryLambda; 9 | 10 | namespace RevertInventoryLambda.Tests 11 | { 12 | public class RevertInventoryLambdaShould 13 | { 14 | [Fact] 15 | public void RevertInventory() 16 | { 17 | var function = new RevertInventory(); 18 | var context = new TestLambdaContext(); 19 | var orderDetails = new OrderDetails {ItemId = "ABC/001", FailAtStage = "RevertInventory", Status = "ERROR"}; 20 | var outputObj = function.FunctionHandler(orderDetails, context); 21 | 22 | Assert.Equal("INVENTORY_REVERTED", outputObj.Status); 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software is furnished to do so. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 10 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 11 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 12 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 13 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 14 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 15 | 16 | -------------------------------------------------------------------------------- /saga-orchestration/RevertPaymentLambda/test/RevertPaymentLambda.Tests/FunctionTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Xunit; 6 | using Amazon.Lambda.Core; 7 | using Amazon.Lambda.TestUtilities; 8 | using RevertPaymentLambda; 9 | 10 | namespace RevertPaymentLambda.Tests 11 | { 12 | public class RevertPaymentShould 13 | { 14 | [Fact] 15 | public void ReturnRevertedOnSuccess() 16 | { 17 | // Invoke the lambda function and confirm the string was upper cased. 18 | var function = new RevertPayment(); 19 | var context = new TestLambdaContext(); 20 | var inputObj = new OrderDetails {ItemId = "ABC/001", CustomerId = "SGP/010", FailAtStage = "None"}; 21 | 22 | var retValue = function.FunctionHandler(inputObj,context); 23 | Assert.Equal("PAYMENT_REVERTED", retValue.Status); 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /saga-orchestration/InvokeOrchestratorLambda/src/InvokeOrchestratorLambda/InvokeOrchestratorLambda.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net6.0 4 | true 5 | Lambda 6 | default 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /saga-orchestration/SendNotificationLambda/src/SendNotificationLambda/Function.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Amazon.Lambda.Core; 6 | 7 | // Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class. 8 | [assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] 9 | 10 | namespace SendNotificationLambda 11 | { 12 | public class SendNotification 13 | { 14 | public SendNotificationResult FunctionHandler(ILambdaContext context) 15 | { 16 | context.Logger.Log("In SendNotificationLambda"); 17 | var result = new SendNotificationResult {Status = "SUCCESS"}; 18 | context.Logger.Log("After setting result to success"); 19 | return result; 20 | } 21 | 22 | public class SendNotificationResult 23 | { 24 | public string Status { get; set; } 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /saga-orchestration/MakePaymentLambda/test/MakePaymentLambda.Tests/MakePaymentLambda.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net6.0 4 | default 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | all 13 | runtime; build; native; contentfiles; analyzers; buildtransitive 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /saga-orchestration/RemoveOrderLambda/test/RemoveOrderLambda.Tests/RemoveOrderLambda.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net6.0 4 | default 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | all 13 | runtime; build; native; contentfiles; analyzers; buildtransitive 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /saga-orchestration/RevertPaymentLambda/test/RevertPaymentLambda.Tests/RevertPaymentLambda.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net6.0 4 | default 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | all 13 | runtime; build; native; contentfiles; analyzers; buildtransitive 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /saga-orchestration/RevertInventoryLambda/test/RevertInventoryLambda.Tests/RevertInventoryLambda.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net6.0 4 | default 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | all 13 | runtime; build; native; contentfiles; analyzers; buildtransitive 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /saga-orchestration/UpdateInventoryLambda/test/UpdateInventoryLambda.Tests/UpdateInventoryLambda.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net6.0 4 | default 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | all 13 | runtime; build; native; contentfiles; analyzers; buildtransitive 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /saga-orchestration/SendNotificationLambda/test/SendNotificationLambda.Tests/SendNotificationLambda.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net6.0 4 | default 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | all 13 | runtime; build; native; contentfiles; analyzers; buildtransitive 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /saga-orchestration/InvokeOrchestratorLambda/test/InvokeOrchestratorLambda.Tests/InvokeOrchestratorLambda.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net6.0 4 | default 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | all 13 | runtime; build; native; contentfiles; analyzers; buildtransitive 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /saga-orchestration/RevertPaymentLambda/src/RevertPaymentLambda/Function.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Amazon.Lambda.Core; 6 | 7 | // Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class. 8 | [assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] 9 | 10 | namespace RevertPaymentLambda 11 | { 12 | public class RevertPayment 13 | { 14 | public OrderDetails FunctionHandler(OrderDetails orderDetails, ILambdaContext context) 15 | { 16 | var status = "PAYMENT_REVERTED"; 17 | orderDetails.Status = status; 18 | return orderDetails; 19 | } 20 | } 21 | 22 | public class OrderDetails 23 | { 24 | public string ItemId { get; set; } 25 | public string CustomerId { get; set; } 26 | public string MessageId { get; set; } 27 | public string FailAtStage { get; set; } 28 | public string Status { get; set; } 29 | } 30 | } -------------------------------------------------------------------------------- /cdk-saga-orchestration/LICENSE: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: MIT-0 3 | 4 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of this 7 | software and associated documentation files (the "Software"), to deal in the Software 8 | without restriction, including without limitation the rights to use, copy, modify, 9 | merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so. 11 | 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 14 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 15 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 16 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 17 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | 19 | -------------------------------------------------------------------------------- /saga-orchestration/LICENSE: -------------------------------------------------------------------------------- 1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 2 | // SPDX-License-Identifier: MIT-0 3 | 4 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of this 7 | software and associated documentation files (the "Software"), to deal in the Software 8 | without restriction, including without limitation the rights to use, copy, modify, 9 | merge, publish, distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so. 11 | 12 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 13 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 14 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 15 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 16 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 17 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 18 | 19 | -------------------------------------------------------------------------------- /saga-orchestration/PlaceOrderLambda/test/PlaceOrderLambda.Tests/PlaceOrderLambda.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net6.0 4 | default 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | all 14 | runtime; build; native; contentfiles; analyzers; buildtransitive 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /cdk-saga-orchestration/README.md: -------------------------------------------------------------------------------- 1 | # Welcome to your CDK C# project! 2 | 3 | The `cdk.json` file tells the CDK Toolkit how to execute your app. 4 | 5 | It uses the [.NET Core CLI](https://docs.microsoft.com/dotnet/articles/core/) to compile and execute your project. 6 | 7 | ## Useful commands 8 | 9 | * `dotnet build src` compile this app 10 | * `cdk deploy` deploy this stack to your default AWS account/region 11 | * `cdk diff` compare deployed stack with current state 12 | * `cdk synth` emits the synthesized CloudFormation template 13 | 14 | The saga-orchestration project contains the code for the individual lambda functions. The lambda functions should be compiled and packaged using the following commands. 15 | 16 | * `dotnet build src` 17 | * `dotnet lambda package` 18 | 19 | The packaged lambda function zip file will be present in the bin/Release/netcoreapp3.1 folder. 20 | 21 | Once packaged, create a folder called "lambdas" in the directory where cdk.json file is present. Copy the packaged lambda functions to this folder. The packaged lambda functions (zip files) should be present here for CDK to deploy to the AWS environment. 22 | -------------------------------------------------------------------------------- /saga-orchestration/MakePaymentLambda/test/MakePaymentLambda.Tests/FunctionTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Xunit; 6 | using Amazon.Lambda.Core; 7 | using Amazon.Lambda.TestUtilities; 8 | using MakePaymentLambda; 9 | 10 | namespace MakePaymentLambda.Tests 11 | { 12 | public class FunctionTest 13 | { 14 | [Fact] 15 | public void TestSuccessScenario() 16 | { 17 | var function = new MakePayment(); 18 | var context = new TestLambdaContext(); 19 | var inputObj = new OrderDetails {ItemId = "ABC/001", FailAtStage = "None"}; 20 | var retValue = function.FunctionHandler(inputObj,context); 21 | 22 | Assert.Equal("PAYMENT_COMPLETED", retValue.Status); 23 | } 24 | 25 | 26 | [Fact] 27 | public void TestFailureScenario() 28 | { 29 | var function = new MakePayment(); 30 | var context = new TestLambdaContext(); 31 | var inputObj = new OrderDetails {ItemId = "ABC/001", CustomerId = "SGP/010", FailAtStage = "MakePayment"}; 32 | 33 | var retValue = function.FunctionHandler(inputObj,context); 34 | Assert.Equal("ERROR", retValue.Status); 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /saga-orchestration/PlaceOrderLambda/PlaceOrderLambda.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlaceOrderLambda.Tests", "test\PlaceOrderLambda.Tests\PlaceOrderLambda.Tests.csproj", "{570B97B9-D4B3-4C9B-89B2-D223FC2BC92B}" 4 | EndProject 5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlaceOrderLambda", "src\PlaceOrderLambda\PlaceOrderLambda.csproj", "{5FC60B53-D626-44E0-AF61-5E6C716C373F}" 6 | EndProject 7 | Global 8 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 9 | Debug|Any CPU = Debug|Any CPU 10 | Release|Any CPU = Release|Any CPU 11 | EndGlobalSection 12 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 13 | {570B97B9-D4B3-4C9B-89B2-D223FC2BC92B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 14 | {570B97B9-D4B3-4C9B-89B2-D223FC2BC92B}.Debug|Any CPU.Build.0 = Debug|Any CPU 15 | {570B97B9-D4B3-4C9B-89B2-D223FC2BC92B}.Release|Any CPU.ActiveCfg = Release|Any CPU 16 | {570B97B9-D4B3-4C9B-89B2-D223FC2BC92B}.Release|Any CPU.Build.0 = Release|Any CPU 17 | {5FC60B53-D626-44E0-AF61-5E6C716C373F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 18 | {5FC60B53-D626-44E0-AF61-5E6C716C373F}.Debug|Any CPU.Build.0 = Debug|Any CPU 19 | {5FC60B53-D626-44E0-AF61-5E6C716C373F}.Release|Any CPU.ActiveCfg = Release|Any CPU 20 | {5FC60B53-D626-44E0-AF61-5E6C716C373F}.Release|Any CPU.Build.0 = Release|Any CPU 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /saga-orchestration/MakePaymentLambda/MakePaymentLambda.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MakePaymentLambda.Tests", "test\MakePaymentLambda.Tests\MakePaymentLambda.Tests.csproj", "{35568729-84AB-4D11-998B-AB3BDD2E5B89}" 4 | EndProject 5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MakePaymentLambda", "src\MakePaymentLambda\MakePaymentLambda.csproj", "{E9004A8C-D024-49EA-833F-A88DA8C9DF44}" 6 | EndProject 7 | Global 8 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 9 | Debug|Any CPU = Debug|Any CPU 10 | Release|Any CPU = Release|Any CPU 11 | EndGlobalSection 12 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 13 | {35568729-84AB-4D11-998B-AB3BDD2E5B89}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 14 | {35568729-84AB-4D11-998B-AB3BDD2E5B89}.Debug|Any CPU.Build.0 = Debug|Any CPU 15 | {35568729-84AB-4D11-998B-AB3BDD2E5B89}.Release|Any CPU.ActiveCfg = Release|Any CPU 16 | {35568729-84AB-4D11-998B-AB3BDD2E5B89}.Release|Any CPU.Build.0 = Release|Any CPU 17 | {E9004A8C-D024-49EA-833F-A88DA8C9DF44}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 18 | {E9004A8C-D024-49EA-833F-A88DA8C9DF44}.Debug|Any CPU.Build.0 = Debug|Any CPU 19 | {E9004A8C-D024-49EA-833F-A88DA8C9DF44}.Release|Any CPU.ActiveCfg = Release|Any CPU 20 | {E9004A8C-D024-49EA-833F-A88DA8C9DF44}.Release|Any CPU.Build.0 = Release|Any CPU 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /saga-orchestration/PlaceOrderLambda/buildspec.yml: -------------------------------------------------------------------------------- 1 | version: 0.2 2 | env: 3 | variables: 4 | DOTNET_ROOT: /root/.dotnet 5 | secrets-manager: 6 | AWS_ACCESS_KEY_ID_PARAM: CodeBuild:AWS_ACCESS_KEY_ID 7 | AWS_SECRET_ACCESS_KEY_PARAM: CodeBuild:AWS_SECRET_ACCESS_KEY 8 | phases: 9 | install: 10 | runtime-versions: 11 | dotnet: 3.1 12 | pre_build: 13 | commands: 14 | - echo Restore started on `date` 15 | - export PATH="$PATH:/root/.dotnet/tools" 16 | - pip install --upgrade pip 17 | - pip install --upgrade awscli 18 | - aws configure set aws_access_key_id $AWS_ACCESS_KEY_ID_PARAM 19 | - aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY_PARAM 20 | 21 | build: 22 | commands: 23 | - DB_IMG_PATH=$PWD 24 | - cd Lambdas/PlaceOrderLambda/src/PlaceOrderLambda 25 | - dotnet clean 26 | - dotnet restore 27 | - echo Build started on `date` 28 | - dotnet new -i Amazon.Lambda.Templates::* 29 | - dotnet tool install -g Amazon.Lambda.Tools 30 | - dotnet tool update -g Amazon.Lambda.Tools 31 | - dotnet build -c Release PlaceOrderLambda.csproj 32 | - dotnet test -c Release ../../test/PlaceOrderLambda.Tests/PlaceOrderLambda.Tests.csproj 33 | - dotnet lambda deploy-function "PlaceOrderLambda" --function-role "arn:aws:iam::119176563765:role/AwsomeLambdaExecutionRole" --region "ap-southeast-2" 34 | - cd "$DB_IMG_PATH" 35 | - pwd -------------------------------------------------------------------------------- /saga-orchestration/RemoveOrderLambda/RemoveOrderLambda.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RemoveOrderLambda.Tests", "test\RemoveOrderLambda.Tests\RemoveOrderLambda.Tests.csproj", "{3DB520F8-D41E-4A59-94D3-7C719E133A71}" 4 | EndProject 5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RemoveOrderLambda", "src\RemoveOrderLambda\RemoveOrderLambda.csproj", "{02B1C84D-F23F-4617-B4A0-1C13DC549B8F}" 6 | EndProject 7 | Global 8 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 9 | Debug|Any CPU = Debug|Any CPU 10 | Release|Any CPU = Release|Any CPU 11 | EndGlobalSection 12 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 13 | {3DB520F8-D41E-4A59-94D3-7C719E133A71}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 14 | {3DB520F8-D41E-4A59-94D3-7C719E133A71}.Debug|Any CPU.Build.0 = Debug|Any CPU 15 | {3DB520F8-D41E-4A59-94D3-7C719E133A71}.Release|Any CPU.ActiveCfg = Release|Any CPU 16 | {3DB520F8-D41E-4A59-94D3-7C719E133A71}.Release|Any CPU.Build.0 = Release|Any CPU 17 | {02B1C84D-F23F-4617-B4A0-1C13DC549B8F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 18 | {02B1C84D-F23F-4617-B4A0-1C13DC549B8F}.Debug|Any CPU.Build.0 = Debug|Any CPU 19 | {02B1C84D-F23F-4617-B4A0-1C13DC549B8F}.Release|Any CPU.ActiveCfg = Release|Any CPU 20 | {02B1C84D-F23F-4617-B4A0-1C13DC549B8F}.Release|Any CPU.Build.0 = Release|Any CPU 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /saga-orchestration/MakePaymentLambda/buildspec.yml: -------------------------------------------------------------------------------- 1 | version: 0.2 2 | env: 3 | variables: 4 | DOTNET_ROOT: /root/.dotnet 5 | secrets-manager: 6 | AWS_ACCESS_KEY_ID_PARAM: CodeBuild:AWS_ACCESS_KEY_ID 7 | AWS_SECRET_ACCESS_KEY_PARAM: CodeBuild:AWS_SECRET_ACCESS_KEY 8 | phases: 9 | install: 10 | runtime-versions: 11 | dotnet: 3.1 12 | pre_build: 13 | commands: 14 | - echo Restore started on `date` 15 | - export PATH="$PATH:/root/.dotnet/tools" 16 | - pip install --upgrade pip 17 | - pip install --upgrade awscli 18 | - aws configure set aws_access_key_id $AWS_ACCESS_KEY_ID_PARAM 19 | - aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY_PARAM 20 | 21 | build: 22 | commands: 23 | - DB_IMG_PATH=$PWD 24 | - cd Lambdas/MakePaymentLambda/src/MakePaymentLambda 25 | - dotnet clean 26 | - dotnet restore 27 | - echo Build started on `date` 28 | - dotnet new -i Amazon.Lambda.Templates::* 29 | - dotnet tool install -g Amazon.Lambda.Tools 30 | - dotnet tool update -g Amazon.Lambda.Tools 31 | - dotnet build -c Release MakePaymentLambda.csproj 32 | - dotnet test -c Release ../../test/MakePaymentLambda.Tests/MakePaymentLambda.Tests.csproj 33 | - dotnet lambda deploy-function "MakePaymentLambda" --function-role "arn:aws:iam::119176563765:role/AwsomeLambdaExecutionRole" --region "ap-southeast-2" 34 | - cd "$DB_IMG_PATH" 35 | - pwd -------------------------------------------------------------------------------- /saga-orchestration/RemoveOrderLambda/buildspec.yml: -------------------------------------------------------------------------------- 1 | version: 0.2 2 | env: 3 | variables: 4 | DOTNET_ROOT: /root/.dotnet 5 | secrets-manager: 6 | AWS_ACCESS_KEY_ID_PARAM: CodeBuild:AWS_ACCESS_KEY_ID 7 | AWS_SECRET_ACCESS_KEY_PARAM: CodeBuild:AWS_SECRET_ACCESS_KEY 8 | phases: 9 | install: 10 | runtime-versions: 11 | dotnet: 3.1 12 | pre_build: 13 | commands: 14 | - echo Restore started on `date` 15 | - export PATH="$PATH:/root/.dotnet/tools" 16 | - pip install --upgrade pip 17 | - pip install --upgrade awscli 18 | - aws configure set aws_access_key_id $AWS_ACCESS_KEY_ID_PARAM 19 | - aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY_PARAM 20 | 21 | build: 22 | commands: 23 | - DB_IMG_PATH=$PWD 24 | - cd Lambdas/RemoveOrderLambda/src/RemoveOrderLambda 25 | - dotnet clean 26 | - dotnet restore 27 | - echo Build started on `date` 28 | - dotnet new -i Amazon.Lambda.Templates::* 29 | - dotnet tool install -g Amazon.Lambda.Tools 30 | - dotnet tool update -g Amazon.Lambda.Tools 31 | - dotnet build -c Release RemoveOrderLambda.csproj 32 | - dotnet test -c Release ../../test/RemoveOrderLambda.Tests/RemoveOrderLambda.Tests.csproj 33 | - dotnet lambda deploy-function "RemoveOrderLambda" --function-role "arn:aws:iam::119176563765:role/AwsomeLambdaExecutionRole" --region "ap-southeast-2" 34 | - cd "$DB_IMG_PATH" 35 | - pwd -------------------------------------------------------------------------------- /saga-orchestration/RevertPaymentLambda/RevertPaymentLambda.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RevertPaymentLambda.Tests", "test\RevertPaymentLambda.Tests\RevertPaymentLambda.Tests.csproj", "{F0F54B61-72AF-4937-8CF8-C36ED8CED2EE}" 4 | EndProject 5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RevertPaymentLambda", "src\RevertPaymentLambda\RevertPaymentLambda.csproj", "{22EE7A1C-33A1-4C15-B037-CF2B0DB2F3BB}" 6 | EndProject 7 | Global 8 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 9 | Debug|Any CPU = Debug|Any CPU 10 | Release|Any CPU = Release|Any CPU 11 | EndGlobalSection 12 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 13 | {F0F54B61-72AF-4937-8CF8-C36ED8CED2EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 14 | {F0F54B61-72AF-4937-8CF8-C36ED8CED2EE}.Debug|Any CPU.Build.0 = Debug|Any CPU 15 | {F0F54B61-72AF-4937-8CF8-C36ED8CED2EE}.Release|Any CPU.ActiveCfg = Release|Any CPU 16 | {F0F54B61-72AF-4937-8CF8-C36ED8CED2EE}.Release|Any CPU.Build.0 = Release|Any CPU 17 | {22EE7A1C-33A1-4C15-B037-CF2B0DB2F3BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 18 | {22EE7A1C-33A1-4C15-B037-CF2B0DB2F3BB}.Debug|Any CPU.Build.0 = Debug|Any CPU 19 | {22EE7A1C-33A1-4C15-B037-CF2B0DB2F3BB}.Release|Any CPU.ActiveCfg = Release|Any CPU 20 | {22EE7A1C-33A1-4C15-B037-CF2B0DB2F3BB}.Release|Any CPU.Build.0 = Release|Any CPU 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /saga-orchestration/RevertPaymentLambda/buildspec.yml: -------------------------------------------------------------------------------- 1 | version: 0.2 2 | env: 3 | variables: 4 | DOTNET_ROOT: /root/.dotnet 5 | secrets-manager: 6 | AWS_ACCESS_KEY_ID_PARAM: CodeBuild:AWS_ACCESS_KEY_ID 7 | AWS_SECRET_ACCESS_KEY_PARAM: CodeBuild:AWS_SECRET_ACCESS_KEY 8 | phases: 9 | install: 10 | runtime-versions: 11 | dotnet: 3.1 12 | pre_build: 13 | commands: 14 | - echo Restore started on `date` 15 | - export PATH="$PATH:/root/.dotnet/tools" 16 | - pip install --upgrade pip 17 | - pip install --upgrade awscli 18 | - aws configure set aws_access_key_id $AWS_ACCESS_KEY_ID_PARAM 19 | - aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY_PARAM 20 | 21 | build: 22 | commands: 23 | - DB_IMG_PATH=$PWD 24 | - cd Lambdas/RevertPaymentLambda/src/RevertPaymentLambda 25 | - dotnet clean 26 | - dotnet restore 27 | - echo Build started on `date` 28 | - dotnet new -i Amazon.Lambda.Templates::* 29 | - dotnet tool install -g Amazon.Lambda.Tools 30 | - dotnet tool update -g Amazon.Lambda.Tools 31 | - dotnet build -c Release RevertPaymentLambda.csproj 32 | - dotnet test -c Release ../../test/RevertPaymentLambda.Tests/RevertPaymentLambda.Tests.csproj 33 | - dotnet lambda deploy-function "RevertPaymentLambda" --function-role "arn:aws:iam::119176563765:role/AwsomeLambdaExecutionRole" --region "ap-southeast-2" 34 | - cd "$DB_IMG_PATH" 35 | - pwd -------------------------------------------------------------------------------- /saga-orchestration/RevertInventoryLambda/RevertInventoryLambda.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RevertInventoryLambda.Tests", "test\RevertInventoryLambda.Tests\RevertInventoryLambda.Tests.csproj", "{D90C7B17-FAE9-44AA-BF20-BF9C5870E450}" 4 | EndProject 5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RevertInventoryLambda", "src\RevertInventoryLambda\RevertInventoryLambda.csproj", "{A104ADFB-BEEE-43C1-A230-BE150AFA2085}" 6 | EndProject 7 | Global 8 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 9 | Debug|Any CPU = Debug|Any CPU 10 | Release|Any CPU = Release|Any CPU 11 | EndGlobalSection 12 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 13 | {D90C7B17-FAE9-44AA-BF20-BF9C5870E450}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 14 | {D90C7B17-FAE9-44AA-BF20-BF9C5870E450}.Debug|Any CPU.Build.0 = Debug|Any CPU 15 | {D90C7B17-FAE9-44AA-BF20-BF9C5870E450}.Release|Any CPU.ActiveCfg = Release|Any CPU 16 | {D90C7B17-FAE9-44AA-BF20-BF9C5870E450}.Release|Any CPU.Build.0 = Release|Any CPU 17 | {A104ADFB-BEEE-43C1-A230-BE150AFA2085}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 18 | {A104ADFB-BEEE-43C1-A230-BE150AFA2085}.Debug|Any CPU.Build.0 = Debug|Any CPU 19 | {A104ADFB-BEEE-43C1-A230-BE150AFA2085}.Release|Any CPU.ActiveCfg = Release|Any CPU 20 | {A104ADFB-BEEE-43C1-A230-BE150AFA2085}.Release|Any CPU.Build.0 = Release|Any CPU 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /saga-orchestration/RevertInventoryLambda/buildspec.yml: -------------------------------------------------------------------------------- 1 | version: 0.2 2 | env: 3 | variables: 4 | DOTNET_ROOT: /root/.dotnet 5 | secrets-manager: 6 | AWS_ACCESS_KEY_ID_PARAM: CodeBuild:AWS_ACCESS_KEY_ID 7 | AWS_SECRET_ACCESS_KEY_PARAM: CodeBuild:AWS_SECRET_ACCESS_KEY 8 | phases: 9 | install: 10 | runtime-versions: 11 | dotnet: 3.1 12 | pre_build: 13 | commands: 14 | - echo Restore started on `date` 15 | - export PATH="$PATH:/root/.dotnet/tools" 16 | - pip install --upgrade pip 17 | - pip install --upgrade awscli 18 | - aws configure set aws_access_key_id $AWS_ACCESS_KEY_ID_PARAM 19 | - aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY_PARAM 20 | 21 | build: 22 | commands: 23 | - DB_IMG_PATH=$PWD 24 | - cd Lambdas/RevertInventoryLambda/src/RevertInventoryLambda 25 | - dotnet clean 26 | - dotnet restore 27 | - echo Build started on `date` 28 | - dotnet new -i Amazon.Lambda.Templates::* 29 | - dotnet tool install -g Amazon.Lambda.Tools 30 | - dotnet tool update -g Amazon.Lambda.Tools 31 | - dotnet build -c Release RevertInventoryLambda.csproj 32 | - dotnet test -c Release ../../test/RevertInventoryLambda.Tests/RevertInventoryLambda.Tests.csproj 33 | - dotnet lambda deploy-function "RevertInventoryLambda" --function-role "arn:aws:iam::119176563765:role/AwsomeLambdaExecutionRole" --region "ap-southeast-2" 34 | - cd "$DB_IMG_PATH" 35 | - pwd -------------------------------------------------------------------------------- /saga-orchestration/UpdateInventoryLambda/UpdateInventoryLambda.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UpdateInventoryLambda.Tests", "test\UpdateInventoryLambda.Tests\UpdateInventoryLambda.Tests.csproj", "{61B30707-83DD-4E4C-A06B-A330282B3510}" 4 | EndProject 5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UpdateInventoryLambda", "src\UpdateInventoryLambda\UpdateInventoryLambda.csproj", "{198E9E7A-20AE-4DB8-8ABC-06BC21BF7493}" 6 | EndProject 7 | Global 8 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 9 | Debug|Any CPU = Debug|Any CPU 10 | Release|Any CPU = Release|Any CPU 11 | EndGlobalSection 12 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 13 | {61B30707-83DD-4E4C-A06B-A330282B3510}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 14 | {61B30707-83DD-4E4C-A06B-A330282B3510}.Debug|Any CPU.Build.0 = Debug|Any CPU 15 | {61B30707-83DD-4E4C-A06B-A330282B3510}.Release|Any CPU.ActiveCfg = Release|Any CPU 16 | {61B30707-83DD-4E4C-A06B-A330282B3510}.Release|Any CPU.Build.0 = Release|Any CPU 17 | {198E9E7A-20AE-4DB8-8ABC-06BC21BF7493}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 18 | {198E9E7A-20AE-4DB8-8ABC-06BC21BF7493}.Debug|Any CPU.Build.0 = Debug|Any CPU 19 | {198E9E7A-20AE-4DB8-8ABC-06BC21BF7493}.Release|Any CPU.ActiveCfg = Release|Any CPU 20 | {198E9E7A-20AE-4DB8-8ABC-06BC21BF7493}.Release|Any CPU.Build.0 = Release|Any CPU 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /saga-orchestration/UpdateInventoryLambda/buildspec.yml: -------------------------------------------------------------------------------- 1 | version: 0.2 2 | env: 3 | variables: 4 | DOTNET_ROOT: /root/.dotnet 5 | secrets-manager: 6 | AWS_ACCESS_KEY_ID_PARAM: CodeBuild:AWS_ACCESS_KEY_ID 7 | AWS_SECRET_ACCESS_KEY_PARAM: CodeBuild:AWS_SECRET_ACCESS_KEY 8 | phases: 9 | install: 10 | runtime-versions: 11 | dotnet: 3.1 12 | pre_build: 13 | commands: 14 | - echo Restore started on `date` 15 | - export PATH="$PATH:/root/.dotnet/tools" 16 | - pip install --upgrade pip 17 | - pip install --upgrade awscli 18 | - aws configure set aws_access_key_id $AWS_ACCESS_KEY_ID_PARAM 19 | - aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY_PARAM 20 | 21 | build: 22 | commands: 23 | - DB_IMG_PATH=$PWD 24 | - cd Lambdas/UpdateInventoryLambda/src/UpdateInventoryLambda 25 | - dotnet clean 26 | - dotnet restore 27 | - echo Build started on `date` 28 | - dotnet new -i Amazon.Lambda.Templates::* 29 | - dotnet tool install -g Amazon.Lambda.Tools 30 | - dotnet tool update -g Amazon.Lambda.Tools 31 | - dotnet build -c Release UpdateInventoryLambda.csproj 32 | - dotnet test -c Release ../../test/UpdateInventoryLambda.Tests/UpdateInventoryLambda.Tests.csproj 33 | - dotnet lambda deploy-function "UpdateInventoryLambda" --function-role "arn:aws:iam::119176563765:role/AwsomeLambdaExecutionRole" --region "ap-southeast-2" 34 | - cd "$DB_IMG_PATH" 35 | - pwd -------------------------------------------------------------------------------- /saga-orchestration/SendNotificationLambda/SendNotificationLambda.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SendNotificationLambda.Tests", "test\SendNotificationLambda.Tests\SendNotificationLambda.Tests.csproj", "{11FF7023-904F-4BD3-8264-F6D11C37961C}" 4 | EndProject 5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SendNotificationLambda", "src\SendNotificationLambda\SendNotificationLambda.csproj", "{A904495A-0D01-4984-AFE4-80E8EE8E7F2C}" 6 | EndProject 7 | Global 8 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 9 | Debug|Any CPU = Debug|Any CPU 10 | Release|Any CPU = Release|Any CPU 11 | EndGlobalSection 12 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 13 | {11FF7023-904F-4BD3-8264-F6D11C37961C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 14 | {11FF7023-904F-4BD3-8264-F6D11C37961C}.Debug|Any CPU.Build.0 = Debug|Any CPU 15 | {11FF7023-904F-4BD3-8264-F6D11C37961C}.Release|Any CPU.ActiveCfg = Release|Any CPU 16 | {11FF7023-904F-4BD3-8264-F6D11C37961C}.Release|Any CPU.Build.0 = Release|Any CPU 17 | {A904495A-0D01-4984-AFE4-80E8EE8E7F2C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 18 | {A904495A-0D01-4984-AFE4-80E8EE8E7F2C}.Debug|Any CPU.Build.0 = Debug|Any CPU 19 | {A904495A-0D01-4984-AFE4-80E8EE8E7F2C}.Release|Any CPU.ActiveCfg = Release|Any CPU 20 | {A904495A-0D01-4984-AFE4-80E8EE8E7F2C}.Release|Any CPU.Build.0 = Release|Any CPU 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /saga-orchestration/SendNotificationLambda/buildspec.yml: -------------------------------------------------------------------------------- 1 | version: 0.2 2 | env: 3 | variables: 4 | DOTNET_ROOT: /root/.dotnet 5 | secrets-manager: 6 | AWS_ACCESS_KEY_ID_PARAM: CodeBuild:AWS_ACCESS_KEY_ID 7 | AWS_SECRET_ACCESS_KEY_PARAM: CodeBuild:AWS_SECRET_ACCESS_KEY 8 | phases: 9 | install: 10 | runtime-versions: 11 | dotnet: 3.1 12 | pre_build: 13 | commands: 14 | - echo Restore started on `date` 15 | - export PATH="$PATH:/root/.dotnet/tools" 16 | - pip install --upgrade pip 17 | - pip install --upgrade awscli 18 | - aws configure set aws_access_key_id $AWS_ACCESS_KEY_ID_PARAM 19 | - aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY_PARAM 20 | 21 | build: 22 | commands: 23 | - DB_IMG_PATH=$PWD 24 | - cd Lambdas/SendNotificationLambda/src/SendNotificationLambda 25 | - dotnet clean 26 | - dotnet restore 27 | - echo Build started on `date` 28 | - dotnet new -i Amazon.Lambda.Templates::* 29 | - dotnet tool install -g Amazon.Lambda.Tools 30 | - dotnet tool update -g Amazon.Lambda.Tools 31 | - dotnet build -c Release SendNotificationLambda.csproj 32 | - dotnet test -c Release ../../test/SendNotificationLambda.Tests/SendNotificationLambda.Tests.csproj 33 | - dotnet lambda deploy-function "SendNotificationLambda" --function-role "arn:aws:iam::119176563765:role/AwsomeLambdaExecutionRole" --region "ap-southeast-2" 34 | - cd "$DB_IMG_PATH" 35 | - pwd -------------------------------------------------------------------------------- /saga-orchestration/InvokeOrchestratorLambda/buildspec.yml: -------------------------------------------------------------------------------- 1 | version: 0.2 2 | env: 3 | variables: 4 | DOTNET_ROOT: /root/.dotnet 5 | secrets-manager: 6 | AWS_ACCESS_KEY_ID_PARAM: CodeBuild:AWS_ACCESS_KEY_ID 7 | AWS_SECRET_ACCESS_KEY_PARAM: CodeBuild:AWS_SECRET_ACCESS_KEY 8 | phases: 9 | install: 10 | runtime-versions: 11 | dotnet: 3.1 12 | pre_build: 13 | commands: 14 | - echo Restore started on `date` 15 | - export PATH="$PATH:/root/.dotnet/tools" 16 | - pip install --upgrade pip 17 | - pip install --upgrade awscli 18 | - aws configure set aws_access_key_id $AWS_ACCESS_KEY_ID_PARAM 19 | - aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY_PARAM 20 | 21 | build: 22 | commands: 23 | - DB_IMG_PATH=$PWD 24 | - cd Lambdas/InvokeOrchestratorLambda/src/InvokeOrchestratorLambda 25 | - dotnet clean 26 | - dotnet restore 27 | - echo Build started on `date` 28 | - dotnet new -i Amazon.Lambda.Templates::* 29 | - dotnet tool install -g Amazon.Lambda.Tools 30 | - dotnet tool update -g Amazon.Lambda.Tools 31 | - dotnet build -c Release InvokeOrchestratorLambda.csproj 32 | - dotnet test -c Release ../../test/InvokeOrchestratorLambda.Tests/InvokeOrchestratorLambda.Tests.csproj 33 | - dotnet lambda deploy-function "InvokeOrchestratorLambda" --function-role "arn:aws:iam::119176563765:role/AwsomeLambdaExecutionRole" --region "ap-southeast-2" 34 | - cd "$DB_IMG_PATH" 35 | - pwd -------------------------------------------------------------------------------- /saga-orchestration/InvokeOrchestratorLambda/InvokeOrchestratorLambda.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InvokeOrchestratorLambda.Tests", "test\InvokeOrchestratorLambda.Tests\InvokeOrchestratorLambda.Tests.csproj", "{95E8D143-7CAC-4301-91F2-28D8B74F1DD3}" 4 | EndProject 5 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InvokeOrchestratorLambda", "src\InvokeOrchestratorLambda\InvokeOrchestratorLambda.csproj", "{2672A028-85E6-46E1-BA22-37CE17B918D5}" 6 | EndProject 7 | Global 8 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 9 | Debug|Any CPU = Debug|Any CPU 10 | Release|Any CPU = Release|Any CPU 11 | EndGlobalSection 12 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 13 | {95E8D143-7CAC-4301-91F2-28D8B74F1DD3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 14 | {95E8D143-7CAC-4301-91F2-28D8B74F1DD3}.Debug|Any CPU.Build.0 = Debug|Any CPU 15 | {95E8D143-7CAC-4301-91F2-28D8B74F1DD3}.Release|Any CPU.ActiveCfg = Release|Any CPU 16 | {95E8D143-7CAC-4301-91F2-28D8B74F1DD3}.Release|Any CPU.Build.0 = Release|Any CPU 17 | {2672A028-85E6-46E1-BA22-37CE17B918D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 18 | {2672A028-85E6-46E1-BA22-37CE17B918D5}.Debug|Any CPU.Build.0 = Debug|Any CPU 19 | {2672A028-85E6-46E1-BA22-37CE17B918D5}.Release|Any CPU.ActiveCfg = Release|Any CPU 20 | {2672A028-85E6-46E1-BA22-37CE17B918D5}.Release|Any CPU.Build.0 = Release|Any CPU 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /saga-orchestration/MakePaymentLambda/src/MakePaymentLambda/Function.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Amazon.Lambda.Core; 6 | 7 | // Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class. 8 | [assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] 9 | 10 | namespace MakePaymentLambda 11 | { 12 | public class MakePayment 13 | { 14 | private StageNameEnum CurrentStage = StageNameEnum.MakePayment; 15 | public OrderDetails FunctionHandler(OrderDetails orderDetails, ILambdaContext context) 16 | { 17 | var status = "PAYMENT_COMPLETED"; 18 | Enum.TryParse(orderDetails.FailAtStage, out StageNameEnum stage); 19 | if (stage.Equals(CurrentStage)) 20 | status = "ERROR"; 21 | 22 | orderDetails.Status = status; 23 | return orderDetails; 24 | } 25 | } 26 | 27 | public class OrderDetails 28 | { 29 | public string ItemId { get; set; } 30 | public string CustomerId { get; set; } 31 | public string MessageId { get; set; } 32 | public string FailAtStage { get; set; } 33 | public string Status { get; set; } 34 | } 35 | 36 | public enum StageNameEnum 37 | { 38 | PlaceOrder = 0, 39 | MakePayment = 1, 40 | UpdateInventory = 2, 41 | SendNotification = 3, 42 | None = 4 43 | } 44 | } -------------------------------------------------------------------------------- /saga-orchestration/UpdateInventoryLambda/test/UpdateInventoryLambda.Tests/FunctionTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Xunit; 6 | using Amazon.Lambda.Core; 7 | using Amazon.Lambda.TestUtilities; 8 | using UpdateInventoryLambda; 9 | 10 | namespace UpdateInventoryLambda.Tests 11 | { 12 | public class FunctionTest 13 | { 14 | [Fact] 15 | public void TestSuccessScenario() 16 | { 17 | // Invoke the lambda function and confirm the string was upper cased. 18 | var function = new UpdateInventory(); 19 | var context = new TestLambdaContext(); 20 | var inputObj = new OrderDetails {ItemId = "ABC/001", CustomerId = "SGP/010", FailAtStage = "None"}; 21 | 22 | var retValue = function.FunctionHandler(inputObj,context); 23 | Assert.Equal("INVENTORY_UPDATED", retValue.Status); 24 | } 25 | 26 | 27 | [Fact] 28 | public void TestFailureScenario() 29 | { 30 | // Invoke the lambda function and confirm the string was upper cased. 31 | var function = new UpdateInventory(); 32 | var context = new TestLambdaContext(); 33 | var inputObj = new OrderDetails {ItemId = "ABC/001", CustomerId = "SGP/010", FailAtStage = "UpdateInventory"}; 34 | 35 | var retValue = function.FunctionHandler(inputObj,context); 36 | Assert.Equal("ERROR", retValue.Status); 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /saga-orchestration/PlaceOrderLambda/test/PlaceOrderLambda.Tests/FunctionTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text.Json; 5 | using System.Threading.Tasks; 6 | using Xunit; 7 | using Amazon.Lambda.Core; 8 | using Amazon.Lambda.TestUtilities; 9 | using Newtonsoft.Json; 10 | using PlaceOrderLambda; 11 | 12 | namespace PlaceOrderLambda.Tests 13 | { 14 | public class FunctionTest 15 | { 16 | [Fact] 17 | public void TestSuccessScenario() 18 | { 19 | // Invoke the lambda function and confirm the string was upper cased. 20 | var function = new PlaceOrder(); 21 | var context = new TestLambdaContext(); 22 | var inputObj = new OrderDetails {ItemId = "ABC/001", CustomerId = "SGP/010", FailAtStage = "None"}; 23 | 24 | var retValue = function.FunctionHandler(inputObj,context); 25 | Assert.Equal("ORDER_PLACED", retValue.Status); 26 | } 27 | 28 | 29 | [Fact] 30 | public void TestFailureScenario() 31 | { 32 | // Invoke the lambda function and confirm the string was upper cased. 33 | var function = new PlaceOrder(); 34 | var context = new TestLambdaContext(); 35 | var inputObj = new OrderDetails {ItemId = "ABC/001", CustomerId = "SGP/010", FailAtStage = "PlaceOrder"}; 36 | 37 | var retValue = function.FunctionHandler(inputObj,context); 38 | Assert.Equal("ERROR", retValue.Status); 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /cdk-saga-orchestration/src/CdkSagaOrchestration.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26124.0 5 | MinimumVisualStudioVersion = 15.0.26124.0 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CdkSagaOrchestration", "CdkSagaOrchestration\CdkSagaOrchestration.csproj", "{861318A3-63B8-48E2-8B38-F08F675D5423}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Debug|x64 = Debug|x64 12 | Debug|x86 = Debug|x86 13 | Release|Any CPU = Release|Any CPU 14 | Release|x64 = Release|x64 15 | Release|x86 = Release|x86 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 21 | {861318A3-63B8-48E2-8B38-F08F675D5423}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 22 | {861318A3-63B8-48E2-8B38-F08F675D5423}.Debug|Any CPU.Build.0 = Debug|Any CPU 23 | {861318A3-63B8-48E2-8B38-F08F675D5423}.Debug|x64.ActiveCfg = Debug|Any CPU 24 | {861318A3-63B8-48E2-8B38-F08F675D5423}.Debug|x64.Build.0 = Debug|Any CPU 25 | {861318A3-63B8-48E2-8B38-F08F675D5423}.Debug|x86.ActiveCfg = Debug|Any CPU 26 | {861318A3-63B8-48E2-8B38-F08F675D5423}.Debug|x86.Build.0 = Debug|Any CPU 27 | {861318A3-63B8-48E2-8B38-F08F675D5423}.Release|Any CPU.ActiveCfg = Release|Any CPU 28 | {861318A3-63B8-48E2-8B38-F08F675D5423}.Release|Any CPU.Build.0 = Release|Any CPU 29 | {861318A3-63B8-48E2-8B38-F08F675D5423}.Release|x64.ActiveCfg = Release|Any CPU 30 | {861318A3-63B8-48E2-8B38-F08F675D5423}.Release|x64.Build.0 = Release|Any CPU 31 | {861318A3-63B8-48E2-8B38-F08F675D5423}.Release|x86.ActiveCfg = Release|Any CPU 32 | {861318A3-63B8-48E2-8B38-F08F675D5423}.Release|x86.Build.0 = Release|Any CPU 33 | EndGlobalSection 34 | EndGlobal 35 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider 2 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 3 | 4 | # User-specific stuff 5 | .idea/**/aws.xml 6 | .idea/**/workspace.xml 7 | .idea/**/tasks.xml 8 | .idea/**/usage.statistics.xml 9 | .idea/**/dictionaries 10 | .idea/**/shelf 11 | .idea/**/* 12 | 13 | # Generated files 14 | .idea/**/contentModel.xml 15 | 16 | # Sensitive or high-churn files 17 | .idea/**/dataSources/ 18 | .idea/**/dataSources.ids 19 | .idea/**/dataSources.local.xml 20 | .idea/**/sqlDataSources.xml 21 | .idea/**/dynamic.xml 22 | .idea/**/uiDesigner.xml 23 | .idea/**/dbnavigator.xml 24 | 25 | # Gradle 26 | .idea/**/gradle.xml 27 | .idea/**/libraries 28 | 29 | # Gradle and Maven with auto-import 30 | # When using Gradle or Maven with auto-import, you should exclude module files, 31 | # since they will be recreated, and may cause churn. Uncomment if using 32 | # auto-import. 33 | # .idea/artifacts 34 | # .idea/compiler.xml 35 | # .idea/jarRepositories.xml 36 | # .idea/modules.xml 37 | # .idea/*.iml 38 | # .idea/modules 39 | # *.iml 40 | # *.ipr 41 | 42 | # CMake 43 | cmake-build-*/ 44 | 45 | # Mongo Explorer plugin 46 | .idea/**/mongoSettings.xml 47 | 48 | # File-based project format 49 | *.iws 50 | 51 | # IntelliJ 52 | out/ 53 | 54 | # mpeltonen/sbt-idea plugin 55 | .idea_modules/ 56 | 57 | # JIRA plugin 58 | atlassian-ide-plugin.xml 59 | 60 | # Cursive Clojure plugin 61 | .idea/replstate.xml 62 | 63 | # Crashlytics plugin (for Android Studio and IntelliJ) 64 | com_crashlytics_export_strings.xml 65 | crashlytics.properties 66 | crashlytics-build.properties 67 | fabric.properties 68 | 69 | # Editor-based Rest Client 70 | .idea/httpRequests 71 | 72 | # Android studio 3.1+ serialized cache file 73 | .idea/caches/build_file_checksums.ser 74 | 75 | .DS_Store 76 | 77 | **/bin/Debug/ 78 | **/bin/Release/ 79 | **/obj/Debug/ 80 | **/obj/ 81 | **/.idea/* 82 | **/*.sln.DotSettings.user 83 | 84 | **/cdk.out 85 | **/lambdas/* 86 | -------------------------------------------------------------------------------- /saga-orchestration/PlaceOrderLambda/src/PlaceOrderLambda/Readme.md: -------------------------------------------------------------------------------- 1 | # AWS Lambda Empty Function Project 2 | 3 | This starter project consists of: 4 | * Function.cs - class file containing a class with a single function handler method 5 | * aws-lambda-tools-defaults.json - default argument settings for use with Visual Studio and command line deployment tools for AWS 6 | 7 | You may also have a test project depending on the options selected. 8 | 9 | The generated function handler is a simple method accepting a string argument that returns the uppercase equivalent of the input string. Replace the body of this method, and parameters, to suit your needs. 10 | 11 | ## Here are some steps to follow from Visual Studio: 12 | 13 | To deploy your function to AWS Lambda, right click the project in Solution Explorer and select *Publish to AWS Lambda*. 14 | 15 | To view your deployed function open its Function View window by double-clicking the function name shown beneath the AWS Lambda node in the AWS Explorer tree. 16 | 17 | To perform testing against your deployed function use the Test Invoke tab in the opened Function View window. 18 | 19 | To configure event sources for your deployed function, for example to have your function invoked when an object is created in an Amazon S3 bucket, use the Event Sources tab in the opened Function View window. 20 | 21 | To update the runtime configuration of your deployed function use the Configuration tab in the opened Function View window. 22 | 23 | To view execution logs of invocations of your function use the Logs tab in the opened Function View window. 24 | 25 | ## Here are some steps to follow to get started from the command line: 26 | 27 | Once you have edited your template and code you can deploy your application using the [Amazon.Lambda.Tools Global Tool](https://github.com/aws/aws-extensions-for-dotnet-cli#aws-lambda-amazonlambdatools) from the command line. 28 | 29 | Install Amazon.Lambda.Tools Global Tools if not already installed. 30 | ``` 31 | dotnet tool install -g Amazon.Lambda.Tools 32 | ``` 33 | 34 | If already installed check if new version is available. 35 | ``` 36 | dotnet tool update -g Amazon.Lambda.Tools 37 | ``` 38 | 39 | Execute unit tests 40 | ``` 41 | cd "BlueprintBaseName/test/BlueprintBaseName.Tests" 42 | dotnet test 43 | ``` 44 | 45 | Deploy function to AWS Lambda 46 | ``` 47 | cd "BlueprintBaseName/src/BlueprintBaseName" 48 | dotnet lambda deploy-function 49 | ``` 50 | -------------------------------------------------------------------------------- /saga-orchestration/MakePaymentLambda/src/MakePaymentLambda/Readme.md: -------------------------------------------------------------------------------- 1 | # AWS Lambda Empty Function Project 2 | 3 | This starter project consists of: 4 | * Function.cs - class file containing a class with a single function handler method 5 | * aws-lambda-tools-defaults.json - default argument settings for use with Visual Studio and command line deployment tools for AWS 6 | 7 | You may also have a test project depending on the options selected. 8 | 9 | The generated function handler is a simple method accepting a string argument that returns the uppercase equivalent of the input string. Replace the body of this method, and parameters, to suit your needs. 10 | 11 | ## Here are some steps to follow from Visual Studio: 12 | 13 | To deploy your function to AWS Lambda, right click the project in Solution Explorer and select *Publish to AWS Lambda*. 14 | 15 | To view your deployed function open its Function View window by double-clicking the function name shown beneath the AWS Lambda node in the AWS Explorer tree. 16 | 17 | To perform testing against your deployed function use the Test Invoke tab in the opened Function View window. 18 | 19 | To configure event sources for your deployed function, for example to have your function invoked when an object is created in an Amazon S3 bucket, use the Event Sources tab in the opened Function View window. 20 | 21 | To update the runtime configuration of your deployed function use the Configuration tab in the opened Function View window. 22 | 23 | To view execution logs of invocations of your function use the Logs tab in the opened Function View window. 24 | 25 | ## Here are some steps to follow to get started from the command line: 26 | 27 | Once you have edited your template and code you can deploy your application using the [Amazon.Lambda.Tools Global Tool](https://github.com/aws/aws-extensions-for-dotnet-cli#aws-lambda-amazonlambdatools) from the command line. 28 | 29 | Install Amazon.Lambda.Tools Global Tools if not already installed. 30 | ``` 31 | dotnet tool install -g Amazon.Lambda.Tools 32 | ``` 33 | 34 | If already installed check if new version is available. 35 | ``` 36 | dotnet tool update -g Amazon.Lambda.Tools 37 | ``` 38 | 39 | Execute unit tests 40 | ``` 41 | cd "BlueprintBaseName/test/BlueprintBaseName.Tests" 42 | dotnet test 43 | ``` 44 | 45 | Deploy function to AWS Lambda 46 | ``` 47 | cd "BlueprintBaseName/src/BlueprintBaseName" 48 | dotnet lambda deploy-function 49 | ``` 50 | -------------------------------------------------------------------------------- /saga-orchestration/RemoveOrderLambda/src/RemoveOrderLambda/Readme.md: -------------------------------------------------------------------------------- 1 | # AWS Lambda Empty Function Project 2 | 3 | This starter project consists of: 4 | * Function.cs - class file containing a class with a single function handler method 5 | * aws-lambda-tools-defaults.json - default argument settings for use with Visual Studio and command line deployment tools for AWS 6 | 7 | You may also have a test project depending on the options selected. 8 | 9 | The generated function handler is a simple method accepting a string argument that returns the uppercase equivalent of the input string. Replace the body of this method, and parameters, to suit your needs. 10 | 11 | ## Here are some steps to follow from Visual Studio: 12 | 13 | To deploy your function to AWS Lambda, right click the project in Solution Explorer and select *Publish to AWS Lambda*. 14 | 15 | To view your deployed function open its Function View window by double-clicking the function name shown beneath the AWS Lambda node in the AWS Explorer tree. 16 | 17 | To perform testing against your deployed function use the Test Invoke tab in the opened Function View window. 18 | 19 | To configure event sources for your deployed function, for example to have your function invoked when an object is created in an Amazon S3 bucket, use the Event Sources tab in the opened Function View window. 20 | 21 | To update the runtime configuration of your deployed function use the Configuration tab in the opened Function View window. 22 | 23 | To view execution logs of invocations of your function use the Logs tab in the opened Function View window. 24 | 25 | ## Here are some steps to follow to get started from the command line: 26 | 27 | Once you have edited your template and code you can deploy your application using the [Amazon.Lambda.Tools Global Tool](https://github.com/aws/aws-extensions-for-dotnet-cli#aws-lambda-amazonlambdatools) from the command line. 28 | 29 | Install Amazon.Lambda.Tools Global Tools if not already installed. 30 | ``` 31 | dotnet tool install -g Amazon.Lambda.Tools 32 | ``` 33 | 34 | If already installed check if new version is available. 35 | ``` 36 | dotnet tool update -g Amazon.Lambda.Tools 37 | ``` 38 | 39 | Execute unit tests 40 | ``` 41 | cd "BlueprintBaseName/test/BlueprintBaseName.Tests" 42 | dotnet test 43 | ``` 44 | 45 | Deploy function to AWS Lambda 46 | ``` 47 | cd "BlueprintBaseName/src/BlueprintBaseName" 48 | dotnet lambda deploy-function 49 | ``` 50 | -------------------------------------------------------------------------------- /saga-orchestration/RevertInventoryLambda/src/RevertInventoryLambda/Readme.md: -------------------------------------------------------------------------------- 1 | # AWS Lambda Empty Function Project 2 | 3 | This starter project consists of: 4 | * Function.cs - class file containing a class with a single function handler method 5 | * aws-lambda-tools-defaults.json - default argument settings for use with Visual Studio and command line deployment tools for AWS 6 | 7 | You may also have a test project depending on the options selected. 8 | 9 | The generated function handler is a simple method accepting a string argument that returns the uppercase equivalent of the input string. Replace the body of this method, and parameters, to suit your needs. 10 | 11 | ## Here are some steps to follow from Visual Studio: 12 | 13 | To deploy your function to AWS Lambda, right click the project in Solution Explorer and select *Publish to AWS Lambda*. 14 | 15 | To view your deployed function open its Function View window by double-clicking the function name shown beneath the AWS Lambda node in the AWS Explorer tree. 16 | 17 | To perform testing against your deployed function use the Test Invoke tab in the opened Function View window. 18 | 19 | To configure event sources for your deployed function, for example to have your function invoked when an object is created in an Amazon S3 bucket, use the Event Sources tab in the opened Function View window. 20 | 21 | To update the runtime configuration of your deployed function use the Configuration tab in the opened Function View window. 22 | 23 | To view execution logs of invocations of your function use the Logs tab in the opened Function View window. 24 | 25 | ## Here are some steps to follow to get started from the command line: 26 | 27 | Once you have edited your template and code you can deploy your application using the [Amazon.Lambda.Tools Global Tool](https://github.com/aws/aws-extensions-for-dotnet-cli#aws-lambda-amazonlambdatools) from the command line. 28 | 29 | Install Amazon.Lambda.Tools Global Tools if not already installed. 30 | ``` 31 | dotnet tool install -g Amazon.Lambda.Tools 32 | ``` 33 | 34 | If already installed check if new version is available. 35 | ``` 36 | dotnet tool update -g Amazon.Lambda.Tools 37 | ``` 38 | 39 | Execute unit tests 40 | ``` 41 | cd "BlueprintBaseName/test/BlueprintBaseName.Tests" 42 | dotnet test 43 | ``` 44 | 45 | Deploy function to AWS Lambda 46 | ``` 47 | cd "BlueprintBaseName/src/BlueprintBaseName" 48 | dotnet lambda deploy-function 49 | ``` 50 | -------------------------------------------------------------------------------- /saga-orchestration/RevertPaymentLambda/src/RevertPaymentLambda/Readme.md: -------------------------------------------------------------------------------- 1 | # AWS Lambda Empty Function Project 2 | 3 | This starter project consists of: 4 | * Function.cs - class file containing a class with a single function handler method 5 | * aws-lambda-tools-defaults.json - default argument settings for use with Visual Studio and command line deployment tools for AWS 6 | 7 | You may also have a test project depending on the options selected. 8 | 9 | The generated function handler is a simple method accepting a string argument that returns the uppercase equivalent of the input string. Replace the body of this method, and parameters, to suit your needs. 10 | 11 | ## Here are some steps to follow from Visual Studio: 12 | 13 | To deploy your function to AWS Lambda, right click the project in Solution Explorer and select *Publish to AWS Lambda*. 14 | 15 | To view your deployed function open its Function View window by double-clicking the function name shown beneath the AWS Lambda node in the AWS Explorer tree. 16 | 17 | To perform testing against your deployed function use the Test Invoke tab in the opened Function View window. 18 | 19 | To configure event sources for your deployed function, for example to have your function invoked when an object is created in an Amazon S3 bucket, use the Event Sources tab in the opened Function View window. 20 | 21 | To update the runtime configuration of your deployed function use the Configuration tab in the opened Function View window. 22 | 23 | To view execution logs of invocations of your function use the Logs tab in the opened Function View window. 24 | 25 | ## Here are some steps to follow to get started from the command line: 26 | 27 | Once you have edited your template and code you can deploy your application using the [Amazon.Lambda.Tools Global Tool](https://github.com/aws/aws-extensions-for-dotnet-cli#aws-lambda-amazonlambdatools) from the command line. 28 | 29 | Install Amazon.Lambda.Tools Global Tools if not already installed. 30 | ``` 31 | dotnet tool install -g Amazon.Lambda.Tools 32 | ``` 33 | 34 | If already installed check if new version is available. 35 | ``` 36 | dotnet tool update -g Amazon.Lambda.Tools 37 | ``` 38 | 39 | Execute unit tests 40 | ``` 41 | cd "BlueprintBaseName/test/BlueprintBaseName.Tests" 42 | dotnet test 43 | ``` 44 | 45 | Deploy function to AWS Lambda 46 | ``` 47 | cd "BlueprintBaseName/src/BlueprintBaseName" 48 | dotnet lambda deploy-function 49 | ``` 50 | -------------------------------------------------------------------------------- /saga-orchestration/UpdateInventoryLambda/src/UpdateInventoryLambda/Readme.md: -------------------------------------------------------------------------------- 1 | # AWS Lambda Empty Function Project 2 | 3 | This starter project consists of: 4 | * Function.cs - class file containing a class with a single function handler method 5 | * aws-lambda-tools-defaults.json - default argument settings for use with Visual Studio and command line deployment tools for AWS 6 | 7 | You may also have a test project depending on the options selected. 8 | 9 | The generated function handler is a simple method accepting a string argument that returns the uppercase equivalent of the input string. Replace the body of this method, and parameters, to suit your needs. 10 | 11 | ## Here are some steps to follow from Visual Studio: 12 | 13 | To deploy your function to AWS Lambda, right click the project in Solution Explorer and select *Publish to AWS Lambda*. 14 | 15 | To view your deployed function open its Function View window by double-clicking the function name shown beneath the AWS Lambda node in the AWS Explorer tree. 16 | 17 | To perform testing against your deployed function use the Test Invoke tab in the opened Function View window. 18 | 19 | To configure event sources for your deployed function, for example to have your function invoked when an object is created in an Amazon S3 bucket, use the Event Sources tab in the opened Function View window. 20 | 21 | To update the runtime configuration of your deployed function use the Configuration tab in the opened Function View window. 22 | 23 | To view execution logs of invocations of your function use the Logs tab in the opened Function View window. 24 | 25 | ## Here are some steps to follow to get started from the command line: 26 | 27 | Once you have edited your template and code you can deploy your application using the [Amazon.Lambda.Tools Global Tool](https://github.com/aws/aws-extensions-for-dotnet-cli#aws-lambda-amazonlambdatools) from the command line. 28 | 29 | Install Amazon.Lambda.Tools Global Tools if not already installed. 30 | ``` 31 | dotnet tool install -g Amazon.Lambda.Tools 32 | ``` 33 | 34 | If already installed check if new version is available. 35 | ``` 36 | dotnet tool update -g Amazon.Lambda.Tools 37 | ``` 38 | 39 | Execute unit tests 40 | ``` 41 | cd "BlueprintBaseName/test/BlueprintBaseName.Tests" 42 | dotnet test 43 | ``` 44 | 45 | Deploy function to AWS Lambda 46 | ``` 47 | cd "BlueprintBaseName/src/BlueprintBaseName" 48 | dotnet lambda deploy-function 49 | ``` 50 | -------------------------------------------------------------------------------- /saga-orchestration/SendNotificationLambda/src/SendNotificationLambda/Readme.md: -------------------------------------------------------------------------------- 1 | # AWS Lambda Empty Function Project 2 | 3 | This starter project consists of: 4 | * Function.cs - class file containing a class with a single function handler method 5 | * aws-lambda-tools-defaults.json - default argument settings for use with Visual Studio and command line deployment tools for AWS 6 | 7 | You may also have a test project depending on the options selected. 8 | 9 | The generated function handler is a simple method accepting a string argument that returns the uppercase equivalent of the input string. Replace the body of this method, and parameters, to suit your needs. 10 | 11 | ## Here are some steps to follow from Visual Studio: 12 | 13 | To deploy your function to AWS Lambda, right click the project in Solution Explorer and select *Publish to AWS Lambda*. 14 | 15 | To view your deployed function open its Function View window by double-clicking the function name shown beneath the AWS Lambda node in the AWS Explorer tree. 16 | 17 | To perform testing against your deployed function use the Test Invoke tab in the opened Function View window. 18 | 19 | To configure event sources for your deployed function, for example to have your function invoked when an object is created in an Amazon S3 bucket, use the Event Sources tab in the opened Function View window. 20 | 21 | To update the runtime configuration of your deployed function use the Configuration tab in the opened Function View window. 22 | 23 | To view execution logs of invocations of your function use the Logs tab in the opened Function View window. 24 | 25 | ## Here are some steps to follow to get started from the command line: 26 | 27 | Once you have edited your template and code you can deploy your application using the [Amazon.Lambda.Tools Global Tool](https://github.com/aws/aws-extensions-for-dotnet-cli#aws-lambda-amazonlambdatools) from the command line. 28 | 29 | Install Amazon.Lambda.Tools Global Tools if not already installed. 30 | ``` 31 | dotnet tool install -g Amazon.Lambda.Tools 32 | ``` 33 | 34 | If already installed check if new version is available. 35 | ``` 36 | dotnet tool update -g Amazon.Lambda.Tools 37 | ``` 38 | 39 | Execute unit tests 40 | ``` 41 | cd "BlueprintBaseName/test/BlueprintBaseName.Tests" 42 | dotnet test 43 | ``` 44 | 45 | Deploy function to AWS Lambda 46 | ``` 47 | cd "BlueprintBaseName/src/BlueprintBaseName" 48 | dotnet lambda deploy-function 49 | ``` 50 | -------------------------------------------------------------------------------- /saga-orchestration/InvokeOrchestratorLambda/src/InvokeOrchestratorLambda/Readme.md: -------------------------------------------------------------------------------- 1 | # AWS Lambda Empty Function Project 2 | 3 | This starter project consists of: 4 | * Function.cs - class file containing a class with a single function handler method 5 | * aws-lambda-tools-defaults.json - default argument settings for use with Visual Studio and command line deployment tools for AWS 6 | 7 | You may also have a test project depending on the options selected. 8 | 9 | The generated function handler is a simple method accepting a string argument that returns the uppercase equivalent of the input string. Replace the body of this method, and parameters, to suit your needs. 10 | 11 | ## Here are some steps to follow from Visual Studio: 12 | 13 | To deploy your function to AWS Lambda, right click the project in Solution Explorer and select *Publish to AWS Lambda*. 14 | 15 | To view your deployed function open its Function View window by double-clicking the function name shown beneath the AWS Lambda node in the AWS Explorer tree. 16 | 17 | To perform testing against your deployed function use the Test Invoke tab in the opened Function View window. 18 | 19 | To configure event sources for your deployed function, for example to have your function invoked when an object is created in an Amazon S3 bucket, use the Event Sources tab in the opened Function View window. 20 | 21 | To update the runtime configuration of your deployed function use the Configuration tab in the opened Function View window. 22 | 23 | To view execution logs of invocations of your function use the Logs tab in the opened Function View window. 24 | 25 | ## Here are some steps to follow to get started from the command line: 26 | 27 | Once you have edited your template and code you can deploy your application using the [Amazon.Lambda.Tools Global Tool](https://github.com/aws/aws-extensions-for-dotnet-cli#aws-lambda-amazonlambdatools) from the command line. 28 | 29 | Install Amazon.Lambda.Tools Global Tools if not already installed. 30 | ``` 31 | dotnet tool install -g Amazon.Lambda.Tools 32 | ``` 33 | 34 | If already installed check if new version is available. 35 | ``` 36 | dotnet tool update -g Amazon.Lambda.Tools 37 | ``` 38 | 39 | Execute unit tests 40 | ``` 41 | cd "BlueprintBaseName/test/BlueprintBaseName.Tests" 42 | dotnet test 43 | ``` 44 | 45 | Deploy function to AWS Lambda 46 | ``` 47 | cd "BlueprintBaseName/src/BlueprintBaseName" 48 | dotnet lambda deploy-function 49 | ``` 50 | -------------------------------------------------------------------------------- /saga-orchestration/PlaceOrderLambda/src/PlaceOrderLambda/Function.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Amazon.Lambda.Core; 4 | using Amazon.DynamoDBv2; 5 | using Amazon.DynamoDBv2.Model; 6 | 7 | // Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class. 8 | [assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] 9 | 10 | namespace PlaceOrderLambda 11 | { 12 | public class PlaceOrder 13 | { 14 | private StageNameEnum CurrentStage = StageNameEnum.PlaceOrder; 15 | private static string tableName = "Orders"; 16 | private static AmazonDynamoDBClient client = new AmazonDynamoDBClient(); 17 | 18 | public OrderDetails FunctionHandler(OrderDetails orderDetails, ILambdaContext context) 19 | { 20 | orderDetails.Status = "ORDER_PLACED"; 21 | CreateOrder(orderDetails,context); 22 | 23 | 24 | Enum.TryParse(orderDetails.FailAtStage, out StageNameEnum stage); 25 | if (stage.Equals(CurrentStage)) 26 | orderDetails.Status = "ERROR"; 27 | 28 | return orderDetails; 29 | } 30 | 31 | 32 | private void CreateOrder(OrderDetails orderDetails, ILambdaContext context) 33 | { 34 | // Define item attributes 35 | var attributes = new Dictionary(); 36 | attributes["ItemId"] = new AttributeValue { S = orderDetails.ItemId }; 37 | attributes["CustomerId"] = new AttributeValue { S = orderDetails.CustomerId }; 38 | attributes["Status"] = new AttributeValue { S = orderDetails.Status }; 39 | 40 | // Create PutItem request 41 | var request = new PutItemRequest 42 | { 43 | TableName = tableName, 44 | Item = attributes 45 | }; 46 | 47 | // Issue PutItem request 48 | var response = client.PutItemAsync(request); 49 | 50 | // Check the response. 51 | var attributeList = response.Result.Attributes; // attribute list in the response. 52 | 53 | } 54 | } 55 | 56 | public class OrderDetails 57 | { 58 | public string ItemId { get; set; } 59 | public string CustomerId { get; set; } 60 | public string MessageId { get; set; } 61 | public string FailAtStage { get; set; } 62 | public string Status { get; set; } 63 | } 64 | 65 | public enum StageNameEnum 66 | { 67 | PlaceOrder = 0, 68 | MakePayment = 1, 69 | UpdateInventory = 2, 70 | SendNotification = 3, 71 | None 72 | } 73 | } -------------------------------------------------------------------------------- /saga-orchestration/RemoveOrderLambda/src/RemoveOrderLambda/Function.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Amazon.Lambda.Core; 6 | using MySql.Data.MySqlClient; 7 | using Amazon.DynamoDBv2; 8 | using Amazon.DynamoDBv2.Model; 9 | 10 | // Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class. 11 | [assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] 12 | 13 | namespace RemoveOrderLambda 14 | { 15 | public class RemoveOrder 16 | { 17 | private static string tableName = "Orders"; 18 | private static AmazonDynamoDBClient client = new AmazonDynamoDBClient(); 19 | 20 | public string FunctionHandler(OrderDetails orderDetails,ILambdaContext context) 21 | { 22 | DeleteOrder(orderDetails,context); 23 | orderDetails.Status = "ORDER_REMOVED"; 24 | return orderDetails.Status; 25 | } 26 | 27 | private void DeleteOrder(OrderDetails orderDetails, ILambdaContext context) 28 | { 29 | // Define item attributes 30 | var attributes = new Dictionary 31 | { 32 | {"ItemId", new AttributeValue {S = orderDetails.ItemId}}, 33 | {"CustomerId", new AttributeValue {S = orderDetails.CustomerId}}, 34 | }; 35 | 36 | 37 | // Create DeleteItem request 38 | var request = new DeleteItemRequest() 39 | { 40 | TableName = tableName, 41 | Key = attributes, 42 | ReturnValues = "ALL_OLD" 43 | }; 44 | 45 | var response = client.DeleteItemAsync(request); 46 | 47 | 48 | var attributeList = response.Result.Attributes; // attribute list in the response. 49 | context.Logger.Log("\nPrinting item after retrieving it ............"); 50 | PrintItem(attributeList, context); 51 | } 52 | 53 | private void PrintItem(Dictionary attributeList,ILambdaContext context) 54 | { 55 | foreach (KeyValuePair kvp in attributeList) 56 | { 57 | string attributeName = kvp.Key; 58 | AttributeValue value = kvp.Value; 59 | 60 | context.Logger.Log( 61 | attributeName + " " + 62 | (value.S == null ? "" : value.S + " ") + 63 | (value.N == null ? "" : value.N + " ") + 64 | (value.SS == null ? "" : string.Join(",", value.SS.ToArray()) + " ") + 65 | (value.NS == null ? "" : string.Join(",", value.NS.ToArray()) + " ") 66 | ); 67 | } 68 | } 69 | } 70 | 71 | 72 | public class OrderDetails 73 | { 74 | public string ItemId { get; set; } 75 | public string CustomerId { get; set; } 76 | public string MessageId { get; set; } 77 | public string FailAtStage { get; set; } 78 | public string Status { get; set; } 79 | } 80 | } -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing Guidelines 2 | 3 | Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional 4 | documentation, we greatly value feedback and contributions from our community. 5 | 6 | Please read through this document before submitting any issues or pull requests to ensure we have all the necessary 7 | information to effectively respond to your bug report or contribution. 8 | 9 | 10 | ## Reporting Bugs/Feature Requests 11 | 12 | We welcome you to use the GitHub issue tracker to report bugs or suggest features. 13 | 14 | When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already 15 | reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: 16 | 17 | * A reproducible test case or series of steps 18 | * The version of our code being used 19 | * Any modifications you've made relevant to the bug 20 | * Anything unusual about your environment or deployment 21 | 22 | 23 | ## Contributing via Pull Requests 24 | Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: 25 | 26 | 1. You are working against the latest source on the *main* branch. 27 | 2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. 28 | 3. You open an issue to discuss any significant work - we would hate for your time to be wasted. 29 | 30 | To send us a pull request, please: 31 | 32 | 1. Fork the repository. 33 | 2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change. 34 | 3. Ensure local tests pass. 35 | 4. Commit to your fork using clear commit messages. 36 | 5. Send us a pull request, answering any default questions in the pull request interface. 37 | 6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. 38 | 39 | GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and 40 | [creating a pull request](https://help.github.com/articles/creating-a-pull-request/). 41 | 42 | 43 | ## Finding contributions to work on 44 | Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start. 45 | 46 | 47 | ## Code of Conduct 48 | This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). 49 | For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact 50 | opensource-codeofconduct@amazon.com with any additional questions or comments. 51 | 52 | 53 | ## Security issue notifications 54 | If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue. 55 | 56 | 57 | ## Licensing 58 | 59 | See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. 60 | -------------------------------------------------------------------------------- /saga-orchestration/InvokeOrchestratorLambda/src/InvokeOrchestratorLambda/Function.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Net; 6 | using System.Text.Json; 7 | using System.Text.Json.Serialization; 8 | using System.Threading.Tasks; 9 | using Amazon.Lambda.Core; 10 | using Amazon; 11 | using Amazon.StepFunctions; 12 | using Amazon.StepFunctions.Model; 13 | using Amazon.Lambda.APIGatewayEvents; 14 | 15 | // Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class. 16 | [assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] 17 | 18 | namespace InvokeOrchestratorLambda 19 | { 20 | public class InvokeOrchestrator 21 | { 22 | public async Task FunctionHandler(OrderDetails orderDetails, ILambdaContext context) 23 | { 24 | var input = HttpStatusCode.Accepted; 25 | var awsRegion = System.Environment.GetEnvironmentVariable("AWS_REGION"); 26 | var regionEndpoint = RegionEndpoint.GetBySystemName(awsRegion); 27 | var amazonStepFunctionsConfig = new AmazonStepFunctionsConfig {RegionEndpoint = regionEndpoint}; 28 | 29 | using (var amazonStepFunctionsClient = 30 | new AmazonStepFunctionsClient(amazonStepFunctionsConfig)) 31 | { 32 | context.Logger.Log(orderDetails.ItemId); 33 | 34 | var jsonInput = JsonSerializer.Serialize(orderDetails); 35 | context.Logger.Log(jsonInput); 36 | 37 | var functionArn = context.InvokedFunctionArn; 38 | var splitArn = functionArn.Split(":"); 39 | var accountId = splitArn[4]; 40 | 41 | 42 | var startExecutionRequest = new StartExecutionRequest 43 | { 44 | Input = jsonInput, 45 | StateMachineArn = "arn:aws:states:" + awsRegion + ":" + accountId + ":stateMachine:DistributedTransactionOrchestrator" 46 | }; 47 | context.Logger.Log("before StartExecutionAsync"); 48 | var taskStartExecutionResponse = 49 | await amazonStepFunctionsClient.StartExecutionAsync(startExecutionRequest); 50 | input = taskStartExecutionResponse.HttpStatusCode; 51 | context.Logger.Log(input.ToString()); 52 | } 53 | 54 | var response = CreateResponse(input); 55 | return response; 56 | } 57 | 58 | 59 | private APIGatewayProxyResponse CreateResponse(HttpStatusCode httpStatusCode) 60 | { 61 | int statusCode = (int)httpStatusCode; 62 | 63 | var response = new APIGatewayProxyResponse 64 | { 65 | StatusCode = statusCode, 66 | Body = "Processed", 67 | Headers = new Dictionary 68 | { 69 | { "Content-Type", "application/json" }, 70 | { "Access-Control-Allow-Origin", "*" } 71 | } 72 | }; 73 | 74 | return response; 75 | } 76 | } 77 | public class OrderDetails 78 | { 79 | public string ItemId { get; set; } 80 | public string CustomerId { get; set; } 81 | public string MessageId { get; set; } 82 | public string FailAtStage { get; set; } 83 | public string Status { get; set; } 84 | } 85 | } -------------------------------------------------------------------------------- /saga-orchestration/RevertInventoryLambda/src/RevertInventoryLambda/Function.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Amazon.DynamoDBv2; 6 | using Amazon.DynamoDBv2.Model; 7 | using Amazon.Lambda.Core; 8 | 9 | // Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class. 10 | [assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] 11 | 12 | namespace RevertInventoryLambda 13 | { 14 | public class RevertInventory 15 | { 16 | private static string tableName = "Inventory"; 17 | private static AmazonDynamoDBClient client = new AmazonDynamoDBClient(); 18 | public OrderDetails FunctionHandler(OrderDetails orderDetails, ILambdaContext context) 19 | { 20 | try 21 | { 22 | UpdateStock(orderDetails.ItemId, context); 23 | orderDetails.Status = "INVENTORY_REVERTED"; 24 | } 25 | catch (Exception ex) 26 | { 27 | orderDetails.Status = "ERROR"; 28 | context.Logger.Log("Error while updating inventory"); 29 | context.Logger.Log(ex.Message); 30 | context.Logger.Log(ex.StackTrace); 31 | } 32 | 33 | return orderDetails; 34 | } 35 | 36 | private void UpdateStock(string ItemId, ILambdaContext context) 37 | { 38 | var updateRequest = new UpdateItemRequest() 39 | { 40 | TableName = tableName, 41 | Key = new Dictionary 42 | { 43 | { "ItemId", new AttributeValue { S =ItemId } } 44 | }, 45 | ExpressionAttributeValues = new Dictionary 46 | { 47 | { ":inc", new AttributeValue { N = "1" } } 48 | }, 49 | UpdateExpression = "SET ItemsInStock = ItemsInStock + :inc", 50 | ReturnValues = "ALL_NEW" 51 | }; 52 | var response = client.UpdateItemAsync(updateRequest); 53 | 54 | // Check the response. 55 | var attributeList = response.Result.Attributes; // attribute list in the response. 56 | // print attributeList. 57 | Console.WriteLine("\nPrinting item after incrementing stock ............"); 58 | PrintItem(attributeList,context); 59 | } 60 | 61 | private void PrintItem(Dictionary attributeList,ILambdaContext context) 62 | { 63 | foreach (KeyValuePair kvp in attributeList) 64 | { 65 | string attributeName = kvp.Key; 66 | AttributeValue value = kvp.Value; 67 | 68 | context.Logger.Log( 69 | attributeName + " " + 70 | (value.S == null ? "" : value.S + " ") + 71 | (value.N == null ? "" : value.N + " ") + 72 | (value.SS == null ? "" : string.Join(",", value.SS.ToArray()) + " ") + 73 | (value.NS == null ? "" : string.Join(",", value.NS.ToArray()) + " ") 74 | ); 75 | } 76 | } 77 | } 78 | 79 | public class OrderDetails 80 | { 81 | public string ItemId { get; set; } 82 | public string CustomerId { get; set; } 83 | public string MessageId { get; set; } 84 | public string FailAtStage { get; set; } 85 | public string Status { get; set; } 86 | } 87 | } -------------------------------------------------------------------------------- /saga-orchestration/UpdateInventoryLambda/src/UpdateInventoryLambda/Function.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Amazon.Lambda.Core; 6 | using Amazon.DynamoDBv2; 7 | using Amazon.DynamoDBv2.Model; 8 | 9 | // Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class. 10 | [assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))] 11 | 12 | namespace UpdateInventoryLambda 13 | { 14 | public class UpdateInventory 15 | { 16 | private StageNameEnum CurrentStage = StageNameEnum.UpdateInventory; 17 | 18 | private static string tableName = "Inventory"; 19 | private static AmazonDynamoDBClient client = new AmazonDynamoDBClient(); 20 | public OrderDetails FunctionHandler(OrderDetails orderDetails, ILambdaContext context) 21 | { 22 | Enum.TryParse(orderDetails.FailAtStage, out StageNameEnum stage); 23 | 24 | try 25 | { 26 | UpdateStock(orderDetails.ItemId, context); 27 | orderDetails.Status = "INVENTORY_UPDATED"; 28 | } 29 | catch (Exception ex) 30 | { 31 | orderDetails.Status = "ERROR"; 32 | context.Logger.Log("Error while updating inventory"); 33 | context.Logger.Log(ex.Message); 34 | context.Logger.Log(ex.StackTrace); 35 | } 36 | 37 | 38 | if (stage.Equals(CurrentStage)) 39 | orderDetails.Status = "ERROR"; 40 | 41 | // RetrieveItem(orderDetails.ItemId,context); 42 | return orderDetails; 43 | } 44 | 45 | /*private void RetrieveItem(string ItemId, ILambdaContext context) 46 | { 47 | var request = new GetItemRequest 48 | { 49 | TableName = tableName, 50 | Key = new Dictionary() 51 | { 52 | { "ItemId", new AttributeValue { 53 | S = ItemId 54 | } } 55 | }, 56 | ProjectionExpression = "ItemId, ItemName, ItemsInStock, ItemStatus" 57 | //, ConsistentRead = true 58 | }; 59 | 60 | context.Logger.Log("Before retrieving item ............"); 61 | var response = client.GetItemAsync(request); 62 | 63 | // Check the response. 64 | var attributeList = response.Result.Item; // attribute list in the response. 65 | context.Logger.Log("\nPrinting item after retrieving it ............"); 66 | PrintItem(attributeList, context); 67 | }*/ 68 | 69 | private void UpdateStock(string ItemId, ILambdaContext context) 70 | { 71 | var updateRequest = new UpdateItemRequest() 72 | { 73 | TableName = tableName, 74 | Key = new Dictionary 75 | { 76 | { "ItemId", new AttributeValue { S =ItemId } } 77 | }, 78 | ExpressionAttributeValues = new Dictionary 79 | { 80 | { ":inc", new AttributeValue { N = "1" } } 81 | }, 82 | UpdateExpression = "SET ItemsInStock = ItemsInStock - :inc", 83 | ReturnValues = "ALL_NEW" 84 | }; 85 | var response = client.UpdateItemAsync(updateRequest); 86 | var attributeList = response.Result.Attributes; // attribute list in the response. 87 | // print attributeList. 88 | Console.WriteLine("\nPrinting item after decrementing stock ............"); 89 | PrintItem(attributeList,context); 90 | } 91 | 92 | private void PrintItem(Dictionary attributeList,ILambdaContext context) 93 | { 94 | foreach (KeyValuePair kvp in attributeList) 95 | { 96 | string attributeName = kvp.Key; 97 | AttributeValue value = kvp.Value; 98 | 99 | context.Logger.Log( 100 | attributeName + " " + 101 | (value.S == null ? "" : value.S + " ") + 102 | (value.N == null ? "" : value.N + " ") + 103 | (value.SS == null ? "" : string.Join(",", value.SS.ToArray()) + " ") + 104 | (value.NS == null ? "" : string.Join(",", value.NS.ToArray()) + " ") 105 | ); 106 | } 107 | } 108 | } 109 | 110 | 111 | 112 | public class OrderDetails 113 | { 114 | public string ItemId { get; set; } 115 | public string CustomerId { get; set; } 116 | public string MessageId { get; set; } 117 | public string FailAtStage { get; set; } 118 | public string Status { get; set; } 119 | } 120 | 121 | public enum StageNameEnum 122 | { 123 | PlaceOrder = 0, 124 | MakePayment = 1, 125 | UpdateInventory = 2, 126 | SendNotification = 3, 127 | None 128 | } 129 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Build a serverless distributed application in .NET using Saga orchestration pattern 2 | 3 | The saga orchestration pattern helps preserve data integrity in distributed transactions that span multiple services. In a distributed transaction, multiple services can be called before a transaction is completed. When the services store data in different data stores, it can be challenging to maintain data consistency across these data stores. The source code in this repo provids sample code for the implementation of the saga orchestration pattern using .NET 6.0 on AWS. 4 | 5 | Use the saga orchestration pattern when: 6 | 7 | * Your system requires data integrity and consistency in distributed transactions that span multiple data stores. 8 | * The data store doesn't provide 2PC to provide ACID transactions, and implementing 2PC within the application boundaries is a complex task. 9 | * You have NoSQL databases, which do not provide ACID transactions, and you need to update multiple tables within a single transaction. 10 | 11 | To learn more about the Circuit Breaker pattern and other patterns, please refer to the Amazon Prescriptive Guidance page on [Cloud Design Patterns, architectures, and implementations](https://docs.aws.amazon.com/prescriptive-guidance/latest/cloud-design-patterns/circuit-breaker.html). 12 | 13 | ## Prerequisites 14 | 15 | For this walkthrough, you need: 16 | - An [AWS](https://signin.aws.amazon.com/signin?redirect_uri=https%3A%2F%2Fportal.aws.amazon.com%2Fbilling%2Fsignup%2Fresume&client_id=signup) account 17 | - An AWS user with AdministratorAccess (see the [instructions](https://console.aws.amazon.com/iam/home#/roles%24new?step=review&commonUseCase=EC2%2BEC2&selectedUseCase=EC2&policies=arn:aws:iam::aws:policy%2FAdministratorAccess) on the [AWS Identity and Access Management](http://aws.amazon.com/iam) (IAM) console) 18 | - Access to the following AWS services: Amazon API Gateway, AWS Lambda, AWS Step Functions, and Amazon DynamoDB. 19 | - [Node.js](https://nodejs.org/en/download/) installed 20 | - .NET 6.0 SDK installed 21 | - JetBrains Rider or Microsoft Visual Studio 2017 or later (or Visual Studio Code) 22 | - [Postman](https://www.postman.com/downloads/) to make the API call 23 | 24 | ## Setting up the environment 25 | 26 | For this walkthrough, use the [AWS CDK](https://aws.amazon.com/cdk/) code in the GitHub Repository to create the AWS resources. These include IAM roles, REST API using API Gateway, DynamoDB tables, the Step Functions workflow and Lambda functions. 27 | 28 | 1. You need an AWS access key ID and secret access key for configuring the AWS Command Line Interface (AWS CLI). To learn more about configuring the AWS CLI, follow these [instructions](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html). 29 | 2. Clone the repo: 30 | ```bash 31 | git clone https://github.com/aws-samples/saga-orchestration-netcore-blog 32 | ``` 33 | 3. After cloning, this is the directory structure: 34 | 35 | ![directory_structure](images/directory_structure.png) 36 | 37 | 4. The Lambda functions in the saga-orchestration directory must be packaged and copied to the cdk-saga-orchestration\lambdas directory before deployment. Run these commands to process the PlaceOrderLambda function: 38 | ```bash 39 | cd saga-orchestration 40 | cd PlaceOrderLambda/src/PlaceOrderLambda 41 | dotnet lambda package 42 | cp bin/Release/netcoreapp3.1/PlaceOrderLambda.zip ../../../../cdk-saga-orchestration/lambdas 43 | ``` 44 | 45 | 5. Repeat the same commands for all the Lambda functions in the saga-orchestration directory. 46 | 47 | 6. Build the CDK code before deploying to the console: 48 | ```bash 49 | cd cdk-saga-orchestration/src/CdkSagaOrchestration 50 | dotnet build 51 | ``` 52 | 53 | 7. Install the aws-cdk package: 54 | ```bash 55 | npm install -g aws-cdk 56 | ``` 57 | 58 | 8. The cdk synth command causes the resources defined in the application to be translated into an [AWS CloudFormation](https://aws.amazon.com/cloudformation/) template. The cdk deploy command deploys the stacks into your AWS account. Run: 59 | ```bash 60 | cd cdk-saga-orchestration 61 | cdk synth 62 | cdk deploy 63 | ``` 64 | 9. CDK deploys the environment to AWS. You can monitor the progress using the CloudFormation console. The stack name is CdkSagaOrchestrationStack: 65 | ![cfn_stack](images/cfn_stack.png) 66 | 67 | ## The Step Functions configuration 68 | 69 | ```cs 70 | var stepDefinition = placeOrderTask 71 | .Next(new Choice(this, "Is order placed") 72 | .When(Condition.StringEquals("$.Status", "ORDER_PLACED"), updateInventoryTask 73 | .Next(new Choice(this, "Is inventory updated") 74 | .When(Condition.StringEquals("$.Status", "INVENTORY_UPDATED"), 75 | makePaymentTask.Next(new Choice(this, "Is payment success") 76 | .When(Condition.StringEquals("$.Status", "PAYMENT_COMPLETED"), successState) 77 | .When(Condition.StringEquals("$.Status", "ERROR"), revertPaymentTask))) 78 | .When(Condition.StringEquals("$.Status", "ERROR"), waitState))) 79 | .When(Condition.StringEquals("$.Status", "ERROR"), failState)); 80 | ``` 81 | 82 | Compare the states language definition for the state machine with the definition below. Also observe the inputs and outputs for each step and how the conditions have been configured. The steps with type Task call a Lambda function for the processing. The steps with type Choice are decision-making steps that define the workflow. 83 | 84 | ![stepfunctions_graph](images/stepfunctions_graph.png) 85 | 86 | 87 | ## Setting up the DynamoDB table 88 | 89 | The Orders and Inventory DynamoDB tables are created using AWS CDK. The following snippet creates a DynamoDB table with AWS CDK for .NET: 90 | 91 | ```cs 92 | var inventoryTable = new Table(this, "Inventory", new TableProps 93 | { 94 | TableName = "Inventory", 95 | PartitionKey = new Attribute 96 | { 97 | Name = "ItemId", 98 | Type = AttributeType.STRING 99 | }, 100 | RemovalPolicy = RemovalPolicy.DESTROY 101 | }); 102 | ``` 103 | 104 | You need to create some items in the **Inventory** table to test the saga orchestration pattern: 105 | 106 | 1. In the AWS Console, open the DynamoDB service page, click on Tables in the left pane, and select the Inventory table. 107 | 108 | ![dynamodb_console](images/dynamodb_console.png) 109 | 110 | 2. Choose _Create Item_ from the Actions menu. 111 | 3. Choose _JSON View_ and switch off the _View DynamoDB JSON_ toggle switch. 112 | ![dynamodb_createitem](images/dynamodb_createitem.png) 113 | 4. Paste the following contents, then choose Save. 114 | ```json 115 | { 116 | "ItemId": "ITEM001", 117 | "ItemName": "Soap", 118 | "ItemsInStock": 1000, 119 | "ItemStatus": "" 120 | } 121 | ``` 122 | 5. Similarly, create two more items into the **Inventory** table. 123 | ```json 124 | { 125 | "ItemId": "ITEM002", 126 | "ItemName": "Shampoo", 127 | "ItemsInStock": 500, 128 | "ItemStatus": "" 129 | } 130 | 131 | { 132 | "ItemId": "ITEM003", 133 | "ItemName": "Toothpaste", 134 | "ItemsInStock": 2000, 135 | "ItemStatus": "" 136 | } 137 | ``` 138 | The Lambda functions UpdateInventoryLambda and RevertInventoryLambda increment and decrement the ItemsInStock attribute value. The Lambda functions PlaceOrderLambda and UpdateOrderLambda insert and delete items in the Orders table. These are invoked by the saga orchestration workflow. 139 | 140 | ## Triggering the saga orchestration workflow 141 | 142 | The API Gateway endpoint, _SagaOrchestratorAPI_, is created using AWS CDK. To get the invoke URL, go to the CloudFormation outputs page and copy the value of the output variable, SagaOrchestratorAPIEndpoint. 143 | 144 | ![apigateway_endpoint](images/apigateway_endpoint.png) 145 | 146 | 1. From Postman, open a new tab. Select POST in the dropdown and enter the copied URL in the textbox. Move to the Headers tab and add a new header with the key ‘Content-Type’ and value as ‘application/json’: 147 | ![postman_settings](images/postman_settings.png) 148 | 149 | 2. In the Body tab, enter the following input and choose Send. 150 | ```json 151 | { 152 | "ItemId": "ITEM001", 153 | "CustomerId": "ABC/002", 154 | "MessageId": "", 155 | "FailAtStage": "None" 156 | } 157 | ``` 158 | 3. You see the output: 159 | ![postman_output](images/postman_output.png) 160 | 161 | 4. Open the [Step Functions console](https://console.aws.amazon.com/states/home) and view the execution. The graph inspector shows that the execution has completed successfully. 162 | ![statemachine_success](images/statemachine_success.png) 163 | 164 | 5. Check the items in the DynamoDB tables, Orders & Inventory. You can see an item in the Orders table indicating that an order is placed. The ItemsInStock in the Inventory table has been deducted. 165 | ![orders](images/orders.png) 166 | ![inventory](images/inventory.png) 167 | 168 | 6. To simulate the failure workflow in the saga orchestrator, send the following JSON as body in the Postman call. The FailAtStage parameter injects the failure in the workflow. Select Send in Postman after updating the Body: 169 | 170 | ```json 171 | { 172 | "ItemId": "ITEM002", 173 | "CustomerId": "DEF/002", 174 | "MessageId": "", 175 | "FailAtStage": "UpdateInventory" 176 | } 177 | ``` 178 | 7. Open the Step Functions console to see the execution. 179 | 8. While the function waits in the wait state, look at the items in the DynamoDB tables. A new item is added to the Orders table and the stock for Shampoo is deducted in the Inventory table. 180 | ![orders_beforecompensation](images/orders_beforecompensation.png) 181 | ![inventory_beforecompensation](images/inventory_beforecompensation.png) 182 | 183 | 9. Once the wait completes, the compensatory transaction steps are run: 184 | ![statemachine_compensation](images/statemachine_compensation.png) 185 | 186 | 10. In the graph inspector, select the Update Inventory step. On the right pane, click on the Step output tab. The status is ERROR, which changes the control flow to run the compensatory transactions. 187 | ![step_output](images/step_output.png) 188 | 189 | 11. Look at the items in the DynamoDB table again. The data is now back to a consistent state, as the compensatory transactions have run to preserve data integrity: 190 | ![orders_aftercompensation](images/orders_aftercompensation.png) 191 | ![inventory_aftercompensation](images/inventory_aftercompensation.png) 192 | 193 | The Step Functions workflow implements the saga orchestration pattern. It performs the coordination across distributed services and runs the transactions. It also performs compensatory transactions to preserve the data integrity. 194 | 195 | ## Cleaning up 196 | 197 | To avoid incurring additional charges, clean up all the resources that have been created. Run the following command from a terminal window. This deletes all the resources that were created as part of this example. 198 | 199 | ```bash 200 | cdk destroy 201 | ``` 202 | 203 | Blog reference: [https://aws.amazon.com/blogs/compute/building-a-serverless-distributed-application-using-a-saga-orchestration-pattern/](https://aws.amazon.com/blogs/compute/building-a-serverless-distributed-application-using-a-saga-orchestration-pattern/) 204 | 205 | ## Security 206 | 207 | See [CONTRIBUTING](CONTRIBUTING.md#security-issue-notifications) for more information. 208 | 209 | ## License 210 | 211 | This library is licensed under the MIT-0 License. See the LICENSE file. -------------------------------------------------------------------------------- /cdk-saga-orchestration/src/CdkSagaOrchestration/CdkSagaOrchestrationStack.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using Amazon.CDK; 3 | using Amazon.CDK.AWS.APIGateway; 4 | using Amazon.CDK.AWS.DynamoDB; 5 | using Amazon.CDK.AWS.IAM; 6 | using Amazon.CDK.AWS.Lambda; 7 | using Amazon.CDK.AWS.StepFunctions; 8 | using Amazon.CDK.AWS.StepFunctions.Tasks; 9 | using Constructs; 10 | 11 | namespace CdkSagaOrchestration 12 | { 13 | public class CdkSagaOrchestrationStack : Stack 14 | { 15 | public CdkSagaOrchestrationStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props) 16 | { 17 | 18 | #region iamroles 19 | var iamLambdaRole = new Role(this,"LambdaExecutionRole", new RoleProps 20 | { 21 | RoleName = "LambdaExecutionRole", 22 | AssumedBy = new ServicePrincipal("lambda.amazonaws.com") 23 | }); 24 | 25 | iamLambdaRole.AddManagedPolicy(ManagedPolicy.FromAwsManagedPolicyName("AmazonDynamoDBFullAccess")); 26 | iamLambdaRole.AddManagedPolicy(ManagedPolicy.FromAwsManagedPolicyName("SecretsManagerReadWrite")); 27 | iamLambdaRole.AddManagedPolicy(ManagedPolicy.FromAwsManagedPolicyName("CloudWatchLogsFullAccess")); 28 | iamLambdaRole.AddManagedPolicy(ManagedPolicy.FromAwsManagedPolicyName("AWSXrayFullAccess")); 29 | iamLambdaRole.AddManagedPolicy(ManagedPolicy.FromManagedPolicyArn(this,"AWSLambdaVPCAccessExecutionRole","arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole")); 30 | iamLambdaRole.AddManagedPolicy(ManagedPolicy.FromAwsManagedPolicyName("AWSStepFunctionsFullAccess")); 31 | 32 | var iamStepFunctionRole = new Role(this,"step_functions_basic_execution", new RoleProps 33 | { 34 | RoleName = "step_functions_basic_execution", 35 | AssumedBy = new ServicePrincipal("states.amazonaws.com") 36 | }); 37 | 38 | iamStepFunctionRole.AddManagedPolicy(ManagedPolicy.FromAwsManagedPolicyName("CloudWatchLogsFullAccess")); 39 | iamStepFunctionRole.AddManagedPolicy(ManagedPolicy.FromManagedPolicyArn(this,"AWSLambdaRole","arn:aws:iam::aws:policy/service-role/AWSLambdaRole")); 40 | iamStepFunctionRole.AddManagedPolicy(ManagedPolicy.FromAwsManagedPolicyName("AWSXrayFullAccess")); 41 | #endregion iamroles 42 | 43 | #region DynamoDB tables 44 | 45 | var inventoryTable = new Table(this, "Inventory", new TableProps 46 | { 47 | TableName = "Inventory", 48 | PartitionKey = new Attribute 49 | { 50 | Name = "ItemId", 51 | Type = AttributeType.STRING 52 | }, 53 | RemovalPolicy = RemovalPolicy.DESTROY 54 | }); 55 | 56 | var ordersTable = new Table(this, "Orders", new TableProps 57 | { 58 | TableName = "Orders", 59 | PartitionKey = new Attribute 60 | { 61 | Name = "ItemId", 62 | Type = AttributeType.STRING 63 | }, 64 | SortKey = new Attribute 65 | { 66 | Name = "CustomerId", 67 | Type = AttributeType.STRING 68 | }, 69 | RemovalPolicy = RemovalPolicy.DESTROY 70 | }); 71 | 72 | #endregion 73 | 74 | //Define Lambda Functions 75 | var invokeOrchestratorLambda = new Function(this,"InvokeOrchestratorLambda", new FunctionProps 76 | { 77 | FunctionName = "InvokeOrchestratorLambda", 78 | Runtime = Runtime.DOTNET_6, 79 | Handler = "InvokeOrchestratorLambda::InvokeOrchestratorLambda.InvokeOrchestrator::FunctionHandler", 80 | Role = iamLambdaRole, 81 | Code = Code.FromAsset("lambdas/InvokeOrchestratorLambda.zip"), 82 | Timeout = Duration.Seconds(300), 83 | Tracing = Tracing.ACTIVE 84 | }); 85 | 86 | #region API Gateway 87 | var api = new RestApi(this, "SagaOrchestratorAPI", new RestApiProps 88 | { 89 | RestApiName = "SagaOrchestratorAPI", 90 | Description = "This service triggers the saga orchestration workflow." 91 | 92 | }); 93 | 94 | var invokeOrchestratorIntegration = new LambdaIntegration(invokeOrchestratorLambda, new LambdaIntegrationOptions 95 | { 96 | Proxy = false, 97 | PassthroughBehavior = PassthroughBehavior.WHEN_NO_TEMPLATES, 98 | //Integration request 99 | RequestTemplates = new Dictionary 100 | { 101 | ["application/json"] = "#set($inputRoot = $input.path(\'$\')) { \"ItemId\" : \"$inputRoot.ItemId\", \"CustomerId\" : \"$inputRoot.CustomerId\", \"MessageId\" : \"$inputRoot.MessageId\",\"FailAtStage\" : \"$inputRoot.FailAtStage\"}" 102 | }, 103 | //Integration response 104 | IntegrationResponses = new IIntegrationResponse[] 105 | { 106 | new IntegrationResponse 107 | { 108 | StatusCode = "200", 109 | ResponseTemplates = new Dictionary 110 | { 111 | { "application/json", "" } 112 | } 113 | } 114 | } 115 | }); 116 | 117 | var anyMethod = api.Root.AddMethod("ANY", invokeOrchestratorIntegration, new MethodOptions 118 | { 119 | //Method response 120 | MethodResponses = new[] 121 | { 122 | new MethodResponse 123 | { 124 | StatusCode = "200", ResponseModels = new Dictionary() 125 | { 126 | ["application/json"] = Model.EMPTY_MODEL 127 | } 128 | } 129 | } 130 | 131 | }); 132 | 133 | var mockIntegration = new MockIntegration(new IntegrationOptions 134 | { 135 | //Integration request 136 | RequestTemplates = new Dictionary 137 | { 138 | ["application/json"] = "{ \"statusCode\": \"200\" }" 139 | }, 140 | //Integration response 141 | IntegrationResponses = new IIntegrationResponse[] 142 | { 143 | new IntegrationResponse 144 | { 145 | StatusCode = "200", 146 | ResponseTemplates = new Dictionary 147 | { 148 | { "application/json", "" } 149 | } 150 | } 151 | } 152 | }); 153 | var mockMethod = api.Root.AddMethod("OPTIONS", mockIntegration, new MethodOptions 154 | { 155 | //Method response 156 | MethodResponses = new[] 157 | { 158 | new MethodResponse 159 | { 160 | StatusCode = "200", ResponseModels = new Dictionary() 161 | { 162 | ["application/json"] = Model.EMPTY_MODEL 163 | } 164 | } 165 | } 166 | }); 167 | 168 | #endregion 169 | 170 | #region Lambda Functions 171 | 172 | var placeOrderLambda = new Function(this,"PlaceOrderLambda", new FunctionProps 173 | { 174 | FunctionName = "PlaceOrderLambda", 175 | Runtime = Runtime.DOTNET_6, 176 | Handler = "PlaceOrderLambda::PlaceOrderLambda.PlaceOrder::FunctionHandler", 177 | Role = iamLambdaRole, 178 | Code = Code.FromAsset("lambdas/PlaceOrderLambda.zip"), 179 | Timeout = Duration.Seconds(300) 180 | }); 181 | 182 | var updateInventoryLambda = new Function(this,"UpdateInventoryLambda", new FunctionProps 183 | { 184 | FunctionName = "UpdateInventoryLambda", 185 | Runtime = Runtime.DOTNET_6, 186 | Handler = "UpdateInventoryLambda::UpdateInventoryLambda.UpdateInventory::FunctionHandler", 187 | Role = iamLambdaRole, 188 | Code = Code.FromAsset("lambdas/UpdateInventoryLambda.zip"), 189 | Timeout = Duration.Seconds(300) 190 | }); 191 | 192 | var makePaymentLambda = new Function(this,"MakePaymentLambda", new FunctionProps 193 | { 194 | FunctionName = "MakePaymentLambda", 195 | Runtime = Runtime.DOTNET_6, 196 | Handler = "MakePaymentLambda::MakePaymentLambda.MakePayment::FunctionHandler", 197 | Role = iamLambdaRole, 198 | Code = Code.FromAsset("lambdas/MakePaymentLambda.zip"), 199 | Timeout = Duration.Seconds(300) 200 | }); 201 | 202 | var revertPaymentLambda = new Function(this,"RevertPaymentLambda", new FunctionProps 203 | { 204 | FunctionName = "RevertPaymentLambda", 205 | Runtime = Runtime.DOTNET_6, 206 | Handler = "RevertPaymentLambda::RevertPaymentLambda.RevertPayment::FunctionHandler", 207 | Role = iamLambdaRole, 208 | Code = Code.FromAsset("lambdas/RevertPaymentLambda.zip"), 209 | Timeout = Duration.Seconds(300) 210 | }); 211 | 212 | var revertInventoryLambda = new Function(this,"RevertInventoryLambda", new FunctionProps 213 | { 214 | FunctionName = "RevertInventoryLambda", 215 | Runtime = Runtime.DOTNET_6, 216 | Handler = "RevertInventoryLambda::RevertInventoryLambda.RevertInventory::FunctionHandler", 217 | Role = iamLambdaRole, 218 | Code = Code.FromAsset("lambdas/RevertInventoryLambda.zip"), 219 | Timeout = Duration.Seconds(300) 220 | }); 221 | 222 | var removeOrderLambda = new Function(this,"RemoveOrderLambda", new FunctionProps 223 | { 224 | FunctionName = "RemoveOrderLambda", 225 | Runtime = Runtime.DOTNET_6, 226 | Handler = "RemoveOrderLambda::RemoveOrderLambda.RemoveOrder::FunctionHandler", 227 | Role = iamLambdaRole, 228 | Code = Code.FromAsset("lambdas/RemoveOrderLambda.zip"), 229 | Timeout = Duration.Seconds(300) 230 | }); 231 | 232 | #endregion 233 | 234 | 235 | 236 | #region stepfunction 237 | 238 | var successState = new Succeed(this,"SuccessState"); 239 | var failState = new Fail(this, "Fail"); 240 | 241 | var placeOrderTask = new LambdaInvoke(this, "Place Order", new LambdaInvokeProps 242 | { 243 | LambdaFunction = placeOrderLambda, 244 | Comment = "Place Order", 245 | RetryOnServiceExceptions = false, 246 | PayloadResponseOnly = true 247 | }); 248 | 249 | var updateInventoryTask = new LambdaInvoke(this,"Update Inventory", new LambdaInvokeProps 250 | { 251 | LambdaFunction = updateInventoryLambda, 252 | Comment = "Update inventory", 253 | RetryOnServiceExceptions = false, 254 | PayloadResponseOnly = true 255 | }); 256 | 257 | var makePaymentTask = new LambdaInvoke(this,"Make Payment", new LambdaInvokeProps 258 | { 259 | LambdaFunction = makePaymentLambda, 260 | Comment = "Make Payment", 261 | RetryOnServiceExceptions = false, 262 | PayloadResponseOnly = true 263 | }); 264 | 265 | var removeOrderTask = new LambdaInvoke(this, "Remove Order", new LambdaInvokeProps 266 | { 267 | LambdaFunction = removeOrderLambda, 268 | Comment = "Remove Order", 269 | RetryOnServiceExceptions = false, 270 | PayloadResponseOnly = true 271 | }).Next(failState); 272 | 273 | var revertInventoryTask = new LambdaInvoke(this,"Revert Inventory", new LambdaInvokeProps 274 | { 275 | LambdaFunction = revertInventoryLambda, 276 | Comment = "Revert inventory", 277 | RetryOnServiceExceptions = false, 278 | PayloadResponseOnly = true 279 | }).Next(removeOrderTask); 280 | 281 | var revertPaymentTask = new LambdaInvoke(this,"Revert Payment", new LambdaInvokeProps 282 | { 283 | LambdaFunction = revertPaymentLambda, 284 | Comment = "Revert Payment", 285 | RetryOnServiceExceptions = false, 286 | PayloadResponseOnly = true 287 | }).Next(revertInventoryTask); 288 | 289 | var waitState = new Wait(this, "Wait state", new WaitProps 290 | { 291 | Time = WaitTime.Duration(Duration.Seconds(30)) 292 | }).Next(revertInventoryTask); 293 | 294 | var stepDefinition = placeOrderTask 295 | .Next(new Choice(this, "Is order placed") 296 | .When(Condition.StringEquals("$.Status", "ORDER_PLACED"), updateInventoryTask 297 | .Next(new Choice(this, "Is inventory updated") 298 | .When(Condition.StringEquals("$.Status", "INVENTORY_UPDATED"), 299 | makePaymentTask.Next(new Choice(this, "Is payment success") 300 | .When(Condition.StringEquals("$.Status", "PAYMENT_COMPLETED"), successState) 301 | .When(Condition.StringEquals("$.Status", "ERROR"), revertPaymentTask))) 302 | .When(Condition.StringEquals("$.Status", "ERROR"), waitState))) 303 | .When(Condition.StringEquals("$.Status", "ERROR"), failState)); 304 | 305 | var stateMachine = new StateMachine(this, "DistributedTransactionOrchestrator", new StateMachineProps { 306 | StateMachineName = "DistributedTransactionOrchestrator", 307 | StateMachineType = StateMachineType.STANDARD, 308 | Role = iamStepFunctionRole, 309 | TracingEnabled = true, 310 | Definition = stepDefinition 311 | }); 312 | #endregion 313 | } 314 | } 315 | 316 | } --------------------------------------------------------------------------------