{
    "Comment": "Bulk Session Ingest Queue 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": 3,
                    "Comment": "Retry 3 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": 3,
                    "Comment": "Retry 3 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": {
                "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": "FailureBulkState"
        },
        "ProcessBulkProducts": {
            "Type": "Map",
            "Label": "Map",
            "ResultPath": null,
            "Next": "SuccessBulkState",
            "MaxConcurrency": 25,
            "ToleratedFailurePercentage": 100,
            "ItemReader": {
                "ReaderConfig": {
                    "InputType": "JSON"
                },
                "Resource": "arn:aws:states:::s3:getObject",
                "Parameters": {
                    "Bucket.$": "$.bucket",
                    "Key.$": "$.key"
                }
            },
            "ItemSelector": {
                "bulk_session_id.$": "$.bulk_session_id",
                "bulk_session_ingestion_id.$": "$.bulk_session_ingestion_id",
                "identity_uuid.$": "$.identity_uuid",
                "execution_arn.$": "$.execution_arn",
                "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": "SetParticipants",
                "States": {
                    "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": 3,
                                "Comment": "Retry 3 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": 3,
                                "Comment": "Retry 3 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": 3,
                                "Comment": "Retry 3 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": 3,
                                "Comment": "Retry 3 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": 3,
                                "Comment": "Retry 3 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": 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": "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": "HandleProductFailure",
                                "ResultPath": "$.exception"
                            }
                        ],
                        "Next": "EnqueueCopyArtwork"
                    },
                    "EnqueueCopyArtwork": {
                        "Type": "Task",
                        "Resource": "${enqueue_copy_artwork_lambda_arn}",
                        "Next": "ProcessTrackAssets",
                        "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"
                            }
                        ],
                        "Catch": [
                            {
                                "ErrorEquals": [
                                    "States.ALL"
                                ],
                                "Next": "HandleProductFailure",
                                "ResultPath": "$.exception"
                            }
                        ]
                    },
                    "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",
                                            "ingestion_status.$": "$.ingestion_status",
                                            "send_notifications.$": "$.send_notifications",
                                            "correlation_id.$": "$.correlation_id",
                                            "product_info.$": "$.product_info",
                                            "track": {
                                                "tuid.$": "$$.Map.Item.Value.tuid",
                                                "asset.$": "$$.Map.Item.Value.asset"
                                            }
                                        },
                                        "Iterator": {
                                            "StartAt": "EnqueueCopyAudio",
                                            "States": {
                                                "EnqueueCopyAudio": {
                                                    "Type": "Task",
                                                    "Resource": "${enqueue_copy_audio_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"
                                                        }
                                                    ],
                                                    "End": true
                                                }
                                            }
                                        },
                                        "End": true
                                    }
                                }
                            }
                        ],
                        "Next": "SuccessState",
                        "Catch": [
                            {
                                "ErrorEquals": [
                                    "States.ALL"
                                ],
                                "Next": "HandleProductFailure",
                                "ResultPath": "$.exception",
                                "Comment": "Track asset processing failed"
                            }
                        ]
                    },
                    "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": 7,
                                "Comment": "Retry 7 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.$": "$.result.identity_uuid",
                            "assets_required.$": "$.result.assets_required",
                            "submit_products.$": "$.result.submit_products",
                            "send_notifications.$": "$.result.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)"
                    }
                }
            }
        },
        "SuccessBulkState": {
            "Type": "Succeed"
        },
        "FailureBulkState": {
            "Type": "Fail"
        }
    }
}
