Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
The execution context allows to separate the different elements that forms the full execution context: from the workflow execution input to the full context. @rantonmattei
- Loading branch information
Showing
6 changed files
with
175 additions
and
72 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
# -*- coding: utf-8 -*- | ||
""" | ||
Context | ||
======= | ||
Context carries information that have been retrieved from the different SWF | ||
events of an execution. | ||
""" | ||
|
||
import json | ||
|
||
|
||
class ExecutionContext: | ||
|
||
def __init__(self, events=None): | ||
"""Create the execution context. | ||
An execution context gathers the execution input and the result of all | ||
the activities that have successfully ran. It also adds the execution | ||
input into the mix (for logger purposes). | ||
Args: | ||
events (list): optional list of all the events. | ||
""" | ||
|
||
self.current = {} | ||
self.workflow_input = {} | ||
|
||
if events: | ||
for event in events: | ||
self.add(event) | ||
|
||
def add(self, event): | ||
"""Add an event into the execution context. | ||
The events are the ones coming from SWF directly (so the fields are the | ||
ones we expect). | ||
Args: | ||
event (dict): the event to add to the context. | ||
""" | ||
|
||
event_type = event.get('eventType') | ||
if event_type == 'ActivityTaskCompleted': | ||
self.add_activity_result(event) | ||
elif event_type == 'WorkflowExecutionStarted': | ||
self.set_execution_input(event) | ||
|
||
def set_workflow_execution_info(self, execution_info, domain): | ||
"""Add the workflow execution info. | ||
Workflow execution info contains the domain, workflow id and run id. | ||
This allows the logger to properly namespace the messages and | ||
facilitate debugging. | ||
Args: | ||
execution_info (dict): the execution information. | ||
domain (str): the current domain | ||
""" | ||
|
||
if ('workflowExecution' in execution_info and | ||
'workflowId' in execution_info['workflowExecution'] and | ||
'runId' in execution_info['workflowExecution']): | ||
|
||
workflow_execution = execution_info['workflowExecution'] | ||
self.current.update({ | ||
'execution.domain': domain, | ||
'execution.workflow_id': workflow_execution['workflowId'], | ||
'execution.run_id': workflow_execution['runId'] | ||
}) | ||
|
||
def set_execution_input(self, execution_event): | ||
"""Add the workflow execution input. | ||
Please note the input within the execution event should always be a | ||
json string. | ||
Args: | ||
execution_event (str): the execution event information. | ||
""" | ||
|
||
attributes = execution_event['workflowExecutionStartedEventAttributes'] | ||
result = attributes.get('input') | ||
if result: | ||
result = json.loads(result) | ||
self.workflow_input = result | ||
self.current.update(result) | ||
|
||
def add_activity_result(self, activity_event): | ||
"""Add an activity result. | ||
Please note: the result of an activity event should always be a json | ||
string. | ||
Args: | ||
activity_event (str): json object that represents the activity | ||
information. | ||
""" | ||
|
||
attributes = activity_event['activityTaskCompletedEventAttributes'] | ||
result = attributes.get('result') | ||
|
||
if result: | ||
self.current.update(json.loads(result)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
from __future__ import absolute_import | ||
try: | ||
from unittest.mock import MagicMock | ||
except: | ||
from mock import MagicMock | ||
import boto.swf.layer2 as swf | ||
|
||
from garcon import context | ||
from tests.fixtures import decider as decider_events | ||
|
||
|
||
def mock(monkeypatch): | ||
for base in [swf.Decider, swf.WorkflowType, swf.ActivityType, swf.Domain]: | ||
monkeypatch.setattr(base, '__init__', MagicMock(return_value=None)) | ||
if base is not swf.Decider: | ||
monkeypatch.setattr(base, 'register', MagicMock()) | ||
|
||
|
||
def test_context_creation_without_events(monkeypatch): | ||
"""Check the basic context creation. | ||
""" | ||
|
||
mock(monkeypatch) | ||
current_context = context.ExecutionContext() | ||
assert not current_context.current | ||
assert not current_context.workflow_input | ||
|
||
|
||
def test_context_creation_with_events(monkeypatch): | ||
"""Test context creation with events. | ||
""" | ||
|
||
mock(monkeypatch) | ||
from tests.fixtures import decider as poll | ||
|
||
current_context = context.ExecutionContext(poll.history.get('events')) | ||
assert current_context.current == {'k': 'v'} | ||
|
||
def test_get_workflow_execution_info(monkeypatch): | ||
"""Check that the workflow execution info are properly extracted | ||
""" | ||
|
||
mock(monkeypatch) | ||
from tests.fixtures import decider as poll | ||
|
||
current_context = context.ExecutionContext() | ||
current_context.set_workflow_execution_info(poll.history, 'dev') | ||
|
||
# Test extracting workflow execution info | ||
assert current_context.current == { | ||
'execution.domain': 'dev', | ||
'execution.run_id': '123abc=', | ||
'execution.workflow_id': 'test-workflow-id'} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters