Add SWF endpoint: DescribeWorkflowExecution
This commit is contained in:
		
							parent
							
								
									a589dc08b5
								
							
						
					
					
						commit
						2878252816
					
				@ -84,6 +84,17 @@ class Domain(object):
 | 
				
			|||||||
            raise SWFWorkflowExecutionAlreadyStartedFault()
 | 
					            raise SWFWorkflowExecutionAlreadyStartedFault()
 | 
				
			||||||
        self.workflow_executions[_id] = workflow_execution
 | 
					        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):
 | 
					class GenericType(object):
 | 
				
			||||||
    def __init__(self, name, version, **kwargs):
 | 
					    def __init__(self, name, version, **kwargs):
 | 
				
			||||||
@ -177,12 +188,68 @@ class WorkflowExecution(object):
 | 
				
			|||||||
        self.workflow_type = workflow_type
 | 
					        self.workflow_type = workflow_type
 | 
				
			||||||
        self.workflow_id = workflow_id
 | 
					        self.workflow_id = workflow_id
 | 
				
			||||||
        self.run_id = uuid.uuid4().hex
 | 
					        self.run_id = uuid.uuid4().hex
 | 
				
			||||||
 | 
					        self.execution_status = "OPEN"
 | 
				
			||||||
 | 
					        self.cancel_requested = False
 | 
				
			||||||
 | 
					        #config
 | 
				
			||||||
        for key, value in kwargs.iteritems():
 | 
					        for key, value in kwargs.iteritems():
 | 
				
			||||||
            self.__setattr__(key, value)
 | 
					            self.__setattr__(key, value)
 | 
				
			||||||
 | 
					        #counters
 | 
				
			||||||
 | 
					        self.open_counts = {
 | 
				
			||||||
 | 
					            "openTimers": 0,
 | 
				
			||||||
 | 
					            "openDecisionTasks": 0,
 | 
				
			||||||
 | 
					            "openActivityTasks": 0,
 | 
				
			||||||
 | 
					            "openChildWorkflowExecutions": 0,
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __repr__(self):
 | 
					    def __repr__(self):
 | 
				
			||||||
        return "WorkflowExecution(run_id: {})".format(self.run_id)
 | 
					        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):
 | 
					class SWFBackend(BaseBackend):
 | 
				
			||||||
    def __init__(self, region_name):
 | 
					    def __init__(self, region_name):
 | 
				
			||||||
@ -318,6 +385,13 @@ class SWFBackend(BaseBackend):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        return wfe
 | 
					        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 = {}
 | 
					swf_backends = {}
 | 
				
			||||||
for region in boto.swf.regions():
 | 
					for region in boto.swf.regions():
 | 
				
			||||||
 | 
				
			|||||||
@ -139,7 +139,6 @@ class SWFResponse(BaseResponse):
 | 
				
			|||||||
    def describe_activity_type(self):
 | 
					    def describe_activity_type(self):
 | 
				
			||||||
        return self._describe_type("activity")
 | 
					        return self._describe_type("activity")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # TODO: refactor with list_activity_types()
 | 
					 | 
				
			||||||
    def list_workflow_types(self):
 | 
					    def list_workflow_types(self):
 | 
				
			||||||
        return self._list_types("workflow")
 | 
					        return self._list_types("workflow")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -201,3 +200,12 @@ class SWFResponse(BaseResponse):
 | 
				
			|||||||
        return json.dumps({
 | 
					        return json.dumps({
 | 
				
			||||||
            "runId": wfe.run_id
 | 
					            "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 (
 | 
					from moto.swf.models import (
 | 
				
			||||||
    Domain,
 | 
					    Domain,
 | 
				
			||||||
    GenericType,
 | 
					    GenericType,
 | 
				
			||||||
 | 
					    WorkflowType,
 | 
				
			||||||
    WorkflowExecution,
 | 
					    WorkflowExecution,
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -89,3 +90,44 @@ def test_workflow_execution_generates_a_random_run_id():
 | 
				
			|||||||
    wfe1 = WorkflowExecution("workflow_type_whatever", "ab1234")
 | 
					    wfe1 = WorkflowExecution("workflow_type_whatever", "ab1234")
 | 
				
			||||||
    wfe2 = WorkflowExecution("workflow_type_whatever", "ab1235")
 | 
					    wfe2 = WorkflowExecution("workflow_type_whatever", "ab1235")
 | 
				
			||||||
    wfe1.run_id.should_not.equal(wfe2.run_id)
 | 
					    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 (
 | 
					from moto.swf.exceptions import (
 | 
				
			||||||
    SWFWorkflowExecutionAlreadyStartedFault,
 | 
					    SWFWorkflowExecutionAlreadyStartedFault,
 | 
				
			||||||
    SWFTypeDeprecatedFault,
 | 
					    SWFTypeDeprecatedFault,
 | 
				
			||||||
 | 
					    SWFUnknownResourceFault,
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -57,3 +58,30 @@ def test_start_workflow_execution_on_deprecated_type():
 | 
				
			|||||||
        "__type": "com.amazonaws.swf.base.model#TypeDeprecatedFault",
 | 
					        "__type": "com.amazonaws.swf.base.model#TypeDeprecatedFault",
 | 
				
			||||||
        "message": "WorkflowType=[name=test-workflow, version=v1.0]"
 | 
					        "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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user