Edit Order Notification ECS Task

Dependencies

SSM Attribute

See SSM Key

Configuration (from config service)

Attribute

Description

storepick-edit-order-notification.json

Edit Order Notification application configuration

Variables in Edit Order Notification application config:

Variable

Use

EON_LOGGING_CONFIG.disable_existing_loggers

Must be included and set to false so that all logs are shown and loggers do not overwrite each other

EON_LOGGING_CONFIG.formatters.monitoring

Must have the value shown below in order for metric monitoring (e.g. datadog to run correctly if used)

DATASET and TABLE

These values together connected with a . should be the equivalent of that shown in: Big Query Cutoff Time Tomorrow View

REPORT_TABLE

Should match what is shown in: Big Query Report

EMAIL_TEMPLATE_ID

Decides the email format sent to customers, see here: Marketing v2 Template

SMS_MESSAGE

The exact text that is sent by sms to the customers

The expected storepick-edit-order-notification.json file:

{
    "TEST_REPORT": true,
    "MORI_CONFIG": {},
    "EON_LOGGING_CONFIG": {
        "disable_existing_loggers": false,
        "version": 1,
        "formatters": {
            "simple": {
                "format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
            },
            "monitoring": {
                "format": "MONITORING|%(created)f|%(message)s"
            }
        },
        "handlers": {
            "console": {
                "class": "logging.StreamHandler",
                "level": "DEBUG",
                "formatter": "simple",
                "stream": "ext://sys.stdout"
            },
            "monitoring": {
                "class": "logging.StreamHandler",
                "level": "DEBUG",
                "formatter": "monitoring",
                "stream": "ext://sys.stdout"
            }
        },
        "loggers": {
            "monitoring": {
                "level": "DEBUG",
                "handlers": [
                    "monitoring"
                ],
                "propagate": false,
                "formatter": "monitoring"
            },
            "console": {
                "level": "DEBUG",
                "handlers": [
                    "console"
                ],
                "propagate": false
            }
        },
        "root": {
            "level": "DEBUG",
            "handlers": [
                "console"
            ]
        }
    },
    "DATASET": "mrw-prod-storepick",
    "TABLE": "store_pick_views.edit_cutoff_time_tomorrow",
    "REPORT_TABLE": "mrw-prod-storepick.store_pick.Edit_Order_Notification_Report",
    "MORI_BASE_URL": "https://api.morrisons.com",
    "CUSTOMER_URL": "customer/v2/customers",
    "MARKETINGEMAIL_URL": "marketing/v2/channels/email",
    "MARKETING_URL": "marketing/v2/channels",
    "MARKETINGSMS_URL": "marketing/v2/channels/sms",
    "EMAIL_TEMPLATE_ID": "8080221",
    "SMS_MESSAGE": "Your Morrisons delivery is tomorrow. Forgotten something? You can make last minute changes to your order until 23:30 today."
}

ECS Task

Sequence Diagram

@startuml

title Edit Order Notification

skinparam participant {

	BackgroundColor<<NEW>> DarkSeaGreen
	BorderColor<<NEW>> DarkSlateGray
	CardFontColor<<NEW>> white

	BackgroundColor<<NEW>> DarkSeaGreen
	BorderColor<<NEW>> DarkSlateGray
	CardFontColor<<NEW>> white

	ArrowColor Olive
}

Actor "CloudWatch cron" as CloudWatchTrigger

participant "<<AWS ECS Task>>\nEmail Notification Task" as AWSECSEmailNotification << NEW >>
participant "<<class>>\n<pymorri>\nSSM" as ssm_reader
participant "<<class>>\n<pymorri>\nConfigReader2" as config_reader
participant "<<BigQuery View>>\nEdit Cutoff Time Tomorrow" as BQEONView <<NEW>>
participant "<pymorri>\nMorissons Customer API" as MoriCustomer << NEW >>
participant "<<pymorri>>\nMorissons Marketing API" as MoriMarketing << NEW >>
participant "<<list>>\nreport list" as list
participant "<<Monitoring Service>>\nDatadog monitoring" as Monitoring << NEW >>
participant "<<BigQuery Table>>\nEdit Order Notification Report" as BQEONReport << NEW >>

