Commit Graph

5001 Commits

Author SHA1 Message Date
Ben Thorner
8c7ad16452 Merge pull request #3503 from alphagov/allow-repeat-send-letter
Don't error sending a letter that's sent already
2022-04-12 16:04:54 +01:00
Ben Thorner
413c6c4c26 Move check for existing letter earlier in endpoint
In response to: [^1].

[^1]: https://github.com/alphagov/notifications-api/pull/3503#discussion_r848426047
2022-04-12 15:51:06 +01:00
Leo Hemsted
91200a2088 Merge pull request #3502 from alphagov/provider-report
add new daily sms provider volume report
2022-04-12 15:48:24 +01:00
Ben Thorner
a5e0fd6104 Merge pull request #3508 from alphagov/redis-ssl-181796569
Prepare to switch to Redis on PaaS
2022-04-12 15:47:46 +01:00
Ben Thorner
44d90b0a4f Remove redundant ternary on SMS client FROM_NUMBER
Logs over the past 14 days confirm we never call this code with
None as the sender, so it's safe to remove the ternary.
2022-04-12 14:59:21 +01:00
Ben Thorner
fb405977fa Allow REDIS_URL to optionally come from PaaS
This is to support a migration from Redislabs to PaaS native Redis,
allowing us to toggle between old and new using the env vars for
the instance - without needing to change the code.
2022-04-12 14:48:08 +01:00
Leo Hemsted
259d4a0569 add new daily sms provider volume report
code generally lifted almost exactly from the daily_volumes_report, but
per provider and only for SMS.
2022-04-11 13:42:40 +01:00
Ben Thorner
3f5a811e8f Further tweaks to SMS provider resting points 2022-04-11 10:44:57 +01:00
Ben Thorner
5810d46d35 Don't error sending a letter that's sent already
Fixes this error (in Admin):

      File "/home/vcap/app/app/notify_client/notification_api_client.py", line 74, in send_precompiled_letter
        return self.post(url='/service/{}/send-pdf-letter'.format(service_id), data=data)
      File "/home/vcap/app/app/notify_client/__init__.py", line 59, in post
        return super().post(*args, **kwargs)
      File "/home/vcap/deps/0/python/lib/python3.9/site-packages/notifications_python_client/base.py", line 48, in post
        return self.request("POST", url, data=data)
      File "/home/vcap/deps/0/python/lib/python3.9/site-packages/notifications_python_client/base.py", line 64, in request
        response = self._perform_request(method, url, kwargs)
      File "/home/vcap/deps/0/python/lib/python3.9/site-packages/notifications_python_client/base.py", line 118, in _perform_request
        raise api_error
    notifications_python_client.errors.HTTPError: 500 - Internal server error

Due to this error (in API):

      File "/home/vcap/app/app/service/send_notification.py", line 178, in send_pdf_letter_notification
        raise e
      File "/home/vcap/app/app/service/send_notification.py", line 173, in send_pdf_letter_notification
        letter = utils_s3download(current_app.config['TRANSIENT_UPLOADED_LETTERS'], file_location)
      File "/home/vcap/deps/0/python/lib/python3.9/site-packages/notifications_utils/s3.py", line 53, in s3download
        raise S3ObjectNotFound(error.response, error.operation_name)
    notifications_utils.s3.S3ObjectNotFound: An error occurred (NoSuchKey) when calling the GetObject operation: The specified key does not exist.

I checked the DB to verify the letter does actually exist i.e. it
is an instance of the problem we're fixing here.
2022-04-08 17:20:44 +01:00
Ben Thorner
6ca550a1a6 Merge pull request #3497 from alphagov/broadcast-alert-earlier-181423293
Alert earlier when a broadcast is approved
2022-04-07 10:34:23 +01:00
Ben Thorner
190c2b5122 Fix broadcast alert not triggering PagerDuty
We previously decided against this [^1] but the lambda alerts are
not a replacement for this one.

Even if both sets of alerts go off, we expect PagerDuty to aggregate
them into a single notification.

