Add SWF endpoint: DescribeWorkflowExecution
This commit is contained in:
parent
a589dc08b5
commit
2878252816
@ -84,6 +84,17 @@ class Domain(object):
|
||||
raise SWFWorkflowExecutionAlreadyStartedFault()
|
||||
self.workflow_executions[_id] = workflow_execution
|
||||
|
||||
def get_workflow_execution(self, run_id, workflow_id):
|
||||
wfe = self.workflow_executions.get(workflow_id)
|
||||
if not wfe or wfe.run_id != run_id:
|
||||
raise SWFUnknownResourceFault(
|
||||
"execution",
|
||||
"WorkflowExecution=[workflowId={}, runId={}]".format(
|
||||
workflow_id, run_id
|
||||
)
|
||||
)
|
||||
return wfe
|
||||
|
||||
|
||||
class GenericType(object):
|
||||
def __init__(self, name, version, **kwargs):
|
||||
@ -177,12 +188,68 @@ class WorkflowExecution(object):
|
||||
self.workflow_type = workflow_type
|
||||
self.workflow_id = workflow_id
|
||||
self.run_id = uuid.uuid4().hex
|
||||
self.execution_status = "OPEN"
|
||||
self.cancel_requested = False
|
||||
#config
|
||||
for key, value in kwargs.iteritems():
|
||||
self.__setattr__(key, value)
|
||||
#counters
|
||||
self.open_counts = {
|
||||
"openTimers": 0,
|
||||
"openDecisionTasks": 0,
|
||||
"openActivityTasks": 0,
|
||||
"openChildWorkflowExecutions": 0,
|
||||
}
|
||||
|
||||
def __repr__(self):
|
||||
return "WorkflowExecution(run_id: {})".format(self.run_id)
|
||||
|
||||
@property
|
||||
def _configuration_keys(self):
|
||||
return [
|
||||
"executionStartToCloseTimeout",
|
||||
"childPolicy",
|
||||
"taskPriority",
|
||||
"taskStartToCloseTimeout",
|
||||
]
|
||||
|
||||
def to_short_dict(self):
|
||||
return {
|
||||
"workflowId": self.workflow_id,
|
||||
"runId": self.run_id
|
||||
}
|
||||
|
||||
def to_medium_dict(self):
|
||||
hsh = {
|
||||
"execution": self.to_short_dict(),
|
||||
"workflowType": self.workflow_type.to_short_dict(),
|
||||
"startTimestamp": 1420066800.123,
|
||||
"executionStatus": self.execution_status,
|
||||
"cancelRequested": self.cancel_requested,
|
||||
}
|
||||
if hasattr(self, "tag_list"):
|
||||
hsh["tagList"] = self.tag_list
|
||||
return hsh
|
||||
|
||||
def to_full_dict(self):
|
||||
hsh = {
|
||||
"executionInfo": self.to_medium_dict(),
|
||||
"executionConfiguration": {}
|
||||
}
|
||||
#configuration
|
||||
if hasattr(self, "task_list"):
|
||||
hsh["executionConfiguration"]["taskList"] = {"name": self.task_list}
|
||||
for key in self._configuration_keys:
|
||||
attr = camelcase_to_underscores(key)
|
||||
if not hasattr(self, attr):
|
||||
continue
|
||||
if not getattr(self, attr):
|
||||
continue
|
||||
hsh["executionConfiguration"][key] = getattr(self, attr)
|
||||
#counters
|
||||
hsh["openCounts"] = self.open_counts
|
||||
return hsh
|
||||
|
||||
|
||||
class SWFBackend(BaseBackend):
|
||||
def __init__(self, region_name):
|
||||
@ -318,6 +385,13 @@ class SWFBackend(BaseBackend):
|
||||
|
||||
return wfe
|
||||
|
||||
def describe_workflow_execution(self, domain_name, run_id, workflow_id):
|
||||
self._check_string(domain_name)
|
||||
self._check_string(run_id)
|
||||
self._check_string(workflow_id)
|
||||
domain = self._get_domain(domain_name)
|
||||
return domain.get_workflow_execution(run_id, workflow_id)
|
||||
|
||||
|
||||
swf_backends = {}
|
||||
for region in boto.swf.regions():
|
||||
|
@ -139,7 +139,6 @@ class SWFResponse(BaseResponse):
|
||||
def describe_activity_type(self):
|
||||
return self._describe_type("activity")
|
||||
|
||||
# TODO: refactor with list_activity_types()
|
||||
def list_workflow_types(self):
|
||||
return self._list_types("workflow")
|
||||
|
||||
@ -201,3 +200,12 @@ class SWFResponse(BaseResponse):
|
||||
return json.dumps({
|
||||
"runId": wfe.run_id
|
||||
})
|
||||
|
||||
def describe_workflow_execution(self):
|
||||
domain_name = self._params["domain"]
|
||||
_workflow_execution = self._params["execution"]
|
||||
run_id = _workflow_execution["runId"]
|
||||
workflow_id = _workflow_execution["workflowId"]
|
||||
|
||||
wfe = self.swf_backend.describe_workflow_execution(domain_name, run_id, workflow_id)
|
||||
return json.dumps(wfe.to_full_dict())
|
||||
|
@ -3,6 +3,7 @@ from sure import expect
|
||||
from moto.swf.models import (
|
||||
Domain,
|
||||
GenericType,
|
||||
WorkflowType,
|
||||
WorkflowExecution,
|
||||
)
|
||||
|
||||
@ -89,3 +90,44 @@ def test_workflow_execution_generates_a_random_run_id():
|
||||
wfe1 = WorkflowExecution("workflow_type_whatever", "ab1234")
|
||||
wfe2 = WorkflowExecution("workflow_type_whatever", "ab1235")
|
||||
wfe1.run_id.should_not.equal(wfe2.run_id)
|
||||
|
||||
def test_workflow_execution_short_dict_representation():
|
||||
wf_type = WorkflowType("test-workflow", "v1.0")
|
||||
wfe = WorkflowExecution(wf_type, "ab1234")
|
||||
|
||||
sd = wfe.to_short_dict()
|
||||
sd["workflowId"].should.equal("ab1234")
|
||||
sd.should.contain("runId")
|
||||
|
||||
def test_workflow_execution_medium_dict_representation():
|
||||
wf_type = WorkflowType("test-workflow", "v1.0")
|
||||
wfe = WorkflowExecution(wf_type, "ab1234")
|
||||
|
||||
md = wfe.to_medium_dict()
|
||||
md["execution"].should.equal(wfe.to_short_dict())
|
||||
md["workflowType"].should.equal(wf_type.to_short_dict())
|
||||
md["startTimestamp"].should.be.a('float')
|
||||
md["executionStatus"].should.equal("OPEN")
|
||||
md["cancelRequested"].should.equal(False)
|
||||
md.should_not.contain("tagList")
|
||||
|
||||
wfe.tag_list = ["foo", "bar", "baz"]
|
||||
md = wfe.to_medium_dict()
|
||||
md["tagList"].should.equal(["foo", "bar", "baz"])
|
||||
|
||||
def test_workflow_execution_full_dict_representation():
|
||||
wf_type = WorkflowType("test-workflow", "v1.0")
|
||||
wfe = WorkflowExecution(wf_type, "ab1234")
|
||||
|
||||
fd = wfe.to_full_dict()
|
||||
fd["executionInfo"].should.equal(wfe.to_medium_dict())
|
||||
fd["openCounts"]["openTimers"].should.equal(0)
|
||||
fd["openCounts"]["openDecisionTasks"].should.equal(0)
|
||||
fd["openCounts"]["openActivityTasks"].should.equal(0)
|
||||
fd["executionConfiguration"].should.equal({})
|
||||
|
||||
wfe.task_list = "special"
|
||||
wfe.task_start_to_close_timeout = "45"
|
||||
fd = wfe.to_full_dict()
|
||||
fd["executionConfiguration"]["taskList"]["name"].should.equal("special")
|
||||
fd["executionConfiguration"]["taskStartToCloseTimeout"].should.equal("45")
|
||||
|
@ -6,6 +6,7 @@ from moto import mock_swf
|
||||
from moto.swf.exceptions import (
|
||||
SWFWorkflowExecutionAlreadyStartedFault,
|
||||
SWFTypeDeprecatedFault,
|
||||
SWFUnknownResourceFault,
|
||||
)
|
||||
|
||||
|
||||
@ -57,3 +58,30 @@ def test_start_workflow_execution_on_deprecated_type():
|
||||
"__type": "com.amazonaws.swf.base.model#TypeDeprecatedFault",
|
||||
"message": "WorkflowType=[name=test-workflow, version=v1.0]"
|
||||
})
|
||||
|
||||
|
||||
# DescribeWorkflowExecution endpoint
|
||||
@mock_swf
|
||||
def test_describe_workflow_execution():
|
||||
conn = setup_swf_environment()
|
||||
hsh = conn.start_workflow_execution("test-domain", "uid-abcd1234", "test-workflow", "v1.0")
|
||||
run_id = hsh["runId"]
|
||||
|
||||
wfe = conn.describe_workflow_execution("test-domain", run_id, "uid-abcd1234")
|
||||
wfe["executionInfo"]["execution"]["workflowId"].should.equal("uid-abcd1234")
|
||||
wfe["executionInfo"]["executionStatus"].should.equal("OPEN")
|
||||
|
||||
@mock_swf
|
||||
def test_describe_non_existent_workflow_execution():
|
||||
conn = setup_swf_environment()
|
||||
|
||||
with assert_raises(SWFUnknownResourceFault) as err:
|
||||
conn.describe_workflow_execution("test-domain", "wrong-run-id", "wrong-workflow-id")
|
||||
|
||||
ex = err.exception
|
||||
ex.status.should.equal(400)
|
||||
ex.error_code.should.equal("UnknownResourceFault")
|
||||
ex.body.should.equal({
|
||||
"__type": "com.amazonaws.swf.base.model#UnknownResourceFault",
|
||||
"message": "Unknown execution: WorkflowExecution=[workflowId=wrong-workflow-id, runId=wrong-run-id]"
|
||||
})
|
||||
|
Loading…
Reference in New Issue
Block a user