Merge branch 'master' into fix-template-versions

This commit is contained in:
Rebecca Law
2018-02-15 09:45:56 +00:00
21 changed files with 215 additions and 385 deletions

View File

@@ -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)

View File

@@ -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'
}

View File

@@ -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):

View File

@@ -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(),

View File

@@ -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

View File

@@ -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

View File

@@ -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