Skip to content

Commit 7bae865

Browse files
authored
New: [AEA-5280] - Push notify data to dynamo (#1598)
## Summary - Routine Change ### Details When the notify processor pulls a message off the queue, log that activity in a dynamo data store.
1 parent 8df71a1 commit 7bae865

9 files changed

Lines changed: 357 additions & 234 deletions

File tree

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@
128128
"sourcetype",
129129
"timonwong",
130130
"Truststore",
131+
"Upserted",
131132
"URID",
132133
"URPID",
133134
"uuidv4",

SAMtemplates/tables/main.yaml

Lines changed: 7 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,7 @@ Resources:
417417
- kms:Encrypt
418418
- kms:ReEncrypt*
419419
- kms:Decrypt
420-
Resource: !GetAtt PrescriptionStatusUpdatesKMSKey.Arn
420+
Resource: !GetAtt PrescriptionNotificationStateKMSKey.Arn
421421

422422
PrescriptionNotificationStateTable:
423423
Type: AWS::DynamoDB::Table
@@ -426,29 +426,19 @@ Resources:
426426
PointInTimeRecoverySpecification:
427427
PointInTimeRecoveryEnabled: true
428428
AttributeDefinitions:
429-
- AttributeName: PrescriptionID
430-
AttributeType: S
431429
- AttributeName: NHSNumber
432430
AttributeType: S
431+
- AttributeName: ODSCode
432+
AttributeType: S
433433
KeySchema:
434-
- AttributeName: PrescriptionID
435-
KeyType: HASH
434+
- AttributeName: NHSNumber
435+
KeyType: HASH # Partition key
436+
- AttributeName: ODSCode
437+
KeyType: RANGE # Sort key
436438
BillingMode: !If
437439
- EnableDynamoDBAutoScalingCondition
438440
- PROVISIONED
439441
- PAY_PER_REQUEST
440-
GlobalSecondaryIndexes:
441-
- IndexName: NotificationNHSNumberIndex
442-
KeySchema:
443-
- AttributeName: NHSNumber
444-
KeyType: HASH
445-
Projection:
446-
ProjectionType: ALL
447-
ProvisionedThroughput: !If
448-
- EnableDynamoDBAutoScalingCondition
449-
- ReadCapacityUnits: 1
450-
WriteCapacityUnits: !Ref MinWritePrescriptionNotificationStateCapacity
451-
- !Ref "AWS::NoValue"
452442
ProvisionedThroughput: !If
453443
- EnableDynamoDBAutoScalingCondition
454444
- ReadCapacityUnits: 1
@@ -524,59 +514,6 @@ Resources:
524514
PredefinedMetricSpecification:
525515
PredefinedMetricType: DynamoDBReadCapacityUtilization
526516

527-
# Scaling for the indexes
528-
NotificationNHSNumberIndexScalingWriteTarget:
529-
Type: AWS::ApplicationAutoScaling::ScalableTarget
530-
DependsOn: PrescriptionNotificationStateTable
531-
Condition: EnableDynamoDBAutoScalingCondition
532-
Properties:
533-
MinCapacity: !Ref MinWritePrescriptionNotificationStateCapacity
534-
MaxCapacity: !Ref MaxWritePrescriptionNotificationStateCapacity
535-
ResourceId: !Sub table/${PrescriptionNotificationStateTable}/index/NotificationNHSNumberIndex
536-
RoleARN: !GetAtt DynamoDbScalingRole.Arn
537-
ScalableDimension: "dynamodb:index:WriteCapacityUnits"
538-
ServiceNamespace: dynamodb
539-
540-
NotificationNHSNumberIndexScalingWritePolicy:
541-
Type: AWS::ApplicationAutoScaling::ScalingPolicy
542-
Condition: EnableDynamoDBAutoScalingCondition
543-
Properties:
544-
PolicyName: NotificationNHSNumberIndexScalingWritePolicy
545-
PolicyType: TargetTrackingScaling
546-
ScalingTargetId: !Ref NotificationNHSNumberIndexScalingWriteTarget
547-
TargetTrackingScalingPolicyConfiguration:
548-
TargetValue: 50
549-
ScaleInCooldown: 600
550-
ScaleOutCooldown: 0
551-
PredefinedMetricSpecification:
552-
PredefinedMetricType: DynamoDBWriteCapacityUtilization
553-
554-
NotificationNHSNumberIndexScalingReadTarget:
555-
Type: AWS::ApplicationAutoScaling::ScalableTarget
556-
DependsOn: PrescriptionNotificationStateTable
557-
Condition: EnableDynamoDBAutoScalingCondition
558-
Properties:
559-
MinCapacity: 1
560-
MaxCapacity: 100
561-
ResourceId: !Sub table/${PrescriptionNotificationStateTable}/index/NotificationNHSNumberIndex
562-
RoleARN: !GetAtt DynamoDbScalingRole.Arn
563-
ScalableDimension: "dynamodb:index:ReadCapacityUnits"
564-
ServiceNamespace: dynamodb
565-
566-
NotificationNHSNumberIndexScalingReadPolicy:
567-
Type: AWS::ApplicationAutoScaling::ScalingPolicy
568-
Condition: EnableDynamoDBAutoScalingCondition
569-
Properties:
570-
PolicyName: NotificationNHSNumberIndexReadScalingPolicy
571-
PolicyType: TargetTrackingScaling
572-
ScalingTargetId: !Ref NotificationNHSNumberIndexScalingReadTarget
573-
TargetTrackingScalingPolicyConfiguration:
574-
TargetValue: 70
575-
ScaleInCooldown: 60
576-
ScaleOutCooldown: 60
577-
PredefinedMetricSpecification:
578-
PredefinedMetricType: DynamoDBReadCapacityUtilization
579-
580517
Outputs:
581518
PrescriptionStatusUpdatesTableName:
582519
Description: PrescriptionStatusUpdates table name

packages/nhsNotifyLambda/jest.config.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,15 @@ import type {JestConfigWithTsJest} from "ts-jest"
33

44
const jestConfig: JestConfigWithTsJest = {
55
...defaultConfig,
6-
"rootDir": "./",
7-
setupFiles: ["<rootDir>/.jest/setEnvVars.js"]
6+
rootDir: "./",
7+
setupFiles: ["<rootDir>/.jest/setEnvVars.js"],
8+
coveragePathIgnorePatterns: ["<rootDir>/tests/"],
9+
coverageReporters: [
10+
"clover",
11+
"json",
12+
"text",
13+
["lcov", {projectRoot: "../../"}]
14+
]
815
}
916

1017
export default jestConfig

packages/nhsNotifyLambda/src/nhsNotifyLambda.ts

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,12 @@ import middy from "@middy/core"
66
import inputOutputLogger from "@middy/input-output-logger"
77
import errorHandler from "@nhs/fhir-middy-error-handler"
88

9-
import {PSUDataItem} from "@PrescriptionStatusUpdate_common/commonTypes"
10-
import {clearCompletedSQSMessages, drainQueue} from "./utils"
9+
import {
10+
addPrescriptionMessagesToNotificationStateStore,
11+
clearCompletedSQSMessages,
12+
drainQueue,
13+
PSUDataItemMessage
14+
} from "./utils"
1115

1216
const logger = new Logger({serviceName: "nhsNotify"})
1317

@@ -21,7 +25,7 @@ export const lambdaHandler = async (event: EventBridgeEvent<string, string>): Pr
2125

2226
logger.info("NHS Notify lambda triggered by scheduler", {event})
2327

24-
let messages
28+
let messages: Array<PSUDataItemMessage>
2529
try {
2630
messages = await drainQueue(logger, 100)
2731

@@ -30,19 +34,9 @@ export const lambdaHandler = async (event: EventBridgeEvent<string, string>): Pr
3034
return
3135
}
3236

33-
// parse & log each PSUDataItem as a placeholder for now.
34-
const items = messages.map((m) => {
35-
try {
36-
return JSON.parse(m.Body!) as PSUDataItem
37-
} catch (err) {
38-
logger.error("Failed to parse message body", {body: m.Body, error: err})
39-
return null
40-
}
41-
}).filter((i): i is PSUDataItem => i !== null)
42-
43-
const toNotify = items.map((m) => ({
44-
RequestID: m.RequestID,
45-
TaskId: m.TaskID,
37+
const toNotify = messages.map((m) => ({
38+
RequestID: m.PSUDataItem.RequestID,
39+
TaskId: m.PSUDataItem.TaskID,
4640
Message: "Notification Required"
4741
}))
4842
logger.info("Fetched prescription notification messages", {count: toNotify.length, toNotify})
@@ -58,10 +52,17 @@ export const lambdaHandler = async (event: EventBridgeEvent<string, string>): Pr
5852
throw err
5953
}
6054

55+
try {
56+
await addPrescriptionMessagesToNotificationStateStore(logger, messages)
57+
} catch (err) {
58+
logger.error("Error while pushing data to the PSU notification state data store", {err})
59+
throw err
60+
}
61+
6162
// By waiting until a message is successfully processed before deleting it from SQS,
6263
// failed messages will eventually be retried by subsequent notify consumers.
6364
try {
64-
await clearCompletedSQSMessages(messages, logger)
65+
await clearCompletedSQSMessages(logger, messages)
6566
} catch (err) {
6667
logger.error("Error while deleting successfully processed messages from SQS", {error: err})
6768
throw err

0 commit comments

Comments
 (0)