示例#1
0
    def cancel(self, task_token, details=None):
        """Responds to ``swf`` that the activity task was canceled

        :param  task_token: canceled activity task token
        :type   task_token: string

        :param  details: provided details about cancel
        :type   details: string
        """
        try:
            return self.connection.respond_activity_task_canceled(
                task_token,
                details=format.details(details),
            )
        except boto.exception.SWFResponseError as e:
            message = self.get_error_message(e)
            if e.error_code == 'UnknownResourceFault':
                raise DoesNotExistError(
                    "Unable to cancel activity task with token={}".format(
                        task_token),
                    message,
                )
            raise ResponseError(message)
        finally:
            logging_context.reset()
示例#2
0
    def _diff(self):
        """Checks for differences between Domain instance
        and upstream version

        :returns: A list of swf.models.base.ModelDiff namedtuple describing
                  differences
        :rtype: list
        """
        try:
            description = self.connection.describe_domain(self.name)
        except SWFResponseError as e:
            if e.error_code == 'UnknownResourceFault':
                raise DoesNotExistError("Remote Domain does not exist")

            raise ResponseError(e.body['message'])

        domain_info = description['domainInfo']
        domain_config = description['configuration']

        return ModelDiff(
            ('name', self.name, domain_info['name']),
            ('status', self.status, domain_info['status']),
            ('description', self.description, domain_info.get('description')),
            ('retention_period', self.retention_period,
             domain_config['workflowExecutionRetentionPeriodInDays']),
        )
示例#3
0
 def save(self):
     """Creates the activity type amazon side"""
     try:
         self.connection.register_activity_type(
             self.domain.name,
             self.name,
             self.version,
             task_list=str(self.task_list),
             default_task_heartbeat_timeout=str(
                 self.task_heartbeat_timeout),
             default_task_schedule_to_close_timeout=str(
                 self.task_schedule_to_close_timeout),
             default_task_schedule_to_start_timeout=str(
                 self.task_schedule_to_start_timeout),
             default_task_start_to_close_timeout=str(
                 self.task_start_to_close_timeout),
             description=self.description)
     except SWFTypeAlreadyExistsError as err:
         raise AlreadyExistsError('{} already exists'.format(self))
     except SWFResponseError as err:
         if err.error_code in [
                 'UnknownResourceFault', 'TypeDeprecatedFault'
         ]:
             raise DoesNotExistError(err.body['message'])
         raise
示例#4
0
    def complete(self, task_token, decisions=None, execution_context=None):
        """Responds to ``swf`` decisions have been made about
        the task with `task_token``

        :param  task_token: completed decision task token
        :type   task_token: str

        :param  decisions: The list of decisions (possibly empty)
                           made by the decider while processing this decision task
        :type   decisions: list[swf.models.decision.base.Decision]
        :param execution_context: User-defined context to add to workflow execution.
        :type execution_context: str
        """
        try:
            self.connection.respond_decision_task_completed(
                task_token,
                decisions,
                execution_context,
            )
        except boto.exception.SWFResponseError as e:
            if e.error_code == 'UnknownResourceFault':
                raise DoesNotExistError(
                    "Unable to complete decision task with token={}".format(
                        task_token),
                    e.body['message'],
                )

            raise ResponseError(e.body['message'])
示例#5
0
    def heartbeat(self, task_token, details=None):
        """Records activity task heartbeat

        :param  task_token: canceled activity task token
        :type   task_token: str

        :param  details: provided details about task progress
        :type   details: string
        """
        try:
            return self.connection.record_activity_task_heartbeat(
                task_token, format.heartbeat_details(details),
            )
        except boto.exception.SWFResponseError as e:
            message = self.get_error_message(e)
            if e.error_code == "UnknownResourceFault":
                raise DoesNotExistError(
                    "Unable to send heartbeat with token={}".format(task_token),
                    message,
                )

            if e.error_code == "ThrottlingException":
                raise RateLimitExceededError(
                    "Rate exceeded when sending heartbeat with token={}".format(
                        task_token
                    ),
                    message,
                )

            raise ResponseError(message)