[^1]: 65c21f694c
2022-04-06 14:06:03 +01:00
Ben Thorner
13b01579c8 Limit provider history to 100 results
This stops the pages being slow to load and defers the need to add
any pagination. Only the most recent data is likely to be relevant.
2022-04-06 11:53:01 +01:00
Ben Thorner
a8ce4cabc3 Adjust resting positions for SMS providers
It's worth noting this will break the Admin page to edit provider
priorities, which currently works in units of 10. We already have
work planned to fix this [^1] and it's not an immediate problem.

The automatic adjustment algorithm will continue to work properly
as it can cope with increments smaller than 10 [^2].

[^1]: https://www.pivotaltracker.com/story/show/181681739
[^2]: b145a29935/app/dao/provider_details_dao.py (L122)
2022-04-06 10:35:21 +01:00
Katie Smith
badd0e0894 Bump Flask and itsdangerous
This bumps Flask to version 2.1.0, which requires some minor changes to
the app code and itsdangerous to also be bumped.
2022-04-05 17:06:08 +01:00
Ben Thorner
f4cc87dc77 Remove excess indentation in broadcast alert
In response to: [^1].

[^1]: https://github.com/alphagov/notifications-api/pull/3497#discussion_r842747749
2022-04-05 14:42:24 +01:00
Ben Thorner
e84014b86d Update broadcast approval alert content
This now links to the new runbook for the alert.
2022-04-05 12:57:09 +01:00
Ben Thorner
779b8e941f Rewrite broadcast Zendesk alert at approval time
The new alert happens earlier but is otherwise the same:

- We only create a ticket in Production.
- We only create a ticket on approval.

I took this opportunity to refactor the alert as a private function
and test this specifically in detail to avoid lots of repetitive
mocks, which are required when calling the main "update" function.

One test I haven't preserved was for when the "names" array is empty,
as this was added for a legacy data integrity scenario [^1].

[^1]: bf0bf4e31c
2022-04-05 12:57:08 +01:00
Ben Thorner
c7c5793da4 Shorten name of broadcast utility function
This is doing more than just validating and updating an is about to
do even more. Saying "update" is broad enough to cover the others.
2022-04-05 11:35:33 +01:00
Ben Thorner
3b705a780a Extract broadcast validations into separate fn
This makes it easier to see the key stages of the function, which
we're about to make a bit bigger.
2022-04-05 11:29:36 +01:00
Ben Thorner
0d07220923 Fix log for sending SMS to be generic per client
This was a mistake in [^1].

[^1]: 3b082477f0 (diff-95316b574f974237b3b7ce453fec09628bd1062087154789ff4d0176ea23c460R52)
2022-04-05 10:46:14 +01:00
Ben Thorner
e6fffc00da Add temporary log to check if code is in use
In response to: [^1].

[^1]: https://github.com/alphagov/notifications-api/pull/3493#discussion_r838477599
2022-03-31 10:32:18 +01:00
Ben Thorner
7d92a0869a Remove per-client SMS exception classes
In response to: [^1].

The stacktrace conveys the same and more information. We don't do
anything different for each exception class, so there's no value
in having three of them over one exception.

I did think about DRYing-up the duplicate exception behaviour into
the base class one. This isn't ideal because the base class would
be making assumptions about how inheriting classes make requests,
which might change with future providers. Although it might be nice
to have more info in the top-level message, we'll still get it in
the stacktrace e.g.

    ValueError: Expected 'code' to be '0'
    During handling of the above exception, another exception occurred:
    app.clients.sms.SmsClientResponseException: SMS client error (Invalid response JSON)

    requests.exceptions.ReadTimeout
    During handling of the above exception, another exception occurred:
    app.clients.sms.SmsClientResponseException: SMS client error (Request failed)

[^1]: https://github.com/alphagov/notifications-api/pull/3493#discussion_r837363717
2022-03-30 13:38:50 +01:00
Ben Thorner
a2e1d03009 Require "sender" argument to send_sms method
In response to [^1].

[^1]: https://github.com/alphagov/notifications-api/pull/3493#discussion_r836616675
2022-03-30 13:38:48 +01:00
Ben Thorner
015152bab2 Add boilerplate for sending SMS via Reach
This works in conjunction with the new SMS provider stub [^1].

Local testing:

- Run the migrations to add Reach as an inactive provider.
- Activate the Reach provider locally and deactivate the others.

      update provider_details set priority = 100, active = false where notification_type = 'sms';
      update provider_details set active = true where identifier = 'reach';

