Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MLPAB-2321: Delete scheduled tasks when CANNOT_REGISTER lpa-updated event received #1640

Merged
merged 15 commits into from
Nov 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ coverage:
- "./cmd/mock-onelogin/main.go"
- "./cmd/mock-os-api/main.go"
- "./cmd/schedule-runner/main.go"
- "./cmd/scheduled-task-adder/main.go"
- "./internal/identity/yoti*"
- "./internal/notify/email.go"
- "./internal/notify/sms.go"
Expand Down
49 changes: 35 additions & 14 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -127,32 +127,59 @@ delete-all-items: ##@dynamodb deletes and recreates lpas dynamodb table
--global-secondary-indexes file://dynamodb-lpa-gsi-schema.json

emit-evidence-received: ##@events emits an evidence-received event with the given LpaUID e.g. emit-evidence-received uid=abc-123
$(eval BODY := $(shell echo '{"version":"0","id":"63eb7e5f-1f10-4744-bba9-e16d327c3b98","detail-type":"evidence-received","source":"opg.poas.sirius","account":"653761790766","time":"2023-08-30T13:40:30Z","region":"eu-west-1","resources":[],"detail":{"UID":"$(uid)"}}' | sed 's/"/\\"/g'))

docker compose -f docker/docker-compose.yml exec localstack awslocal lambda invoke \
--endpoint-url=http://localhost:4566 \
--region eu-west-1 \
--function-name event-received text \
--payload '{"version":"0","id":"63eb7e5f-1f10-4744-bba9-e16d327c3b98","detail-type":"evidence-received","source":"opg.poas.sirius","account":"653761790766","time":"2023-08-30T13:40:30Z","region":"eu-west-1","resources":[],"detail":{"UID":"$(uid)"}}'
--payload '{"Records": [{"messageId": "19dd0b57-b21e-4ac1-bd88-01bbb068cb78", "body": "$(BODY)"}]}'

emit-reduced-fee-approved: ##@events emits a reduced-fee-approved event with the given LpaUID e.g. emit-reduced-fee-approved uid=abc-123
docker compose -f docker/docker-compose.yml exec localstack awslocal lambda invoke \
--endpoint-url=http://localhost:4566 \
--region eu-west-1 \
--function-name event-received text \
--payload '{"version":"0","id":"63eb7e5f-1f10-4744-bba9-e16d327c3b98","detail-type":"reduced-fee-approved","source":"opg.poas.sirius","account":"653761790766","time":"2023-08-30T13:40:30Z","region":"eu-west-1","resources":[],"detail":{"UID":"$(uid)"}}'
$(eval BODY := $(shell echo '{"version":"0","id":"abcdef01-2345-6789-abcd-ef0123456789","detail-type":"reduced-fee-approved","source":"opg.poas.sirius","account":"653761790766","time":"2024-01-01T12:00:00Z","region":"eu-west-1","resources":[],"detail":{"uid":"$(uid)"}}' | sed 's/"/\\"/g'))

docker compose -f docker/docker-compose.yml exec localstack awslocal lambda invoke \
--endpoint-url=http://localhost:4566 \
--region eu-west-1 \
--function-name event-received text \
--payload '{"Records": [{"messageId": "19dd0b57-b21e-4ac1-bd88-01bbb068cb78", "body": "$(BODY)"}]}'

emit-reduced-fee-declined: ##@events emits a reduced-fee-declined event with the given LpaUID e.g. emit-reduced-fee-declined uid=abc-123
$(eval BODY := $(shell echo '{"version":"0","id":"63eb7e5f-1f10-4744-bba9-e16d327c3b98","detail-type":"reduced-fee-declined","source":"opg.poas.sirius","account":"653761790766","time":"2023-08-30T13:40:30Z","region":"eu-west-1","resources":[],"detail":{"UID":"$(uid)"}}' | sed 's/"/\\"/g'))

docker compose -f docker/docker-compose.yml exec localstack awslocal lambda invoke \
--endpoint-url=http://localhost:4566 \
--region eu-west-1 \
--function-name event-received text \
--payload '{"version":"0","id":"63eb7e5f-1f10-4744-bba9-e16d327c3b98","detail-type":"reduced-fee-declined","source":"opg.poas.sirius","account":"653761790766","time":"2023-08-30T13:40:30Z","region":"eu-west-1","resources":[],"detail":{"UID":"$(uid)"}}'
--payload '{"Records": [{"messageId": "19dd0b57-b21e-4ac1-bd88-01bbb068cb78", "body": "$(BODY)"}]}'