示例#6
0
    def complete(self, task_token, decisions=None, execution_context=None):
        """Responds to ``swf`` decisions have been made about
        the task with `task_token``

        :param  task_token: completed decision task token
        :type   task_token: str

        :param  decisions: The list of decisions (possibly empty)
                           made by the decider while processing this decision task
        :type   decisions: list[swf.models.decision.base.Decision]
        :param execution_context: User-defined context to add to workflow execution.
        :type execution_context: str
        """
        if execution_context is not None and not isinstance(
                execution_context, compat.string_types):
            execution_context = json_dumps(execution_context)
        try:
            self.connection.respond_decision_task_completed(
                task_token,
                decisions,
                format.execution_context(execution_context),
            )
        except boto.exception.SWFResponseError as e:
            message = self.get_error_message(e)
            if e.error_code == 'UnknownResourceFault':
                raise DoesNotExistError(
                    "Unable to complete decision task with token={}".format(
                        task_token),
                    message,
                )
            raise ResponseError(message)
        finally:
            logging_context.reset()
示例#7
0
    def _diff(self):
        """Checks for differences between Domain instance
        and upstream version

        :returns: A swf.models.base.ModelDiff describing
                  differences
        :rtype: ModelDiff
        """
        try:
            description = self.connection.describe_domain(self.name)
        except SWFResponseError as e:
            if e.error_code == "UnknownResourceFault":
                raise DoesNotExistError("Remote Domain does not exist")

            raise ResponseError(e.body["message"])

        domain_info = description["domainInfo"]
        domain_config = description["configuration"]

        return ModelDiff(
            ("name", self.name, domain_info["name"]),
            ("status", self.status, domain_info["status"]),
            ("description", self.description, domain_info.get("description")),
            (
                "retention_period",
                self.retention_period,
                domain_config["workflowExecutionRetentionPeriodInDays"],
            ),
        )
示例#8
0
    def fail(self, task_token, details=None, reason=None):
        """Replies to ``swf`` that the activity task failed

        :param  task_token: canceled activity task token
        :type   task_token: string

        :param  details: provided details about the failure
        :type   details: string

        :param  reason: Description of the error that may assist in diagnostics
        :type   reason: string
        """
        try:
            return self.connection.respond_activity_task_failed(
                task_token,
                details=format.details(details),
                reason=format.reason(reason),
            )
        except boto.exception.SWFResponseError as e:
            message = self.get_error_message(e)
            if e.error_code == "UnknownResourceFault":
                raise DoesNotExistError(
                    "Unable to fail activity task with token={}".format(task_token),
                    message,
                )

            raise ResponseError(message)
示例#9
0
    def _diff(self):
        """Checks for differences between WorkflowType instance
        and upstream version

        :returns: A swf.models.base.ModelDiff describing
                  differences
        :rtype: ModelDiff
        """
        try:
            description = self.connection.describe_workflow_type(
                self.domain.name,
                self.name,
                self.version
            )
        except SWFResponseError as e:
            if e.error_code == 'UnknownResourceFault':
                raise DoesNotExistError("Remote Domain does not exist")

            raise ResponseError(e.body['message'])

        workflow_info = description['typeInfo']
        workflow_config = description['configuration']

        return ModelDiff(
            ('name', self.name, workflow_info['workflowType']['name']),
            ('version', self.version, workflow_info['workflowType']['version']),
            ('status', self.status, workflow_info['status']),
            ('creation_date', self.creation_date, workflow_info['creationDate']),
            ('deprecation_date', self.deprecation_date, workflow_info['deprecationDate']),
            ('task_list', self.task_list, workflow_config['defaultTaskList']['name']),
            ('child_policy', self.child_policy, workflow_config['defaultChildPolicy']),
            ('execution_timeout', self.execution_timeout, workflow_config['defaultExecutionStartToCloseTimeout']),
            ('decision_tasks_timout', self.decision_tasks_timeout, workflow_config['defaultTaskStartToCloseTimeout']),
            ('description', self.description, workflow_info['description']),
        )
示例#10
0
 def delete(self):
     """Deprecates the workflow type amazon-side"""
     try:
         self.connection.deprecate_workflow_type(self.domain.name, self.name, self.version)
     except SWFResponseError as e:
         if e.error_code in ['UnknownResourceFault', 'TypeDeprecatedFault']:
             raise DoesNotExistError(e.body['message'])
