Commit Graph

3659 Commits

Author SHA1 Message Date
David McDonald
43f1f48093 Add notification ID to SES bounce reason
At the moment we log everytime we get a bounce from SES, however we
don't link it to a particular notification so it's hard to know for what
sub reason a notifcation did not deliver by looking at the logs.

This commit changes this by now looking the bounce reason after we have
found the notification ID and including them together. So if you know
search for a notification ID in Kibana, you will see full logs for why
it failed to deliver.
2020-11-20 14:10:13 +00:00
Leo Hemsted
b72640bf5e refactor cbc proxy and fix tests
moved the lambda invocation to a separate function to keep DRY

asserts on exception types need to be outside of with blocks, or they
won't trip (as the exception will stop execution of the inner with
block). the asserts were also the wrong way round so fixed that.
2020-11-17 13:35:04 +00:00
Leo Hemsted
732c203d3e rename clients to notification_provider_clients
i think it's causing havoc with my attempts to mock stuff in the
`app.clients` directory because it's also accessible at that path. the
name's super vague and doesn't explain what it is anyway
2020-11-17 13:34:58 +00:00
Rebecca Law
171bc74c69 Rename check_character_count method to check_is_message_to_long.
Add different error message for email and text if content is too long.
Use utils version with is_message_too_long method implemented for email templates.
2020-11-09 16:06:57 +00:00
Rebecca Law
5bacfc1df9 Change how we validate the length of templates.
We want to add validation for an email that's too long, that way the user knows why the message is failing. At the moment if an email is too long it will get a technical failure, after the retries fail. This way the email post will get a validation error.

Once this: https://github.com/alphagov/notifications-utils/pull/804 is reverted, we can update the utils version.
2020-11-09 15:54:39 +00:00
Toby Lorne
31f845bbff Revert "Specify sslmode in Cloud Foundry environment variables" 2020-11-09 12:04:40 +00:00
Toby Lorne
cfcc3128c2 db: specify sslmode in Cloud Foundry env
Refer to
https://www.postgresql.org/docs/11/libpq-connect.html#LIBPQ-CONNECT-SSLMODE

GOV.UK PaaS gives us the database URI, and we use the default mode of
postgres auth which prefers a TLS connection instead of a plain TCP
connection

We are now specifying the SSL mode in the URI when establishing our
connection to the database, so that:

* We will not connect to the database via a plaintext connection
* We will verify the database connection against a list of trusted CAs

The RDS CA from which the database's certificate is issued is added into
the Cloud Foundry app container via
925681f19b/manifests/cf-manifest/operations.d/350-diego-cell.yml (L17-L22)

Signed-off-by: Toby Lorne <toby.lornewelch-richards@digital.cabinet-office.gov.uk>
Co-authored-by: David <david.mcdonald@digital.cabinet-office.gov.uk>
2020-11-09 10:47:44 +00:00
Katie Smith
c4075f1fc0 Revert "Tailor message-too-long error message depending on the notification type" 2020-11-03 10:55:15 +00:00
Rebecca Law
184db4fa5d Merge pull request #3024 from alphagov/revert-3020-revert-3000-add-save-sms-api-task
Add a task to save-api-sms for high volume services.
2020-11-02 12:36:19 +00:00
Pea Tyczynska
41d1cf453d Update limit to 1MB and update tests
SES rejects email messages bigger than 10485760 bytes (just over 10 MB per message (after base64 encoding)):
https://docs.aws.amazon.com/ses/latest/DeveloperGuide/quotas.html#limits-message

Base64 is apparently wasteful because we use just 64 different values per byte, whereas a byte can represent
256 different characters. That is, we use bytes (which are 8-bit words) as 6-bit words. There is
a waste of 2 bits for each 8 bits of transmission data. To send three bytes of information
(3 times 8 is 24 bits), you need to use four bytes (4 times 6 is again 24 bits). Thus the base64 version
of a file is 4/3 larger than it might be. So we use 33% more storage than we could.
https://lemire.me/blog/2019/01/30/what-is-the-space-overhead-of-base64-encoding/

That brings down our max safe size to 7.5 MB == 7500000 bytes before base64 encoding

But this is not the end! The message we send to SES is structured as follows:
"Message": {
    'Subject': {
        'Data': subject,
    },
    'Body': {'Text': {'Data': body}, 'Html': {'Data': html_body}}
},
Which means that we are sending the contents of email message twice in one request: once in plain text
and once with html tags. That means our plain text content needs to be much shorter to make sure we
fit within the limit, especially since HTML body can be much byte-heavier than plain text body.