- Tweak your local environment to point at the SMS stub.

      export REACH_URL="http://host.docker.internal:6300/reach"

- Start / restart Celery to pick up the config change.
- Send a SMS via the Admin app and see the stub log it.
- Reset your environment so you can send normal SMS.

      update provider_details set active = true where notification_type = 'sms';
      update provider_details set active = false where identifier = 'reach';

[^1]: https://github.com/alphagov/notifications-sms-provider-stub/pull/10
2022-03-30 13:38:46 +01:00
Ben Thorner
27ddc4501e DRY-up overriding shortcode with sender
This avoids duplicating the logic when we add a new provider.
2022-03-30 13:37:01 +01:00
Ben Thorner
3b082477f0 DRY-up logging and metrics for sending SMS
This avoids duplicating it as we add a new provider and means we
can test it all in one place (although it wasn't tested before).

I'm not sure why the previous code did "super(..)__init__" in a
non-init function - it's a bit late! - so I've just replaced it
with a call to the new "init_app" function in the parent class.
2022-03-30 13:37:00 +01:00
Ben Thorner
22e055f4d1 DRY-up recording the outcome of SMS sending
This reduces the code to copy when we add a new provider. I don't
think we need to log the URL or status code each time:

- The URL is always the same.
- A "200" status code is implicit in "success".
- Other status codes will be reported as exceptions.

Removing these specific elements means "record_outcome" is generic
and can be de-duplicated in the base class.
2022-03-30 13:36:58 +01:00
Ben Thorner
35f710bdf3 Remove redundant "multi" parameter for MMG client
This is never overridden and can't be used in practie because all
SMS clients have to use the same interface. Removing it will make
it possible to DRY-up some of the code in this method.
2022-03-30 13:36:57 +01:00
Ben Thorner
3988a6cd07 Include exception info in SMS warning log
This makes it easier to debug failures when adding a new provider.
2022-03-30 13:36:56 +01:00
Ben Thorner
e6e16a81d0 Simplify getting name of email / sms providers
Previously we used a combination of "provider.name" and "get_name()"
which was confusing. Using a non-property function also gave me the
impression that the name was more dynamic than it actually is.
2022-03-30 13:36:55 +01:00
Ben Thorner
eef4868651 Merge pull request #3492 from alphagov/reach-basics-181665654
Add boilerplate for Reach SMS callbacks
2022-03-29 16:32:12 +01:00
Ben Thorner
13245f74d4 Merge pull request #3491 from alphagov/fix-broadcast-perm-command
Fix missing permission for dev broadcast users
2022-03-28 14:03:54 +01:00
Ben Thorner
b439fd0718 Add boilerplate for Reach SMS callbacks
This is enough to update a notification in DB:

1. First create a notification in the UI and sent it.

2. Then reset its attributes to pretend it's for Reach.

    update notifications set
      sent_at = null,
      sent_by = null,
      notification_status='sending'
    where id='some-uuid';

3. Change "notification_id" to "<some-uuid>" in the code.

4. Call the boilerplate endpoint for Reach callbacks.

    curl -X POST localhost:6011/notifications/sms/reach

Interestingly there's no foreign key constraint on "sent_by" in the
DB, so this just works: the notification is updated.
2022-03-24 16:56:33 +00:00
Ben Thorner
0b6f1d818b Remove redundant debug logs for providers
We don't log at this level and can always add them in manually if
we need to debug something locally.
2022-03-24 16:47:27 +00:00
Ben Thorner
3b519a2188 Fix missing permission for dev broadcast users
This is normally added automatically [^1].

[^1]: b145a29935/app/dao/broadcast_service_dao.py (L69)
2022-03-24 12:36:23 +00:00
Ben Thorner
b145a29935 Merge pull request #3488 from alphagov/fix-provider-adjustment-bug-181574489
Fix SMS priority adjustment if only 1 provider
2022-03-22 16:21:53 +00:00
Rebecca Law
f5f860a34b Merge pull request #3487 from alphagov/set-free-allowance-to-zero
Set free allowance to zero if previous year is zero in command to set free allowance for a year
2022-03-22 10:45:45 +00:00
Rebecca Law
926eb5b48f Update app.commands.populate_annual_billing_with_defaults so that if the
service has zero free allowance in the previous year, set this year to
zero as well.
2022-03-22 10:02:32 +00:00
Ben Thorner
7bffe9ee50 Log Service ID when we get a duplicate receipt
This will make it easier to group these logs if a service complains
about the issue.
2022-03-21 15:43:08 +00:00
Ben Thorner
b4d4133b1f Fix SMS priority adjustment if only 1 provider
Fixes:

    >       reduced_provider = providers[identifier]
    E       KeyError: 'firetext'

Note that the mock return value in the other test was wrong [^1].

[^1]: bff97f0bbe/app/dao/provider_details_dao.py (L73)
2022-03-17 17:09:13 +00:00
Rebecca Law
4b6de79dae Merge pull request #3484 from alphagov/update-free-allowance-2022
Free allowance rates for 2022
2022-03-15 14:00:09 +00:00
Rebecca Law
8402e7c97b Free allowance rates for 2022
Update the map for determine the free allowance (aka: free sms fragments) for services.
2022-03-15 12:35:39 +00:00
Ben Thorner
6cd3650b3f Merge pull request #3482 from alphagov/fix-docker-host-181498273
Fix letter functional tests to work in Docker
2022-03-15 12:32:54 +00:00
Leo Hemsted
2fbe9e85ac Merge pull request #3479 from alphagov/auto-retry-stuck-av-letters
automatically retry letters stuck in pending-virus-scan
2022-03-15 11:43:42 +00:00
Leo Hemsted
9e8df8b623 remove "letters stuck pending av" runbook
there's not anything we know we need to do now that we resolve stuck
letters automatically. Letters couuld still get into this state, so it's
worth alerting us. However, we don't have anything concrete that we know
how to fix these letters, so we should just remove the runbook entirely.
2022-03-10 14:10:01 +00:00
Rebecca Law
cd78361be1 Merge pull request #3477 from alphagov/volume-stat-report
Report for total notifications sent per day for each channel.
2022-03-09 13:42:00 +00:00
Rebecca Law
29ebf0eb9a Move the casting the column as an int to the the endpoint, we need to
convert the Decimal data type to datatype json can work with.
2022-03-09 12:29:58 +00:00
Ben Thorner
3fab7a0ca9 Fix letter functional tests to work in Docker
Currently "test_send_letter_notification_via_api" fails at the final
stage in create-fake-letter-response-file [^1]:

        requests.exceptions.ConnectionError: HTTPConnectionPool(host='localhost', port=6011): Max retries exceeded with url: /notifications/letter/dvla (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0xffff95ffc460>: Failed to establish a new connection: [Errno 111] Connection refused'))

This only applies when running in Docker so the default should still
be "localhost" for the Flask app itself.

[^1]: 5093064533/app/celery/research_mode_tasks.py (L57)
2022-03-09 11:07:50 +00:00
David McDonald
0d952b4d8c Reduce timeout for service callback attempt to 5 seconds
It is currently 60 seconds but we have had two incidents in the
past week where there is a connection error talking to a service
and the request takes up to 60 seconds before failing. When this
happens, if there are a few of these callbacks then all of them
will completely hog the service callback worker and build up a big
queue of all the other service callbacks.

5 seconds has been chosen as that is still a pretty decent length
time for a simple web request that should just be giving them a
little bit of information for them to store. 5 seconds should be a
sufficient enough reduction that we dramatically reduce this problem
for the moment.

Open to this number
being changed in the future based on how we see it perform.
2022-03-08 13:05:32 +00:00
Leo Hemsted
00259893f1 automatically retry letters stuck in pending-virus-scan
Since sept 2019 we've had to log on to production around once every
twenty days to restart the virus scan task for a letter. Most of the
time this is just a case of making sure the file is in the scan bucket,
and then triggering the task. If the file isn't in the scan bucket we'd
need to do some more manual investigation to find out exactly where the
file got stuck, but I can only remember times when it's been in the scan
bucket.

So if the file is in the scan bucket, we can just check that with code
and kick the task off automatically.
2022-03-07 18:31:46 +00:00