{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Description": "A sample template to setup infrastructure to poll data from Neptune Stream.",
  "Parameters": {
    "ApplicationName": {
      "Type": "String",
      "Default": "NeptuneStream",
      "Description": "Application Name used as a reference to create resources"
    },
    "AdditionalParams": {
      "Type": "String",
      "Default": "",
      "Description": "Additional params to be supplied to Lambda via environment variable in the form of a JSON object."
    },
    "LambdaS3Bucket": {
      "Type": "String",
      "Description": "Stream poller Lambda S3 bucket"
    },
    "LambdaS3Key": {
      "Type": "String",
      "Description": "Stream poller Lambda S3 key"
    },
    "LambdaMemorySize": {
      "Type": "Number",
      "Default": 128,
      "Description": "Poller Lambda  memory size (in MB)."
    },
    "LambdaRuntime": {
      "Type": "String",
      "Description": "Lambda Runtime",
      "Default": "python3.12",
      "AllowedValues": [
        "python3.12"
      ]
    },
    "LambdaLoggingLevel": {
      "Type": "String",
      "Default": "INFO",
      "AllowedValues": [
        "DEBUG",
        "INFO",
        "WARN",
        "ERROR",
        "FATAL"
      ],
      "Description": "Poller Lambda logging level."
    },
    "ManagedPolicies": {
      "Type": "CommaDelimitedList",
      "Default": "",
      "Description": "Comma-delimited list of ARNs of managed policies to be attached to Lambda execution role."
    },
    "StreamRecordsHandler": {
      "Type": "String",
      "Description": "Handler for processing stream records. Optional Parameter - If left blank default Handler is used."
    },
    "StreamRecordsBatchSize": {
      "Type": "Number",
      "Default": 5000,
      "MaxValue": 50000,
      "MinValue": 1,
      "Description": "Number of records to be read from stream in each batch. Should be between 1 to 50000."
    },
    "MaxPollingWaitTime": {
      "Type": "Number",
      "Default": 60,
      "MaxValue": 3600,
      "MinValue": 0,
      "Description": "Maximum wait time in seconds between two successive polling from stream. Set value to 0 sec for continuous polling. Maximum value can be 3600 sec (1 hour)."
    },
    "MaxPollingInterval": {
      "Type": "Number",
      "Default": 600,
      "MaxValue": 900,
      "MinValue": 5,
      "Description": "Period for which we can continuously poll stream for records on one Lambda instance. Should be between 5 sec to 900 sec. This parameter is used to set Poller Lambda Timeout."
    },
    "NeptuneStreamEndpoint": {
      "Type": "String",
      "AllowedPattern": "^(.+)$",
      "ConstraintDescription": "Must be a valid stream endpoint",
      "Description": "Endpoint for source Neptune Stream. This is of the form https://<cluster>:<port>/propertygraph/stream or https://<cluster>:<port>/sparql/stream."
    },
    "IAMAuthEnabledOnSourceStream": {
      "Type": "String",
      "Default": "false",
      "AllowedValues": [
        "true",
        "false"
      ],
      "ConstraintDescription": "Must be a either true or false",
      "Description": "Flag to determine if IAM Auth is Enabled for Source Neptune Cluster or not."
    },
    "StreamDBClusterResourceId": {
      "Type": "String",
      "Default": "",
      "Description": "Neptune DB Cluster Resource Id. Ex: cluster-5DSWZGISGVCHJPHOV5MK7QF2PY. Optional Parameter- Only needed when IAM Auth is Enabled."
    },
    "StepFunctionFallbackPeriod": {
      "Type": "Number",
      "Default": 5,
      "Description": "Period after which Step function is invoked using Cloud Watch Events to recover from failure. Unit for Step Function Fallback period is set separately."
    },
    "StepFunctionFallbackPeriodUnit": {
      "Type": "String",
      "Default": "minutes",
      "AllowedValues": [
        "minutes",
        "minute",
        "hours",
        "hour",
        "days",
        "day"
      ],
      "Description": "Step Function FallbackPeriod unit. Should be one of minutes, minute, hours, hour, days, day"
    },
    "NotificationEmail": {
      "Type": "String",
      "Default": "",
      "Description": "Email Address for CloudWatch Alarm Notification. Optional Parameter - Only needed when selecting option to create CloudWatch Alarm."
    },
    "NotificationSNSTopicArn": {
      "Type": "String",
      "Default": "",
      "Description": "SNS Topic ARN where CloudWatch Alarm Notifications would be sent. Optional."
    },
    "VPC": {
      "Type": "AWS::EC2::VPC::Id",
      "Description": "The VPC in which Neptune Stream Instance is present"
    },
    "SubnetIds": {
      "Type": "String",
      "Description": "The subnets to which a network interface is established. Add subnets associated with both Neptune Stream Cluster & Neptune target Cluster."
    },
    "SecurityGroupIds": {
      "Type": "String",
      "ConstraintDescription": "Must be a security group ID (for example, sg-a123fd85)."
    },
    "RouteTableIds": {
      "Type": "String",
      "Default": "",
      "Description": "Comma Delimited list of Route table ids associated with the Subnets. For Example: rtb-a12345,rtba7863k1. Optional parameter - Only needed when creating DynamoDB VPC Endpoint."
    },
    "CreateDDBVPCEndPoint": {
      "Type": "String",
      "Default": "true",
      "AllowedValues": [
        "true",
        "false"
      ],
      "ConstraintDescription": "Must be a either true or false",
      "Description": "Flag used to determine whether to create Dynamo DB VPC Endpoint or not. Select false only if Dynamo DB VPC endpoint already present."
    },
    "CreateMonitoringEndPoint": {
      "Type": "String",
      "Default": "true",
      "AllowedValues": [
        "true",
        "false"
      ],
      "ConstraintDescription": "Must be a either true or false",
      "Description": "Flag used to determine whether to create Monitoring VPC Endpoint or not. Select false only if Monitoring VPC endpoint already present."
    },
    "CreateCloudWatchAlarm": {
      "Type": "String",
      "Default": "false",
      "AllowedValues": [
        "true",
        "false"
      ],
      "ConstraintDescription": "Must be a either true or false",
      "Description": "Flag used to determine whether to create Cloud watch alarm or not."
    },
    "StreamPollerInitialState": {
      "Type": "String",
      "Default": "ENABLED",
      "AllowedValues": [
        "DISABLED",
        "ENABLED"
      ],
      "ConstraintDescription": "Must be a either DISABLED or ENABLED",
      "Description": "Initial state of poller." 
    },
    "StartingCheckpoint": {
      "Type": "String",
      "Default": "0:0",
      "Description": "Starting checkpoint for stream poller."
    }
  },
  "Resources": {
    "NeptuneStreamCommonStack": {
      "Type": "AWS::CloudFormation::Stack",
      "Properties": {
        "Parameters": {
          "ApplicationName": {
            "Ref": "ApplicationName"
          },
          "CreateDDBVPCEndPoint": {
            "Ref": "CreateDDBVPCEndPoint"
          },
          "CreateMonitoringEndPoint": {
            "Ref": "CreateMonitoringEndPoint"
          },
          "RouteTableIds": {
            "Ref": "RouteTableIds"
          },
          "SubnetIds": {
            "Ref": "SubnetIds"
          },
          "VPC": {
            "Ref": "VPC"
          }
        },
        "TemplateURL": "https://s3.amazonaws.com/aws-neptune-customer-samples/neptune-stream/neptune_stream_poller_common_stack.json"
      }
    },
    "NeptuneStreamPollerLambdaStack": {
      "Type": "AWS::CloudFormation::Stack",
      "Properties": {
        "Parameters": {
          "ApplicationName": {
            "Ref": "ApplicationName"
          },
          "LambdaS3Bucket": {
            "Ref": "LambdaS3Bucket"
          },
          "LambdaS3Key": {
            "Ref": "LambdaS3Key"
          },
          "LambdaLoggingLevel": {
            "Ref": "LambdaLoggingLevel"
          },
          "AdditionalParams": {
            "Ref": "AdditionalParams"
          },
          "ManagedPolicies": {
            "Fn::Join": [
              ",",
              {
                "Ref": "ManagedPolicies"
              }
            ]
          },
          "StreamRecordsHandler": {
            "Ref": "StreamRecordsHandler"
          },
          "LeaseDynamoDBTable": {
            "Fn::GetAtt": [
              "NeptuneStreamCommonStack",
              "Outputs.LeaseDynamoDBTable"
            ]
          },
          "LambdaMemorySize": {
            "Ref": "LambdaMemorySize"
          },
          "LambdaRuntime": {
            "Ref": "LambdaRuntime"
          },
          "MaxPollingInterval": {
            "Ref": "MaxPollingInterval"
          },
          "StreamRecordsBatchSize": {
            "Ref": "StreamRecordsBatchSize"
          },
          "NeptuneStreamEndpoint": {
            "Ref": "NeptuneStreamEndpoint"
          },
          "IAMAuthEnabledOnSourceStream": {
            "Ref": "IAMAuthEnabledOnSourceStream"
          },
          "StreamDBClusterResourceId": {
            "Ref": "StreamDBClusterResourceId"
          },
          "MaxPollingWaitTime": {
            "Ref": "MaxPollingWaitTime"
          },
          "SecurityGroupIds": {
            "Ref": "SecurityGroupIds"
          },
          "SubnetIds": {
            "Ref": "SubnetIds"
          },
          "HTTPSAccessSG": {
            "Fn::GetAtt": [
              "NeptuneStreamCommonStack",
              "Outputs.HTTPSAccessSG"
            ]
          },
          "StartingCheckpoint" : {
            "Ref" : "StartingCheckpoint" 
          } 
        },
        "TemplateURL": "https://s3.amazonaws.com/aws-neptune-customer-samples/neptune-stream/neptune_stream_poller_lambda_stack.json"
      },
      "DependsOn": [
        "NeptuneStreamCommonStack"
      ]
    },
    "NeptuneStreamSchedulerStack": {
      "Type": "AWS::CloudFormation::Stack",
      "Properties": {
        "Parameters": {
          "ApplicationName": {
            "Ref": "ApplicationName"
          },
          "StepFunctionFallbackPeriod": {
            "Ref": "StepFunctionFallbackPeriod"
          },
          "StepFunctionFallbackPeriodUnit": {
            "Ref": "StepFunctionFallbackPeriodUnit"
          },
          "MaxPollingInterval": {
            "Ref": "MaxPollingInterval"
          },
          "NotificationEmail": {
            "Ref": "NotificationEmail"
          },
          "NotificationSNSTopicArn": {
            "Ref": "NotificationSNSTopicArn"
          },
          "CreateCloudWatchAlarm": {
            "Ref": "CreateCloudWatchAlarm"
          },
          "NeptuneStreamPollerLambdaArn": {
            "Fn::GetAtt": [
              "NeptuneStreamPollerLambdaStack",
              "Outputs.NeptuneStreamPollerLambdaArn"
            ]
          },
          "RestartStateMachineExecutionLambdaArn": {
            "Fn::GetAtt": [
              "NeptuneStreamPollerLambdaStack",
              "Outputs.RestartStateMachineExecutionLambdaArn"
            ]
          },
          "CheckForDuplicateExecutionLambdaArn": {
            "Fn::GetAtt": [
              "NeptuneStreamPollerLambdaStack",
              "Outputs.CheckForDuplicateExecutionLambdaArn"
            ]
          }, 
          "StreamPollerInitialState":{
	     "Ref" : "StreamPollerInitialState"
          }
        },
        "TemplateURL": "https://s3.amazonaws.com/aws-neptune-customer-samples/neptune-stream/neptune_stream_scheduler_stack.json"
      },
      "DependsOn": [
        "NeptuneStreamPollerLambdaStack"
      ]
    },
    "NeptuneStreamDashboardStack": {
      "Type": "AWS::CloudFormation::Stack",
      "Properties": {
        "Parameters": {
          "ApplicationName": {
            "Ref": "ApplicationName"
          },
          "LeaseDynamoDBTable": {
            "Fn::GetAtt": [
              "NeptuneStreamCommonStack",
              "Outputs.LeaseDynamoDBTable"
            ]
          },
          "NeptuneStreamEndpoint": {
            "Ref": "NeptuneStreamEndpoint"
          },
          "StateMachineArn": {
            "Fn::GetAtt": [
              "NeptuneStreamSchedulerStack",
              "Outputs.StateMachineArn"
            ]
          },
          "NeptuneStreamPollerLambdaName": {
            "Fn::GetAtt": [
              "NeptuneStreamPollerLambdaStack",
              "Outputs.NeptuneStreamPollerLambdaName"
            ]
          }
        },
        "TemplateURL": "https://s3.amazonaws.com/aws-neptune-customer-samples/neptune-stream/neptune_stream_dashboard_stack.json"
      },
      "DependsOn": [
        "NeptuneStreamSchedulerStack"
      ]

    }
  },
  "Outputs": {
    "HTTPSAccessSG": {
      "Description": "HTTPS Access Security Group Arn",
      "Value": {
        "Fn::GetAtt": [
          "NeptuneStreamCommonStack",
          "Outputs.HTTPSAccessSG"
        ]
      }
    },
    "LeaseDynamoDBTable": {
      "Description": "Neptune Stream Poller Lease Table",
      "Value": {
        "Fn::GetAtt": [
          "NeptuneStreamCommonStack",
          "Outputs.LeaseDynamoDBTable"
        ]
      }
    },
    "StateMachineArn": {
      "Description": "Neptune Stream Poller State Machine Arn",
      "Value": {
        "Fn::GetAtt": [
          "NeptuneStreamSchedulerStack",
          "Outputs.StateMachineArn"
        ]
      }
    },
    "CronArn": {
      "Description": "Neptune Stream Poller Scheduler Cron Arn",
      "Value": {
        "Fn::GetAtt": [
          "NeptuneStreamSchedulerStack",
          "Outputs.CronArn"
        ]
      }
    },
    "StateMachineAlarmArn": {
      "Description": "Neptune Stream Poller State Machine Alarm Arn",
      "Value": {
        "Fn::GetAtt": [
          "NeptuneStreamSchedulerStack",
          "Outputs.StateMachineAlarmArn"
        ]
      }
    },
    "NeptuneStreamPollerLambdaArn": {
      "Description": "Neptune Stream Poller Lambda Arn",
      "Value": {
        "Fn::GetAtt": [
          "NeptuneStreamPollerLambdaStack",
          "Outputs.NeptuneStreamPollerLambdaArn"
        ]
      }
    },
    "CloudWatchMetricsDashboardURI": {
      "Description": "CloudWatch Metics Dashboard URI",
      "Value": {
        "Fn::GetAtt": [
          "NeptuneStreamDashboardStack",
          "Outputs.CloudWatchMetricsDashboardURI"
        ]
      }
    }
  }
}