示例#11
0
    def get(self, workflow_id, run_id, *args, **kwargs):
        """ """
        try:
            response = self.connection.describe_workflow_execution(
                self.domain.name, run_id, workflow_id
            )
        except SWFResponseError as e:
            if e.error_code == "UnknownResourceFault":
                raise DoesNotExistError(e.body["message"])

            raise ResponseError(e.body["message"])

        execution_info = response[self._infos]
        execution_config = response["executionConfiguration"]

        return self.to_WorkflowExecution(
            self.domain,
            execution_info,
            task_list=get_subkey(execution_config, ["taskList", "name"]),
            child_policy=execution_config.get("childPolicy"),
            execution_timeout=execution_config.get("executionStartToCloseTimeout"),
            decision_tasks_timeout=execution_config.get("taskStartToCloseTimeout"),
            latest_activity_task_timestamp=response.get("latestActivityTaskTimestamp"),
            latest_execution_context=response.get("latestExecutionContext"),
            open_counts=response["openCounts"],
        )
示例#12
0
    def _diff(self):
        """Checks for differences between WorkflowExecution instance
        and upstream version

        :returns: A swf.models.base.ModelDiff describing
                  differences
        :rtype: ModelDiff
        """
        try:
            description = self.connection.describe_workflow_execution(
                self.domain.name,
                self.run_id,
                self.workflow_id
            )
        except SWFResponseError as e:
            if e.error_code == 'UnknownResourceFault':
                raise DoesNotExistError("Remote Domain does not exist")

            raise ResponseError(e.body['message'])

        execution_info = description['executionInfo']
        execution_config = description['executionConfiguration']

        return ModelDiff(
            ('workflow_id', self.workflow_id, execution_info['execution']['workflowId']),
            ('run_id', self.run_id, execution_info['execution']['runId']),
            ('status', self.status, execution_info['executionStatus']),
            ('task_list', self.task_list, execution_config['taskList']['name']),
            ('child_policy', self.child_policy, execution_config['childPolicy']),
            ('execution_timeout', self.execution_timeout, execution_config['executionStartToCloseTimeout']),
            ('tag_list', self.tag_list, execution_info.get('tagList')),
            ('decision_tasks_timeout', self.decision_tasks_timeout, execution_config['taskStartToCloseTimeout']),
        )
示例#13
0
    def test_get_or_create_non_existent_domain(self):
        with patch.object(Layer1, 'describe_domain') as mock:
            mock.side_effect = DoesNotExistError("Mocked exception")

            with patch.object(Layer1, 'register_domain', mock_describe_domain):
                domain = self.qs.get_or_create("TestDomain")

                self.assertIsInstance(domain, Domain)
示例#14
0
    def test_get_or_create_non_existent_workflow_type(self):
        with patch.object(Layer1, 'describe_workflow_type') as mock:
            mock.side_effect = DoesNotExistError("Mocked exception")

            with patch.object(Layer1, 'register_workflow_type', mock_describe_workflow_type):
                workflow_type = self.wtq.get_or_create("TestDomain", "testversion")

                self.assertIsInstance(workflow_type, WorkflowType)
示例#15
0
    def test_get_or_create_non_existent_activity_type(self):
        with patch.object(Layer1, "describe_activity_type") as mock:
            mock.side_effect = DoesNotExistError("Mocked exception")

            with patch.object(Layer1, "register_activity_type",
                              mock_describe_activity_type):
                activity_type = self.atq.get_or_create("TestDomain",
                                                       "testversion")

                self.assertIsInstance(activity_type, ActivityType)
示例#16
0
    def poll(self, task_list=None, identity=None):
        """Polls for an activity task to process from current
        actor's instance defined ``task_list``

        if no activity task was polled, raises a PollTimeout
        exception.

        :param  task_list: task list the Actor should watch for tasks on
        :type   task_list: string

        :param  identity: Identity of the worker making the request,
                          which is recorded in the ActivityTaskStarted
                          event in the workflow history. This enables
                          diagnostic tracing when problems arise.
                          The form of this identity is user defined.
        :type   identity: string

        :raises: PollTimeout

        :returns: task token, polled activity task
        :rtype: (str, ActivityTask)
        """
        logging_context.reset()
        task_list = task_list or self.task_list
        identity = identity or self._identity

        try:
            task = self.connection.poll_for_activity_task(
                self.domain.name, task_list, identity=format.identity(identity),
            )
        except boto.exception.SWFResponseError as e:
            message = self.get_error_message(e)
            if e.error_code == "UnknownResourceFault":
                raise DoesNotExistError(
                    "Unable to poll activity task", message,
                )

            raise ResponseError(message)

        if not task.get("taskToken"):
            raise PollTimeout("Activity Worker poll timed out")

        logging_context.set("workflow_id", task["workflowExecution"]["workflowId"])
        logging_context.set("task_type", "activity")
        logging_context.set("event_id", task["startedEventId"])
        logging_context.set("activity_id", task["activityId"])

        activity_task = ActivityTask.from_poll(self.domain, self.task_list, task,)

        return Response(
            task_token=activity_task.task_token,
            activity_task=activity_task,
            raw_response=task,
        )
