From c0bbba6f85027a2634b5af85f0bb30f98d9f16cd Mon Sep 17 00:00:00 2001 From: Dan Date: Fri, 24 Feb 2023 15:02:03 -0500 Subject: [PATCH] run_pyl --- .../models/correlation_property_cache.py | 4 -- .../models/message_instance.py | 49 ++++++++++++------- .../services/error_handling_service.py | 2 +- .../services/process_instance_processor.py | 6 +-- .../services/spec_file_service.py | 26 +++++----- .../unit/test_message_service.py | 15 ++++-- 6 files changed, 58 insertions(+), 44 deletions(-) diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/models/correlation_property_cache.py b/spiffworkflow-backend/src/spiffworkflow_backend/models/correlation_property_cache.py index 558c5eaf..dd311b93 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/models/correlation_property_cache.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/models/correlation_property_cache.py @@ -1,12 +1,8 @@ """Message_correlation.""" from dataclasses import dataclass -from sqlalchemy import ForeignKey -from sqlalchemy.orm import relationship - from spiffworkflow_backend.models.db import db from spiffworkflow_backend.models.db import SpiffworkflowBaseDBModel -from spiffworkflow_backend.models.message_instance import MessageInstanceModel @dataclass diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/models/message_instance.py b/spiffworkflow-backend/src/spiffworkflow_backend/models/message_instance.py index 95f687a3..6443f149 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/models/message_instance.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/models/message_instance.py @@ -51,7 +51,8 @@ class MessageInstanceModel(SpiffworkflowBaseDBModel): message_type: str = db.Column(db.String(20), nullable=False) # Only Send Messages have a payload payload: dict = db.Column(db.JSON) - correlation_keys: dict = db.Column(db.JSON) # The correlation keys of the process at the time the message was created. + # The correlation keys of the process at the time the message was created. + correlation_keys: dict = db.Column(db.JSON) status: str = db.Column(db.String(20), nullable=False, default="ready") user_id: int = db.Column(ForeignKey(UserModel.id), nullable=False) # type: ignore user = relationship("UserModel") @@ -75,16 +76,15 @@ class MessageInstanceModel(SpiffworkflowBaseDBModel): """Validate_status.""" return self.validate_enum_field(key, value, MessageStatuses) - def correlates( - self, other: Any, expression_engine: PythonScriptEngine - ) -> bool: - """ Returns true if the this Message correlates with the given message. + def correlates(self, other: Any, expression_engine: PythonScriptEngine) -> bool: + """Returns true if the this Message correlates with the given message. - This must be a 'receive' message, and the other must be a 'send' or vice/versa. We evaluate - the other messages payload and run our correlation's retrieval expressions against it, then - compare it against our expected values (as stored in this messages' correlation_keys) - IF we don't have an expected value, we accept any non-error result from the retrieval - expression. """ + This must be a 'receive' message, and the other must be a 'send' or vice/versa. + If both messages have identical correlation_keys, they are a match. Otherwise + we check through this messages correlation properties and use the retrieval expressions + to extract the correlation keys from the send's payload, and verify that these + match up with correlation keys on this message. + """ if self.is_send() and other.is_receive(): # Flip the call. return other.correlates(self, expression_engine) # type: ignore @@ -93,33 +93,44 @@ class MessageInstanceModel(SpiffworkflowBaseDBModel): return False if not self.is_receive(): return False - if isinstance(self.correlation_keys, dict) and self.correlation_keys == other.correlation_keys: + if ( + isinstance(self.correlation_keys, dict) + and self.correlation_keys == other.correlation_keys + ): # We know we have a match, and we can just return if we don't have to figure out the key return True # Loop over the receives' correlation keys - if any of the keys fully match, then we match. for expected_values in self.correlation_keys.values(): - if self.payload_matches_expected_values(other.payload, expected_values, expression_engine): + if self.payload_matches_expected_values( + other.payload, expected_values, expression_engine + ): return True return False - def is_receive(self): + def is_receive(self) -> bool: return self.message_type == MessageTypes.receive.value - def is_send(self): + def is_send(self) -> bool: return self.message_type == MessageTypes.send.value def payload_matches_expected_values( - self, payload: dict, - expected_values: dict, - expression_engine: PythonScriptEngine) -> bool: + self, + payload: dict, + expected_values: dict, + expression_engine: PythonScriptEngine, + ) -> bool: """Compares the payload of a 'send' message against a single correlation key's expected values.""" for correlation_key in self.correlation_rules: expected_value = expected_values.get(correlation_key.name, None) - if expected_value is None: # This key is not required for this instance to match. + if ( + expected_value is None + ): # This key is not required for this instance to match. continue try: - result = expression_engine._evaluate(correlation_key.retrieval_expression, payload) + result = expression_engine._evaluate( + correlation_key.retrieval_expression, payload + ) except Exception: # the failure of a payload evaluation may not mean that matches for these # message instances can't happen with other messages. So don't error up. diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/services/error_handling_service.py b/spiffworkflow-backend/src/spiffworkflow_backend/services/error_handling_service.py index 56b3f547..f1d7f1bc 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/services/error_handling_service.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/services/error_handling_service.py @@ -94,7 +94,7 @@ class ErrorHandlingService: message_type="send", name=message_name, payload=message_payload, - user_id=g.user.id + user_id=g.user.id, ) db.session.add(message_instance) db.session.commit() diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/services/process_instance_processor.py b/spiffworkflow-backend/src/spiffworkflow_backend/services/process_instance_processor.py index 51f6ba81..16652a83 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/services/process_instance_processor.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/services/process_instance_processor.py @@ -62,7 +62,7 @@ from spiffworkflow_backend.models.human_task import HumanTaskModel from spiffworkflow_backend.models.human_task_user import HumanTaskUserModel from spiffworkflow_backend.models.message_instance import MessageInstanceModel from spiffworkflow_backend.models.message_instance_correlation import ( - MessageInstanceCorrelationRuleModel + MessageInstanceCorrelationRuleModel, ) from spiffworkflow_backend.models.process_instance import ProcessInstanceModel from spiffworkflow_backend.models.process_instance import ProcessInstanceStatus @@ -1352,7 +1352,7 @@ class ProcessInstanceProcessor: message_type="send", name=bpmn_message.name, payload=bpmn_message.payload, - correlation_keys=self.bpmn_process_instance.correlations + correlation_keys=self.bpmn_process_instance.correlations, ) db.session.add(message_instance) db.session.commit() @@ -1382,7 +1382,7 @@ class ProcessInstanceProcessor: user_id=self.process_instance_model.process_initiator_id, message_type="receive", name=event["name"], - correlation_keys=self.bpmn_process_instance.correlations + correlation_keys=self.bpmn_process_instance.correlations, ) for correlation_property in event["value"]: message_correlation = MessageInstanceCorrelationRuleModel( diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/services/spec_file_service.py b/spiffworkflow-backend/src/spiffworkflow_backend/services/spec_file_service.py index 281db4ee..4a36fe11 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/services/spec_file_service.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/services/spec_file_service.py @@ -8,7 +8,9 @@ from typing import Optional from lxml import etree # type: ignore from SpiffWorkflow.bpmn.parser.BpmnParser import BpmnValidator # type: ignore -from spiffworkflow_backend.models.correlation_property_cache import CorrelationPropertyCache +from spiffworkflow_backend.models.correlation_property_cache import ( + CorrelationPropertyCache, +) from spiffworkflow_backend.models.db import db from spiffworkflow_backend.models.file import File from spiffworkflow_backend.models.file import FileType @@ -375,29 +377,27 @@ class SpecFileService(FileSystemService): def update_correlation_cache(ref: SpecReference) -> None: """Update_correlation_cache.""" for name in ref.correlations.keys(): - correlation_property_retrieval_expressions = ref.correlations[ - name - ]["retrieval_expressions"] + correlation_property_retrieval_expressions = ref.correlations[name][ + "retrieval_expressions" + ] for cpre in correlation_property_retrieval_expressions: message_name = ref.messages.get(cpre["messageRef"], None) retrieval_expression = cpre["expression"] process_model_id = ref.process_model_id - existing = ( - CorrelationPropertyCache.query.filter_by( - name=name, - message_name=message_name, - process_model_id=process_model_id, - retrieval_expression=retrieval_expression - ).first() - ) + existing = CorrelationPropertyCache.query.filter_by( + name=name, + message_name=message_name, + process_model_id=process_model_id, + retrieval_expression=retrieval_expression, + ).first() if existing is None: new_cache = CorrelationPropertyCache( name=name, message_name=message_name, process_model_id=process_model_id, - retrieval_expression=retrieval_expression + retrieval_expression=retrieval_expression, ) db.session.add(new_cache) db.session.commit() diff --git a/spiffworkflow-backend/tests/spiffworkflow_backend/unit/test_message_service.py b/spiffworkflow-backend/tests/spiffworkflow_backend/unit/test_message_service.py index 986951e9..9848d3c3 100644 --- a/spiffworkflow-backend/tests/spiffworkflow_backend/unit/test_message_service.py +++ b/spiffworkflow-backend/tests/spiffworkflow_backend/unit/test_message_service.py @@ -105,7 +105,9 @@ class TestMessageService(BaseTest): ) # Now start the main process - self.start_sender_process(client, with_super_admin_user, "test_between_processes") + self.start_sender_process( + client, with_super_admin_user, "test_between_processes" + ) self.assure_a_message_was_sent() # This is typically called in a background cron process, so we will manually call it @@ -145,7 +147,10 @@ class TestMessageService(BaseTest): assert message_receiver_process.status == "complete" def start_sender_process( - self, client: FlaskClient, with_super_admin_user: UserModel, group_name:str = "test_group" + self, + client: FlaskClient, + with_super_admin_user: UserModel, + group_name: str = "test_group", ) -> None: process_group_id = group_name self.create_process_group( @@ -186,7 +191,7 @@ class TestMessageService(BaseTest): assert len(send_messages) == 1 send_message = send_messages[0] assert ( - send_message.payload == self.payload + send_message.payload == self.payload ), "The send message should match up with the payload" assert send_message.name == "Request Approval" assert send_message.status == "ready" @@ -208,7 +213,9 @@ class TestMessageService(BaseTest): ) -> None: # Correlation Properties should match up po_curr = next(c for c in message.correlation_rules if c.name == "po_number") - customer_curr = next(c for c in message.correlation_rules if c.name == "customer_id") + customer_curr = next( + c for c in message.correlation_rules if c.name == "customer_id" + ) assert po_curr is not None assert customer_curr is not None