Hence, we decided to put the limit at 1MB, which is equivalent of between 250 and 500 pages of text.
That's still an extremely long email, and should be sufficient for all normal use, while at the same
time giving us safe margin while sending the emails through Amazon SES.
2020-10-29 14:07:49 +00:00
Pea Tyczynska
9708b09ba3 Tailor message-too-long error message
depending on the notification type.

Up until now, only sms messages could get message-too-long error,
but now we also need to validate the size of email messages, so
the message content needs to be tailored to the notification type.
2020-10-29 14:07:48 +00:00
Rebecca Law
29b6f84f6c Revert "Revert "Add a task to save-api-sms for high volume services."" 2020-10-29 11:12:46 +00:00
Toby Lorne
dd012d6831 client: cbc_proxy passes through sent/expires
A BroadcastEvent knows when an event was sent and should expire

We pass through these values directly to the CBC Proxy, because
BroadcastEvent knows how they should be formatted

Signed-off-by: Toby Lorne <toby.lornewelch-richards@digital.cabinet-office.gov.uk>
2020-10-28 11:37:06 +00:00
Toby Lorne
2c29b45c9c Merge pull request #3018 from alphagov/link-tests
Link tests
2020-10-28 09:58:56 +00:00
Rebecca Law
df325c78b7 There seems to be a UTC time bug around the dao_get_uploads_by_service_id function.
To fix the build tonight I'm putting freezing the time for the test. But will investigate further tomorrow.
2020-10-27 17:25:58 +00:00
Rebecca Law
06ff1bf596 Revert "Add a task to save-api-sms for high volume services." 2020-10-27 16:18:57 +00:00
Toby Lorne
dda71bf685 celery: add task for triggering link tests
We want to periodically kick off some link tests, so that:

- we are periodically communicating with the CBC Proxies
- each CBC Proxy is periodically communicating with its CBC

This simulation of traffic to the CBC will give us advance warning if
something is going to break, or is broken, before someone tries to send
a real live message

Signed-off-by: Toby Lorne <toby.lornewelch-richards@digital.cabinet-office.gov.uk>
Co-authored-by: Richard <richard.baker@digital.cabinet-office.gov.uk>
Co-authored-by: Pea <pea.tyczynska@digital.cabinet-office.gov.uk>
2020-10-27 15:39:28 +00:00
Toby Lorne
7542709455 clients: cbc_proxy sends message_type
When we ask the CBC Proxy to send a message, we should specify that we
want to send a real message, when we want a real message

We will do this by specifying the message_type which can have 4 types, 3
of which represent a real message:

| Name   | Effect                   |
| ------ | ------------------------ |
| alert  | Create an alert          |
| update | Update an existing alert |
| cancel | Cancel an existing alert |
| test   | Send a link test         |

We will use message_type to represent the table above

Signed-off-by: Toby Lorne <toby.lornewelch-richards@digital.cabinet-office.gov.uk>
Co-authored-by: Richard <richard.baker@digital.cabinet-office.gov.uk>
Co-authored-by: Pea <pea.tyczynska@digital.cabinet-office.gov.uk>
2020-10-27 15:24:02 +00:00
Rebecca Law
ef416a64ed Merge pull request #3000 from alphagov/add-save-sms-api-task
Add a task to save-api-sms for high volume services.
2020-10-27 14:41:51 +00:00
Rebecca Law
a32e418bab Make sure that letters can not use the high volume service code path.
This code is already restricted to SMS and email, so this is only to make it obvious if there is a code refactor down the line. Perhaps this is overkill and we back out this commit.
2020-10-27 12:05:59 +00:00
Toby Lorne
be90455944 Add task to send canary to cbc proxy
Create and schedule a Celery task that tests if we
can send a canary message to cbc proxy.

This will help us know if something happens to our
connection to cbc proxy.

Signed-off-by: Toby Lorne <toby.lornewelch-richards@digital.cabinet-office.gov.uk>
Co-authored-by: Pea <pea.tyczynska@digital.cabinet-office.gov.uk>
Co-authored-by: Richard <richard.baker@digital.cabinet-office.gov.uk>
2020-10-27 10:38:09 +00:00
Toby Lorne
052de84c9e clients: cbc_proxy client has canary method
The CBC Proxy is essentially a lambda function which we invoke with
various arguments.