示例#17
0
    def _diff(self):
        """Checks for differences between ActivityType instance
        and upstream version

        :returns: A list (swf.models.base.ModelDiff) namedtuple describing
                  differences
        :rtype: ModelDiff
        """
        try:
            description = self.connection.describe_activity_type(
                self.domain.name, self.name, self.version)
        except SWFResponseError as err:
            if err.error_code == "UnknownResourceFault":
                raise DoesNotExistError("Remote ActivityType does not exist")

            raise ResponseError(err.body["message"])

        info = description["typeInfo"]
        config = description["configuration"]

        return ModelDiff(
            ("name", self.name, info["activityType"]["name"]),
            ("version", self.version, info["activityType"]["version"]),
            ("status", self.status, info["status"]),
            ("description", self.description, info["description"]),
            ("creation_date", self.creation_date, info["creationDate"]),
            ("deprecation_date", self.deprecation_date,
             info["deprecationDate"]),
            ("task_list", self.task_list, config["defaultTaskList"]["name"]),
            (
                "task_heartbeat_timeout",
                self.task_heartbeat_timeout,
                config["defaultTaskHeartbeatTimeout"],
            ),
            (
                "task_schedule_to_close_timeout",
                self.task_schedule_to_close_timeout,
                config["defaultTaskScheduleToCloseTimeout"],
            ),
            (
                "task_schedule_to_start_timeout",
                self.task_schedule_to_start_timeout,
                config["defaultTaskScheduleToStartTimeout"],
            ),
            (
                "task_start_to_close_timeout",
                self.task_start_to_close_timeout,
                config["defaultTaskStartToCloseTimeout"],
            ),
        )
示例#18
0
    def _diff(self):
        """Checks for differences between WorkflowType instance
        and upstream version

        :returns: A swf.models.base.ModelDiff describing
                  differences
        :rtype: ModelDiff
        """
        try:
            description = self.connection.describe_workflow_type(
                self.domain.name, self.name, self.version)
        except SWFResponseError as e:
            if e.error_code == "UnknownResourceFault":
                raise DoesNotExistError("Remote Domain does not exist")

            raise ResponseError(e.body["message"])

        workflow_info = description["typeInfo"]
        workflow_config = description["configuration"]

        return ModelDiff(
            ("name", self.name, workflow_info["workflowType"]["name"]),
            ("version", self.version,
             workflow_info["workflowType"]["version"]),
            ("status", self.status, workflow_info["status"]),
            ("creation_date", self.creation_date,
             workflow_info["creationDate"]),
            (
                "deprecation_date",
                self.deprecation_date,
                workflow_info["deprecationDate"],
            ),
            ("task_list", self.task_list,
             workflow_config["defaultTaskList"]["name"]),
            ("child_policy", self.child_policy,
             workflow_config["defaultChildPolicy"]),
            (
                "execution_timeout",
                self.execution_timeout,
                workflow_config["defaultExecutionStartToCloseTimeout"],
            ),
            (
                "decision_tasks_timout",
                self.decision_tasks_timeout,
                workflow_config["defaultTaskStartToCloseTimeout"],
            ),
            ("description", self.description, workflow_info["description"]),
        )
示例#19
0
    def poll(self, task_list=None, identity=None):
        """Polls for an activity task to process from current
        actor's instance defined ``task_list``

        if no activity task was polled, raises a PollTimeout
        exception.

        :param  task_list: task list the Actor should watch for tasks on
        :type   task_list: string

        :param  identity: Identity of the worker making the request,
                          which is recorded in the ActivityTaskStarted
                          event in the workflow history. This enables
                          diagnostic tracing when problems arise.
                          The form of this identity is user defined.
        :type   identity: string

        :raises: PollTimeout

        :returns: task token, polled activity task
        :rtype: (str, ActivityTask)
        """
        task_list = task_list or self.task_list
        identity = identity or self._identity

        try:
            polled_activity_data = self.connection.poll_for_activity_task(
                self.domain.name, task_list, identity=identity)
        except boto.exception.SWFResponseError as e:
            message = self.get_error_message(e)
            if e.error_code == 'UnknownResourceFault':
                raise DoesNotExistError(
                    "Unable to poll activity task",
                    message,
                )

            raise ResponseError(message)

        if 'taskToken' not in polled_activity_data:
            raise PollTimeout("Activity Worker poll timed out")

        activity_task = ActivityTask.from_poll(self.domain, self.task_list,
                                               polled_activity_data)
        task_token = activity_task.task_token

        return task_token, activity_task
示例#20
0
 def save(self):
     """Creates the workflow type amazon side"""
     try:
         self.connection.register_workflow_type(
             self.domain.name,
             self.name,
             self.version,
             task_list=str(self.task_list),
             default_child_policy=str(self.child_policy),
             default_execution_start_to_close_timeout=str(self.execution_timeout),
             default_task_start_to_close_timeout=str(self.decision_tasks_timeout),
             description=self.description
         )
     except SWFTypeAlreadyExistsError:
         raise AlreadyExistsError("Workflow type %s already exists amazon-side" % self.name)
     except SWFResponseError as e:
         if e.error_code == 'UnknownResourceFault':
             raise DoesNotExistError(e.body['message'])
示例#21
0
    def _diff(self):
        """Checks for differences between WorkflowExecution instance
        and upstream version

        :returns: A swf.models.base.ModelDiff describing
                  differences
        :rtype: ModelDiff
        """
        try:
            description = self.connection.describe_workflow_execution(
                self.domain.name, self.run_id, self.workflow_id)
        except SWFResponseError as e:
            if e.error_code == "UnknownResourceFault":
                raise DoesNotExistError("Remote Domain does not exist")

            raise ResponseError(e.body["message"])

        execution_info = description["executionInfo"]
        execution_config = description["executionConfiguration"]

        return ModelDiff(
            (
                "workflow_id",
                self.workflow_id,
                execution_info["execution"]["workflowId"],
            ),
            ("run_id", self.run_id, execution_info["execution"]["runId"]),
            ("status", self.status, execution_info["executionStatus"]),
            ("task_list", self.task_list,
             execution_config["taskList"]["name"]),
            ("child_policy", self.child_policy,
             execution_config["childPolicy"]),
            (
                "execution_timeout",
                self.execution_timeout,
                execution_config["executionStartToCloseTimeout"],
            ),
            ("tag_list", self.tag_list, execution_info.get("tagList")),
            (
                "decision_tasks_timeout",
                self.decision_tasks_timeout,
                execution_config["taskStartToCloseTimeout"],
            ),
        )
示例#22
0
    def get(self, name, *args, **kwargs):
        """Fetches the Domain with `name`

        :param      name:  name of the domain to fetch
        :type       name: string

        A typical Amazon response looks like:

        .. code-block:: json

            {
                "configuration": {
                    "workflowExecutionRetentionPeriodInDays": "7",
                },
                "domainInfo": {
                    "status": "REGISTERED",
                    "name": "CrawlTest",
                }
            }
        """
        try:
            response = self.connection.describe_domain(name)
        except SWFResponseError as e:
            # If resource does not exist, amazon throws 400 with
            # UnknownResourceFault exception
            if e.error_code == "UnknownResourceFault":
                raise DoesNotExistError("No such domain: %s" % name)
            elif e.error_code == "UnrecognizedClientException":
                raise InvalidCredentialsError("Invalid aws credentials supplied")
            # Any other errors should raise
            raise ResponseError(e.body["message"])

        domain_info = response["domainInfo"]
        domain_config = response["configuration"]

        return Domain(
            domain_info["name"],
            status=domain_info["status"],
            retention_period=domain_config["workflowExecutionRetentionPeriodInDays"],
            connection=self.connection,
        )
示例#23
0
    def heartbeat(self, task_token, details=None):
        """Records activity task heartbeat

        :param  task_token: canceled activity task token
        :type   task_token: string

        :param  details: provided details about cancel
        :type   details: string
        """
        try:
            return self.connection.record_activity_task_heartbeat(
                task_token, details)
        except boto.exception.SWFResponseError as e:
            if e.error_code == 'UnknownResourceFault':
                raise DoesNotExistError(
                    "Unable to send heartbeat with token={}".format(
                        task_token),
                    e.body['message'],
                )

            raise ResponseError(e.body['message'])
