Skip to content

Commit

Permalink
Merge pull request #1497 from GSA/main
Browse files Browse the repository at this point in the history
Production release for 12/20/24
  • Loading branch information
ccostino authored Dec 23, 2024
2 parents 42536d5 + 786b661 commit 1b37fa9
Show file tree
Hide file tree
Showing 11 changed files with 94 additions and 2 deletions.
4 changes: 4 additions & 0 deletions app/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import logging as real_logging
import os
import secrets
import string
Expand Down Expand Up @@ -36,6 +37,9 @@ def init_app(self, app):

# Configure Celery app with options from the main app config.
self.config_from_object(app.config["CELERY"])
self.conf.worker_hijack_root_logger = False
logger = real_logging.getLogger("celery")
logger.propagate = False

def send_task(self, name, args=None, kwargs=None, **other_kwargs):
other_kwargs["headers"] = other_kwargs.get("headers") or {}
Expand Down
7 changes: 6 additions & 1 deletion app/aws/s3.py
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,12 @@ def extract_phones(job):
phone_index = 0
for item in first_row:
# Note: may contain a BOM and look like \ufeffphone number
if item.lower() in ["phone number", "\\ufeffphone number"]:
if item.lower() in [
"phone number",
"\\ufeffphone number",
"\\ufeffphone number\n",
"phone number\n",
]:
break
phone_index = phone_index + 1

Expand Down
2 changes: 2 additions & 0 deletions app/celery/provider_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ def deliver_sms(self, notification_id):
)
# Code branches off to send_to_providers.py
message_id = send_to_providers.send_sms_to_provider(notification)

# DEPRECATED
# We have to put it in UTC. For other timezones, the delay
# will be ignored and it will fire immediately (although this probably only affects developer testing)
my_eta = utc_now() + timedelta(seconds=DELIVERY_RECEIPT_DELAY_IN_SECONDS)
Expand Down
8 changes: 8 additions & 0 deletions app/celery/tasks.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import json

from celery.signals import task_postrun
from flask import current_app
from requests import HTTPError, RequestException, request
from sqlalchemy.exc import IntegrityError, SQLAlchemyError
Expand Down Expand Up @@ -170,6 +171,13 @@ def __total_sending_limits_for_job_exceeded(service, job, job_id):
return True


@task_postrun.connect
def log_task_ejection(sender=None, task_id=None, **kwargs):
current_app.logger.info(
f"Task {task_id} ({sender.name if sender else 'unknown_task'}) has been completed and removed"
)


@notify_celery.task(bind=True, name="save-sms", max_retries=2, default_retry_delay=600)
def save_sms(self, service_id, notification_id, encrypted_notification, sender_id=None):
"""Persist notification to db and place notification in queue to send to sns."""
Expand Down
2 changes: 2 additions & 0 deletions app/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ class Config(object):