Actor "OSP Customer" as OSPCustomer

CloudWatchTrigger -> AWSECSEmailNotification : cron daily at 9am

== Initialise ECS Task ==

AWSECSEmailNotification -> ssm_reader : Read Config credentials from SSM
ssm_reader -> AWSECSEmailNotification : JSON object with config credentials
AWSECSEmailNotification -> config_reader : Read application configuration from \nstorepick-email-notification-app.json
config_reader -> AWSECSEmailNotification : JSON object with app config

== End Initialise ECS Task ==

AWSECSEmailNotification -> BQEONView : Retrieve view 'edit_cutoff_time_tomorrow'
BQEONView -> AWSECSEmailNotification : return JSON payload containing customer orders

group loop CustomerOrder

    == Process Notification ==
       AWSECSEmailNotification -> MoriCustomer : retrieve customer details
       AWSECSEmailNotification -> AWSECSEmailNotification : extract email and phone number
       AWSECSEmailNotification -> AWSECSEmailNotification : validate email (simple, does it contain '@' and is it a reasonable length)
       AWSECSEmailNotification -> AWSECSEmailNotification : validate phone number (simple, length and numeric)\n strip leading '+'\nreplace leading '0' with '44'

       AWSECSEmailNotification -> MoriMarketing : POST /channels/email/{templateId}
       alt If response.status != 200
            AWSECSEmailNotification -> list : add entry to report list
            AWSECSEmailNotification -> Monitoring : add result to monitoring
       else
            AWSECSEmailNotification -> list : add entry to report list
            AWSECSEmailNotification -> Monitoring : add result to monitoring
       end

       AWSECSEmailNotification -> MoriMarketing : POST /channels/sms
       alt If response.status != 200
            AWSECSEmailNotification -> list : add entry to report list
            AWSECSEmailNotification -> Monitoring : add result to monitoring
       else
            AWSECSEmailNotification -> list : add entry to report list
            AWSECSEmailNotification -> Monitoring : add result to monitoring
       end

    == End Process Notification ==

end 'CustomerOrder'

== Write control file to assist testing ==

'AWSLambda -> s3_file_operations : write control list to <s3_bucket>/processing
's3_file_operations <-> S3 : write list as csv to S3
's3_file_operations -> AWSLambda : file successfully written

== Write report on processing ==

AWSECSEmailNotification -> AWSECSEmailNotification : Prepare report summary list\nready for big query
AWSECSEmailNotification -> BQEONReport : Write report details to 'Edit_Order_Notification_Report'

'AWSLambda -> s3_file_operations : write control list to <s3_bucket>/processing
's3_file_operations <-> S3 : write list as csv to S3
's3_file_operations -> AWSLambda : file successfully written

== What to do here.... NOT_IMPLEMENTED ==

alt If ECSTask.status != 200
' This may be written to BQ
    AWSECSEmailNotification -> Log : Failure
    AWSECSEmailNotification -> Monitoring : Failure

else
    AWSECSEmailNotification -> Log : Success
    AWSECSEmailNotification -> Monitoring : Success
end

AWSECSEmailNotification -> CloudWatchTrigger : notifications successfully processed

@enduml

Functions

ecstask.main.run_application()[source]

The main method to run the application.

Initialises dependencies class to retrieve google credentials for big query and application config.

Retrieves order and customer id’s for edit order cutoff tomorrow orders from big query.

Uses pymorri Customer API to retrieve each customer’s details using id, then formats and validates the data. The Marketing API then attempts to send an email and sms to each customer found.

The success or failure of these attempts is recorded and sent as a report to a big query table.

ecstask.main.get_application_env()[source]

Method to fetch the application environment from the command line

Returns

A 3 letter environment description.

Return type

str

Examples

“[0-9]{3,4}” - Building feature branch with number (relates to ticket reference in Jira)

“dev” - Building develop branch

“prd” - production environment