示例#24
0
    def cancel(self, task_token, details=None):
        """Responds to ``swf`` that the activity task was canceled

        :param  task_token: canceled activity task token
        :type   task_token: string

        :param  details: provided details about cancel
        :type   details: string
        """
        try:
            return self.connection.respond_activity_task_canceled(
                task_token, details)
        except boto.exception.SWFResponseError as e:
            if e.error_code == 'UnknownResourceFault':
                raise DoesNotExistError(
                    "Unable to cancel activity task with token={}".format(
                        task_token),
                    e.body['message'],
                )

            raise ResponseError(e.body['message'])
示例#25
0
    def complete(self, task_token, result=None):
        """Responds to ``swf`` that the activity task is completed

        :param  task_token: completed activity task token
        :type   task_token: string

        :param  result: The result of the activity task.
        :type   result: string
        """
        try:
            return self.connection.respond_activity_task_completed(
                task_token, result)
        except boto.exception.SWFResponseError as e:
            if e.error_code == 'UnknownResourceFault':
                raise DoesNotExistError(
                    "Unable to complete activity task with token={}".format(
                        task_token),
                    e.body['message'],
                )

            raise ResponseError(e.body['message'])
示例#26
0
    def _diff(self):
        """Checks for differences between ActivityType instance
        and upstream version

        :returns: A list (swf.models.base.ModelDiff) namedtuple describing
                  differences
        :rtype: ModelDiff
        """
        try:
            description = self.connection.describe_activity_type(
                self.domain.name, self.name, self.version)
        except SWFResponseError as err:
            if err.error_code == 'UnknownResourceFault':
                raise DoesNotExistError("Remote ActivityType does not exist")

            raise ResponseError(err.body['message'])

        info = description['typeInfo']
        config = description['configuration']

        return ModelDiff(
            ('name', self.name, info['activityType']['name']),
            ('version', self.version, info['activityType']['version']),
            ('status', self.status, info['status']),
            ('description', self.description, info['description']),
            ('creation_date', self.creation_date, info['creationDate']),
            ('deprecation_date', self.deprecation_date,
             info['deprecationDate']),
            ('task_list', self.task_list, config['defaultTaskList']['name']),
            ('task_heartbeat_timeout', self.task_heartbeat_timeout,
             config['defaultTaskHeartbeatTimeout']),
            ('task_schedule_to_close_timeout',
             self.task_schedule_to_close_timeout,
             config['defaultTaskScheduleToCloseTimeout']),
            ('task_schedule_to_start_timeout',
             self.task_schedule_to_start_timeout,
             config['defaultTaskScheduleToStartTimeout']),
            ('task_start_to_close_timeout', self.task_start_to_close_timeout,
             config['defaultTaskStartToCloseTimeout']),
        )
示例#27
0
    def get(self, workflow_id, run_id, *args, **kwargs):
        """ """
        try:
            response = self.connection.describe_workflow_execution(
                self.domain.name,
                run_id,
                workflow_id)
        except SWFResponseError as e:
            if e.error_code == 'UnknownResourceFault':
                raise DoesNotExistError(e.body['message'])

            raise ResponseError(e.body['message'])

        execution_info = response[self._infos]
        execution_config = response['executionConfiguration']

        return self.to_WorkflowExecution(
            self.domain,
            execution_info,
            task_list=get_subkey(execution_config, ['defaultTaskList', 'name']),
            child_policy=execution_config.get('childPolicy'),
            execution_timeout=execution_config.get('executionStartToCloseTimeout'),
            decision_tasks_timeout=execution_config.get('taskStartToCloseTimeout'),
        )