CELERY = {
"worker_max_tasks_per_child": 500,
"task_ignore_result": True,
"result_persistent": False,
"broker_url": REDIS_URL,
"broker_transport_options": {
"visibility_timeout": 310,
Expand Down
10 changes: 10 additions & 0 deletions app/dao/notifications_dao.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,16 @@ def _update_notification_status(
return notification


def update_notification_message_id(notification_id, message_id):
stmt = (
update(Notification)
.where(Notification.id == notification_id)
.values(message_id=message_id)
)
db.session.execute(stmt)
db.session.commit()


@autocommit
def update_notification_status_by_id(
notification_id, status, sent_by=None, provider_response=None, carrier=None
Expand Down
6 changes: 5 additions & 1 deletion app/delivery/send_to_providers.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@
from app.aws.s3 import get_personalisation_from_s3, get_phone_number_from_s3
from app.celery.test_key_tasks import send_email_response, send_sms_response
from app.dao.email_branding_dao import dao_get_email_branding_by_id
from app.dao.notifications_dao import dao_update_notification
from app.dao.notifications_dao import (
dao_update_notification,
update_notification_message_id,
)
from app.dao.provider_details_dao import get_provider_details_by_notification_type
from app.dao.service_sms_sender_dao import dao_get_sms_senders_by_service_id
from app.enums import BrandType, KeyType, NotificationStatus, NotificationType
Expand Down Expand Up @@ -117,6 +120,7 @@ def send_sms_to_provider(notification):

message_id = provider.send_sms(**send_sms_kwargs)
current_app.logger.info(f"got message_id {message_id}")
update_notification_message_id(notification.id, message_id)
except Exception as e:
n = notification
msg = f"FAILED send to sms, job_id: {n.job_id} row_number {n.job_row_number} message_id {message_id}"
Expand Down
1 change: 1 addition & 0 deletions app/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1532,6 +1532,7 @@ class Notification(db.Model):

provider_response = db.Column(db.Text, nullable=True)
carrier = db.Column(db.Text, nullable=True)
message_id = db.Column(db.Text, nullable=True)

# queue_name = db.Column(db.Text, nullable=True)

Expand Down
2 changes: 2 additions & 0 deletions notifications_utils/logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,12 @@ def init_app(app):
for logger_instance, handler in product(loggers, handlers):
logger_instance.addHandler(handler)
logger_instance.setLevel(loglevel)
logger_instance.propagate = False
warning_loggers = [logging.getLogger("boto3"), logging.getLogger("s3transfer")]
for logger_instance, handler in product(warning_loggers, handlers):
logger_instance.addHandler(handler)
logger_instance.setLevel(logging.WARNING)
logger_instance.propagate = False

# Suppress specific loggers to prevent leaking sensitive info
logging.getLogger("boto3").setLevel(logging.ERROR)
Expand Down
14 changes: 14 additions & 0 deletions tests/app/aws/test_s3.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,20 @@ def test_get_s3_file_makes_correct_call(notify_api, mocker):
2,
"5555555552",
),
(
# simulate file saved with utf8withbom
"\\ufeffPHONE NUMBER\n",
"eee",
2,
"5555555552",
),
(
# simulate file saved without utf8withbom
"\\PHONE NUMBER\n",
"eee",
2,
"5555555552",
),
],
)
def test_get_phone_number_from_s3(
Expand Down
40 changes: 40 additions & 0 deletions tests/app/delivery/test_send_to_providers.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ def test_should_send_personalised_template_to_correct_sms_provider_and_persist(
mock_s3 = mocker.patch("app.delivery.send_to_providers.get_phone_number_from_s3")
mock_s3.return_value = "2028675309"

mocker.patch("app.delivery.send_to_providers.update_notification_message_id")
mock_personalisation = mocker.patch(
"app.delivery.send_to_providers.get_personalisation_from_s3"
)
Expand Down Expand Up @@ -233,6 +234,7 @@ def test_send_sms_should_use_template_version_from_notification_not_latest(
mock_s3 = mocker.patch("app.delivery.send_to_providers.get_phone_number_from_s3")
mock_s3.return_value = "2028675309"

mocker.patch("app.delivery.send_to_providers.update_notification_message_id")
mock_s3_p = mocker.patch(
"app.delivery.send_to_providers.get_personalisation_from_s3"
)
Expand Down Expand Up @@ -327,6 +329,7 @@ def test_should_send_sms_with_downgraded_content(notify_db_session, mocker):
# ī, grapes, tabs, zero width space and ellipsis are not
# ó isn't in GSM, but it is in the welsh alphabet so will still be sent

mocker.patch("app.delivery.send_to_providers.update_notification_message_id")
mocker.patch("app.delivery.send_to_providers.redis_store", return_value=None)
mocker.patch(
"app.delivery.send_to_providers.get_sender_numbers", return_value=["testing"]
Expand Down Expand Up @@ -365,6 +368,7 @@ def test_send_sms_should_use_service_sms_sender(

mocker.patch("app.delivery.send_to_providers.redis_store", return_value=None)
mocker.patch("app.aws_sns_client.send_sms")
mocker.patch("app.delivery.send_to_providers.update_notification_message_id")

sms_sender = create_service_sms_sender(
service=sample_service, sms_sender="123456", is_default=False
Expand Down Expand Up @@ -405,6 +409,8 @@ def test_send_email_to_provider_should_not_send_to_provider_when_status_is_not_c
)
mocker.patch("app.aws_ses_client.send_email")
mocker.patch("app.delivery.send_to_providers.send_email_response")

mocker.patch("app.delivery.send_to_providers.update_notification_message_id")
mock_phone = mocker.patch("app.delivery.send_to_providers.get_phone_number_from_s3")
mock_phone.return_value = "15555555555"

Expand Down Expand Up @@ -627,6 +633,10 @@ def test_should_update_billable_units_and_status_according_to_research_mode_and_
):

mocker.patch("app.delivery.send_to_providers.redis_store", return_value=None)
mocker.patch(
"app.delivery.send_to_providers.update_notification_message_id",
return_value=None,
)
mocker.patch(
"app.delivery.send_to_providers.get_sender_numbers", return_value=["testing"]
)
Expand All @@ -637,6 +647,11 @@ def test_should_update_billable_units_and_status_according_to_research_mode_and_
key_type=key_type,
reply_to_text="testing",
)

mocker.patch(
"app.delivery.send_to_providers.update_notification_message_id",
return_value=None,
)
mocker.patch("app.aws_sns_client.send_sms")
mocker.patch(
"app.delivery.send_to_providers.send_sms_response",
Expand All @@ -647,6 +662,8 @@ def test_should_update_billable_units_and_status_according_to_research_mode_and_
sample_template.service.research_mode = True

mock_phone = mocker.patch("app.delivery.send_to_providers.get_phone_number_from_s3")

mocker.patch("app.delivery.send_to_providers.update_notification_message_id")
mock_phone.return_value = "15555555555"

mock_personalisation = mocker.patch(
Expand All @@ -670,6 +687,8 @@ def test_should_set_notification_billable_units_and_reduces_provider_priority_if
assert sample_notification.sent_by is None

mock_phone = mocker.patch("app.delivery.send_to_providers.get_phone_number_from_s3")

mocker.patch("app.delivery.send_to_providers.update_notification_message_id")
mock_phone.return_value = "15555555555"

mock_personalisation = mocker.patch(
Expand Down Expand Up @@ -705,8 +724,14 @@ def test_should_send_sms_to_international_providers(
)

mock_s3 = mocker.patch("app.delivery.send_to_providers.get_phone_number_from_s3")

mocker.patch("app.delivery.send_to_providers.update_notification_message_id")
mock_s3.return_value = "601117224412"

mocker.patch(
"app.delivery.send_to_providers.update_notification_message_id",
return_value=None,
)
mock_personalisation = mocker.patch(
"app.delivery.send_to_providers.get_personalisation_from_s3"
)
Expand Down Expand Up @@ -744,6 +769,11 @@ def test_should_handle_sms_sender_and_prefix_message(

mocker.patch("app.delivery.send_to_providers.redis_store", return_value=None)
mocker.patch("app.aws_sns_client.send_sms")

mocker.patch(
"app.delivery.send_to_providers.update_notification_message_id",
return_value=None,
)
service = create_service_with_defined_sms_sender(
sms_sender_value=sms_sender, prefix_sms=prefix_sms
)
Expand Down Expand Up @@ -803,6 +833,11 @@ def test_send_sms_to_provider_should_use_normalised_to(mocker, client, sample_te
mocker.patch(
"app.delivery.send_to_providers.get_sender_numbers", return_value=["testing"]
)

mocker.patch(
"app.delivery.send_to_providers.update_notification_message_id",
return_value=None,
)
send_mock = mocker.patch("app.aws_sns_client.send_sms")
notification = create_notification(
template=sample_template,
Expand Down Expand Up @@ -866,6 +901,11 @@ def test_send_sms_to_provider_should_return_template_if_found_in_redis(
mocker.patch(
"app.delivery.send_to_providers.get_sender_numbers", return_value=["testing"]
)

mocker.patch(
"app.delivery.send_to_providers.update_notification_message_id",
return_value=None,
)
from app.schemas import service_schema, template_schema

service_dict = service_schema.dump(sample_template.service)
Expand Down

0 comments on commit 1b37fa9

Please sign in to comment.