Commit Graph

3549 Commits

Author SHA1 Message Date
Rebecca Law
10fe7d9fe8 Add postage for send-one-off letters.
The postage is set to europe or rest-of-world for international letters, otherwise the template postage is used.

Also set international for letters.
2020-08-03 14:01:59 +01:00
Rebecca Law
ed5e73d548 Set postage for templated letters when the address is not from the united-kingdom.
If the address is from the united-kingdom use the postage from the template.
2020-08-03 12:03:35 +01:00
Katie Smith
c9f663fe76 Check for invalid chars in letter addresses when sending through the API
This uses the new method in notifications-utils to validate for invalid
characters in address blocks.
2020-07-31 08:58:56 +01:00
Leo Hemsted
bdf221a421 add tests for get_earlier_events_for_broadcast_event 2020-07-28 12:10:18 +01:00
Leo Hemsted
36ae5fadf6 add broadcast_event table
It's clear that we need a way to track updates to a broadcast message.
It's also clear that we'll need some kind of audit log that captures
exactly what was sent out in a message.

This commit adds a new database table, `broadcast_event`, which maps 1:1
with CAP XML sent to the CBCs. We'll create one of these just before
sending out.

The main driver for this was that cancel and update messages need to
contain a list of references of all previous messages that they're
amending. This is of format `{sender},{identifier},{sent_timestamp}`,
and the identifier itself needs to be unique for each message.
2020-07-28 12:10:18 +01:00
Leo Hemsted
6302c74565 allow draft -> broadcasting
we haven't built pending_approval functionality yet
2020-07-27 15:51:16 +01:00
Leo Hemsted
483221df7d add broadcast message status transition map
be explicit about which transitions we allow. this is not necessarily an exhaustive list of everything we'll allow
2020-07-27 15:51:16 +01:00
Leo Hemsted
4043e8fa5e reject approvals from people outside your service
even if they're a platform admin
2020-07-27 15:51:16 +01:00
Leo Hemsted
b8e6689f62 allow platform admins to approve their own messages
makes development a lot easier. we should remove this when we go live
2020-07-27 15:51:16 +01:00
Leo Hemsted
0c870e8dcd enforce kwargs when creating user in tests
spent WAY too long trying to figure out why my user wasn't being created
in tests. the user isn't created if their email already exists in the
system, but email isn't a required field when creating!

Note: I tried just removing the check to see if the user already exists,
but 16 tests try and create duplicate users. I'm of the belief we should
just fix all those tests but I didn't have the energy for it right now
2020-07-27 15:51:15 +01:00
Leo Hemsted
8dda1a5123 forbid editing after broadcast message goes live
only allow editing while in:

* draft
* pending-approval
* rejected (not too sure if/how this'll be used, so easier to include it
 for now)
2020-07-27 15:51:15 +01:00
Chris Hill-Scott
bc0cfed468 Merge pull request #2855 from alphagov/contact-list-used-property
Add property to contact lists to say if they’ve ever been used
2020-07-27 11:42:54 +01:00
Rebecca Law
80e4dc8af8 Merge pull request #2935 from alphagov/remove-jobs-incomplete-error
Stop raising error in scheduled task
2020-07-24 07:49:35 +01:00
Pea M. Tyczynska
a2f911b253 Merge pull request #2924 from alphagov/add-contact-block-to-serialize-template
Add contact block to serialize template for v2
2020-07-23 15:42:17 +01:00
Rebecca Law
dd126df122 We have a scheduled task to check that all the jobs have completed, this will catch if an app is shut down and the job is complete yet, we only wait 10 seconds before forcing the app to shut down.
The task was raising a JobIncompleteError, yet it's not an error the task is performing it's task correctly and calling the appropriate task to restart the job.
Also used apply_sync to create the task instead of send_task.
2020-07-22 17:00:20 +01:00
Chris Hill-Scott
dbbff3ba64 Add property to contact lists to say if they’ve ever been used
At the moment we return a count of recent jobs for contact lists, where
recent is defined as being within the service’s data retention period.

