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:
parent
51b3dc5a35
commit
4ee2a289c3
|
@ -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 ###
|
|
@ -8,5 +8,7 @@ class MessageTriggerableProcessModel(SpiffworkflowBaseDBModel):
|
||||||
id = db.Column(db.Integer, primary_key=True)
|
id = db.Column(db.Integer, primary_key=True)
|
||||||
message_name: str = db.Column(db.String(255), index=True)
|
message_name: str = db.Column(db.String(255), index=True)
|
||||||
process_model_identifier: str = db.Column(db.String(255), nullable=False, 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)
|
updated_at_in_seconds: int = db.Column(db.Integer)
|
||||||
created_at_in_seconds: int = db.Column(db.Integer)
|
created_at_in_seconds: int = db.Column(db.Integer)
|
||||||
|
|
|
@ -310,6 +310,9 @@ class SpecFileService(FileSystemService):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def update_message_trigger_cache(ref: Reference) -> None:
|
def update_message_trigger_cache(ref: Reference) -> None:
|
||||||
"""Assure we know which messages can trigger the start of a process."""
|
"""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:
|
for message_name in ref.start_messages:
|
||||||
message_triggerable_process_model = MessageTriggerableProcessModel.query.filter_by(
|
message_triggerable_process_model = MessageTriggerableProcessModel.query.filter_by(
|
||||||
message_name=message_name,
|
message_name=message_name,
|
||||||
|
@ -318,6 +321,7 @@ class SpecFileService(FileSystemService):
|
||||||
message_triggerable_process_model = MessageTriggerableProcessModel(
|
message_triggerable_process_model = MessageTriggerableProcessModel(
|
||||||
message_name=message_name,
|
message_name=message_name,
|
||||||
process_model_identifier=ref.relative_location,
|
process_model_identifier=ref.relative_location,
|
||||||
|
file_name=ref.file_name,
|
||||||
)
|
)
|
||||||
db.session.add(message_triggerable_process_model)
|
db.session.add(message_triggerable_process_model)
|
||||||
else:
|
else:
|
||||||
|
@ -325,6 +329,12 @@ class SpecFileService(FileSystemService):
|
||||||
raise ProcessModelFileInvalidError(
|
raise ProcessModelFileInvalidError(
|
||||||
f"Message model is already used to start process model {ref.relative_location}"
|
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
|
@staticmethod
|
||||||
def update_correlation_cache(ref: Reference) -> None:
|
def update_correlation_cache(ref: Reference) -> None:
|
||||||
|
|
|
@ -8,6 +8,7 @@ from spiffworkflow_backend.models.process_instance import ProcessInstanceStatus
|
||||||
from spiffworkflow_backend.services.message_service import MessageService
|
from spiffworkflow_backend.services.message_service import MessageService
|
||||||
from spiffworkflow_backend.services.process_instance_processor import ProcessInstanceProcessor
|
from spiffworkflow_backend.services.process_instance_processor import ProcessInstanceProcessor
|
||||||
from spiffworkflow_backend.services.process_instance_service import ProcessInstanceService
|
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.base_test import BaseTest
|
||||||
from tests.spiffworkflow_backend.helpers.test_data import load_test_spec
|
from tests.spiffworkflow_backend.helpers.test_data import load_test_spec
|
||||||
|
@ -252,3 +253,39 @@ class TestMessageService(BaseTest):
|
||||||
assert len(message_instances) == 2
|
assert len(message_instances) == 2
|
||||||
mi_statuses = [mi.status for mi in message_instances]
|
mi_statuses = [mi.status for mi in message_instances]
|
||||||
assert mi_statuses == ["completed", "completed"]
|
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
|
||||||
|
|
Loading…
Reference in New Issue