Add SWF endpoint RespondActivityTaskCompleted

This commit is contained in:
Jean-Baptiste Barth 2015-10-27 05:17:33 +01:00
commit c9e8ad03f8
6 changed files with 172 additions and 17 deletions

View file

@ -298,6 +298,49 @@ class SWFBackend(BaseBackend):
count += len(pending)
return count
def respond_activity_task_completed(self, task_token, result=None):
self._check_string(task_token)
self._check_none_or_string(result)
# let's find the activity task
activity_task = None
for domain in self.domains:
for _, wfe in domain.workflow_executions.iteritems():
for task in wfe.activity_tasks:
if task.task_token == task_token:
activity_task = task
# no task found
if not activity_task:
# Same as for decision tasks, we raise an invalid token BOTH for clearly
# wrong SWF tokens and OK tokens but not used correctly. This should not
# be a problem in moto.
raise SWFValidationException("Invalid token")
# activity task found, but WorflowExecution is CLOSED
wfe = activity_task.workflow_execution
if wfe.execution_status != "OPEN":
raise SWFUnknownResourceFault(
"execution",
"WorkflowExecution=[workflowId={}, runId={}]".format(
wfe.workflow_id, wfe.run_id
)
)
# activity task found, but already completed
if activity_task.state != "STARTED":
if activity_task.state == "COMPLETED":
raise SWFUnknownResourceFault(
"activity, scheduledEventId = {}".format(activity_task.scheduled_event_id)
)
else:
raise ValueError(
"This shouldn't happen: you have to PollForActivityTask to get a token, "
"which changes ActivityTask status to 'STARTED' ; then it can only change "
"to 'COMPLETED'. If you didn't hack moto/swf internals, this is probably "
"a bug in moto, please report it, thanks!"
)
# everything's good
if activity_task:
wfe = activity_task.workflow_execution
wfe.complete_activity_task(activity_task.task_token, result=result)
swf_backends = {}
for region in boto.swf.regions():

View file

@ -113,6 +113,14 @@ class HistoryEvent(object):
if hasattr(self, "identity") and self.identity:
hsh["identity"] = self.identity
return hsh
elif self.event_type == "ActivityTaskCompleted":
hsh = {
"scheduledEventId": self.scheduled_event_id,
"startedEventId": self.started_event_id,
}
if hasattr(self, "result") and self.result is not None:
hsh["result"] = self.result
return hsh
else:
raise NotImplementedError(
"HistoryEvent does not implement attributes for type '{}'".format(self.event_type)

View file

@ -430,3 +430,16 @@ class WorkflowExecution(object):
identity=identity
)
task.start(evt.event_id)
def complete_activity_task(self, task_token, result=None):
task = self._find_activity_task(task_token)
evt = self._add_event(
"ActivityTaskCompleted",
scheduled_event_id=task.scheduled_event_id,
started_event_id=task.started_event_id,
result=result,
)
task.complete()
self.open_counts["openActivityTasks"] -= 1
# TODO: ensure we don't schedule multiple decisions at the same time!
self.schedule_decision_task()

View file

@ -270,3 +270,11 @@ class SWFResponse(BaseResponse):
task_list = self._params["taskList"]["name"]
count = self.swf_backend.count_pending_activity_tasks(domain_name, task_list)
return json.dumps({"count": count, "truncated": False})
def respond_activity_task_completed(self):
task_token = self._params["taskToken"]
result = self._params.get("result")
self.swf_backend.respond_activity_task_completed(
task_token, result=result
)
return ""