This lets us write nice bits of UI copy like ‘used 3 times in the last
7 days’. But it’s hard to write the copy for when the count is 0,
because this could be for one of two reasons:
- the contact list has never been used
- the contact list has been used, but not within the data retention
  period for that channel

At the moment we can’t know which of those reasons is the case, so we
can’t write nice clear content like ‘never been used’.

This commit adds a property to contact lists which says whether they’ve
ever been used.

It also renames the existing, as-yet-unused property to make clear that
it’s only counting within the data retention (so can still be 0 even if
`has_jobs` is `True`).
2020-07-21 15:08:05 +01:00
Katie Smith
da8eaaed44 Update letter data for usage-for-all-services report
Usage for all services is a platform admin report that groups letters by
postage. We want it to show `europe` and `rest-of-world` letters under a
single category of `international`, so this updates the query to do
that and to order appropriately.
2020-07-14 10:22:30 +01:00
Katie Smith
5d47e1cf06 Migration to add international letter rates
New rows giving the prices of letters with a post_class of `europe` and
`rest-of-world` have been added to the `letter_rates` table. All rates
are currently the same for international letters.
2020-07-14 10:22:30 +01:00
Pea M. Tyczynska
fbdfa6416f Merge pull request #2921 from alphagov/remove-statsd-http-api-decorators
Remove statsd http api decorators and turn statsd back on for celery apps
2020-07-14 10:16:44 +01:00
Pea Tyczynska
f6f88750b5 Add contact block to serialize template for v2
This attribute has been requested by a user, and we have not been
serializing it so far.
2020-07-13 17:04:01 +01:00
Leo Hemsted
403885722e trigger send_broadcast_message task when user approves
lets leave the cancellation can of worms alone for now
2020-07-09 18:23:30 +01:00
Leo Hemsted
eca37d0853 add send_broadcast_message task
task takes a brodcast_message_id, and makes a post to the cbc-proxy
for now, hardcode the url to the notify stub. the stub requires template
as the admin/api get it, so use the marshmallow schema to json dump it.
Note - this also required us to tweak the BroadcastMessage.serialize
function so that it converts uuids in to ids - flask's jsonify function
does that for free but requests.post doesn't sadly.

if the request fails (either 4xx or 5xx) just raise an exception and let
it bubble up for now - in the future we'll add retry logic
2020-07-09 18:23:30 +01:00
Leo Hemsted
6b5e2af497 set finishes_at correctly
whoops
2020-07-09 15:36:08 +01:00
Leo Hemsted
efa2e75e56 add broadcast message tests
sorry for big unhelpful test commit
2020-07-09 14:19:58 +01:00
Pea Tyczynska
fff004da2b Turn statsd back on, but not for api main app, only for delivery
workers.
2020-07-09 10:10:24 +01:00
Pea M. Tyczynska
9186083ea7 Merge pull request #2796 from alphagov/split-letters-into-zips-based-on-postage
Split letters into zips based on postage
2020-07-08 11:49:21 +01:00
Pea Tyczynska
9c4205c7c6 Remove statsd decorators from dao functions
This done so that we do not use statsd on our http endpoint.
We decided we do not need metrics that this gave us. If we
change our minds, we will add Prometheus-friendly decorators
instead in the future.
2020-07-07 18:02:24 +01:00
Leo Hemsted
0282a76bf7 rename template.serialize to serialize_for_v2
make it clear that this is for the public api, and we shouldn't add
fields to it without considering impacts

also add the broadcast_messages relationship on service and template to
the exclude from the marshmallow schemas, so it's not included elsewhere
2020-07-06 16:42:31 +01:00
Leo Hemsted
5f337f7914 add broadcast_message to database
new broadcast_message table. contains a whole bunch of timestamps, a
couple of user ids for who created and who approved, some
personalisation and a template id/version. areas is a jsonb field - it
is expected that this will be an array, for example `["england",
"wales"]`

intended valid state transitions are as follows, from an initial status
of draft

* draft -> pending-approval, rejected
* pending-approval -> broadcasting, rejected, (draft maybe)
* broadcasting -> completed, cancelled

rejected, completed, cancelled and technical-failure are terminating
states.

