Files
notifications-api/app/notifications/process_notifications.py
Martyn Inglis 2591d3a1df This massive set of changes uses the new queue names object throughout the app and tests.
Lots of changes, all changing the line of code that puts things into queues, and the code that tests that.
2017-05-25 10:51:49 +01:00

125 lines
4.5 KiB
Python

from datetime import datetime
from flask import current_app
from notifications_utils.recipients import (
get_international_phone_info,
validate_and_format_phone_number
)
from app import redis_store
from app.celery import provider_tasks
from notifications_utils.clients import redis
from app.config import QueueNames
from app.dao.notifications_dao import dao_create_notification, dao_delete_notifications_and_history_by_id
from app.models import SMS_TYPE, Notification, KEY_TYPE_TEST, EMAIL_TYPE
from app.v2.errors import BadRequestError, SendNotificationToQueueError
from app.utils import get_template_instance, cache_key_for_service_template_counter
def create_content_for_notification(template, personalisation):
template_object = get_template_instance(template.__dict__, personalisation)
check_placeholders(template_object)
return template_object
def check_placeholders(template_object):
if template_object.missing_data:
message = 'Template missing personalisation: {}'.format(", ".join(template_object.missing_data))
raise BadRequestError(fields=[{'template': message}], message=message)
def persist_notification(
template_id,
template_version,
recipient,
service,
personalisation,
notification_type,
api_key_id,
key_type,
created_at=None,
job_id=None,
job_row_number=None,
reference=None,
client_reference=None,
notification_id=None,
simulated=False
):
notification_created_at = created_at or datetime.utcnow()
notification = Notification(
id=notification_id,
template_id=template_id,
template_version=template_version,
to=recipient,
service_id=service.id,
service=service,
personalisation=personalisation,
notification_type=notification_type,
api_key_id=api_key_id,
key_type=key_type,
created_at=notification_created_at,
job_id=job_id,
job_row_number=job_row_number,
client_reference=client_reference,
reference=reference
)
if notification_type == SMS_TYPE:
formatted_recipient = validate_and_format_phone_number(recipient, international=True)
recipient_info = get_international_phone_info(formatted_recipient)
notification.international = recipient_info.international
notification.phone_prefix = recipient_info.country_prefix
notification.rate_multiplier = recipient_info.billable_units
# if simulated create a Notification model to return but do not persist the Notification to the dB
if not simulated:
dao_create_notification(notification)
if key_type != KEY_TYPE_TEST:
if redis_store.get(redis.daily_limit_cache_key(service.id)):
redis_store.incr(redis.daily_limit_cache_key(service.id))
if redis_store.get_all_from_hash(cache_key_for_service_template_counter(service.id)):
redis_store.increment_hash_value(cache_key_for_service_template_counter(service.id), template_id)
current_app.logger.info(
"{} {} created at {}".format(notification_type, notification_id, notification_created_at)
)
return notification
def send_notification_to_queue(notification, research_mode, queue=None):
if research_mode or notification.key_type == KEY_TYPE_TEST:
queue = QueueNames.RESEARCH_MODE
elif not queue:
queue = QueueNames.SEND
if notification.notification_type == SMS_TYPE:
deliver_task = provider_tasks.deliver_sms
if notification.notification_type == EMAIL_TYPE:
deliver_task = provider_tasks.deliver_email
try:
deliver_task.apply_async([str(notification.id)], queue=queue)
except Exception as e:
current_app.logger.exception(e)
dao_delete_notifications_and_history_by_id(notification.id)
raise SendNotificationToQueueError()
current_app.logger.info(
"{} {} sent to the {} queue for delivery".format(notification.notification_type,
notification.id,
queue))
def simulated_recipient(to_address, notification_type):
if notification_type == SMS_TYPE:
formatted_simulated_numbers = [
validate_and_format_phone_number(number) for number in current_app.config['SIMULATED_SMS_NUMBERS']
]
return to_address in formatted_simulated_numbers
else:
return to_address in current_app.config['SIMULATED_EMAIL_ADDRESSES']