def get_amount_of_workloads(self, topic: str, **kwargs) -> int: """ Retrieves count of tasks. By default expects a topic name, but all parameters from the original endpoint may be provided: https://docs.camunda.org/manual/latest/reference/rest/external-task/get-query-count/ """ with self._shared_resources.api_client as api_client: api_instance = openapi_client.ExternalTaskApi(api_client) try: response: CountResultDto = api_instance.get_external_tasks_count( topic_name=topic, **kwargs) except ApiException as e: raise ApiException( f'Failed to count workload for topic "{topic}":\n{e}') logger.info(f'Amount of workloads for "{topic}":\t{response.count}') return response.count
def deploy(self, *args): """Creates a deployment from all given files and uploads them to camunda. Return response from camunda rest api as dictionary. Further documentation: https://docs.camunda.org/manual/7.14/reference/rest/deployment/post-deployment/ By default, this keyword only deploys changed models and filters duplicates. Deployment name is the filename of the first file. Example: | ${response} | *Deploy model from file* | _../bpmn/my_model.bpnm_ | _../forms/my_forms.html_ | """ if not args: raise ValueError( 'Failed deploying model, because no file provided.') if len(args) > 1: # We have to use plain REST then when uploading more than 1 file. return self.deploy_multiple_files(*args) filename = os.path.basename(args[0]) with self._shared_resources.api_client as api_client: api_instance = openapi_client.DeploymentApi(api_client) data = [*args] deployment_name = filename try: response: DeploymentWithDefinitionsDto = api_instance.create_deployment( deploy_changed_only=True, enable_duplicate_filtering=True, deployment_name=deployment_name, data=data) logger.info(f'Response from camunda:\t{response}') except ApiException as e: logger.error(f'Failed to upload {filename}:\n{e}') raise e return response.to_dict()
def get_deployments(self, deployment_id: str = None, **kwargs): """ Retrieves all deployments that match given criteria. All parameters are available from https://docs.camunda.org/manual/latest/reference/rest/deployment/get-query/ Example: | ${list_of_deployments} | get deployments | ${my_deployments_id} | | ${list_of_deployments} | get deployments | id=${my_deployments_id} | | ${list_of_deployments} | get deployments | after=2013-01-23T14:42:45.000+0200 | """ if deployment_id: kwargs['id'] = deployment_id with self._shared_resources.api_client as api_client: api_instance = openapi_client.DeploymentApi(api_client) try: response: List[DeploymentDto] = api_instance.get_deployments( **kwargs) logger.info(f'Response from camunda:\t{response}') except ApiException as e: raise ApiException(f'Failed get deployments:\n{e}') return [r.to_dict() for r in response]
def start_process(self, process_key: str, variables: Dict = None, files: Dict = None, before_activity_id: str = None, after_activity_id: str = None, **kwargs) -> Dict: """ Starts a new process instance from a process definition with given key. variables: _optional_ dictionary like: {'variable name' : 'value'} files: _optional_ dictionary like: {'variable name' : path}. will be attached to variables in Camunda before_activity_id: _optional_ id of activity at which the process starts before. *CANNOT BE USED TOGETHER WITH _after_activity_id_* after_activity_id: _optional_ id of activity at which the process starts after. *CANNOT BE USED TOGETHER WITH _before_activity_id_* Returns response from Camunda as dictionary == Examples == | `start process` | apply for job promotion | _variables_= { 'employee' : 'John Doe', 'permission_for_application_granted' : True} | _files_ = { 'cv' : 'documents/my_life.md'} | _after_activity_id_ = 'Activity_ask_boss_for_persmission' | | `start process` | apply for promotion | business_key=John again | """ if not process_key: raise ValueError( 'Error starting process. No process key provided.') if before_activity_id and after_activity_id: raise AssertionError( '2 activity ids provided. Cannot start before and after an activity.' ) with self._shared_resources.api_client as api_client: api_instance: ProcessDefinitionApi = openapi_client.ProcessDefinitionApi( api_client) openapi_variables = CamundaResources.convert_dict_to_openapi_variables( variables) openapi_files = CamundaResources.convert_file_dict_to_openapi_variables( files) openapi_variables.update(openapi_files) if before_activity_id or after_activity_id: instruction: ProcessInstanceModificationInstructionDto = ProcessInstanceModificationInstructionDto( type='startBeforeActivity' if before_activity_id else 'startAfterActivity', activity_id=before_activity_id if before_activity_id else after_activity_id, ) kwargs.update(start_instructions=[instruction]) start_process_instance_dto: StartProcessInstanceDto = StartProcessInstanceDto( variables=openapi_variables, **kwargs) try: response: ProcessInstanceWithVariablesDto = api_instance.start_process_instance_by_key( key=process_key, start_process_instance_dto=start_process_instance_dto) except ApiException as e: logger.error(f'Failed to start process {process_key}:\n{e}') raise e logger.info(f'Response:\n{response}') return response.to_dict()
def fetch_workload(self, topic: str, async_response_timeout=None, use_priority=None, **kwargs) -> Dict: """ Locks and fetches workloads from camunda on a given topic. Returns a list of variable dictionary. Each dictionary representing 1 workload from a process instance. If a process instance was fetched, the process instance is cached and can be retrieved by keyword `Get recent process instance` The only mandatory parameter for this keyword is *topic* which is the name of the topic to fetch workload from. More parameters can be added from the Camunda documentation: https://docs.camunda.org/manual/7.14/reference/rest/external-task/fetch/ If not provided, this keyword will use a lock_duration of 60000 ms (10 minutes) and set {{deserialize_value=True}} Examples: | ${input_variables} | *Create Dictionary* | _name=Robot_ | | | *start process* | _my_demo_ | _${input_variables}_ | | ${variables} | *fetch and lock workloads* | _first_task_in_demo_ | | | *Dictionary Should Contain Key* | _${variables}_ | _name_ | | | *Should Be Equal As String* | _Robot_ | _${variables}[name]_ | Example deserializing only some variables: | ${input_variables} | *Create Dictionary* | _name=Robot_ | _profession=Framework_ | | | *start process* | _my_demo_ | _${input_variables}_ | | ${variables_of_interest} | *Create List* | _profession_ | | ${variables} | *Fetch Workload* | _first_task_in_demo_ | _variables=${variables_of_interest}_ | | | *Dictionary Should Not Contain Key* | _${variables}_ | _name_ | | | *Dictionary Should Contain Key* | _${variables}_ | _profession_ | | | *Should Be Equal As String* | _Framework_ | _${variables}[profession]_ | """ api_response = [] with self._shared_resources.api_client as api_client: # Create an instance of the API class api_instance = openapi_client.ExternalTaskApi(api_client) if 'lock_duration' not in kwargs: kwargs['lock_duration'] = 60000 if 'deserialize_values' not in kwargs: kwargs['deserialize_values'] = True topic_dto = FetchExternalTaskTopicDto(topic_name=topic, **kwargs) fetch_external_tasks_dto = FetchExternalTasksDto( worker_id=self.WORKER_ID, max_tasks=1, async_response_timeout=async_response_timeout, use_priority=use_priority, topics=[topic_dto]) try: api_response = api_instance.fetch_and_lock( fetch_external_tasks_dto=fetch_external_tasks_dto) logger.info(api_response) except ApiException as e: logger.error( "Exception when calling ExternalTaskApi->fetch_and_lock: %s\n" % e) work_items: List[LockedExternalTaskDto] = api_response if work_items: logger.debug( f'Received {len(work_items)} work_items from camunda engine for topic:\t{topic}' ) else: logger.debug( f'Received no work items from camunda engine for topic:\t{topic}' ) if not work_items: return {} self.FETCH_RESPONSE = work_items[0] variables: Dict[str, VariableValueDto] = self.FETCH_RESPONSE.variables return CamundaResources.convert_openapi_variables_to_dict(variables)