{
  "Comment": "Product metadata indexing.",
  "StartAt": "Process Current Indexing Op",
  "States": {
    "Process Current Indexing Op": {
      "Type": "Map",
      "InputPath": "$.data",
      "ItemsPath": "$.indexing_inputs",
      "ResultSelector": {
        "Results.$": "$",
        "Failures.$": "$[*].TaskResponse.Error"
      },
      "ResultPath": "$.ExecutionResult",
      "OutputPath": "$.ExecutionResult",
      "ItemProcessor": {
        "StartAt": "Get Operation",
        "States": {
          "Get Operation": {
            "Type": "Choice",
            "Choices": [
              {
                "Variable": "$.operation_type",
                "StringMatches": "add_to_index",
                "Next": "Add to Index"
              },
              {
                "Variable": "$.operation_type",
                "StringMatches": "update_index",
                "Next": "Update Index"
              },
              {
                "Variable": "$.operation_type",
                "StringMatches": "deindex",
                "Next": "Remove from Index"
              }
            ],
            "Default": "InvalidOperationType"
          },
          "Add to Index": {
            "Type": "Task",
            "Resource": "arn:aws:states:::lambda:invoke",
            "Parameters": {
              "FunctionName": "${lambda_prefix}-index-add-product",
              "Payload.$": "$"
            },
            "ResultSelector": {
              "ExecutedVersion.$": "$.ExecutedVersion",
              "StatusCode.$": "$.StatusCode",
              "Payload.$": "$.Payload",
              "Error": null
            },
            "ResultPath": "$.TaskResponse",
            "Retry": [
              {
                "ErrorEquals": [
                  "InvalidMessageException",
                  "SoundRecordingsException"
                ],
                "MaxAttempts": 0
              },
              {
                "ErrorEquals": ["States.Timeout", "GatewayTimeoutException"],
                "IntervalSeconds": 5,
                "MaxAttempts": 8,
                "BackoffRate": 2
              },
              {
                "ErrorEquals": ["States.ALL"],
                "IntervalSeconds": 5,
                "MaxAttempts": 5,
                "BackoffRate": 1.5
              }
            ],
            "Catch": [
              {
                "ErrorEquals": ["States.ALL"],
                "ResultPath": "$.TaskResponse",
                "Next": "CatchEndState"
              }
            ],
            "End": true
          },
          "Update Index": {
            "Type": "Task",
            "Resource": "arn:aws:states:::lambda:invoke",
            "Parameters": {
              "FunctionName": "${lambda_prefix}-index-update-product",
              "Payload.$": "$"
            },
            "ResultSelector": {
              "ExecutedVersion.$": "$.ExecutedVersion",
              "StatusCode.$": "$.StatusCode",
              "Payload.$": "$.Payload",
              "Error": null
            },
            "ResultPath": "$.TaskResponse",
            "Retry": [
              {
                "ErrorEquals": ["InvalidMessageException"],
                "MaxAttempts": 0
              },
              {
                "ErrorEquals": ["States.Timeout", "GatewayTimeoutException"],
                "IntervalSeconds": 5,
                "MaxAttempts": 8,
                "BackoffRate": 2
              },
              {
                "ErrorEquals": ["States.ALL"],
                "IntervalSeconds": 5,
                "MaxAttempts": 5,
                "BackoffRate": 1.5
              }
            ],
            "Catch": [
              {
                "ErrorEquals": ["States.ALL"],
                "ResultPath": "$.TaskResponse",
                "Next": "CatchEndState"
              }
            ],
            "End": true
          },
          "Remove from Index": {
            "Type": "Task",
            "Resource": "arn:aws:states:::lambda:invoke",
            "Parameters": {
              "FunctionName": "${lambda_prefix}-deindex-product-metadata",
              "Payload.$": "$"
            },
            "ResultSelector": {
              "ExecutedVersion.$": "$.ExecutedVersion",
              "StatusCode.$": "$.StatusCode",
              "Payload.$": "$.Payload",
              "Error": null
            },
            "ResultPath": "$.TaskResponse",
            "Retry": [
              {
                "ErrorEquals": ["States.ALL"],
                "IntervalSeconds": 1,
                "MaxAttempts": 10,
                "BackoffRate": 1.5
              }
            ],
            "Catch": [
              {
                "ErrorEquals": ["States.ALL"],
                "ResultPath": "$.TaskResponse",
                "Next": "CatchEndState"
              }
            ],
            "End": true
          },
          "InvalidOperationType": {
            "Type": "Pass",
            "Result": {
              "Error": "InvalidOperationType",
              "Cause": "Invalid or non-existent operation_type."
            },
            "ResultPath": "$.TaskResponse",
            "End": true
          },
          "CatchEndState": {
            "Type": "Pass",
            "End": true
          }
        }
      },
      "Next": "Parse Indexing Results"
    },
    "Parse Indexing Results": {
      "Type": "Pass",
      "Parameters": {
        "FunctionOutput.$": "$",
        "Failures.$": "$.Failures",
        "UniqueFailures.$": "States.ArrayUnique($.Failures)",
        "UniqueFailuresArrLength.$": "States.ArrayLength(States.ArrayUnique($.Failures))"
      },
      "Next": "Check for Failures"
    },
    "Check for Failures": {
      "Type": "Choice",
      "Choices": [
        {
          "Or": [
            {
              "Variable": "$.UniqueFailuresArrLength",
              "NumericEquals": 0
            },
            {
              "And": [
                {
                  "Variable": "$.UniqueFailuresArrLength",
                  "NumericEquals": 1
                },
                {
                  "Variable": "$.UniqueFailures[0]",
                  "IsNull": true
                }
              ]
            }
          ],
          "Next": "Prepare to Succeed"
        }
      ],
      "Default": "Prepare to Fail"
    },
    "Prepare to Succeed": {
      "Type": "Pass",
      "Parameters": {
        "Results.$": "$.FunctionOutput.Results"
      },
      "Next": "Succeed"
    },
    "Succeed": {
      "Type": "Succeed"
    },
    "Prepare to Fail": {
      "Type": "Pass",
      "Parameters": {
        "FunctionOutput.$": "States.JsonToString($.FunctionOutput)",
        "Failures.$": "$.Failures"
      },
      "Next": "Fail"
    },
    "Fail": {
      "Type": "Fail",
      "CausePath": "$.FunctionOutput"
    }
  }
}