示例#28
0
class ActivityType(BaseModel):
    """ActivityType wrapper

    :param  domain: Domain the workflow type should be registered in
    :type   domain: swf.models.Domain

    :param  name: name of the ActivityType
    :type   name: str

    :param  version: version of the ActivityType
    :type   version: str

    :param  status: ActivityType status
    :type   status: swf.constants.{REGISTERED, DEPRECATED}

    :param  description: ActivityType description
    :type   description: str | None

    :param   creation_date: creation date of the current ActivityType
    :type    creation_date: float (timestamp)

    :param   deprecation_date: deprecation date of ActivityType
    :type    deprecation_date: float (timestamp)

    :param  task_list: specifies the default task list to use for scheduling
                       tasks of this activity type.
    :type   task_list: str

    :param  task_heartbeat_timeout: default maximum time before which a worker
                                    processing a task of this type must report
                                    progress by calling RecordActivityTaskHeartbeat.
    :type   task_heartbeat_timeout: int

    :param  task_schedule_to_close_timeout: default maximum duration for a task
                                            of this activity type.
    :type   task_schedule_to_close_timeout: int

    :param  task_schedule_to_start_timeout: default maximum duration that a
                                            task of this activity type can wait
                                            before being assigned to a worker.
    :type   task_schedule_to_start_timeout: int

    :param   task_start_to_close_timeout: default maximum duration that a
                                          worker can take to process tasks of
                                          this activity type.
    :type    task_start_to_close_timeout: int
    """
    kind = 'type'

    __slots__ = [
        'domain',
        'name',
        'version',
        'status',
        'description',
        'creation_date',
        'deprecation_date',
        'task_list',
        'task_heartbeat_timeout',
        'task_schedule_to_close_timeout',
        'task_schedule_to_start_timeout',
        'task_start_to_close_timeout',
    ]

    def __init__(self, domain, name, version,
                 status=REGISTERED,
                 description=None,
                 creation_date=0.0,
                 deprecation_date=0.0,
                 task_list=None,
                 task_heartbeat_timeout=0,
                 task_schedule_to_close_timeout=0,
                 task_schedule_to_start_timeout=0,
                 task_start_to_close_timeout=0,
                 *args, **kwargs):

        self.domain = domain
        self.name = name
        self.version = version
        self.status = status
        self.description = description

        self.creation_date = creation_date
        self.deprecation_date = deprecation_date

        self.task_list = task_list
        self.task_heartbeat_timeout = task_heartbeat_timeout
        self.task_schedule_to_close_timeout = task_schedule_to_close_timeout
        self.task_schedule_to_start_timeout = task_schedule_to_start_timeout
        self.task_start_to_close_timeout = task_start_to_close_timeout

        # immutable decorator rebinds class name,
        # so have to use generice self.__class__
        super(self.__class__, self).__init__(*args, **kwargs)

    def _diff(self):
        """Checks for differences between ActivityType instance
        and upstream version

        :returns: A list of swf.models.base.ModelDiff namedtuple describing
                  differences
        :rtype: list
        """
        try:
            description = self.connection.describe_activity_type(
                self.name,
                self.name,
                self.version
            )
        except SWFResponseError as err:
            if err.error_code == 'UnknownResourceFault':
                raise DoesNotExistError("Remote ActivityType does not exist")

            raise ResponseError(err.body['message'])

        info = description['typeInfo']
        config = description['configuration']

        return ModelDiff(
            ('name', self.name, info['activityType']['name']),
            ('version', self.version, info['activityType']['version']),
            ('status', self.status, info['status']),
            ('description', self.description, info['description']),
            ('creation_date', self.creation_date, info['creationDate']),
            ('deprecation_date', self.deprecation_date, info['deprecationDate']),
            ('task_list', self.task_list, config['defaultTaskList']['name']),
            ('task_heartbeat_timeout', self.task_heartbeat_timeout, config['defaultTaskHeartbeatTimeout']),
            ('task_schedule_to_close_timeout', self.task_schedule_to_close_timeout, config['defaultTaskScheduleToCloseTimeout']),
            ('task_schedule_to_start_timeout', self.task_schedule_to_start_timeout, config['defaultTaskScheduleToStartTimeout']),
            ('task_start_to_close_timeout', self.task_start_to_close_timeout, config['defaultTaskStartToCloseTimeout']),
        )

    @property
    @exceptions.is_not(ActivityTypeDoesNotExist)
    @exceptions.when(SWFResponseError,
                     raises(ActivityTypeDoesNotExist,
                            when=exceptions.is_unknown('ActivityType'),
                            extract=exceptions.extract_resource))
    def exists(self):
        """Checks if the ActivityType exists amazon-side

        :rtype: bool
        """
        self.connection.describe_activity_type(
            self.domain.name,
            self.name,
            self.version
        )
        return True

    def save(self):
        """Creates the activity type amazon side"""
        try:
            self.connection.register_activity_type(
                self.domain.name,
                self.name,
                self.version,
                task_list=str(self.task_list),
                default_task_heartbeat_timeout=str(self.task_heartbeat_timeout),
                default_task_schedule_to_close_timeout=str(self.task_schedule_to_close_timeout),
                default_task_schedule_to_start_timeout=str(self.task_schedule_to_start_timeout),
                default_task_start_to_close_timeout=str(self.task_start_to_close_timeout),
                description=self.description)
        except SWFTypeAlreadyExistsError, err:
            raise AlreadyExistsError('{} already exists'.format(self))
        except SWFResponseError as err:
            if err.error_code in ['UnknownResourceFault', 'TypeDeprecatedFault']:
                raise DoesNotExistError(err.body['message'])
            raise
