From 61699b6b5d643b91dae0396958f986b2abec067a Mon Sep 17 00:00:00 2001 From: mike cullerton Date: Tue, 10 Jan 2023 08:44:53 -0500 Subject: [PATCH] Work on System Notification handler --- .../spiffworkflow_backend/config/default.py | 3 + .../services/error_handling_service.py | 123 ++++++++++++------ 2 files changed, 86 insertions(+), 40 deletions(-) diff --git a/spiffworkflow-backend/src/spiffworkflow_backend/config/default.py b/spiffworkflow-backend/src/spiffworkflow_backend/config/default.py index d0d6a401..1a2f7504 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/config/default.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/config/default.py @@ -74,3 +74,6 @@ SPIFF_DATABASE_TYPE = environ.get( SPIFFWORKFLOW_BACKEND_DATABASE_URI = environ.get( "SPIFFWORKFLOW_BACKEND_DATABASE_URI", default=None ) +SYSTEM_NOTIFICATION_PROCESS_MODEL_MESSAGE_ID = environ.get( + "SYSTEM_NOTIFICATION_PROCESS_MODEL_MESSAGE_ID", default="Message_SystemMessageNotification" +) 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 1e8b38f2..1c8e66a3 100644 --- a/spiffworkflow-backend/src/spiffworkflow_backend/services/error_handling_service.py +++ b/spiffworkflow-backend/src/spiffworkflow_backend/services/error_handling_service.py @@ -1,4 +1,9 @@ """Error_handling_service.""" +import json + +from flask import g +from flask import current_app +from flask.wrappers import Response from typing import Any from typing import List from typing import Union @@ -6,9 +11,15 @@ from typing import Union from flask_bpmn.api.api_error import ApiError from flask_bpmn.models.db import db +from spiffworkflow_backend.models.message_model import MessageModel +from spiffworkflow_backend.models.message_triggerable_process_model import ( + MessageTriggerableProcessModel, +) from spiffworkflow_backend.models.process_instance import ProcessInstanceModel +from spiffworkflow_backend.models.process_instance import ProcessInstanceModelSchema from spiffworkflow_backend.models.process_instance import ProcessInstanceStatus from spiffworkflow_backend.services.email_service import EmailService +from spiffworkflow_backend.services.message_service import MessageService from spiffworkflow_backend.services.process_instance_processor import ( ProcessInstanceProcessor, ) @@ -37,6 +48,7 @@ class ErrorHandlingService: process_model = ProcessModelService.get_process_model( _processor.process_model_identifier ) + # First, suspend or fault the instance if process_model.fault_or_suspend_on_exception == "suspend": self.set_instance_status( _processor.process_instance_model.id, @@ -49,57 +61,88 @@ class ErrorHandlingService: ProcessInstanceStatus.error.value, ) + # Second, call the System Notification Process + # Note that this isn't the best way to do this. + # The configs are all in the model. + # Maybe we can move some of this to the notification process, or dmn tables. if len(process_model.exception_notification_addresses) > 0: try: - # some notification method (waku?) - self.handle_email_notification( - _processor, _error, process_model.exception_notification_addresses - ) + self.handle_system_notification(_error, process_model.exception_notification_addresses) except Exception as e: # hmm... what to do if a notification method fails. Probably log, at least print(e) @staticmethod - def hanle_sentry_notification(_error: ApiError, _recipients: List) -> None: - """SentryHandler.""" - ... - - @staticmethod - def handle_email_notification( - processor: ProcessInstanceProcessor, + def handle_system_notification( error: Union[ApiError, Exception], recipients: List, - ) -> None: - """EmailHandler.""" - subject = "Unexpected error in app" - if isinstance(error, ApiError): - content = f"{error.message}" - else: - content = str(error) - content_html = content - - EmailService.add_email( - subject, - "sender@company.com", - recipients, - content, - content_html, - cc=None, - bcc=None, - reply_to=None, - attachment_files=None, + ): + message_payload = { + 'my_var': 'my_value', + 'error': error.__repr__(), + 'recipients': recipients + } + message_identifier = current_app.config["SYSTEM_NOTIFICATION_PROCESS_MODEL_MESSAGE_ID"] + message_model = MessageModel.query.filter_by(identifier=message_identifier).first() + message_triggerable_process_model = ( + MessageTriggerableProcessModel.query.filter_by( + message_model_id=message_model.id + ).first() + ) + process_instance = MessageService.process_message_triggerable_process_model( + message_triggerable_process_model, + message_identifier, + message_payload, + g.user ) - @staticmethod - def handle_waku_notification(_error: ApiError, _recipients: List) -> Any: - """WakuHandler.""" - # class WakuMessage: - # """WakuMessage.""" - # - # payload: str - # contentTopic: str # Optional - # version: int # Optional - # timestamp: int # Optional + return Response( + json.dumps(ProcessInstanceModelSchema().dump(process_instance)), + status=200, + mimetype="application/json", + ) + + # @staticmethod + # def handle_sentry_notification(_error: ApiError, _recipients: List) -> None: + # """SentryHandler.""" + # ... + # + # @staticmethod + # def handle_email_notification( + # processor: ProcessInstanceProcessor, + # error: Union[ApiError, Exception], + # recipients: List, + # ) -> None: + # """EmailHandler.""" + # subject = "Unexpected error in app" + # if isinstance(error, ApiError): + # content = f"{error.message}" + # else: + # content = str(error) + # content_html = content + # + # EmailService.add_email( + # subject, + # "sender@company.com", + # recipients, + # content, + # content_html, + # cc=None, + # bcc=None, + # reply_to=None, + # attachment_files=None, + # ) + # + # @staticmethod + # def handle_waku_notification(_error: ApiError, _recipients: List) -> Any: + # """WakuHandler.""" + # # class WakuMessage: + # # """WakuMessage.""" + # # + # # payload: str + # # contentTopic: str # Optional + # # version: int # Optional + # # timestamp: int # Optional class FailingService: