do not allow sending messages to terminated and suspended process instances w/ burnettk
This commit is contained in:
parent
acef4bae07
commit
0bf232d92b
|
@ -1820,7 +1820,7 @@ paths:
|
||||||
post:
|
post:
|
||||||
tags:
|
tags:
|
||||||
- Messages
|
- Messages
|
||||||
operationId: spiffworkflow_backend.routes.messages_controller.message_start
|
operationId: spiffworkflow_backend.routes.messages_controller.message_send
|
||||||
summary: Instantiate and run a given process model with a message start event matching given identifier
|
summary: Instantiate and run a given process model with a message start event matching given identifier
|
||||||
requestBody:
|
requestBody:
|
||||||
content:
|
content:
|
||||||
|
|
|
@ -19,6 +19,7 @@ from spiffworkflow_backend.models.message_triggerable_process_model import (
|
||||||
)
|
)
|
||||||
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
|
from spiffworkflow_backend.models.process_instance import ProcessInstanceModel
|
||||||
from spiffworkflow_backend.models.process_instance import ProcessInstanceModelSchema
|
from spiffworkflow_backend.models.process_instance import ProcessInstanceModelSchema
|
||||||
|
from spiffworkflow_backend.models.process_instance import ProcessInstanceStatus
|
||||||
from spiffworkflow_backend.routes.process_api_blueprint import (
|
from spiffworkflow_backend.routes.process_api_blueprint import (
|
||||||
_find_process_instance_by_id_or_raise,
|
_find_process_instance_by_id_or_raise,
|
||||||
)
|
)
|
||||||
|
@ -90,7 +91,7 @@ def message_instance_list(
|
||||||
# payload: dict,
|
# payload: dict,
|
||||||
# process_instance_id: Optional[int],
|
# process_instance_id: Optional[int],
|
||||||
# }
|
# }
|
||||||
def message_start(
|
def message_send(
|
||||||
message_identifier: str,
|
message_identifier: str,
|
||||||
body: Dict[str, Any],
|
body: Dict[str, Any],
|
||||||
) -> flask.wrappers.Response:
|
) -> flask.wrappers.Response:
|
||||||
|
@ -121,6 +122,26 @@ def message_start(
|
||||||
body["process_instance_id"]
|
body["process_instance_id"]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if process_instance.status == ProcessInstanceStatus.suspended.value:
|
||||||
|
raise ApiError(
|
||||||
|
error_code="process_instance_is_suspended",
|
||||||
|
message=(
|
||||||
|
f"Process Instance '{process_instance.id}' is suspended and cannot"
|
||||||
|
" accept messages.'"
|
||||||
|
),
|
||||||
|
status_code=400,
|
||||||
|
)
|
||||||
|
|
||||||
|
if process_instance.status == ProcessInstanceStatus.terminated.value:
|
||||||
|
raise ApiError(
|
||||||
|
error_code="process_instance_is_terminated",
|
||||||
|
message=(
|
||||||
|
f"Process Instance '{process_instance.id}' is terminated and cannot"
|
||||||
|
" accept messages.'"
|
||||||
|
),
|
||||||
|
status_code=400,
|
||||||
|
)
|
||||||
|
|
||||||
message_instance = MessageInstanceModel.query.filter_by(
|
message_instance = MessageInstanceModel.query.filter_by(
|
||||||
process_instance_id=process_instance.id,
|
process_instance_id=process_instance.id,
|
||||||
message_model_id=message_model.id,
|
message_model_id=message_model.id,
|
||||||
|
|
|
@ -1296,16 +1296,16 @@ class TestProcessApi(BaseTest):
|
||||||
xml_file_contents = f_open.read()
|
xml_file_contents = f_open.read()
|
||||||
assert show_response.json["bpmn_xml_file_contents"] == xml_file_contents
|
assert show_response.json["bpmn_xml_file_contents"] == xml_file_contents
|
||||||
|
|
||||||
def test_message_start_when_starting_process_instance(
|
def test_message_send_when_starting_process_instance(
|
||||||
self,
|
self,
|
||||||
app: Flask,
|
app: Flask,
|
||||||
client: FlaskClient,
|
client: FlaskClient,
|
||||||
with_db_and_bpmn_file_cleanup: None,
|
with_db_and_bpmn_file_cleanup: None,
|
||||||
with_super_admin_user: UserModel,
|
with_super_admin_user: UserModel,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test_message_start_when_starting_process_instance."""
|
"""Test_message_send_when_starting_process_instance."""
|
||||||
# ensure process model is loaded
|
# ensure process model is loaded
|
||||||
process_group_id = "test_message_start"
|
process_group_id = "test_message_send"
|
||||||
process_model_id = "message_receiver"
|
process_model_id = "message_receiver"
|
||||||
bpmn_file_name = "message_receiver.bpmn"
|
bpmn_file_name = "message_receiver.bpmn"
|
||||||
bpmn_file_location = "message_send_one_conversation"
|
bpmn_file_location = "message_send_one_conversation"
|
||||||
|
@ -1345,15 +1345,15 @@ class TestProcessApi(BaseTest):
|
||||||
assert process_instance_data
|
assert process_instance_data
|
||||||
assert process_instance_data["the_payload"] == payload
|
assert process_instance_data["the_payload"] == payload
|
||||||
|
|
||||||
def test_message_start_when_providing_message_to_running_process_instance(
|
def test_message_send_when_providing_message_to_running_process_instance(
|
||||||
self,
|
self,
|
||||||
app: Flask,
|
app: Flask,
|
||||||
client: FlaskClient,
|
client: FlaskClient,
|
||||||
with_db_and_bpmn_file_cleanup: None,
|
with_db_and_bpmn_file_cleanup: None,
|
||||||
with_super_admin_user: UserModel,
|
with_super_admin_user: UserModel,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test_message_start_when_providing_message_to_running_process_instance."""
|
"""Test_message_send_when_providing_message_to_running_process_instance."""
|
||||||
process_group_id = "test_message_start"
|
process_group_id = "test_message_send"
|
||||||
process_model_id = "message_sender"
|
process_model_id = "message_sender"
|
||||||
bpmn_file_name = "message_sender.bpmn"
|
bpmn_file_name = "message_sender.bpmn"
|
||||||
bpmn_file_location = "message_send_one_conversation"
|
bpmn_file_location = "message_send_one_conversation"
|
||||||
|
@ -1412,6 +1412,105 @@ class TestProcessApi(BaseTest):
|
||||||
assert process_instance_data
|
assert process_instance_data
|
||||||
assert process_instance_data["the_payload"] == payload
|
assert process_instance_data["the_payload"] == payload
|
||||||
|
|
||||||
|
def test_message_send_errors_when_providing_message_to_suspended_process_instance(
|
||||||
|
self,
|
||||||
|
app: Flask,
|
||||||
|
client: FlaskClient,
|
||||||
|
with_db_and_bpmn_file_cleanup: None,
|
||||||
|
with_super_admin_user: UserModel,
|
||||||
|
) -> None:
|
||||||
|
"""Test_message_send_when_providing_message_to_running_process_instance."""
|
||||||
|
process_group_id = "test_message_send"
|
||||||
|
process_model_id = "message_sender"
|
||||||
|
bpmn_file_name = "message_sender.bpmn"
|
||||||
|
bpmn_file_location = "message_send_one_conversation"
|
||||||
|
process_model_identifier = self.create_group_and_model_with_bpmn(
|
||||||
|
client,
|
||||||
|
with_super_admin_user,
|
||||||
|
process_group_id=process_group_id,
|
||||||
|
process_model_id=process_model_id,
|
||||||
|
bpmn_file_name=bpmn_file_name,
|
||||||
|
bpmn_file_location=bpmn_file_location,
|
||||||
|
)
|
||||||
|
|
||||||
|
message_model_identifier = "message_response"
|
||||||
|
payload = {
|
||||||
|
"the_payload": {
|
||||||
|
"topica": "the_payload.topica_string",
|
||||||
|
"topicb": "the_payload.topicb_string",
|
||||||
|
"andThis": "another_item_non_key",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
response = self.create_process_instance_from_process_model_id_with_api(
|
||||||
|
client,
|
||||||
|
process_model_identifier,
|
||||||
|
self.logged_in_headers(with_super_admin_user),
|
||||||
|
)
|
||||||
|
assert response.json is not None
|
||||||
|
process_instance_id = response.json["id"]
|
||||||
|
|
||||||
|
response = client.post(
|
||||||
|
f"/v1.0/process-instances/{self.modify_process_identifier_for_path_param(process_model_identifier)}/{process_instance_id}/run",
|
||||||
|
headers=self.logged_in_headers(with_super_admin_user),
|
||||||
|
)
|
||||||
|
|
||||||
|
assert response.status_code == 200
|
||||||
|
assert response.json is not None
|
||||||
|
|
||||||
|
process_instance = ProcessInstanceModel.query.filter_by(
|
||||||
|
id=process_instance_id
|
||||||
|
).first()
|
||||||
|
processor = ProcessInstanceProcessor(process_instance)
|
||||||
|
|
||||||
|
processor.suspend()
|
||||||
|
response = client.post(
|
||||||
|
f"/v1.0/messages/{message_model_identifier}",
|
||||||
|
content_type="application/json",
|
||||||
|
headers=self.logged_in_headers(with_super_admin_user),
|
||||||
|
data=json.dumps(
|
||||||
|
{"payload": payload, "process_instance_id": process_instance_id}
|
||||||
|
),
|
||||||
|
)
|
||||||
|
assert response.status_code == 400
|
||||||
|
assert response.json
|
||||||
|
assert response.json["error_code"] == "process_instance_is_suspended"
|
||||||
|
|
||||||
|
processor.resume()
|
||||||
|
response = client.post(
|
||||||
|
f"/v1.0/messages/{message_model_identifier}",
|
||||||
|
content_type="application/json",
|
||||||
|
headers=self.logged_in_headers(with_super_admin_user),
|
||||||
|
data=json.dumps(
|
||||||
|
{"payload": payload, "process_instance_id": process_instance_id}
|
||||||
|
),
|
||||||
|
)
|
||||||
|
assert response.status_code == 200
|
||||||
|
json_data = response.json
|
||||||
|
assert json_data
|
||||||
|
assert json_data["status"] == "complete"
|
||||||
|
process_instance_id = json_data["id"]
|
||||||
|
process_instance = ProcessInstanceModel.query.filter_by(
|
||||||
|
id=process_instance_id
|
||||||
|
).first()
|
||||||
|
assert process_instance
|
||||||
|
processor = ProcessInstanceProcessor(process_instance)
|
||||||
|
process_instance_data = processor.get_data()
|
||||||
|
assert process_instance_data
|
||||||
|
assert process_instance_data["the_payload"] == payload
|
||||||
|
|
||||||
|
processor.terminate()
|
||||||
|
response = client.post(
|
||||||
|
f"/v1.0/messages/{message_model_identifier}",
|
||||||
|
content_type="application/json",
|
||||||
|
headers=self.logged_in_headers(with_super_admin_user),
|
||||||
|
data=json.dumps(
|
||||||
|
{"payload": payload, "process_instance_id": process_instance_id}
|
||||||
|
),
|
||||||
|
)
|
||||||
|
assert response.status_code == 400
|
||||||
|
assert response.json
|
||||||
|
assert response.json["error_code"] == "process_instance_is_terminated"
|
||||||
|
|
||||||
def test_process_instance_can_be_terminated(
|
def test_process_instance_can_be_terminated(
|
||||||
self,
|
self,
|
||||||
app: Flask,
|
app: Flask,
|
||||||
|
@ -1419,9 +1518,9 @@ class TestProcessApi(BaseTest):
|
||||||
with_db_and_bpmn_file_cleanup: None,
|
with_db_and_bpmn_file_cleanup: None,
|
||||||
with_super_admin_user: UserModel,
|
with_super_admin_user: UserModel,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test_message_start_when_providing_message_to_running_process_instance."""
|
"""Test_message_send_when_providing_message_to_running_process_instance."""
|
||||||
# this task will wait on a catch event
|
# this task will wait on a catch event
|
||||||
process_group_id = "test_message_start"
|
process_group_id = "test_message_send"
|
||||||
process_model_id = "message_sender"
|
process_model_id = "message_sender"
|
||||||
bpmn_file_name = "message_sender.bpmn"
|
bpmn_file_name = "message_sender.bpmn"
|
||||||
bpmn_file_location = "message_send_one_conversation"
|
bpmn_file_location = "message_send_one_conversation"
|
||||||
|
@ -2188,7 +2287,7 @@ class TestProcessApi(BaseTest):
|
||||||
with_super_admin_user: UserModel,
|
with_super_admin_user: UserModel,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test_can_get_message_instances_by_process_instance_id."""
|
"""Test_can_get_message_instances_by_process_instance_id."""
|
||||||
process_group_id = "test_message_start"
|
process_group_id = "test_message_send"
|
||||||
process_model_id = "message_receiver"
|
process_model_id = "message_receiver"
|
||||||
bpmn_file_name = "message_receiver.bpmn"
|
bpmn_file_name = "message_receiver.bpmn"
|
||||||
bpmn_file_location = "message_send_one_conversation"
|
bpmn_file_location = "message_send_one_conversation"
|
||||||
|
|
Loading…
Reference in New Issue