delete message triggerable processes if they no longer exist within the corresponding file w/ burnettk (#1070)

Co-authored-by: jasquat <jasquat@users.noreply.github.com>
This commit is contained in:
jasquat 2024-02-20 10:44:02 -05:00 committed by GitHub
parent 51b3dc5a35
commit 4ee2a289c3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 83 additions and 0 deletions

View File

@ -0,0 +1,34 @@
"""empty message
Revision ID: c6e246c3c04e
Revises: 6344d90d20fa
Create Date: 2024-02-19 16:41:52.728357
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'c6e246c3c04e'
down_revision = '6344d90d20fa'
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('message_triggerable_process_model', schema=None) as batch_op:
batch_op.add_column(sa.Column('file_name', sa.String(length=255), nullable=True))
batch_op.create_index(batch_op.f('ix_message_triggerable_process_model_file_name'), ['file_name'], unique=False)
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table('message_triggerable_process_model', schema=None) as batch_op:
batch_op.drop_index(batch_op.f('ix_message_triggerable_process_model_file_name'))
batch_op.drop_column('file_name')
# ### end Alembic commands ###

View File

@ -8,5 +8,7 @@ class MessageTriggerableProcessModel(SpiffworkflowBaseDBModel):
id = db.Column(db.Integer, primary_key=True)
message_name: str = db.Column(db.String(255), index=True)
process_model_identifier: str = db.Column(db.String(255), nullable=False, index=True)
file_name: str = db.Column(db.String(255), index=True)
updated_at_in_seconds: int = db.Column(db.Integer)
created_at_in_seconds: int = db.Column(db.Integer)

View File

@ -310,6 +310,9 @@ class SpecFileService(FileSystemService):
@staticmethod
def update_message_trigger_cache(ref: Reference) -> None:
"""Assure we know which messages can trigger the start of a process."""
current_triggerable_processes = MessageTriggerableProcessModel.query.filter_by(
file_name=ref.file_name, process_model_identifier=ref.relative_location
).all()
for message_name in ref.start_messages:
message_triggerable_process_model = MessageTriggerableProcessModel.query.filter_by(
message_name=message_name,
@ -318,6 +321,7 @@ class SpecFileService(FileSystemService):
message_triggerable_process_model = MessageTriggerableProcessModel(
message_name=message_name,
process_model_identifier=ref.relative_location,
file_name=ref.file_name,
)
db.session.add(message_triggerable_process_model)
else:
@ -325,6 +329,12 @@ class SpecFileService(FileSystemService):
raise ProcessModelFileInvalidError(
f"Message model is already used to start process model {ref.relative_location}"
)
elif message_triggerable_process_model.file_name is None:
message_triggerable_process_model.file_name = ref.file_name
db.session.add(message_triggerable_process_model)
current_triggerable_processes.remove(message_triggerable_process_model)
for trigger_pm in current_triggerable_processes:
db.session.delete(trigger_pm)
@staticmethod
def update_correlation_cache(ref: Reference) -> None:

View File

@ -8,6 +8,7 @@ from spiffworkflow_backend.models.process_instance import ProcessInstanceStatus
from spiffworkflow_backend.services.message_service import MessageService
from spiffworkflow_backend.services.process_instance_processor import ProcessInstanceProcessor
from spiffworkflow_backend.services.process_instance_service import ProcessInstanceService
from spiffworkflow_backend.services.spec_file_service import SpecFileService
from tests.spiffworkflow_backend.helpers.base_test import BaseTest
from tests.spiffworkflow_backend.helpers.test_data import load_test_spec
@ -252,3 +253,39 @@ class TestMessageService(BaseTest):
assert len(message_instances) == 2
mi_statuses = [mi.status for mi in message_instances]
assert mi_statuses == ["completed", "completed"]
def test_can_delete_message_start_events_from_database_if_model_no_longer_references_it(
self,
app: Flask,
with_db_and_bpmn_file_cleanup: None,
) -> None:
process_model_without_message_start_event = load_test_spec(
"test_group/sample",
process_model_source_directory="sample",
)
old_message_triggerable_process = MessageTriggerableProcessModel(
message_name="travel_start_test_v2",
process_model_identifier=process_model_without_message_start_event.id,
file_name=process_model_without_message_start_event.primary_file_name,
)
db.session.add(old_message_triggerable_process)
db.session.commit()
message_triggerable_process_model = MessageTriggerableProcessModel.query.filter_by(
message_name="travel_start_test_v2"
).first()
assert message_triggerable_process_model is not None
assert message_triggerable_process_model.process_model_identifier == process_model_without_message_start_event.id
assert process_model_without_message_start_event.primary_file_name is not None
primary_file_contents = SpecFileService.get_data(
process_model_without_message_start_event, process_model_without_message_start_event.primary_file_name
)
SpecFileService.update_file(
process_model_without_message_start_event,
process_model_without_message_start_event.primary_file_name,
primary_file_contents,
)
message_triggerable_process_model = MessageTriggerableProcessModel.query.filter_by(
message_name="travel_start_test_v2"
).first()
assert message_triggerable_process_model is None