Add checks for *DecisionAttributes within RespondDecisionTaskCompleted
This commit is contained in:
parent
507351612e
commit
558b84fb6a
6 changed files with 169 additions and 7 deletions
|
|
@ -2,6 +2,8 @@ from __future__ import unicode_literals
|
|||
from datetime import datetime
|
||||
from time import mktime
|
||||
|
||||
from ..utils import decapitalize
|
||||
|
||||
|
||||
class HistoryEvent(object):
|
||||
def __init__(self, event_id, event_type, **kwargs):
|
||||
|
|
@ -23,8 +25,7 @@ class HistoryEvent(object):
|
|||
|
||||
def _attributes_key(self):
|
||||
key = "{}EventAttributes".format(self.event_type)
|
||||
key = key[0].lower() + key[1:]
|
||||
return key
|
||||
return decapitalize(key)
|
||||
|
||||
def event_attributes(self):
|
||||
if self.event_type == "WorkflowExecutionStarted":
|
||||
|
|
|
|||
|
|
@ -3,11 +3,15 @@ import uuid
|
|||
|
||||
from moto.core.utils import camelcase_to_underscores
|
||||
|
||||
from ..constants import (
|
||||
DECISIONS_FIELDS,
|
||||
)
|
||||
from ..exceptions import (
|
||||
SWFDefaultUndefinedFault,
|
||||
SWFValidationException,
|
||||
SWFDecisionValidationException,
|
||||
)
|
||||
from ..utils import decapitalize
|
||||
from .decision_task import DecisionTask
|
||||
from .history_event import HistoryEvent
|
||||
|
||||
|
|
@ -189,6 +193,19 @@ class WorkflowExecution(object):
|
|||
dt.complete()
|
||||
self.handle_decisions(evt.event_id, decisions)
|
||||
|
||||
def _check_decision_attributes(self, kind, value, decision_id):
|
||||
problems = []
|
||||
constraints = DECISIONS_FIELDS.get(kind, {})
|
||||
for key, constraint in constraints.iteritems():
|
||||
if constraint["required"] and not value.get(key):
|
||||
problems.append({
|
||||
"type": "null_value",
|
||||
"where": "decisions.{}.member.{}.{}".format(
|
||||
decision_id, kind, key
|
||||
)
|
||||
})
|
||||
return problems
|
||||
|
||||
def validate_decisions(self, decisions):
|
||||
"""
|
||||
Performs some basic validations on decisions. The real SWF service
|
||||
|
|
@ -202,7 +219,7 @@ class WorkflowExecution(object):
|
|||
problems = []
|
||||
|
||||
# check close decision is last
|
||||
# TODO: see what happens on real SWF service if we ask for 2 close decisions
|
||||
# (the real SWF service also works that way if you provide 2 close decision tasks)
|
||||
for dcs in decisions[:-1]:
|
||||
close_decision_types = [
|
||||
"CompleteWorkflowExecution",
|
||||
|
|
@ -217,7 +234,16 @@ class WorkflowExecution(object):
|
|||
decision_number = 0
|
||||
for dcs in decisions:
|
||||
decision_number += 1
|
||||
# TODO: check decision types mandatory attributes
|
||||
# check decision types mandatory attributes
|
||||
# NB: the real SWF service seems to check attributes even for attributes list
|
||||
# that are not in line with the decisionType, so we do the same
|
||||
attrs_to_check = filter(lambda x: x.endswith("DecisionAttributes"), dcs.keys())
|
||||
if dcs["decisionType"] in self.KNOWN_DECISION_TYPES:
|
||||
decision_type = dcs["decisionType"]
|
||||
decision_attr = "{}DecisionAttributes".format(decapitalize(decision_type))
|
||||
attrs_to_check.append(decision_attr)
|
||||
for attr in attrs_to_check:
|
||||
problems += self._check_decision_attributes(attr, dcs.get(attr, {}), decision_number)
|
||||
# check decision type is correct
|
||||
if dcs["decisionType"] not in self.KNOWN_DECISION_TYPES:
|
||||
problems.append({
|
||||
|
|
@ -243,9 +269,7 @@ class WorkflowExecution(object):
|
|||
# handle each decision separately, in order
|
||||
for decision in decisions:
|
||||
decision_type = decision["decisionType"]
|
||||
attributes_key = "{}{}EventAttributes".format(
|
||||
decision_type[0].lower(), decision_type[1:]
|
||||
)
|
||||
attributes_key = "{}EventAttributes".format(decapitalize(decision_type))
|
||||
attributes = decision.get(attributes_key, {})
|
||||
if decision_type == "CompleteWorkflowExecution":
|
||||
self.complete(event_id, attributes.get("result"))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue