fix call activities to get the form from the process called and added tests to ensure they are working w/ burnettk
This commit is contained in:
parent
5b43326fb6
commit
6eef611095
|
@ -1,5 +1,6 @@
|
|||
"""APIs for dealing with process groups, process models, and process instances."""
|
||||
import json
|
||||
import os
|
||||
import uuid
|
||||
from typing import Any
|
||||
from typing import Dict
|
||||
|
@ -44,6 +45,7 @@ from spiffworkflow_backend.models.process_model import ProcessModelInfo
|
|||
from spiffworkflow_backend.models.process_model import ProcessModelInfoSchema
|
||||
from spiffworkflow_backend.models.spiff_logging import SpiffLoggingModel
|
||||
from spiffworkflow_backend.services.error_handling_service import ErrorHandlingService
|
||||
from spiffworkflow_backend.services.file_system_service import FileSystemService
|
||||
from spiffworkflow_backend.services.message_service import MessageService
|
||||
from spiffworkflow_backend.services.process_instance_processor import (
|
||||
ProcessInstanceProcessor,
|
||||
|
@ -773,9 +775,25 @@ def task_show(process_instance_id: int, task_id: str) -> flask.wrappers.Response
|
|||
form_ui_schema_file_name = properties["formUiSchemaFilename"]
|
||||
task = ProcessInstanceService.spiff_task_to_api_task(spiff_task)
|
||||
task.data = spiff_task.data
|
||||
task.process_name = process_model.id
|
||||
task.process_model_display_name = process_model.display_name
|
||||
|
||||
process_model_with_form = process_model
|
||||
if task.process_name != process_model.primary_process_id:
|
||||
bpmn_file_full_path = (
|
||||
ProcessInstanceProcessor.bpmn_file_full_path_from_bpmn_process_identifier(
|
||||
task.process_name
|
||||
)
|
||||
)
|
||||
relative_path = os.path.relpath(
|
||||
bpmn_file_full_path, start=FileSystemService.root_path()
|
||||
)
|
||||
process_model_relative_path = os.path.dirname(relative_path)
|
||||
process_model_with_form = (
|
||||
ProcessModelService.get_process_model_from_relative_path(
|
||||
process_model_relative_path
|
||||
)
|
||||
)
|
||||
|
||||
if task.type == "UserTask":
|
||||
if not form_schema_file_name:
|
||||
raise (
|
||||
|
@ -789,7 +807,7 @@ def task_show(process_instance_id: int, task_id: str) -> flask.wrappers.Response
|
|||
form_contents = prepare_form_data(
|
||||
form_schema_file_name,
|
||||
task.data,
|
||||
process_model,
|
||||
process_model_with_form,
|
||||
)
|
||||
|
||||
if form_contents:
|
||||
|
@ -799,7 +817,7 @@ def task_show(process_instance_id: int, task_id: str) -> flask.wrappers.Response
|
|||
ui_form_contents = prepare_form_data(
|
||||
form_ui_schema_file_name,
|
||||
task.data,
|
||||
process_model,
|
||||
process_model_with_form,
|
||||
)
|
||||
if ui_form_contents:
|
||||
task.form_ui_schema = ui_form_contents
|
||||
|
|
|
@ -462,7 +462,7 @@ class ProcessInstanceProcessor:
|
|||
|
||||
@staticmethod
|
||||
def backfill_missing_bpmn_process_id_lookup_records(
|
||||
bpmn_process_identifier: None,
|
||||
bpmn_process_identifier: str,
|
||||
) -> Optional[str]:
|
||||
"""Backfill_missing_bpmn_process_id_lookup_records."""
|
||||
process_models = ProcessModelService().get_process_models()
|
||||
|
@ -494,6 +494,34 @@ class ProcessInstanceProcessor:
|
|||
)
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def bpmn_file_full_path_from_bpmn_process_identifier(
|
||||
bpmn_process_identifier: str,
|
||||
) -> str:
|
||||
"""Bpmn_file_full_path_from_bpmn_process_identifier."""
|
||||
bpmn_process_id_lookup = BpmnProcessIdLookup.query.filter_by(
|
||||
bpmn_process_identifier=bpmn_process_identifier
|
||||
).first()
|
||||
bpmn_file_full_path = None
|
||||
if bpmn_process_id_lookup is None:
|
||||
bpmn_file_full_path = ProcessInstanceProcessor.backfill_missing_bpmn_process_id_lookup_records(
|
||||
bpmn_process_identifier
|
||||
)
|
||||
else:
|
||||
bpmn_file_full_path = os.path.join(
|
||||
FileSystemService.root_path(),
|
||||
bpmn_process_id_lookup.bpmn_file_relative_path,
|
||||
)
|
||||
if bpmn_file_full_path is None:
|
||||
raise (
|
||||
ApiError(
|
||||
code="could_not_find_bpmn_process_identifier",
|
||||
message="Could not find the the given bpmn process identifier from any sources: %s"
|
||||
% bpmn_process_identifier,
|
||||
)
|
||||
)
|
||||
return os.path.abspath(bpmn_file_full_path)
|
||||
|
||||
@staticmethod
|
||||
def update_spiff_parser_with_all_process_dependency_files(
|
||||
parser: BpmnDmnParser,
|
||||
|
@ -504,7 +532,7 @@ class ProcessInstanceProcessor:
|
|||
processed_identifiers = set()
|
||||
processor_dependencies = parser.get_process_dependencies()
|
||||
processor_dependencies_new = processor_dependencies - processed_identifiers
|
||||
bpmn_process_identifiers_in_parser = parser.find_all_specs().keys()
|
||||
bpmn_process_identifiers_in_parser = parser.get_process_ids()
|
||||
|
||||
new_bpmn_files = set()
|
||||
for bpmn_process_identifier in processor_dependencies_new:
|
||||
|
@ -513,28 +541,9 @@ class ProcessInstanceProcessor:
|
|||
if bpmn_process_identifier in bpmn_process_identifiers_in_parser:
|
||||
continue
|
||||
|
||||
bpmn_process_id_lookup = BpmnProcessIdLookup.query.filter_by(
|
||||
bpmn_process_identifier=bpmn_process_identifier
|
||||
).first()
|
||||
new_bpmn_file_full_path = None
|
||||
if bpmn_process_id_lookup is None:
|
||||
new_bpmn_file_full_path = ProcessInstanceProcessor.backfill_missing_bpmn_process_id_lookup_records(
|
||||
bpmn_process_identifier
|
||||
)
|
||||
else:
|
||||
new_bpmn_file_full_path = os.path.join(
|
||||
FileSystemService.root_path(),
|
||||
bpmn_process_id_lookup.bpmn_file_relative_path,
|
||||
)
|
||||
if new_bpmn_file_full_path is None:
|
||||
raise (
|
||||
ApiError(
|
||||
code="could_not_find_bpmn_process_identifier",
|
||||
message="Could not find the the given bpmn process identifier from any sources: %s"
|
||||
% bpmn_process_identifier,
|
||||
)
|
||||
)
|
||||
|
||||
new_bpmn_file_full_path = ProcessInstanceProcessor.bpmn_file_full_path_from_bpmn_process_identifier(
|
||||
bpmn_process_identifier
|
||||
)
|
||||
new_bpmn_files.add(new_bpmn_file_full_path)
|
||||
processed_identifiers.add(bpmn_process_identifier)
|
||||
|
||||
|
@ -739,7 +748,7 @@ class ProcessInstanceProcessor:
|
|||
|
||||
db.session.commit()
|
||||
|
||||
def do_engine_steps(self, exit_at: None = None) -> None:
|
||||
def do_engine_steps(self, exit_at: None = None, save: bool = False) -> None:
|
||||
"""Do_engine_steps."""
|
||||
try:
|
||||
self.bpmn_process_instance.refresh_waiting_tasks()
|
||||
|
@ -747,6 +756,9 @@ class ProcessInstanceProcessor:
|
|||
self.process_bpmn_messages()
|
||||
self.queue_waiting_receive_messages()
|
||||
|
||||
if save:
|
||||
self.save()
|
||||
|
||||
except WorkflowTaskExecException as we:
|
||||
raise ApiError.from_workflow_exception("task_error", str(we), we) from we
|
||||
|
||||
|
|
|
@ -102,6 +102,16 @@ class ProcessModelService(FileSystemService):
|
|||
return self.__scan_spec(path, FileSystemService.MASTER_SPECIFICATION)
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def get_process_model_from_relative_path(
|
||||
cls, relative_path: str
|
||||
) -> ProcessModelInfo:
|
||||
"""Get_process_model_from_relative_path."""
|
||||
process_group_identifier = os.path.dirname(relative_path)
|
||||
process_group = cls().get_process_group(process_group_identifier)
|
||||
path = os.path.join(FileSystemService.root_path(), relative_path)
|
||||
return cls().__scan_spec(path, process_group=process_group)
|
||||
|
||||
def get_process_model(
|
||||
self, process_model_id: str, group_id: Optional[str] = None
|
||||
) -> ProcessModelInfo:
|
||||
|
@ -268,7 +278,10 @@ class ProcessModelService(FileSystemService):
|
|||
return process_group
|
||||
|
||||
def __scan_spec(
|
||||
self, path: str, name: str, process_group: Optional[ProcessGroup] = None
|
||||
self,
|
||||
path: str,
|
||||
name: Optional[str] = None,
|
||||
process_group: Optional[ProcessGroup] = None,
|
||||
) -> ProcessModelInfo:
|
||||
"""__scan_spec."""
|
||||
spec_path = os.path.join(path, self.WF_JSON_FILE)
|
||||
|
@ -284,6 +297,12 @@ class ProcessModelService(FileSystemService):
|
|||
message=f"We could not load the process_model from disk with data: {data}",
|
||||
)
|
||||
else:
|
||||
if name is None:
|
||||
raise ApiError(
|
||||
code="missing_name_of_process_model",
|
||||
message="Missing name of process model. It should be given",
|
||||
)
|
||||
|
||||
spec = ProcessModelInfo(
|
||||
id=name,
|
||||
library=False,
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_96f6665" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="3.0.0-dev">
|
||||
<bpmn:process id="Process_bd2e724" isExecutable="true">
|
||||
<bpmn:startEvent id="StartEvent_1">
|
||||
<bpmn:outgoing>Flow_1rcteeq</bpmn:outgoing>
|
||||
</bpmn:startEvent>
|
||||
<bpmn:sequenceFlow id="Flow_1rcteeq" sourceRef="StartEvent_1" targetRef="the_call_activity" />
|
||||
<bpmn:callActivity id="the_call_activity" name="The Call Activity" calledElement="process_to_call">
|
||||
<bpmn:incoming>Flow_1rcteeq</bpmn:incoming>
|
||||
<bpmn:outgoing>Flow_1rid3w7</bpmn:outgoing>
|
||||
</bpmn:callActivity>
|
||||
<bpmn:endEvent id="Event_1w7nqwy">
|
||||
<bpmn:incoming>Flow_1rid3w7</bpmn:incoming>
|
||||
</bpmn:endEvent>
|
||||
<bpmn:sequenceFlow id="Flow_1rid3w7" sourceRef="the_call_activity" targetRef="Event_1w7nqwy" />
|
||||
</bpmn:process>
|
||||
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_bd2e724">
|
||||
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
|
||||
<dc:Bounds x="179" y="159" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Activity_0pmcny7_di" bpmnElement="the_call_activity">
|
||||
<dc:Bounds x="270" y="137" width="100" height="80" />
|
||||
<bpmndi:BPMNLabel />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Event_1w7nqwy_di" bpmnElement="Event_1w7nqwy">
|
||||
<dc:Bounds x="432" y="159" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="Flow_1rcteeq_di" bpmnElement="Flow_1rcteeq">
|
||||
<di:waypoint x="215" y="177" />
|
||||
<di:waypoint x="270" y="177" />
|
||||
</bpmndi:BPMNEdge>
|
||||
<bpmndi:BPMNEdge id="Flow_1rid3w7_di" bpmnElement="Flow_1rid3w7">
|
||||
<di:waypoint x="370" y="177" />
|
||||
<di:waypoint x="432" y="177" />
|
||||
</bpmndi:BPMNEdge>
|
||||
</bpmndi:BPMNPlane>
|
||||
</bpmndi:BPMNDiagram>
|
||||
</bpmn:definitions>
|
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_96f6665" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="3.0.0-dev">
|
||||
<bpmn:process id="process_to_call" name="Process to call" isExecutable="true">
|
||||
<bpmn:startEvent id="StartEvent_1">
|
||||
<bpmn:outgoing>Flow_0ogjqo9</bpmn:outgoing>
|
||||
</bpmn:startEvent>
|
||||
<bpmn:endEvent id="Event_08g7f08">
|
||||
<bpmn:incoming>Flow_0ogjqo9</bpmn:incoming>
|
||||
</bpmn:endEvent>
|
||||
<bpmn:sequenceFlow id="Flow_0ogjqo9" sourceRef="StartEvent_1" targetRef="Event_08g7f08" />
|
||||
</bpmn:process>
|
||||
<bpmndi:BPMNDiagram id="BPMNDiagram_1">
|
||||
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="process_to_call">
|
||||
<bpmndi:BPMNShape id="_BPMNShape_StartEvent_2" bpmnElement="StartEvent_1">
|
||||
<dc:Bounds x="179" y="159" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNShape id="Event_08g7f08_di" bpmnElement="Event_08g7f08">
|
||||
<dc:Bounds x="402" y="159" width="36" height="36" />
|
||||
</bpmndi:BPMNShape>
|
||||
<bpmndi:BPMNEdge id="Flow_0ogjqo9_di" bpmnElement="Flow_0ogjqo9">
|
||||
<di:waypoint x="215" y="177" />
|
||||
<di:waypoint x="402" y="177" />
|
||||
</bpmndi:BPMNEdge>
|
||||
</bpmndi:BPMNPlane>
|
||||
</bpmndi:BPMNDiagram>
|
||||
</bpmn:definitions>
|
|
@ -22,7 +22,23 @@ class TestProcessModel(BaseTest):
|
|||
assert process_model_one.files == []
|
||||
assert process_model_one.libraries == []
|
||||
|
||||
def test_can_run_process_model_with_call_activities(
|
||||
def test_can_run_process_model_with_call_activities_when_in_same_process_model_directory(
|
||||
self, app: Flask, with_db_and_bpmn_file_cleanup: None
|
||||
) -> None:
|
||||
"""Test_can_run_process_model_with_call_activities."""
|
||||
process_model = load_test_spec(
|
||||
"call_activity_test",
|
||||
process_model_source_directory="call_activity_same_directory",
|
||||
)
|
||||
|
||||
process_instance = self.create_process_instance_from_process_model(
|
||||
process_model
|
||||
)
|
||||
processor = ProcessInstanceProcessor(process_instance)
|
||||
processor.do_engine_steps(save=True)
|
||||
assert process_instance.status == "complete"
|
||||
|
||||
def test_can_run_process_model_with_call_activities_when_not_in_same_directory(
|
||||
self, app: Flask, with_db_and_bpmn_file_cleanup: None
|
||||
) -> None:
|
||||
"""Test_can_run_process_model_with_call_activities."""
|
||||
|
@ -47,7 +63,8 @@ class TestProcessModel(BaseTest):
|
|||
process_model
|
||||
)
|
||||
processor = ProcessInstanceProcessor(process_instance)
|
||||
processor.do_engine_steps()
|
||||
processor.do_engine_steps(save=True)
|
||||
assert process_instance.status == "complete"
|
||||
|
||||
def test_can_run_process_model_with_call_activities_when_process_identifier_is_not_in_database(
|
||||
self, app: Flask, with_db_and_bpmn_file_cleanup: None
|
||||
|
@ -78,7 +95,8 @@ class TestProcessModel(BaseTest):
|
|||
# process model when running the process
|
||||
db.session.query(BpmnProcessIdLookup).delete()
|
||||
processor = ProcessInstanceProcessor(process_instance)
|
||||
processor.do_engine_steps()
|
||||
processor.do_engine_steps(save=True)
|
||||
assert process_instance.status == "complete"
|
||||
|
||||
def create_test_process_model(self, id: str, display_name: str) -> ProcessModelInfo:
|
||||
"""Create_test_process_model."""
|
||||
|
|
|
@ -58,7 +58,7 @@ class TestSpecFileService(BaseTest):
|
|||
with pytest.raises(ApiError) as exception:
|
||||
load_test_spec(
|
||||
"call_activity_nested_duplicate",
|
||||
process_model_source_directory="call_activity_nested",
|
||||
process_model_source_directory="call_activity_duplicate",
|
||||
bpmn_file_name="call_activity_nested_duplicate",
|
||||
)
|
||||
assert f"Process id ({bpmn_process_identifier}) has already been used" in str(
|
||||
|
|
Loading…
Reference in New Issue