{
  "StartAt": "SetupWorkflow",
  "States": {
    "SetupWorkflow": {
      "Type": "Pass",
      "Parameters": {
        "note": "State machine workflow setup",
        "start_time.$": "$$.Execution.StartTime",
        "execution_id.$": "$$.Execution.Id",
        "execution_name.$": "$$.Execution.Name",
        "slack_channel": "#{appsETLNotificationSlackChannel}",
        "unit_of_work_id.$": "$.unit_of_work_id",
        "last_attempt.$": "$.last_attempt",
        "send_slack_notification": false,
        "uow": {
          "completeness_status.$": "$.next_completeness_status",
          "activity_status": "NOT_IN_PROGRESS"
        },
        "errors": {}
      },
      "ResultPath": "$.info",
      "Next": "WaitForDBTransactionCommited"
    },
    "WaitForDBTransactionCommited": {
      "Type": "Wait",
      "Seconds": 10,
      "Next": "StartDatabricks"
    },
    "StartDatabricks": {
      "Type": "Task",
      "Resource":"arn:aws:states:::lambda:invoke.waitForTaskToken",
      "Parameters":{
         "FunctionName":"#{appsETLDatabricksStarter_arn}",
         "Payload":{
           "start": {
              "dsp.$": "$.dsp",
              "report_date.$": "$.report_date",
              "conversion_params.$": "$.conversion_params",
              "unit_of_work_id.$": "$.unit_of_work_id",
              "sf_token.$":"$$.Task.Token",
              "sf_execution_name.$": "$.info.execution_name",
              "licensor_ids.$": "$.licensor_ids",
              "content_status_ids.$": "$.content_status_ids",
              "dbx_job_id.$": "$.databricks_job_id",
              "dbx_spark_params.$": "$.databricks_spark_params",
              "dbx_job_max_lifetime.$": "$.databricks_job_max_lifetime"
           }
         }
      },
      "TimeoutSecondsPath": "$.databricks_job_max_lifetime",
      "HeartbeatSeconds": 600,
      "ResultPath": "$.results.databricks.start",
      "Catch": [
        {
          "ErrorEquals": [ "States.Timeout" ],
          "ResultPath": "$.info.errors.datarbricks.start",
          "Next": "CancelExpiredDBXJob"
        },
        {
          "ErrorEquals": [ "States.ALL" ],
          "ResultPath": "$.info.errors.datarbricks.start",
          "Next": "DBXJobFailed"
        }
      ],
      "Next": "WaitForDatabricksState"
    },
    "CancelExpiredDBXJob": {
      "Type": "Task",
      "Resource": "#{appsETLDatabricksStarter_arn}",
      "Parameters": {
        "cancel": {
          "sf_execution_name.$": "$.info.execution_name"
        }
      },
      "ResultPath": "$.results.databricks.cancel",
      "Next": "DBXJobFailed",
      "Catch": [{
        "ErrorEquals": ["States.ALL"],
        "Next": "DBXJobFailed",
        "ResultPath": "$.info.errors.datarbricks.sync"
      }]
    },
    "DBXJobFailed": {
      "Type": "Pass",
      "Result": true,
      "ResultPath": "$.info.send_slack_notification",
      "Next": "UoWStatusFailed"
    },
    "UoWStatusFailed": {
      "Type": "Pass",
      "Result": "FAILED",
      "ResultPath": "$.info.uow.completeness_status",
      "Next": "CheckDBXJobCancelled"
    },
    "CheckDBXJobCancelled": {
      "Type": "Choice",
      "Choices": [
        {
          "And": [
            {
              "Variable": "$.results.databricks.cancel.cancel",
              "IsPresent": true
            },
            {
              "Variable": "$.results.databricks.cancel.cancel.is_cancelled",
              "BooleanEquals": true
            }
          ],
          "Next": "SyncUoWStatus"
        }
      ],
      "Default": "WaitForDatabricksState"
    },
    "WaitForDatabricksState": {
      "Type": "Wait",
      "Seconds": 60,
      "Next": "SyncDatabricksState"
    },
    "SyncDatabricksState": {
      "Type": "Task",
      "Resource": "#{appsETLDatabricksStarter_arn}",
      "Parameters": {
        "sync": {
          "sf_execution_name.$": "$.info.execution_name",
          "conversion_params.$": "$.conversion_params"
        }
      },
      "ResultPath": "$.results.databricks.sync",
      "Next": "SyncUoWStatus",
      "Catch": [{
        "ErrorEquals": ["States.ALL"],
        "Next": "SyncDatabricksFailed",
        "ResultPath": "$.info.errors.datarbricks.sync"
      }]
    },
    "SyncDatabricksFailed": {
      "Type": "Pass",
      "Result": "FAILED",
      "ResultPath": "$.info.uow.completeness_status",
      "Next": "SyncUoWStatus"
    },
    "SyncUoWStatus": {
      "Type": "Task",
      "Resource": "#{appsETLSetUoWStatus_arn}",
      "Parameters": {
        "execution_id.$": "$.info.execution_id",
        "unit_of_work_id.$": "$.info.unit_of_work_id",
        "values.$": "$.info.uow",
        "error.$": "$.info.errors"
      },
      "ResultPath": "$.results.uow",
      "Next": "CheckIfNeedSendSlaskNotification",
      "Catch": [
        {
          "ErrorEquals": [ "States.ALL" ],
          "Next": "FailureSlackNotify"
        }
      ],
      "Retry": [
        {
          "ErrorEquals": ["States.TaskFailed"],
          "IntervalSeconds": 3,
          "MaxAttempts": 3,
          "BackoffRate": 2
        }
      ]
    },
    "CheckIfNeedSendSlaskNotification": {
      "Type": "Choice",
      "Choices": [
        {
          "Variable": "$.info.send_slack_notification",
          "BooleanEquals": true,
          "Next": "FailureSlackNotify"
        }
      ],
      "Default": "JobSucceed"
    },
    "FailureSlackNotify": {
      "Type": "Task",
      "Resource": "#{slackNotify_arn}",
      "Parameters": {
        "channel.$": "$.info.slack_channel",
        "message.$": "$.info"
      },
      "Catch": [
        {
          "ErrorEquals": [ "States.ALL" ],
          "ResultPath": "$.info.error",
          "Next": "JobFail"
        }
      ],
      "Retry": [
        {
          "ErrorEquals": ["States.TaskFailed"],
          "IntervalSeconds": 3,
          "MaxAttempts": 3,
          "BackoffRate": 2
        }
      ],
      "Next": "CheckMaxFailureCount",
      "ResultPath": "$.result"
    },
    "CheckMaxFailureCount": {
      "Type": "Choice",
      "Choices": [
        {
          "Variable": "$.info.last_attempt",
          "BooleanEquals": true,
          "Next": "SlackNotificationAboutMaxFailureCount"
        }
      ],
      "Default": "JobFail"
    },
    "SlackNotificationAboutMaxFailureCount": {
      "Type": "Task",
      "Resource": "#{slackNotify_arn}",
      "Parameters": {
        "channel.$": "$.info.slack_channel",
        "message": {
          "message": "Max failure count is reached",
          "unit_of_work_id.$": "$.info.unit_of_work_id"
        }
      },
      "Catch": [
        {
          "ErrorEquals": [ "States.ALL" ],
          "ResultPath": "$.info.error",
          "Next": "JobFail"
        }
      ],
      "Retry": [
        {
          "ErrorEquals": ["States.TaskFailed"],
          "IntervalSeconds": 3,
          "MaxAttempts": 3,
          "BackoffRate": 2
        }
      ],
      "Next": "JobFail"
    },
    "JobFail": {
      "Type": "Fail",
      "Cause": "UoW execution failed"
    },
    "JobSucceed": {
      "Type": "Succeed"
    }
  }
}
