Skip to content

Commit 5c99f65

Browse files
authored
New: [AEA-5199] - Setup notifications flow (#1546)
## Summary - ✨ New Feature ### Details This PR is to add the various components needed for the NHS notify integration to the PSU. There are four new things to deploy: - EventBridge scheduler - Lambda function to handle the processing, triggered by the scheduler - SQS (eventually to be populated by the existing PSU function) - Notifications state Dynamo database Initially, the only requirement is that the lambda function is executed every minute. The PSU will not push anything to SQS yet. The lambda will only log that it has been run.
1 parent 07a260d commit 5c99f65

38 files changed

Lines changed: 2277 additions & 2872 deletions

.pre-commit-config.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,16 @@ repos:
8686
files: ^packages\/checkPrescriptionStatusUpdates
8787
types_or: [ts, tsx, javascript, jsx, json]
8888
pass_filenames: false
89+
90+
- id: lint-nhsNotifyLambda
91+
name: Lint nhsNotifyLambda
92+
entry: npm
93+
args:
94+
["run", "--prefix=packages/nhsNotifyLambda", "lint"]
95+
language: system
96+
files: ^packages\/nhsNotifyLambda
97+
types_or: [ts, tsx, javascript, jsx, json]
98+
pass_filenames: false
8999

90100
- id: lint-commonTesting
91101
name: Lint common/testing

.vscode/eps-prescription-status-update-api.code-workspace

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@
2828
"name": "packages/cpsuLambda",
2929
"path": "../packages/cpsuLambda"
3030
},
31+
{
32+
"name": "packages/nhsNotifyLambda",
33+
"path": "../packages/nhsNotifyLambda"
34+
},
3135
{
3236
"name": "packages/capabilityStatement",
3337
"path": "../packages/capabilityStatement"
@@ -36,6 +40,10 @@
3640
"name": "packages/checkPrescriptionStatusUpdates",
3741
"path": "../packages/checkPrescriptionStatusUpdates"
3842
},
43+
{
44+
"name": "packages/common/commonTypes",
45+
"path": "../packages/common/commonTypes"
46+
},
3947
{
4048
"name": "packages/common/testing",
4149
"path": "../packages/common/testing"

Makefile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,10 @@ lint-node: compile-node
116116
npm run lint --workspace packages/capabilityStatement
117117
npm run lint --workspace packages/cpsuLambda
118118
npm run lint --workspace packages/checkPrescriptionStatusUpdates
119+
npm run lint --workspace packages/nhsNotifyLambda
119120
npm run lint --workspace packages/common/testing
120121
npm run lint --workspace packages/common/middyErrorHandler
122+
npm run lint --workspace packages/common/commonTypes
121123

122124
lint-specification: compile-specification
123125
npm run lint --workspace packages/specification
@@ -144,6 +146,7 @@ test: compile
144146
npm run test --workspace packages/capabilityStatement
145147
npm run test --workspace packages/cpsuLambda
146148
npm run test --workspace packages/checkPrescriptionStatusUpdates
149+
npm run test --workspace packages/nhsNotifyLambda
147150
npm run test --workspace packages/common/middyErrorHandler
148151

149152
clean:
@@ -159,9 +162,12 @@ clean:
159162
rm -rf packages/capabilityStatement/lib
160163
rm -rf packages/cpsuLambda/coverage
161164
rm -rf packages/cpsuLambda/lib
165+
rm -rf packages/nhsNotifyLambda/coverage
166+
rm -rf packages/nhsNotifyLambda/lib
162167
rm -rf packages/checkPrescriptionStatusUpdates/lib
163168
rm -rf packages/common/testing/lib
164169
rm -rf packages/common/middyErrorHandler/lib
170+
rm -rf packages/common/commonTypes/lib
165171
rm -rf .aws-sam
166172

167173
deep-clean: clean

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ This is the AWS layer that provides an API for EPS Prescription Status Update.
1919
- `packages/statusLambda/` Returns the status of the updatePrescriptionStatus endpoint
2020
- `packages/capabilityStatement/` Returns a static capability statement.
2121
- `packages/cpsuLambda` Handles updating prescription status using a custom format.
22+
- `packages/nhsNotifyLambda` Handles sending prescription notifications to the NHS notify service.
2223
- `scripts/` Utilities helpful to developers of this specification.
2324
- `postman/` Postman collections to call the APIs. Documentation on how to use them are in the collections.
2425
- `SAMtemplates/` Contains the SAM templates used to define the stacks.

SAMtemplates/functions/main.yaml

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,14 @@ Parameters:
2525
Type: String
2626
Default: none
2727

28+
PrescriptionNotificationStateTableName:
29+
Type: String
30+
Default: none
31+
32+
NHSNotifyPrescriptionsSQSQueueUrl:
33+
Type: String
34+
Default: none
35+
2836
LogLevel:
2937
Type: String
3038

@@ -62,6 +70,7 @@ Resources:
6270
Environment:
6371
Variables:
6472
TABLE_NAME: !Ref PrescriptionStatusUpdatesTableName
73+
NHS_NOTIFY_PRESCRIPTIONS_SQS_QUEUE_URL: !Ref NHSNotifyPrescriptionsSQSQueueUrl
6574
LOG_LEVEL: !Ref LogLevel
6675
ENVIRONMENT: !Ref Environment
6776
TEST_PRESCRIPTIONS_1: "None"
@@ -96,6 +105,8 @@ Resources:
96105
- - Fn::ImportValue: !Sub ${StackName}:tables:${PrescriptionStatusUpdatesTableName}:TableWritePolicyArn
97106
- Fn::ImportValue: !Sub ${StackName}:tables:${PrescriptionStatusUpdatesTableName}:TableReadPolicyArn
98107
- Fn::ImportValue: !Sub ${StackName}:tables:UsePrescriptionStatusUpdatesKMSKeyPolicyArn
108+
- Fn::ImportValue: !Sub ${StackName}-UseNotificationSQSQueueKMSKeyPolicyArn
109+
- Fn::ImportValue: !Sub ${StackName}-WriteNHSNotifyPrescriptionsSQSQueuePolicyArn
99110
LogRetentionInDays: !Ref LogRetentionInDays
100111
CloudWatchKMSKeyId: !ImportValue account-resources:CloudwatchLogsKmsKeyArn
101112
EnableSplunk: !Ref EnableSplunk
@@ -320,6 +331,91 @@ Resources:
320331
SplunkSubscriptionFilterRole: !ImportValue lambda-resources:SplunkSubscriptionFilterRole
321332
SplunkDeliveryStreamArn: !ImportValue lambda-resources:SplunkDeliveryStream
322333

334+
NHSNotifyLambdaScheduleEventRole:
335+
Type: AWS::IAM::Role
336+
Properties:
337+
AssumeRolePolicyDocument:
338+
Version: 2012-10-17
339+
Statement:
340+
- Effect: Allow
341+
Principal:
342+
Service:
343+
- scheduler.amazonaws.com
344+
Action:
345+
- sts:AssumeRole
346+
ManagedPolicyArns:
347+
- !Ref NHSNotifyLambdaScheduleEventRolePolicy
348+
349+
NHSNotifyLambdaScheduleEventRolePolicy:
350+
Type: AWS::IAM::ManagedPolicy
351+
Properties:
352+
PolicyDocument:
353+
Version: 2012-10-17
354+
Statement:
355+
- Effect: Allow
356+
Action:
357+
- lambda:InvokeFunction
358+
Resource:
359+
- !GetAtt NHSNotifyLambda.Arn
360+
361+
NHSNotifyLambda:
362+
Type: AWS::Serverless::Function
363+
Properties:
364+
FunctionName: !Sub ${StackName}-NHSNotifyLambda
365+
CodeUri: ../../packages/
366+
Handler: nhsNotifyLambda.handler
367+
Role: !GetAtt NHSNotifyLambdaResources.Outputs.LambdaRoleArn
368+
Environment:
369+
Variables:
370+
LOG_LEVEL: !Ref LogLevel
371+
NHS_NOTIFY_PRESCRIPTIONS_SQS_QUEUE_URL: !Ref NHSNotifyPrescriptionsSQSQueueUrl
372+
TABLE_NAME: !Ref PrescriptionNotificationStateTableName
373+
Events:
374+
ScheduleEvent:
375+
Type: ScheduleV2
376+
Properties:
377+
Name: !Sub ${StackName}-NHSNotifySchedule
378+
ScheduleExpression: "rate(1 minute)"
379+
RoleArn: !GetAtt NHSNotifyLambdaScheduleEventRole.Arn
380+
Metadata:
381+
BuildMethod: esbuild
382+
guard:
383+
SuppressedRules:
384+
- LAMBDA_DLQ_CHECK
385+
- LAMBDA_INSIDE_VPC
386+
- LAMBDA_CONCURRENCY_CHECK
387+
BuildProperties:
388+
Minify: true
389+
Target: es2020
390+
Sourcemap: true
391+
tsconfig: nhsNotifyLambda/tsconfig.json
392+
packages: bundle
393+
EntryPoints:
394+
- nhsNotifyLambda/src/nhsNotifyLambda.ts
395+
396+
NHSNotifyLambdaResources:
397+
Type: AWS::Serverless::Application
398+
Properties:
399+
Location: lambda_resources.yaml
400+
Parameters:
401+
StackName: !Ref StackName
402+
LambdaName: !Sub ${StackName}-NHSNotifyLambda
403+
LambdaArn: !Sub arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:${StackName}-NHSNotifyLambda
404+
LogRetentionInDays: !Ref LogRetentionInDays
405+
CloudWatchKMSKeyId: !ImportValue account-resources:CloudwatchLogsKmsKeyArn
406+
EnableSplunk: !Ref EnableSplunk
407+
SplunkSubscriptionFilterRole: !ImportValue lambda-resources:SplunkSubscriptionFilterRole
408+
SplunkDeliveryStreamArn: !ImportValue lambda-resources:SplunkDeliveryStream
409+
IncludeAdditionalPolicies: true
410+
AdditionalPolicies: !Join
411+
- ","
412+
- - Fn::ImportValue: !Sub ${StackName}-WriteNHSNotifyPrescriptionsSQSQueuePolicyArn
413+
- Fn::ImportValue: !Sub ${StackName}-ReadNHSNotifyPrescriptionsSQSQueuePolicyArn
414+
- Fn::ImportValue: !Sub ${StackName}-UseNotificationSQSQueueKMSKeyPolicyArn
415+
- Fn::ImportValue: !Sub ${StackName}:tables:${PrescriptionNotificationStateTableName}:TableReadPolicyArn
416+
- Fn::ImportValue: !Sub ${StackName}:tables:${PrescriptionNotificationStateTableName}:TableWritePolicyArn
417+
- Fn::ImportValue: !Sub ${StackName}:tables:UsePrescriptionNotificationStateKMSKeyPolicyArn
418+
323419
Outputs:
324420
UpdatePrescriptionStatusFunctionName:
325421
Description: The function name of the UpdatePrescriptionStatus lambda
@@ -378,3 +474,11 @@ Outputs:
378474
- ShouldDeployCheckPrescriptionStatusUpdate
379475
- !GetAtt CheckPrescriptionStatusUpdates.Arn
380476
- ""
477+
478+
NHSNotifyLambdaFunctionName:
479+
Description: The function name of the NHS Notify lambda
480+
Value: !Ref NHSNotifyLambda
481+
482+
NHSNotifyLambdaFunctionArn:
483+
Description: The function ARN of the NHS Notify lambda
484+
Value: !GetAtt NHSNotifyLambda.Arn

SAMtemplates/main_template.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,13 @@ Resources:
9898
StackName: !Ref AWS::StackName
9999
EnableDynamoDBAutoScaling: !Ref EnableDynamoDBAutoScaling
100100

101+
Messaging:
102+
Type: AWS::Serverless::Application
103+
Properties:
104+
Location: messaging/main.yaml
105+
Parameters:
106+
StackName: !Ref AWS::StackName
107+
101108
Apis:
102109
Type: AWS::Serverless::Application
103110
Properties:
@@ -127,6 +134,8 @@ Resources:
127134
Parameters:
128135
StackName: !Ref AWS::StackName
129136
PrescriptionStatusUpdatesTableName: !GetAtt Tables.Outputs.PrescriptionStatusUpdatesTableName
137+
PrescriptionNotificationStateTableName: !GetAtt Tables.Outputs.PrescriptionNotificationStateTableName
138+
NHSNotifyPrescriptionsSQSQueueUrl: !GetAtt Messaging.Outputs.NHSNotifyPrescriptionsSQSQueueUrl
130139
LogLevel: !Ref LogLevel
131140
LogRetentionInDays: !Ref LogRetentionInDays
132141
EnableSplunk: !Ref EnableSplunk

SAMtemplates/messaging/main.yaml

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
AWSTemplateFormatVersion: "2010-09-09"
2+
Transform: AWS::Serverless-2016-10-31
3+
Description: |
4+
SQS messaging stacks used by the PSU
5+
6+
Parameters:
7+
StackName:
8+
Type: String
9+
10+
Resources:
11+
NotificationSQSQueueKMSKey:
12+
Type: AWS::KMS::Key
13+
Properties:
14+
EnableKeyRotation: true
15+
KeyPolicy:
16+
Version: 2012-10-17
17+
Id: NotificationSQSQueueKeyPolicy
18+
Statement:
19+
- Sid: EnableIAMUserPermissions
20+
Effect: Allow
21+
Principal:
22+
AWS: !Sub "arn:aws:iam::${AWS::AccountId}:root"
23+
Action: kms:*
24+
Resource: "*"
25+
26+
NotificationSQSQueueKMSKeyAlias:
27+
Type: AWS::KMS::Alias
28+
Properties:
29+
AliasName: !Sub alias/${StackName}-NotificationSQSQueueKMSKey
30+
TargetKeyId: !Ref NotificationSQSQueueKMSKey
31+
32+
UseNotificationSQSQueueKMSKeyPolicy:
33+
Type: AWS::IAM::ManagedPolicy
34+
Properties:
35+
ManagedPolicyName: !Sub ${StackName}-UseNotificationSQSQueueKMSKey
36+
PolicyDocument:
37+
Version: "2012-10-17"
38+
Statement:
39+
- Sid: AllowKmsForSqsEncryption
40+
Effect: Allow
41+
Action:
42+
- kms:DescribeKey
43+
- kms:GenerateDataKey*
44+
- kms:Encrypt
45+
- kms:Decrypt
46+
Resource: !GetAtt NotificationSQSQueueKMSKey.Arn
47+
48+
NHSNotifyPrescriptionsSQSQueue:
49+
Type: AWS::SQS::Queue
50+
Properties:
51+
QueueName: !Sub ${StackName}-NHSNotifyPrescriptions
52+
KmsMasterKeyId: !Ref NotificationSQSQueueKMSKeyAlias
53+
MessageRetentionPeriod: 86400 # 1 day in seconds
54+
RedrivePolicy:
55+
deadLetterTargetArn: !GetAtt NHSNotifyPrescriptionsDeadLetterQueue.Arn
56+
maxReceiveCount: 5
57+
VisibilityTimeout: 300
58+
59+
NHSNotifyPrescriptionsDeadLetterQueue:
60+
Type: AWS::SQS::Queue
61+
Properties:
62+
QueueName: !Sub ${StackName}-NHSNotifyPrescriptionsDeadLetter
63+
KmsMasterKeyId: !Ref NotificationSQSQueueKMSKeyAlias
64+
MessageRetentionPeriod: 604800 # 1 week in seconds
65+
VisibilityTimeout: 300
66+
67+
ReadNHSNotifyPrescriptionsSQSQueuePolicy:
68+
Type: AWS::IAM::ManagedPolicy
69+
Properties:
70+
PolicyDocument:
71+
Version: 2012-10-17
72+
Statement:
73+
- Effect: Allow
74+
Action:
75+
- sqs:ReceiveMessage
76+
- sqs:DeleteMessage
77+
- sqs:ChangeMessageVisibility
78+
- sqs:GetQueueAttributes
79+
- sqs:GetQueueUrl
80+
- kms:GenerateDataKey
81+
- kms:Decrypt
82+
Resource: !GetAtt NHSNotifyPrescriptionsSQSQueue.Arn
83+
84+
WriteNHSNotifyPrescriptionsSQSQueuePolicy:
85+
Type: AWS::IAM::ManagedPolicy
86+
Properties:
87+
ManagedPolicyName: !Sub ${StackName}-NHSNotifyPrescriptionsSendMessagePolicy
88+
PolicyDocument:
89+
Version: "2012-10-17"
90+
Statement:
91+
- Effect: Allow
92+
Action:
93+
- sqs:SendMessage
94+
- sqs:SendMessageBatch
95+
- sqs:GetQueueUrl
96+
- kms:GenerateDataKey
97+
- kms:Decrypt
98+
Resource: !GetAtt NHSNotifyPrescriptionsSQSQueue.Arn
99+
100+
Outputs:
101+
NHSNotifyPrescriptionsSQSQueueUrl:
102+
Description: The URL of the NHS Notify Prescriptions SQS Queue
103+
Value: !Ref NHSNotifyPrescriptionsSQSQueue
104+
Export:
105+
Name: !Sub ${StackName}-NHSNotifyPrescriptionsSQSQueueUrl
106+
107+
NHSNotifyPrescriptionsSQSQueueArn:
108+
Description: The ARN of the NHS Notify Prescriptions SQS Queue
109+
Value: !GetAtt NHSNotifyPrescriptionsSQSQueue.Arn
110+
Export:
111+
Name: !Sub ${StackName}-NHSNotifyPrescriptionsSQSQueueArn
112+
113+
ReadNHSNotifyPrescriptionsSQSQueuePolicyArn:
114+
Description: ARN of policy granting permission to read the prescriptions queue
115+
Value: !Ref ReadNHSNotifyPrescriptionsSQSQueuePolicy
116+
Export:
117+
Name: !Sub ${StackName}-ReadNHSNotifyPrescriptionsSQSQueuePolicyArn
118+
119+
WriteNHSNotifyPrescriptionsSQSQueuePolicyArn:
120+
Description: ARN of policy granting permission to write to the prescriptions queue
121+
Value: !Ref WriteNHSNotifyPrescriptionsSQSQueuePolicy
122+
Export:
123+
Name: !Sub ${StackName}-WriteNHSNotifyPrescriptionsSQSQueuePolicyArn
124+
125+
UseNotificationSQSQueueKMSKeyPolicyArn:
126+
Description: ARN of managed policy granting prescriptions queue KMS usage
127+
Value: !Ref UseNotificationSQSQueueKMSKeyPolicy
128+
Export:
129+
Name: !Sub ${StackName}-UseNotificationSQSQueueKMSKeyPolicyArn

0 commit comments

Comments
 (0)