also copy across the enum switching code from migration 0060 (adding
letter type).
2020-07-06 16:37:35 +01:00
Leo Hemsted
7ecd7341b0 add broadcast to template_types and add broadcast_data
had to go through the code and change a few places where we filter on
template types. i specifically didn't worry about jobs or notifications.

Also, add braodcast_data - a json column that might contain arbitrary
broadcast data that we'll figure out as we go. We don't know what it'll
look like, but it should be returned by the API
2020-07-06 15:47:13 +01:00
Pea Tyczynska
efdaadbdf4 Do not update notification to sending if the status is already final
This prevents a race condition when we get delivery receipt before
updating notification to sending, and so the sending status would
supersede the delivered status, and the notification would time out
as temporary-failure after three days.
2020-07-03 17:19:03 +01:00
Pea Tyczynska
61de908c5d Simplify putting letters in right postage folders 2020-07-02 16:26:44 +01:00
David McDonald
7e4acda633 Merge pull request #2910 from alphagov/inbound-sms-metric
Add prometheus client metric for number of inbound text messages
2020-06-30 11:49:57 +01:00
David McDonald
1e253b2257 Add prometheus client metric for number of inbound text messages
As we gradually move from statsd to prometheus, we change the metric to
be a prometheus metric rather than statsd.

The change worth pointing out is that we have dropped the 'successful'
and 'failed' statuses from the metrics. I don't think it's useful to
have these statuses. It's very rare for an inbound message to fail when
we receive it and when it does, we raise an error and see it in our
logs. We aren't going to be looking at a graph of it as it's a rare
event, not typical behaviour that we want to monitor with a graph.
2020-06-30 10:13:55 +01:00
Chris Hill-Scott
5ef9ad2953 Fix sending one-off international text messages
This was broken because sometimes `service.permissions` is a list of
strings (for when we’re caching the service object) and sometimes it’s a
list of permission objects (when we’re dealing with ORM objects).

Because the validator code is shared, the least-messy way to fix it is
to make sure it can handle both types.

It can’t just take a list of permissions as argument, because it uses
other fields on the service.

It would be messy to rewrite the endpoint to use a serialised service
because the tests all expect to be dealing with database objects, so it
would be a faff to change what they’re mocking.
2020-06-29 14:43:33 +01:00
Chris Hill-Scott
40f09097c8 Merge pull request #2908 from alphagov/fix-template-history-created-by
Fix template history created by
2020-06-29 13:12:44 +01:00
David McDonald
12f460adc5 Turn off statsd wrapper for synchronous statsd calls during POSTs
This commit turns off StatsD metrics for the following
- the `dao_create_notification` function
- the `user-agent` metric
- the response times and response codes per flask endpoint

This has been done with the purpose of not having the creation of text
messages or emails call out to StatsD during the request process. These
are the three current metrics that are currently called during the
processing of one of those requests and so have been removed from the
API.

The reason for removing the calls out to StatsD when processing a
request to send a notification is that we have seen two incidents
recently affected by DNS resolution for StatsD (either by a slow down in
resolution time or a failure to resolve). These POST requests are our
most critical code path and we don't want them to be affected by any
potential unforeseen trouble with StatsD DNS resolution.

We are not going to miss the removal of these metrics.
- the `dao_create_notification` metric is rarely/never looked at
- the `user-agent` metric is rarely/never looked at and can be got from
  our logs if we want it
- the response times and response codes per flask endpoint are already
  exposed using the gds metrics python library

I did not remove the statsd metrics from any other parts of the API
because
- As the POST notification endpoints are the main source of web traffic,
  we should have already removed most calls to StatsD which should
  greatly reduce the chance of their being any further issues with
  DNS resolution
- Some of the other metrics still provide value so no point deleting
  them if we don't need to
- The metrics on celery tasks will not affect any HTTP requests from
  users as they are async and also we do not currently have the
  infrastructure set up to replace them with a prometheus HTTP endpoint that
  can be scraped so this would require more work
