mirror of
https://github.com/GSA/notifications-api.git
synced 2026-02-01 15:46:07 -05:00
Merge branch 'master' into fix-template-versions
This commit is contained in:
@@ -119,21 +119,11 @@ def process_job(job_id):
|
||||
).enumerated_recipients_and_personalisation:
|
||||
process_row(row_number, recipient, personalisation, template, job, service)
|
||||
|
||||
job_complete(job, service, template.template_type, start=start)
|
||||
job_complete(job, start=start)
|
||||
|
||||
|
||||
def job_complete(job, service, template_type, resumed=False, start=None):
|
||||
if (
|
||||
template_type == LETTER_TYPE and
|
||||
not service.has_permission('letters_as_pdf')
|
||||
):
|
||||
if service.research_mode:
|
||||
update_job_to_sent_to_dvla.apply_async([str(job.id)], queue=QueueNames.RESEARCH_MODE)
|
||||
else:
|
||||
build_dvla_file.apply_async([str(job.id)], queue=QueueNames.JOBS)
|
||||
current_app.logger.debug("send job {} to build-dvla-file in the {} queue".format(job.id, QueueNames.JOBS))
|
||||
else:
|
||||
job.job_status = JOB_STATUS_FINISHED
|
||||
def job_complete(job, resumed=False, start=None):
|
||||
job.job_status = JOB_STATUS_FINISHED
|
||||
|
||||
finished = datetime.utcnow()
|
||||
job.processing_finished = finished
|
||||
@@ -326,19 +316,18 @@ def save_letter(
|
||||
status=status
|
||||
)
|
||||
|
||||
if service.has_permission('letters_as_pdf'):
|
||||
if not service.research_mode:
|
||||
letters_pdf_tasks.create_letters_pdf.apply_async(
|
||||
[str(saved_notification.id)],
|
||||
queue=QueueNames.CREATE_LETTERS_PDF
|
||||
)
|
||||
elif current_app.config['NOTIFY_ENVIRONMENT'] in ['preview', 'development']:
|
||||
research_mode_tasks.create_fake_letter_response_file.apply_async(
|
||||
(saved_notification.reference,),
|
||||
queue=QueueNames.RESEARCH_MODE
|
||||
)
|
||||
else:
|
||||
update_notification_status_by_reference(saved_notification.reference, 'delivered')
|
||||
if not service.research_mode:
|
||||
letters_pdf_tasks.create_letters_pdf.apply_async(
|
||||
[str(saved_notification.id)],
|
||||
queue=QueueNames.CREATE_LETTERS_PDF
|
||||
)
|
||||
elif current_app.config['NOTIFY_ENVIRONMENT'] in ['preview', 'development']:
|
||||
research_mode_tasks.create_fake_letter_response_file.apply_async(
|
||||
(saved_notification.reference,),
|
||||
queue=QueueNames.RESEARCH_MODE
|
||||
)
|
||||
else:
|
||||
update_notification_status_by_reference(saved_notification.reference, 'delivered')
|
||||
|
||||
current_app.logger.debug("Letter {} created at {}".format(saved_notification.id, saved_notification.created_at))
|
||||
except SQLAlchemyError as e:
|
||||
@@ -608,4 +597,4 @@ def process_incomplete_job(job_id):
|
||||
if row_number > resume_from_row:
|
||||
process_row(row_number, recipient, personalisation, template, job, job.service)
|
||||
|
||||
job_complete(job, job.service, template.template_type, resumed=True)
|
||||
job_complete(job, resumed=True)
|
||||
|
||||
@@ -5,7 +5,6 @@ from monotonic import monotonic
|
||||
from requests import request, RequestException
|
||||
|
||||
from app.clients.sms import (SmsClient, SmsClientResponseException)
|
||||
from app.clients import STATISTICS_DELIVERED, STATISTICS_FAILURE
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -15,24 +14,9 @@ logger = logging.getLogger(__name__)
|
||||
# the notification status to temporary-failure rather than permanent failure.
|
||||
# See the code in the notification_dao.update_notifications_status_by_id
|
||||
firetext_responses = {
|
||||
'0': {
|
||||
"message": 'Delivered',
|
||||
"notification_statistics_status": STATISTICS_DELIVERED,
|
||||
"success": True,
|
||||
"notification_status": 'delivered'
|
||||
},
|
||||
'1': {
|
||||
"message": 'Declined',
|
||||
"success": False,
|
||||
"notification_statistics_status": STATISTICS_FAILURE,
|
||||
"notification_status": 'permanent-failure'
|
||||
},
|
||||
'2': {
|
||||
"message": 'Undelivered (Pending with Network)',
|
||||
"success": True,
|
||||
"notification_statistics_status": None,
|
||||
"notification_status": 'pending'
|
||||
}
|
||||
'0': 'delivered',
|
||||
'1': 'permanent-failure',
|
||||
'2': 'pending'
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,45 +1,18 @@
|
||||
import json
|
||||
from monotonic import monotonic
|
||||
from requests import (request, RequestException)
|
||||
from app.clients import (STATISTICS_DELIVERED, STATISTICS_FAILURE)
|
||||
from app.clients.sms import (SmsClient, SmsClientResponseException)
|
||||
|
||||
mmg_response_map = {
|
||||
'2': {
|
||||
"message": ' Permanent failure',
|
||||
"notification_statistics_status": STATISTICS_FAILURE,
|
||||
"success": False,
|
||||
"notification_status": 'permanent-failure'
|
||||
},
|
||||
'3': {
|
||||
"message": 'Delivered',
|
||||
"notification_statistics_status": STATISTICS_DELIVERED,
|
||||
"success": True,
|
||||
"notification_status": 'delivered'
|
||||
},
|
||||
'4': {
|
||||
"message": ' Temporary failure',
|
||||
"notification_statistics_status": STATISTICS_FAILURE,
|
||||
"success": False,
|
||||
"notification_status": 'temporary-failure'
|
||||
},
|
||||
'5': {
|
||||
"message": 'Permanent failure',
|
||||
"notification_statistics_status": STATISTICS_FAILURE,
|
||||
"success": False,
|
||||
"notification_status": 'permanent-failure'
|
||||
},
|
||||
'default': {
|
||||
"message": 'Declined',
|
||||
"success": False,
|
||||
"notification_statistics_status": STATISTICS_FAILURE,
|
||||
"notification_status": 'failed'
|
||||
}
|
||||
'2': 'permanent-failure',
|
||||
'3': 'delivered',
|
||||
'4': 'temporary-failure',
|
||||
'5': 'permanent-failure'
|
||||
}
|
||||
|
||||
|
||||
def get_mmg_responses(status):
|
||||
return mmg_response_map.get(status, mmg_response_map.get('default'))
|
||||
return mmg_response_map[status]
|
||||
|
||||
|
||||
class MMGClientResponseException(SmsClientResponseException):
|
||||
|
||||
@@ -170,11 +170,6 @@ class Config(object):
|
||||
'schedule': crontab(minute=1),
|
||||
'options': {'queue': QueueNames.PERIODIC}
|
||||
},
|
||||
# 'send-scheduled-notifications': {
|
||||
# 'task': 'send-scheduled-notifications',
|
||||
# 'schedule': crontab(minute='*/15'),
|
||||
# 'options': {'queue': 'periodic'}
|
||||
# },
|
||||
'delete-verify-codes': {
|
||||
'task': 'delete-verify-codes',
|
||||
'schedule': timedelta(minutes=63),
|
||||
@@ -252,11 +247,6 @@ class Config(object):
|
||||
'schedule': crontab(hour=16, minute=30),
|
||||
'options': {'queue': QueueNames.PERIODIC}
|
||||
},
|
||||
'run-letter-jobs': {
|
||||
'task': 'run-letter-jobs',
|
||||
'schedule': crontab(hour=17, minute=30),
|
||||
'options': {'queue': QueueNames.PERIODIC}
|
||||
},
|
||||
'trigger-letter-pdfs-for-day': {
|
||||
'task': 'trigger-letter-pdfs-for-day',
|
||||
'schedule': crontab(hour=17, minute=50),
|
||||
@@ -267,11 +257,6 @@ class Config(object):
|
||||
'schedule': crontab(hour=23, minute=00),
|
||||
'options': {'queue': QueueNames.PERIODIC}
|
||||
},
|
||||
'run-letter-api-notifications': {
|
||||
'task': 'run-letter-api-notifications',
|
||||
'schedule': crontab(hour=17, minute=40),
|
||||
'options': {'queue': QueueNames.PERIODIC}
|
||||
},
|
||||
'check-job-status': {
|
||||
'task': 'check-job-status',
|
||||
'schedule': crontab(),
|
||||
|
||||
@@ -4,6 +4,7 @@ from datetime import datetime
|
||||
from flask import current_app
|
||||
|
||||
from app import statsd_client
|
||||
from app.clients import ClientException
|
||||
from app.dao import notifications_dao
|
||||
from app.clients.sms.firetext import get_firetext_responses
|
||||
from app.clients.sms.mmg import get_mmg_responses
|
||||
@@ -39,8 +40,8 @@ def process_sms_client_response(status, reference, client_name):
|
||||
try:
|
||||
uuid.UUID(reference, version=4)
|
||||
except ValueError:
|
||||
message = "{} callback with invalid reference {}".format(client_name, reference)
|
||||
return success, message
|
||||
errors = "{} callback with invalid reference {}".format(client_name, reference)
|
||||
return success, errors
|
||||
|
||||
try:
|
||||
response_parser = sms_response_mapper[client_name]
|
||||
@@ -49,32 +50,27 @@ def process_sms_client_response(status, reference, client_name):
|
||||
|
||||
# validate status
|
||||
try:
|
||||
response_dict = response_parser(status)
|
||||
notification_status = response_parser(status)
|
||||
current_app.logger.info('{} callback return status of {} for reference: {}'.format(
|
||||
client_name, status, reference)
|
||||
)
|
||||
except KeyError:
|
||||
msg = "{} callback failed: status {} not found.".format(client_name, status)
|
||||
return success, msg
|
||||
_process_for_status(notification_status='technical-failure', client_name=client_name, reference=reference)
|
||||
raise ClientException("{} callback failed: status {} not found.".format(client_name, status))
|
||||
|
||||
notification_status = response_dict['notification_status']
|
||||
notification_status_message = response_dict['message']
|
||||
notification_success = response_dict['success']
|
||||
success = _process_for_status(notification_status=notification_status, client_name=client_name, reference=reference)
|
||||
return success, errors
|
||||
|
||||
|
||||
def _process_for_status(notification_status, client_name, reference):
|
||||
# record stats
|
||||
notification = notifications_dao.update_notification_status_by_id(reference, notification_status)
|
||||
if not notification:
|
||||
current_app.logger.warning("{} callback failed: notification {} either not found or already updated "
|
||||
"from sending. Status {}".format(client_name,
|
||||
reference,
|
||||
notification_status_message))
|
||||
return success, errors
|
||||
|
||||
if not notification_success:
|
||||
current_app.logger.debug(
|
||||
"{} delivery failed: notification {} has error found. Status {}".format(client_name,
|
||||
reference,
|
||||
notification_status_message))
|
||||
notification_status))
|
||||
return
|
||||
|
||||
statsd_client.incr('callback.{}.{}'.format(client_name.lower(), notification_status))
|
||||
if notification.sent_at:
|
||||
@@ -92,4 +88,4 @@ def process_sms_client_response(status, reference, client_name):
|
||||
send_delivery_status_to_service.apply_async([str(notification.id)], queue=QueueNames.CALLBACKS)
|
||||
|
||||
success = "{} callback succeeded. reference {} updated".format(client_name, reference)
|
||||
return success, errors
|
||||
return success
|
||||
|
||||
@@ -673,15 +673,24 @@ def get_organisation_for_service(service_id):
|
||||
|
||||
@service_blueprint.route('/unique', methods=["GET"])
|
||||
def is_service_name_unique():
|
||||
name, email_from = check_request_args(request)
|
||||
service_id, name, email_from = check_request_args(request)
|
||||
|
||||
name_exists = Service.query.filter_by(name=name).first()
|
||||
email_from_exists = Service.query.filter_by(email_from=email_from).first()
|
||||
|
||||
if service_id:
|
||||
email_from_exists = Service.query.filter(
|
||||
Service.email_from == email_from,
|
||||
Service.id != service_id
|
||||
).first()
|
||||
else:
|
||||
email_from_exists = Service.query.filter_by(email_from=email_from).first()
|
||||
|
||||
result = not (name_exists or email_from_exists)
|
||||
return jsonify(result=result), 200
|
||||
|
||||
|
||||
def check_request_args(request):
|
||||
service_id = request.args.get('service_id')
|
||||
name = request.args.get('name', None)
|
||||
email_from = request.args.get('email_from', None)
|
||||
errors = []
|
||||
@@ -691,4 +700,4 @@ def check_request_args(request):
|
||||
errors.append({'email_from': ["Can't be empty"]})
|
||||
if errors:
|
||||
raise InvalidRequest(errors, status_code=400)
|
||||
return name, email_from
|
||||
return service_id, name, email_from
|
||||
|
||||
@@ -183,20 +183,19 @@ def process_letter_notification(*, letter_data, api_key, template, reply_to_text
|
||||
status=status,
|
||||
reply_to_text=reply_to_text)
|
||||
|
||||
if api_key.service.has_permission('letters_as_pdf'):
|
||||
if should_send:
|
||||
create_letters_pdf.apply_async(
|
||||
[str(notification.id)],
|
||||
queue=QueueNames.CREATE_LETTERS_PDF
|
||||
)
|
||||
elif (api_key.service.research_mode and
|
||||
current_app.config['NOTIFY_ENVIRONMENT'] in ['preview', 'development']):
|
||||
create_fake_letter_response_file.apply_async(
|
||||
(notification.reference,),
|
||||
queue=QueueNames.RESEARCH_MODE
|
||||
)
|
||||
else:
|
||||
update_notification_status_by_reference(notification.reference, NOTIFICATION_DELIVERED)
|
||||
if should_send:
|
||||
create_letters_pdf.apply_async(
|
||||
[str(notification.id)],
|
||||
queue=QueueNames.CREATE_LETTERS_PDF
|
||||
)
|
||||
elif (api_key.service.research_mode and
|
||||
current_app.config['NOTIFY_ENVIRONMENT'] in ['preview', 'development']):
|
||||
create_fake_letter_response_file.apply_async(
|
||||
(notification.reference,),
|
||||
queue=QueueNames.RESEARCH_MODE
|
||||
)
|
||||
else:
|
||||
update_notification_status_by_reference(notification.reference, NOTIFICATION_DELIVERED)
|
||||
|
||||
return notification
|
||||
|
||||
|
||||
Reference in New Issue
Block a user