def complete(self, task_id, global_variables, local_variables={}): url = self.get_task_complete_url(task_id) body = { "workerId": self.worker_id, "variables": Variables.format(global_variables), "localVariables": Variables.format(local_variables) } response = requests.post(url, headers=self._get_headers(), json=body, timeout=self.http_timeout_seconds) raise_exception_if_not_ok(response) return response.status_code == HTTPStatus.NO_CONTENT
def test_format_returns_formatted_variables_keeps_already_formatted(self): variables = { "var1": 1, "var2": True, "var3": "string", "var4": { "value": 1 } } formatted_vars = Variables.format(variables) self.assertDictEqual( { "var1": { "value": 1 }, "var2": { "value": True }, "var3": { "value": "string" }, "var4": { "value": 1 } }, formatted_vars)
def correlate_message(self, message_name, process_instance_id=None, tenant_id=None, business_key=None, process_variables=None): """ Correlates a message to the process engine to either trigger a message start event or an intermediate message catching event. :param message_name: :param process_instance_id: :param tenant_id: :param business_key: :param process_variables: :return: response json """ url = f"{self.engine_base_url}/message" body = { "messageName": message_name, "resultEnabled": True, "processVariables": Variables.format(process_variables) if process_variables else None, "processInstanceId": process_instance_id, "tenantId": tenant_id, "withoutTenantId": not tenant_id, "businessKey": business_key, } body = {k: v for k, v in body.items() if v is not None} response = requests.post(url, headers=self._get_headers(), json=body) raise_exception_if_not_ok(response) return response.json()
def test_to_dict_returns_variables_as_dict(self): variables = Variables({ "var1": { "value": 1 }, "var2": { "value": True }, "var3": { "value": "string" } }) self.assertDictEqual({ "var1": 1, "var2": True, "var3": "string" }, variables.to_dict())
def start_process_by_version(self, process_key, version_tag, variables, tenant_id=None, business_key=None): """ Start a process instance with the process_key and specified version tag and variables passed. If multiple versions with same version tag found, it triggers the latest one :param process_key: Mandatory :param version_tag: :param variables: Mandatory - can be empty dict :param tenant_id: Optional :param business_key: Optional :return: response json """ tenant_ids = [tenant_id] if tenant_id else [] process_definitions = self.get_process_definitions(process_key, version_tag, tenant_ids, sort_by="version", sort_order="desc", offset=0, limit=1) if len(process_definitions) == 0: raise Exception( f"cannot start process because no process definitions found " f"for process_key: {process_key}, version_tag: {version_tag} and tenant_id: {tenant_id}" ) process_definition_id = process_definitions[0]['id'] version = process_definitions[0]['version'] if len(process_definitions) > 1: logger.info( f"multiple process definitions found for process_key: {process_key}, " f"version_tag: {version_tag} and tenant_id: {tenant_id}, " f"using latest process_definition_id: {process_definition_id} with version: {version}" ) else: logger.info( f"exactly one process definition found for process_key: {process_key}, " f"version_tag: {version_tag} and tenant_id: {tenant_id}, " f"using process_definition_id: {process_definition_id} with version: {version}" ) url = self.get_start_process_url(process_definition_id) body = {"variables": Variables.format(variables)} if business_key: body["businessKey"] = business_key response = requests.post(url, headers=self._get_headers(), json=body) raise_exception_if_not_ok(response) return response.json()
def test_format_returns_formatted_variables_when_variables_present(self): variables = {"var1": 1, "var2": True, "var3": "string"} formatted_vars = Variables.format(variables) self.assertDictEqual( { "var1": { "value": 1 }, "var2": { "value": True }, "var3": { "value": "string" } }, formatted_vars)
def start_process(self, process_key, variables, tenant_id=None, business_key=None): """ Start a process instance with the process_key and variables passed. :param process_key: Mandatory :param variables: Mandatory - can be empty dict :param tenant_id: Optional :param business_key: Optional :return: response json """ url = self.get_start_process_instance_url(process_key, tenant_id) body = { "variables": Variables.format(variables) } if business_key: body["businessKey"] = business_key response = requests.post(url, headers=self._get_headers(), json=body) raise_exception_if_not_ok(response) return response.json()
def bpmn_failure(self, task_id, error_code, error_message, variables={}): url = self.get_task_bpmn_error_url(task_id) body = { "workerId": self.worker_id, "errorCode": error_code, "errorMessage": error_message, "variables": Variables.format(variables), } if self.is_debug: self._log_with_context( f"trying to report bpmn error with request payload: {body}") resp = requests.post(url, headers=self._get_headers(), json=body, timeout=self.http_timeout_seconds) resp.raise_for_status() return resp.status_code == HTTPStatus.NO_CONTENT
def test_format_returns_empty_dict_when_variables_absent(self): variables = {} self.assertDictEqual({}, Variables.format(variables))
def test_format_returns_empty_dict_when_none_is_passed(self): variables = None self.assertDictEqual({}, Variables.format(variables))
def test_get_variable_returns_value_when_variable_present(self): variables = Variables({"var1": {"value": 1}}) self.assertEqual(1, variables.get_variable("var1"))
class ExternalTask: def __init__(self, context): self._context = context self._variables = Variables(context.get("variables", {})) self._task_result = TaskResult.empty_task_result(task=self) self._extProperties = Properties(context.get("extensionProperties", {})) def get_worker_id(self): return self._context["workerId"] def get_process_instance_id(self): return self._context['processInstanceId'] def get_variables(self): return self._variables.to_dict() def get_extension_properties(self) -> dict: return self._extProperties.to_dict() def get_task_id(self): return self._context["id"] def get_activity_id(self): return self._context["activityId"] def get_topic_name(self): return self._context["topicName"] def get_variable(self, variable_name, with_meta=False): return self._variables.get_variable(variable_name, with_meta=with_meta) def get_extension_property(self, property_name) -> str: return self._extProperties.get_property(property_name) def get_tenant_id(self): return self._context.get("tenantId", None) def get_business_key(self): return self._context.get("businessKey", None) def get_task_result(self): return self._task_result def set_task_result(self, task_result): self._task_result = task_result def complete(self, global_variables={}, local_variables={}): self._task_result = TaskResult.success(self, global_variables, local_variables) return self._task_result def failure(self, error_message, error_details, max_retries, retry_timeout): retries = self._calculate_retries(max_retries) self._task_result = TaskResult.failure(self, error_message=error_message, error_details=error_details, retries=retries, retry_timeout=retry_timeout) return self._task_result def _calculate_retries(self, max_retries): retries = self._context.get("retries", None) retries = int(retries - 1) if retries and retries >= 1 else max_retries return retries def bpmn_error(self, error_code, error_message, variables={}): self._task_result = TaskResult.bpmn_error(self, error_code=error_code, error_message=error_message, variables=variables) return self._task_result def __str__(self): return f"{self._context}"
def test_get_variable_returns_without_meta(self): var1_raw = {"value": 1} variables = Variables({"var1": var1_raw}) self.assertEqual(1, variables.get_variable("var1", False))
def test_get_variable_returns_with_meta(self): var1_raw = {"value": 1} variables = Variables({"var1": var1_raw}) self.assertEqual(var1_raw, variables.get_variable("var1", True))
def __init__(self, context): self._context = context self._variables = Variables(context.get("variables", {})) self._task_result = TaskResult.empty_task_result(task=self) self._extProperties = Properties(context.get("extensionProperties", {}))
def test_get_variable_returns_none_when_variable_absent(self): variables = Variables({}) self.assertIsNone(variables.get_variable("var1"))
def __init__(self, context: Dict[str, str]): self._context = context self.local_variables = Variables() self.global_variables = Variables() self.context_variables = Variables(self._context.get("variables", {}))