Exemple #1
0
        internal TheScalableWebhookStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            /*
             * DynamoDB Table
             * This is standing in for what is RDS on the diagram due to simpler/cheaper setup
             */
            _dynamoDbTable = new DynamoDB.Table(this, "Messages", new DynamoDB.TableProps
            {
                PartitionKey = new DynamoDB.Attribute {
                    Name = "id", Type = DynamoDB.AttributeType.STRING
                }
            });

            /*
             * Queue Setup
             */
            _queueRds = new SQS.Queue(this, "RDSPublishQueue", new SQS.QueueProps
            {
                VisibilityTimeout = Duration.Seconds(300)
            });

            /*
             * Lambdas
             * Both publisher and subscriber from pattern
             */

            /*
             * defines an AWS  Lambda resource to publish to our sqs_queue
             */
            _functionPublish = new Lambda.Function(this, "SQSPublishLambdaHandler", new Lambda.FunctionProps
            {
                Runtime     = Lambda.Runtime.NODEJS_12_X,                  // execution environment
                Handler     = "lambda.handler",                            // file is "lambda", function is "handler"
                Code        = Lambda.Code.FromAsset("lambda_fns/publish"), // code loaded from the "lambda_fns/publish" directory
                Environment = new Dictionary <string, string>
                {
                    { "queueURL", _queueRds.QueueUrl }
                }
            });

            _queueRds.GrantSendMessages(_functionPublish);

            /*
             * defines an AWS  Lambda resource to pull from our sqs_queue
             */
            _functionSubscribe = new Lambda.Function(this, "SQSSubscribeLambdaHandler", new Lambda.FunctionProps
            {
                Runtime     = Lambda.Runtime.NODEJS_12_X,                    // execution environment
                Handler     = "lambda.handler",                              // file is "lambda", function is "handler"
                Code        = Lambda.Code.FromAsset("lambda_fns/subscribe"), // code loaded from the "lambda_fns/subscribe" directory
                Environment = new Dictionary <string, string>
                {
                    { "queueURL", _queueRds.QueueUrl },
                    { "tableName", _dynamoDbTable.TableName }
                },
                ReservedConcurrentExecutions = 2 // throttle lambda to 2 concurrent invocations
            });

            _queueRds.GrantConsumeMessages(_functionSubscribe);
            _functionSubscribe.AddEventSource(new LambdaEvents.SqsEventSource(_queueRds));
            _dynamoDbTable.GrantReadWriteData(_functionSubscribe);

            /**
             * API Gateway Proxy
             * Used to expose the webhook through a URL
             *
             * defines an API Gateway REST API resource backed by our "sqs_publish_lambda" function.
             */
            new APIG.LambdaRestApi(this, "Endpoint", new APIG.LambdaRestApiProps
            {
                Handler = _functionPublish
            });
        }
Exemple #2
0
        internal TheStateMachineStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
        {
            // Step Function Starts Here

            // The first thing we need to do is see if they are asking for pineapple on a pizza
            _pineppaleCheckHandler = new Lambda.Function(this, "pineappleCheckLambdaHandler", new Lambda.FunctionProps
            {
                Runtime = Lambda.Runtime.NODEJS_12_X,
                Code    = Lambda.Code.FromAsset("lambda_fns"),
                Handler = "orderPizza.handler"
            });

            /*
             * Step functions are built up of steps, we need to define our first step
             * This step was refactored due to Deprecated function
             */
            _orderPizzaTask = new StepFuncionTasks.LambdaInvoke(this, "Order Pizza Job", new StepFuncionTasks.LambdaInvokeProps
            {
                LambdaFunction      = _pineppaleCheckHandler,
                InputPath           = "$.flavour",
                ResultPath          = "$.pineappleAnalysis",
                PayloadResponseOnly = true
            });

            // Pizza Order failure step defined
            _jobFailed = new StepFunction.Fail(this, "Sorry, We Dont add Pineapple", new StepFunction.FailProps
            {
                Cause = "Failed To Make Pizza",
                Error = "They asked for Pineapple"
            });

            // If they didnt ask for pineapple let's cook the pizza
            _cookPizza = new StepFunction.Pass(this, "Lets make your pizza");

            // If they ask for a pizza with pineapple, fail. Otherwise cook the pizza
            _chainDefinition = StepFunction.Chain
                               .Start(_orderPizzaTask)
                               .Next(new StepFunction.Choice(this, "With Pineapple?") // Logical choice added to flow
                                     .When(StepFunction.Condition.BooleanEquals("$.pineappleAnalysis.containsPineapple", true), _jobFailed)
                                     .Otherwise(_cookPizza));

            // Building the state machine
            _stateMachine = new StepFunction.StateMachine(this, "StateMachine", new StepFunction.StateMachineProps
            {
                Definition = _chainDefinition,
                Timeout    = Duration.Minutes(5)
            });

            /**
             * Dead Letter Queue Setup
             * SQS creation
             * https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-dead-letter-queues.html
             */
            _deadeLetterQueue = new SQS.Queue(this, "stateMachineLambdaDLQ", new SQS.QueueProps
            {
                VisibilityTimeout = Duration.Seconds(300)
            });

            // defines an AWS Lambda resource to connect to our API Gateway
            _stateMachineHandler = new Lambda.Function(this, "stateMachineLambdaHandler", new Lambda.FunctionProps
            {
                Runtime         = Lambda.Runtime.NODEJS_12_X,
                Code            = Lambda.Code.FromAsset("lambda_fns"),
                Handler         = "stateMachineLambda.handler",
                DeadLetterQueue = _deadeLetterQueue,
                Environment     = new Dictionary <string, string>
                {
                    { "statemachine_arn", _stateMachine.StateMachineArn }
                }
            });

            // Grants to state machine execution
            _stateMachine.GrantStartExecution(_stateMachineHandler);

            /*
             * Simple API Gateway proxy integration
             */
            // defines an API Gateway REST API resource backed by our "sqs_publish_lambda" function.
            new APIGateway.LambdaRestApi(this, "Endpoint", new APIGateway.LambdaRestApiProps
            {
                Handler = _stateMachineHandler
            });
        }