{
  "Comment": "Handles parsing a bulk assets ingestion document and ingesting assets listed in it into the Orchard",
  "StartAt": "DetectEventShape",
  "States": {
    "DetectEventShape": {
      "Type": "Choice",
      "Choices": [
        {
          "Variable": "$['detail-type']",
          "StringEquals": "Object Created",
          "Next": "CheckForSentinelFile"
        },
        {
          "Variable": "$['detail-type']",
          "StringEquals": "AWS API Call via CloudTrail",
          "Next": "NormalizeEventStyle"
        }
      ],
      "Default": "SentinelFailState"
    },
    "NormalizeEventStyle": {
      "Type": "Pass",
      "Parameters": {
        "source.$": "$.source",
        "detail-type.$": "$['detail-type']",
        "correlation_id.$": "$.correlation_id",
        "detail": {
          "bucket": {
            "name.$": "$.detail.requestParameters.bucketName"
          },
          "object": {
            "key.$": "$.detail.requestParameters.key"
          }
        }
      },
      "ResultPath": "$",
      "Next": "CheckForSentinelFile"
    },
    "CheckForSentinelFile": {
      "Type": "Choice",
      "Choices": [
        {
          "Variable": "$.detail.object.key",
          "StringMatches": "*/${filename_pattern}",
          "Next": "ParseBulkAssetsData"
        }
      ],
      "Default": "SentinelFailState"
    },
    "ParseBulkAssetsData": {
      "Type": "Task",
      "Resource": "${lambda_parse_bulk_assets_arn}",
      "Parameters": {
        "bucket.$": "$.detail.bucket.name",
        "key.$": "$.detail.object.key",
        "correlation_id.$": "$.correlation_id",
        "execution_name.$": "$$.Execution.Name",
        "state_machine_name.$": "$$.StateMachine.Name",
        "execution_start_time.$": "$$.Execution.StartTime"
      },
      "HeartbeatSeconds": 60,
      "TimeoutSeconds": 3600,
      "Retry": [
        {
          "ErrorEquals": [
            "States.Timeout"
          ],
          "IntervalSeconds": 60,
          "MaxAttempts": 5,
          "BackoffRate": 2.0
        }
      ],
      "Catch": [
        {
          "ErrorEquals": [
            "States.ALL"
          ],
          "Next": "CatchParseErrors",
          "ResultPath": "$.errors"
        }
      ],
      "Next": "ProcessAssets"
    },
    "ProcessAssets": {
      "Type": "Map",
      "InputPath": "$",
      "ItemsPath": "$.items",
      "Parameters": {
        "execution_name.$": "$.execution_name",
        "state_machine_name.$": "$.state_machine_name",
        "correlation_id.$": "$.correlation_id",
        "key.$": "$.key",
        "bucket.$": "$.bucket",
        "item_index.$": "$$.Map.Item.Value"
      },
      "MaxConcurrency": 2,
      "Iterator": {
        "StartAt": "LookupOrchardProduct",
        "States": {
          "LookupOrchardProduct": {
            "Type": "Task",
            "Resource": "${lambda_lookup_orchard_product_arn}",
            "HeartbeatSeconds": 60,
            "TimeoutSeconds": 3600,
            "Retry": [
              {
                "ErrorEquals": [
                  "States.Timeout",
                  "Lambda.ServiceException",
                  "Lambda.AWSLambdaException",
                  "Lambda.SdkClientException",
                  "Lambda.TooManyRequestsException"
                ],
                "IntervalSeconds": 5,
                "MaxAttempts": 5,
                "BackoffRate": 3.0
              },
              {
                "ErrorEquals": [
                  "GraphQLError"
                ],
                "IntervalSeconds": 60,
                "MaxAttempts": 3,
                "BackoffRate": 5
              }
            ],
            "Catch": [
              {
                "ErrorEquals": [
                  "States.ALL"
                ],
                "Next": "CatchIngestionErrors",
                "ResultPath": "$.errors"
              }
            ],
            "Next": "ChoiceAsset"
          },
          "ChoiceAsset": {
            "Type": "Choice",
            "Choices": [
              {
                "Variable": "$.asset_type",
                "StringEquals": "cover",
                "Next": "PreProcessImage"
              },
              {
                "Variable": "$.asset_type",
                "StringEquals": "audio",
                "Next": "PreProcessAudio"
              }
            ],
            "Default": "BadAssetType"
          },
          "BadAssetType": {
            "Type": "Pass",
            "Result": {
              "Cause": "Bad Asset Type.",
              "Error": "BadAssetType"
            },
            "ResultPath": "$.errors",
            "Next": "CatchIngestionErrors"
          },
          "PreProcessImage": {
            "Type": "Task",
            "Resource": "${lambda_pre_process_art_arn}",
            "HeartbeatSeconds": 60,
            "TimeoutSeconds": 3600,
            "Retry": [
              {
                "ErrorEquals": [
                  "States.Timeout",
                  "Lambda.ServiceException",
                  "Lambda.AWSLambdaException",
                  "Lambda.SdkClientException",
                  "Lambda.TooManyRequestsException"
                ],
                "IntervalSeconds": 5,
                "MaxAttempts": 5,
                "BackoffRate": 3.0
              }
            ],
            "Catch": [
              {
                "ErrorEquals": [
                  "States.ALL"
                ],
                "Next": "CatchIngestionErrors",
                "ResultPath": "$.errors"
              }
            ],
            "Next": "HandleArtwork"
          },
          "HandleArtwork": {
            "Type": "Task",
            "Resource": "${lambda_handle_artwork_arn}",
            "HeartbeatSeconds": 60,
            "TimeoutSeconds": 3600,
            "Retry": [
              {
                "ErrorEquals": [
                  "States.Timeout",
                  "Lambda.ServiceException",
                  "Lambda.AWSLambdaException",
                  "Lambda.SdkClientException",
                  "Lambda.TooManyRequestsException"
                ],
                "IntervalSeconds": 5,
                "MaxAttempts": 5,
                "BackoffRate": 3
              },
              {
                "ErrorEquals": [
                  "GraphQLError"
                ],
                "IntervalSeconds": 60,
                "MaxAttempts": 3,
                "BackoffRate": 5
              }
            ],
            "Catch": [
              {
                "ErrorEquals": [
                  "States.ALL"
                ],
                "Next": "CatchIngestionErrors",
                "ResultPath": "$.errors"
              }
            ],
            "Next": "PollArtworkAssetStatus"
          },
          "PollArtworkAssetStatus": {
            "Type": "Task",
            "Resource": "${lambda_poll_artwork_asset_status_arn}",
            "HeartbeatSeconds": 60,
            "TimeoutSeconds": 3600,
            "Retry": [
              {
                "ErrorEquals": [
                  "ArtworkException"
                ],
                "IntervalSeconds": 30,
                "MaxAttempts": 15,
                "BackoffRate": 1
              },
              {
                "ErrorEquals": [
                  "GraphQLError"
                ],
                "IntervalSeconds": 60,
                "MaxAttempts": 3,
                "BackoffRate": 5
              },
              {
                "ErrorEquals": [
                  "States.Timeout",
                  "Lambda.ServiceException",
                  "Lambda.AWSLambdaException",
                  "Lambda.SdkClientException",
                  "Lambda.TooManyRequestsException"
                ],
                "IntervalSeconds": 5,
                "MaxAttempts": 5,
                "BackoffRate": 3
              }
            ],
            "Catch": [
              {
                "ErrorEquals": [
                  "States.ALL"
                ],
                "Next": "CatchIngestionErrors",
                "ResultPath": "$.errors"
              }
            ],
            "End": true
          },
          "PreProcessAudio": {
            "Type": "Task",
            "Resource": "${lambda_pre_process_audio_arn}",
            "HeartbeatSeconds": 60,
            "TimeoutSeconds": 3600,
            "Retry": [
              {
                "ErrorEquals": [
                  "States.Timeout",
                  "Lambda.ServiceException",
                  "Lambda.AWSLambdaException",
                  "Lambda.SdkClientException",
                  "Lambda.TooManyRequestsException"
                ],
                "IntervalSeconds": 5,
                "MaxAttempts": 5,
                "BackoffRate": 3.0
              }
            ],
            "Catch": [
              {
                "ErrorEquals": [
                  "States.ALL"
                ],
                "Next": "CatchIngestionErrors",
                "ResultPath": "$.errors"
              }
            ],
            "Next": "HandleAudio"
          },
          "HandleAudio": {
            "Type": "Task",
            "Resource": "${lambda_handle_audio_arn}",
            "HeartbeatSeconds": 60,
            "TimeoutSeconds": 3600,
            "Retry": [
              {
                "ErrorEquals": [
                  "States.Timeout",
                  "Lambda.ServiceException",
                  "Lambda.AWSLambdaException",
                  "Lambda.SdkClientException",
                  "Lambda.TooManyRequestsException"
                ],
                "IntervalSeconds": 5,
                "MaxAttempts": 5,
                "BackoffRate": 3
              },
              {
                "ErrorEquals": [
                  "GraphQLError"
                ],
                "IntervalSeconds": 60,
                "MaxAttempts": 3,
                "BackoffRate": 5
              }
            ],
            "Catch": [
              {
                "ErrorEquals": [
                  "States.ALL"
                ],
                "Next": "CatchIngestionErrors",
                "ResultPath": "$.errors"
              }
            ],
            "Next": "PollAudioAssetStatus"
          },
          "PollAudioAssetStatus": {
            "Type": "Task",
            "Resource": "${lambda_poll_audio_asset_status_arn}",
            "HeartbeatSeconds": 60,
            "TimeoutSeconds": 3600,
            "Retry": [
              {
                "ErrorEquals": [
                  "AudioException"
                ],
                "IntervalSeconds": 30,
                "MaxAttempts": 30,
                "BackoffRate": 1
              },
              {
                "ErrorEquals": [
                  "GraphQLError"
                ],
                "IntervalSeconds": 60,
                "MaxAttempts": 3,
                "BackoffRate": 5
              },
              {
                "ErrorEquals": [
                  "States.Timeout",
                  "Lambda.ServiceException",
                  "Lambda.AWSLambdaException",
                  "Lambda.SdkClientException",
                  "Lambda.TooManyRequestsException"
                ],
                "IntervalSeconds": 5,
                "MaxAttempts": 5,
                "BackoffRate": 3
              }
            ],
            "Catch": [
              {
                "ErrorEquals": [
                  "States.ALL"
                ],
                "Next": "CatchIngestionErrors",
                "ResultPath": "$.errors"
              }
            ],
            "End": true
          },
          "CatchIngestionErrors": {
            "Type": "Task",
            "Resource": "${lambda_log_asset_error_arn}",
            "HeartbeatSeconds": 60,
            "TimeoutSeconds": 3600,
            "Retry": [
              {
                "ErrorEquals": [
                  "States.Timeout",
                  "Lambda.ServiceException",
                  "Lambda.AWSLambdaException",
                  "Lambda.SdkClientException",
                  "Lambda.TooManyRequestsException"
                ],
                "IntervalSeconds": 5,
                "MaxAttempts": 5,
                "BackoffRate": 3.0
              }
            ],
            "Catch": [
              {
                "ErrorEquals": [
                  "States.ALL"
                ],
                "Next": "CatchLoggerErrors",
                "ResultPath": "$.errors"
              }
            ],
            "End": true
          },
          "CatchLoggerErrors": {
            "Type": "Succeed"
          }
        }
      },
      "End": true
    },
    "SentinelFailState": {
      "Type": "Pass",
      "Result": {
        "Cause": "Parser Failed.",
        "Error": "ParserError"
      },
      "ResultPath": "$.errors",
      "Next": "CatchParseErrors"
    },
    "CatchParseErrors": {
      "Type": "Task",
      "Resource": "${lambda_log_asset_error_arn}",
      "HeartbeatSeconds": 60,
      "TimeoutSeconds": 3600,
      "Retry": [
        {
          "ErrorEquals": [
            "States.Timeout",
            "Lambda.ServiceException",
            "Lambda.AWSLambdaException",
            "Lambda.SdkClientException",
            "Lambda.TooManyRequestsException"
          ],
          "IntervalSeconds": 5,
          "MaxAttempts": 5,
          "BackoffRate": 3.0
        }
      ],
      "Catch": [
        {
          "ErrorEquals": [
            "States.ALL"
          ],
          "Next": "CatchParseLoggerErrors",
          "ResultPath": "$.errors"
        }
      ],
      "End": true
    },
    "CatchParseLoggerErrors": {
      "Type": "Succeed"
    }
  }
}
