{
    "Comment": "Bulk Session Ingest Step Function",
    "StartAt": "BeginExecution",
    "States": {
        "BeginExecution": {
            "Type": "Task",
            "Resource": "${begin_execution_lambda_arn}",
            "Parameters": {
                "execution_arn.$": "$$.Execution.Id",
                "bulk_session_id.$": "$.bulk_session_id",
                "bulk_session_ingestion_id.$": "$.bulk_session_ingestion_id",
                "identity_uuid.$": "$.identity_uuid",
                "assets_required.$": "$.assets_required",
                "submit_products.$": "$.submit_products",
                "send_notifications.$": "$.send_notifications",
                "ingestion_status.$": "$.ingestion_status",
                "correlation_id.$": "$.correlation_id",
                "bucket.$": "$.bucket",
                "key.$": "$.key"
            },
            "Retry": [
                {
                    "ErrorEquals": [
                        "NetworkException",
                        "ReadTimeout",
                        "States.Timeout",
                        "Lambda.ServiceException",
                        "Lambda.AWSLambdaException",
                        "Lambda.SdkClientException",
                        "Lambda.TooManyRequestsException"
                    ],
                    "BackoffRate": 2,
                    "IntervalSeconds": 60,
                    "MaxAttempts": 8,
                    "Comment": "Retry 8 times with a backoff rate of 2"
                },
                {
                    "ErrorEquals": [
                        "States.ALL"
                    ],
                    "BackoffRate": 1,
                    "IntervalSeconds": 300,
                    "MaxAttempts": 1,
                    "Comment": "Retry once on any failure"
                }
            ],
            "Catch": [
                {
                    "ErrorEquals": [
                        "States.ALL"
                    ],
                    "Next": "SetIngestionStatusFailure",
                    "ResultPath": "$.exception",
                    "Comment": "Error after retry"
                }
            ],
            "Next": "PrepareBulkMetadata"
        },
        "PrepareBulkMetadata": {
            "Type": "Task",
            "Resource": "${prepare_metadata_lambda_arn}",
            "Retry": [
                {
                    "ErrorEquals": [
                        "PrepareMetadataException",
                        "NetworkException",
                        "ReadTimeout",
                        "States.Timeout",
                        "Lambda.ServiceException",
                        "Lambda.AWSLambdaException",
                        "Lambda.SdkClientException",
                        "Lambda.TooManyRequestsException"
                    ],
                    "BackoffRate": 2,
                    "IntervalSeconds": 60,
                    "MaxAttempts": 8,
                    "Comment": "Retry 8 times with a backoff rate of 2"
                },
                {
                    "ErrorEquals": [
                        "HydrationException"
                    ],
                    "MaxAttempts": 0,
                    "Comment": "Don't retry"
                },
                {
                    "ErrorEquals": [
                        "States.ALL"
                    ],
                    "BackoffRate": 1,
                    "IntervalSeconds": 300,
                    "MaxAttempts": 1,
                    "Comment": "Retry once on any failure"
                }
            ],
            "Catch": [
                {
                    "ErrorEquals": [
                        "HydrationException"
                    ],
                    "Next": "SetIngestionStatusFailure",
                    "ResultPath": "$.exception",
                    "Comment": "Hydration has failed due to inconsistent data"
                },
                {
                    "ErrorEquals": [
                        "States.ALL"
                    ],
                    "Next": "SetIngestionStatusFailure",
                    "ResultPath": "$.exception",
                    "Comment": "Error after retry"
                }
            ],
            "Next": "ProcessBulkProducts"
        },
        "SetIngestionStatusFailure": {
            "Type": "Pass",
            "Parameters": {
                "execution_arn.$": "$$.Execution.Id",
                "bulk_session_id.$": "$.bulk_session_id",
                "bulk_session_ingestion_id.$": "$.bulk_session_ingestion_id",
                "identity_uuid.$": "$.identity_uuid",
                "assets_required.$": "$.assets_required",
                "submit_products.$": "$.submit_products",
                "send_notifications.$": "$.send_notifications",
                "correlation_id.$": "$.correlation_id",
                "ingestion_status": "failure",
                "bucket.$": "$.bucket",
                "key.$": "$.key",
                "exception.$": "$.exception"
            },
            "Next": "UpdateBulkSession"
        },
        "ProcessBulkProducts": {
            "Type": "Map",
            "Label": "Map",
            "ResultPath": null,
            "Next": "UpdateBulkSession",
            "MaxConcurrency": 25,
            "ToleratedFailurePercentage": 100,
            "ItemReader": {
                "ReaderConfig": {
                    "InputType": "JSON"
                },
                "Resource": "arn:aws:states:::s3:getObject",
                "Parameters": {
                    "Bucket.$": "$.bucket",
                    "Key.$": "$.key"
                }
            },
            "ItemSelector": {
                "execution_arn.$": "$$.Execution.Id",
                "bulk_session_id.$": "$.bulk_session_id",
                "bulk_session_ingestion_id.$": "$.bulk_session_ingestion_id",
                "identity_uuid.$": "$.identity_uuid",
                "assets_required.$": "$.assets_required",
                "submit_products.$": "$.submit_products",
                "send_notifications.$": "$.send_notifications",
                "ingestion_status.$": "$.ingestion_status",
                "correlation_id.$": "$.correlation_id",
                "product_info.$": "$$.Map.Item.Value.product_info"
            },
            "ItemProcessor": {
                "ProcessorConfig": {
                    "Mode": "DISTRIBUTED",
                    "ExecutionType": "STANDARD"
                },
                "StartAt": "CheckProductExists",
                "States": {
                    "CheckProductExists": {
                        "Type": "Task",
                        "Resource": "${check_product_exists_lambda_arn}",
                        "Retry": [
                            {
                                "ErrorEquals": [
                                    "NetworkException",
                                    "ReadTimeout",
                                    "States.Timeout",
                                    "Lambda.ServiceException",
                                    "Lambda.AWSLambdaException",
                                    "Lambda.SdkClientException",
                                    "Lambda.TooManyRequestsException"
                                ],
                                "BackoffRate": 2,
                                "IntervalSeconds": 60,
                                "MaxAttempts": 8,
                                "Comment": "Retry 8 times with a backoff rate of 2"
                            },
                            {
                                "ErrorEquals": [
                                    "ProductAlreadyIngested",
                                    "ProductAlreadyExists"
                                ],
                                "MaxAttempts": 0,
                                "Comment": "Don't retry"
                            },
                            {
                                "ErrorEquals": [
                                    "States.ALL"
                                ],
                                "BackoffRate": 1,
                                "IntervalSeconds": 300,
                                "MaxAttempts": 1,
                                "Comment": "Retry once on any failure"
                            }
                        ],
                        "Catch": [
                            {
                                "ErrorEquals": [
                                    "ProductAlreadyIngested"
                                ],
                                "Next": "SuccessState",
                                "ResultPath": "$.exception",
                                "Comment": "Skip to the end of the product loop"
                            },
                            {
                                "ErrorEquals": [
                                    "ProductAlreadyExists"
                                ],
                                "Next": "HandleProductFailure",
                                "ResultPath": "$.exception",
                                "Comment": "Skip to the end of the product loop"
                            },
                            {
                                "ErrorEquals": [
                                    "States.ALL"
                                ],
                                "Next": "HandleProductFailure",
                                "ResultPath": "$.exception",
                                "Comment": "Error after retry"
                            }
                        ],
                        "Next": "SetParticipants"
                    },
                    "SetParticipants": {
                        "Type": "Task",
                        "Resource": "${set_participants_lambda_arn}",
                        "Retry": [
                            {
                                "ErrorEquals": [
                                    "RetryException",
                                    "NetworkException",
                                    "ReadTimeout",
                                    "States.Timeout",
                                    "Lambda.ServiceException",
                                    "Lambda.AWSLambdaException",
                                    "Lambda.SdkClientException",
                                    "Lambda.TooManyRequestsException"
                                ],
                                "BackoffRate": 2,
                                "IntervalSeconds": 60,
                                "MaxAttempts": 8,
                                "Comment": "Retry 8 times with a backoff rate of 2"
                            },
                            {
                                "ErrorEquals": [
                                    "States.ALL"
                                ],
                                "BackoffRate": 1,
                                "IntervalSeconds": 300,
                                "MaxAttempts": 1,
                                "Comment": "Retry once on any failure"
                            }
                        ],
                        "Catch": [
                            {
                                "ErrorEquals": [
                                    "States.ALL"
                                ],
                                "Next": "HandleProductFailure",
                                "ResultPath": "$.exception",
                                "Comment": "Error after retry"
                            }
                        ],
                        "Next": "SetProject"
                    },
                    "SetProject": {
                        "Type": "Task",
                        "Resource": "${set_project_lambda_arn}",
                        "Retry": [
                            {
                                "ErrorEquals": [
                                    "DuplicateProjectCodeException"
                                ],
                                "BackoffRate": 2,
                                "IntervalSeconds": 60,
                                "MaxAttempts": 2,
                                "Comment": "Race condition when two lambdas try to create the same project"
                            },
                            {
                                "ErrorEquals": [
                                    "NetworkException",
                                    "ReadTimeout",
                                    "States.Timeout",
                                    "Lambda.ServiceException",
                                    "Lambda.AWSLambdaException",
                                    "Lambda.SdkClientException",
                                    "Lambda.TooManyRequestsException"
                                ],
                                "BackoffRate": 2,
                                "IntervalSeconds": 60,
                                "MaxAttempts": 8,
                                "Comment": "Retry 8 times with a backoff rate of 2"
                            },
                            {
                                "ErrorEquals": [
                                    "States.ALL"
                                ],
                                "BackoffRate": 1,
                                "IntervalSeconds": 300,
                                "MaxAttempts": 1,
                                "Comment": "Retry once on any failure"
                            }
                        ],
                        "Catch": [
                            {
                                "ErrorEquals": [
                                    "States.ALL"
                                ],
                                "Next": "HandleProductFailure",
                                "ResultPath": "$.exception",
                                "Comment": "Error after retry"
                            }
                        ],
                        "Next": "SetProduct"
                    },
                    "SetProduct": {
                        "Type": "Task",
                        "Resource": "${set_product_lambda_arn}",
                        "Retry": [
                            {
                                "ErrorEquals": [
                                    "NetworkException",
                                    "ReadTimeout",
                                    "States.Timeout",
                                    "Lambda.ServiceException",
                                    "Lambda.AWSLambdaException",
                                    "Lambda.SdkClientException",
                                    "Lambda.TooManyRequestsException"
                                ],
                                "BackoffRate": 2,
                                "IntervalSeconds": 60,
                                "MaxAttempts": 8,
                                "Comment": "Retry 8 times with a backoff rate of 2"
                            },
                            {
                                "ErrorEquals": [
                                    "CreateProductException"
                                ],
                                "MaxAttempts": 0,
                                "Comment": "Don't retry"
                            },
                            {
                                "ErrorEquals": [
                                    "States.ALL"
                                ],
                                "BackoffRate": 1,
                                "IntervalSeconds": 300,
                                "MaxAttempts": 1,
                                "Comment": "Retry once on any failure"
                            }
                        ],
                        "Catch": [
                            {
                                "ErrorEquals": [
                                    "States.ALL"
                                ],
                                "Next": "HandleProductFailure",
                                "ResultPath": "$.exception",
                                "Comment": "Error after retry"
                            }
                        ],
                        "Next": "SetTracks"
                    },
                    "SetTracks": {
                        "Type": "Task",
                        "Resource": "${set_tracks_lambda_arn}",
                        "Retry": [
                            {
                                "ErrorEquals": [
                                    "NetworkException",
                                    "ReadTimeout",
                                    "States.Timeout",
                                    "Lambda.ServiceException",
                                    "Lambda.AWSLambdaException",
                                    "Lambda.SdkClientException",
                                    "Lambda.TooManyRequestsException"
                                ],
                                "BackoffRate": 2,
                                "IntervalSeconds": 60,
                                "MaxAttempts": 8,
                                "Comment": "Retry 8 times with a backoff rate of 2"
                            },
                            {
                                "ErrorEquals": [
                                    "States.ALL"
                                ],
                                "BackoffRate": 1,
                                "IntervalSeconds": 300,
                                "MaxAttempts": 1,
                                "Comment": "Retry once on any failure"
                            }
                        ],
                        "Catch": [
                            {
                                "ErrorEquals": [
                                    "States.ALL"
                                ],
                                "Next": "HandleProductFailure",
                                "ResultPath": "$.exception",
                                "Comment": "Error after retry"
                            }
                        ],
                        "Next": "SetCarveouts"
                    },
                    "SetCarveouts": {
                        "Type": "Task",
                        "Resource": "${set_carveouts_lambda_arn}",
                        "Retry": [
                            {
                                "ErrorEquals": [
                                    "NetworkException",
                                    "ReadTimeout",
                                    "States.Timeout",
                                    "Lambda.ServiceException",
                                    "Lambda.AWSLambdaException",
                                    "Lambda.SdkClientException",
                                    "Lambda.TooManyRequestsException"
                                ],
                                "BackoffRate": 2,
                                "IntervalSeconds": 60,
                                "MaxAttempts": 8,
                                "Comment": "Retry 8 times with a backoff rate of 2"
                            },
                            {
                                "ErrorEquals": [
                                    "States.ALL"
                                ],
                                "BackoffRate": 1,
                                "IntervalSeconds": 300,
                                "MaxAttempts": 1,
                                "Comment": "Retry once on any failure"
                            }
                        ],
                        "Catch": [
                            {
                                "ErrorEquals": [
                                    "States.ALL"
                                ],
                                "Next": "HandleProductFailure",
                                "ResultPath": "$.exception",
                                "Comment": "Error after retry"
                            }
                        ],
                        "Next": "SetMainReleaseDate"
                    },
                    "SetMainReleaseDate": {
                        "Type": "Task",
                        "Resource": "${set_release_dates_lambda_arn}",
                        "Retry": [
                            {
                                "ErrorEquals": [
                                    "NetworkException",
                                    "ReadTimeout",
                                    "States.Timeout",
                                    "Lambda.ServiceException",
                                    "Lambda.AWSLambdaException",
                                    "Lambda.SdkClientException",
                                    "Lambda.TooManyRequestsException"
                                ],
                                "BackoffRate": 2,
                                "IntervalSeconds": 60,
                                "MaxAttempts": 8,
                                "Comment": "Retry 8 times with a backoff rate of 2"
                            },
                            {
                                "ErrorEquals": [
                                    "InvalidDataException"
                                ],
                                "MaxAttempts": 0,
                                "Comment": "Don't retry"
                            },
                            {
                                "ErrorEquals": [
                                    "States.ALL"
                                ],
                                "BackoffRate": 1,
                                "IntervalSeconds": 300,
                                "MaxAttempts": 1,
                                "Comment": "Retry once on any failure"
                            }
                        ],
                        "Catch": [
                            {
                                "ErrorEquals": [
                                    "States.ALL"
                                ],
                                "Next": "HandleProductFailure",
                                "ResultPath": "$.exception",
                                "Comment": "Error after retry or invalid input"
                            }
                        ],
                        "Next": "HandleMetadataSuccess"
                    },
                    "HandleMetadataSuccess": {
                        "Type": "Task",
                        "Resource": "${handle_metadata_success_lambda_arn}",
                        "Retry": [
                            {
                                "ErrorEquals": [
                                    "NetworkException",
                                    "ReadTimeout",
                                    "States.Timeout",
                                    "Lambda.ServiceException",
                                    "Lambda.AWSLambdaException",
                                    "Lambda.SdkClientException",
                                    "Lambda.TooManyRequestsException"
                                ],
                                "BackoffRate": 2,
                                "IntervalSeconds": 60,
                                "MaxAttempts": 3,
                                "Comment": "Retry 3 times with a backoff rate of 2"
                            },
                            {
                                "ErrorEquals": [
                                    "InvalidDataException"
                                ],
                                "MaxAttempts": 0,
                                "Comment": "Don't retry"
                            },
                            {
                                "ErrorEquals": [
                                    "States.ALL"
                                ],
                                "BackoffRate": 1,
                                "IntervalSeconds": 300,
                                "MaxAttempts": 1,
                                "Comment": "Retry once on any failure"
                            }
                        ],
                        "Catch": [
                            {
                                "ErrorEquals": [
                                    "States.ALL"
                                ],
                                "Next": "CopyArtwork",
                                "ResultPath": "$.exception",
                                "Comment": "Until confirmed working, exceptions pass through to CopyArtwork lambda."
                            }
                        ],
                        "Next": "CopyArtwork"
                    },
                    "CopyArtwork": {
                        "Type": "Task",
                        "Resource": "${copy_asset_lambda_arn}",
                        "Retry": [
                            {
                                "ErrorEquals": [
                                    "NetworkException",
                                    "ReadTimeout",
                                    "States.Timeout",
                                    "Lambda.ServiceException",
                                    "Lambda.AWSLambdaException",
                                    "Lambda.SdkClientException",
                                    "Lambda.TooManyRequestsException"
                                ],
                                "BackoffRate": 2,
                                "IntervalSeconds": 60,
                                "MaxAttempts": 8,
                                "Comment": "Retry 8 times with a backoff rate of 2"
                            },
                            {
                                "ErrorEquals": [
                                    "AssetNotFound"
                                ],
                                "MaxAttempts": 0,
                                "Comment": "Don't retry"
                            },
                            {
                                "ErrorEquals": [
                                    "States.ALL"
                                ],
                                "BackoffRate": 1,
                                "IntervalSeconds": 300,
                                "MaxAttempts": 1,
                                "Comment": "Retry once on any failure"
                            }
                        ],
                        "Catch": [
                            {
                                "ErrorEquals": [
                                    "AssetNotFound"
                                ],
                                "Next": "ProcessTrackAssets",
                                "ResultPath": "$.asset_not_found",
                                "Comment": "Asset was not uploaded"
                            },
                            {
                                "ErrorEquals": [
                                    "States.ALL"
                                ],
                                "Next": "ProcessTrackAssets",
                                "ResultPath": "$.exception",
                                "Comment": "Error after retry"
                            }
                        ],
                        "Next": "PollArtworkStatus"
                    },
                    "PollArtworkStatus": {
                        "Type": "Task",
                        "Resource": "${poll_asset_status_lambda_arn}",
                        "HeartbeatSeconds": 60,
                        "TimeoutSeconds": 3600,
                        "Retry": [
                            {
                                "ErrorEquals": [
                                    "RetryException",
                                    "GraphQLException"
                                ],
                                "IntervalSeconds": 60,
                                "MaxAttempts": 120,
                                "BackoffRate": 1
                            },
                            {
                                "ErrorEquals": [
                                    "NetworkException",
                                    "ReadTimeout",
                                    "States.Timeout",
                                    "Lambda.ServiceException",
                                    "Lambda.AWSLambdaException",
                                    "Lambda.SdkClientException",
                                    "Lambda.TooManyRequestsException"
                                ],
                                "BackoffRate": 2,
                                "IntervalSeconds": 60,
                                "MaxAttempts": 8,
                                "Comment": "Retry 8 times with a backoff rate of 2"
                            },
                            {
                                "ErrorEquals": [
                                    "States.ALL"
                                ],
                                "BackoffRate": 1,
                                "IntervalSeconds": 300,
                                "MaxAttempts": 1,
                                "Comment": "Retry once on any failure"
                            }
                        ],
                        "Catch": [
                            {
                                "ErrorEquals": [
                                    "States.ALL"
                                ],
                                "Next": "ProcessTrackAssets",
                                "ResultPath": "$.exception",
                                "Comment": "Error after retry"
                            }
                        ],
                        "Next": "ProcessTrackAssets"
                    },
                    "ProcessTrackAssets": {
                        "Type": "Parallel",
                        "Branches": [
                            {
                                "StartAt": "PassContextToOutput",
                                "States": {
                                    "PassContextToOutput": {
                                        "Type": "Pass",
                                        "End": true
                                    }
                                }
                            },
                            {
                                "StartAt": "TrackAssetIterator",
                                "States": {
                                    "TrackAssetIterator": {
                                        "Type": "Map",
                                        "MaxConcurrency": 1,
                                        "ItemsPath": "$.product_info.tracks",
                                        "Parameters": {
                                            "bulk_session_id.$": "$.bulk_session_id",
                                            "bulk_session_ingestion_id.$": "$.bulk_session_ingestion_id",
                                            "identity_uuid.$": "$.identity_uuid",
                                            "assets_required.$": "$.assets_required",
                                            "submit_products.$": "$.submit_products",
                                            "send_notifications.$": "$.send_notifications",
                                            "ingestion_status.$": "$.ingestion_status",
                                            "correlation_id.$": "$.correlation_id",
                                            "product_info.$": "$.product_info",
                                            "track": {
                                                "tuid.$": "$$.Map.Item.Value.tuid",
                                                "asset.$": "$$.Map.Item.Value.asset"
                                            }
                                        },
                                        "Iterator": {
                                            "StartAt": "CopyAudioAsset",
                                            "States": {
                                                "CopyAudioAsset": {
                                                    "Type": "Task",
                                                    "Resource": "${copy_asset_lambda_arn}",
                                                    "Retry": [
                                                        {
                                                            "ErrorEquals": [
                                                                "NetworkException",
                                                                "ReadTimeout",
                                                                "States.Timeout",
                                                                "Lambda.ServiceException",
                                                                "Lambda.AWSLambdaException",
                                                                "Lambda.SdkClientException",
                                                                "Lambda.TooManyRequestsException"
                                                            ],
                                                            "BackoffRate": 2,
                                                            "IntervalSeconds": 60,
                                                            "MaxAttempts": 8,
                                                            "Comment": "Retry 8 times with a backoff rate of 2"
                                                        },
                                                        {
                                                            "ErrorEquals": [
                                                                "AssetNotFound"
                                                            ],
                                                            "MaxAttempts": 0,
                                                            "Comment": "Don't retry"
                                                        },
                                                        {
                                                            "ErrorEquals": [
                                                                "States.ALL"
                                                            ],
                                                            "BackoffRate": 1,
                                                            "IntervalSeconds": 300,
                                                            "MaxAttempts": 1,
                                                            "Comment": "Retry once on any failure"
                                                        }
                                                    ],
                                                    "Catch": [
                                                        {
                                                            "ErrorEquals": [
                                                                "AssetNotFound"
                                                            ],
                                                            "Next": "CatchCopyAudioAssetError",
                                                            "Comment": "Asset was not uploaded"
                                                        },
                                                        {
                                                            "ErrorEquals": [
                                                                "States.ALL"
                                                            ],
                                                            "Next": "CatchCopyAudioAssetError",
                                                            "Comment": "Error after retry"
                                                        }
                                                    ],
                                                    "Next": "PollAudioStatus"
                                                },
                                                "PollAudioStatus": {
                                                    "Type": "Task",
                                                    "Resource": "${poll_asset_status_lambda_arn}",
                                                    "HeartbeatSeconds": 60,
                                                    "TimeoutSeconds": 3600,
                                                    "Retry": [
                                                        {
                                                            "ErrorEquals": [
                                                                "RetryException"
                                                            ],
                                                            "IntervalSeconds": 60,
                                                            "MaxAttempts": 120,
                                                            "BackoffRate": 1
                                                        },
                                                        {
                                                            "ErrorEquals": [
                                                                "NetworkException",
                                                                "ReadTimeout",
                                                                "States.Timeout",
                                                                "Lambda.ServiceException",
                                                                "Lambda.AWSLambdaException",
                                                                "Lambda.SdkClientException",
                                                                "Lambda.TooManyRequestsException"
                                                            ],
                                                            "BackoffRate": 2,
                                                            "IntervalSeconds": 60,
                                                            "MaxAttempts": 8,
                                                            "Comment": "Retry 8 times with a backoff rate of 2"
                                                        },
                                                        {
                                                            "ErrorEquals": [
                                                                "ValidationException"
                                                            ],
                                                            "MaxAttempts": 0,
                                                            "Comment": "Validation exceptions are always fatal, don't retry"
                                                        },
                                                        {
                                                            "ErrorEquals": [
                                                                "States.ALL"
                                                            ],
                                                            "BackoffRate": 1,
                                                            "IntervalSeconds": 300,
                                                            "MaxAttempts": 1,
                                                            "Comment": "Retry once on any failure"
                                                        }
                                                    ],
                                                    "Catch": [
                                                        {
                                                            "ErrorEquals": [
                                                                "States.ALL"
                                                            ],
                                                            "Next": "CatchCopyAudioAssetError",
                                                            "Comment": "Error after retry"
                                                        }
                                                    ],
                                                    "OutputPath": "$.track",
                                                    "End": true
                                                },
                                                "CatchCopyAudioAssetError": {
                                                    "Type": "Succeed",
                                                    "OutputPath": null
                                                }
                                            }
                                        },
                                        "End": true
                                    }
                                }
                            }
                        ],
                        "Next": "SelectFirstFromInput"
                    },
                    "SelectFirstFromInput": {
                        "Type": "Pass",
                        "OutputPath": "$[0]",
                        "Next": "SetNFD"
                    },
                    "SetNFD": {
                        "Type": "Task",
                        "Resource": "${set_nfd_lambda_arn}",
                        "Retry": [
                            {
                                "ErrorEquals": [
                                    "NetworkException",
                                    "ReadTimeout",
                                    "States.Timeout",
                                    "Lambda.ServiceException",
                                    "Lambda.AWSLambdaException",
                                    "Lambda.SdkClientException",
                                    "Lambda.TooManyRequestsException"
                                ],
                                "BackoffRate": 2,
                                "IntervalSeconds": 60,
                                "MaxAttempts": 8,
                                "Comment": "Retry 8 times with a backoff rate of 2"
                            },
                            {
                                "ErrorEquals": [
                                    "States.ALL"
                                ],
                                "BackoffRate": 1,
                                "IntervalSeconds": 300,
                                "MaxAttempts": 1,
                                "Comment": "Retry once on any failure"
                            }
                        ],
                        "Catch": [
                            {
                                "ErrorEquals": [
                                    "States.ALL"
                                ],
                                "Next": "HandleProductFailure",
                                "ResultPath": "$.exception",
                                "Comment": "Error after retry"
                            }
                        ],
                        "Next": "CheckSubmitProducts"
                    },
                    "CheckSubmitProducts": {
                        "Type": "Choice",
                        "Choices": [
                            {
                                "Variable": "$.submit_products",
                                "BooleanEquals": true,
                                "Next": "SubmitProduct"
                            }
                        ],
                        "Default": "SuccessState"
                    },
                    "SubmitProduct": {
                        "Type": "Task",
                        "Resource": "${submit_product_lambda_arn}",
                        "Retry": [
                            {
                                "ErrorEquals": [
                                    "RetrySubmitException",
                                    "NetworkException",
                                    "ReadTimeout",
                                    "States.Timeout",
                                    "Lambda.ServiceException",
                                    "Lambda.AWSLambdaException",
                                    "Lambda.SdkClientException",
                                    "Lambda.TooManyRequestsException"
                                ],
                                "BackoffRate": 2,
                                "IntervalSeconds": 60,
                                "MaxAttempts": 8,
                                "Comment": "Retry 8 times with a backoff rate of 2"
                            },
                            {
                                "ErrorEquals": [
                                    "States.ALL"
                                ],
                                "BackoffRate": 1,
                                "IntervalSeconds": 300,
                                "MaxAttempts": 1,
                                "Comment": "Retry once on any failure"
                            }
                        ],
                        "Catch": [
                            {
                                "ErrorEquals": [
                                    "RetrySubmitException"
                                ],
                                "Next": "SuccessState",
                                "ResultPath": "$.exception",
                                "Comment": "Ran out of attempts to retry to submit the product"
                            },
                            {
                                "ErrorEquals": [
                                    "States.ALL"
                                ],
                                "Next": "HandleProductFailure",
                                "ResultPath": "$.exception",
                                "Comment": "Error after retry"
                            }
                        ],
                        "Next": "SuccessState"
                    },
                    "HandleProductFailure": {
                        "Type": "Task",
                        "Resource": "${handle_product_failure_lambda_arn}",
                        "Retry": [
                            {
                                "ErrorEquals": [
                                    "NetworkException",
                                    "ReadTimeout",
                                    "States.Timeout",
                                    "Lambda.ServiceException",
                                    "Lambda.AWSLambdaException",
                                    "Lambda.SdkClientException",
                                    "Lambda.TooManyRequestsException"
                                ],
                                "BackoffRate": 2,
                                "IntervalSeconds": 60,
                                "MaxAttempts": 8,
                                "Comment": "Retry 8 times with a backoff rate of 2. Total time 2 hours"
                            },
                            {
                                "ErrorEquals": [
                                    "HandleProductFailureException"
                                ],
                                "MaxAttempts": 0,
                                "Comment": "Don't retry"
                            },
                            {
                                "ErrorEquals": [
                                    "States.ALL"
                                ],
                                "BackoffRate": 1,
                                "IntervalSeconds": 300,
                                "MaxAttempts": 1,
                                "Comment": "Retry once on any failure"
                            }
                        ],
                        "Catch": [
                            {
                                "ErrorEquals": [
                                    "States.ALL"
                                ],
                                "Next": "FailureState",
                                "ResultPath": "$.exception",
                                "Comment": "Error after retry or invalid input"
                            }
                        ],
                        "ResultPath": "$.result",
                        "Next": "formatProductFailure"
                    },
                    "formatProductFailure": {
                        "Type": "Pass",
                        "Parameters": {
                            "bulk_session_id.$": "$.result.bulk_session_id",
                            "bulk_session_ingestion_id.$": "$.result.bulk_session_ingestion_id",
                            "identity_uuid.$": "$.identity_uuid",
                            "assets_required.$": "$.result.assets_required",
                            "submit_products.$": "$.result.submit_products",
                            "send_notifications.$": "$.send_notifications",
                            "correlation_id.$": "$.result.correlation_id",
                            "product_info.$": "$.result.product_info",
                            "exception.$": "$.exception"
                        },
                        "Next": "FailureState"
                    },
                    "SuccessState": {
                        "Type": "Succeed"
                    },
                    "FailureState": {
                        "Type": "Fail",
                        "ErrorPath": "$.exception.Error",
                        "CausePath": "States.Format('Error: {}, Cause: {}', $.exception.Error, $.exception.Cause)"
                    }
                }
            }
        },
        "UpdateBulkSession": {
            "Type": "Task",
            "Resource": "${update_session_lambda_arn}",
            "Parameters": {
                "execution_arn.$": "$$.Execution.Id",
                "bulk_session_id.$": "$.bulk_session_id",
                "bulk_session_ingestion_id.$": "$.bulk_session_ingestion_id",
                "identity_uuid.$": "$.identity_uuid",
                "assets_required.$": "$.assets_required",
                "submit_products.$": "$.submit_products",
                "send_notifications.$": "$.send_notifications",
                "ingestion_status.$": "$.ingestion_status",
                "correlation_id.$": "$.correlation_id"
            },
            "Retry": [
                {
                    "ErrorEquals": [
                        "NetworkException",
                        "ReadTimeout",
                        "States.Timeout",
                        "Lambda.ServiceException",
                        "Lambda.AWSLambdaException",
                        "Lambda.SdkClientException",
                        "Lambda.TooManyRequestsException"
                    ],
                    "BackoffRate": 2,
                    "IntervalSeconds": 60,
                    "MaxAttempts": 8,
                    "Comment": "Retry 8 times with a backoff rate of 2"
                },
                {
                    "ErrorEquals": [
                        "IngestionException"
                    ],
                    "MaxAttempts": 0,
                    "Comment": "Don't retry"
                },
                {
                    "ErrorEquals": [
                        "States.ALL"
                    ],
                    "BackoffRate": 1,
                    "IntervalSeconds": 300,
                    "MaxAttempts": 1,
                    "Comment": "Retry once on any failure"
                }
            ],
            "Catch": [
                {
                    "ErrorEquals": [
                        "States.ALL"
                    ],
                    "Next": "GenerateFailureReport",
                    "ResultPath": "$.exception",
                    "Comment": "Error after retry"
                }
            ],
            "Next": "CheckIngestionStatus"
        },
        "CheckIngestionStatus": {
            "Type": "Choice",
            "Choices": [
                {
                    "Variable": "$.ingestion_status",
                    "StringEquals": "failure",
                    "Next": "GenerateFailureReport"
                }
            ],
            "Default": "NotifyIngestSuccess"
        },
        "NotifyIngestSuccess": {
            "Type": "Task",
            "Resource": "${notify_ingest_success_lambda_arn}",
            "Retry": [
                {
                    "ErrorEquals": [
                        "NetworkException",
                        "ReadTimeout",
                        "States.Timeout",
                        "Lambda.ServiceException",
                        "Lambda.AWSLambdaException",
                        "Lambda.SdkClientException",
                        "Lambda.TooManyRequestsException"
                    ],
                    "BackoffRate": 2,
                    "IntervalSeconds": 60,
                    "MaxAttempts": 8,
                    "Comment": "Retry 8 times with a backoff rate of 2"
                },
                {
                    "ErrorEquals": [
                        "States.ALL"
                    ],
                    "BackoffRate": 1,
                    "IntervalSeconds": 300,
                    "MaxAttempts": 1,
                    "Comment": "Retry once on any failure"
                }
            ],
            "Catch": [
                {
                    "ErrorEquals": [
                        "States.ALL"
                    ],
                    "Next": "FailureBulkState",
                    "ResultPath": "$.exception",
                    "Comment": "Error after retry"
                }
            ],
            "Next": "SuccessBulkState"
        },
        "GenerateFailureReport": {
            "Type": "Task",
            "Resource": "${generate_failure_report_lambda_arn}",
            "Retry": [
                {
                    "ErrorEquals": [
                        "NetworkException",
                        "ReadTimeout",
                        "States.Timeout",
                        "Lambda.ServiceException",
                        "Lambda.AWSLambdaException",
                        "Lambda.SdkClientException",
                        "Lambda.TooManyRequestsException"
                    ],
                    "BackoffRate": 2,
                    "IntervalSeconds": 60,
                    "MaxAttempts": 8,
                    "Comment": "Retry 8 times with a backoff rate of 2"
                },
                {
                    "ErrorEquals": [
                        "States.ALL"
                    ],
                    "BackoffRate": 1,
                    "IntervalSeconds": 300,
                    "MaxAttempts": 1,
                    "Comment": "Retry once on any failure"
                }
            ],
            "Catch": [
                {
                    "ErrorEquals": [
                        "States.ALL"
                    ],
                    "Next": "NotifyIngestFailure",
                    "ResultPath": "$.exception",
                    "Comment": "Error after retry"
                }
            ],
            "Next": "NotifyIngestFailure"
        },
        "NotifyIngestFailure": {
            "Type": "Task",
            "Resource": "${notify_ingest_failure_lambda_arn}",
            "Retry": [
                {
                    "ErrorEquals": [
                        "NetworkException",
                        "ReadTimeout",
                        "States.Timeout",
                        "Lambda.ServiceException",
                        "Lambda.AWSLambdaException",
                        "Lambda.SdkClientException",
                        "Lambda.TooManyRequestsException"
                    ],
                    "BackoffRate": 2,
                    "IntervalSeconds": 60,
                    "MaxAttempts": 8,
                    "Comment": "Retry 8 times with a backoff rate of 2"
                },
                {
                    "ErrorEquals": [
                        "States.ALL"
                    ],
                    "BackoffRate": 1,
                    "IntervalSeconds": 300,
                    "MaxAttempts": 1,
                    "Comment": "Retry once on any failure"
                }
            ],
            "Catch": [
                {
                    "ErrorEquals": [
                        "States.ALL"
                    ],
                    "Next": "FailureBulkState",
                    "ResultPath": "$.exception",
                    "Comment": "Error after retry"
                }
            ],
            "Next": "FailureBulkState"
        },
        "FailureBulkState": {
            "Type": "Fail",
            "ErrorPath": "$.exception.Error",
            "CausePath": "States.Format('Error: {}, Cause: {}', $.exception.Error, $.exception.Cause)"
        },
        "SuccessBulkState": {
            "Type": "Succeed",
            "Comment": "Bulk session ingestion completed successfully"
        }
    }
}
