Ejemplo n.º 1
0
def _check_and_queue_callback_task(notification):
    # queue callback task only if the service_callback_api exists
    service_callback_api = get_service_delivery_status_callback_api_for_service(service_id=notification.service_id)
    if service_callback_api:
        notification_data = create_delivery_status_callback_data(notification, service_callback_api)
        send_delivery_status_to_service.apply_async([str(notification.id), notification_data],
                                                    queue=QueueNames.CALLBACKS)
Ejemplo n.º 2
0
def timeout_notifications():
    (
        technical_failure_notifications,
        temporary_failure_notifications,
    ) = dao_timeout_notifications(
        current_app.config.get("SENDING_NOTIFICATIONS_TIMEOUT_PERIOD"))

    notifications = technical_failure_notifications + temporary_failure_notifications
    for notification in notifications:
        # queue callback task only if the service_callback_api exists
        service_callback_api = get_service_delivery_status_callback_api_for_service(
            service_id=notification.service_id)
        if service_callback_api:
            encrypted_notification = create_delivery_status_callback_data(
                notification, service_callback_api)
            send_delivery_status_to_service.apply_async(
                [str(notification.id), encrypted_notification],
                queue=QueueNames.CALLBACKS,
            )

    current_app.logger.info(
        "Timeout period reached for {} notifications, status has been updated."
        .format(len(notifications)))
    if technical_failure_notifications:
        message = (
            "{} notifications have been updated to technical-failure because they "
            "have timed out and are still in created.Notification ids: {}".
            format(
                len(technical_failure_notifications),
                [str(x.id) for x in technical_failure_notifications],
            ))
        raise NotificationTechnicalFailureException(message)
def process_service_callback(notification):
    if notification.status != NOTIFICATION_PENDING:
        service_callback_api = get_service_delivery_status_callback_api_for_service(service_id=notification.service_id)
        # queue callback task only if the service_callback_api exists
        if service_callback_api:
            encrypted_notification = create_delivery_status_callback_data(notification, service_callback_api)
            send_delivery_status_to_service.apply_async([notification.id, encrypted_notification],
                                                        queue=QueueNames.CALLBACKS)
def _process_for_status(notification_status,
                        client_name,
                        provider_reference,
                        detailed_status_code=None):
    # record stats
    if client_name == 'Twilio':
        notification = notifications_dao.update_notification_status_by_reference(
            reference=provider_reference, status=notification_status)
    else:
        notification = notifications_dao.update_notification_status_by_id(
            notification_id=provider_reference,
            status=notification_status,
            sent_by=client_name.lower(),
            detailed_status_code=detailed_status_code)

    if not notification:
        return

    statsd_client.incr('callback.{}.{}'.format(client_name.lower(),
                                               notification_status))

    if notification.sent_at:
        statsd_client.timing_with_dates(
            'callback.{}.elapsed-time'.format(client_name.lower()),
            datetime.utcnow(), notification.sent_at)

    if notification.billable_units == 0:
        service = notification.service
        template_model = dao_get_template_by_id(notification.template_id,
                                                notification.template_version)

        template = SMSMessageTemplate(
            template_model.__dict__,
            values=notification.personalisation,
            prefix=service.name,
            show_prefix=service.prefix_sms,
        )
        notification.billable_units = template.fragment_count
        notifications_dao.dao_update_notification(notification)

    if notification_status != NOTIFICATION_PENDING:
        service_callback_api = get_service_delivery_status_callback_api_for_service(
            service_id=notification.service_id)
        # queue callback task only if the service_callback_api exists
        if service_callback_api:
            encrypted_notification = create_delivery_status_callback_data(
                notification, service_callback_api)
            send_delivery_status_to_service.apply_async(
                [str(notification.id), encrypted_notification],
                queue=QueueNames.CALLBACKS)
Ejemplo n.º 5
0
def check_for_callback_and_send_delivery_status_to_service(notification):
    service_callback_api = get_service_delivery_status_callback_api_for_service(
        service_id=notification.service_id)

    # If a status callback was provided on the notification or if the service
    # has a service_callback_api record, then queue the callback task.
    if (notification.status_callback_url and
            notification.status_callback_bearer_token) or service_callback_api:
        encrypted_notification = create_delivery_status_callback_data(
            notification, service_callback_api)

        send_delivery_status_to_service.apply_async(
            [str(notification.id), encrypted_notification],
            queue=QueueNames.CALLBACKS,
        )
Ejemplo n.º 6
0
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 = []
    file = open(file_name)

    for ref in file:
        try:
            notification = Notification.query.filter_by(
                client_reference=ref.strip()).one()
            notifications.append(notification)
        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:
        data = {
            "notification_id": str(n.id),
            "notification_client_reference": n.client_reference,
            "notification_to": n.to,
            "notification_status": n.status,
            "notification_created_at": n.created_at.strftime(DATETIME_FORMAT),
            "notification_updated_at": n.updated_at.strftime(DATETIME_FORMAT),
            "notification_sent_at": n.sent_at.strftime(DATETIME_FORMAT),
            "notification_type": n.notification_type,
            "service_callback_api_url": callback_api.url,
            "service_callback_api_bearer_token": callback_api.bearer_token,
        }
        encrypted_status_update = encryption.encrypt(data)
        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)))
Ejemplo n.º 7
0
def check_for_callback_and_send_delivery_status_to_service(notification):
    service_callback_api = get_service_delivery_status_callback_api_for_service(
        service_id=notification.service_id)

    # If a status callback was provided on the notification or if the service
    # has a service_callback_api record, then queue the callback task.
    if (notification.status_callback_url and
            notification.status_callback_bearer_token) or service_callback_api:
        if dao_service_callbacks_are_failing(notification.service_id):
            current_app.logger.warning(
                f"send_delivery_status_to_service not called for notification_id: {notification.id} due to failing service_id: {notification.service_id}"
            )
            return

        encrypted_notification = create_delivery_status_callback_data(
            notification, service_callback_api)
        send_delivery_status_to_service.apply_async(
            [str(notification.id), encrypted_notification],
            queue=QueueNames.CALLBACKS,
        )
Ejemplo n.º 8
0
def _process_for_status(notification_status, client_name, provider_reference):
    # record stats
    notification = notifications_dao.update_notification_status_by_id(
        provider_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, provider_reference,
                                             notification_status))
        return

    statsd_client.incr('callback.{}.{}'.format(client_name.lower(),
                                               notification_status))

    if not notification.sent_by:
        set_notification_sent_by(notification, client_name.lower())

    if notification.sent_at:
        statsd_client.timing_with_dates(
            'callback.{}.elapsed-time'.format(client_name.lower()),
            datetime.utcnow(), notification.sent_at)

    # queue callback task only if the service_callback_api exists
    service_callback_api = get_service_delivery_status_callback_api_for_service(
        service_id=notification.service_id)

    if service_callback_api:
        encrypted_notification = create_encrypted_callback_data(
            notification, service_callback_api)
        send_delivery_status_to_service.apply_async(
            [str(notification.id), encrypted_notification],
            queue=QueueNames.CALLBACKS)

    success = "{} callback succeeded. reference {} updated".format(
        client_name, provider_reference)
    return success
Ejemplo n.º 9
0
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 = []
    file = open(file_name)

    for ref in file:
        try:
            notification = Notification.query.filter_by(
                client_reference=ref.strip()).one()
            notifications.append(notification)
        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)))