示例#29
0
    def poll(self, task_list=None, identity=None, **kwargs):
        """
        Polls a decision task and returns the token and the full history of the
        workflow's events.

        :param task_list: task list to poll for decision tasks from.
        :type task_list: str

        :param identity: Identity of the decider making the request,
        which is recorded in the DecisionTaskStarted event in the
        workflow history.
        :type identity: str

        :returns: a Response object with history, token, and execution set
        :rtype: swf.responses.Response

        """
        task_list = task_list or self.task_list

        task = self.connection.poll_for_decision_task(self.domain.name,
                                                      task_list=task_list,
                                                      identity=identity,
                                                      **kwargs)
        token = task.get('taskToken')
        if token is None:
            raise PollTimeout("Decider poll timed out")

        events = task['events']

        next_page = task.get('nextPageToken')
        while next_page:
            try:
                task = self.connection.poll_for_decision_task(
                    self.domain.name,
                    task_list=task_list,
                    identity=identity,
                    next_page_token=next_page,
                    **kwargs)
            except boto.exception.SWFResponseError as e:
                if e.error_code == 'UnknownResourceFault':
                    raise DoesNotExistError(
                        "Unable to poll decision task",
                        e.body['message'],
                    )

                raise ResponseError(e.body['message'])

            token = task.get('taskToken')
            if token is None:
                raise PollTimeout("Decider poll timed out")

            events.extend(task['events'])
            next_page = task.get('nextPageToken')

        history = History.from_event_list(events)

        workflow_type = WorkflowType(
            domain=self.domain,
            name=task['workflowType']['name'],
            version=task['workflowType']['version'],
        )
        execution = WorkflowExecution(
            domain=self.domain,
            workflow_id=task['workflowExecution']['workflowId'],
            run_id=task['workflowExecution']['runId'],
            workflow_type=workflow_type,
        )

        # TODO: move history into execution (needs refactoring on WorkflowExecution.history())
        return Response(token=token, history=history, execution=execution)
示例#30
0
    def get(self, name, version, *args, **kwargs):
        """Fetches the Workflow Type with `name` and `version`

        :param  name: name of the workflow type
        :type   name: String

        :param  version: workflow type version
        :type   version: String

        :returns: matched workflow type instance
        :rtype: swf.core.model.workflow.WorkflowType

        A typical Amazon response looks like:

        .. code-block:: json

            {
                "configuration": {
                    "defaultExecutionStartToCloseTimeout": "300",
                    "defaultTaskStartToCloseTimeout": "300",
                    "defaultTaskList": {
                        "name": "None"
                    },
                    "defaultChildPolicy": "TERMINATE"
                },
                "typeInfo": {
                    "status": "REGISTERED",
                    "creationDate": 1364492094.968,
                    "workflowType": {
                        "version": "1",
                        "name": "testW"
                    }
                }
            }
        """
        try:
            response = self.connection.describe_workflow_type(
                self.domain.name, name, version
            )
        except SWFResponseError as e:
            if e.error_code == "UnknownResourceFault":
                raise DoesNotExistError(e.body["message"])

            raise ResponseError(e.body["message"])

        wt_info = response[self._infos]
        wt_config = response["configuration"]

        task_list = kwargs.get("task_list")
        if task_list is None:
            task_list = get_subkey(wt_config, ["defaultTaskList", "name"])

        child_policy = kwargs.get("child_policy")
        if child_policy is None:
            child_policy = wt_config.get("defaultChildPolicy")

        decision_task_timeout = kwargs.get("decision_task_timeout")
        if decision_task_timeout is None:
            decision_task_timeout = wt_config.get("defaultTaskStartToCloseTimeout")

        execution_timeout = kwargs.get("execution_timeout")
        if execution_timeout is None:
            execution_timeout = wt_config.get("defaultExecutionStartToCloseTimeout")

        decision_tasks_timeout = kwargs.get("decision_tasks_timeout")
        if decision_tasks_timeout is None:
            decision_tasks_timeout = wt_config.get("defaultTaskStartToCloseTimeout")

        return self.to_WorkflowType(
            self.domain,
            wt_info,
            task_list=task_list,
            child_policy=child_policy,
            execution_timeout=execution_timeout,
            decision_tasks_timeout=decision_tasks_timeout,
        )