A way in which this can fail is that the notifications-api app invoking
the function may not be able, any longer, to invoke the function.

This could be caused by, for example:
* an egress restriction preventing access to eu-west-2.lambda.amazonaws.com
* a network partition preventing access to eu-west-2.lambda.amazonaws.com
* the app's credentials have been rotated or revoked

If we invoke a simple "canary" lambda function for which the app should
have access to invoke, and check it for failures, we will know quickly
if something is likely to be broken.

This is especially important for cell broadcasts compared to email/SMS
because we always have a baseline of traffic for email/SMS, and so any
failure is observed almost immediately. This is not true for CB where we
may expect to only see one CB message every week/month/quarter/year, as
opposed to every minute or second for email/SMS.

Signed-off-by: Toby Lorne <toby.lornewelch-richards@digital.cabinet-office.gov.uk>
Co-authored-by: Pea <pea.tyczynska@digital.cabinet-office.gov.uk>
2020-10-26 17:14:08 +00:00
Toby Lorne
d22adb7813 broadcasts: do not send description to cbc_proxy
"areas" and "simple_polygons" in "transmitted_areas" do not have the
same length

as an example, choosing the area "england" results in a single item in
"areas" but many polygons in "simple_polygons"

therefore zipping these two together gives a list of areas:
* of length 1
* containing only new grimsby

which is not what we want

as the CBC does not care about the areaDesc field within CAP, we should
omit it from the function invocation and delegate the contents of
areaDesc to the CBC Proxy implementation

Signed-off-by: Toby Lorne <toby.lornewelch-richards@digital.cabinet-office.gov.uk>
Co-authored-by: Richard <richard.baker@digital.cabinet-office.gov.uk>
Co-authored-by: David <david.mcdonald@digital.cabinet-office.gov.uk>
2020-10-26 15:16:33 +00:00
Toby Lorne
ca2bea8ae6 broadcasts: test helper uses areas from message
instead of looking at "transmitted_areas" argument in the
create_broadcast_event, we should use the areas from the broadcast
message

we should be explicit in our tests about which areas we are sending, the
tests were implicitly using the default, rather than the areas from the
broadcast message which was confusing

Signed-off-by: Toby Lorne <toby.lornewelch-richards@digital.cabinet-office.gov.uk>
Co-authored-by: Richard <richard.baker@digital.cabinet-office.gov.uk>
Co-authored-by: David <david.mcdonald@digital.cabinet-office.gov.uk>
2020-10-26 15:14:26 +00:00
Leo Hemsted
902a2dde94 Merge pull request #3014 from alphagov/get-query-in-50k-batches
Optimise dao_get_letters_to_be_printed query
2020-10-26 13:23:17 +00:00
Rebecca Law
3dee4ad310 Add a task to save-api-sms for high volume services.
When we initially added a new task to persist the notifications for a high volume service we wanted to implement it as quickly as possible, so ignored SMS.
This will allow a high volume service to send SMS, the SMS will be sent to a queue to then persist and send the SMS, similar to emails.

At this point I haven't added a new application to consume the new save-api-sms-tasks. But we can add a separate application or be happy with how the app scales for both email and sms.
2020-10-26 13:09:37 +00:00
Leo Hemsted
3bc3ed88b3 use yield_per instead of limit
limit means we only return 50k letters, if there are more than that for
a service we'll skip them and they won't be picked up until the next
day.

If you remove the limit, sqlalchemy prefetches query results so it can
build up ORM results, for example collapsing joined rows into single
objects with chidren. SQLAlchemy streams the data into a buffer, and
normally will still prefetch the entire resultset so it can ensure
integrity of the session, (so that if you modify one result that is
duplicated further down in the results, both rows are updated in the
session for example). However, we don't care about that, but we do care
about preventing the result set taking up too much memory. We can use
`yield_per` to yield from sqlalchemy to the iterator (in this case the
`for letter in letters_awaiting_sending` loop in letters_pdf_tasks.py) -
this means every time we hit 10000 rows, we go back to the database to
get the next 10k. This way, we only ever need 10k rows in memory at a
time.

This has some caveats, mostly around how we handle the data the query
returns. They're a bit hard to parse but I'm pretty sure the notable
limitations are:

