Show callers for non primary files (#334)

* WIP - working with multiple process ids, need to return a file's process ids

* Send bpmn process ids back with bpmn files

* Getting ./bin/pyl to pass

* Fix up unit test

* Wire up the front end

* Pre pr cleanup
This commit is contained in:
jbirddog 2023-06-23 02:15:23 -04:00 committed by GitHub
parent 2afd49a3e4
commit 2c99e17381
10 changed files with 35 additions and 18 deletions

View File

@ -633,14 +633,17 @@ paths:
schema:
type: string
/processes/callers:
/processes/callers/{bpmn_process_identifiers}:
parameters:
- name: bpmn_process_identifier
in: query
- name: bpmn_process_identifiers
in: path
required: true
description: the bpmn process identifier/id (not the name with spaces and not the process model identifier)
description: the bpmn process identifiers/ids (not the names with spaces and not the process model identifiers)
schema:
type: array
items:
type: string
minItems: 1
get:
operationId: spiffworkflow_backend.routes.process_api_blueprint.process_caller_list
summary:

View File

@ -70,6 +70,7 @@ class File:
references: list[SpecReference] | None = None
file_contents: bytes | None = None
process_model_id: str | None = None
bpmn_process_ids: list[str] | None = None
file_contents_hash: str | None = None
def __post_init__(self) -> None:

View File

@ -68,8 +68,8 @@ def process_list() -> Any:
return SpecReferenceSchema(many=True).dump(references)
def process_caller_list(bpmn_process_identifier: str) -> Any:
callers = ProcessCallerService.callers(bpmn_process_identifier)
def process_caller_list(bpmn_process_identifiers: list[str]) -> Any:
callers = ProcessCallerService.callers(bpmn_process_identifiers)
references = (
SpecReferenceCache.query.filter_by(type="process").filter(SpecReferenceCache.identifier.in_(callers)).all()
)

View File

@ -16,6 +16,7 @@ from werkzeug.datastructures import FileStorage
from spiffworkflow_backend.exceptions.api_error import ApiError
from spiffworkflow_backend.interfaces import IdToProcessGroupMapping
from spiffworkflow_backend.models.file import FileType
from spiffworkflow_backend.models.process_group import ProcessGroup
from spiffworkflow_backend.models.process_instance_report import ProcessInstanceReportModel
from spiffworkflow_backend.models.process_model import ProcessModelInfo
@ -290,6 +291,10 @@ def process_model_file_show(modified_process_model_identifier: str, file_name: s
file_contents_hash = sha256(file_contents).hexdigest()
file.file_contents_hash = file_contents_hash
file.process_model_id = process_model.id
if file.type == FileType.bpmn.value:
file.bpmn_process_ids = SpecFileService.get_bpmn_process_ids_for_file_contents(file_contents)
return make_response(jsonify(file), 200)

View File

@ -30,10 +30,10 @@ class ProcessCallerService:
db.session.commit()
@staticmethod
def callers(process_id: str) -> list[str]:
def callers(process_ids: list[str]) -> list[str]:
records = (
db.session.query(ProcessCallerCacheModel)
.filter(ProcessCallerCacheModel.process_identifier == process_id)
.filter(ProcessCallerCacheModel.process_identifier.in_(process_ids))
.all()
)
return list({r.calling_process_identifier for r in records})
return sorted({r.calling_process_identifier for r in records})

View File

@ -77,6 +77,12 @@ class SpecFileService(FileSystemService):
etree_xml_parser = etree.XMLParser(resolve_entities=False)
return etree.fromstring(binary_data, parser=etree_xml_parser) # noqa: S320
@classmethod
def get_bpmn_process_ids_for_file_contents(cls, binary_data: bytes) -> list[str]:
parser = MyCustomParser()
parser.add_bpmn_xml(cls.get_etree_from_xml_bytes(binary_data))
return list(parser.process_parsers.keys())
@classmethod
def get_references_for_file_contents(
cls, process_model_info: ProcessModelInfo, file_name: str, binary_data: bytes

View File

@ -565,7 +565,7 @@ class TestProcessApi(BaseTest):
# get the results
response = client.get(
"/v1.0/processes/callers?bpmn_process_identifier=Level2",
"/v1.0/processes/callers/Level2",
headers=self.logged_in_headers(with_super_admin_user),
)
assert response.json is not None

View File

@ -110,19 +110,19 @@ class TestProcessCallerService(BaseTest):
assert ProcessCallerService.count() == 2
def test_can_return_no_callers_when_no_records(self, with_no_process_callers: None) -> None:
assert ProcessCallerService.callers("bob") == []
assert ProcessCallerService.callers(["bob"]) == []
def test_can_return_no_callers_when_process_id_is_unknown(self, with_multiple_process_callers: None) -> None:
assert ProcessCallerService.callers("bob") == []
assert ProcessCallerService.callers(["bob"]) == []
def test_can_return_single_caller(self, with_single_process_caller: None) -> None:
assert ProcessCallerService.callers("called_once") == ["one_caller"]
assert ProcessCallerService.callers(["called_once"]) == ["one_caller"]
def test_can_return_mulitple_callers(self, with_multiple_process_callers: None) -> None:
callers = sorted(ProcessCallerService.callers("called_many"))
callers = sorted(ProcessCallerService.callers(["called_many"]))
assert callers == ["one_caller", "three_caller", "two_caller"]
def test_can_return_single_caller_when_there_are_other_process_ids(
self, with_single_process_caller: None, with_multiple_process_callers: None
) -> None:
assert ProcessCallerService.callers("called_once") == ["one_caller"]
assert ProcessCallerService.callers(["called_once"]) == ["one_caller"]

View File

@ -124,6 +124,7 @@ export interface ProcessFile {
type: string;
file_contents?: string;
file_contents_hash?: string;
bpmn_process_ids?: string[];
}
export interface ProcessInstanceMetadata {

View File

@ -171,9 +171,10 @@ export default function ProcessModelEditDiagram() {
}, [processModelPath, params]);
useEffect(() => {
if (processModel !== null) {
const bpmn_process_ids = processModelFile?.bpmn_process_ids;
if (processModel !== null && bpmn_process_ids) {
HttpService.makeCallToBackend({
path: `/processes/callers?bpmn_process_identifier=${processModel.primary_process_id}`,
path: `/processes/callers/${bpmn_process_ids.join(',')}`,
successCallback: setCallers,
});
}