emit-more-evidence-required: ##@events emits a more-evidence-required event with the given LpaUID e.g. emit-more-evidence-required uid=abc-123
$(eval BODY := $(shell echo '{"version":"0","id":"63eb7e5f-1f10-4744-bba9-e16d327c3b98","detail-type":"more-evidence-required","source":"opg.poas.sirius","account":"653761790766","time":"2023-08-30T13:40:30Z","region":"eu-west-1","resources":[],"detail":{"UID":"$(uid)"}}' | sed 's/"/\\"/g'))

docker compose -f docker/docker-compose.yml exec localstack awslocal lambda invoke \
--endpoint-url=http://localhost:4566 \
--region eu-west-1 \
--function-name event-received text \
--payload '{"version":"0","id":"63eb7e5f-1f10-4744-bba9-e16d327c3b98","detail-type":"more-evidence-required","source":"opg.poas.sirius","account":"653761790766","time":"2023-08-30T13:40:30Z","region":"eu-west-1","resources":[],"detail":{"UID":"$(uid)"}}'
--payload '{"Records": [{"messageId": "19dd0b57-b21e-4ac1-bd88-01bbb068cb78", "body": "$(BODY)"}]}'

emit-uid-requested: ##@events emits a uid-requested event with the given detail e.g. emit-uid-requested lpaId=abc sessionId=xyz
$(eval BODY := $(shell echo '{"version":"0","id":"63eb7e5f-1f10-4744-bba9-e16d327c3b98","detail-type":"uid-requested","source":"opg.poas.makeregister","account":"653761790766","time":"2023-08-30T13:40:30Z","region":"eu-west-1","resources":[],"detail":{"LpaID":"$(lpaId)","DonorSessionID":"$(sessionId)","Type":"property-and-affairs","Donor":{"Name":"abc","Dob":"2000-01-01","Postcode":"F1 1FF"}}}' | sed 's/"/\\"/g'))

docker compose -f docker/docker-compose.yml exec localstack awslocal lambda invoke \
--endpoint-url=http://localhost:4566 \
--region eu-west-1 \
--function-name event-received text \
--payload '{"Records": [{"messageId": "19dd0b57-b21e-4ac1-bd88-01bbb068cb78", "body": "$(BODY)"}]}'

emit-lpa-updated-event: ##@events emits an lpa-updated event with the given change type e.g. emit-uid-requested uid=abc-123 changeType=CANNOT_REGISTER
$(eval BODY := $(shell echo '{"version":"0","id":"63eb7e5f-1f10-4744-bba9-e16d327c3b98","detail-type":"lpa-updated","source":"opg.poas.lpastore","account":"653761790766","time":"2023-08-30T13:40:30Z","region":"eu-west-1","resources":[],"detail":{"uid":"$(uid)","changeType":"$(changeType)"}}' | sed 's/"/\\"/g'))

docker compose -f docker/docker-compose.yml exec localstack awslocal lambda invoke \
--endpoint-url=http://localhost:4566 \
--region eu-west-1 \
--function-name event-received text \
--payload '{"Records": [{"messageId": "19dd0b57-b21e-4ac1-bd88-01bbb068cb78", "body": "$(BODY)"}]}'

emit-object-tags-added-with-virus: ##@events emits a ObjectTagging:Put event with the given S3 key e.g. emit-object-tags-added-with-virus key=doc/key. Also ensures a tag with virus-scan-status exists on an existing object set to infected
docker compose -f docker/docker-compose.yml exec localstack awslocal s3api \
Expand All @@ -174,12 +201,6 @@ emit-object-tags-added-without-virus: ##@events emits a ObjectTagging:Put event
--function-name event-received text \
--payload '{"Records":[{"eventSource":"aws:s3","eventTime":"2023-10-23T15:58:33.081Z","eventName":"ObjectTagging:Put","s3":{"bucket":{"name":"uploads-opg-modernising-lpa-eu-west-1"},"object":{"key":"$(key)"}}}]}'

emit-uid-requested: ##@events emits a uid-requested event with the given detail e.g. emit-uid-requested lpaId=abc sessionId=xyz
docker compose -f docker/docker-compose.yml exec localstack awslocal lambda invoke \
--endpoint-url=http://localhost:4566 \
--region eu-west-1 \
--function-name event-received text \
--payload '{"version":"0","id":"63eb7e5f-1f10-4744-bba9-e16d327c3b98","detail-type":"uid-requested","source":"opg.poas.makeregister","account":"653761790766","time":"2023-08-30T13:40:30Z","region":"eu-west-1","resources":[],"detail":{"LpaID":"$(lpaId)","DonorSessionID":"$(sessionId)","Type":"property-and-affairs","Donor":{"Name":"abc","Dob":"2000-01-01","Postcode":"F1 1FF"}}}'