* It's dangerous to modify ORM objects returned by yield_per queries
* It's dangerous to join in a yield_per query if you think there will be
  more than one row per item (for example, if you join from notification
  to service, there'll be multiple result rows containing the same
  service, and if these are split over different yield chunks, then we
  may experience undefined behaviour.

These two limitations are focused around there being no guarantee of
having one unique row per item.

For more reading:
https://docs.sqlalchemy.org/en/13/orm/query.html?highlight=yield_per#sqlalchemy.orm.query.Query.yield_per
https://www.mail-archive.com/sqlalchemy@googlegroups.com/msg12443.html
2020-10-26 13:01:34 +00:00
Toby Lorne
fdacb2e0d7 broadcasts: remove references to cbc stub
We are phasing out our cbc-proxy stub which displayed CAP XML messages

We are in the process of testing with real CBCs, so maintaining our own
stub is not useful

This commit
* removes the HTTP POST requests to the CBC proxy
* writes up the update/cancel methods of the cbc_client (not impl)

Signed-off-by: Toby Lorne <toby.lornewelch-richards@digital.cabinet-office.gov.uk>
2020-10-26 10:23:49 +00:00
Leo Hemsted
ed182c2a22 return just the columns we need for collating letters
previously we were returning the entire ORM object. Returning columns
has a couple of benefits:

* Means we can join on to services there and then, avoiding second
  queries to get the crown status of the service later in the collate
  flow.
* Massively reduces the amount of data we return - particularly free
  text fields like personalisation that could be potentially quite big.
  5 columns rather than 26 columns.
* Minor thing, but will skip some CPU cycles as sqlalchemy will no
  longer construct an ORM object and try and keep track of changes. We
  know this function doesn't change any of the values to persist them
  back, so this is an unnecessary step from sqlalchemy.

Disadvantages are:

* The dao_get_letters_to_be_printed return interface is now much more
  tightly coupled to the get_key_and_size_of_letters_to_be_sent_to_print
  function that calls it.
2020-10-23 20:01:18 +01:00
Toby Lorne
aa002afd31 clients: cbc_proxy actions accepts areas param
related:
https://github.com/alphagov/notifications-broadcasts-infra/pull/23

Signed-off-by: Toby Lorne <toby.lornewelch-richards@digital.cabinet-office.gov.uk>
2020-10-23 17:09:00 +01:00
Chris Hill-Scott
88cd92b946 Revert "Remove the upload letters permission" 2020-10-23 15:14:37 +01:00
Chris Hill-Scott
e7c1f7c60e Merge pull request #3001 from alphagov/remove-upload-letters-permission
Remove the upload letters permission
2020-10-23 14:27:48 +01:00
Leo Hemsted
4b61060d32 stream notifications when collating zip files
we had issues where we had 150k 2nd class notifications, and the collate
task never ran properly, presumably because the volume of data being
returned was too big.

to try and help with this, we can switch to streaming rather than using
`.all` and building up lists of data. This should help, though the
initial query may be a problem still.
2020-10-23 12:20:26 +01:00
David McDonald
3dcb97c45a Remove 'INSOLVENCY' from zip files for insolvency letters
This is at request of DVLA. They would prefer to have zip files with the
same number of arguments in the name. After being offered a few
different options, such as including an org and service id for all zips,
they chose to just remove the 'INSOLVENCY' tag.

For more context see PR that added the tag
https://github.com/alphagov/notifications-api/pull/3006
2020-10-23 09:58:28 +01:00
David McDonald
890a66de46 Merge pull request #3003 from alphagov/staging-preview-cbc
Non-production environments invoke CBC Proxy during broadcast event creation
2020-10-22 16:21:11 +01:00
Toby Lorne
ff1ffc7fba clients: cbc_proxy lambda client is unabbreviated
for code clarity

Signed-off-by: Toby Lorne <toby.lornewelch-richards@digital.cabinet-office.gov.uk>
2020-10-22 12:22:11 +01:00
Toby Lorne
c9eb9c8622 clients: cbc_proxy client tests remove unused stmt
Signed-off-by: Toby Lorne <toby.lornewelch-richards@digital.cabinet-office.gov.uk>
2020-10-22 12:20:31 +01:00
Pea Tyczynska
deb360846d Mark letters from insolvency service
So that DVLA knows to process them separately to avoid issues.
2020-10-21 16:56:18 +01:00
Pea Tyczynska
9ac65ee95c Start sending letters from insolvency service again 2020-10-21 16:56:18 +01:00
Pea Tyczynska
d745ba310e Divide letters by service when putting in ZIPs
When letters are sent to DVLA, we will now put them in a separate
ZIP file for each service, so that if there are printing issues
due to bad files from one service, other services will hopefully
not be affected by that.
2020-10-21 15:19:06 +01:00
Toby Lorne
62951fa039 clients: cbc_proxy tests for handling lambda response
Signed-off-by: Toby Lorne <toby.lornewelch-richards@digital.cabinet-office.gov.uk>
2020-10-20 15:26:27 +01:00
Toby Lorne
75de4abd47 clients: cbc_proxy handles lambda invoke response
Signed-off-by: Toby Lorne <toby.lornewelch-richards@digital.cabinet-office.gov.uk>
2020-10-20 15:18:11 +01:00
Toby Lorne
73507b3abc clients: cbc_proxy invokes hardcoded function
right now we are doing an end-to-end journey with a CBC from Notify (the
CBE) and we would like to approve a broadcast in notify and have it
appear on our test handset

in order to do this, we:
* hook up the lambda that we made in the correct VPC to cbc_proxy client
* test that it is called correctly

Signed-off-by: Toby Lorne <toby.lornewelch-richards@digital.cabinet-office.gov.uk>
Co-authored-by: Pea <pea.tyczynska@digital.cabinet-office.gov.uk>
Co-authored-by: Katie <katie.smith@digital.cabinet-office.gov.uk>
2020-10-20 14:00:53 +01:00
Toby Lorne
ee79768d43 clients: cbc_proxy client uses _ld not _lambda
_ld is better than _lambda because it causes primitive python syntax
highlighting to not get confused

_lambda is better than _ld because it is less jargon

Signed-off-by: Toby Lorne <toby.lornewelch-richards@digital.cabinet-office.gov.uk>
Co-authored-by: Pea <pea.tyczynska@digital.cabinet-office.gov.uk>
Co-authored-by: Katie <katie.smith@digital.cabinet-office.gov.uk>
2020-10-20 13:59:52 +01:00
Toby Lorne
14f8e7a5ff clients: cbc_proxy client inits lambda client
Using correct:
* key id
* secret key
* region

Signed-off-by: Toby Lorne <toby.lornewelch-richards@digital.cabinet-office.gov.uk>
Co-authored-by: Pea <pea.tyczynska@digital.cabinet-office.gov.uk>
Co-authored-by: Katie <katie.smith@digital.cabinet-office.gov.uk>
2020-10-20 13:33:51 +01:00
Toby Lorne
2cc0a65851 celery: broadcast msg create invokes cbc proxy
When we create a broadcast message, we should invoke the cbc proxy to
send a cap message

Either a function will be invoked within AWS, or a noop function call
is made, depending on the environment

We have only implemented CB message creation in the CBC Proxy, without
polygons, therefore we:
* only invoke the CBC Proxy during message creation
* only send description, identifier, and hard-coded headline

Signed-off-by: Toby Lorne <toby.lornewelch-richards@digital.cabinet-office.gov.uk>
Co-authored-by: Pea <pea.tyczynska@digital.cabinet-office.gov.uk>
Co-authored-by: Katie <katie.smith@digital.cabinet-office.gov.uk>
2020-10-20 11:57:26 +01:00
Chris Hill-Scott
182bfa7e10 Remove the upload letters permission
As of https://github.com/alphagov/notifications-admin/pull/3690 it’s no
longer referred to.
2020-10-20 11:46:11 +01:00
Pea Tyczynska
30bd311eb1 Temporarily do not send letters from Insolvency Service
to DVLA. This is a temporary measure over the weekend so that
DVLA can catch up with all other letters.

We should revert this on Monday 19.10.2020
2020-10-16 16:13:32 +01:00
Chris Hill-Scott
8b123fd6a4 Merge pull request #2996 from alphagov/serialise-broadcast-template-content
Serialise content for broadcast templates
2020-10-15 16:35:10 +01:00
Rebecca Law
b2ff4277c9 Adding service_id to the sort order for the letters being sent to print.
We have had a few instances where letters have caused problems. Particularly for precompiled letters, often the issue comes from the same service.
The hope is that by adding a sort order this will help the print provider narrow down the problem.

There is a small degradation of the performance of the query, but it's not enough to concern me.
2020-10-15 09:39:07 +01:00