Repurpose command to replay notification callbacks

This is so we can use it to address issues highlighted by the new
alert, if it's not possible to actually send the notifications e.g.
if they are somehow 'invalid'.

Previously this was added for a one-off use case [1]. This rewrites
the task to operate on arbitrary notification IDs instead of client
refs, which aren't always present for notifications we may want to
send / replay callbacks for. Since the task may now need to work on
notifications more than one service, I had to restructure it to cope
with multiple callback APIs.

Note that, in the test, I've chosen to do a chain of invocations and
assertions, rather than duplicate a load of boilerplate or introduce
funky parametrize flags for a service with/out a callback API. We'll
refactor this in a later commit.

[1]: e95740a6b5
This commit is contained in:
Ben Thorner
2021-11-25 17:02:57 +00:00
parent f96ba5361a
commit 2acc4ee67d
2 changed files with 72 additions and 33 deletions

View File

@@ -284,42 +284,37 @@ def recreate_pdf_for_precompiled_or_uploaded_letter(notification_id):
resanitise_pdf.apply_async([str(notification_id)], queue=QueueNames.LETTERS)
@notify_command(name='replay-service-callbacks')
@click.option('-f', '--file_name', required=True,
help="""Full path of the file to upload, file is a contains client references of
@notify_command(name='replay-callbacks')
@click.option('-f', '--file-name', required=True,
help="""Full path of the file to upload, containing IDs of
notifications that need the status to be sent to the service.""")
@click.option('-s', '--service_id', required=True,
help="""The service that the callbacks are for""")
def replay_service_callbacks(file_name, service_id):
print("Start send service callbacks for service: ", service_id)
callback_api = get_service_delivery_status_callback_api_for_service(service_id=service_id)
if not callback_api:
print("Callback api was not found for service: {}".format(service_id))
return
errors = []
notifications = []
def replay_callbacks(file_name):
print("Replaying callbacks.")
file = open(file_name)
for ref in file:
for id in [id.strip() for id in file]:
try:
notification = Notification.query.filter_by(client_reference=ref.strip()).one()
notifications.append(notification)
notification = Notification.query.filter_by(id=id).one()
callback_api = get_service_delivery_status_callback_api_for_service(
service_id=notification.service_id
)
if not callback_api:
print(f"Callback api was not found for notification: {id}.")
continue
encrypted_status_update = create_delivery_status_callback_data(
notification, callback_api
)
send_delivery_status_to_service.apply_async(
[id, encrypted_status_update], queue=QueueNames.CALLBACKS
)
print(f"Created callback task for notification: {id}.")
except NoResultFound:
errors.append("Reference: {} was not found in notifications.".format(ref))
for e in errors:
print(e)
if errors:
raise Exception("Some notifications for the given references were not found")
for n in notifications:
encrypted_status_update = create_delivery_status_callback_data(n, callback_api)
send_delivery_status_to_service.apply_async([str(n.id), encrypted_status_update],
queue=QueueNames.CALLBACKS)
print("Replay service status for service: {}. Sent {} notification status updates to the queue".format(
service_id, len(notifications)))
print(f"ID: {id} was not found in notifications.")
def setup_commands(application):