set-uploads-clean: ##@events calls emit-object-tags-added-without-virus for all documents on a given lpa e.g. set-uploads-clean lpaId=abc
for k in $$(docker compose -f docker/docker-compose.yml exec localstack awslocal dynamodb --region eu-west-1 query --table-name lpas --key-condition-expression 'PK = :pk and begins_with(SK, :sk)' --expression-attribute-values '{":pk": {"S": "LPA#$(lpaId)"}, ":sk": {"S": "DOCUMENT#"}}' | jq -c -r '.Items[] | .Key[]'); do \
Expand Down
10 changes: 10 additions & 0 deletions cmd/event-received/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/ministryofjustice/opg-modernising-lpa/internal/lpastore/lpadata"
"github.com/ministryofjustice/opg-modernising-lpa/internal/notify"
"github.com/ministryofjustice/opg-modernising-lpa/internal/random"
"github.com/ministryofjustice/opg-modernising-lpa/internal/scheduled"
"github.com/ministryofjustice/opg-modernising-lpa/internal/search"
"github.com/ministryofjustice/opg-modernising-lpa/internal/secrets"
"github.com/ministryofjustice/opg-modernising-lpa/internal/sharecode"
Expand Down Expand Up @@ -80,6 +81,7 @@ type Factory struct {
lpaStoreClient LpaStoreClient
uidStore UidStore
uidClient UidClient
scheduledStore ScheduledStore
}

func (f *Factory) Now() func() time.Time {
Expand Down Expand Up @@ -211,3 +213,11 @@ func (f *Factory) EventClient() EventClient {

return f.eventClient
}

func (f *Factory) ScheduledStore() ScheduledStore {
if f.scheduledStore == nil {
f.scheduledStore = scheduled.NewStore(f.dynamoClient)
}

return f.scheduledStore
}
15 changes: 15 additions & 0 deletions cmd/event-received/factory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -212,3 +212,18 @@ func TestEventClientWhenSet(t *testing.T) {
client := factory.EventClient()
assert.Equal(t, expected, client)
}

func TestScheduledStore(t *testing.T) {
factory := &Factory{}

client := factory.ScheduledStore()
assert.NotNil(t, client)
}

func TestScheduledStoreWhenSet(t *testing.T) {
expected := newMockScheduledStore(t)
factory := &Factory{scheduledStore: expected}

client := factory.ScheduledStore()
assert.Equal(t, expected, client)
}
43 changes: 25 additions & 18 deletions cmd/event-received/lpastore_event_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,32 +11,35 @@

type lpastoreEventHandler struct{}

func (h *lpastoreEventHandler) Handle(ctx context.Context, factory factory, cloudWatchEvent *events.CloudWatchEvent) error {
switch cloudWatchEvent.DetailType {
case "lpa-updated":
return handleLpaUpdated(ctx, factory.DynamoClient(), cloudWatchEvent, factory.Now())

default:
return fmt.Errorf("unknown lpastore event")
}
}

type lpaUpdatedEvent struct {
UID string `json:"uid"`
ChangeType string `json:"changeType"`
}

func handleLpaUpdated(ctx context.Context, client dynamodbClient, event *events.CloudWatchEvent, now func() time.Time) error {
var v lpaUpdatedEvent
if err := json.Unmarshal(event.Detail, &v); err != nil {
return fmt.Errorf("failed to unmarshal detail: %w", err)
func (h *lpastoreEventHandler) Handle(ctx context.Context, factory factory, cloudWatchEvent *events.CloudWatchEvent) error {
if cloudWatchEvent.DetailType == "lpa-updated" {
var v lpaUpdatedEvent
if err := json.Unmarshal(cloudWatchEvent.Detail, &v); err != nil {
return fmt.Errorf("failed to unmarshal detail: %w", err)
}

Check warning on line 24 in cmd/event-received/lpastore_event_handler.go

View check run for this annotation

Codecov / codecov/patch

cmd/event-received/lpastore_event_handler.go#L23-L24

Added lines #L23 - L24 were not covered by tests

switch v.ChangeType {
case "STATUTORY_WAITING_PERIOD":
return handleStatutoryWaitingPeriod(ctx, factory.DynamoClient(), factory.Now(), v)

case "CANNOT_REGISTER":
return handleCannotRegister(ctx, factory.ScheduledStore(), v)

default:
return nil
}
}

if v.ChangeType != "STATUTORY_WAITING_PERIOD" {
return nil
}
return fmt.Errorf("unknown lpastore event")
}

donor, err := getDonorByLpaUID(ctx, client, v.UID)
func handleStatutoryWaitingPeriod(ctx context.Context, client dynamodbClient, now func() time.Time, event lpaUpdatedEvent) error {
donor, err := getDonorByLpaUID(ctx, client, event.UID)
if err != nil {
return err
}
Expand All @@ -49,3 +52,7 @@

return nil
}

func handleCannotRegister(ctx context.Context, store ScheduledStore, event lpaUpdatedEvent) error {
return store.DeleteAllByUID(ctx, event.UID)
}
Loading