2020-06-29 12:40:22 +01:00
Chris Hill-Scott
02e5ff61a4 Test that template history updates created by 2020-06-29 12:30:08 +01:00
Chris Hill-Scott
8def7d0d3b Fix serialisation of callbacks
Because the IDs of our callback and inbound SMS APIs were stored in
lists instead of directly on the serialised model they weren’t getting
cast to a string before trying to JSONify them. And JSON doesn’t know
what to do with a UUID object.

For some reason this was only affecting the endpoint for fetching
inbound SMS.
2020-06-26 16:31:49 +01:00
Chris Hill-Scott
9f41e77bf7 Add rate_limit and message_limit to SerialisedService
The API needs these to check whether a service can send a notification.
This commit also updates all the tests in `test_validators.py` to take
a serialised service, not a database object.
2020-06-26 14:10:25 +01:00
Chris Hill-Scott
3ffdb3093b Revert "Revert "Merge pull request #2887 from alphagov/cache-the-serialised-things""
This reverts commit 7e85e37e1d.
2020-06-26 14:10:12 +01:00
Chris Hill-Scott
59aba018bd Ensure rate limit is in serialised service
Once we start using the serialised service to power the `POST`
notifications endpoint it needs to include rate limit to do the rate
limit checks.
2020-06-26 13:46:32 +01:00
Chris Hill-Scott
7e85e37e1d Revert "Merge pull request #2887 from alphagov/cache-the-serialised-things"
This reverts commit b8c2c6b291, reversing
changes made to 351aca2c5a.
2020-06-26 13:42:44 +01:00
Chris Hill-Scott
b8c2c6b291 Merge pull request #2887 from alphagov/cache-the-serialised-things
Serialise and cache services and API keys
2020-06-26 09:18:45 +01:00
Pea Tyczynska
f3c7c098d6 Include postage in zip folder filenames when sending letters
Also split letters into zips in 4 categories based on their postage.

Also have a separate count for zipfiles in each postage category.
2020-06-24 14:59:10 +01:00
Rebecca Law
ce32e577b7 Remove the use of schedule_for in post_notifications.
Years ago we started to implement a way to schedule a notification. We hit a problem but we never came up with a good solution and the feature never made it back to the top of the priority list.

This PR removes the code for scheduled_for. There will be another PR to drop the scheduled_notifications table and remove the schedule_notifications service permission

Unfortunately, I don't think we can remove the `scheduled_for` attribute from the notification.serialized method because out clients might fail if something is missing. For now I have left it in but defaulted the value to None.
2020-06-24 14:54:40 +01:00
Chris Hill-Scott
d16d06fdef Cache serialised services in Redis
Same as we’re doing for templates.

This means avoiding a database call, even for services that don’t hit
our API so often.

They’ll still need to go to the database for the API keys, because we’re
not comfortable putting the API key secrets in Redis.

But once a service has got its keys from the database we commit the
transaction, so the connection can be freed up until we need it again to
insert the notification.
2020-06-24 08:52:12 +01:00
Chris Hill-Scott
6a9818b5fd Cache services and API keys in memory
Same as we’ve done for templates.

For high volume services this should mean avoiding calls to external
services, either the database or Redis.

TTL is set to 2 seconds, so that’s the maximum time it will take for
revoking an API key or renaming a service to propagate.

Some of the tests created services with the same service ID. This
caused intermittent failures because the cache relies on unique service
IDs (like we have in the real world) to key itself.
2020-06-24 08:46:13 +01:00
Chris Hill-Scott
320bca70f7 Serialise service, API keys and permissions
By serialising these straight away we can:
- not go back to the database later, potentially closing the connection
  sooner
- potentially cache the serialised data, meaning we don’t touch the
  database at all
2020-06-23 16:00:41 +01:00
Chris Hill-Scott
5ae3b0fc64 Ensure templates are cached with correct schema
For some reason our V1 get template response wraps the whole template in
a dictionary with one key, `'data'`:
0d99033889/app/template/rest.py (L166)

That means when the admin app caches the response it also caches it in
this format.

The API needs to do the same, otherwise it will be cacheing data with a
schema that the admin app isn’t expecting, and vice-versa.
2020-06-23 15:09:38 +01:00