Clean up process references when deleting models and groups (#1561)
This commit is contained in:
parent
afd598bb8f
commit
10e9511cfc
|
@ -12,6 +12,7 @@ from flask.wrappers import Response
|
|||
from spiffworkflow_backend.exceptions.api_error import ApiError
|
||||
from spiffworkflow_backend.exceptions.error import NotAuthorizedError
|
||||
from spiffworkflow_backend.exceptions.process_entity_not_found_error import ProcessEntityNotFoundError
|
||||
from spiffworkflow_backend.models.db import db
|
||||
from spiffworkflow_backend.models.process_group import ProcessGroup
|
||||
from spiffworkflow_backend.models.process_group import ProcessGroupSchema
|
||||
from spiffworkflow_backend.routes.process_api_blueprint import _commit_and_push_to_git
|
||||
|
@ -19,6 +20,7 @@ from spiffworkflow_backend.routes.process_api_blueprint import _un_modify_modifi
|
|||
from spiffworkflow_backend.services.authorization_service import AuthorizationService
|
||||
from spiffworkflow_backend.services.process_model_service import ProcessModelService
|
||||
from spiffworkflow_backend.services.process_model_service import ProcessModelWithInstancesNotDeletableError
|
||||
from spiffworkflow_backend.services.spec_file_service import SpecFileService
|
||||
from spiffworkflow_backend.services.user_service import UserService
|
||||
|
||||
|
||||
|
@ -49,6 +51,11 @@ def process_group_delete(modified_process_group_id: str) -> flask.wrappers.Respo
|
|||
|
||||
try:
|
||||
ProcessModelService.process_group_delete(process_group_id)
|
||||
|
||||
# can't do this in the ProcessModelService due to circular imports
|
||||
SpecFileService.clear_caches_for_process_group(process_group_id)
|
||||
db.session.commit()
|
||||
|
||||
except ProcessModelWithInstancesNotDeletableError as exception:
|
||||
raise ApiError(
|
||||
error_code="existing_instances",
|
||||
|
|
|
@ -112,7 +112,12 @@ def process_model_delete(
|
|||
) -> flask.wrappers.Response:
|
||||
process_model_identifier = modified_process_model_identifier.replace(":", "/")
|
||||
try:
|
||||
process_model = _get_process_model(process_model_identifier)
|
||||
ProcessModelService.process_model_delete(process_model_identifier)
|
||||
|
||||
# can't do this in the ProcessModelService due to circular imports
|
||||
SpecFileService.clear_caches_for_process_model(process_model)
|
||||
db.session.commit()
|
||||
except ProcessModelWithInstancesNotDeletableError as exception:
|
||||
raise ApiError(
|
||||
error_code="existing_instances",
|
||||
|
|
|
@ -275,6 +275,36 @@ class SpecFileService(FileSystemService):
|
|||
|
||||
ProcessCallerService.clear_cache_for_process_ids(reference_cache_ids)
|
||||
|
||||
@staticmethod
|
||||
def clear_caches_for_process_group(process_group_id: str) -> None:
|
||||
records = (
|
||||
db.session.query(ReferenceCacheModel)
|
||||
.filter(ReferenceCacheModel.relative_location.like(f"{process_group_id}/%")) # type: ignore
|
||||
.all()
|
||||
)
|
||||
|
||||
reference_cache_ids = []
|
||||
|
||||
for record in records:
|
||||
reference_cache_ids.append(record.id)
|
||||
db.session.delete(record)
|
||||
|
||||
ProcessCallerService.clear_cache_for_process_ids(reference_cache_ids)
|
||||
|
||||
@staticmethod
|
||||
def clear_caches_for_process_model(process_model_info: ProcessModelInfo) -> None:
|
||||
records = (
|
||||
db.session.query(ReferenceCacheModel).filter(ReferenceCacheModel.relative_location == process_model_info.id).all()
|
||||
)
|
||||
|
||||
reference_cache_ids = []
|
||||
|
||||
for record in records:
|
||||
reference_cache_ids.append(record.id)
|
||||
db.session.delete(record)
|
||||
|
||||
ProcessCallerService.clear_cache_for_process_ids(reference_cache_ids)
|
||||
|
||||
@staticmethod
|
||||
def update_process_cache(ref: Reference) -> None:
|
||||
process_id_lookup = (
|
||||
|
|
|
@ -0,0 +1,127 @@
|
|||
from flask.app import Flask
|
||||
from flask.testing import FlaskClient
|
||||
from spiffworkflow_backend.models.task import TaskModel # noqa: F401
|
||||
from spiffworkflow_backend.models.user import UserModel
|
||||
|
||||
from tests.spiffworkflow_backend.helpers.base_test import BaseTest
|
||||
|
||||
|
||||
class TestProcessCallers(BaseTest):
|
||||
def test_references_after_process_model_create(
|
||||
self,
|
||||
app: Flask,
|
||||
client: FlaskClient,
|
||||
with_db_and_bpmn_file_cleanup: None,
|
||||
with_super_admin_user: UserModel,
|
||||
) -> None:
|
||||
self.create_group_and_model_with_bpmn(
|
||||
client=client,
|
||||
user=with_super_admin_user,
|
||||
process_group_id="test_group_two",
|
||||
process_model_id="call_activity_nested",
|
||||
bpmn_file_location="call_activity_nested",
|
||||
)
|
||||
|
||||
response = client.get(
|
||||
"/v1.0/processes",
|
||||
headers=self.logged_in_headers(with_super_admin_user),
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
assert response.json is not None
|
||||
assert isinstance(response.json, list)
|
||||
assert len(response.json) == 4
|
||||
|
||||
response = client.get(
|
||||
"/v1.0/processes/callers/Level2",
|
||||
headers=self.logged_in_headers(with_super_admin_user),
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
assert response.json is not None
|
||||
assert isinstance(response.json, list)
|
||||
assert len(response.json) == 1
|
||||
|
||||
def test_references_after_process_model_delete(
|
||||
self,
|
||||
app: Flask,
|
||||
client: FlaskClient,
|
||||
with_db_and_bpmn_file_cleanup: None,
|
||||
with_super_admin_user: UserModel,
|
||||
) -> None:
|
||||
self.create_group_and_model_with_bpmn(
|
||||
client=client,
|
||||
user=with_super_admin_user,
|
||||
process_group_id="test_group_two",
|
||||
process_model_id="call_activity_nested",
|
||||
bpmn_file_location="call_activity_nested",
|
||||
)
|
||||
|
||||
response = client.delete(
|
||||
"/v1.0/process-models/test_group_two:call_activity_nested",
|
||||
headers=self.logged_in_headers(with_super_admin_user),
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
|
||||
response = client.get(
|
||||
"/v1.0/processes",
|
||||
headers=self.logged_in_headers(with_super_admin_user),
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
assert response.json is not None
|
||||
assert isinstance(response.json, list)
|
||||
assert len(response.json) == 0
|
||||
|
||||
response = client.get(
|
||||
"/v1.0/processes/callers/Level2",
|
||||
headers=self.logged_in_headers(with_super_admin_user),
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
assert response.json is not None
|
||||
assert isinstance(response.json, list)
|
||||
assert len(response.json) == 0
|
||||
|
||||
def test_references_after_process_group_delete(
|
||||
self,
|
||||
app: Flask,
|
||||
client: FlaskClient,
|
||||
with_db_and_bpmn_file_cleanup: None,
|
||||
with_super_admin_user: UserModel,
|
||||
) -> None:
|
||||
self.create_group_and_model_with_bpmn(
|
||||
client=client,
|
||||
user=with_super_admin_user,
|
||||
process_group_id="test_group_two",
|
||||
process_model_id="call_activity_nested",
|
||||
bpmn_file_location="call_activity_nested",
|
||||
)
|
||||
|
||||
response = client.delete(
|
||||
"/v1.0/process-groups/test_group_two",
|
||||
headers=self.logged_in_headers(with_super_admin_user),
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
|
||||
response = client.get(
|
||||
"/v1.0/processes",
|
||||
headers=self.logged_in_headers(with_super_admin_user),
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
assert response.json is not None
|
||||
assert isinstance(response.json, list)
|
||||
assert len(response.json) == 0
|
||||
|
||||
response = client.get(
|
||||
"/v1.0/processes/callers/Level2",
|
||||
headers=self.logged_in_headers(with_super_admin_user),
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
assert response.json is not None
|
||||
assert isinstance(response.json, list)
|
||||
assert len(response.json) == 0
|
Loading…
Reference in New Issue