async-durable-execution-runner 2.0.0a1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- LICENSE +175 -0
- NOTICE +8 -0
- VERSION.py +5 -0
- async_durable_execution_runner/__about__.py +33 -0
- async_durable_execution_runner/__init__.py +23 -0
- async_durable_execution_runner/checkpoint/__init__.py +1 -0
- async_durable_execution_runner/checkpoint/processor.py +101 -0
- async_durable_execution_runner/checkpoint/processors/__init__.py +1 -0
- async_durable_execution_runner/checkpoint/processors/base.py +199 -0
- async_durable_execution_runner/checkpoint/processors/callback.py +89 -0
- async_durable_execution_runner/checkpoint/processors/context.py +59 -0
- async_durable_execution_runner/checkpoint/processors/execution.py +52 -0
- async_durable_execution_runner/checkpoint/processors/step.py +124 -0
- async_durable_execution_runner/checkpoint/processors/wait.py +95 -0
- async_durable_execution_runner/checkpoint/transformer.py +104 -0
- async_durable_execution_runner/checkpoint/validators/__init__.py +1 -0
- async_durable_execution_runner/checkpoint/validators/checkpoint.py +242 -0
- async_durable_execution_runner/checkpoint/validators/operations/__init__.py +1 -0
- async_durable_execution_runner/checkpoint/validators/operations/callback.py +45 -0
- async_durable_execution_runner/checkpoint/validators/operations/context.py +73 -0
- async_durable_execution_runner/checkpoint/validators/operations/execution.py +47 -0
- async_durable_execution_runner/checkpoint/validators/operations/invoke.py +56 -0
- async_durable_execution_runner/checkpoint/validators/operations/step.py +106 -0
- async_durable_execution_runner/checkpoint/validators/operations/wait.py +54 -0
- async_durable_execution_runner/checkpoint/validators/transitions.py +66 -0
- async_durable_execution_runner/cli.py +498 -0
- async_durable_execution_runner/client.py +50 -0
- async_durable_execution_runner/exceptions.py +288 -0
- async_durable_execution_runner/execution.py +444 -0
- async_durable_execution_runner/executor.py +1234 -0
- async_durable_execution_runner/invoker.py +340 -0
- async_durable_execution_runner/model.py +3296 -0
- async_durable_execution_runner/observer.py +144 -0
- async_durable_execution_runner/py.typed +1 -0
- async_durable_execution_runner/runner.py +1167 -0
- async_durable_execution_runner/scheduler.py +246 -0
- async_durable_execution_runner/stores/__init__.py +1 -0
- async_durable_execution_runner/stores/base.py +147 -0
- async_durable_execution_runner/stores/filesystem.py +79 -0
- async_durable_execution_runner/stores/memory.py +38 -0
- async_durable_execution_runner/stores/sqlite.py +273 -0
- async_durable_execution_runner/token.py +49 -0
- async_durable_execution_runner/web/__init__.py +1 -0
- async_durable_execution_runner/web/errors.py +8 -0
- async_durable_execution_runner/web/handlers.py +813 -0
- async_durable_execution_runner/web/models.py +266 -0
- async_durable_execution_runner/web/routes.py +692 -0
- async_durable_execution_runner/web/serialization.py +235 -0
- async_durable_execution_runner/web/server.py +243 -0
- async_durable_execution_runner-2.0.0a1.dist-info/METADATA +238 -0
- async_durable_execution_runner-2.0.0a1.dist-info/RECORD +55 -0
- async_durable_execution_runner-2.0.0a1.dist-info/WHEEL +4 -0
- async_durable_execution_runner-2.0.0a1.dist-info/entry_points.txt +2 -0
- async_durable_execution_runner-2.0.0a1.dist-info/licenses/LICENSE +175 -0
- async_durable_execution_runner-2.0.0a1.dist-info/licenses/NOTICE +1 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"""Callback operation validator."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from async_durable_execution.lambda_service import (
|
|
6
|
+
Operation,
|
|
7
|
+
OperationAction,
|
|
8
|
+
OperationStatus,
|
|
9
|
+
OperationUpdate,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
from async_durable_execution_runner.exceptions import (
|
|
13
|
+
InvalidParameterValueException,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
VALID_ACTIONS_FOR_CALLBACK = frozenset(
|
|
18
|
+
[
|
|
19
|
+
OperationAction.START,
|
|
20
|
+
]
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class CallbackOperationValidator:
|
|
25
|
+
"""Validates CALLBACK operation transitions."""
|
|
26
|
+
|
|
27
|
+
_ALLOWED_STATUS_TO_CANCEL = frozenset(
|
|
28
|
+
[
|
|
29
|
+
OperationStatus.STARTED,
|
|
30
|
+
]
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
@staticmethod
|
|
34
|
+
def validate(current_state: Operation | None, update: OperationUpdate) -> None:
|
|
35
|
+
"""Validate CALLBACK operation update."""
|
|
36
|
+
match update.action:
|
|
37
|
+
case OperationAction.START:
|
|
38
|
+
if current_state is not None:
|
|
39
|
+
msg_callback_exists: str = (
|
|
40
|
+
"Cannot start a CALLBACK that already exist."
|
|
41
|
+
)
|
|
42
|
+
raise InvalidParameterValueException(msg_callback_exists)
|
|
43
|
+
case _:
|
|
44
|
+
msg: str = "Invalid action for CALLBACK operation."
|
|
45
|
+
raise InvalidParameterValueException(msg)
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"""Context operation validator."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from async_durable_execution.lambda_service import (
|
|
6
|
+
Operation,
|
|
7
|
+
OperationAction,
|
|
8
|
+
OperationStatus,
|
|
9
|
+
OperationUpdate,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
from async_durable_execution_runner.exceptions import (
|
|
13
|
+
InvalidParameterValueException,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
VALID_ACTIONS_FOR_CONTEXT = frozenset(
|
|
18
|
+
[
|
|
19
|
+
OperationAction.START,
|
|
20
|
+
OperationAction.FAIL,
|
|
21
|
+
OperationAction.SUCCEED,
|
|
22
|
+
]
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class ContextOperationValidator:
|
|
27
|
+
"""Validates CONTEXT operation transitions."""
|
|
28
|
+
|
|
29
|
+
_ALLOWED_STATUS_TO_CLOSE = frozenset(
|
|
30
|
+
[
|
|
31
|
+
OperationStatus.STARTED,
|
|
32
|
+
]
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
@staticmethod
|
|
36
|
+
def validate(current_state: Operation | None, update: OperationUpdate) -> None:
|
|
37
|
+
"""Validate CONTEXT operation update."""
|
|
38
|
+
match update.action:
|
|
39
|
+
case OperationAction.START:
|
|
40
|
+
if current_state is not None:
|
|
41
|
+
msg_context_exists: str = (
|
|
42
|
+
"Cannot start a CONTEXT that already exist."
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
raise InvalidParameterValueException(msg_context_exists)
|
|
46
|
+
case OperationAction.FAIL | OperationAction.SUCCEED:
|
|
47
|
+
if (
|
|
48
|
+
current_state is not None
|
|
49
|
+
and current_state.status
|
|
50
|
+
not in ContextOperationValidator._ALLOWED_STATUS_TO_CLOSE
|
|
51
|
+
):
|
|
52
|
+
msg_context_close: str = "Invalid current CONTEXT state to close."
|
|
53
|
+
|
|
54
|
+
raise InvalidParameterValueException(msg_context_close)
|
|
55
|
+
if update.action == OperationAction.FAIL and update.payload is not None:
|
|
56
|
+
msg_context_fail_payload: str = (
|
|
57
|
+
"Cannot provide a Payload for FAIL action."
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
raise InvalidParameterValueException(msg_context_fail_payload)
|
|
61
|
+
if (
|
|
62
|
+
update.action == OperationAction.SUCCEED
|
|
63
|
+
and update.error is not None
|
|
64
|
+
):
|
|
65
|
+
msg_context_succeed_error: str = (
|
|
66
|
+
"Cannot provide an Error for SUCCEED action."
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
raise InvalidParameterValueException(msg_context_succeed_error)
|
|
70
|
+
case _:
|
|
71
|
+
msg_context_invalid: str = "Invalid CONTEXT action."
|
|
72
|
+
|
|
73
|
+
raise InvalidParameterValueException(msg_context_invalid)
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"""Execution operation validator."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from async_durable_execution.lambda_service import (
|
|
6
|
+
OperationAction,
|
|
7
|
+
OperationUpdate,
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
from async_durable_execution_runner.exceptions import (
|
|
11
|
+
InvalidParameterValueException,
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
VALID_ACTIONS_FOR_EXECUTION = frozenset(
|
|
16
|
+
[
|
|
17
|
+
OperationAction.SUCCEED,
|
|
18
|
+
OperationAction.FAIL,
|
|
19
|
+
]
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class ExecutionOperationValidator:
|
|
24
|
+
"""Validates EXECUTION operation transitions."""
|
|
25
|
+
|
|
26
|
+
@staticmethod
|
|
27
|
+
def validate(update: OperationUpdate) -> None:
|
|
28
|
+
"""Validate EXECUTION operation update."""
|
|
29
|
+
match update.action:
|
|
30
|
+
case OperationAction.SUCCEED:
|
|
31
|
+
if update.error is not None:
|
|
32
|
+
msg_exec_succeed_error: str = (
|
|
33
|
+
"Cannot provide an Error for SUCCEED action."
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
raise InvalidParameterValueException(msg_exec_succeed_error)
|
|
37
|
+
case OperationAction.FAIL:
|
|
38
|
+
if update.payload is not None:
|
|
39
|
+
msg_exec_fail_payload: str = (
|
|
40
|
+
"Cannot provide a Payload for FAIL action."
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
raise InvalidParameterValueException(msg_exec_fail_payload)
|
|
44
|
+
case _:
|
|
45
|
+
msg_exec_invalid: str = "Invalid EXECUTION action."
|
|
46
|
+
|
|
47
|
+
raise InvalidParameterValueException(msg_exec_invalid)
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"""Invoke operation validator."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from async_durable_execution.lambda_service import (
|
|
6
|
+
Operation,
|
|
7
|
+
OperationAction,
|
|
8
|
+
OperationStatus,
|
|
9
|
+
OperationUpdate,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
from async_durable_execution_runner.exceptions import (
|
|
13
|
+
InvalidParameterValueException,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
VALID_ACTIONS_FOR_INVOKE = frozenset(
|
|
18
|
+
[
|
|
19
|
+
OperationAction.START,
|
|
20
|
+
OperationAction.CANCEL,
|
|
21
|
+
]
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class ChainedInvokeOperationValidator:
|
|
26
|
+
"""Validates INVOKE operation transitions."""
|
|
27
|
+
|
|
28
|
+
_ALLOWED_STATUS_TO_CANCEL = frozenset(
|
|
29
|
+
[
|
|
30
|
+
OperationStatus.STARTED,
|
|
31
|
+
]
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
@staticmethod
|
|
35
|
+
def validate(current_state: Operation | None, update: OperationUpdate) -> None:
|
|
36
|
+
"""Validate INVOKE operation update."""
|
|
37
|
+
match update.action:
|
|
38
|
+
case OperationAction.START:
|
|
39
|
+
if current_state is not None:
|
|
40
|
+
msg_invoke_exists: str = (
|
|
41
|
+
"Cannot start an INVOKE that already exist."
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
raise InvalidParameterValueException(msg_invoke_exists)
|
|
45
|
+
case OperationAction.CANCEL:
|
|
46
|
+
if (
|
|
47
|
+
current_state is None
|
|
48
|
+
or current_state.status
|
|
49
|
+
not in ChainedInvokeOperationValidator._ALLOWED_STATUS_TO_CANCEL
|
|
50
|
+
):
|
|
51
|
+
msg_invoke_cancel: str = "Cannot cancel an INVOKE that does not exist or has already completed."
|
|
52
|
+
raise InvalidParameterValueException(msg_invoke_cancel)
|
|
53
|
+
case _:
|
|
54
|
+
msg_invoke_invalid: str = "Invalid INVOKE action."
|
|
55
|
+
|
|
56
|
+
raise InvalidParameterValueException(msg_invoke_invalid)
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"""Step operation validator."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from async_durable_execution.lambda_service import (
|
|
6
|
+
Operation,
|
|
7
|
+
OperationAction,
|
|
8
|
+
OperationStatus,
|
|
9
|
+
OperationUpdate,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
from async_durable_execution_runner.exceptions import (
|
|
13
|
+
InvalidParameterValueException,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
VALID_ACTIONS_FOR_STEP = frozenset(
|
|
18
|
+
[
|
|
19
|
+
OperationAction.START,
|
|
20
|
+
OperationAction.FAIL,
|
|
21
|
+
OperationAction.RETRY,
|
|
22
|
+
OperationAction.SUCCEED,
|
|
23
|
+
]
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class StepOperationValidator:
|
|
28
|
+
"""Validates STEP operation transitions."""
|
|
29
|
+
|
|
30
|
+
_ALLOWED_STATUS_TO_CLOSE = frozenset(
|
|
31
|
+
[
|
|
32
|
+
OperationStatus.STARTED,
|
|
33
|
+
OperationStatus.READY,
|
|
34
|
+
]
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
_ALLOWED_STATUS_TO_START = frozenset(
|
|
38
|
+
[
|
|
39
|
+
OperationStatus.READY,
|
|
40
|
+
]
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
_ALLOWED_STATUS_TO_REATTEMPT = frozenset(
|
|
44
|
+
[
|
|
45
|
+
OperationStatus.STARTED,
|
|
46
|
+
OperationStatus.READY,
|
|
47
|
+
]
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
@staticmethod
|
|
51
|
+
def validate(current_state: Operation | None, update: OperationUpdate) -> None:
|
|
52
|
+
"""Validate STEP operation update."""
|
|
53
|
+
if current_state is None:
|
|
54
|
+
return
|
|
55
|
+
|
|
56
|
+
match update.action:
|
|
57
|
+
case OperationAction.START:
|
|
58
|
+
if (
|
|
59
|
+
current_state.status
|
|
60
|
+
not in StepOperationValidator._ALLOWED_STATUS_TO_START
|
|
61
|
+
):
|
|
62
|
+
msg_step_start: str = "Invalid current STEP state to start."
|
|
63
|
+
|
|
64
|
+
raise InvalidParameterValueException(msg_step_start)
|
|
65
|
+
case OperationAction.FAIL | OperationAction.SUCCEED:
|
|
66
|
+
if (
|
|
67
|
+
current_state.status
|
|
68
|
+
not in StepOperationValidator._ALLOWED_STATUS_TO_CLOSE
|
|
69
|
+
):
|
|
70
|
+
msg_step_close: str = "Invalid current STEP state to close."
|
|
71
|
+
|
|
72
|
+
raise InvalidParameterValueException(msg_step_close)
|
|
73
|
+
if update.action == OperationAction.FAIL and update.payload is not None:
|
|
74
|
+
msg_fail_payload: str = "Cannot provide a Payload for FAIL action."
|
|
75
|
+
|
|
76
|
+
raise InvalidParameterValueException(msg_fail_payload)
|
|
77
|
+
if (
|
|
78
|
+
update.action == OperationAction.SUCCEED
|
|
79
|
+
and update.error is not None
|
|
80
|
+
):
|
|
81
|
+
msg_succeed_error: str = (
|
|
82
|
+
"Cannot provide an Error for SUCCEED action."
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
raise InvalidParameterValueException(msg_succeed_error)
|
|
86
|
+
case OperationAction.RETRY:
|
|
87
|
+
if (
|
|
88
|
+
current_state.status
|
|
89
|
+
not in StepOperationValidator._ALLOWED_STATUS_TO_REATTEMPT
|
|
90
|
+
):
|
|
91
|
+
msg_step_retry: str = "Invalid current STEP state to re-attempt."
|
|
92
|
+
|
|
93
|
+
raise InvalidParameterValueException(msg_step_retry)
|
|
94
|
+
if update.step_options is None:
|
|
95
|
+
msg_step_options: str = "Invalid StepOptions for the given action."
|
|
96
|
+
|
|
97
|
+
raise InvalidParameterValueException(msg_step_options)
|
|
98
|
+
if update.error is not None and update.payload is not None:
|
|
99
|
+
msg_retry_both: str = (
|
|
100
|
+
"Cannot provide both error and payload to RETRY a STEP."
|
|
101
|
+
)
|
|
102
|
+
raise InvalidParameterValueException(msg_retry_both)
|
|
103
|
+
case _:
|
|
104
|
+
msg_step_invalid: str = "Invalid STEP action."
|
|
105
|
+
|
|
106
|
+
raise InvalidParameterValueException(msg_step_invalid)
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"""Wait operation validator."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from async_durable_execution.lambda_service import (
|
|
6
|
+
Operation,
|
|
7
|
+
OperationAction,
|
|
8
|
+
OperationStatus,
|
|
9
|
+
OperationUpdate,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
from async_durable_execution_runner.exceptions import (
|
|
13
|
+
InvalidParameterValueException,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
VALID_ACTIONS_FOR_WAIT = frozenset(
|
|
18
|
+
[
|
|
19
|
+
OperationAction.START,
|
|
20
|
+
OperationAction.CANCEL,
|
|
21
|
+
]
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class WaitOperationValidator:
|
|
26
|
+
"""Validates WAIT operation transitions."""
|
|
27
|
+
|
|
28
|
+
_ALLOWED_STATUS_TO_CANCEL = frozenset(
|
|
29
|
+
[
|
|
30
|
+
OperationStatus.STARTED,
|
|
31
|
+
]
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
@staticmethod
|
|
35
|
+
def validate(current_state: Operation | None, update: OperationUpdate) -> None:
|
|
36
|
+
"""Validate WAIT operation update."""
|
|
37
|
+
match update.action:
|
|
38
|
+
case OperationAction.START:
|
|
39
|
+
if current_state is not None:
|
|
40
|
+
msg_wait_exists: str = "Cannot start a WAIT that already exist."
|
|
41
|
+
|
|
42
|
+
raise InvalidParameterValueException(msg_wait_exists)
|
|
43
|
+
case OperationAction.CANCEL:
|
|
44
|
+
if (
|
|
45
|
+
current_state is None
|
|
46
|
+
or current_state.status
|
|
47
|
+
not in WaitOperationValidator._ALLOWED_STATUS_TO_CANCEL
|
|
48
|
+
):
|
|
49
|
+
msg_wait_cancel: str = "Cannot cancel a WAIT that does not exist or has already completed."
|
|
50
|
+
raise InvalidParameterValueException(msg_wait_cancel)
|
|
51
|
+
case _:
|
|
52
|
+
msg_wait_invalid: str = "Invalid WAIT action."
|
|
53
|
+
|
|
54
|
+
raise InvalidParameterValueException(msg_wait_invalid)
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"""Validator for valid actions by operation type."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import ClassVar
|
|
6
|
+
|
|
7
|
+
from async_durable_execution.lambda_service import (
|
|
8
|
+
OperationAction,
|
|
9
|
+
OperationType,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
from async_durable_execution_runner.checkpoint.validators.operations.callback import (
|
|
13
|
+
VALID_ACTIONS_FOR_CALLBACK,
|
|
14
|
+
)
|
|
15
|
+
from async_durable_execution_runner.checkpoint.validators.operations.context import (
|
|
16
|
+
VALID_ACTIONS_FOR_CONTEXT,
|
|
17
|
+
)
|
|
18
|
+
from async_durable_execution_runner.checkpoint.validators.operations.execution import (
|
|
19
|
+
VALID_ACTIONS_FOR_EXECUTION,
|
|
20
|
+
)
|
|
21
|
+
from async_durable_execution_runner.checkpoint.validators.operations.invoke import (
|
|
22
|
+
VALID_ACTIONS_FOR_INVOKE,
|
|
23
|
+
)
|
|
24
|
+
from async_durable_execution_runner.checkpoint.validators.operations.step import (
|
|
25
|
+
VALID_ACTIONS_FOR_STEP,
|
|
26
|
+
)
|
|
27
|
+
from async_durable_execution_runner.checkpoint.validators.operations.wait import (
|
|
28
|
+
VALID_ACTIONS_FOR_WAIT,
|
|
29
|
+
)
|
|
30
|
+
from async_durable_execution_runner.exceptions import (
|
|
31
|
+
InvalidParameterValueException,
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class ValidActionsByOperationTypeValidator:
|
|
36
|
+
"""Validates that the given action is valid for the given operation type."""
|
|
37
|
+
|
|
38
|
+
_VALID_ACTIONS_BY_OPERATION_TYPE: ClassVar[
|
|
39
|
+
dict[OperationType, frozenset[OperationAction]]
|
|
40
|
+
] = {
|
|
41
|
+
OperationType.STEP: VALID_ACTIONS_FOR_STEP,
|
|
42
|
+
OperationType.CONTEXT: VALID_ACTIONS_FOR_CONTEXT,
|
|
43
|
+
OperationType.WAIT: VALID_ACTIONS_FOR_WAIT,
|
|
44
|
+
OperationType.CALLBACK: VALID_ACTIONS_FOR_CALLBACK,
|
|
45
|
+
OperationType.CHAINED_INVOKE: VALID_ACTIONS_FOR_INVOKE,
|
|
46
|
+
OperationType.EXECUTION: VALID_ACTIONS_FOR_EXECUTION,
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
@staticmethod
|
|
50
|
+
def validate(operation_type: OperationType, action: OperationAction) -> None:
|
|
51
|
+
"""Validate that the action is valid for the operation type."""
|
|
52
|
+
valid_actions = (
|
|
53
|
+
ValidActionsByOperationTypeValidator._VALID_ACTIONS_BY_OPERATION_TYPE.get(
|
|
54
|
+
operation_type
|
|
55
|
+
)
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
if valid_actions is None:
|
|
59
|
+
msg_unknown_op: str = "Unknown operation type."
|
|
60
|
+
|
|
61
|
+
raise InvalidParameterValueException(msg_unknown_op)
|
|
62
|
+
|
|
63
|
+
if action not in valid_actions:
|
|
64
|
+
msg_invalid_action: str = "Invalid action for the given operation type."
|
|
65
|
+
|
|
66
|
+
raise InvalidParameterValueException(msg_invalid_action)
|